Repository: owncloud/ocis
Pull request #8898 (2024-04-19 06:25:12)

build(deps): bump github.com/onsi/gomega from 1.32.0 to 1.33.0
Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.32.0 to 1.33.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/onsi/gomega/releases">github.com/onsi/gomega's releases</a>.</em></p>
<blockquote>
<h2>v1.33.0</h2>
<h2>1.33.0</h2>
<h3>Features</h3>
<p><code>Receive</code> not accepts <code>Receive(&lt;POINTER&gt;, MATCHER&gt;)</code>, allowing you to pick out a specific value on the channel that satisfies the provided matcher and is stored in the provided pointer.</p>
<h3>Maintenance</h3>
<ul>
<li>Bump github.com/onsi/ginkgo/v2 from 2.15.0 to 2.17.1 (<a href="https://redirect.github.com/onsi/gomega/issues/745">#745</a>) [9999deb]</li>
<li>Bump github-pages from 229 to 230 in /docs (<a href="https://redirect.github.com/onsi/gomega/issues/735">#735</a>) [cb5ff21]</li>
<li>Bump golang.org/x/net from 0.20.0 to 0.23.0 (<a href="https://redirect.github.com/onsi/gomega/issues/746">#746</a>) [bac6596]</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a href="https://github.com/onsi/gomega/blob/master/CHANGELOG.md">github.com/onsi/gomega's changelog</a>.</em></p>
<blockquote>
<h2>1.33.0</h2>
<h3>Features</h3>
<p><code>Receive</code> not accepts <code>Receive(&lt;POINTER&gt;, MATCHER&gt;)</code>, allowing you to pick out a specific value on the channel that satisfies the provided matcher and is stored in the provided pointer.</p>
<h3>Maintenance</h3>
<ul>
<li>Bump github.com/onsi/ginkgo/v2 from 2.15.0 to 2.17.1 (<a href="https://redirect.github.com/onsi/gomega/issues/745">#745</a>) [9999deb]</li>
<li>Bump github-pages from 229 to 230 in /docs (<a href="https://redirect.github.com/onsi/gomega/issues/735">#735</a>) [cb5ff21]</li>
<li>Bump golang.org/x/net from 0.20.0 to 0.23.0 (<a href="https://redirect.github.com/onsi/gomega/issues/746">#746</a>) [bac6596]</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/onsi/gomega/commit/f2e65fc89a9236e471ae9832a3e91cc17642ec16"><code>f2e65fc</code></a> v1.33.0</li>
<li><a href="https://github.com/onsi/gomega/commit/02e8706354ce9b25c178f841102f76dca6479326"><code>02e8706</code></a> docs: Receive(POINTER, MATCHER)</li>
<li><a href="https://github.com/onsi/gomega/commit/ec1f186861bc4fcbe3f2cdb2a1442f81a710ec3e"><code>ec1f186</code></a> feat: receiver matcher accepting (POINTER, MATCHER), includes unit tests</li>
<li><a href="https://github.com/onsi/gomega/commit/9999deb756cb1bf51c547f39ac475ee571e4e056"><code>9999deb</code></a> Bump github.com/onsi/ginkgo/v2 from 2.15.0 to 2.17.1 (<a href="https://redirect.github.com/onsi/gomega/issues/745">#745</a>)</li>
<li><a href="https://github.com/onsi/gomega/commit/cb5ff21fc5bb9d0bdfd104474da0094d219f5535"><code>cb5ff21</code></a> Bump github-pages from 229 to 230 in /docs (<a href="https://redirect.github.com/onsi/gomega/issues/735">#735</a>)</li>
<li><a href="https://github.com/onsi/gomega/commit/bac65967dba1b39bf760d42d2ffdee7d2ee567c6"><code>bac6596</code></a> Bump golang.org/x/net from 0.20.0 to 0.23.0 (<a href="https://redirect.github.com/onsi/gomega/issues/746">#746</a>)</li>
<li>See full diff in <a href="https://github.com/onsi/gomega/compare/v1.32.0...v1.33.0">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/onsi/gomega&package-manager=go_modules&previous-version=1.32.0&new-version=1.33.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 show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency
- `@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>


Patch:
diff --git a/.drone.star b/.drone.star
index 8a1b363b507..7d1d8cd1b5a 100644
--- a/.drone.star
+++ b/.drone.star
@@ -33,7 +33,7 @@ REDIS = "redis:6-alpine"
 SELENIUM_STANDALONE_CHROME = "selenium/standalone-chrome:104.0-20220812"
 SONARSOURCE_SONAR_SCANNER_CLI = "sonarsource/sonar-scanner-cli:5.0"
 
-DEFAULT_PHP_VERSION = "7.4"
+DEFAULT_PHP_VERSION = "8.2"
 DEFAULT_NODEJS_VERSION = "18"
 
 dirs = {
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 231416f142f..e8336c9894f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -66,6 +66,7 @@ The following sections list the changes for unreleased.
 * Bugfix - Fix unmount item from share: [#8827](https://github.com/owncloud/ocis/pull/8827)
 * Bugfix - Fix creating new WOPI documents on public shares: [#8828](https://github.com/owncloud/ocis/pull/8828)
 * Bugfix - Nats reconnects: [#8880](https://github.com/owncloud/ocis/pull/8880)
+* Bugfix - Update the admin user role assignment to enforce the config: [#8897](https://github.com/owncloud/ocis/pull/8897)
 * Change - Change the default store for presigned keys to nats-js-kv: [#8419](https://github.com/owncloud/ocis/pull/8419)
 * Change - Disable resharing by default for deprecation: [#8653](https://github.com/owncloud/ocis/pull/8653)
 * Enhancement - Introduce staticroutes package & remove well-known OIDC middleware: [#6095](https://github.com/owncloud/ocis/issues/6095)
@@ -89,6 +90,7 @@ The following sections list the changes for unreleased.
 * Enhancement - Bump Reva: [#8795](https://github.com/owncloud/ocis/pull/8795)
 * Enhancement - Sharing SSEs: [#8854](https://github.com/owncloud/ocis/pull/8854)
 * Enhancement - Update web to v9.0.0-alpha.5: [#8868](https://github.com/owncloud/ocis/pull/8868)
+* Enhancement - Add Link SSEs: [#8908](https://github.com/owncloud/ocis/pull/8908)
 
 ## Details
 
@@ -252,6 +254,16 @@ The following sections list the changes for unreleased.
 
    https://github.com/owncloud/ocis/pull/8880
 
+* Bugfix - Update the admin user role assignment to enforce the config: [#8897](https://github.com/owncloud/ocis/pull/8897)
+
+   The admin user role assigment was not updated after the first assignment. We now
+   read the assigned role during init and update the admin user ID accordingly if
+   the role is not assigned. This is especially needed when the OCIS_ADMIN_USER_ID
+   is set after the autoprovisioning of the admin user when it originates from an
+   external Identity Provider.
+
+   https://github.com/owncloud/ocis/pull/8897
+
 * Change - Change the default store for presigned keys to nats-js-kv: [#8419](https://github.com/owncloud/ocis/pull/8419)
 
    We wrapped the store service in a micro store implementation and changed the
@@ -507,6 +519,12 @@ The following sections list the changes for unreleased.
    https://github.com/owncloud/ocis/pull/8868
    https://github.com/owncloud/web/releases/tag/v9.0.0-alpha.5
 
+* Enhancement - Add Link SSEs: [#8908](https://github.com/owncloud/ocis/pull/8908)
+
+   Add sses for link created/updated/removed.
+
+   https://github.com/owncloud/ocis/pull/8908
+
 # Changelog for [5.0.2] (2024-04-17)
 
 The following sections list the changes for 5.0.2.
diff --git a/changelog/unreleased/fix-admin-role-assignment.md b/changelog/unreleased/fix-admin-role-assignment.md
new file mode 100644
index 00000000000..25b2cc84d51
--- /dev/null
+++ b/changelog/unreleased/fix-admin-role-assignment.md
@@ -0,0 +1,6 @@
+Bugfix: Update the admin user role assignment to enforce the config
+
+The admin user role assigment was not updated after the first assignment. We now read the assigned role during init and update the admin user ID accordingly if the role is not assigned.
+This is especially needed when the OCIS_ADMIN_USER_ID is set after the autoprovisioning of the admin user when it originates from an external Identity Provider.
+
+https://github.com/owncloud/ocis/pull/8897
diff --git a/changelog/unreleased/link-sses.md b/changelog/unreleased/link-sses.md
new file mode 100644
index 00000000000..6ac8fbb3d06
--- /dev/null
+++ b/changelog/unreleased/link-sses.md
@@ -0,0 +1,5 @@
+Enhancement: Add Link SSEs
+
+Add sses for link created/updated/removed.
+
+https://github.com/owncloud/ocis/pull/8908
diff --git a/composer.json b/composer.json
index cde88424690..19b11d6d5a5 100644
--- a/composer.json
+++ b/composer.json
@@ -2,7 +2,7 @@
   "name": "owncloud/ocis",
   "config" : {
     "platform": {
-      "php": "7.4"
+      "php": "8.2"
     },
     "vendor-dir": "./vendor-php",
     "allow-plugins": {
diff --git a/go.mod b/go.mod
index b9eeef95b6c..c0b949de377 100644
--- a/go.mod
+++ b/go.mod
@@ -14,7 +14,7 @@ require (
 	github.com/cenkalti/backoff v2.2.1+incompatible
 	github.com/coreos/go-oidc/v3 v3.10.0
 	github.com/cs3org/go-cs3apis v0.0.0-20231023073225-7748710e0781
-	github.com/cs3org/reva/v2 v2.19.2-0.20240416121921-56d2be7011cf
+	github.com/cs3org/reva/v2 v2.19.2-0.20240419134937-8a636c82c1cf
 	github.com/dhowden/tag v0.0.0-20230630033851-978a0926ee25
 	github.com/disintegration/imaging v1.6.2
 	github.com/dutchcoders/go-clamd v0.0.0-20170520113014-b970184f4d9e
@@ -66,8 +66,8 @@ require (
 	github.com/oklog/run v1.1.0
 	github.com/olekukonko/tablewriter v0.0.5
 	github.com/onsi/ginkgo v1.16.5
-	github.com/onsi/ginkgo/v2 v2.17.0
-	github.com/onsi/gomega v1.32.0
+	github.com/onsi/ginkgo/v2 v2.17.1
+	github.com/onsi/gomega v1.33.0
 	github.com/open-policy-agent/opa v0.62.1
 	github.com/orcaman/concurrent-map v1.0.0
 	github.com/owncloud/libre-graph-api-go v1.0.5-0.20240130152355-ac663a9002a1
diff --git a/go.sum b/go.sum
index e4b954d4f2c..c6b04b2f52b 100644
--- a/go.sum
+++ b/go.sum
@@ -1022,8 +1022,8 @@ github.com/crewjam/saml v0.4.14 h1:g9FBNx62osKusnFzs3QTN5L9CVA/Egfgm+stJShzw/c=
 github.com/crewjam/saml v0.4.14/go.mod h1:UVSZCf18jJkk6GpWNVqcyQJMD5HsRugBPf4I1nl2mME=
 github.com/cs3org/go-cs3apis v0.0.0-20231023073225-7748710e0781 h1:BUdwkIlf8IS2FasrrPg8gGPHQPOrQ18MS1Oew2tmGtY=
 github.com/cs3org/go-cs3apis v0.0.0-20231023073225-7748710e0781/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY=
-github.com/cs3org/reva/v2 v2.19.2-0.20240416121921-56d2be7011cf h1:RSuahP/PhMCVB/SHCkiXolJ8xGvGKjkhINcda21A+gY=
-github.com/cs3org/reva/v2 v2.19.2-0.20240416121921-56d2be7011cf/go.mod h1:GRUrOp5HbFVwZTgR9bVrMZ/MvVy+Jhxw1PdMmhhKP9E=
+github.com/cs3org/reva/v2 v2.19.2-0.20240419134937-8a636c82c1cf h1:MCXXZKR3fj2ZCaEPQ3l3cpR4q/TmVaaPbgKUB2hhCvo=
+github.com/cs3org/reva/v2 v2.19.2-0.20240419134937-8a636c82c1cf/go.mod h1:GRUrOp5HbFVwZTgR9bVrMZ/MvVy+Jhxw1PdMmhhKP9E=
 github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4=
 github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
 github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
@@ -1782,13 +1782,13 @@ github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W
 github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
 github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
 github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
-github.com/onsi/ginkgo/v2 v2.17.0 h1:kdnunFXpBjbzN56hcJHrXZ8M+LOkenKA7NnBzTNigTI=
-github.com/onsi/ginkgo/v2 v2.17.0/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs=
+github.com/onsi/ginkgo/v2 v2.17.1 h1:V++EzdbhI4ZV4ev0UTIj0PzhzOcReJFyJaLjtSF55M8=
+github.com/onsi/ginkgo/v2 v2.17.1/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs=
 github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
 github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
 github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
-github.com/onsi/gomega v1.32.0 h1:JRYU78fJ1LPxlckP6Txi/EYqJvjtMrDC04/MM5XRHPk=
-github.com/onsi/gomega v1.32.0/go.mod h1:a4x4gW6Pz2yK1MAmvluYme5lvYTn61afQ2ETw/8n4Lg=
+github.com/onsi/gomega v1.33.0 h1:snPCflnZrpMsy94p4lXVEkHo12lmPnc3vY5XBbreexE=
+github.com/onsi/gomega v1.33.0/go.mod h1:+925n5YtiFsLzzafLUHzVMBpvvRAzrydIBiSIxjX3wY=
 github.com/open-policy-agent/opa v0.62.1 h1:UcxBQ0fe6NEjkYc775j4PWoUFFhx4f6yXKIKSTAuTVk=
 github.com/open-policy-agent/opa v0.62.1/go.mod h1:YqiSIIuvKwyomtnnXkJvy0E3KtVKbavjPJ/hNMuOmeM=
 github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg=
diff --git a/services/clientlog/pkg/command/server.go b/services/clientlog/pkg/command/server.go
index 7c41e7a36e5..0723a7485a8 100644
--- a/services/clientlog/pkg/command/server.go
+++ b/services/clientlog/pkg/command/server.go
@@ -39,6 +39,9 @@ var _registeredEvents = []events.Unmarshaller{
 	events.ShareCreated{},
 	events.ShareRemoved{},
 	events.ShareUpdated{},
+	events.LinkCreated{},
+	events.LinkUpdated{},
+	events.LinkRemoved{},
 }
 
 // Server is the entrypoint for the server command.
diff --git a/services/clientlog/pkg/service/service.go b/services/clientlog/pkg/service/service.go
index 841b13e3f49..70341aa30f3 100644
--- a/services/clientlog/pkg/service/service.go
+++ b/services/clientlog/pkg/service/service.go
@@ -177,6 +177,12 @@ func (cl *ClientlogService) processEvent(event events.Event) {
 	case events.ShareRemoved:
 		p("share-removed", &provider.Reference{ResourceId: e.ItemID})
 		users, err = addSharees(ctx, users, gwc, e.GranteeUserID, e.GranteeGroupID)
+	case events.LinkCreated:
+		p("link-created", &provider.Reference{ResourceId: e.ItemID})
+	case events.LinkUpdated:
+		p("link-updated", &provider.Reference{ResourceId: e.ItemID})
+	case events.LinkRemoved:
+		p("link-removed", &provider.Reference{ResourceId: e.ItemID})
 	}
 
 	if err != nil {
diff --git a/services/settings/pkg/store/metadata/store.go b/services/settings/pkg/store/metadata/store.go
index 68946a3a80d..3985e84a1d4 100644
--- a/services/settings/pkg/store/metadata/store.go
+++ b/services/settings/pkg/store/metadata/store.go
@@ -7,6 +7,7 @@ import (
 	"log"
 	"sync"
 
+	"github.com/cs3org/reva/v2/pkg/errtypes"
 	"github.com/cs3org/reva/v2/pkg/storage/utils/metadata"
 	"github.com/gofrs/uuid"
 	olog "github.com/owncloud/ocis/v2/ocis-pkg/log"
@@ -139,10 +140,20 @@ func (s *Store) initMetadataClient(mdc MetadataClient) error {
 		if err != nil {
 			return err
 		}
-		if len(assIDs) > 0 {
+
+		adminUserID := accountUUID == s.cfg.AdminUserID
+		if len(assIDs) > 0 && !adminUserID {
 			// There is already a role assignment for this ID, skip to the next
 			continue
 		}
+		// for the adminUserID we need to check if the user has the admin role every time
+		if adminUserID {
+			err = s.userMustHaveAdminRole(accountUUID, assIDs, mdc)
+			if err != nil {
+				return err
+			}
+			continue
+		}
 
 		ass := &settingsmsg.UserRoleAssignment{
 			Id:          uuid.Must(uuid.NewV4()).String(),
@@ -164,6 +175,64 @@ func (s *Store) initMetadataClient(mdc MetadataClient) error {
 	return nil
 }
 
+func (s *Store) userMustHaveAdminRole(accountUUID string, assIDs []string, mdc MetadataClient) error {
+	ctx := context.TODO()
+	var hasAdminRole bool
+
+	// load the assignments from the store and check if the admin role is already assigned
+	for _, assID := range assIDs {
+		b, err := mdc.SimpleDownload(ctx, assignmentPath(accountUUID, assID))
+		switch err.(type) {
+		case nil:
+			// continue
+		case errtypes.NotFound:
+			continue
+		default:
+			return err
+		}
+
+		a := &settingsmsg.UserRoleAssignment{}
+		err = json.Unmarshal(b, a)
+		if err != nil {
+			return err
+		}
+
+		if a.RoleId == defaults.BundleUUIDRoleAdmin {
+			hasAdminRole = true
+		}
+	}
+
+	// delete old role assignment and set admin role
+	if !hasAdminRole {
+		err := mdc.Delete(ctx, accountPath(accountUUID))
+		switch err.(type) {
+		case nil:
+			// continue
+		case errtypes.NotFound:
+			// already gone, continue
+		default:
+			return err
+		}
+
+		err = mdc.MakeDirIfNotExist(ctx, accountPath(accountUUID))
+		if err != nil {
+			return err
+		}
+
+		ass := &settingsmsg.UserRoleAssignment{
+			Id:          uuid.Must(uuid.NewV4()).String(),
+			AccountUuid: accountUUID,
+			RoleId:      defaults.BundleUUIDRoleAdmin,
+		}
+		b, err := json.Marshal(ass)
+		if err != nil {
+			return err
+		}
+		return mdc.SimpleUpload(ctx, assignmentPath(accountUUID, ass.Id), b)
+	}
+	return nil
+}
+
 func init() {
 	settings.Registry[managerName] = New
 }
diff --git a/vendor-bin/behat/composer.json b/vendor-bin/behat/composer.json
index 0192865a4d7..07344d2cc5e 100644
--- a/vendor-bin/behat/composer.json
+++ b/vendor-bin/behat/composer.json
@@ -1,7 +1,7 @@
 {
     "config" : {
       "platform": {
-        "php": "7.4"
+        "php": "8.2"
       },
         "allow-plugins": {
             "composer/package-versions-deprecated": true
diff --git a/vendor/github.com/cs3org/reva/v2/internal/grpc/interceptors/eventsmiddleware/conversion.go b/vendor/github.com/cs3org/reva/v2/internal/grpc/interceptors/eventsmiddleware/conversion.go
index 1a123f1ca9a..87ee14af578 100644
--- a/vendor/github.com/cs3org/reva/v2/internal/grpc/interceptors/eventsmiddleware/conversion.go
+++ b/vendor/github.com/cs3org/reva/v2/internal/grpc/interceptors/eventsmiddleware/conversion.go
@@ -179,11 +179,14 @@ func LinkAccessFailed(r *link.GetPublicShareByTokenResponse, req *link.GetPublic
 
 // LinkRemoved converts the response to an event
 func LinkRemoved(r *link.RemovePublicShareResponse, req *link.RemovePublicShareRequest, executant *user.UserId) events.LinkRemoved {
+	var rid *provider.ResourceId
+	_ = utils.ReadJSONFromOpaque(r.Opaque, "resourceid", &rid)
 	return events.LinkRemoved{
 		Executant:  executant,
 		ShareID:    req.Ref.GetId(),
 		ShareToken: req.Ref.GetToken(),
 		Timestamp:  utils.TSNow(),
+		ItemID:     rid,
 	}
 }
 
diff --git a/vendor/github.com/cs3org/reva/v2/internal/grpc/services/gateway/storageprovider.go b/vendor/github.com/cs3org/reva/v2/internal/grpc/services/gateway/storageprovider.go
index 781295963da..1541fff8745 100644
--- a/vendor/github.com/cs3org/reva/v2/internal/grpc/services/gateway/storageprovider.go
+++ b/vendor/github.com/cs3org/reva/v2/internal/grpc/services/gateway/storageprovider.go
@@ -250,14 +250,14 @@ func (s *svc) ListStorageSpaces(ctx context.Context, req *provider.ListStorageSp
 	for _, f := range req.Filters {
 		switch f.Type {
 		case provider.ListStorageSpacesRequest_Filter_TYPE_ID:
-			sid, spid, oid, err := storagespace.SplitID(f.GetId().OpaqueId)
+			sid, spid, oid, err := storagespace.SplitID(f.GetId().GetOpaqueId())
 			if err != nil {
 				continue
 			}
 			filters["storage_id"], filters["space_id"], filters["opaque_id"] = sid, spid, oid
 		case provider.ListStorageSpacesRequest_Filter_TYPE_OWNER:
-			filters["owner_idp"] = f.GetOwner().Idp
-			filters["owner_id"] = f.GetOwner().OpaqueId
+			filters["owner_idp"] = f.GetOwner().GetIdp()
+			filters["owner_id"] = f.GetOwner().GetOpaqueId()
 		case provider.ListStorageSpacesRequest_Filter_TYPE_SPACE_TYPE:
 			filters["space_type"] = f.GetSpaceType()
 		case provider.ListStorageSpacesRequest_Filter_TYPE_USER:
@@ -339,7 +339,7 @@ func (s *svc) DeleteStorageSpace(ctx context.Context, req *provider.DeleteStorag
 		_, purge = opaque.Map["purge"]
 	}
 
-	rid, err := storagespace.ParseID(req.Id.OpaqueId)
+	rid, err := storagespace.ParseID(req.GetId().GetOpaqueId())
 	if err != nil {
 		return &provider.DeleteStorageSpaceResponse{
 			Status: status.NewStatusFromErrType(ctx, fmt.Sprintf("gateway could not parse space id %s", req.GetId().GetOpaqueId()), err),
@@ -361,7 +361,7 @@ func (s *svc) DeleteStorageSpace(ctx context.Context, req *provider.DeleteStorag
 		}, nil
 	}
 
-	id := &provider.ResourceId{OpaqueId: req.Id.OpaqueId}
+	id := &provider.ResourceId{OpaqueId: req.GetId().GetOpaqueId()}
 	s.providerCache.RemoveListStorageProviders(id)
 
 	if dsRes.Status.Code != rpc.Code_CODE_OK {
@@ -1221,11 +1221,11 @@ func unwrap(ref *provider.Reference, mountPoint string, root *provider.ResourceI
 
 	return &provider.Reference{
 		ResourceId: &provider.ResourceId{
-			StorageId: ref.ResourceId.StorageId,
-			SpaceId:   ref.ResourceId.SpaceId,
-			OpaqueId:  ref.ResourceId.OpaqueId,
+			StorageId: ref.GetResourceId().GetStorageId(),
+			SpaceId:   ref.GetResourceId().GetSpaceId(),
+			OpaqueId:  ref.GetResourceId().GetOpaqueId(),
 		},
-		Path: ref.Path,
+		Path: ref.GetPath(),
 	}
 }
 
diff --git a/vendor/github.com/cs3org/reva/v2/internal/grpc/services/gateway/usershareprovider.go b/vendor/github.com/cs3org/reva/v2/internal/grpc/services/gateway/usershareprovider.go
index fb3057638f4..25a1a2965d4 100644
--- a/vendor/github.com/cs3org/reva/v2/internal/grpc/services/gateway/usershareprovider.go
+++ b/vendor/github.com/cs3org/reva/v2/internal/grpc/services/gateway/usershareprovider.go
@@ -45,9 +45,9 @@ func (s *svc) CreateShare(ctx context.Context, req *collaboration.CreateShareReq
 }
 
 func (s *svc) RemoveShare(ctx context.Context, req *collaboration.RemoveShareRequest) (*collaboration.RemoveShareResponse, error) {
-	key := req.Ref.GetKey()
+	key := req.GetRef().GetKey()
 	if !s.c.UseCommonSpaceRootShareLogic && shareIsSpaceRoot(key) {
-		return s.removeSpaceShare(ctx, key.ResourceId, key.Grantee)
+		return s.removeSpaceShare(ctx, key.GetResourceId(), key.GetGrantee())
 	}
 	return s.removeShare(ctx, req)
 }
@@ -149,7 +149,7 @@ func (s *svc) updateShare(ctx context.Context, req *collaboration.UpdateShareReq
 		if updateGrantStatus.Code != rpc.Code_CODE_OK {
 			return &collaboration.UpdateShareResponse{
 				Status: updateGrantStatus,
-				Share:  res.Share,
+				Share:  res.GetShare(),
 			}, nil
 		}
 	}
@@ -835,11 +835,11 @@ func isEqualGrantee(a, b *provider.Grantee) bool {
 	var aID, bID string
 	switch a.Type {
 	case provider.GranteeType_GRANTEE_TYPE_GROUP:
-		aID = a.GetGroupId().OpaqueId
-		bID = b.GetGroupId().OpaqueId
+		aID = a.GetGroupId().GetOpaqueId()
+		bID = b.GetGroupId().GetOpaqueId()
 	case provider.GranteeType_GRANTEE_TYPE_USER:
-		aID = a.GetUserId().OpaqueId
-		bID = b.GetUserId().OpaqueId
+		aID = a.GetUserId().GetOpaqueId()
+		bID = b.GetUserId().GetOpaqueId()
 	}
 	return aID == bID
 }
diff --git a/vendor/github.com/cs3org/reva/v2/internal/grpc/services/publicshareprovider/publicshareprovider.go b/vendor/github.com/cs3org/reva/v2/internal/grpc/services/publicshareprovider/publicshareprovider.go
index 4879d7caf43..0c740f3668c 100644
--- a/vendor/github.com/cs3org/reva/v2/internal/grpc/services/publicshareprovider/publicshareprovider.go
+++ b/vendor/github.com/cs3org/reva/v2/internal/grpc/services/publicshareprovider/publicshareprovider.go
@@ -372,6 +372,7 @@ func (s *service) RemovePublicShare(ctx context.Context, req *link.RemovePublicS
 		}, err
 	}
 	return &link.RemovePublicShareResponse{
+		Opaque: utils.AppendJSONToOpaque(nil, "resourceid", ps.GetResourceId()),
 		Status: status.NewOK(ctx),
 	}, nil
 }
diff --git a/vendor/github.com/cs3org/reva/v2/pkg/events/sharing.go b/vendor/github.com/cs3org/reva/v2/pkg/events/sharing.go
index 77c7f04bedb..6c438d5dbad 100644
--- a/vendor/github.com/cs3org/reva/v2/pkg/events/sharing.go
+++ b/vendor/github.com/cs3org/reva/v2/pkg/events/sharing.go
@@ -223,6 +223,7 @@ type LinkRemoved struct {
 	ShareID    *link.PublicShareId
 	ShareToken string
 	Timestamp  *types.Timestamp
+	ItemID     *provider.ResourceId
 }
 
 // Unmarshal to fulfill umarshaller interface
diff --git a/vendor/github.com/onsi/ginkgo/v2/CHANGELOG.md b/vendor/github.com/onsi/ginkgo/v2/CHANGELOG.md
index 57992854b23..44222220a38 100644
--- a/vendor/github.com/onsi/ginkgo/v2/CHANGELOG.md
+++ b/vendor/github.com/onsi/ginkgo/v2/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 2.17.1
+
+### Fixes
+- If the user sets --seed=0, make sure all parallel nodes get the same seed [af0330d]
+
 ## 2.17.0
 
 ### Features
diff --git a/vendor/github.com/onsi/ginkgo/v2/types/config.go b/vendor/github.com/onsi/ginkgo/v2/types/config.go
index 7c82065df10..cef273ee1ff 100644
--- a/vendor/github.com/onsi/ginkgo/v2/types/config.go
+++ b/vendor/github.com/onsi/ginkgo/v2/types/config.go
@@ -265,7 +265,7 @@ var FlagSections = GinkgoFlagSections{
 // SuiteConfigFlags provides flags for the Ginkgo test process, and CLI
 var SuiteConfigFlags = GinkgoFlags{
 	{KeyPath: "S.RandomSeed", Name: "seed", SectionKey: "order", UsageDefaultValue: "randomly generated by Ginkgo",
-		Usage: "The seed used to randomize the spec suite."},
+		Usage: "The seed used to randomize the spec suite.", AlwaysExport: true},
 	{KeyPath: "S.RandomizeAllSpecs", Name: "randomize-all", SectionKey: "order", DeprecatedName: "randomizeAllSpecs", DeprecatedDocLink: "changed-command-line-flags",
 		Usage: "If set, ginkgo will randomize all specs together.  By default, ginkgo only randomizes the top level Describe, Context and When containers."},
 
diff --git a/vendor/github.com/onsi/ginkgo/v2/types/flags.go b/vendor/github.com/onsi/ginkgo/v2/types/flags.go
index 9186ae873d0..de69f3022de 100644
--- a/vendor/github.com/onsi/ginkgo/v2/types/flags.go
+++ b/vendor/github.com/onsi/ginkgo/v2/types/flags.go
@@ -24,7 +24,8 @@ type GinkgoFlag struct {
 	DeprecatedDocLink string
 	DeprecatedVersion string
 
-	ExportAs string
+	ExportAs     string
+	AlwaysExport bool
 }
 
 type GinkgoFlags []GinkgoFlag
@@ -431,7 +432,7 @@ func (ssv stringSliceVar) Set(s string) error {
 	return nil
 }
 
-//given a set of GinkgoFlags and bindings, generate flag arguments suitable to be passed to an application with that set of flags configured.
+// given a set of GinkgoFlags and bindings, generate flag arguments suitable to be passed to an application with that set of flags configured.
 func GenerateFlagArgs(flags GinkgoFlags, bindings interface{}) ([]string, error) {
 	result := []string{}
 	for _, flag := range flags {
@@ -451,19 +452,19 @@ func GenerateFlagArgs(flags GinkgoFlags, bindings interface{}) ([]string, error)
 		iface := value.Interface()
 		switch value.Type() {
 		case reflect.TypeOf(string("")):
-			if iface.(string) != "" {
+			if iface.(string) != "" || flag.AlwaysExport {
 				result = append(result, fmt.Sprintf("--%s=%s", name, iface))
 			}
 		case reflect.TypeOf(int64(0)):
-			if iface.(int64) != 0 {
+			if iface.(int64) != 0 || flag.AlwaysExport {
 				result = append(result, fmt.Sprintf("--%s=%d", name, iface))
 			}
 		case reflect.TypeOf(float64(0)):
-			if iface.(float64) != 0 {
+			if iface.(float64) != 0 || flag.AlwaysExport {
 				result = append(result, fmt.Sprintf("--%s=%f", name, iface))
 			}
 		case reflect.TypeOf(int(0)):
-			if iface.(int) != 0 {
+			if iface.(int) != 0 || flag.AlwaysExport {
 				result = append(result, fmt.Sprintf("--%s=%d", name, iface))
 			}
 		case reflect.TypeOf(bool(true)):
@@ -471,7 +472,7 @@ func GenerateFlagArgs(flags GinkgoFlags, bindings interface{}) ([]string, error)
 				result = append(result, fmt.Sprintf("--%s", name))
 			}
 		case reflect.TypeOf(time.Duration(0)):
-			if iface.(time.Duration) != time.Duration(0) {
+			if iface.(time.Duration) != time.Duration(0) || flag.AlwaysExport {
 				result = append(result, fmt.Sprintf("--%s=%s", name, iface))
 			}
 
diff --git a/vendor/github.com/onsi/ginkgo/v2/types/version.go b/vendor/github.com/onsi/ginkgo/v2/types/version.go
index ccd6516faa1..851d42b456b 100644
--- a/vendor/github.com/onsi/ginkgo/v2/types/version.go
+++ b/vendor/github.com/onsi/ginkgo/v2/types/version.go
@@ -1,3 +1,3 @@
 package types
 
-const VERSION = "2.17.0"
+const VERSION = "2.17.1"
diff --git a/vendor/github.com/onsi/gomega/CHANGELOG.md b/vendor/github.com/onsi/gomega/CHANGELOG.md
index 01ec5245cdc..89230f199d0 100644
--- a/vendor/github.com/onsi/gomega/CHANGELOG.md
+++ b/vendor/github.com/onsi/gomega/CHANGELOG.md
@@ -1,3 +1,14 @@
+## 1.33.0
+
+### Features
+
+`Receive` not accepts `Receive(<POINTER>, MATCHER>)`, allowing you to pick out a specific value on the channel that satisfies the provided matcher and is stored in the provided pointer.
+
+### Maintenance
+- Bump github.com/onsi/ginkgo/v2 from 2.15.0 to 2.17.1 (#745) [9999deb]
+- Bump github-pages from 229 to 230 in /docs (#735) [cb5ff21]
+- Bump golang.org/x/net from 0.20.0 to 0.23.0 (#746) [bac6596]
+
 ## 1.32.0
 
 ### Maintenance
diff --git a/vendor/github.com/onsi/gomega/gomega_dsl.go b/vendor/github.com/onsi/gomega/gomega_dsl.go
index ffb81b1feb3..1980a63c7f1 100644
--- a/vendor/github.com/onsi/gomega/gomega_dsl.go
+++ b/vendor/github.com/onsi/gomega/gomega_dsl.go
@@ -22,7 +22,7 @@ import (
 	"github.com/onsi/gomega/types"
 )
 
-const GOMEGA_VERSION = "1.32.0"
+const GOMEGA_VERSION = "1.33.0"
 
 const nilGomegaPanic = `You are trying to make an assertion, but haven't registered Gomega's fail handler.
 If you're using Ginkgo then you probably forgot to put your assertion in an It().
diff --git a/vendor/github.com/onsi/gomega/matchers.go b/vendor/github.com/onsi/gomega/matchers.go
index 8860d677fc8..7ef27dc9c95 100644
--- a/vendor/github.com/onsi/gomega/matchers.go
+++ b/vendor/github.com/onsi/gomega/matchers.go
@@ -194,20 +194,21 @@ func BeClosed() types.GomegaMatcher {
 //
 // will repeatedly attempt to pull values out of `c` until a value matching "bar" is received.
 //
-// Finally, if you want to have a reference to the value *sent* to the channel you can pass the `Receive` matcher a pointer to a variable of the appropriate type:
+// Furthermore, if you want to have a reference to the value *sent* to the channel you can pass the `Receive` matcher a pointer to a variable of the appropriate type:
 //
 //	var myThing thing
 //	Eventually(thingChan).Should(Receive(&myThing))
 //	Expect(myThing.Sprocket).Should(Equal("foo"))
 //	Expect(myThing.IsValid()).Should(BeTrue())
+//
+// Finally, if you want to match the received object as well as get the actual received value into a variable, so you can reason further about the value received,
+// you can pass a pointer to a variable of the approriate type first, and second a matcher:
+//
+//	var myThing thing
+//	Eventually(thingChan).Should(Receive(&myThing, ContainSubstring("bar")))
 func Receive(args ...interface{}) types.GomegaMatcher {
-	var arg interface{}
-	if len(args) > 0 {
-		arg = args[0]
-	}
-
 	return &matchers.ReceiveMatcher{
-		Arg: arg,
+		Args: args,
 	}
 }
 
diff --git a/vendor/github.com/onsi/gomega/matchers/receive_matcher.go b/vendor/github.com/onsi/gomega/matchers/receive_matcher.go
index 1936a2ba52f..948164eaf88 100644
--- a/vendor/github.com/onsi/gomega/matchers/receive_matcher.go
+++ b/vendor/github.com/onsi/gomega/matchers/receive_matcher.go
@@ -3,6 +3,7 @@
 package matchers
 
 import (
+	"errors"
 	"fmt"
 	"reflect"
 
@@ -10,7 +11,7 @@ import (
 )
 
 type ReceiveMatcher struct {
-	Arg           interface{}
+	Args          []interface{}
 	receivedValue reflect.Value
 	channelClosed bool
 }
@@ -29,15 +30,38 @@ func (matcher *ReceiveMatcher) Match(actual interface{}) (success bool, err erro
 
 	var subMatcher omegaMatcher
 	var hasSubMatcher bool
-
-	if matcher.Arg != nil {
-		subMatcher, hasSubMatcher = (matcher.Arg).(omegaMatcher)
+	var resultReference interface{}
+
+	// Valid arg formats are as follows, always with optional POINTER before
+	// optional MATCHER:
+	//   - Receive()
+	//   - Receive(POINTER)
+	//   - Receive(MATCHER)
+	//   - Receive(POINTER, MATCHER)
+	args := matcher.Args
+	if len(args) > 0 {
+		arg := args[0]
+		_, isSubMatcher := arg.(omegaMatcher)
+		if !isSubMatcher && reflect.ValueOf(arg).Kind() == reflect.Ptr {
+			// Consume optional POINTER arg first, if it ain't no matcher ;)
+			resultReference = arg
+			args = args[1:]
+		}
+	}
+	if len(args) > 0 {
+		arg := args[0]
+		subMatcher, hasSubMatcher = arg.(omegaMatcher)
 		if !hasSubMatcher {
-			argType := reflect.TypeOf(matcher.Arg)
-			if argType.Kind() != reflect.Ptr {
-				return false, fmt.Errorf("Cannot assign a value from the channel:\n%s\nTo:\n%s\nYou need to pass a pointer!", format.Object(actual, 1), format.Object(matcher.Arg, 1))
-			}
+			// At this point we assume the dev user wanted to assign a received
+			// value, so [POINTER,]MATCHER.
+			return false, fmt.Errorf("Cannot assign a value from the channel:\n%s\nTo:\n%s\nYou need to pass a pointer!", format.Object(actual, 1), format.Object(arg, 1))
 		}
+		// Consume optional MATCHER arg.
+		args = args[1:]
+	}
+	if len(args) > 0 {
+		// If there are still args present, reject all.
+		return false, errors.New("Receive matcher expects at most an optional pointer and/or an optional matcher")
 	}
 
 	winnerIndex, value, open := reflect.Select([]reflect.SelectCase{
@@ -58,16 +82,20 @@ func (matcher *ReceiveMatcher) Match(actual interface{}) (success bool, err erro
 	}
 
 	if hasSubMatcher {
-		if didReceive {
-			matcher.receivedValue = value
-			return subMatcher.Match(matcher.receivedValue.Interface())
+		if !didReceive {
+			return false, nil
 		}
-		return false, nil
+		matcher.receivedValue = value
+		if match, err := subMatcher.Match(matcher.receivedValue.Interface()); err != nil || !match {
+			return match, err
+		}
+		// if we received a match, then fall through in order to handle an
+		// optional assignment of the received value to the specified reference.
 	}
 
 	if didReceive {
-		if matcher.Arg != nil {
-			outValue := reflect.ValueOf(matcher.Arg)
+		if resultReference != nil {
+			outValue := reflect.ValueOf(resultReference)
 
 			if value.Type().AssignableTo(outValue.Elem().Type()) {
 				outValue.Elem().Set(value)
@@ -77,7 +105,7 @@ func (matcher *ReceiveMatcher) Match(actual interface{}) (success bool, err erro
 				outValue.Elem().Set(value.Elem())
 				return true, nil
 			} else {
-				return false, fmt.Errorf("Cannot assign a value from the channel:\n%s\nType:\n%s\nTo:\n%s", format.Object(actual, 1), format.Object(value.Interface(), 1), format.Object(matcher.Arg, 1))
+				return false, fmt.Errorf("Cannot assign a value from the channel:\n%s\nType:\n%s\nTo:\n%s", format.Object(actual, 1), format.Object(value.Interface(), 1), format.Object(resultReference, 1))
 			}
 
 		}
@@ -88,7 +116,11 @@ func (matcher *ReceiveMatcher) Match(actual interface{}) (success bool, err erro
 }
 
 func (matcher *ReceiveMatcher) FailureMessage(actual interface{}) (message string) {
-	subMatcher, hasSubMatcher := (matcher.Arg).(omegaMatcher)
+	var matcherArg interface{}
+	if len(matcher.Args) > 0 {
+		matcherArg = matcher.Args[len(matcher.Args)-1]
+	}
+	subMatcher, hasSubMatcher := (matcherArg).(omegaMatcher)
 
 	closedAddendum := ""
 	if matcher.channelClosed {
@@ -105,7 +137,11 @@ func (matcher *ReceiveMatcher) FailureMessage(actual interface{}) (message strin
 }
 
 func (matcher *ReceiveMatcher) NegatedFailureMessage(actual interface{}) (message string) {
-	subMatcher, hasSubMatcher := (matcher.Arg).(omegaMatcher)
+	var matcherArg interface{}
+	if len(matcher.Args) > 0 {
+		matcherArg = matcher.Args[len(matcher.Args)-1]
+	}
+	subMatcher, hasSubMatcher := (matcherArg).(omegaMatcher)
 
 	closedAddendum := ""
 	if matcher.channelClosed {
diff --git a/vendor/modules.txt b/vendor/modules.txt
index f2aef2cd090..91f0d7a791a 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -366,7 +366,7 @@ github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1
 github.com/cs3org/go-cs3apis/cs3/storage/registry/v1beta1
 github.com/cs3org/go-cs3apis/cs3/tx/v1beta1
 github.com/cs3org/go-cs3apis/cs3/types/v1beta1
-# github.com/cs3org/reva/v2 v2.19.2-0.20240416121921-56d2be7011cf
+# github.com/cs3org/reva/v2 v2.19.2-0.20240419134937-8a636c82c1cf
 ## explicit; go 1.21
 github.com/cs3org/reva/v2/cmd/revad/internal/grace
 github.com/cs3org/reva/v2/cmd/revad/runtime
@@ -1468,7 +1468,7 @@ github.com/onsi/ginkgo/reporters/stenographer
 github.com/onsi/ginkgo/reporters/stenographer/support/go-colorable
 github.com/onsi/ginkgo/reporters/stenographer/support/go-isatty
 github.com/onsi/ginkgo/types
-# github.com/onsi/ginkgo/v2 v2.17.0
+# github.com/onsi/ginkgo/v2 v2.17.1
 ## explicit; go 1.20
 github.com/onsi/ginkgo/v2
 github.com/onsi/ginkgo/v2/config
@@ -1490,7 +1490,7 @@ github.com/onsi/ginkgo/v2/internal/parallel_support
 github.com/onsi/ginkgo/v2/internal/testingtproxy
 github.com/onsi/ginkgo/v2/reporters
 github.com/onsi/ginkgo/v2/types
-# github.com/onsi/gomega v1.32.0
+# github.com/onsi/gomega v1.33.0
 ## explicit; go 1.20
 github.com/onsi/gomega
 github.com/onsi/gomega/format


Test patch:
diff --git a/services/settings/pkg/store/metadata/store_test.go b/services/settings/pkg/store/metadata/store_test.go
index 0859d38b524..e204618f27a 100644
--- a/services/settings/pkg/store/metadata/store_test.go
+++ b/services/settings/pkg/store/metadata/store_test.go
@@ -2,10 +2,15 @@ package store
 
 import (
 	"context"
+	"encoding/json"
 	"strings"
+	"testing"
 
 	"github.com/cs3org/reva/v2/pkg/errtypes"
+	. "github.com/onsi/gomega"
+	settingsmsg "github.com/owncloud/ocis/v2/protogen/gen/ocis/messages/settings/v0"
 	"github.com/owncloud/ocis/v2/services/settings/pkg/config/defaults"
+	rdefaults "github.com/owncloud/ocis/v2/services/settings/pkg/store/defaults"
 )
 
 const (
@@ -112,3 +117,74 @@ func (m *MockedMetadataClient) IDExists(id string) bool {
 func (m *MockedMetadataClient) IDHasContent(id string, content []byte) bool {
 	return string(m.data[id]) == string(content)
 }
+
+// TestAdminUserIDInit test the happy path during initialization
+func TestAdminUserIDInit(t *testing.T) {
+	RegisterTestingT(t)
+	s := &Store{
+		cfg: defaults.DefaultConfig(),
+	}
+	s.cfg.Bundles = rdefaults.GenerateBundlesDefaultRoles()
+	s.cfg.AdminUserID = "admin"
+
+	// the first assignment is always happening during the initialisation of the metadata client
+	err := NewMDC(s)
+	Expect(err).To(BeNil())
+
+	assID, err := s.mdc.ReadDir(context.TODO(), accountPath(s.cfg.AdminUserID))
+	Expect(len(assID)).To(Equal(1))
+	ass, err := s.mdc.SimpleDownload(context.TODO(), assignmentPath(s.cfg.AdminUserID, assID[0]))
+	Expect(ass).ToNot(BeNil())
+
+	assignment := &settingsmsg.UserRoleAssignment{}
+	err = json.Unmarshal(ass, assignment)
+	Expect(err).To(BeNil())
+	Expect(assignment.RoleId).To(Equal(rdefaults.BundleUUIDRoleAdmin))
+}
+
+// TestAdminUserIDUpdate test the update on following initialisations
+func TestAdminUserIDUpdate(t *testing.T) {
+	RegisterTestingT(t)
+	s := &Store{
+		cfg: defaults.DefaultConfig(),
+	}
+	s.cfg.Bundles = rdefaults.GenerateBundlesDefaultRoles()
+	s.cfg.AdminUserID = "admin"
+
+	// the first assignment is always happening during the initialisation of the metadata client
+	err := NewMDC(s)
+	Expect(err).To(BeNil())
+
+	// read assignment
+	assID, err := s.mdc.ReadDir(context.TODO(), accountPath(s.cfg.AdminUserID))
+	Expect(len(assID)).To(Equal(1))
+
+	// set assignment to user role
+	userRoleAssignment := &settingsmsg.UserRoleAssignment{
+		AccountUuid: s.cfg.AdminUserID,
+		RoleId:      rdefaults.BundleUUIDRoleUser,
+	}
+	b, err := json.Marshal(userRoleAssignment)
+	err = s.mdc.Delete(context.TODO(), assignmentPath(s.cfg.AdminUserID, assID[0]))
+	Expect(err).To(BeNil())
+	err = s.mdc.SimpleUpload(context.TODO(), assignmentPath(s.cfg.AdminUserID, assID[0]), b)
+	Expect(err).To(BeNil())
+
+	// this happens on every Read / Write on the store
+	// the actual init is only done if the metadata client has not been initialized before
+	// this normally needs a restart of the service
+	err = s.initMetadataClient(s.mdc)
+	Expect(err).To(BeNil())
+
+	// read assignment id, changes every time the assignment is written
+	assID, err = s.mdc.ReadDir(context.TODO(), accountPath(s.cfg.AdminUserID))
+	Expect(len(assID)).To(Equal(1))
+
+	// check if the assignment is the admin role again
+	ass, err := s.mdc.SimpleDownload(context.TODO(), assignmentPath(s.cfg.AdminUserID, assID[0]))
+	Expect(ass).ToNot(BeNil())
+	assignment := &settingsmsg.UserRoleAssignment{}
+	err = json.Unmarshal(ass, assignment)
+	Expect(err).To(BeNil())
+	Expect(assignment.RoleId).To(Equal(rdefaults.BundleUUIDRoleAdmin))
+}
diff --git a/tests/acceptance/docker/src/acceptance.yml b/tests/acceptance/docker/src/acceptance.yml
index e98a1f7f6c2..fe380a958a7 100644
--- a/tests/acceptance/docker/src/acceptance.yml
+++ b/tests/acceptance/docker/src/acceptance.yml
@@ -1,6 +1,6 @@
 services:
   acceptance-tests:
-    image: owncloudci/php:7.4
+    image: owncloudci/php:8.2
     working_dir: /drone/src
     command: /bin/bash /test/run-tests.sh
     environment: