Repository: owncloud/ocis
Pull request #4963 (2022-11-03 06:04:06)

Bump github.com/go-micro/plugins/v4/server/http from 1.1.1 to 1.2.0
Bumps [github.com/go-micro/plugins/v4/server/http](https://github.com/go-micro/plugins) from 1.1.1 to 1.2.0.
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/go-micro/plugins/commit/0d18e60b84eaff14af1ca32b70e3c32ec0637517"><code>0d18e60</code></a> fix(actions): update release script</li>
<li><a href="https://github.com/go-micro/plugins/commit/20e6072e9e2ef1b8f1ea14d4989635483db708bc"><code>20e6072</code></a> feat(action): release script</li>
<li><a href="https://github.com/go-micro/plugins/commit/cb3aa4e2a5acdc683e2b0e98563d7d7d9ac29dc7"><code>cb3aa4e</code></a> feat(actions): add release script template  (<a href="https://github-redirect.dependabot.com/go-micro/plugins/issues/82">#82</a>)</li>
<li><a href="https://github.com/go-micro/plugins/commit/46b9956befef0fd8f676f5227969ddcaba5df3e3"><code>46b9956</code></a> fix(registry/consul): http check using node address (<a href="https://github-redirect.dependabot.com/go-micro/plugins/issues/81">#81</a>)</li>
<li><a href="https://github.com/go-micro/plugins/commit/f1a4bcb03186d8c9555eeae4f263b9dfb274d03b"><code>f1a4bcb</code></a> feat(registry): new registry Polaris (<a href="https://github-redirect.dependabot.com/go-micro/plugins/issues/72">#72</a>)</li>
<li><a href="https://github.com/go-micro/plugins/commit/19a34a4c849ee8262ce23e7ca858f307cb0ad096"><code>19a34a4</code></a> feat: add logger option to plugins (<a href="https://github-redirect.dependabot.com/go-micro/plugins/issues/78">#78</a>)</li>
<li><a href="https://github.com/go-micro/plugins/commit/57405c9fd0315f02430a822c420f9e03b1f80e6c"><code>57405c9</code></a> feat(consul): add consul HTTP check (<a href="https://github-redirect.dependabot.com/go-micro/plugins/issues/79">#79</a>)</li>
<li><a href="https://github.com/go-micro/plugins/commit/9c0175b39b049abd3d9c070966395e233220a129"><code>9c0175b</code></a> feat(cache;store;events/redis): Add cluster and sentinel failover support (<a href="https://github-redirect.dependabot.com/go-micro/plugins/issues/80">#80</a>)</li>
<li><a href="https://github.com/go-micro/plugins/commit/c91295de81c390c8152776186c4f6747da9f2bbc"><code>c91295d</code></a> chore(registry/kubernetes): fix linting issues &amp; tests (<a href="https://github-redirect.dependabot.com/go-micro/plugins/issues/77">#77</a>)</li>
<li><a href="https://github.com/go-micro/plugins/commit/e95382c21d8bd38f7a7043778f4a041d45d75170"><code>e95382c</code></a> fix: run golanci-lint --fix on v4</li>
<li>Additional commits viewable in <a href="https://github.com/go-micro/plugins/compare/v4/server/grpc/v1.1.1...v4/auth/jwt/v1.2.0">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/go-micro/plugins/v4/server/http&package-manager=go_modules&previous-version=1.1.1&new-version=1.2.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>

update-docs[bot]: Thanks for opening this pull request! The maintainers of this repository would appreciate it if you would create a [changelog](https://github.com/owncloud/ocis/blob/master/changelog/README.md) item based on your changes.

sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; [![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonarcloud.io/dashboard?id=owncloud_ocis&pullRequest=4963)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=4963&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=4963&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=4963&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=4963&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=4963&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=4963&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=owncloud_ocis&pullRequest=4963&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=owncloud_ocis&pullRequest=4963&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=owncloud_ocis&pullRequest=4963&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=4963&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=4963&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=owncloud_ocis&pullRequest=4963&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=owncloud_ocis&pullRequest=4963&metric=coverage&view=list) No Coverage information  
[![No Duplication information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/NoDuplicationInfo-16px.png 'No Duplication information')](https://sonarcloud.io/component_measures?id=owncloud_ocis&pullRequest=4963&metric=duplicated_lines_density&view=list) No Duplication information



Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d4af401f406..503e09c8015 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -24,6 +24,7 @@ The following sections list the changes for unreleased.
 * Bugfix - Fix the shareroot path in REPORT responses: [#4859](https://github.com/owncloud/ocis/pull/4859)
 * Bugfix - Remove the storage-users event configuration: [#4825](https://github.com/owncloud/ocis/pull/4825)
 * Bugfix - Trigger a rescan of spaces in the search index when items have changed: [#4777](https://github.com/owncloud/ocis/pull/4777)
+* Bugfix - Fix permission check in settings service: [#4890](https://github.com/owncloud/ocis/pull/4890)
 * Bugfix - Make tokeninfo endpoint unprotected: [#4715](https://github.com/owncloud/ocis/pull/4715)
 * Bugfix - Fix wopi access to public shares: [#4631](https://github.com/owncloud/ocis/pull/4631)
 * Change - Build service frontends with pnpm instead of yarn: [#4878](https://github.com/owncloud/ocis/pull/4878)
@@ -188,6 +189,12 @@ The following sections list the changes for unreleased.
    https://github.com/owncloud/ocis/issues/4410
    https://github.com/owncloud/ocis/pull/4777
 
+* Bugfix - Fix permission check in settings service: [#4890](https://github.com/owncloud/ocis/pull/4890)
+
+   Added a check of the stored roles as a fallback if no roles are contained in the context.
+
+   https://github.com/owncloud/ocis/pull/4890
+
 * Bugfix - Make tokeninfo endpoint unprotected: [#4715](https://github.com/owncloud/ocis/pull/4715)
 
    Make the tokeninfo endpoint unprotected as it is supposed to be available to the public.
diff --git a/changelog/unreleased/settings-permissions-check.md b/changelog/unreleased/settings-permissions-check.md
new file mode 100644
index 00000000000..10b302d044e
--- /dev/null
+++ b/changelog/unreleased/settings-permissions-check.md
@@ -0,0 +1,5 @@
+Bugfix: Fix permission check in settings service
+
+Added a check of the stored roles as a fallback if no roles are contained in the context.
+
+https://github.com/owncloud/ocis/pull/4890
diff --git a/go.mod b/go.mod
index 14fe395f112..478029cf01a 100644
--- a/go.mod
+++ b/go.mod
@@ -28,7 +28,7 @@ require (
 	github.com/go-micro/plugins/v4/registry/memory v1.1.0
 	github.com/go-micro/plugins/v4/registry/nats v1.1.0
 	github.com/go-micro/plugins/v4/server/grpc v1.1.1
-	github.com/go-micro/plugins/v4/server/http v1.1.1
+	github.com/go-micro/plugins/v4/server/http v1.2.0
 	github.com/go-micro/plugins/v4/wrapper/breaker/gobreaker v1.2.0
 	github.com/go-micro/plugins/v4/wrapper/monitoring/prometheus v1.2.0
 	github.com/go-micro/plugins/v4/wrapper/trace/opencensus v1.1.0
diff --git a/go.sum b/go.sum
index e48219ed27d..c21e05ce82f 100644
--- a/go.sum
+++ b/go.sum
@@ -492,8 +492,8 @@ github.com/go-micro/plugins/v4/registry/nats v1.1.0 h1:oqQzP5P2FkfoYZiBRuCWsKqh4
 github.com/go-micro/plugins/v4/registry/nats v1.1.0/go.mod h1:4tTfa958PiYUOZNBBNoY1awmgfxFcqQOmix8cR3UM+E=
 github.com/go-micro/plugins/v4/server/grpc v1.1.1 h1:7V5K8RTQhzzFsJCPkKXTJr4YrWyIw5xebUTtDY27l3k=
 github.com/go-micro/plugins/v4/server/grpc v1.1.1/go.mod h1:GntDOa4zIHmyBLAvSXP05gK6im+Fw+Dh8fxUk/yiwaI=
-github.com/go-micro/plugins/v4/server/http v1.1.1 h1:n45l9rrJUWXT25W3DmTBl9DJoc31DxwiL6t3zUoa0e0=
-github.com/go-micro/plugins/v4/server/http v1.1.1/go.mod h1:ZjVZi1l16RjzyT3IISirh9BEZdqzaLLwiE/1fvdSbnI=
+github.com/go-micro/plugins/v4/server/http v1.2.0 h1:7wgXxdTMSwCfxpUdmOdllyJQRZk9ZtMK5WhankTdKcs=
+github.com/go-micro/plugins/v4/server/http v1.2.0/go.mod h1:YuAjaSPxcn3LI8j2FUsqx0Rxunrj4YwDV41Ax76rLl0=
 github.com/go-micro/plugins/v4/store/nats-js v1.1.0 h1:6Fe1/eLtg8kRyaGvMILp4olYtTDGwYNBXyb1sYfAWGk=
 github.com/go-micro/plugins/v4/store/nats-js v1.1.0/go.mod h1:jJf7Gm39OafZlT3s3UE2/9NIYj6OlI2fmZ4czSA3gvo=
 github.com/go-micro/plugins/v4/store/redis v1.1.0 h1:QWl5FAfMaekppZGNcj0mSyi8vCkjZGvHoGdaBNeKNm4=
diff --git a/services/app-provider/pkg/config/config.go b/services/app-provider/pkg/config/config.go
index 66e6003e38f..15681f07edd 100644
--- a/services/app-provider/pkg/config/config.go
+++ b/services/app-provider/pkg/config/config.go
@@ -59,7 +59,7 @@ type GRPCConfig struct {
 }
 
 type Drivers struct {
-	WOPI WOPIDriver `yaml:"wopi" desc:"driver for the CS3org WOPI server"`
+	WOPI WOPIDriver `yaml:"wopi" desc:"Driver for the CS3org WOPI server"`
 }
 
 type WOPIDriver struct {
diff --git a/services/auth-basic/pkg/config/config.go b/services/auth-basic/pkg/config/config.go
index d9ed81ebb20..e3c27744307 100644
--- a/services/auth-basic/pkg/config/config.go
+++ b/services/auth-basic/pkg/config/config.go
@@ -19,7 +19,7 @@ type Config struct {
 	Reva         *shared.Reva  `yaml:"reva"`
 
 	SkipUserGroupsInToken bool          `yaml:"skip_user_groups_in_token" env:"AUTH_BASIC_SKIP_USER_GROUPS_IN_TOKEN" desc:"Disables the encoding of the user's group memberships in the reva access token. This reduces the token size, especially when users are members of a large number of groups."`
-	AuthProvider          string        `yaml:"auth_provider" env:"AUTH_BASIC_AUTH_PROVIDER" desc:"The auth provider which should be used by the service like 'ldap'."`
+	AuthProvider          string        `yaml:"auth_provider" env:"AUTH_BASIC_AUTH_PROVIDER" desc:"The authentication provider to check if credentials are valid. Supported values are 'ldap' and 'owncloudsql'."`
 	AuthProviders         AuthProviders `yaml:"auth_providers"`
 
 	Supervised bool            `yaml:"-"`
diff --git a/services/groups/pkg/config/config.go b/services/groups/pkg/config/config.go
index ee6a903a692..7b4417e091e 100644
--- a/services/groups/pkg/config/config.go
+++ b/services/groups/pkg/config/config.go
@@ -20,7 +20,7 @@ type Config struct {
 
 	SkipUserGroupsInToken bool `yaml:"skip_user_groups_in_token" env:"GROUPS_SKIP_USER_GROUPS_IN_TOKEN" desc:"Disables the loading of user's group memberships from the reva access token."`
 
-	Driver  string  `yaml:"driver" desc:"The driver which should be used by the groups service like 'ldap'."`
+	Driver  string  `yaml:"driver" env:"GROUPS_DRIVER" desc:"The driver which should be used by the groups service. Supported values are 'ldap' and 'owncloudsql'."`
 	Drivers Drivers `yaml:"drivers"`
 
 	Supervised bool            `yaml:"-"`
diff --git a/services/search/pkg/config/config.go b/services/search/pkg/config/config.go
index f9cee19da9f..1f463c0f562 100644
--- a/services/search/pkg/config/config.go
+++ b/services/search/pkg/config/config.go
@@ -18,7 +18,9 @@ type Config struct {
 
 	GRPC GRPCConfig `yaml:"grpc"`
 
-	Datapath      string                `yaml:"data_path" env:"SEARCH_DATA_PATH" desc:"The directory where the filesystem storage will store search data. If not definied, the root directory derives from $OCIS_BASE_DATA_PATH:/search."`
+	Datapath         string `yaml:"data_path" env:"SEARCH_DATA_PATH" desc:"The directory where the filesystem storage will store search data. If not definied, the root directory derives from $OCIS_BASE_DATA_PATH:/search."`
+	DebounceDuration int    `yaml:"debounce_duration" env:"SEARCH_REINDEX_DEBOUNCE_DURATION" desc:"The duration in milliseconds the reindex debouncer waits before triggering a reindex of a space that was modified."`
+
 	Reva          *shared.Reva          `yaml:"reva"`
 	GRPCClientTLS *shared.GRPCClientTLS `yaml:"grpc_client_tls"`
 	Events        Events                `yaml:"events"`
diff --git a/services/search/pkg/config/defaults/defaultconfig.go b/services/search/pkg/config/defaults/defaultconfig.go
index cfc9eb7014d..ac4604e0d64 100644
--- a/services/search/pkg/config/defaults/defaultconfig.go
+++ b/services/search/pkg/config/defaults/defaultconfig.go
@@ -29,8 +29,9 @@ func DefaultConfig() *config.Config {
 		Service: config.Service{
 			Name: "search",
 		},
-		Datapath: path.Join(defaults.BaseDataPath(), "search"),
-		Reva:     shared.DefaultRevaConfig(),
+		Datapath:         path.Join(defaults.BaseDataPath(), "search"),
+		DebounceDuration: 1000,
+		Reva:             shared.DefaultRevaConfig(),
 		Events: config.Events{
 			Endpoint:      "127.0.0.1:9233",
 			Cluster:       "ocis-cluster",
diff --git a/services/search/pkg/search/provider/searchprovider.go b/services/search/pkg/search/provider/searchprovider.go
index 5201daf98c8..f20a3116d28 100644
--- a/services/search/pkg/search/provider/searchprovider.go
+++ b/services/search/pkg/search/provider/searchprovider.go
@@ -79,7 +79,7 @@ func (s MatchArray) Less(i, j int) bool {
 	return s[i].Score > s[j].Score
 }
 
-func New(gwClient gateway.GatewayAPIClient, indexClient search.IndexClient, machineAuthAPIKey string, eventsChan <-chan interface{}, logger log.Logger) *Provider {
+func New(gwClient gateway.GatewayAPIClient, indexClient search.IndexClient, machineAuthAPIKey string, eventsChan <-chan interface{}, debounceDuration int, logger log.Logger) *Provider {
 	p := &Provider{
 		gwClient:          gwClient,
 		indexClient:       indexClient,
@@ -87,7 +87,7 @@ func New(gwClient gateway.GatewayAPIClient, indexClient search.IndexClient, mach
 		logger:            logger,
 	}
 
-	p.indexSpaceDebouncer = NewSpaceDebouncer(50*time.Millisecond, func(id *provider.StorageSpaceId, userID *user.UserId) {
+	p.indexSpaceDebouncer = NewSpaceDebouncer(time.Duration(debounceDuration)*time.Millisecond, func(id *provider.StorageSpaceId, userID *user.UserId) {
 		err := p.doIndexSpace(context.Background(), id, userID)
 		if err != nil {
 			p.logger.Error().Err(err).Interface("spaceID", id).Interface("userID", userID).Msg("error while indexing a space")
@@ -109,7 +109,7 @@ func New(gwClient gateway.GatewayAPIClient, indexClient search.IndexClient, mach
 
 // NewWithDebouncer returns a new provider with a customer index space debouncer
 func NewWithDebouncer(gwClient gateway.GatewayAPIClient, indexClient search.IndexClient, machineAuthAPIKey string, eventsChan <-chan interface{}, logger log.Logger, debouncer *SpaceDebouncer) *Provider {
-	p := New(gwClient, indexClient, machineAuthAPIKey, eventsChan, logger)
+	p := New(gwClient, indexClient, machineAuthAPIKey, eventsChan, 0, logger)
 	p.indexSpaceDebouncer = debouncer
 	return p
 }
diff --git a/services/search/pkg/service/v0/service.go b/services/search/pkg/service/v0/service.go
index 8dd12ba7135..353bacfca33 100644
--- a/services/search/pkg/service/v0/service.go
+++ b/services/search/pkg/service/v0/service.go
@@ -93,7 +93,7 @@ func NewHandler(opts ...Option) (searchsvc.SearchProviderHandler, error) {
 		logger.Fatal().Err(err).Str("addr", cfg.Reva.Address).Msg("could not get reva client")
 	}
 
-	provider := searchprovider.New(gwclient, index, cfg.MachineAuthAPIKey, evts, logger)
+	provider := searchprovider.New(gwclient, index, cfg.MachineAuthAPIKey, evts, cfg.DebounceDuration, logger)
 
 	return &Service{
 		id:       cfg.GRPC.Namespace + "." + cfg.Service.Name,
diff --git a/services/settings/pkg/service/v0/service.go b/services/settings/pkg/service/v0/service.go
index e75fdac2404..93673f52701 100644
--- a/services/settings/pkg/service/v0/service.go
+++ b/services/settings/pkg/service/v0/service.go
@@ -51,6 +51,8 @@ func NewService(cfg *config.Config, logger log.Logger) Service {
 	return service
 }
 
+// CheckPermission implements the CS3 API Permssions service.
+// It's used to check if a subject (user or group) has a permission.
 func (g Service) CheckPermission(ctx context.Context, req *permissions.CheckPermissionRequest) (*permissions.CheckPermissionResponse, error) {
 	spec := req.SubjectRef.Spec
 
@@ -390,13 +392,13 @@ func (g Service) ListRoleAssignments(ctx context.Context, req *settingssvc.ListR
 
 // AssignRoleToUser implements the RoleServiceHandler interface
 func (g Service) AssignRoleToUser(ctx context.Context, req *settingssvc.AssignRoleToUserRequest, res *settingssvc.AssignRoleToUserResponse) error {
-	if err := g.checkStaticPermissionsByBundleType(ctx, settingsmsg.Bundle_TYPE_ROLE); err != nil {
-		return err
+	if !g.canManageRoles(ctx) {
+		return merrors.Forbidden(g.id, "user has no role management permission")
 	}
 
 	req.AccountUuid = getValidatedAccountUUID(ctx, req.AccountUuid)
 	if validationError := validateAssignRoleToUser(req); validationError != nil {
-		return merrors.BadRequest(g.id, "%s", validationError)
+		return merrors.BadRequest(g.id, validationError.Error())
 	}
 
 	ownAccountUUID, ok := metadata.Get(ctx, middleware.AccountID)
@@ -406,12 +408,12 @@ func (g Service) AssignRoleToUser(ctx context.Context, req *settingssvc.AssignRo
 	}
 	if ownAccountUUID == req.AccountUuid {
 		g.logger.Debug().Str("id", g.id).Msg("Changing own role assignment forbidden")
-		return merrors.Forbidden(g.id, "%s", "Changing own role assignment forbidden")
+		return merrors.Forbidden(g.id, "Changing own role assignment forbidden")
 	}
 
 	r, err := g.manager.WriteRoleAssignment(req.AccountUuid, req.RoleId)
 	if err != nil {
-		return merrors.BadRequest(g.id, "%s", err)
+		return merrors.BadRequest(g.id, err.Error())
 	}
 	res.Assignment = r
 	return nil
@@ -419,8 +421,12 @@ func (g Service) AssignRoleToUser(ctx context.Context, req *settingssvc.AssignRo
 
 // RemoveRoleFromUser implements the RoleServiceHandler interface
 func (g Service) RemoveRoleFromUser(ctx context.Context, req *settingssvc.RemoveRoleFromUserRequest, _ *emptypb.Empty) error {
-	if err := g.checkStaticPermissionsByBundleType(ctx, settingsmsg.Bundle_TYPE_ROLE); err != nil {
-		return err
+	if !g.canManageRoles(ctx) {
+		return merrors.Forbidden(g.id, "user has no role management permission")
+	}
+
+	if validationError := validateRemoveRoleFromUser(req); validationError != nil {
+		return merrors.BadRequest(g.id, validationError.Error())
 	}
 
 	ownAccountUUID, ok := metadata.Get(ctx, middleware.AccountID)
@@ -432,22 +438,18 @@ func (g Service) RemoveRoleFromUser(ctx context.Context, req *settingssvc.Remove
 	al, err := g.manager.ListRoleAssignments(ownAccountUUID)
 	if err != nil {
 		g.logger.Debug().Err(err).Str("id", g.id).Msg("ListRoleAssignments failed")
-		return merrors.InternalServerError(g.id, "%s", err)
+		return merrors.InternalServerError(g.id, err.Error())
 	}
 
 	for _, a := range al {
 		if a.Id == req.Id {
 			g.logger.Debug().Str("id", g.id).Msg("Removing own role assignment forbidden")
-			return merrors.Forbidden(g.id, "%s", "Removing own role assignment forbidden")
+			return merrors.Forbidden(g.id, "Removing own role assignment forbidden")
 		}
 	}
 
-	if validationError := validateRemoveRoleFromUser(req); validationError != nil {
-		return merrors.BadRequest(g.id, "%s", validationError)
-	}
-
 	if err := g.manager.RemoveRoleAssignment(req.Id); err != nil {
-		return merrors.BadRequest(g.id, "%s", err)
+		return merrors.BadRequest(g.id, err.Error())
 	}
 	return nil
 }
@@ -547,16 +549,24 @@ func (g Service) getValueWithIdentifier(value *settingsmsg.Value) (*settingsmsg.
 func (g Service) hasStaticPermission(ctx context.Context, permissionID string) bool {
 	roleIDs, ok := roles.ReadRoleIDsFromContext(ctx)
 	if !ok {
-		/**
-		* FIXME: with this we are skipping permission checks on all requests that are coming in without roleIDs in the
-		* metadata context. This is a huge security impairment, as that's the case not only for grpc requests but also
-		* for unauthenticated http requests and http requests coming in without hitting the ocis-proxy first.
-		 */
 		// TODO add system role for internal requests.
 		// - at least the proxy needs to look up account info
 		// - glauth needs to make bind requests
 		// tracked as OCIS-454
-		return true
+
+		accountID, ok := metadata.Get(ctx, middleware.AccountID)
+		if !ok {
+			return false
+		}
+		assignments, err := g.manager.ListRoleAssignments(accountID)
+		if err != nil {
+			return false
+		}
+
+		roleIDs = make([]string, 0, len(assignments))
+		for _, a := range assignments {
+			roleIDs = append(roleIDs, a.GetRoleId())
+		}
 	}
 	p, err := g.manager.ReadPermissionByID(permissionID, roleIDs)
 	return err == nil && p != nil
@@ -590,3 +600,7 @@ func (g Service) isCurrentUser(ctx context.Context, accountID string) bool {
 	}
 	return accountID == ownAccountID
 }
+
+func (g Service) canManageRoles(ctx context.Context) bool {
+	return g.hasStaticPermission(ctx, RoleManagementPermissionID)
+}
diff --git a/services/users/pkg/config/config.go b/services/users/pkg/config/config.go
index f109c43737d..8591124379a 100644
--- a/services/users/pkg/config/config.go
+++ b/services/users/pkg/config/config.go
@@ -20,7 +20,7 @@ type Config struct {
 
 	SkipUserGroupsInToken bool `yaml:"skip_user_groups_in_token" env:"USERS_SKIP_USER_GROUPS_IN_TOKEN" desc:"Disables the loading of user's group memberships from the reva access token."`
 
-	Driver  string  `yaml:"driver" env:"USERS_DRIVER" desc:"The user driver which should be used by the users service. Supported values are 'ldap', 'owncloudsql', 'json' and 'rest'."`
+	Driver  string  `yaml:"driver" env:"USERS_DRIVER" desc:"The driver which should be used by the users service. Supported values are 'ldap' and 'owncloudsql'."`
 	Drivers Drivers `yaml:"drivers"`
 
 	Supervised bool            `yaml:"-"`


Test patch:
diff --git a/services/search/pkg/search/provider/events_test.go b/services/search/pkg/search/provider/events_test.go
index 73ca2a17c78..9e3275acf75 100644
--- a/services/search/pkg/search/provider/events_test.go
+++ b/services/search/pkg/search/provider/events_test.go
@@ -84,7 +84,7 @@ var _ = Describe("Searchprovider", func() {
 
 	Describe("New", func() {
 		It("returns a new instance", func() {
-			p = provider.New(gwClient, indexClient, "", eventsChan, logger)
+			p = provider.New(gwClient, indexClient, "", eventsChan, 1000, logger)
 			Expect(p).ToNot(BeNil())
 		})
 	})
diff --git a/services/search/pkg/search/provider/searchprovider_test.go b/services/search/pkg/search/provider/searchprovider_test.go
index 58439198763..aac1d7a85f3 100644
--- a/services/search/pkg/search/provider/searchprovider_test.go
+++ b/services/search/pkg/search/provider/searchprovider_test.go
@@ -73,7 +73,7 @@ var _ = Describe("Searchprovider", func() {
 		gwClient = &cs3mocks.GatewayAPIClient{}
 		indexClient = &mocks.IndexClient{}
 
-		p = provider.New(gwClient, indexClient, "", eventsChan, logger)
+		p = provider.New(gwClient, indexClient, "", eventsChan, 1000, logger)
 
 		gwClient.On("Authenticate", mock.Anything, mock.Anything).Return(&gateway.AuthenticateResponse{
 			Status: status.NewOK(ctx),
@@ -94,7 +94,7 @@ var _ = Describe("Searchprovider", func() {
 
 	Describe("New", func() {
 		It("returns a new instance", func() {
-			p := provider.New(gwClient, indexClient, "", eventsChan, logger)
+			p := provider.New(gwClient, indexClient, "", eventsChan, 1000, logger)
 			Expect(p).ToNot(BeNil())
 		})
 	})
diff --git a/services/settings/pkg/service/v0/service_test.go b/services/settings/pkg/service/v0/service_test.go
index eb93ad33cf7..d7536648086 100644
--- a/services/settings/pkg/service/v0/service_test.go
+++ b/services/settings/pkg/service/v0/service_test.go
@@ -66,6 +66,19 @@ func TestGetValidatedAccountUUID(t *testing.T) {
 
 func TestEditOwnRoleAssignment(t *testing.T) {
 	manager := &mocks.Manager{}
+	a := []*settingsmsg.UserRoleAssignment{
+		{
+			Id:          "00000000-0000-0000-0000-000000000001",
+			AccountUuid: "61445573-4dbe-4d56-88dc-88ab47aceba7",
+			RoleId:      "aceb15b8-7486-479f-ae32-c91118e07a39",
+		},
+	}
+	editRolePermission := &settingsmsg.Permission{
+		Operation:  settingsmsg.Permission_OPERATION_READWRITE,
+		Constraint: settingsmsg.Permission_CONSTRAINT_ALL,
+	}
+	manager.On("ListRoleAssignments", mock.Anything).Return(a, nil)
+	manager.On("ReadPermissionByID", mock.Anything, mock.Anything).Return(editRolePermission, nil)
 	svc := Service{
 		manager: manager,
 	}
@@ -99,6 +112,11 @@ func TestRemoveOwnRoleAssignment(t *testing.T) {
 			RoleId:      "aceb15b8-7486-479f-ae32-c91118e07a39",
 		},
 	}
+	editRolePermission := &settingsmsg.Permission{
+		Operation:  settingsmsg.Permission_OPERATION_READWRITE,
+		Constraint: settingsmsg.Permission_CONSTRAINT_ALL,
+	}
+	manager.On("ReadPermissionByID", mock.Anything, mock.Anything).Return(editRolePermission, nil)
 	manager.On("ListRoleAssignments", mock.Anything).Return(a, nil)
 	svc := Service{
 		manager: manager,
@@ -114,6 +132,7 @@ func TestRemoveOwnRoleAssignment(t *testing.T) {
 	manager = &mocks.Manager{}
 	manager.On("ListRoleAssignments", mock.Anything).Return(nil, nil)
 	manager.On("RemoveRoleAssignment", mock.Anything).Return(nil)
+	manager.On("ReadPermissionByID", mock.Anything, mock.Anything).Return(editRolePermission, nil)
 	svc = Service{
 		manager: manager,
 	}