Repository: owncloud/ocis
Pull request #8342 (2024-02-01 15:40:35)

[full-ci] chore: bump web to v8.0.0-rc.3
Bump web to `v8.0.0-rc.3`


Patch:
diff --git a/.drone.env b/.drone.env
index 3f6d132ba5a..1a92c7738bb 100644
--- a/.drone.env
+++ b/.drone.env
@@ -1,3 +1,3 @@
 # The test runner source for UI tests
-WEB_COMMITID=934efe5fc60831b2bc6c353c8256c21972066398
+WEB_COMMITID=304fa011f59131657b5fc9698d0627b2b6d8c694
 WEB_BRANCH=stable-8.0
diff --git a/.drone.star b/.drone.star
index ca4988126ed..3f86efd1fdf 100644
--- a/.drone.star
+++ b/.drone.star
@@ -1162,11 +1162,11 @@ def e2eTests(ctx):
     test_suites = {
         "suite1": {
             "path": "tests/e2e/cucumber/features/*/*[!.oc10].feature",
-            "tikaNeeded": True,
+            "tikaNeeded": False,
         },
         "suite2": {
             "path": "tests/e2e/cucumber/features/smoke/*[!app-provider]/*[!.oc10].feature",
-            "tikaNeeded": False,
+            "tikaNeeded": True,
         },
     }
 
diff --git a/changelog/5.0.0-rc.1_2023-12-27/update-web-8.0.0.md b/changelog/5.0.0-rc.1_2023-12-27/update-web-8.0.0.md
index 98301ace858..a960dcee65f 100644
--- a/changelog/5.0.0-rc.1_2023-12-27/update-web-8.0.0.md
+++ b/changelog/5.0.0-rc.1_2023-12-27/update-web-8.0.0.md
@@ -1,7 +1,22 @@
-Enhancement: Update web to v8.0.0-rc.1
+Enhancement: Update web to v8.0.0-rc.3
 
 Tags: web
 
+We updated ownCloud Web to v8.0.0-rc.3. Please refer to the changelog (linked) for details on the web release.
+
+## Summary
+* Bugfix [owncloud/web#10318](https://github.com/owncloud/web/pull/10318): Scrollable account page
+* Bugfix [owncloud/web#10321](https://github.com/owncloud/web/pull/10321): Private link error messages
+* Bugfix [owncloud/web#10347](https://github.com/owncloud/web/pull/10347): Readonly user attributes have no effect on group memberships
+* Bugfix [owncloud/web#10424](https://github.com/owncloud/web/pull/10424): Restore space
+* Enhancement [owncloud/web#10356](https://github.com/owncloud/web/pull/10356): Preview app add reset button for images
+
+We updated ownCloud Web to v8.0.0-rc.2. Please refer to the changelog (linked) for details on the web release.
+
+## Summary
+* Bugfix [owncloud/web#10176](https://github.com/owncloud/web/pull/10176): Turned off file extensions not always respected
+* Bugfix [owncloud/web#10232](https://github.com/owncloud/web/pull/10232): Skip searchbar preview fetch on reload
+
 We updated ownCloud Web to v8.0.0-rc.1. Please refer to the changelog (linked) for details on the web release.
 
 ## Summary
@@ -121,6 +136,10 @@ We updated ownCloud Web to v8.0.0-alpha.12. Please refer to the changelog (linke
 * Enhancement [owncloud/web#10099](https://github.com/owncloud/web/pull/10099): Support mandatory filter while listing users
 * Enhancement [owncloud/web#10102](https://github.com/owncloud/web/pull/10102): Registering quick actions as extension
 
+https://github.com/owncloud/ocis/pull/8342
+https://github.com/owncloud/web/releases/tag/v8.0.0-rc.3
+https://github.com/owncloud/ocis/pull/8154
+https://github.com/owncloud/web/releases/tag/v8.0.0-rc.2
 https://github.com/owncloud/ocis/pull/8055
 https://github.com/owncloud/web/releases/tag/v8.0.0-rc.1
 https://github.com/owncloud/ocis/pull/7930
diff --git a/go.mod b/go.mod
index 94a996fd787..3febc7581f9 100644
--- a/go.mod
+++ b/go.mod
@@ -69,7 +69,7 @@ require (
 	github.com/onsi/gomega v1.31.1
 	github.com/open-policy-agent/opa v0.61.0
 	github.com/orcaman/concurrent-map v1.0.0
-	github.com/owncloud/libre-graph-api-go v1.0.5-0.20240130152355-ac663a9002a1
+	github.com/owncloud/libre-graph-api-go v1.0.5-0.20240115110609-b018a896364e
 	github.com/pkg/errors v0.9.1
 	github.com/pkg/xattr v0.4.9
 	github.com/prometheus/client_golang v1.18.0
diff --git a/go.sum b/go.sum
index 60446e49643..e143347384f 100644
--- a/go.sum
+++ b/go.sum
@@ -1790,8 +1790,8 @@ github.com/oracle/oci-go-sdk v24.3.0+incompatible/go.mod h1:VQb79nF8Z2cwLkLS35uk
 github.com/orcaman/concurrent-map v1.0.0 h1:I/2A2XPCb4IuQWcQhBhSwGfiuybl/J0ev9HDbW65HOY=
 github.com/orcaman/concurrent-map v1.0.0/go.mod h1:Lu3tH6HLW3feq74c2GC+jIMS/K2CFcDWnWD9XkenwhI=
 github.com/ovh/go-ovh v1.1.0/go.mod h1:AxitLZ5HBRPyUd+Zl60Ajaag+rNTdVXWIkzfrVuTXWA=
-github.com/owncloud/libre-graph-api-go v1.0.5-0.20240130152355-ac663a9002a1 h1:QLEERCsKv9VhkQaCP5zMEPdAqJLp/iuyogrg/eTfISg=
-github.com/owncloud/libre-graph-api-go v1.0.5-0.20240130152355-ac663a9002a1/go.mod h1:v2aAl5IwEI8t+GmcWvBd+bvJMYp9Vf1hekLuRf0UnEs=
+github.com/owncloud/libre-graph-api-go v1.0.5-0.20240115110609-b018a896364e h1:Y7MEJYsPe+UGlmU7oR9LaBIsQQYTwCq4a/p0JCia2cA=
+github.com/owncloud/libre-graph-api-go v1.0.5-0.20240115110609-b018a896364e/go.mod h1:v2aAl5IwEI8t+GmcWvBd+bvJMYp9Vf1hekLuRf0UnEs=
 github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c h1:rp5dCmg/yLR3mgFuSOe4oEnDDmGLROTvMragMUXpTQw=
 github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c/go.mod h1:X07ZCGwUbLaax7L0S3Tw4hpejzu63ZrrQiUe6W0hcy0=
 github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
diff --git a/services/graph/.mockery.yaml b/services/graph/.mockery.yaml
index 9ccccd54239..ccf44b59635 100644
--- a/services/graph/.mockery.yaml
+++ b/services/graph/.mockery.yaml
@@ -3,14 +3,6 @@ filename: "{{.InterfaceName | snakecase }}.go"
 mockname: "{{.InterfaceName}}"
 outpkg: "mocks"
 packages:
-    github.com/owncloud/ocis/v2/services/graph/pkg/service/v0:
-        config:
-          dir: "mocks"
-        interfaces:
-            HTTPClient:
-            Permissions:
-            Publisher:
-            RoleService:
     github.com/owncloud/ocis/v2/services/graph/pkg/identity:
         config:
             dir: "pkg/identity/mocks"
@@ -23,4 +15,4 @@ packages:
         interfaces:
             Client:
                 config:
-                    filename: "ldapclient.go"
+                    filename: "ldapclient.go"
\ No newline at end of file
diff --git a/services/graph/mocks/ldapclient.go b/services/graph/mocks/ldapclient.go
new file mode 100644
index 00000000000..f9f1e15b6f6
--- /dev/null
+++ b/services/graph/mocks/ldapclient.go
@@ -0,0 +1,1322 @@
+// Code generated by mockery v2.40.1. DO NOT EDIT.
+
+package mocks
+
+import (
+	context "context"
+
+	ldap "github.com/go-ldap/ldap/v3"
+	mock "github.com/stretchr/testify/mock"
+
+	time "time"
+
+	tls "crypto/tls"
+)
+
+// Client is an autogenerated mock type for the Client type
+type Client struct {
+	mock.Mock
+}
+
+type Client_Expecter struct {
+	mock *mock.Mock
+}
+
+func (_m *Client) EXPECT() *Client_Expecter {
+	return &Client_Expecter{mock: &_m.Mock}
+}
+
+// Add provides a mock function with given fields: _a0
+func (_m *Client) Add(_a0 *ldap.AddRequest) error {
+	ret := _m.Called(_a0)
+
+	if len(ret) == 0 {
+		panic("no return value specified for Add")
+	}
+
+	var r0 error
+	if rf, ok := ret.Get(0).(func(*ldap.AddRequest) error); ok {
+		r0 = rf(_a0)
+	} else {
+		r0 = ret.Error(0)
+	}
+
+	return r0
+}
+
+// Client_Add_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Add'
+type Client_Add_Call struct {
+	*mock.Call
+}
+
+// Add is a helper method to define mock.On call
+//   - _a0 *ldap.AddRequest
+func (_e *Client_Expecter) Add(_a0 interface{}) *Client_Add_Call {
+	return &Client_Add_Call{Call: _e.mock.On("Add", _a0)}
+}
+
+func (_c *Client_Add_Call) Run(run func(_a0 *ldap.AddRequest)) *Client_Add_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run(args[0].(*ldap.AddRequest))
+	})
+	return _c
+}
+
+func (_c *Client_Add_Call) Return(_a0 error) *Client_Add_Call {
+	_c.Call.Return(_a0)
+	return _c
+}
+
+func (_c *Client_Add_Call) RunAndReturn(run func(*ldap.AddRequest) error) *Client_Add_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// Bind provides a mock function with given fields: username, password
+func (_m *Client) Bind(username string, password string) error {
+	ret := _m.Called(username, password)
+
+	if len(ret) == 0 {
+		panic("no return value specified for Bind")
+	}
+
+	var r0 error
+	if rf, ok := ret.Get(0).(func(string, string) error); ok {
+		r0 = rf(username, password)
+	} else {
+		r0 = ret.Error(0)
+	}
+
+	return r0
+}
+
+// Client_Bind_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Bind'
+type Client_Bind_Call struct {
+	*mock.Call
+}
+
+// Bind is a helper method to define mock.On call
+//   - username string
+//   - password string
+func (_e *Client_Expecter) Bind(username interface{}, password interface{}) *Client_Bind_Call {
+	return &Client_Bind_Call{Call: _e.mock.On("Bind", username, password)}
+}
+
+func (_c *Client_Bind_Call) Run(run func(username string, password string)) *Client_Bind_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run(args[0].(string), args[1].(string))
+	})
+	return _c
+}
+
+func (_c *Client_Bind_Call) Return(_a0 error) *Client_Bind_Call {
+	_c.Call.Return(_a0)
+	return _c
+}
+
+func (_c *Client_Bind_Call) RunAndReturn(run func(string, string) error) *Client_Bind_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// Close provides a mock function with given fields:
+func (_m *Client) Close() error {
+	ret := _m.Called()
+
+	if len(ret) == 0 {
+		panic("no return value specified for Close")
+	}
+
+	var r0 error
+	if rf, ok := ret.Get(0).(func() error); ok {
+		r0 = rf()
+	} else {
+		r0 = ret.Error(0)
+	}
+
+	return r0
+}
+
+// Client_Close_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Close'
+type Client_Close_Call struct {
+	*mock.Call
+}
+
+// Close is a helper method to define mock.On call
+func (_e *Client_Expecter) Close() *Client_Close_Call {
+	return &Client_Close_Call{Call: _e.mock.On("Close")}
+}
+
+func (_c *Client_Close_Call) Run(run func()) *Client_Close_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run()
+	})
+	return _c
+}
+
+func (_c *Client_Close_Call) Return(_a0 error) *Client_Close_Call {
+	_c.Call.Return(_a0)
+	return _c
+}
+
+func (_c *Client_Close_Call) RunAndReturn(run func() error) *Client_Close_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// Compare provides a mock function with given fields: dn, attribute, value
+func (_m *Client) Compare(dn string, attribute string, value string) (bool, error) {
+	ret := _m.Called(dn, attribute, value)
+
+	if len(ret) == 0 {
+		panic("no return value specified for Compare")
+	}
+
+	var r0 bool
+	var r1 error
+	if rf, ok := ret.Get(0).(func(string, string, string) (bool, error)); ok {
+		return rf(dn, attribute, value)
+	}
+	if rf, ok := ret.Get(0).(func(string, string, string) bool); ok {
+		r0 = rf(dn, attribute, value)
+	} else {
+		r0 = ret.Get(0).(bool)
+	}
+
+	if rf, ok := ret.Get(1).(func(string, string, string) error); ok {
+		r1 = rf(dn, attribute, value)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// Client_Compare_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Compare'
+type Client_Compare_Call struct {
+	*mock.Call
+}
+
+// Compare is a helper method to define mock.On call
+//   - dn string
+//   - attribute string
+//   - value string
+func (_e *Client_Expecter) Compare(dn interface{}, attribute interface{}, value interface{}) *Client_Compare_Call {
+	return &Client_Compare_Call{Call: _e.mock.On("Compare", dn, attribute, value)}
+}
+
+func (_c *Client_Compare_Call) Run(run func(dn string, attribute string, value string)) *Client_Compare_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run(args[0].(string), args[1].(string), args[2].(string))
+	})
+	return _c
+}
+
+func (_c *Client_Compare_Call) Return(_a0 bool, _a1 error) *Client_Compare_Call {
+	_c.Call.Return(_a0, _a1)
+	return _c
+}
+
+func (_c *Client_Compare_Call) RunAndReturn(run func(string, string, string) (bool, error)) *Client_Compare_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// Del provides a mock function with given fields: _a0
+func (_m *Client) Del(_a0 *ldap.DelRequest) error {
+	ret := _m.Called(_a0)
+
+	if len(ret) == 0 {
+		panic("no return value specified for Del")
+	}
+
+	var r0 error
+	if rf, ok := ret.Get(0).(func(*ldap.DelRequest) error); ok {
+		r0 = rf(_a0)
+	} else {
+		r0 = ret.Error(0)
+	}
+
+	return r0
+}
+
+// Client_Del_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Del'
+type Client_Del_Call struct {
+	*mock.Call
+}
+
+// Del is a helper method to define mock.On call
+//   - _a0 *ldap.DelRequest
+func (_e *Client_Expecter) Del(_a0 interface{}) *Client_Del_Call {
+	return &Client_Del_Call{Call: _e.mock.On("Del", _a0)}
+}
+
+func (_c *Client_Del_Call) Run(run func(_a0 *ldap.DelRequest)) *Client_Del_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run(args[0].(*ldap.DelRequest))
+	})
+	return _c
+}
+
+func (_c *Client_Del_Call) Return(_a0 error) *Client_Del_Call {
+	_c.Call.Return(_a0)
+	return _c
+}
+
+func (_c *Client_Del_Call) RunAndReturn(run func(*ldap.DelRequest) error) *Client_Del_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// DirSync provides a mock function with given fields: searchRequest, flags, maxAttrCount, cookie
+func (_m *Client) DirSync(searchRequest *ldap.SearchRequest, flags int64, maxAttrCount int64, cookie []byte) (*ldap.SearchResult, error) {
+	ret := _m.Called(searchRequest, flags, maxAttrCount, cookie)
+
+	if len(ret) == 0 {
+		panic("no return value specified for DirSync")
+	}
+
+	var r0 *ldap.SearchResult
+	var r1 error
+	if rf, ok := ret.Get(0).(func(*ldap.SearchRequest, int64, int64, []byte) (*ldap.SearchResult, error)); ok {
+		return rf(searchRequest, flags, maxAttrCount, cookie)
+	}
+	if rf, ok := ret.Get(0).(func(*ldap.SearchRequest, int64, int64, []byte) *ldap.SearchResult); ok {
+		r0 = rf(searchRequest, flags, maxAttrCount, cookie)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(*ldap.SearchResult)
+		}
+	}
+
+	if rf, ok := ret.Get(1).(func(*ldap.SearchRequest, int64, int64, []byte) error); ok {
+		r1 = rf(searchRequest, flags, maxAttrCount, cookie)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// Client_DirSync_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DirSync'
+type Client_DirSync_Call struct {
+	*mock.Call
+}
+
+// DirSync is a helper method to define mock.On call
+//   - searchRequest *ldap.SearchRequest
+//   - flags int64
+//   - maxAttrCount int64
+//   - cookie []byte
+func (_e *Client_Expecter) DirSync(searchRequest interface{}, flags interface{}, maxAttrCount interface{}, cookie interface{}) *Client_DirSync_Call {
+	return &Client_DirSync_Call{Call: _e.mock.On("DirSync", searchRequest, flags, maxAttrCount, cookie)}
+}
+
+func (_c *Client_DirSync_Call) Run(run func(searchRequest *ldap.SearchRequest, flags int64, maxAttrCount int64, cookie []byte)) *Client_DirSync_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run(args[0].(*ldap.SearchRequest), args[1].(int64), args[2].(int64), args[3].([]byte))
+	})
+	return _c
+}
+
+func (_c *Client_DirSync_Call) Return(_a0 *ldap.SearchResult, _a1 error) *Client_DirSync_Call {
+	_c.Call.Return(_a0, _a1)
+	return _c
+}
+
+func (_c *Client_DirSync_Call) RunAndReturn(run func(*ldap.SearchRequest, int64, int64, []byte) (*ldap.SearchResult, error)) *Client_DirSync_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// DirSyncAsync provides a mock function with given fields: ctx, searchRequest, bufferSize, flags, maxAttrCount, cookie
+func (_m *Client) DirSyncAsync(ctx context.Context, searchRequest *ldap.SearchRequest, bufferSize int, flags int64, maxAttrCount int64, cookie []byte) ldap.Response {
+	ret := _m.Called(ctx, searchRequest, bufferSize, flags, maxAttrCount, cookie)
+
+	if len(ret) == 0 {
+		panic("no return value specified for DirSyncAsync")
+	}
+
+	var r0 ldap.Response
+	if rf, ok := ret.Get(0).(func(context.Context, *ldap.SearchRequest, int, int64, int64, []byte) ldap.Response); ok {
+		r0 = rf(ctx, searchRequest, bufferSize, flags, maxAttrCount, cookie)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(ldap.Response)
+		}
+	}
+
+	return r0
+}
+
+// Client_DirSyncAsync_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DirSyncAsync'
+type Client_DirSyncAsync_Call struct {
+	*mock.Call
+}
+
+// DirSyncAsync is a helper method to define mock.On call
+//   - ctx context.Context
+//   - searchRequest *ldap.SearchRequest
+//   - bufferSize int
+//   - flags int64
+//   - maxAttrCount int64
+//   - cookie []byte
+func (_e *Client_Expecter) DirSyncAsync(ctx interface{}, searchRequest interface{}, bufferSize interface{}, flags interface{}, maxAttrCount interface{}, cookie interface{}) *Client_DirSyncAsync_Call {
+	return &Client_DirSyncAsync_Call{Call: _e.mock.On("DirSyncAsync", ctx, searchRequest, bufferSize, flags, maxAttrCount, cookie)}
+}
+
+func (_c *Client_DirSyncAsync_Call) Run(run func(ctx context.Context, searchRequest *ldap.SearchRequest, bufferSize int, flags int64, maxAttrCount int64, cookie []byte)) *Client_DirSyncAsync_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run(args[0].(context.Context), args[1].(*ldap.SearchRequest), args[2].(int), args[3].(int64), args[4].(int64), args[5].([]byte))
+	})
+	return _c
+}
+
+func (_c *Client_DirSyncAsync_Call) Return(_a0 ldap.Response) *Client_DirSyncAsync_Call {
+	_c.Call.Return(_a0)
+	return _c
+}
+
+func (_c *Client_DirSyncAsync_Call) RunAndReturn(run func(context.Context, *ldap.SearchRequest, int, int64, int64, []byte) ldap.Response) *Client_DirSyncAsync_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// ExternalBind provides a mock function with given fields:
+func (_m *Client) ExternalBind() error {
+	ret := _m.Called()
+
+	if len(ret) == 0 {
+		panic("no return value specified for ExternalBind")
+	}
+
+	var r0 error
+	if rf, ok := ret.Get(0).(func() error); ok {
+		r0 = rf()
+	} else {
+		r0 = ret.Error(0)
+	}
+
+	return r0
+}
+
+// Client_ExternalBind_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ExternalBind'
+type Client_ExternalBind_Call struct {
+	*mock.Call
+}
+
+// ExternalBind is a helper method to define mock.On call
+func (_e *Client_Expecter) ExternalBind() *Client_ExternalBind_Call {
+	return &Client_ExternalBind_Call{Call: _e.mock.On("ExternalBind")}
+}
+
+func (_c *Client_ExternalBind_Call) Run(run func()) *Client_ExternalBind_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run()
+	})
+	return _c
+}
+
+func (_c *Client_ExternalBind_Call) Return(_a0 error) *Client_ExternalBind_Call {
+	_c.Call.Return(_a0)
+	return _c
+}
+
+func (_c *Client_ExternalBind_Call) RunAndReturn(run func() error) *Client_ExternalBind_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// GetLastError provides a mock function with given fields:
+func (_m *Client) GetLastError() error {
+	ret := _m.Called()
+
+	if len(ret) == 0 {
+		panic("no return value specified for GetLastError")
+	}
+
+	var r0 error
+	if rf, ok := ret.Get(0).(func() error); ok {
+		r0 = rf()
+	} else {
+		r0 = ret.Error(0)
+	}
+
+	return r0
+}
+
+// Client_GetLastError_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetLastError'
+type Client_GetLastError_Call struct {
+	*mock.Call
+}
+
+// GetLastError is a helper method to define mock.On call
+func (_e *Client_Expecter) GetLastError() *Client_GetLastError_Call {
+	return &Client_GetLastError_Call{Call: _e.mock.On("GetLastError")}
+}
+
+func (_c *Client_GetLastError_Call) Run(run func()) *Client_GetLastError_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run()
+	})
+	return _c
+}
+
+func (_c *Client_GetLastError_Call) Return(_a0 error) *Client_GetLastError_Call {
+	_c.Call.Return(_a0)
+	return _c
+}
+
+func (_c *Client_GetLastError_Call) RunAndReturn(run func() error) *Client_GetLastError_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// IsClosing provides a mock function with given fields:
+func (_m *Client) IsClosing() bool {
+	ret := _m.Called()
+
+	if len(ret) == 0 {
+		panic("no return value specified for IsClosing")
+	}
+
+	var r0 bool
+	if rf, ok := ret.Get(0).(func() bool); ok {
+		r0 = rf()
+	} else {
+		r0 = ret.Get(0).(bool)
+	}
+
+	return r0
+}
+
+// Client_IsClosing_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IsClosing'
+type Client_IsClosing_Call struct {
+	*mock.Call
+}
+
+// IsClosing is a helper method to define mock.On call
+func (_e *Client_Expecter) IsClosing() *Client_IsClosing_Call {
+	return &Client_IsClosing_Call{Call: _e.mock.On("IsClosing")}
+}
+
+func (_c *Client_IsClosing_Call) Run(run func()) *Client_IsClosing_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run()
+	})
+	return _c
+}
+
+func (_c *Client_IsClosing_Call) Return(_a0 bool) *Client_IsClosing_Call {
+	_c.Call.Return(_a0)
+	return _c
+}
+
+func (_c *Client_IsClosing_Call) RunAndReturn(run func() bool) *Client_IsClosing_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// Modify provides a mock function with given fields: _a0
+func (_m *Client) Modify(_a0 *ldap.ModifyRequest) error {
+	ret := _m.Called(_a0)
+
+	if len(ret) == 0 {
+		panic("no return value specified for Modify")
+	}
+
+	var r0 error
+	if rf, ok := ret.Get(0).(func(*ldap.ModifyRequest) error); ok {
+		r0 = rf(_a0)
+	} else {
+		r0 = ret.Error(0)
+	}
+
+	return r0
+}
+
+// Client_Modify_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Modify'
+type Client_Modify_Call struct {
+	*mock.Call
+}
+
+// Modify is a helper method to define mock.On call
+//   - _a0 *ldap.ModifyRequest
+func (_e *Client_Expecter) Modify(_a0 interface{}) *Client_Modify_Call {
+	return &Client_Modify_Call{Call: _e.mock.On("Modify", _a0)}
+}
+
+func (_c *Client_Modify_Call) Run(run func(_a0 *ldap.ModifyRequest)) *Client_Modify_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run(args[0].(*ldap.ModifyRequest))
+	})
+	return _c
+}
+
+func (_c *Client_Modify_Call) Return(_a0 error) *Client_Modify_Call {
+	_c.Call.Return(_a0)
+	return _c
+}
+
+func (_c *Client_Modify_Call) RunAndReturn(run func(*ldap.ModifyRequest) error) *Client_Modify_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// ModifyDN provides a mock function with given fields: _a0
+func (_m *Client) ModifyDN(_a0 *ldap.ModifyDNRequest) error {
+	ret := _m.Called(_a0)
+
+	if len(ret) == 0 {
+		panic("no return value specified for ModifyDN")
+	}
+
+	var r0 error
+	if rf, ok := ret.Get(0).(func(*ldap.ModifyDNRequest) error); ok {
+		r0 = rf(_a0)
+	} else {
+		r0 = ret.Error(0)
+	}
+
+	return r0
+}
+
+// Client_ModifyDN_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ModifyDN'
+type Client_ModifyDN_Call struct {
+	*mock.Call
+}
+
+// ModifyDN is a helper method to define mock.On call
+//   - _a0 *ldap.ModifyDNRequest
+func (_e *Client_Expecter) ModifyDN(_a0 interface{}) *Client_ModifyDN_Call {
+	return &Client_ModifyDN_Call{Call: _e.mock.On("ModifyDN", _a0)}
+}
+
+func (_c *Client_ModifyDN_Call) Run(run func(_a0 *ldap.ModifyDNRequest)) *Client_ModifyDN_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run(args[0].(*ldap.ModifyDNRequest))
+	})
+	return _c
+}
+
+func (_c *Client_ModifyDN_Call) Return(_a0 error) *Client_ModifyDN_Call {
+	_c.Call.Return(_a0)
+	return _c
+}
+
+func (_c *Client_ModifyDN_Call) RunAndReturn(run func(*ldap.ModifyDNRequest) error) *Client_ModifyDN_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// ModifyWithResult provides a mock function with given fields: _a0
+func (_m *Client) ModifyWithResult(_a0 *ldap.ModifyRequest) (*ldap.ModifyResult, error) {
+	ret := _m.Called(_a0)
+
+	if len(ret) == 0 {
+		panic("no return value specified for ModifyWithResult")
+	}
+
+	var r0 *ldap.ModifyResult
+	var r1 error
+	if rf, ok := ret.Get(0).(func(*ldap.ModifyRequest) (*ldap.ModifyResult, error)); ok {
+		return rf(_a0)
+	}
+	if rf, ok := ret.Get(0).(func(*ldap.ModifyRequest) *ldap.ModifyResult); ok {
+		r0 = rf(_a0)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(*ldap.ModifyResult)
+		}
+	}
+
+	if rf, ok := ret.Get(1).(func(*ldap.ModifyRequest) error); ok {
+		r1 = rf(_a0)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// Client_ModifyWithResult_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ModifyWithResult'
+type Client_ModifyWithResult_Call struct {
+	*mock.Call
+}
+
+// ModifyWithResult is a helper method to define mock.On call
+//   - _a0 *ldap.ModifyRequest
+func (_e *Client_Expecter) ModifyWithResult(_a0 interface{}) *Client_ModifyWithResult_Call {
+	return &Client_ModifyWithResult_Call{Call: _e.mock.On("ModifyWithResult", _a0)}
+}
+
+func (_c *Client_ModifyWithResult_Call) Run(run func(_a0 *ldap.ModifyRequest)) *Client_ModifyWithResult_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run(args[0].(*ldap.ModifyRequest))
+	})
+	return _c
+}
+
+func (_c *Client_ModifyWithResult_Call) Return(_a0 *ldap.ModifyResult, _a1 error) *Client_ModifyWithResult_Call {
+	_c.Call.Return(_a0, _a1)
+	return _c
+}
+
+func (_c *Client_ModifyWithResult_Call) RunAndReturn(run func(*ldap.ModifyRequest) (*ldap.ModifyResult, error)) *Client_ModifyWithResult_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// NTLMUnauthenticatedBind provides a mock function with given fields: domain, username
+func (_m *Client) NTLMUnauthenticatedBind(domain string, username string) error {
+	ret := _m.Called(domain, username)
+
+	if len(ret) == 0 {
+		panic("no return value specified for NTLMUnauthenticatedBind")
+	}
+
+	var r0 error
+	if rf, ok := ret.Get(0).(func(string, string) error); ok {
+		r0 = rf(domain, username)
+	} else {
+		r0 = ret.Error(0)
+	}
+
+	return r0
+}
+
+// Client_NTLMUnauthenticatedBind_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'NTLMUnauthenticatedBind'
+type Client_NTLMUnauthenticatedBind_Call struct {
+	*mock.Call
+}
+
+// NTLMUnauthenticatedBind is a helper method to define mock.On call
+//   - domain string
+//   - username string
+func (_e *Client_Expecter) NTLMUnauthenticatedBind(domain interface{}, username interface{}) *Client_NTLMUnauthenticatedBind_Call {
+	return &Client_NTLMUnauthenticatedBind_Call{Call: _e.mock.On("NTLMUnauthenticatedBind", domain, username)}
+}
+
+func (_c *Client_NTLMUnauthenticatedBind_Call) Run(run func(domain string, username string)) *Client_NTLMUnauthenticatedBind_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run(args[0].(string), args[1].(string))
+	})
+	return _c
+}
+
+func (_c *Client_NTLMUnauthenticatedBind_Call) Return(_a0 error) *Client_NTLMUnauthenticatedBind_Call {
+	_c.Call.Return(_a0)
+	return _c
+}
+
+func (_c *Client_NTLMUnauthenticatedBind_Call) RunAndReturn(run func(string, string) error) *Client_NTLMUnauthenticatedBind_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// PasswordModify provides a mock function with given fields: _a0
+func (_m *Client) PasswordModify(_a0 *ldap.PasswordModifyRequest) (*ldap.PasswordModifyResult, error) {
+	ret := _m.Called(_a0)
+
+	if len(ret) == 0 {
+		panic("no return value specified for PasswordModify")
+	}
+
+	var r0 *ldap.PasswordModifyResult
+	var r1 error
+	if rf, ok := ret.Get(0).(func(*ldap.PasswordModifyRequest) (*ldap.PasswordModifyResult, error)); ok {
+		return rf(_a0)
+	}
+	if rf, ok := ret.Get(0).(func(*ldap.PasswordModifyRequest) *ldap.PasswordModifyResult); ok {
+		r0 = rf(_a0)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(*ldap.PasswordModifyResult)
+		}
+	}
+
+	if rf, ok := ret.Get(1).(func(*ldap.PasswordModifyRequest) error); ok {
+		r1 = rf(_a0)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// Client_PasswordModify_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'PasswordModify'
+type Client_PasswordModify_Call struct {
+	*mock.Call
+}
+
+// PasswordModify is a helper method to define mock.On call
+//   - _a0 *ldap.PasswordModifyRequest
+func (_e *Client_Expecter) PasswordModify(_a0 interface{}) *Client_PasswordModify_Call {
+	return &Client_PasswordModify_Call{Call: _e.mock.On("PasswordModify", _a0)}
+}
+
+func (_c *Client_PasswordModify_Call) Run(run func(_a0 *ldap.PasswordModifyRequest)) *Client_PasswordModify_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run(args[0].(*ldap.PasswordModifyRequest))
+	})
+	return _c
+}
+
+func (_c *Client_PasswordModify_Call) Return(_a0 *ldap.PasswordModifyResult, _a1 error) *Client_PasswordModify_Call {
+	_c.Call.Return(_a0, _a1)
+	return _c
+}
+
+func (_c *Client_PasswordModify_Call) RunAndReturn(run func(*ldap.PasswordModifyRequest) (*ldap.PasswordModifyResult, error)) *Client_PasswordModify_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// Search provides a mock function with given fields: _a0
+func (_m *Client) Search(_a0 *ldap.SearchRequest) (*ldap.SearchResult, error) {
+	ret := _m.Called(_a0)
+
+	if len(ret) == 0 {
+		panic("no return value specified for Search")
+	}
+
+	var r0 *ldap.SearchResult
+	var r1 error
+	if rf, ok := ret.Get(0).(func(*ldap.SearchRequest) (*ldap.SearchResult, error)); ok {
+		return rf(_a0)
+	}
+	if rf, ok := ret.Get(0).(func(*ldap.SearchRequest) *ldap.SearchResult); ok {
+		r0 = rf(_a0)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(*ldap.SearchResult)
+		}
+	}
+
+	if rf, ok := ret.Get(1).(func(*ldap.SearchRequest) error); ok {
+		r1 = rf(_a0)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// Client_Search_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Search'
+type Client_Search_Call struct {
+	*mock.Call
+}
+
+// Search is a helper method to define mock.On call
+//   - _a0 *ldap.SearchRequest
+func (_e *Client_Expecter) Search(_a0 interface{}) *Client_Search_Call {
+	return &Client_Search_Call{Call: _e.mock.On("Search", _a0)}
+}
+
+func (_c *Client_Search_Call) Run(run func(_a0 *ldap.SearchRequest)) *Client_Search_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run(args[0].(*ldap.SearchRequest))
+	})
+	return _c
+}
+
+func (_c *Client_Search_Call) Return(_a0 *ldap.SearchResult, _a1 error) *Client_Search_Call {
+	_c.Call.Return(_a0, _a1)
+	return _c
+}
+
+func (_c *Client_Search_Call) RunAndReturn(run func(*ldap.SearchRequest) (*ldap.SearchResult, error)) *Client_Search_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// SearchAsync provides a mock function with given fields: ctx, searchRequest, bufferSize
+func (_m *Client) SearchAsync(ctx context.Context, searchRequest *ldap.SearchRequest, bufferSize int) ldap.Response {
+	ret := _m.Called(ctx, searchRequest, bufferSize)
+
+	if len(ret) == 0 {
+		panic("no return value specified for SearchAsync")
+	}
+
+	var r0 ldap.Response
+	if rf, ok := ret.Get(0).(func(context.Context, *ldap.SearchRequest, int) ldap.Response); ok {
+		r0 = rf(ctx, searchRequest, bufferSize)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(ldap.Response)
+		}
+	}
+
+	return r0
+}
+
+// Client_SearchAsync_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SearchAsync'
+type Client_SearchAsync_Call struct {
+	*mock.Call
+}
+
+// SearchAsync is a helper method to define mock.On call
+//   - ctx context.Context
+//   - searchRequest *ldap.SearchRequest
+//   - bufferSize int
+func (_e *Client_Expecter) SearchAsync(ctx interface{}, searchRequest interface{}, bufferSize interface{}) *Client_SearchAsync_Call {
+	return &Client_SearchAsync_Call{Call: _e.mock.On("SearchAsync", ctx, searchRequest, bufferSize)}
+}
+
+func (_c *Client_SearchAsync_Call) Run(run func(ctx context.Context, searchRequest *ldap.SearchRequest, bufferSize int)) *Client_SearchAsync_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run(args[0].(context.Context), args[1].(*ldap.SearchRequest), args[2].(int))
+	})
+	return _c
+}
+
+func (_c *Client_SearchAsync_Call) Return(_a0 ldap.Response) *Client_SearchAsync_Call {
+	_c.Call.Return(_a0)
+	return _c
+}
+
+func (_c *Client_SearchAsync_Call) RunAndReturn(run func(context.Context, *ldap.SearchRequest, int) ldap.Response) *Client_SearchAsync_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// SearchWithPaging provides a mock function with given fields: searchRequest, pagingSize
+func (_m *Client) SearchWithPaging(searchRequest *ldap.SearchRequest, pagingSize uint32) (*ldap.SearchResult, error) {
+	ret := _m.Called(searchRequest, pagingSize)
+
+	if len(ret) == 0 {
+		panic("no return value specified for SearchWithPaging")
+	}
+
+	var r0 *ldap.SearchResult
+	var r1 error
+	if rf, ok := ret.Get(0).(func(*ldap.SearchRequest, uint32) (*ldap.SearchResult, error)); ok {
+		return rf(searchRequest, pagingSize)
+	}
+	if rf, ok := ret.Get(0).(func(*ldap.SearchRequest, uint32) *ldap.SearchResult); ok {
+		r0 = rf(searchRequest, pagingSize)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(*ldap.SearchResult)
+		}
+	}
+
+	if rf, ok := ret.Get(1).(func(*ldap.SearchRequest, uint32) error); ok {
+		r1 = rf(searchRequest, pagingSize)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// Client_SearchWithPaging_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SearchWithPaging'
+type Client_SearchWithPaging_Call struct {
+	*mock.Call
+}
+
+// SearchWithPaging is a helper method to define mock.On call
+//   - searchRequest *ldap.SearchRequest
+//   - pagingSize uint32
+func (_e *Client_Expecter) SearchWithPaging(searchRequest interface{}, pagingSize interface{}) *Client_SearchWithPaging_Call {
+	return &Client_SearchWithPaging_Call{Call: _e.mock.On("SearchWithPaging", searchRequest, pagingSize)}
+}
+
+func (_c *Client_SearchWithPaging_Call) Run(run func(searchRequest *ldap.SearchRequest, pagingSize uint32)) *Client_SearchWithPaging_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run(args[0].(*ldap.SearchRequest), args[1].(uint32))
+	})
+	return _c
+}
+
+func (_c *Client_SearchWithPaging_Call) Return(_a0 *ldap.SearchResult, _a1 error) *Client_SearchWithPaging_Call {
+	_c.Call.Return(_a0, _a1)
+	return _c
+}
+
+func (_c *Client_SearchWithPaging_Call) RunAndReturn(run func(*ldap.SearchRequest, uint32) (*ldap.SearchResult, error)) *Client_SearchWithPaging_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// SetTimeout provides a mock function with given fields: _a0
+func (_m *Client) SetTimeout(_a0 time.Duration) {
+	_m.Called(_a0)
+}
+
+// Client_SetTimeout_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetTimeout'
+type Client_SetTimeout_Call struct {
+	*mock.Call
+}
+
+// SetTimeout is a helper method to define mock.On call
+//   - _a0 time.Duration
+func (_e *Client_Expecter) SetTimeout(_a0 interface{}) *Client_SetTimeout_Call {
+	return &Client_SetTimeout_Call{Call: _e.mock.On("SetTimeout", _a0)}
+}
+
+func (_c *Client_SetTimeout_Call) Run(run func(_a0 time.Duration)) *Client_SetTimeout_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run(args[0].(time.Duration))
+	})
+	return _c
+}
+
+func (_c *Client_SetTimeout_Call) Return() *Client_SetTimeout_Call {
+	_c.Call.Return()
+	return _c
+}
+
+func (_c *Client_SetTimeout_Call) RunAndReturn(run func(time.Duration)) *Client_SetTimeout_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// SimpleBind provides a mock function with given fields: _a0
+func (_m *Client) SimpleBind(_a0 *ldap.SimpleBindRequest) (*ldap.SimpleBindResult, error) {
+	ret := _m.Called(_a0)
+
+	if len(ret) == 0 {
+		panic("no return value specified for SimpleBind")
+	}
+
+	var r0 *ldap.SimpleBindResult
+	var r1 error
+	if rf, ok := ret.Get(0).(func(*ldap.SimpleBindRequest) (*ldap.SimpleBindResult, error)); ok {
+		return rf(_a0)
+	}
+	if rf, ok := ret.Get(0).(func(*ldap.SimpleBindRequest) *ldap.SimpleBindResult); ok {
+		r0 = rf(_a0)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(*ldap.SimpleBindResult)
+		}
+	}
+
+	if rf, ok := ret.Get(1).(func(*ldap.SimpleBindRequest) error); ok {
+		r1 = rf(_a0)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// Client_SimpleBind_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SimpleBind'
+type Client_SimpleBind_Call struct {
+	*mock.Call
+}
+
+// SimpleBind is a helper method to define mock.On call
+//   - _a0 *ldap.SimpleBindRequest
+func (_e *Client_Expecter) SimpleBind(_a0 interface{}) *Client_SimpleBind_Call {
+	return &Client_SimpleBind_Call{Call: _e.mock.On("SimpleBind", _a0)}
+}
+
+func (_c *Client_SimpleBind_Call) Run(run func(_a0 *ldap.SimpleBindRequest)) *Client_SimpleBind_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run(args[0].(*ldap.SimpleBindRequest))
+	})
+	return _c
+}
+
+func (_c *Client_SimpleBind_Call) Return(_a0 *ldap.SimpleBindResult, _a1 error) *Client_SimpleBind_Call {
+	_c.Call.Return(_a0, _a1)
+	return _c
+}
+
+func (_c *Client_SimpleBind_Call) RunAndReturn(run func(*ldap.SimpleBindRequest) (*ldap.SimpleBindResult, error)) *Client_SimpleBind_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// Start provides a mock function with given fields:
+func (_m *Client) Start() {
+	_m.Called()
+}
+
+// Client_Start_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Start'
+type Client_Start_Call struct {
+	*mock.Call
+}
+
+// Start is a helper method to define mock.On call
+func (_e *Client_Expecter) Start() *Client_Start_Call {
+	return &Client_Start_Call{Call: _e.mock.On("Start")}
+}
+
+func (_c *Client_Start_Call) Run(run func()) *Client_Start_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run()
+	})
+	return _c
+}
+
+func (_c *Client_Start_Call) Return() *Client_Start_Call {
+	_c.Call.Return()
+	return _c
+}
+
+func (_c *Client_Start_Call) RunAndReturn(run func()) *Client_Start_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// StartTLS provides a mock function with given fields: _a0
+func (_m *Client) StartTLS(_a0 *tls.Config) error {
+	ret := _m.Called(_a0)
+
+	if len(ret) == 0 {
+		panic("no return value specified for StartTLS")
+	}
+
+	var r0 error
+	if rf, ok := ret.Get(0).(func(*tls.Config) error); ok {
+		r0 = rf(_a0)
+	} else {
+		r0 = ret.Error(0)
+	}
+
+	return r0
+}
+
+// Client_StartTLS_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'StartTLS'
+type Client_StartTLS_Call struct {
+	*mock.Call
+}
+
+// StartTLS is a helper method to define mock.On call
+//   - _a0 *tls.Config
+func (_e *Client_Expecter) StartTLS(_a0 interface{}) *Client_StartTLS_Call {
+	return &Client_StartTLS_Call{Call: _e.mock.On("StartTLS", _a0)}
+}
+
+func (_c *Client_StartTLS_Call) Run(run func(_a0 *tls.Config)) *Client_StartTLS_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run(args[0].(*tls.Config))
+	})
+	return _c
+}
+
+func (_c *Client_StartTLS_Call) Return(_a0 error) *Client_StartTLS_Call {
+	_c.Call.Return(_a0)
+	return _c
+}
+
+func (_c *Client_StartTLS_Call) RunAndReturn(run func(*tls.Config) error) *Client_StartTLS_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// Syncrepl provides a mock function with given fields: ctx, searchRequest, bufferSize, mode, cookie, reloadHint
+func (_m *Client) Syncrepl(ctx context.Context, searchRequest *ldap.SearchRequest, bufferSize int, mode ldap.ControlSyncRequestMode, cookie []byte, reloadHint bool) ldap.Response {
+	ret := _m.Called(ctx, searchRequest, bufferSize, mode, cookie, reloadHint)
+
+	if len(ret) == 0 {
+		panic("no return value specified for Syncrepl")
+	}
+
+	var r0 ldap.Response
+	if rf, ok := ret.Get(0).(func(context.Context, *ldap.SearchRequest, int, ldap.ControlSyncRequestMode, []byte, bool) ldap.Response); ok {
+		r0 = rf(ctx, searchRequest, bufferSize, mode, cookie, reloadHint)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(ldap.Response)
+		}
+	}
+
+	return r0
+}
+
+// Client_Syncrepl_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Syncrepl'
+type Client_Syncrepl_Call struct {
+	*mock.Call
+}
+
+// Syncrepl is a helper method to define mock.On call
+//   - ctx context.Context
+//   - searchRequest *ldap.SearchRequest
+//   - bufferSize int
+//   - mode ldap.ControlSyncRequestMode
+//   - cookie []byte
+//   - reloadHint bool
+func (_e *Client_Expecter) Syncrepl(ctx interface{}, searchRequest interface{}, bufferSize interface{}, mode interface{}, cookie interface{}, reloadHint interface{}) *Client_Syncrepl_Call {
+	return &Client_Syncrepl_Call{Call: _e.mock.On("Syncrepl", ctx, searchRequest, bufferSize, mode, cookie, reloadHint)}
+}
+
+func (_c *Client_Syncrepl_Call) Run(run func(ctx context.Context, searchRequest *ldap.SearchRequest, bufferSize int, mode ldap.ControlSyncRequestMode, cookie []byte, reloadHint bool)) *Client_Syncrepl_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run(args[0].(context.Context), args[1].(*ldap.SearchRequest), args[2].(int), args[3].(ldap.ControlSyncRequestMode), args[4].([]byte), args[5].(bool))
+	})
+	return _c
+}
+
+func (_c *Client_Syncrepl_Call) Return(_a0 ldap.Response) *Client_Syncrepl_Call {
+	_c.Call.Return(_a0)
+	return _c
+}
+
+func (_c *Client_Syncrepl_Call) RunAndReturn(run func(context.Context, *ldap.SearchRequest, int, ldap.ControlSyncRequestMode, []byte, bool) ldap.Response) *Client_Syncrepl_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// TLSConnectionState provides a mock function with given fields:
+func (_m *Client) TLSConnectionState() (tls.ConnectionState, bool) {
+	ret := _m.Called()
+
+	if len(ret) == 0 {
+		panic("no return value specified for TLSConnectionState")
+	}
+
+	var r0 tls.ConnectionState
+	var r1 bool
+	if rf, ok := ret.Get(0).(func() (tls.ConnectionState, bool)); ok {
+		return rf()
+	}
+	if rf, ok := ret.Get(0).(func() tls.ConnectionState); ok {
+		r0 = rf()
+	} else {
+		r0 = ret.Get(0).(tls.ConnectionState)
+	}
+
+	if rf, ok := ret.Get(1).(func() bool); ok {
+		r1 = rf()
+	} else {
+		r1 = ret.Get(1).(bool)
+	}
+
+	return r0, r1
+}
+
+// Client_TLSConnectionState_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'TLSConnectionState'
+type Client_TLSConnectionState_Call struct {
+	*mock.Call
+}
+
+// TLSConnectionState is a helper method to define mock.On call
+func (_e *Client_Expecter) TLSConnectionState() *Client_TLSConnectionState_Call {
+	return &Client_TLSConnectionState_Call{Call: _e.mock.On("TLSConnectionState")}
+}
+
+func (_c *Client_TLSConnectionState_Call) Run(run func()) *Client_TLSConnectionState_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run()
+	})
+	return _c
+}
+
+func (_c *Client_TLSConnectionState_Call) Return(_a0 tls.ConnectionState, _a1 bool) *Client_TLSConnectionState_Call {
+	_c.Call.Return(_a0, _a1)
+	return _c
+}
+
+func (_c *Client_TLSConnectionState_Call) RunAndReturn(run func() (tls.ConnectionState, bool)) *Client_TLSConnectionState_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// UnauthenticatedBind provides a mock function with given fields: username
+func (_m *Client) UnauthenticatedBind(username string) error {
+	ret := _m.Called(username)
+
+	if len(ret) == 0 {
+		panic("no return value specified for UnauthenticatedBind")
+	}
+
+	var r0 error
+	if rf, ok := ret.Get(0).(func(string) error); ok {
+		r0 = rf(username)
+	} else {
+		r0 = ret.Error(0)
+	}
+
+	return r0
+}
+
+// Client_UnauthenticatedBind_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UnauthenticatedBind'
+type Client_UnauthenticatedBind_Call struct {
+	*mock.Call
+}
+
+// UnauthenticatedBind is a helper method to define mock.On call
+//   - username string
+func (_e *Client_Expecter) UnauthenticatedBind(username interface{}) *Client_UnauthenticatedBind_Call {
+	return &Client_UnauthenticatedBind_Call{Call: _e.mock.On("UnauthenticatedBind", username)}
+}
+
+func (_c *Client_UnauthenticatedBind_Call) Run(run func(username string)) *Client_UnauthenticatedBind_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run(args[0].(string))
+	})
+	return _c
+}
+
+func (_c *Client_UnauthenticatedBind_Call) Return(_a0 error) *Client_UnauthenticatedBind_Call {
+	_c.Call.Return(_a0)
+	return _c
+}
+
+func (_c *Client_UnauthenticatedBind_Call) RunAndReturn(run func(string) error) *Client_UnauthenticatedBind_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// Unbind provides a mock function with given fields:
+func (_m *Client) Unbind() error {
+	ret := _m.Called()
+
+	if len(ret) == 0 {
+		panic("no return value specified for Unbind")
+	}
+
+	var r0 error
+	if rf, ok := ret.Get(0).(func() error); ok {
+		r0 = rf()
+	} else {
+		r0 = ret.Error(0)
+	}
+
+	return r0
+}
+
+// Client_Unbind_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Unbind'
+type Client_Unbind_Call struct {
+	*mock.Call
+}
+
+// Unbind is a helper method to define mock.On call
+func (_e *Client_Expecter) Unbind() *Client_Unbind_Call {
+	return &Client_Unbind_Call{Call: _e.mock.On("Unbind")}
+}
+
+func (_c *Client_Unbind_Call) Run(run func()) *Client_Unbind_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		run()
+	})
+	return _c
+}
+
+func (_c *Client_Unbind_Call) Return(_a0 error) *Client_Unbind_Call {
+	_c.Call.Return(_a0)
+	return _c
+}
+
+func (_c *Client_Unbind_Call) RunAndReturn(run func() error) *Client_Unbind_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// NewClient creates a new instance of Client. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+// The first argument is typically a *testing.T value.
+func NewClient(t interface {
+	mock.TestingT
+	Cleanup(func())
+}) *Client {
+	mock := &Client{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/services/graph/mocks/value_service.go b/services/graph/mocks/value_service.go
new file mode 100644
index 00000000000..8a099b699d9
--- /dev/null
+++ b/services/graph/mocks/value_service.go
@@ -0,0 +1,336 @@
+// Code generated by mockery v2.40.1. DO NOT EDIT.
+
+package mocks
+
+import (
+	context "context"
+
+	client "go-micro.dev/v4/client"
+
+	mock "github.com/stretchr/testify/mock"
+
+	v0 "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/settings/v0"
+)
+
+// ValueService is an autogenerated mock type for the ValueService type
+type ValueService struct {
+	mock.Mock
+}
+
+type ValueService_Expecter struct {
+	mock *mock.Mock
+}
+
+func (_m *ValueService) EXPECT() *ValueService_Expecter {
+	return &ValueService_Expecter{mock: &_m.Mock}
+}
+
+// GetValue provides a mock function with given fields: ctx, in, opts
+func (_m *ValueService) GetValue(ctx context.Context, in *v0.GetValueRequest, opts ...client.CallOption) (*v0.GetValueResponse, error) {
+	_va := make([]interface{}, len(opts))
+	for _i := range opts {
+		_va[_i] = opts[_i]
+	}
+	var _ca []interface{}
+	_ca = append(_ca, ctx, in)
+	_ca = append(_ca, _va...)
+	ret := _m.Called(_ca...)
+
+	if len(ret) == 0 {
+		panic("no return value specified for GetValue")
+	}
+
+	var r0 *v0.GetValueResponse
+	var r1 error
+	if rf, ok := ret.Get(0).(func(context.Context, *v0.GetValueRequest, ...client.CallOption) (*v0.GetValueResponse, error)); ok {
+		return rf(ctx, in, opts...)
+	}
+	if rf, ok := ret.Get(0).(func(context.Context, *v0.GetValueRequest, ...client.CallOption) *v0.GetValueResponse); ok {
+		r0 = rf(ctx, in, opts...)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(*v0.GetValueResponse)
+		}
+	}
+
+	if rf, ok := ret.Get(1).(func(context.Context, *v0.GetValueRequest, ...client.CallOption) error); ok {
+		r1 = rf(ctx, in, opts...)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// ValueService_GetValue_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetValue'
+type ValueService_GetValue_Call struct {
+	*mock.Call
+}
+
+// GetValue is a helper method to define mock.On call
+//   - ctx context.Context
+//   - in *v0.GetValueRequest
+//   - opts ...client.CallOption
+func (_e *ValueService_Expecter) GetValue(ctx interface{}, in interface{}, opts ...interface{}) *ValueService_GetValue_Call {
+	return &ValueService_GetValue_Call{Call: _e.mock.On("GetValue",
+		append([]interface{}{ctx, in}, opts...)...)}
+}
+
+func (_c *ValueService_GetValue_Call) Run(run func(ctx context.Context, in *v0.GetValueRequest, opts ...client.CallOption)) *ValueService_GetValue_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		variadicArgs := make([]client.CallOption, len(args)-2)
+		for i, a := range args[2:] {
+			if a != nil {
+				variadicArgs[i] = a.(client.CallOption)
+			}
+		}
+		run(args[0].(context.Context), args[1].(*v0.GetValueRequest), variadicArgs...)
+	})
+	return _c
+}
+
+func (_c *ValueService_GetValue_Call) Return(_a0 *v0.GetValueResponse, _a1 error) *ValueService_GetValue_Call {
+	_c.Call.Return(_a0, _a1)
+	return _c
+}
+
+func (_c *ValueService_GetValue_Call) RunAndReturn(run func(context.Context, *v0.GetValueRequest, ...client.CallOption) (*v0.GetValueResponse, error)) *ValueService_GetValue_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// GetValueByUniqueIdentifiers provides a mock function with given fields: ctx, in, opts
+func (_m *ValueService) GetValueByUniqueIdentifiers(ctx context.Context, in *v0.GetValueByUniqueIdentifiersRequest, opts ...client.CallOption) (*v0.GetValueResponse, error) {
+	_va := make([]interface{}, len(opts))
+	for _i := range opts {
+		_va[_i] = opts[_i]
+	}
+	var _ca []interface{}
+	_ca = append(_ca, ctx, in)
+	_ca = append(_ca, _va...)
+	ret := _m.Called(_ca...)
+
+	if len(ret) == 0 {
+		panic("no return value specified for GetValueByUniqueIdentifiers")
+	}
+
+	var r0 *v0.GetValueResponse
+	var r1 error
+	if rf, ok := ret.Get(0).(func(context.Context, *v0.GetValueByUniqueIdentifiersRequest, ...client.CallOption) (*v0.GetValueResponse, error)); ok {
+		return rf(ctx, in, opts...)
+	}
+	if rf, ok := ret.Get(0).(func(context.Context, *v0.GetValueByUniqueIdentifiersRequest, ...client.CallOption) *v0.GetValueResponse); ok {
+		r0 = rf(ctx, in, opts...)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(*v0.GetValueResponse)
+		}
+	}
+
+	if rf, ok := ret.Get(1).(func(context.Context, *v0.GetValueByUniqueIdentifiersRequest, ...client.CallOption) error); ok {
+		r1 = rf(ctx, in, opts...)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// ValueService_GetValueByUniqueIdentifiers_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetValueByUniqueIdentifiers'
+type ValueService_GetValueByUniqueIdentifiers_Call struct {
+	*mock.Call
+}
+
+// GetValueByUniqueIdentifiers is a helper method to define mock.On call
+//   - ctx context.Context
+//   - in *v0.GetValueByUniqueIdentifiersRequest
+//   - opts ...client.CallOption
+func (_e *ValueService_Expecter) GetValueByUniqueIdentifiers(ctx interface{}, in interface{}, opts ...interface{}) *ValueService_GetValueByUniqueIdentifiers_Call {
+	return &ValueService_GetValueByUniqueIdentifiers_Call{Call: _e.mock.On("GetValueByUniqueIdentifiers",
+		append([]interface{}{ctx, in}, opts...)...)}
+}
+
+func (_c *ValueService_GetValueByUniqueIdentifiers_Call) Run(run func(ctx context.Context, in *v0.GetValueByUniqueIdentifiersRequest, opts ...client.CallOption)) *ValueService_GetValueByUniqueIdentifiers_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		variadicArgs := make([]client.CallOption, len(args)-2)
+		for i, a := range args[2:] {
+			if a != nil {
+				variadicArgs[i] = a.(client.CallOption)
+			}
+		}
+		run(args[0].(context.Context), args[1].(*v0.GetValueByUniqueIdentifiersRequest), variadicArgs...)
+	})
+	return _c
+}
+
+func (_c *ValueService_GetValueByUniqueIdentifiers_Call) Return(_a0 *v0.GetValueResponse, _a1 error) *ValueService_GetValueByUniqueIdentifiers_Call {
+	_c.Call.Return(_a0, _a1)
+	return _c
+}
+
+func (_c *ValueService_GetValueByUniqueIdentifiers_Call) RunAndReturn(run func(context.Context, *v0.GetValueByUniqueIdentifiersRequest, ...client.CallOption) (*v0.GetValueResponse, error)) *ValueService_GetValueByUniqueIdentifiers_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// ListValues provides a mock function with given fields: ctx, in, opts
+func (_m *ValueService) ListValues(ctx context.Context, in *v0.ListValuesRequest, opts ...client.CallOption) (*v0.ListValuesResponse, error) {
+	_va := make([]interface{}, len(opts))
+	for _i := range opts {
+		_va[_i] = opts[_i]
+	}
+	var _ca []interface{}
+	_ca = append(_ca, ctx, in)
+	_ca = append(_ca, _va...)
+	ret := _m.Called(_ca...)
+
+	if len(ret) == 0 {
+		panic("no return value specified for ListValues")
+	}
+
+	var r0 *v0.ListValuesResponse
+	var r1 error
+	if rf, ok := ret.Get(0).(func(context.Context, *v0.ListValuesRequest, ...client.CallOption) (*v0.ListValuesResponse, error)); ok {
+		return rf(ctx, in, opts...)
+	}
+	if rf, ok := ret.Get(0).(func(context.Context, *v0.ListValuesRequest, ...client.CallOption) *v0.ListValuesResponse); ok {
+		r0 = rf(ctx, in, opts...)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(*v0.ListValuesResponse)
+		}
+	}
+
+	if rf, ok := ret.Get(1).(func(context.Context, *v0.ListValuesRequest, ...client.CallOption) error); ok {
+		r1 = rf(ctx, in, opts...)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// ValueService_ListValues_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListValues'
+type ValueService_ListValues_Call struct {
+	*mock.Call
+}
+
+// ListValues is a helper method to define mock.On call
+//   - ctx context.Context
+//   - in *v0.ListValuesRequest
+//   - opts ...client.CallOption
+func (_e *ValueService_Expecter) ListValues(ctx interface{}, in interface{}, opts ...interface{}) *ValueService_ListValues_Call {
+	return &ValueService_ListValues_Call{Call: _e.mock.On("ListValues",
+		append([]interface{}{ctx, in}, opts...)...)}
+}
+
+func (_c *ValueService_ListValues_Call) Run(run func(ctx context.Context, in *v0.ListValuesRequest, opts ...client.CallOption)) *ValueService_ListValues_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		variadicArgs := make([]client.CallOption, len(args)-2)
+		for i, a := range args[2:] {
+			if a != nil {
+				variadicArgs[i] = a.(client.CallOption)
+			}
+		}
+		run(args[0].(context.Context), args[1].(*v0.ListValuesRequest), variadicArgs...)
+	})
+	return _c
+}
+
+func (_c *ValueService_ListValues_Call) Return(_a0 *v0.ListValuesResponse, _a1 error) *ValueService_ListValues_Call {
+	_c.Call.Return(_a0, _a1)
+	return _c
+}
+
+func (_c *ValueService_ListValues_Call) RunAndReturn(run func(context.Context, *v0.ListValuesRequest, ...client.CallOption) (*v0.ListValuesResponse, error)) *ValueService_ListValues_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// SaveValue provides a mock function with given fields: ctx, in, opts
+func (_m *ValueService) SaveValue(ctx context.Context, in *v0.SaveValueRequest, opts ...client.CallOption) (*v0.SaveValueResponse, error) {
+	_va := make([]interface{}, len(opts))
+	for _i := range opts {
+		_va[_i] = opts[_i]
+	}
+	var _ca []interface{}
+	_ca = append(_ca, ctx, in)
+	_ca = append(_ca, _va...)
+	ret := _m.Called(_ca...)
+
+	if len(ret) == 0 {
+		panic("no return value specified for SaveValue")
+	}
+
+	var r0 *v0.SaveValueResponse
+	var r1 error
+	if rf, ok := ret.Get(0).(func(context.Context, *v0.SaveValueRequest, ...client.CallOption) (*v0.SaveValueResponse, error)); ok {
+		return rf(ctx, in, opts...)
+	}
+	if rf, ok := ret.Get(0).(func(context.Context, *v0.SaveValueRequest, ...client.CallOption) *v0.SaveValueResponse); ok {
+		r0 = rf(ctx, in, opts...)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(*v0.SaveValueResponse)
+		}
+	}
+
+	if rf, ok := ret.Get(1).(func(context.Context, *v0.SaveValueRequest, ...client.CallOption) error); ok {
+		r1 = rf(ctx, in, opts...)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// ValueService_SaveValue_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SaveValue'
+type ValueService_SaveValue_Call struct {
+	*mock.Call
+}
+
+// SaveValue is a helper method to define mock.On call
+//   - ctx context.Context
+//   - in *v0.SaveValueRequest
+//   - opts ...client.CallOption
+func (_e *ValueService_Expecter) SaveValue(ctx interface{}, in interface{}, opts ...interface{}) *ValueService_SaveValue_Call {
+	return &ValueService_SaveValue_Call{Call: _e.mock.On("SaveValue",
+		append([]interface{}{ctx, in}, opts...)...)}
+}
+
+func (_c *ValueService_SaveValue_Call) Run(run func(ctx context.Context, in *v0.SaveValueRequest, opts ...client.CallOption)) *ValueService_SaveValue_Call {
+	_c.Call.Run(func(args mock.Arguments) {
+		variadicArgs := make([]client.CallOption, len(args)-2)
+		for i, a := range args[2:] {
+			if a != nil {
+				variadicArgs[i] = a.(client.CallOption)
+			}
+		}
+		run(args[0].(context.Context), args[1].(*v0.SaveValueRequest), variadicArgs...)
+	})
+	return _c
+}
+
+func (_c *ValueService_SaveValue_Call) Return(_a0 *v0.SaveValueResponse, _a1 error) *ValueService_SaveValue_Call {
+	_c.Call.Return(_a0, _a1)
+	return _c
+}
+
+func (_c *ValueService_SaveValue_Call) RunAndReturn(run func(context.Context, *v0.SaveValueRequest, ...client.CallOption) (*v0.SaveValueResponse, error)) *ValueService_SaveValue_Call {
+	_c.Call.Return(run)
+	return _c
+}
+
+// NewValueService creates a new instance of ValueService. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+// The first argument is typically a *testing.T value.
+func NewValueService(t interface {
+	mock.TestingT
+	Cleanup(func())
+}) *ValueService {
+	mock := &ValueService{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/services/graph/pkg/service/v0/graph.go b/services/graph/pkg/service/v0/graph.go
index 33893e18e2e..92edfcb2b51 100644
--- a/services/graph/pkg/service/v0/graph.go
+++ b/services/graph/pkg/service/v0/graph.go
@@ -31,6 +31,8 @@ import (
 	"github.com/owncloud/ocis/v2/services/graph/pkg/identity"
 )
 
+//go:generate make -C ../../.. generate
+
 // Publisher is the interface for events publisher
 type Publisher interface {
 	Publish(string, interface{}, ...mevents.PublishOption) error
diff --git a/services/graph/pkg/service/v0/sharedwithme.go b/services/graph/pkg/service/v0/sharedwithme.go
index 261de483c34..73558f324fd 100644
--- a/services/graph/pkg/service/v0/sharedwithme.go
+++ b/services/graph/pkg/service/v0/sharedwithme.go
@@ -4,16 +4,17 @@ import (
 	"context"
 	"net/http"
 	"reflect"
+	"slices"
 
 	cs3User "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
 	collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1"
 	storageprovider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
+	"github.com/cs3org/reva/v2/pkg/utils"
 	"github.com/go-chi/render"
 	libregraph "github.com/owncloud/libre-graph-api-go"
 	"golang.org/x/sync/errgroup"
 
 	"github.com/cs3org/reva/v2/pkg/storagespace"
-	"github.com/cs3org/reva/v2/pkg/utils"
 
 	"github.com/owncloud/ocis/v2/services/graph/pkg/errorcode"
 	"github.com/owncloud/ocis/v2/services/graph/pkg/unifiedrole"
@@ -47,16 +48,6 @@ func (g Graph) listSharedWithMe(ctx context.Context) ([]libregraph.DriveItem, er
 		return nil, *errCode
 	}
 
-	return g.cs3ReceivedSharesToDriveItems(ctx, listReceivedSharesResponse.GetShares())
-}
-
-func (g Graph) cs3ReceivedSharesToDriveItems(ctx context.Context, receivedShares []*collaboration.ReceivedShare) ([]libregraph.DriveItem, error) {
-	gatewayClient, err := g.gatewaySelector.Next()
-	if err != nil {
-		g.logger.Error().Err(err).Msg("could not select next gateway client")
-		return nil, err
-	}
-
 	// doStat is a helper function that stat a resource.
 	doStat := func(resourceId *storageprovider.ResourceId) (*storageprovider.StatResponse, error) {
 		shareStat, err := gatewayClient.Stat(ctx, &storageprovider.StatRequest{
@@ -76,87 +67,28 @@ func (g Graph) cs3ReceivedSharesToDriveItems(ctx context.Context, receivedShares
 		return shareStat, nil
 	}
 
-	ch := make(chan libregraph.DriveItem)
 	group := new(errgroup.Group)
-	// Set max concurrency
-	group.SetLimit(10)
-
-	receivedSharesByResourceID := make(map[string][]*collaboration.ReceivedShare, len(receivedShares))
-	for _, receivedShare := range receivedShares {
-		rIDStr := storagespace.FormatResourceID(*receivedShare.GetShare().GetResourceId())
-		receivedSharesByResourceID[rIDStr] = append(receivedSharesByResourceID[rIDStr], receivedShare)
-	}
+	receivedShares := listReceivedSharesResponse.GetShares()
+	driveItems := make([]libregraph.DriveItem, len(receivedShares))
 
-	for _, receivedSharesForResource := range receivedSharesByResourceID {
-		receivedShares := receivedSharesForResource
+	for i, receivedShare := range receivedShares {
+		i, receivedShare := i, receivedShare
 
 		group.Go(func() error {
-			var err error // redeclare
-			resourceID := receivedShares[0].GetShare().GetResourceId()
-			shareStat, err := doStat(receivedShares[0].GetShare().GetResourceId())
+			shareStat, err := doStat(receivedShare.GetShare().GetResourceId())
 			if shareStat == nil || err != nil {
 				return err
 			}
 
-			driveItem := libregraph.NewDriveItem()
-
-			// The id of the driveItem will be the composed of the StorageID and the SpaceID of the sharestorage
-			// appended with the ResourceID of the shared resource
-			// '<sharestorageid>$<sharespaceid>!<resource's storageid>:<resource's spaceid>:<resource's opaque id>'
-			driveItem.SetId(storagespace.FormatResourceID(storageprovider.ResourceId{
-				StorageId: utils.ShareStorageProviderID,
-				OpaqueId:  resourceID.GetStorageId() + ":" + resourceID.GetSpaceId() + ":" + resourceID.GetOpaqueId(),
-				SpaceId:   utils.ShareStorageSpaceID,
-			}))
-			permissions := make([]libregraph.Permission, 0, len(receivedShares))
-
-			for _, receivedShare := range receivedShares {
-				permission, err := g.cs3ReceivedShareToLibreGraphPermissions(ctx, receivedShare)
-				if err != nil {
-					return err
-				}
-
-				// If at least one of the shares was accepted, we consider the driveItem's synchronized
-				// flag enabled.
-				// Also we use the Mountpoint name of the first accepted mountpoint as the name of
-				// of the driveItem
-				if receivedShare.GetState() == collaboration.ShareState_SHARE_STATE_ACCEPTED {
-					driveItem.SetClientSynchronize(true)
-					if name := receivedShare.GetMountPoint().GetPath(); name != "" && driveItem.GetName() == "" {
-						driveItem.SetName(receivedShare.GetMountPoint().GetPath())
-					}
-				}
-
-				// if at least one share is marked as hidden, consider the whole driveItem to be hidden
-				if receivedShare.GetHidden() {
-					driveItem.SetUIHidden(true)
-				}
-
-				if userID := receivedShare.GetShare().GetCreator(); userID != nil {
-					identity, err := g.cs3UserIdToIdentity(ctx, userID)
-					if err != nil {
-						g.logger.Warn().Err(err).Str("userid", userID.String()).Msg("could not get creator of the share")
-					}
-
-					permission.SetInvitation(
-						libregraph.SharingInvitation{
-							InvitedBy: &libregraph.IdentitySet{
-								User: &identity,
-							},
-						},
-					)
-				}
-				permissions = append(permissions, *permission)
-
+			permission, err := g.cs3ReceivedShareToLibreGraphPermissions(ctx, receivedShare, shareStat.GetInfo())
+			if err != nil {
+				return err
 			}
 
-			if !driveItem.HasUIHidden() {
-				driveItem.SetUIHidden(false)
-			}
-			if !driveItem.HasClientSynchronize() {
-				driveItem.SetClientSynchronize(false)
-				if name := shareStat.GetInfo().GetName(); name != "" {
-					driveItem.SetName(name)
+			shared := libregraph.NewShared()
+			{
+				if cTime := receivedShare.GetShare().GetCtime(); cTime != nil {
+					shared.SetSharedDateTime(cs3TimestampToTime(cTime))
 				}
 			}
 
@@ -196,18 +128,43 @@ func (g Graph) cs3ReceivedSharesToDriveItems(ctx context.Context, receivedShares
 
 			}
 
-			// the parentReference of the outer driveItem should be the drive
-			// containing the mountpoint i.e. the share jail
-			driveItem.ParentReference = libregraph.NewItemReference()
-			driveItem.ParentReference.SetDriveType("virtual")
-			driveItem.ParentReference.SetDriveId(storagespace.FormatStorageID(utils.ShareStorageProviderID, utils.ShareStorageSpaceID))
-			driveItem.ParentReference.SetId(storagespace.FormatResourceID(storageprovider.ResourceId{
-				StorageId: utils.ShareStorageProviderID,
-				OpaqueId:  utils.ShareStorageSpaceID,
-				SpaceId:   utils.ShareStorageSpaceID,
-			}))
-			if etag := shareStat.GetInfo().GetEtag(); etag != "" {
-				driveItem.SetETag(etag)
+			driveItem := libregraph.NewDriveItem()
+
+			// handle share state related stuff
+			switch receivedShare.GetState() {
+			case collaboration.ShareState_SHARE_STATE_ACCEPTED:
+
+				driveItem.SetId(storagespace.FormatResourceID(storageprovider.ResourceId{
+					StorageId: utils.ShareStorageProviderID,
+					OpaqueId:  receivedShare.GetShare().GetId().GetOpaqueId(),
+					SpaceId:   utils.ShareStorageSpaceID,
+				}))
+
+				if name := receivedShare.GetMountPoint().GetPath(); name != "" {
+					driveItem.SetName(receivedShare.GetMountPoint().GetPath())
+				}
+
+				if etag := shareStat.GetInfo().GetEtag(); etag != "" {
+					driveItem.SetETag(etag)
+				}
+
+				// parentReference of the out driveItem should be the drive containing the mountpoint
+				// i.e. the share jail
+				driveItem.ParentReference = libregraph.NewItemReference()
+				driveItem.ParentReference.SetDriveType("virtual")
+				driveItem.ParentReference.SetDriveId(storagespace.FormatStorageID(utils.ShareStorageProviderID, utils.ShareStorageSpaceID))
+				driveItem.ParentReference.SetId(storagespace.FormatResourceID(storageprovider.ResourceId{
+					StorageId: utils.ShareStorageProviderID,
+					OpaqueId:  utils.ShareStorageSpaceID,
+					SpaceId:   utils.ShareStorageSpaceID,
+				}))
+
+			case collaboration.ShareState_SHARE_STATE_PENDING:
+				fallthrough
+			case collaboration.ShareState_SHARE_STATE_REJECTED:
+				if name := shareStat.GetInfo().GetName(); name != "" {
+					driveItem.SetName(name)
+				}
 			}
 
 			// connect the dots
@@ -226,7 +183,7 @@ func (g Graph) cs3ReceivedSharesToDriveItems(ctx context.Context, receivedShares
 					remoteItem.SetSize(s)
 				}
 
-				if userID := shareStat.GetInfo().GetOwner(); userID != nil && userID.Type != cs3User.UserType_USER_TYPE_SPACE_OWNER {
+				if userID := shareStat.GetInfo().GetOwner(); userID != nil {
 					identity, err := g.cs3UserIdToIdentity(ctx, userID)
 					if err != nil {
 						// TODO: define a proper error behavior here. We don't
@@ -241,6 +198,25 @@ func (g Graph) cs3ReceivedSharesToDriveItems(ctx context.Context, receivedShares
 					remoteItem.SetCreatedBy(libregraph.IdentitySet{User: &identity})
 					driveItem.SetCreatedBy(libregraph.IdentitySet{User: &identity})
 				}
+
+				if userID := receivedShare.GetShare().GetOwner(); userID != nil {
+					identity, err := g.cs3UserIdToIdentity(ctx, userID)
+					if err != nil {
+						g.logger.Warn().Err(err).Str("userid", userID.String()).Msg("could not get owner of the share")
+					}
+					shared.SetOwner(libregraph.IdentitySet{User: &identity})
+				}
+
+				if userID := receivedShare.GetShare().GetCreator(); userID != nil {
+					identity, err := g.cs3UserIdToIdentity(ctx, userID)
+					if err != nil {
+						g.logger.Warn().Err(err).Str("userid", userID.String()).Msg("could not get creator of the share")
+					}
+
+					shared.SetSharedBy(libregraph.IdentitySet{User: &identity})
+
+				}
+
 				switch info := shareStat.GetInfo(); {
 				case info.GetType() == storageprovider.ResourceType_RESOURCE_TYPE_CONTAINER:
 					folder := libregraph.NewFolder()
@@ -258,7 +234,13 @@ func (g Graph) cs3ReceivedSharesToDriveItems(ctx context.Context, receivedShares
 					driveItem.File = file
 				}
 
-				if len(permissions) > 0 {
+				if !reflect.ValueOf(*shared).IsZero() {
+					remoteItem.Shared = shared
+				}
+
+				if !reflect.ValueOf(*permission).IsZero() {
+					permissions := []libregraph.Permission{*permission}
+
 					remoteItem.Permissions = permissions
 				}
 
@@ -267,27 +249,22 @@ func (g Graph) cs3ReceivedSharesToDriveItems(ctx context.Context, receivedShares
 				}
 			}
 
-			ch <- *driveItem
+			driveItems[i] = *driveItem
 
 			return nil
 		})
 	}
 
 	// wait for concurrent requests to finish
-	go func() {
-		err = group.Wait()
-		close(ch)
-	}()
-
-	driveItems := make([]libregraph.DriveItem, 0, len(receivedSharesByResourceID))
-	for di := range ch {
-		driveItems = append(driveItems, di)
-	}
+	err = group.Wait()
 
-	return driveItems, err
+	// filter out empty drive items
+	return slices.Clip(slices.DeleteFunc(driveItems, func(item libregraph.DriveItem) bool {
+		return reflect.ValueOf(item).IsZero()
+	})), err
 }
 
-func (g Graph) cs3ReceivedShareToLibreGraphPermissions(ctx context.Context, receivedShare *collaboration.ReceivedShare) (*libregraph.Permission, error) {
+func (g Graph) cs3ReceivedShareToLibreGraphPermissions(ctx context.Context, receivedShare *collaboration.ReceivedShare, shareStatInfo *storageprovider.ResourceInfo) (*libregraph.Permission, error) {
 	permission := libregraph.NewPermission()
 	if id := receivedShare.GetShare().GetId().GetOpaqueId(); id != "" {
 		permission.SetId(id)
@@ -297,7 +274,7 @@ func (g Graph) cs3ReceivedShareToLibreGraphPermissions(ctx context.Context, rece
 		permission.SetExpirationDateTime(cs3TimestampToTime(expiration))
 	}
 
-	if permissionSet := receivedShare.GetShare().GetPermissions().GetPermissions(); permissionSet != nil {
+	if permissionSet := shareStatInfo.GetPermissionSet(); permissionSet != nil {
 		role := unifiedrole.CS3ResourcePermissionsToUnifiedRole(
 			*permissionSet,
 			unifiedrole.UnifiedRoleConditionGrantee,
@@ -344,6 +321,8 @@ func (g Graph) cs3ReceivedShareToLibreGraphPermissions(ctx context.Context, rece
 			},
 		})
 	}
+	permission.SetUiHidden(receivedShare.GetHidden())
+	permission.SetClientSynchronize(receivedShare.GetState() == collaboration.ShareState_SHARE_STATE_ACCEPTED)
 
 	return permission, nil
 }
diff --git a/services/proxy/.mockery.yaml b/services/proxy/.mockery.yaml
deleted file mode 100644
index fe7d02d7885..00000000000
--- a/services/proxy/.mockery.yaml
+++ /dev/null
@@ -1,15 +0,0 @@
-with-expecter: true
-filename: "{{.InterfaceName | snakecase }}.go"
-mockname: "{{.InterfaceName}}"
-outpkg: "mocks"
-packages:
-    github.com/owncloud/ocis/v2/services/proxy/pkg/user/backend:
-        config:
-          dir: "pkg/user/backend/mocks"
-        interfaces:
-            UserBackend:
-    github.com/owncloud/ocis/v2/services/proxy/pkg/userroles:
-        config:
-          dir: "pkg/userroles/mocks"
-        interfaces:
-            UserRoleAssigner:
diff --git a/services/proxy/Makefile b/services/proxy/Makefile
index 7aa5c0a96e2..44e10f95e46 100644
--- a/services/proxy/Makefile
+++ b/services/proxy/Makefile
@@ -24,8 +24,7 @@ docs-generate: config-docs-generate
 include ../../.make/generate.mk
 
 .PHONY: ci-go-generate
-ci-go-generate: $(MOCKERY) # CI runs ci-node-generate automatically before this target
-	$(MOCKERY)
+ci-go-generate: # CI runs ci-node-generate automatically before this target
 
 .PHONY: ci-node-generate
 ci-node-generate:
diff --git a/services/proxy/pkg/user/backend/mocks/UserBackend.go b/services/proxy/pkg/user/backend/mocks/UserBackend.go
new file mode 100644
index 00000000000..76fe443c0cb
--- /dev/null
+++ b/services/proxy/pkg/user/backend/mocks/UserBackend.go
@@ -0,0 +1,113 @@
+// Code generated by mockery v2.14.0. DO NOT EDIT.
+
+package mocks
+
+import (
+	context "context"
+
+	userv1beta1 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
+	mock "github.com/stretchr/testify/mock"
+)
+
+// UserBackend is an autogenerated mock type for the UserBackend type
+type UserBackend struct {
+	mock.Mock
+}
+
+// Authenticate provides a mock function with given fields: ctx, username, password
+func (_m *UserBackend) Authenticate(ctx context.Context, username string, password string) (*userv1beta1.User, string, error) {
+	ret := _m.Called(ctx, username, password)
+
+	var r0 *userv1beta1.User
+	if rf, ok := ret.Get(0).(func(context.Context, string, string) *userv1beta1.User); ok {
+		r0 = rf(ctx, username, password)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(*userv1beta1.User)
+		}
+	}
+
+	var r1 string
+	if rf, ok := ret.Get(1).(func(context.Context, string, string) string); ok {
+		r1 = rf(ctx, username, password)
+	} else {
+		r1 = ret.Get(1).(string)
+	}
+
+	var r2 error
+	if rf, ok := ret.Get(2).(func(context.Context, string, string) error); ok {
+		r2 = rf(ctx, username, password)
+	} else {
+		r2 = ret.Error(2)
+	}
+
+	return r0, r1, r2
+}
+
+// CreateUserFromClaims provides a mock function with given fields: ctx, claims
+func (_m *UserBackend) CreateUserFromClaims(ctx context.Context, claims map[string]interface{}) (*userv1beta1.User, error) {
+	ret := _m.Called(ctx, claims)
+
+	var r0 *userv1beta1.User
+	if rf, ok := ret.Get(0).(func(context.Context, map[string]interface{}) *userv1beta1.User); ok {
+		r0 = rf(ctx, claims)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(*userv1beta1.User)
+		}
+	}
+
+	var r1 error
+	if rf, ok := ret.Get(1).(func(context.Context, map[string]interface{}) error); ok {
+		r1 = rf(ctx, claims)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// GetUserByClaims provides a mock function with given fields: ctx, claim, value
+func (_m *UserBackend) GetUserByClaims(ctx context.Context, claim string, value string) (*userv1beta1.User, string, error) {
+	ret := _m.Called(ctx, claim, value)
+
+	var r0 *userv1beta1.User
+	if rf, ok := ret.Get(0).(func(context.Context, string, string) *userv1beta1.User); ok {
+		r0 = rf(ctx, claim, value)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(*userv1beta1.User)
+		}
+	}
+
+	var r1 string
+	if rf, ok := ret.Get(1).(func(context.Context, string, string) string); ok {
+		r1 = rf(ctx, claim, value)
+	} else {
+		r1 = ret.Get(1).(string)
+	}
+
+	var r2 error
+	if rf, ok := ret.Get(2).(func(context.Context, string, string) error); ok {
+		r2 = rf(ctx, claim, value)
+	} else {
+		r2 = ret.Error(2)
+	}
+
+	return r0, r1, r2
+}
+
+type mockConstructorTestingTNewUserBackend interface {
+	mock.TestingT
+	Cleanup(func())
+}
+
+// NewUserBackend creates a new instance of UserBackend. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+func NewUserBackend(t mockConstructorTestingTNewUserBackend) *UserBackend {
+	mock := &UserBackend{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/services/proxy/pkg/user/backend/mocks/user_backend.go b/services/proxy/pkg/user/backend/mocks/user_backend.go
deleted file mode 100644
index c625438af96..00000000000
--- a/services/proxy/pkg/user/backend/mocks/user_backend.go
+++ /dev/null
@@ -1,230 +0,0 @@
-// Code generated by mockery v2.40.1. DO NOT EDIT.
-
-package mocks
-
-import (
-	context "context"
-
-	userv1beta1 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
-	mock "github.com/stretchr/testify/mock"
-)
-
-// UserBackend is an autogenerated mock type for the UserBackend type
-type UserBackend struct {
-	mock.Mock
-}
-
-type UserBackend_Expecter struct {
-	mock *mock.Mock
-}
-
-func (_m *UserBackend) EXPECT() *UserBackend_Expecter {
-	return &UserBackend_Expecter{mock: &_m.Mock}
-}
-
-// Authenticate provides a mock function with given fields: ctx, username, password
-func (_m *UserBackend) Authenticate(ctx context.Context, username string, password string) (*userv1beta1.User, string, error) {
-	ret := _m.Called(ctx, username, password)
-
-	if len(ret) == 0 {
-		panic("no return value specified for Authenticate")
-	}
-
-	var r0 *userv1beta1.User
-	var r1 string
-	var r2 error
-	if rf, ok := ret.Get(0).(func(context.Context, string, string) (*userv1beta1.User, string, error)); ok {
-		return rf(ctx, username, password)
-	}
-	if rf, ok := ret.Get(0).(func(context.Context, string, string) *userv1beta1.User); ok {
-		r0 = rf(ctx, username, password)
-	} else {
-		if ret.Get(0) != nil {
-			r0 = ret.Get(0).(*userv1beta1.User)
-		}
-	}
-
-	if rf, ok := ret.Get(1).(func(context.Context, string, string) string); ok {
-		r1 = rf(ctx, username, password)
-	} else {
-		r1 = ret.Get(1).(string)
-	}
-
-	if rf, ok := ret.Get(2).(func(context.Context, string, string) error); ok {
-		r2 = rf(ctx, username, password)
-	} else {
-		r2 = ret.Error(2)
-	}
-
-	return r0, r1, r2
-}
-
-// UserBackend_Authenticate_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Authenticate'
-type UserBackend_Authenticate_Call struct {
-	*mock.Call
-}
-
-// Authenticate is a helper method to define mock.On call
-//   - ctx context.Context
-//   - username string
-//   - password string
-func (_e *UserBackend_Expecter) Authenticate(ctx interface{}, username interface{}, password interface{}) *UserBackend_Authenticate_Call {
-	return &UserBackend_Authenticate_Call{Call: _e.mock.On("Authenticate", ctx, username, password)}
-}
-
-func (_c *UserBackend_Authenticate_Call) Run(run func(ctx context.Context, username string, password string)) *UserBackend_Authenticate_Call {
-	_c.Call.Run(func(args mock.Arguments) {
-		run(args[0].(context.Context), args[1].(string), args[2].(string))
-	})
-	return _c
-}
-
-func (_c *UserBackend_Authenticate_Call) Return(_a0 *userv1beta1.User, _a1 string, _a2 error) *UserBackend_Authenticate_Call {
-	_c.Call.Return(_a0, _a1, _a2)
-	return _c
-}
-
-func (_c *UserBackend_Authenticate_Call) RunAndReturn(run func(context.Context, string, string) (*userv1beta1.User, string, error)) *UserBackend_Authenticate_Call {
-	_c.Call.Return(run)
-	return _c
-}
-
-// CreateUserFromClaims provides a mock function with given fields: ctx, claims
-func (_m *UserBackend) CreateUserFromClaims(ctx context.Context, claims map[string]interface{}) (*userv1beta1.User, error) {
-	ret := _m.Called(ctx, claims)
-
-	if len(ret) == 0 {
-		panic("no return value specified for CreateUserFromClaims")
-	}
-
-	var r0 *userv1beta1.User
-	var r1 error
-	if rf, ok := ret.Get(0).(func(context.Context, map[string]interface{}) (*userv1beta1.User, error)); ok {
-		return rf(ctx, claims)
-	}
-	if rf, ok := ret.Get(0).(func(context.Context, map[string]interface{}) *userv1beta1.User); ok {
-		r0 = rf(ctx, claims)
-	} else {
-		if ret.Get(0) != nil {
-			r0 = ret.Get(0).(*userv1beta1.User)
-		}
-	}
-
-	if rf, ok := ret.Get(1).(func(context.Context, map[string]interface{}) error); ok {
-		r1 = rf(ctx, claims)
-	} else {
-		r1 = ret.Error(1)
-	}
-
-	return r0, r1
-}
-
-// UserBackend_CreateUserFromClaims_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreateUserFromClaims'
-type UserBackend_CreateUserFromClaims_Call struct {
-	*mock.Call
-}
-
-// CreateUserFromClaims is a helper method to define mock.On call
-//   - ctx context.Context
-//   - claims map[string]interface{}
-func (_e *UserBackend_Expecter) CreateUserFromClaims(ctx interface{}, claims interface{}) *UserBackend_CreateUserFromClaims_Call {
-	return &UserBackend_CreateUserFromClaims_Call{Call: _e.mock.On("CreateUserFromClaims", ctx, claims)}
-}
-
-func (_c *UserBackend_CreateUserFromClaims_Call) Run(run func(ctx context.Context, claims map[string]interface{})) *UserBackend_CreateUserFromClaims_Call {
-	_c.Call.Run(func(args mock.Arguments) {
-		run(args[0].(context.Context), args[1].(map[string]interface{}))
-	})
-	return _c
-}
-
-func (_c *UserBackend_CreateUserFromClaims_Call) Return(_a0 *userv1beta1.User, _a1 error) *UserBackend_CreateUserFromClaims_Call {
-	_c.Call.Return(_a0, _a1)
-	return _c
-}
-
-func (_c *UserBackend_CreateUserFromClaims_Call) RunAndReturn(run func(context.Context, map[string]interface{}) (*userv1beta1.User, error)) *UserBackend_CreateUserFromClaims_Call {
-	_c.Call.Return(run)
-	return _c
-}
-
-// GetUserByClaims provides a mock function with given fields: ctx, claim, value
-func (_m *UserBackend) GetUserByClaims(ctx context.Context, claim string, value string) (*userv1beta1.User, string, error) {
-	ret := _m.Called(ctx, claim, value)
-
-	if len(ret) == 0 {
-		panic("no return value specified for GetUserByClaims")
-	}
-
-	var r0 *userv1beta1.User
-	var r1 string
-	var r2 error
-	if rf, ok := ret.Get(0).(func(context.Context, string, string) (*userv1beta1.User, string, error)); ok {
-		return rf(ctx, claim, value)
-	}
-	if rf, ok := ret.Get(0).(func(context.Context, string, string) *userv1beta1.User); ok {
-		r0 = rf(ctx, claim, value)
-	} else {
-		if ret.Get(0) != nil {
-			r0 = ret.Get(0).(*userv1beta1.User)
-		}
-	}
-
-	if rf, ok := ret.Get(1).(func(context.Context, string, string) string); ok {
-		r1 = rf(ctx, claim, value)
-	} else {
-		r1 = ret.Get(1).(string)
-	}
-
-	if rf, ok := ret.Get(2).(func(context.Context, string, string) error); ok {
-		r2 = rf(ctx, claim, value)
-	} else {
-		r2 = ret.Error(2)
-	}
-
-	return r0, r1, r2
-}
-
-// UserBackend_GetUserByClaims_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetUserByClaims'
-type UserBackend_GetUserByClaims_Call struct {
-	*mock.Call
-}
-
-// GetUserByClaims is a helper method to define mock.On call
-//   - ctx context.Context
-//   - claim string
-//   - value string
-func (_e *UserBackend_Expecter) GetUserByClaims(ctx interface{}, claim interface{}, value interface{}) *UserBackend_GetUserByClaims_Call {
-	return &UserBackend_GetUserByClaims_Call{Call: _e.mock.On("GetUserByClaims", ctx, claim, value)}
-}
-
-func (_c *UserBackend_GetUserByClaims_Call) Run(run func(ctx context.Context, claim string, value string)) *UserBackend_GetUserByClaims_Call {
-	_c.Call.Run(func(args mock.Arguments) {
-		run(args[0].(context.Context), args[1].(string), args[2].(string))
-	})
-	return _c
-}
-
-func (_c *UserBackend_GetUserByClaims_Call) Return(_a0 *userv1beta1.User, _a1 string, _a2 error) *UserBackend_GetUserByClaims_Call {
-	_c.Call.Return(_a0, _a1, _a2)
-	return _c
-}
-
-func (_c *UserBackend_GetUserByClaims_Call) RunAndReturn(run func(context.Context, string, string) (*userv1beta1.User, string, error)) *UserBackend_GetUserByClaims_Call {
-	_c.Call.Return(run)
-	return _c
-}
-
-// NewUserBackend creates a new instance of UserBackend. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
-// The first argument is typically a *testing.T value.
-func NewUserBackend(t interface {
-	mock.TestingT
-	Cleanup(func())
-}) *UserBackend {
-	mock := &UserBackend{}
-	mock.Mock.Test(t)
-
-	t.Cleanup(func() { mock.AssertExpectations(t) })
-
-	return mock
-}
diff --git a/services/proxy/pkg/userroles/mocks/UserRoleAssigner.go b/services/proxy/pkg/userroles/mocks/UserRoleAssigner.go
new file mode 100644
index 00000000000..39282c5b904
--- /dev/null
+++ b/services/proxy/pkg/userroles/mocks/UserRoleAssigner.go
@@ -0,0 +1,77 @@
+// Code generated by mockery v2.14.0. DO NOT EDIT.
+
+package mocks
+
+import (
+	context "context"
+
+	mock "github.com/stretchr/testify/mock"
+
+	userv1beta1 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
+)
+
+// UserRoleAssigner is an autogenerated mock type for the UserRoleAssigner type
+type UserRoleAssigner struct {
+	mock.Mock
+}
+
+// ApplyUserRole provides a mock function with given fields: ctx, user
+func (_m *UserRoleAssigner) ApplyUserRole(ctx context.Context, user *userv1beta1.User) (*userv1beta1.User, error) {
+	ret := _m.Called(ctx, user)
+
+	var r0 *userv1beta1.User
+	if rf, ok := ret.Get(0).(func(context.Context, *userv1beta1.User) *userv1beta1.User); ok {
+		r0 = rf(ctx, user)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(*userv1beta1.User)
+		}
+	}
+
+	var r1 error
+	if rf, ok := ret.Get(1).(func(context.Context, *userv1beta1.User) error); ok {
+		r1 = rf(ctx, user)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// UpdateUserRoleAssignment provides a mock function with given fields: ctx, user, claims
+func (_m *UserRoleAssigner) UpdateUserRoleAssignment(ctx context.Context, user *userv1beta1.User, claims map[string]interface{}) (*userv1beta1.User, error) {
+	ret := _m.Called(ctx, user, claims)
+
+	var r0 *userv1beta1.User
+	if rf, ok := ret.Get(0).(func(context.Context, *userv1beta1.User, map[string]interface{}) *userv1beta1.User); ok {
+		r0 = rf(ctx, user, claims)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(*userv1beta1.User)
+		}
+	}
+
+	var r1 error
+	if rf, ok := ret.Get(1).(func(context.Context, *userv1beta1.User, map[string]interface{}) error); ok {
+		r1 = rf(ctx, user, claims)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+type mockConstructorTestingTNewUserRoleAssigner interface {
+	mock.TestingT
+	Cleanup(func())
+}
+
+// NewUserRoleAssigner creates a new instance of UserRoleAssigner. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+func NewUserRoleAssigner(t mockConstructorTestingTNewUserRoleAssigner) *UserRoleAssigner {
+	mock := &UserRoleAssigner{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/services/proxy/pkg/userroles/mocks/user_role_assigner.go b/services/proxy/pkg/userroles/mocks/user_role_assigner.go
deleted file mode 100644
index 3a601b6aa34..00000000000
--- a/services/proxy/pkg/userroles/mocks/user_role_assigner.go
+++ /dev/null
@@ -1,157 +0,0 @@
-// Code generated by mockery v2.40.1. DO NOT EDIT.
-
-package mocks
-
-import (
-	context "context"
-
-	mock "github.com/stretchr/testify/mock"
-
-	userv1beta1 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
-)
-
-// UserRoleAssigner is an autogenerated mock type for the UserRoleAssigner type
-type UserRoleAssigner struct {
-	mock.Mock
-}
-
-type UserRoleAssigner_Expecter struct {
-	mock *mock.Mock
-}
-
-func (_m *UserRoleAssigner) EXPECT() *UserRoleAssigner_Expecter {
-	return &UserRoleAssigner_Expecter{mock: &_m.Mock}
-}
-
-// ApplyUserRole provides a mock function with given fields: ctx, user
-func (_m *UserRoleAssigner) ApplyUserRole(ctx context.Context, user *userv1beta1.User) (*userv1beta1.User, error) {
-	ret := _m.Called(ctx, user)
-
-	if len(ret) == 0 {
-		panic("no return value specified for ApplyUserRole")
-	}
-
-	var r0 *userv1beta1.User
-	var r1 error
-	if rf, ok := ret.Get(0).(func(context.Context, *userv1beta1.User) (*userv1beta1.User, error)); ok {
-		return rf(ctx, user)
-	}
-	if rf, ok := ret.Get(0).(func(context.Context, *userv1beta1.User) *userv1beta1.User); ok {
-		r0 = rf(ctx, user)
-	} else {
-		if ret.Get(0) != nil {
-			r0 = ret.Get(0).(*userv1beta1.User)
-		}
-	}
-
-	if rf, ok := ret.Get(1).(func(context.Context, *userv1beta1.User) error); ok {
-		r1 = rf(ctx, user)
-	} else {
-		r1 = ret.Error(1)
-	}
-
-	return r0, r1
-}
-
-// UserRoleAssigner_ApplyUserRole_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ApplyUserRole'
-type UserRoleAssigner_ApplyUserRole_Call struct {
-	*mock.Call
-}
-
-// ApplyUserRole is a helper method to define mock.On call
-//   - ctx context.Context
-//   - user *userv1beta1.User
-func (_e *UserRoleAssigner_Expecter) ApplyUserRole(ctx interface{}, user interface{}) *UserRoleAssigner_ApplyUserRole_Call {
-	return &UserRoleAssigner_ApplyUserRole_Call{Call: _e.mock.On("ApplyUserRole", ctx, user)}
-}
-
-func (_c *UserRoleAssigner_ApplyUserRole_Call) Run(run func(ctx context.Context, user *userv1beta1.User)) *UserRoleAssigner_ApplyUserRole_Call {
-	_c.Call.Run(func(args mock.Arguments) {
-		run(args[0].(context.Context), args[1].(*userv1beta1.User))
-	})
-	return _c
-}
-
-func (_c *UserRoleAssigner_ApplyUserRole_Call) Return(_a0 *userv1beta1.User, _a1 error) *UserRoleAssigner_ApplyUserRole_Call {
-	_c.Call.Return(_a0, _a1)
-	return _c
-}
-
-func (_c *UserRoleAssigner_ApplyUserRole_Call) RunAndReturn(run func(context.Context, *userv1beta1.User) (*userv1beta1.User, error)) *UserRoleAssigner_ApplyUserRole_Call {
-	_c.Call.Return(run)
-	return _c
-}
-
-// UpdateUserRoleAssignment provides a mock function with given fields: ctx, user, claims
-func (_m *UserRoleAssigner) UpdateUserRoleAssignment(ctx context.Context, user *userv1beta1.User, claims map[string]interface{}) (*userv1beta1.User, error) {
-	ret := _m.Called(ctx, user, claims)
-
-	if len(ret) == 0 {
-		panic("no return value specified for UpdateUserRoleAssignment")
-	}
-
-	var r0 *userv1beta1.User
-	var r1 error
-	if rf, ok := ret.Get(0).(func(context.Context, *userv1beta1.User, map[string]interface{}) (*userv1beta1.User, error)); ok {
-		return rf(ctx, user, claims)
-	}
-	if rf, ok := ret.Get(0).(func(context.Context, *userv1beta1.User, map[string]interface{}) *userv1beta1.User); ok {
-		r0 = rf(ctx, user, claims)
-	} else {
-		if ret.Get(0) != nil {
-			r0 = ret.Get(0).(*userv1beta1.User)
-		}
-	}
-
-	if rf, ok := ret.Get(1).(func(context.Context, *userv1beta1.User, map[string]interface{}) error); ok {
-		r1 = rf(ctx, user, claims)
-	} else {
-		r1 = ret.Error(1)
-	}
-
-	return r0, r1
-}
-
-// UserRoleAssigner_UpdateUserRoleAssignment_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdateUserRoleAssignment'
-type UserRoleAssigner_UpdateUserRoleAssignment_Call struct {
-	*mock.Call
-}
-
-// UpdateUserRoleAssignment is a helper method to define mock.On call
-//   - ctx context.Context
-//   - user *userv1beta1.User
-//   - claims map[string]interface{}
-func (_e *UserRoleAssigner_Expecter) UpdateUserRoleAssignment(ctx interface{}, user interface{}, claims interface{}) *UserRoleAssigner_UpdateUserRoleAssignment_Call {
-	return &UserRoleAssigner_UpdateUserRoleAssignment_Call{Call: _e.mock.On("UpdateUserRoleAssignment", ctx, user, claims)}
-}
-
-func (_c *UserRoleAssigner_UpdateUserRoleAssignment_Call) Run(run func(ctx context.Context, user *userv1beta1.User, claims map[string]interface{})) *UserRoleAssigner_UpdateUserRoleAssignment_Call {
-	_c.Call.Run(func(args mock.Arguments) {
-		run(args[0].(context.Context), args[1].(*userv1beta1.User), args[2].(map[string]interface{}))
-	})
-	return _c
-}
-
-func (_c *UserRoleAssigner_UpdateUserRoleAssignment_Call) Return(_a0 *userv1beta1.User, _a1 error) *UserRoleAssigner_UpdateUserRoleAssignment_Call {
-	_c.Call.Return(_a0, _a1)
-	return _c
-}
-
-func (_c *UserRoleAssigner_UpdateUserRoleAssignment_Call) RunAndReturn(run func(context.Context, *userv1beta1.User, map[string]interface{}) (*userv1beta1.User, error)) *UserRoleAssigner_UpdateUserRoleAssignment_Call {
-	_c.Call.Return(run)
-	return _c
-}
-
-// NewUserRoleAssigner creates a new instance of UserRoleAssigner. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
-// The first argument is typically a *testing.T value.
-func NewUserRoleAssigner(t interface {
-	mock.TestingT
-	Cleanup(func())
-}) *UserRoleAssigner {
-	mock := &UserRoleAssigner{}
-	mock.Mock.Test(t)
-
-	t.Cleanup(func() { mock.AssertExpectations(t) })
-
-	return mock
-}
diff --git a/services/settings/.mockery.yaml b/services/settings/.mockery.yaml
deleted file mode 100644
index ba758a5bb3e..00000000000
--- a/services/settings/.mockery.yaml
+++ /dev/null
@@ -1,10 +0,0 @@
-with-expecter: true
-filename: "{{.InterfaceName | snakecase }}.go"
-mockname: "{{.InterfaceName}}"
-outpkg: "mocks"
-packages:
-    github.com/owncloud/ocis/v2/services/settings/pkg/settings:
-        config:
-          dir: "pkg/settings/mocks"
-        interfaces:
-            Manager:
diff --git a/services/settings/Makefile b/services/settings/Makefile
index f426f34a640..05982ea7004 100644
--- a/services/settings/Makefile
+++ b/services/settings/Makefile
@@ -26,8 +26,7 @@ docs-generate: config-docs-generate \
 include ../../.make/generate.mk
 
 .PHONY: ci-go-generate
-ci-go-generate: $(MOCKERY) protobuf # CI runs ci-node-generate automatically before this target
-	$(MOCKERY)
+ci-go-generate: protobuf # CI runs ci-node-generate automatically before this target
 
 .PHONY: ci-node-generate
 ci-node-generate:
diff --git a/services/settings/pkg/settings/mocks/Manager.go b/services/settings/pkg/settings/mocks/Manager.go
new file mode 100644
index 00000000000..c5542f3ed37
--- /dev/null
+++ b/services/settings/pkg/settings/mocks/Manager.go
@@ -0,0 +1,379 @@
+// Code generated by mockery v2.14.0. DO NOT EDIT.
+
+package mocks
+
+import (
+	mock "github.com/stretchr/testify/mock"
+
+	v0 "github.com/owncloud/ocis/v2/protogen/gen/ocis/messages/settings/v0"
+)
+
+// Manager is an autogenerated mock type for the Manager type
+type Manager struct {
+	mock.Mock
+}
+
+// AddSettingToBundle provides a mock function with given fields: bundleID, setting
+func (_m *Manager) AddSettingToBundle(bundleID string, setting *v0.Setting) (*v0.Setting, error) {
+	ret := _m.Called(bundleID, setting)
+
+	var r0 *v0.Setting
+	if rf, ok := ret.Get(0).(func(string, *v0.Setting) *v0.Setting); ok {
+		r0 = rf(bundleID, setting)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(*v0.Setting)
+		}
+	}
+
+	var r1 error
+	if rf, ok := ret.Get(1).(func(string, *v0.Setting) error); ok {
+		r1 = rf(bundleID, setting)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// ListBundles provides a mock function with given fields: bundleType, bundleIDs
+func (_m *Manager) ListBundles(bundleType v0.Bundle_Type, bundleIDs []string) ([]*v0.Bundle, error) {
+	ret := _m.Called(bundleType, bundleIDs)
+
+	var r0 []*v0.Bundle
+	if rf, ok := ret.Get(0).(func(v0.Bundle_Type, []string) []*v0.Bundle); ok {
+		r0 = rf(bundleType, bundleIDs)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).([]*v0.Bundle)
+		}
+	}
+
+	var r1 error
+	if rf, ok := ret.Get(1).(func(v0.Bundle_Type, []string) error); ok {
+		r1 = rf(bundleType, bundleIDs)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// ListPermissionsByResource provides a mock function with given fields: resource, roleIDs
+func (_m *Manager) ListPermissionsByResource(resource *v0.Resource, roleIDs []string) ([]*v0.Permission, error) {
+	ret := _m.Called(resource, roleIDs)
+
+	var r0 []*v0.Permission
+	if rf, ok := ret.Get(0).(func(*v0.Resource, []string) []*v0.Permission); ok {
+		r0 = rf(resource, roleIDs)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).([]*v0.Permission)
+		}
+	}
+
+	var r1 error
+	if rf, ok := ret.Get(1).(func(*v0.Resource, []string) error); ok {
+		r1 = rf(resource, roleIDs)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// ListRoleAssignments provides a mock function with given fields: accountUUID
+func (_m *Manager) ListRoleAssignments(accountUUID string) ([]*v0.UserRoleAssignment, error) {
+	ret := _m.Called(accountUUID)
+
+	var r0 []*v0.UserRoleAssignment
+	if rf, ok := ret.Get(0).(func(string) []*v0.UserRoleAssignment); ok {
+		r0 = rf(accountUUID)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).([]*v0.UserRoleAssignment)
+		}
+	}
+
+	var r1 error
+	if rf, ok := ret.Get(1).(func(string) error); ok {
+		r1 = rf(accountUUID)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// ListValues provides a mock function with given fields: bundleID, accountUUID
+func (_m *Manager) ListValues(bundleID string, accountUUID string) ([]*v0.Value, error) {
+	ret := _m.Called(bundleID, accountUUID)
+
+	var r0 []*v0.Value
+	if rf, ok := ret.Get(0).(func(string, string) []*v0.Value); ok {
+		r0 = rf(bundleID, accountUUID)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).([]*v0.Value)
+		}
+	}
+
+	var r1 error
+	if rf, ok := ret.Get(1).(func(string, string) error); ok {
+		r1 = rf(bundleID, accountUUID)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// ReadBundle provides a mock function with given fields: bundleID
+func (_m *Manager) ReadBundle(bundleID string) (*v0.Bundle, error) {
+	ret := _m.Called(bundleID)
+
+	var r0 *v0.Bundle
+	if rf, ok := ret.Get(0).(func(string) *v0.Bundle); ok {
+		r0 = rf(bundleID)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(*v0.Bundle)
+		}
+	}
+
+	var r1 error
+	if rf, ok := ret.Get(1).(func(string) error); ok {
+		r1 = rf(bundleID)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// ReadPermissionByID provides a mock function with given fields: permissionID, roleIDs
+func (_m *Manager) ReadPermissionByID(permissionID string, roleIDs []string) (*v0.Permission, error) {
+	ret := _m.Called(permissionID, roleIDs)
+
+	var r0 *v0.Permission
+	if rf, ok := ret.Get(0).(func(string, []string) *v0.Permission); ok {
+		r0 = rf(permissionID, roleIDs)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(*v0.Permission)
+		}
+	}
+
+	var r1 error
+	if rf, ok := ret.Get(1).(func(string, []string) error); ok {
+		r1 = rf(permissionID, roleIDs)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// ReadPermissionByName provides a mock function with given fields: name, roleIDs
+func (_m *Manager) ReadPermissionByName(name string, roleIDs []string) (*v0.Permission, error) {
+	ret := _m.Called(name, roleIDs)
+
+	var r0 *v0.Permission
+	if rf, ok := ret.Get(0).(func(string, []string) *v0.Permission); ok {
+		r0 = rf(name, roleIDs)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(*v0.Permission)
+		}
+	}
+
+	var r1 error
+	if rf, ok := ret.Get(1).(func(string, []string) error); ok {
+		r1 = rf(name, roleIDs)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// ReadSetting provides a mock function with given fields: settingID
+func (_m *Manager) ReadSetting(settingID string) (*v0.Setting, error) {
+	ret := _m.Called(settingID)
+
+	var r0 *v0.Setting
+	if rf, ok := ret.Get(0).(func(string) *v0.Setting); ok {
+		r0 = rf(settingID)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(*v0.Setting)
+		}
+	}
+
+	var r1 error
+	if rf, ok := ret.Get(1).(func(string) error); ok {
+		r1 = rf(settingID)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// ReadValue provides a mock function with given fields: valueID
+func (_m *Manager) ReadValue(valueID string) (*v0.Value, error) {
+	ret := _m.Called(valueID)
+
+	var r0 *v0.Value
+	if rf, ok := ret.Get(0).(func(string) *v0.Value); ok {
+		r0 = rf(valueID)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(*v0.Value)
+		}
+	}
+
+	var r1 error
+	if rf, ok := ret.Get(1).(func(string) error); ok {
+		r1 = rf(valueID)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// ReadValueByUniqueIdentifiers provides a mock function with given fields: accountUUID, settingID
+func (_m *Manager) ReadValueByUniqueIdentifiers(accountUUID string, settingID string) (*v0.Value, error) {
+	ret := _m.Called(accountUUID, settingID)
+
+	var r0 *v0.Value
+	if rf, ok := ret.Get(0).(func(string, string) *v0.Value); ok {
+		r0 = rf(accountUUID, settingID)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(*v0.Value)
+		}
+	}
+
+	var r1 error
+	if rf, ok := ret.Get(1).(func(string, string) error); ok {
+		r1 = rf(accountUUID, settingID)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// RemoveRoleAssignment provides a mock function with given fields: assignmentID
+func (_m *Manager) RemoveRoleAssignment(assignmentID string) error {
+	ret := _m.Called(assignmentID)
+
+	var r0 error
+	if rf, ok := ret.Get(0).(func(string) error); ok {
+		r0 = rf(assignmentID)
+	} else {
+		r0 = ret.Error(0)
+	}
+
+	return r0
+}
+
+// RemoveSettingFromBundle provides a mock function with given fields: bundleID, settingID
+func (_m *Manager) RemoveSettingFromBundle(bundleID string, settingID string) error {
+	ret := _m.Called(bundleID, settingID)
+
+	var r0 error
+	if rf, ok := ret.Get(0).(func(string, string) error); ok {
+		r0 = rf(bundleID, settingID)
+	} else {
+		r0 = ret.Error(0)
+	}
+
+	return r0
+}
+
+// WriteBundle provides a mock function with given fields: bundle
+func (_m *Manager) WriteBundle(bundle *v0.Bundle) (*v0.Bundle, error) {
+	ret := _m.Called(bundle)
+
+	var r0 *v0.Bundle
+	if rf, ok := ret.Get(0).(func(*v0.Bundle) *v0.Bundle); ok {
+		r0 = rf(bundle)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(*v0.Bundle)
+		}
+	}
+
+	var r1 error
+	if rf, ok := ret.Get(1).(func(*v0.Bundle) error); ok {
+		r1 = rf(bundle)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// WriteRoleAssignment provides a mock function with given fields: accountUUID, roleID
+func (_m *Manager) WriteRoleAssignment(accountUUID string, roleID string) (*v0.UserRoleAssignment, error) {
+	ret := _m.Called(accountUUID, roleID)
+
+	var r0 *v0.UserRoleAssignment
+	if rf, ok := ret.Get(0).(func(string, string) *v0.UserRoleAssignment); ok {
+		r0 = rf(accountUUID, roleID)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(*v0.UserRoleAssignment)
+		}
+	}
+
+	var r1 error
+	if rf, ok := ret.Get(1).(func(string, string) error); ok {
+		r1 = rf(accountUUID, roleID)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+// WriteValue provides a mock function with given fields: value
+func (_m *Manager) WriteValue(value *v0.Value) (*v0.Value, error) {
+	ret := _m.Called(value)
+
+	var r0 *v0.Value
+	if rf, ok := ret.Get(0).(func(*v0.Value) *v0.Value); ok {
+		r0 = rf(value)
+	} else {
+		if ret.Get(0) != nil {
+			r0 = ret.Get(0).(*v0.Value)
+		}
+	}
+
+	var r1 error
+	if rf, ok := ret.Get(1).(func(*v0.Value) error); ok {
+		r1 = rf(value)
+	} else {
+		r1 = ret.Error(1)
+	}
+
+	return r0, r1
+}
+
+type mockConstructorTestingTNewManager interface {
+	mock.TestingT
+	Cleanup(func())
+}
+
+// NewManager creates a new instance of Manager. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
+func NewManager(t mockConstructorTestingTNewManager) *Manager {
+	mock := &Manager{}
+	mock.Mock.Test(t)
+
+	t.Cleanup(func() { mock.AssertExpectations(t) })
+
+	return mock
+}
diff --git a/services/settings/pkg/settings/mocks/manager.go b/services/settings/pkg/settings/mocks/manager.go
deleted file mode 100644
index 687d1688850..00000000000
--- a/services/settings/pkg/settings/mocks/manager.go
+++ /dev/null
@@ -1,949 +0,0 @@
-// Code generated by mockery v2.40.1. DO NOT EDIT.
-
-package mocks
-
-import (
-	mock "github.com/stretchr/testify/mock"
-
-	v0 "github.com/owncloud/ocis/v2/protogen/gen/ocis/messages/settings/v0"
-)
-
-// Manager is an autogenerated mock type for the Manager type
-type Manager struct {
-	mock.Mock
-}
-
-type Manager_Expecter struct {
-	mock *mock.Mock
-}
-
-func (_m *Manager) EXPECT() *Manager_Expecter {
-	return &Manager_Expecter{mock: &_m.Mock}
-}
-
-// AddSettingToBundle provides a mock function with given fields: bundleID, setting
-func (_m *Manager) AddSettingToBundle(bundleID string, setting *v0.Setting) (*v0.Setting, error) {
-	ret := _m.Called(bundleID, setting)
-
-	if len(ret) == 0 {
-		panic("no return value specified for AddSettingToBundle")
-	}
-
-	var r0 *v0.Setting
-	var r1 error
-	if rf, ok := ret.Get(0).(func(string, *v0.Setting) (*v0.Setting, error)); ok {
-		return rf(bundleID, setting)
-	}
-	if rf, ok := ret.Get(0).(func(string, *v0.Setting) *v0.Setting); ok {
-		r0 = rf(bundleID, setting)
-	} else {
-		if ret.Get(0) != nil {
-			r0 = ret.Get(0).(*v0.Setting)
-		}
-	}
-
-	if rf, ok := ret.Get(1).(func(string, *v0.Setting) error); ok {
-		r1 = rf(bundleID, setting)
-	} else {
-		r1 = ret.Error(1)
-	}
-
-	return r0, r1
-}
-
-// Manager_AddSettingToBundle_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AddSettingToBundle'
-type Manager_AddSettingToBundle_Call struct {
-	*mock.Call
-}
-
-// AddSettingToBundle is a helper method to define mock.On call
-//   - bundleID string
-//   - setting *v0.Setting
-func (_e *Manager_Expecter) AddSettingToBundle(bundleID interface{}, setting interface{}) *Manager_AddSettingToBundle_Call {
-	return &Manager_AddSettingToBundle_Call{Call: _e.mock.On("AddSettingToBundle", bundleID, setting)}
-}
-
-func (_c *Manager_AddSettingToBundle_Call) Run(run func(bundleID string, setting *v0.Setting)) *Manager_AddSettingToBundle_Call {
-	_c.Call.Run(func(args mock.Arguments) {
-		run(args[0].(string), args[1].(*v0.Setting))
-	})
-	return _c
-}
-
-func (_c *Manager_AddSettingToBundle_Call) Return(_a0 *v0.Setting, _a1 error) *Manager_AddSettingToBundle_Call {
-	_c.Call.Return(_a0, _a1)
-	return _c
-}
-
-func (_c *Manager_AddSettingToBundle_Call) RunAndReturn(run func(string, *v0.Setting) (*v0.Setting, error)) *Manager_AddSettingToBundle_Call {
-	_c.Call.Return(run)
-	return _c
-}
-
-// ListBundles provides a mock function with given fields: bundleType, bundleIDs
-func (_m *Manager) ListBundles(bundleType v0.Bundle_Type, bundleIDs []string) ([]*v0.Bundle, error) {
-	ret := _m.Called(bundleType, bundleIDs)
-
-	if len(ret) == 0 {
-		panic("no return value specified for ListBundles")
-	}
-
-	var r0 []*v0.Bundle
-	var r1 error
-	if rf, ok := ret.Get(0).(func(v0.Bundle_Type, []string) ([]*v0.Bundle, error)); ok {
-		return rf(bundleType, bundleIDs)
-	}
-	if rf, ok := ret.Get(0).(func(v0.Bundle_Type, []string) []*v0.Bundle); ok {
-		r0 = rf(bundleType, bundleIDs)
-	} else {
-		if ret.Get(0) != nil {
-			r0 = ret.Get(0).([]*v0.Bundle)
-		}
-	}
-
-	if rf, ok := ret.Get(1).(func(v0.Bundle_Type, []string) error); ok {
-		r1 = rf(bundleType, bundleIDs)
-	} else {
-		r1 = ret.Error(1)
-	}
-
-	return r0, r1
-}
-
-// Manager_ListBundles_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListBundles'
-type Manager_ListBundles_Call struct {
-	*mock.Call
-}
-
-// ListBundles is a helper method to define mock.On call
-//   - bundleType v0.Bundle_Type
-//   - bundleIDs []string
-func (_e *Manager_Expecter) ListBundles(bundleType interface{}, bundleIDs interface{}) *Manager_ListBundles_Call {
-	return &Manager_ListBundles_Call{Call: _e.mock.On("ListBundles", bundleType, bundleIDs)}
-}
-
-func (_c *Manager_ListBundles_Call) Run(run func(bundleType v0.Bundle_Type, bundleIDs []string)) *Manager_ListBundles_Call {
-	_c.Call.Run(func(args mock.Arguments) {
-		run(args[0].(v0.Bundle_Type), args[1].([]string))
-	})
-	return _c
-}
-
-func (_c *Manager_ListBundles_Call) Return(_a0 []*v0.Bundle, _a1 error) *Manager_ListBundles_Call {
-	_c.Call.Return(_a0, _a1)
-	return _c
-}
-
-func (_c *Manager_ListBundles_Call) RunAndReturn(run func(v0.Bundle_Type, []string) ([]*v0.Bundle, error)) *Manager_ListBundles_Call {
-	_c.Call.Return(run)
-	return _c
-}
-
-// ListPermissionsByResource provides a mock function with given fields: resource, roleIDs
-func (_m *Manager) ListPermissionsByResource(resource *v0.Resource, roleIDs []string) ([]*v0.Permission, error) {
-	ret := _m.Called(resource, roleIDs)
-
-	if len(ret) == 0 {
-		panic("no return value specified for ListPermissionsByResource")
-	}
-
-	var r0 []*v0.Permission
-	var r1 error
-	if rf, ok := ret.Get(0).(func(*v0.Resource, []string) ([]*v0.Permission, error)); ok {
-		return rf(resource, roleIDs)
-	}
-	if rf, ok := ret.Get(0).(func(*v0.Resource, []string) []*v0.Permission); ok {
-		r0 = rf(resource, roleIDs)
-	} else {
-		if ret.Get(0) != nil {
-			r0 = ret.Get(0).([]*v0.Permission)
-		}
-	}
-
-	if rf, ok := ret.Get(1).(func(*v0.Resource, []string) error); ok {
-		r1 = rf(resource, roleIDs)
-	} else {
-		r1 = ret.Error(1)
-	}
-
-	return r0, r1
-}
-
-// Manager_ListPermissionsByResource_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListPermissionsByResource'
-type Manager_ListPermissionsByResource_Call struct {
-	*mock.Call
-}
-
-// ListPermissionsByResource is a helper method to define mock.On call
-//   - resource *v0.Resource
-//   - roleIDs []string
-func (_e *Manager_Expecter) ListPermissionsByResource(resource interface{}, roleIDs interface{}) *Manager_ListPermissionsByResource_Call {
-	return &Manager_ListPermissionsByResource_Call{Call: _e.mock.On("ListPermissionsByResource", resource, roleIDs)}
-}
-
-func (_c *Manager_ListPermissionsByResource_Call) Run(run func(resource *v0.Resource, roleIDs []string)) *Manager_ListPermissionsByResource_Call {
-	_c.Call.Run(func(args mock.Arguments) {
-		run(args[0].(*v0.Resource), args[1].([]string))
-	})
-	return _c
-}
-
-func (_c *Manager_ListPermissionsByResource_Call) Return(_a0 []*v0.Permission, _a1 error) *Manager_ListPermissionsByResource_Call {
-	_c.Call.Return(_a0, _a1)
-	return _c
-}
-
-func (_c *Manager_ListPermissionsByResource_Call) RunAndReturn(run func(*v0.Resource, []string) ([]*v0.Permission, error)) *Manager_ListPermissionsByResource_Call {
-	_c.Call.Return(run)
-	return _c
-}
-
-// ListRoleAssignments provides a mock function with given fields: accountUUID
-func (_m *Manager) ListRoleAssignments(accountUUID string) ([]*v0.UserRoleAssignment, error) {
-	ret := _m.Called(accountUUID)
-
-	if len(ret) == 0 {
-		panic("no return value specified for ListRoleAssignments")
-	}
-
-	var r0 []*v0.UserRoleAssignment
-	var r1 error
-	if rf, ok := ret.Get(0).(func(string) ([]*v0.UserRoleAssignment, error)); ok {
-		return rf(accountUUID)
-	}
-	if rf, ok := ret.Get(0).(func(string) []*v0.UserRoleAssignment); ok {
-		r0 = rf(accountUUID)
-	} else {
-		if ret.Get(0) != nil {
-			r0 = ret.Get(0).([]*v0.UserRoleAssignment)
-		}
-	}
-
-	if rf, ok := ret.Get(1).(func(string) error); ok {
-		r1 = rf(accountUUID)
-	} else {
-		r1 = ret.Error(1)
-	}
-
-	return r0, r1
-}
-
-// Manager_ListRoleAssignments_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListRoleAssignments'
-type Manager_ListRoleAssignments_Call struct {
-	*mock.Call
-}
-
-// ListRoleAssignments is a helper method to define mock.On call
-//   - accountUUID string
-func (_e *Manager_Expecter) ListRoleAssignments(accountUUID interface{}) *Manager_ListRoleAssignments_Call {
-	return &Manager_ListRoleAssignments_Call{Call: _e.mock.On("ListRoleAssignments", accountUUID)}
-}
-
-func (_c *Manager_ListRoleAssignments_Call) Run(run func(accountUUID string)) *Manager_ListRoleAssignments_Call {
-	_c.Call.Run(func(args mock.Arguments) {
-		run(args[0].(string))
-	})
-	return _c
-}
-
-func (_c *Manager_ListRoleAssignments_Call) Return(_a0 []*v0.UserRoleAssignment, _a1 error) *Manager_ListRoleAssignments_Call {
-	_c.Call.Return(_a0, _a1)
-	return _c
-}
-
-func (_c *Manager_ListRoleAssignments_Call) RunAndReturn(run func(string) ([]*v0.UserRoleAssignment, error)) *Manager_ListRoleAssignments_Call {
-	_c.Call.Return(run)
-	return _c
-}
-
-// ListValues provides a mock function with given fields: bundleID, accountUUID
-func (_m *Manager) ListValues(bundleID string, accountUUID string) ([]*v0.Value, error) {
-	ret := _m.Called(bundleID, accountUUID)
-
-	if len(ret) == 0 {
-		panic("no return value specified for ListValues")
-	}
-
-	var r0 []*v0.Value
-	var r1 error
-	if rf, ok := ret.Get(0).(func(string, string) ([]*v0.Value, error)); ok {
-		return rf(bundleID, accountUUID)
-	}
-	if rf, ok := ret.Get(0).(func(string, string) []*v0.Value); ok {
-		r0 = rf(bundleID, accountUUID)
-	} else {
-		if ret.Get(0) != nil {
-			r0 = ret.Get(0).([]*v0.Value)
-		}
-	}
-
-	if rf, ok := ret.Get(1).(func(string, string) error); ok {
-		r1 = rf(bundleID, accountUUID)
-	} else {
-		r1 = ret.Error(1)
-	}
-
-	return r0, r1
-}
-
-// Manager_ListValues_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListValues'
-type Manager_ListValues_Call struct {
-	*mock.Call
-}
-
-// ListValues is a helper method to define mock.On call
-//   - bundleID string
-//   - accountUUID string
-func (_e *Manager_Expecter) ListValues(bundleID interface{}, accountUUID interface{}) *Manager_ListValues_Call {
-	return &Manager_ListValues_Call{Call: _e.mock.On("ListValues", bundleID, accountUUID)}
-}
-
-func (_c *Manager_ListValues_Call) Run(run func(bundleID string, accountUUID string)) *Manager_ListValues_Call {
-	_c.Call.Run(func(args mock.Arguments) {
-		run(args[0].(string), args[1].(string))
-	})
-	return _c
-}
-
-func (_c *Manager_ListValues_Call) Return(_a0 []*v0.Value, _a1 error) *Manager_ListValues_Call {
-	_c.Call.Return(_a0, _a1)
-	return _c
-}
-
-func (_c *Manager_ListValues_Call) RunAndReturn(run func(string, string) ([]*v0.Value, error)) *Manager_ListValues_Call {
-	_c.Call.Return(run)
-	return _c
-}
-
-// ReadBundle provides a mock function with given fields: bundleID
-func (_m *Manager) ReadBundle(bundleID string) (*v0.Bundle, error) {
-	ret := _m.Called(bundleID)
-
-	if len(ret) == 0 {
-		panic("no return value specified for ReadBundle")
-	}
-
-	var r0 *v0.Bundle
-	var r1 error
-	if rf, ok := ret.Get(0).(func(string) (*v0.Bundle, error)); ok {
-		return rf(bundleID)
-	}
-	if rf, ok := ret.Get(0).(func(string) *v0.Bundle); ok {
-		r0 = rf(bundleID)
-	} else {
-		if ret.Get(0) != nil {
-			r0 = ret.Get(0).(*v0.Bundle)
-		}
-	}
-
-	if rf, ok := ret.Get(1).(func(string) error); ok {
-		r1 = rf(bundleID)
-	} else {
-		r1 = ret.Error(1)
-	}
-
-	return r0, r1
-}
-
-// Manager_ReadBundle_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ReadBundle'
-type Manager_ReadBundle_Call struct {
-	*mock.Call
-}
-
-// ReadBundle is a helper method to define mock.On call
-//   - bundleID string
-func (_e *Manager_Expecter) ReadBundle(bundleID interface{}) *Manager_ReadBundle_Call {
-	return &Manager_ReadBundle_Call{Call: _e.mock.On("ReadBundle", bundleID)}
-}
-
-func (_c *Manager_ReadBundle_Call) Run(run func(bundleID string)) *Manager_ReadBundle_Call {
-	_c.Call.Run(func(args mock.Arguments) {
-		run(args[0].(string))
-	})
-	return _c
-}
-
-func (_c *Manager_ReadBundle_Call) Return(_a0 *v0.Bundle, _a1 error) *Manager_ReadBundle_Call {
-	_c.Call.Return(_a0, _a1)
-	return _c
-}
-
-func (_c *Manager_ReadBundle_Call) RunAndReturn(run func(string) (*v0.Bundle, error)) *Manager_ReadBundle_Call {
-	_c.Call.Return(run)
-	return _c
-}
-
-// ReadPermissionByID provides a mock function with given fields: permissionID, roleIDs
-func (_m *Manager) ReadPermissionByID(permissionID string, roleIDs []string) (*v0.Permission, error) {
-	ret := _m.Called(permissionID, roleIDs)
-
-	if len(ret) == 0 {
-		panic("no return value specified for ReadPermissionByID")
-	}
-
-	var r0 *v0.Permission
-	var r1 error
-	if rf, ok := ret.Get(0).(func(string, []string) (*v0.Permission, error)); ok {
-		return rf(permissionID, roleIDs)
-	}
-	if rf, ok := ret.Get(0).(func(string, []string) *v0.Permission); ok {
-		r0 = rf(permissionID, roleIDs)
-	} else {
-		if ret.Get(0) != nil {
-			r0 = ret.Get(0).(*v0.Permission)
-		}
-	}
-
-	if rf, ok := ret.Get(1).(func(string, []string) error); ok {
-		r1 = rf(permissionID, roleIDs)
-	} else {
-		r1 = ret.Error(1)
-	}
-
-	return r0, r1
-}
-
-// Manager_ReadPermissionByID_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ReadPermissionByID'
-type Manager_ReadPermissionByID_Call struct {
-	*mock.Call
-}
-
-// ReadPermissionByID is a helper method to define mock.On call
-//   - permissionID string
-//   - roleIDs []string
-func (_e *Manager_Expecter) ReadPermissionByID(permissionID interface{}, roleIDs interface{}) *Manager_ReadPermissionByID_Call {
-	return &Manager_ReadPermissionByID_Call{Call: _e.mock.On("ReadPermissionByID", permissionID, roleIDs)}
-}
-
-func (_c *Manager_ReadPermissionByID_Call) Run(run func(permissionID string, roleIDs []string)) *Manager_ReadPermissionByID_Call {
-	_c.Call.Run(func(args mock.Arguments) {
-		run(args[0].(string), args[1].([]string))
-	})
-	return _c
-}
-
-func (_c *Manager_ReadPermissionByID_Call) Return(_a0 *v0.Permission, _a1 error) *Manager_ReadPermissionByID_Call {
-	_c.Call.Return(_a0, _a1)
-	return _c
-}
-
-func (_c *Manager_ReadPermissionByID_Call) RunAndReturn(run func(string, []string) (*v0.Permission, error)) *Manager_ReadPermissionByID_Call {
-	_c.Call.Return(run)
-	return _c
-}
-
-// ReadPermissionByName provides a mock function with given fields: name, roleIDs
-func (_m *Manager) ReadPermissionByName(name string, roleIDs []string) (*v0.Permission, error) {
-	ret := _m.Called(name, roleIDs)
-
-	if len(ret) == 0 {
-		panic("no return value specified for ReadPermissionByName")
-	}
-
-	var r0 *v0.Permission
-	var r1 error
-	if rf, ok := ret.Get(0).(func(string, []string) (*v0.Permission, error)); ok {
-		return rf(name, roleIDs)
-	}
-	if rf, ok := ret.Get(0).(func(string, []string) *v0.Permission); ok {
-		r0 = rf(name, roleIDs)
-	} else {
-		if ret.Get(0) != nil {
-			r0 = ret.Get(0).(*v0.Permission)
-		}
-	}
-
-	if rf, ok := ret.Get(1).(func(string, []string) error); ok {
-		r1 = rf(name, roleIDs)
-	} else {
-		r1 = ret.Error(1)
-	}
-
-	return r0, r1
-}
-
-// Manager_ReadPermissionByName_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ReadPermissionByName'
-type Manager_ReadPermissionByName_Call struct {
-	*mock.Call
-}
-
-// ReadPermissionByName is a helper method to define mock.On call
-//   - name string
-//   - roleIDs []string
-func (_e *Manager_Expecter) ReadPermissionByName(name interface{}, roleIDs interface{}) *Manager_ReadPermissionByName_Call {
-	return &Manager_ReadPermissionByName_Call{Call: _e.mock.On("ReadPermissionByName", name, roleIDs)}
-}
-
-func (_c *Manager_ReadPermissionByName_Call) Run(run func(name string, roleIDs []string)) *Manager_ReadPermissionByName_Call {
-	_c.Call.Run(func(args mock.Arguments) {
-		run(args[0].(string), args[1].([]string))
-	})
-	return _c
-}
-
-func (_c *Manager_ReadPermissionByName_Call) Return(_a0 *v0.Permission, _a1 error) *Manager_ReadPermissionByName_Call {
-	_c.Call.Return(_a0, _a1)
-	return _c
-}
-
-func (_c *Manager_ReadPermissionByName_Call) RunAndReturn(run func(string, []string) (*v0.Permission, error)) *Manager_ReadPermissionByName_Call {
-	_c.Call.Return(run)
-	return _c
-}
-
-// ReadSetting provides a mock function with given fields: settingID
-func (_m *Manager) ReadSetting(settingID string) (*v0.Setting, error) {
-	ret := _m.Called(settingID)
-
-	if len(ret) == 0 {
-		panic("no return value specified for ReadSetting")
-	}
-
-	var r0 *v0.Setting
-	var r1 error
-	if rf, ok := ret.Get(0).(func(string) (*v0.Setting, error)); ok {
-		return rf(settingID)
-	}
-	if rf, ok := ret.Get(0).(func(string) *v0.Setting); ok {
-		r0 = rf(settingID)
-	} else {
-		if ret.Get(0) != nil {
-			r0 = ret.Get(0).(*v0.Setting)
-		}
-	}
-
-	if rf, ok := ret.Get(1).(func(string) error); ok {
-		r1 = rf(settingID)
-	} else {
-		r1 = ret.Error(1)
-	}
-
-	return r0, r1
-}
-
-// Manager_ReadSetting_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ReadSetting'
-type Manager_ReadSetting_Call struct {
-	*mock.Call
-}
-
-// ReadSetting is a helper method to define mock.On call
-//   - settingID string
-func (_e *Manager_Expecter) ReadSetting(settingID interface{}) *Manager_ReadSetting_Call {
-	return &Manager_ReadSetting_Call{Call: _e.mock.On("ReadSetting", settingID)}
-}
-
-func (_c *Manager_ReadSetting_Call) Run(run func(settingID string)) *Manager_ReadSetting_Call {
-	_c.Call.Run(func(args mock.Arguments) {
-		run(args[0].(string))
-	})
-	return _c
-}
-
-func (_c *Manager_ReadSetting_Call) Return(_a0 *v0.Setting, _a1 error) *Manager_ReadSetting_Call {
-	_c.Call.Return(_a0, _a1)
-	return _c
-}
-
-func (_c *Manager_ReadSetting_Call) RunAndReturn(run func(string) (*v0.Setting, error)) *Manager_ReadSetting_Call {
-	_c.Call.Return(run)
-	return _c
-}
-
-// ReadValue provides a mock function with given fields: valueID
-func (_m *Manager) ReadValue(valueID string) (*v0.Value, error) {
-	ret := _m.Called(valueID)
-
-	if len(ret) == 0 {
-		panic("no return value specified for ReadValue")
-	}
-
-	var r0 *v0.Value
-	var r1 error
-	if rf, ok := ret.Get(0).(func(string) (*v0.Value, error)); ok {
-		return rf(valueID)
-	}
-	if rf, ok := ret.Get(0).(func(string) *v0.Value); ok {
-		r0 = rf(valueID)
-	} else {
-		if ret.Get(0) != nil {
-			r0 = ret.Get(0).(*v0.Value)
-		}
-	}
-
-	if rf, ok := ret.Get(1).(func(string) error); ok {
-		r1 = rf(valueID)
-	} else {
-		r1 = ret.Error(1)
-	}
-
-	return r0, r1
-}
-
-// Manager_ReadValue_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ReadValue'
-type Manager_ReadValue_Call struct {
-	*mock.Call
-}
-
-// ReadValue is a helper method to define mock.On call
-//   - valueID string
-func (_e *Manager_Expecter) ReadValue(valueID interface{}) *Manager_ReadValue_Call {
-	return &Manager_ReadValue_Call{Call: _e.mock.On("ReadValue", valueID)}
-}
-
-func (_c *Manager_ReadValue_Call) Run(run func(valueID string)) *Manager_ReadValue_Call {
-	_c.Call.Run(func(args mock.Arguments) {
-		run(args[0].(string))
-	})
-	return _c
-}
-
-func (_c *Manager_ReadValue_Call) Return(_a0 *v0.Value, _a1 error) *Manager_ReadValue_Call {
-	_c.Call.Return(_a0, _a1)
-	return _c
-}
-
-func (_c *Manager_ReadValue_Call) RunAndReturn(run func(string) (*v0.Value, error)) *Manager_ReadValue_Call {
-	_c.Call.Return(run)
-	return _c
-}
-
-// ReadValueByUniqueIdentifiers provides a mock function with given fields: accountUUID, settingID
-func (_m *Manager) ReadValueByUniqueIdentifiers(accountUUID string, settingID string) (*v0.Value, error) {
-	ret := _m.Called(accountUUID, settingID)
-
-	if len(ret) == 0 {
-		panic("no return value specified for ReadValueByUniqueIdentifiers")
-	}
-
-	var r0 *v0.Value
-	var r1 error
-	if rf, ok := ret.Get(0).(func(string, string) (*v0.Value, error)); ok {
-		return rf(accountUUID, settingID)
-	}
-	if rf, ok := ret.Get(0).(func(string, string) *v0.Value); ok {
-		r0 = rf(accountUUID, settingID)
-	} else {
-		if ret.Get(0) != nil {
-			r0 = ret.Get(0).(*v0.Value)
-		}
-	}
-
-	if rf, ok := ret.Get(1).(func(string, string) error); ok {
-		r1 = rf(accountUUID, settingID)
-	} else {
-		r1 = ret.Error(1)
-	}
-
-	return r0, r1
-}
-
-// Manager_ReadValueByUniqueIdentifiers_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ReadValueByUniqueIdentifiers'
-type Manager_ReadValueByUniqueIdentifiers_Call struct {
-	*mock.Call
-}
-
-// ReadValueByUniqueIdentifiers is a helper method to define mock.On call
-//   - accountUUID string
-//   - settingID string
-func (_e *Manager_Expecter) ReadValueByUniqueIdentifiers(accountUUID interface{}, settingID interface{}) *Manager_ReadValueByUniqueIdentifiers_Call {
-	return &Manager_ReadValueByUniqueIdentifiers_Call{Call: _e.mock.On("ReadValueByUniqueIdentifiers", accountUUID, settingID)}
-}
-
-func (_c *Manager_ReadValueByUniqueIdentifiers_Call) Run(run func(accountUUID string, settingID string)) *Manager_ReadValueByUniqueIdentifiers_Call {
-	_c.Call.Run(func(args mock.Arguments) {
-		run(args[0].(string), args[1].(string))
-	})
-	return _c
-}
-
-func (_c *Manager_ReadValueByUniqueIdentifiers_Call) Return(_a0 *v0.Value, _a1 error) *Manager_ReadValueByUniqueIdentifiers_Call {
-	_c.Call.Return(_a0, _a1)
-	return _c
-}
-
-func (_c *Manager_ReadValueByUniqueIdentifiers_Call) RunAndReturn(run func(string, string) (*v0.Value, error)) *Manager_ReadValueByUniqueIdentifiers_Call {
-	_c.Call.Return(run)
-	return _c
-}
-
-// RemoveRoleAssignment provides a mock function with given fields: assignmentID
-func (_m *Manager) RemoveRoleAssignment(assignmentID string) error {
-	ret := _m.Called(assignmentID)
-
-	if len(ret) == 0 {
-		panic("no return value specified for RemoveRoleAssignment")
-	}
-
-	var r0 error
-	if rf, ok := ret.Get(0).(func(string) error); ok {
-		r0 = rf(assignmentID)
-	} else {
-		r0 = ret.Error(0)
-	}
-
-	return r0
-}
-
-// Manager_RemoveRoleAssignment_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RemoveRoleAssignment'
-type Manager_RemoveRoleAssignment_Call struct {
-	*mock.Call
-}
-
-// RemoveRoleAssignment is a helper method to define mock.On call
-//   - assignmentID string
-func (_e *Manager_Expecter) RemoveRoleAssignment(assignmentID interface{}) *Manager_RemoveRoleAssignment_Call {
-	return &Manager_RemoveRoleAssignment_Call{Call: _e.mock.On("RemoveRoleAssignment", assignmentID)}
-}
-
-func (_c *Manager_RemoveRoleAssignment_Call) Run(run func(assignmentID string)) *Manager_RemoveRoleAssignment_Call {
-	_c.Call.Run(func(args mock.Arguments) {
-		run(args[0].(string))
-	})
-	return _c
-}
-
-func (_c *Manager_RemoveRoleAssignment_Call) Return(_a0 error) *Manager_RemoveRoleAssignment_Call {
-	_c.Call.Return(_a0)
-	return _c
-}
-
-func (_c *Manager_RemoveRoleAssignment_Call) RunAndReturn(run func(string) error) *Manager_RemoveRoleAssignment_Call {
-	_c.Call.Return(run)
-	return _c
-}
-
-// RemoveSettingFromBundle provides a mock function with given fields: bundleID, settingID
-func (_m *Manager) RemoveSettingFromBundle(bundleID string, settingID string) error {
-	ret := _m.Called(bundleID, settingID)
-
-	if len(ret) == 0 {
-		panic("no return value specified for RemoveSettingFromBundle")
-	}
-
-	var r0 error
-	if rf, ok := ret.Get(0).(func(string, string) error); ok {
-		r0 = rf(bundleID, settingID)
-	} else {
-		r0 = ret.Error(0)
-	}
-
-	return r0
-}
-
-// Manager_RemoveSettingFromBundle_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'RemoveSettingFromBundle'
-type Manager_RemoveSettingFromBundle_Call struct {
-	*mock.Call
-}
-
-// RemoveSettingFromBundle is a helper method to define mock.On call
-//   - bundleID string
-//   - settingID string
-func (_e *Manager_Expecter) RemoveSettingFromBundle(bundleID interface{}, settingID interface{}) *Manager_RemoveSettingFromBundle_Call {
-	return &Manager_RemoveSettingFromBundle_Call{Call: _e.mock.On("RemoveSettingFromBundle", bundleID, settingID)}
-}
-
-func (_c *Manager_RemoveSettingFromBundle_Call) Run(run func(bundleID string, settingID string)) *Manager_RemoveSettingFromBundle_Call {
-	_c.Call.Run(func(args mock.Arguments) {
-		run(args[0].(string), args[1].(string))
-	})
-	return _c
-}
-
-func (_c *Manager_RemoveSettingFromBundle_Call) Return(_a0 error) *Manager_RemoveSettingFromBundle_Call {
-	_c.Call.Return(_a0)
-	return _c
-}
-
-func (_c *Manager_RemoveSettingFromBundle_Call) RunAndReturn(run func(string, string) error) *Manager_RemoveSettingFromBundle_Call {
-	_c.Call.Return(run)
-	return _c
-}
-
-// WriteBundle provides a mock function with given fields: bundle
-func (_m *Manager) WriteBundle(bundle *v0.Bundle) (*v0.Bundle, error) {
-	ret := _m.Called(bundle)
-
-	if len(ret) == 0 {
-		panic("no return value specified for WriteBundle")
-	}
-
-	var r0 *v0.Bundle
-	var r1 error
-	if rf, ok := ret.Get(0).(func(*v0.Bundle) (*v0.Bundle, error)); ok {
-		return rf(bundle)
-	}
-	if rf, ok := ret.Get(0).(func(*v0.Bundle) *v0.Bundle); ok {
-		r0 = rf(bundle)
-	} else {
-		if ret.Get(0) != nil {
-			r0 = ret.Get(0).(*v0.Bundle)
-		}
-	}
-
-	if rf, ok := ret.Get(1).(func(*v0.Bundle) error); ok {
-		r1 = rf(bundle)
-	} else {
-		r1 = ret.Error(1)
-	}
-
-	return r0, r1
-}
-
-// Manager_WriteBundle_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteBundle'
-type Manager_WriteBundle_Call struct {
-	*mock.Call
-}
-
-// WriteBundle is a helper method to define mock.On call
-//   - bundle *v0.Bundle
-func (_e *Manager_Expecter) WriteBundle(bundle interface{}) *Manager_WriteBundle_Call {
-	return &Manager_WriteBundle_Call{Call: _e.mock.On("WriteBundle", bundle)}
-}
-
-func (_c *Manager_WriteBundle_Call) Run(run func(bundle *v0.Bundle)) *Manager_WriteBundle_Call {
-	_c.Call.Run(func(args mock.Arguments) {
-		run(args[0].(*v0.Bundle))
-	})
-	return _c
-}
-
-func (_c *Manager_WriteBundle_Call) Return(_a0 *v0.Bundle, _a1 error) *Manager_WriteBundle_Call {
-	_c.Call.Return(_a0, _a1)
-	return _c
-}
-
-func (_c *Manager_WriteBundle_Call) RunAndReturn(run func(*v0.Bundle) (*v0.Bundle, error)) *Manager_WriteBundle_Call {
-	_c.Call.Return(run)
-	return _c
-}
-
-// WriteRoleAssignment provides a mock function with given fields: accountUUID, roleID
-func (_m *Manager) WriteRoleAssignment(accountUUID string, roleID string) (*v0.UserRoleAssignment, error) {
-	ret := _m.Called(accountUUID, roleID)
-
-	if len(ret) == 0 {
-		panic("no return value specified for WriteRoleAssignment")
-	}
-
-	var r0 *v0.UserRoleAssignment
-	var r1 error
-	if rf, ok := ret.Get(0).(func(string, string) (*v0.UserRoleAssignment, error)); ok {
-		return rf(accountUUID, roleID)
-	}
-	if rf, ok := ret.Get(0).(func(string, string) *v0.UserRoleAssignment); ok {
-		r0 = rf(accountUUID, roleID)
-	} else {
-		if ret.Get(0) != nil {
-			r0 = ret.Get(0).(*v0.UserRoleAssignment)
-		}
-	}
-
-	if rf, ok := ret.Get(1).(func(string, string) error); ok {
-		r1 = rf(accountUUID, roleID)
-	} else {
-		r1 = ret.Error(1)
-	}
-
-	return r0, r1
-}
-
-// Manager_WriteRoleAssignment_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteRoleAssignment'
-type Manager_WriteRoleAssignment_Call struct {
-	*mock.Call
-}
-
-// WriteRoleAssignment is a helper method to define mock.On call
-//   - accountUUID string
-//   - roleID string
-func (_e *Manager_Expecter) WriteRoleAssignment(accountUUID interface{}, roleID interface{}) *Manager_WriteRoleAssignment_Call {
-	return &Manager_WriteRoleAssignment_Call{Call: _e.mock.On("WriteRoleAssignment", accountUUID, roleID)}
-}
-
-func (_c *Manager_WriteRoleAssignment_Call) Run(run func(accountUUID string, roleID string)) *Manager_WriteRoleAssignment_Call {
-	_c.Call.Run(func(args mock.Arguments) {
-		run(args[0].(string), args[1].(string))
-	})
-	return _c
-}
-
-func (_c *Manager_WriteRoleAssignment_Call) Return(_a0 *v0.UserRoleAssignment, _a1 error) *Manager_WriteRoleAssignment_Call {
-	_c.Call.Return(_a0, _a1)
-	return _c
-}
-
-func (_c *Manager_WriteRoleAssignment_Call) RunAndReturn(run func(string, string) (*v0.UserRoleAssignment, error)) *Manager_WriteRoleAssignment_Call {
-	_c.Call.Return(run)
-	return _c
-}
-
-// WriteValue provides a mock function with given fields: value
-func (_m *Manager) WriteValue(value *v0.Value) (*v0.Value, error) {
-	ret := _m.Called(value)
-
-	if len(ret) == 0 {
-		panic("no return value specified for WriteValue")
-	}
-
-	var r0 *v0.Value
-	var r1 error
-	if rf, ok := ret.Get(0).(func(*v0.Value) (*v0.Value, error)); ok {
-		return rf(value)
-	}
-	if rf, ok := ret.Get(0).(func(*v0.Value) *v0.Value); ok {
-		r0 = rf(value)
-	} else {
-		if ret.Get(0) != nil {
-			r0 = ret.Get(0).(*v0.Value)
-		}
-	}
-
-	if rf, ok := ret.Get(1).(func(*v0.Value) error); ok {
-		r1 = rf(value)
-	} else {
-		r1 = ret.Error(1)
-	}
-
-	return r0, r1
-}
-
-// Manager_WriteValue_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'WriteValue'
-type Manager_WriteValue_Call struct {
-	*mock.Call
-}
-
-// WriteValue is a helper method to define mock.On call
-//   - value *v0.Value
-func (_e *Manager_Expecter) WriteValue(value interface{}) *Manager_WriteValue_Call {
-	return &Manager_WriteValue_Call{Call: _e.mock.On("WriteValue", value)}
-}
-
-func (_c *Manager_WriteValue_Call) Run(run func(value *v0.Value)) *Manager_WriteValue_Call {
-	_c.Call.Run(func(args mock.Arguments) {
-		run(args[0].(*v0.Value))
-	})
-	return _c
-}
-
-func (_c *Manager_WriteValue_Call) Return(_a0 *v0.Value, _a1 error) *Manager_WriteValue_Call {
-	_c.Call.Return(_a0, _a1)
-	return _c
-}
-
-func (_c *Manager_WriteValue_Call) RunAndReturn(run func(*v0.Value) (*v0.Value, error)) *Manager_WriteValue_Call {
-	_c.Call.Return(run)
-	return _c
-}
-
-// NewManager creates a new instance of Manager. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
-// The first argument is typically a *testing.T value.
-func NewManager(t interface {
-	mock.TestingT
-	Cleanup(func())
-}) *Manager {
-	mock := &Manager{}
-	mock.Mock.Test(t)
-
-	t.Cleanup(func() { mock.AssertExpectations(t) })
-
-	return mock
-}
diff --git a/services/web/Makefile b/services/web/Makefile
index 017fab5408b..d25b19aecc6 100644
--- a/services/web/Makefile
+++ b/services/web/Makefile
@@ -1,6 +1,6 @@
 SHELL := bash
 NAME := web
-WEB_ASSETS_VERSION = v8.0.0-rc.1
+WEB_ASSETS_VERSION = v8.0.0-rc.3
 
 include ../../.make/recursion.mk
 
diff --git a/vendor/github.com/owncloud/libre-graph-api-go/README.md b/vendor/github.com/owncloud/libre-graph-api-go/README.md
index f5d8162e770..e574cacf048 100644
--- a/vendor/github.com/owncloud/libre-graph-api-go/README.md
+++ b/vendor/github.com/owncloud/libre-graph-api-go/README.md
@@ -215,7 +215,7 @@ Class | Method | HTTP request | Description
  - [Quota](docs/Quota.md)
  - [RemoteItem](docs/RemoteItem.md)
  - [SharePointIdentitySet](docs/SharePointIdentitySet.md)
- - [SharingInvitation](docs/SharingInvitation.md)
+ - [Shared](docs/Shared.md)
  - [SharingLink](docs/SharingLink.md)
  - [SharingLinkPassword](docs/SharingLinkPassword.md)
  - [SharingLinkType](docs/SharingLinkType.md)
diff --git a/vendor/github.com/owncloud/libre-graph-api-go/api_drive_item.go b/vendor/github.com/owncloud/libre-graph-api-go/api_drive_item.go
index ce8fb235791..aa152a84ac3 100644
--- a/vendor/github.com/owncloud/libre-graph-api-go/api_drive_item.go
+++ b/vendor/github.com/owncloud/libre-graph-api-go/api_drive_item.go
@@ -40,7 +40,7 @@ Delete a DriveItem by using its ID.
 
 Deleting items using this method moves the items to the recycle bin instead of permanently deleting the item.
 
-Mounted shares in the share jail are unmounted. The `@client.synchronize` property of the `driveItem` in the [sharedWithMe](#/me.drive/ListSharedWithMe) endpoint will change to false.
+Mounted shares in the share jail are unmounted. The `@client.synchronize` property of the `remoteItem` in the [sharedWithMe](#/me.drive/ListSharedWithMe) endpoint will change to false.
 
 
  @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
diff --git a/vendor/github.com/owncloud/libre-graph-api-go/api_drives_root.go b/vendor/github.com/owncloud/libre-graph-api-go/api_drives_root.go
index 8dd48fc81de..82314a31162 100644
--- a/vendor/github.com/owncloud/libre-graph-api-go/api_drives_root.go
+++ b/vendor/github.com/owncloud/libre-graph-api-go/api_drives_root.go
@@ -42,7 +42,7 @@ func (r ApiCreateDriveItemRequest) Execute() (*DriveItem, *http.Response, error)
 /*
 CreateDriveItem Create a drive item
 
-You can use the root childrens endpoint to mount a remoteItem in the share jail. The `@client.synchronize` property of the `driveItem` in the [sharedWithMe](#/me.drive/ListSharedWithMe) endpoint will change to true.
+You can use the root childrens endpoint to mount a remoteItem in the share jail. The `@client.synchronize` property of the `remoteItem` in the [sharedWithMe](#/me.drive/ListSharedWithMe) endpoint will change to true.
 
 
  @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
diff --git a/vendor/github.com/owncloud/libre-graph-api-go/model_drive_item.go b/vendor/github.com/owncloud/libre-graph-api-go/model_drive_item.go
index 916578c135e..061a4f84730 100644
--- a/vendor/github.com/owncloud/libre-graph-api-go/model_drive_item.go
+++ b/vendor/github.com/owncloud/libre-graph-api-go/model_drive_item.go
@@ -63,10 +63,6 @@ type DriveItem struct {
 	Permissions []Permission `json:"permissions,omitempty"`
 	Audio       *Audio       `json:"audio,omitempty"`
 	Video       *Video       `json:"video,omitempty"`
-	// Indicates if the item is synchronized with the underlying storage provider. Read-only.
-	ClientSynchronize *bool `json:"@client.synchronize,omitempty"`
-	// Properties or facets (see UI.Facet) annotated with this term will not be rendered if the annotation evaluates to true. Users can set this to hide permissons.
-	UIHidden *bool `json:"@UI.Hidden,omitempty"`
 }
 
 // NewDriveItem instantiates a new DriveItem object
@@ -1014,70 +1010,6 @@ func (o *DriveItem) SetVideo(v Video) {
 	o.Video = &v
 }
 
-// GetClientSynchronize returns the ClientSynchronize field value if set, zero value otherwise.
-func (o *DriveItem) GetClientSynchronize() bool {
-	if o == nil || IsNil(o.ClientSynchronize) {
-		var ret bool
-		return ret
-	}
-	return *o.ClientSynchronize
-}
-
-// GetClientSynchronizeOk returns a tuple with the ClientSynchronize field value if set, nil otherwise
-// and a boolean to check if the value has been set.
-func (o *DriveItem) GetClientSynchronizeOk() (*bool, bool) {
-	if o == nil || IsNil(o.ClientSynchronize) {
-		return nil, false
-	}
-	return o.ClientSynchronize, true
-}
-
-// HasClientSynchronize returns a boolean if a field has been set.
-func (o *DriveItem) HasClientSynchronize() bool {
-	if o != nil && !IsNil(o.ClientSynchronize) {
-		return true
-	}
-
-	return false
-}
-
-// SetClientSynchronize gets a reference to the given bool and assigns it to the ClientSynchronize field.
-func (o *DriveItem) SetClientSynchronize(v bool) {
-	o.ClientSynchronize = &v
-}
-
-// GetUIHidden returns the UIHidden field value if set, zero value otherwise.
-func (o *DriveItem) GetUIHidden() bool {
-	if o == nil || IsNil(o.UIHidden) {
-		var ret bool
-		return ret
-	}
-	return *o.UIHidden
-}
-
-// GetUIHiddenOk returns a tuple with the UIHidden field value if set, nil otherwise
-// and a boolean to check if the value has been set.
-func (o *DriveItem) GetUIHiddenOk() (*bool, bool) {
-	if o == nil || IsNil(o.UIHidden) {
-		return nil, false
-	}
-	return o.UIHidden, true
-}
-
-// HasUIHidden returns a boolean if a field has been set.
-func (o *DriveItem) HasUIHidden() bool {
-	if o != nil && !IsNil(o.UIHidden) {
-		return true
-	}
-
-	return false
-}
-
-// SetUIHidden gets a reference to the given bool and assigns it to the UIHidden field.
-func (o *DriveItem) SetUIHidden(v bool) {
-	o.UIHidden = &v
-}
-
 func (o DriveItem) MarshalJSON() ([]byte, error) {
 	toSerialize, err := o.ToMap()
 	if err != nil {
@@ -1175,12 +1107,6 @@ func (o DriveItem) ToMap() (map[string]interface{}, error) {
 	if !IsNil(o.Video) {
 		toSerialize["video"] = o.Video
 	}
-	if !IsNil(o.ClientSynchronize) {
-		toSerialize["@client.synchronize"] = o.ClientSynchronize
-	}
-	if !IsNil(o.UIHidden) {
-		toSerialize["@UI.Hidden"] = o.UIHidden
-	}
 	return toSerialize, nil
 }
 
diff --git a/vendor/github.com/owncloud/libre-graph-api-go/model_permission.go b/vendor/github.com/owncloud/libre-graph-api-go/model_permission.go
index 49ed4f6b9eb..546369acfbf 100644
--- a/vendor/github.com/owncloud/libre-graph-api-go/model_permission.go
+++ b/vendor/github.com/owncloud/libre-graph-api-go/model_permission.go
@@ -33,8 +33,11 @@ type Permission struct {
 	// Deprecated
 	GrantedToIdentities []IdentitySet `json:"grantedToIdentities,omitempty"`
 	// Use this to create a permission with custom actions.
-	LibreGraphPermissionsActions []string           `json:"@libre.graph.permissions.actions,omitempty"`
-	Invitation                   *SharingInvitation `json:"invitation,omitempty"`
+	LibreGraphPermissionsActions []string `json:"@libre.graph.permissions.actions,omitempty"`
+	// Indicates if the item is synchronized with the underlying storage provider. Read-only.
+	ClientSynchronize *bool `json:"@client.synchronize,omitempty"`
+	// Properties or facets (see UI.Facet) annotated with this term will not be rendered if the annotation evaluates to true. Users can set this to hide permissons.
+	UiHidden *bool `json:"@ui.hidden,omitempty"`
 }
 
 // NewPermission instantiates a new Permission object
@@ -324,36 +327,68 @@ func (o *Permission) SetLibreGraphPermissionsActions(v []string) {
 	o.LibreGraphPermissionsActions = v
 }
 
-// GetInvitation returns the Invitation field value if set, zero value otherwise.
-func (o *Permission) GetInvitation() SharingInvitation {
-	if o == nil || IsNil(o.Invitation) {
-		var ret SharingInvitation
+// GetClientSynchronize returns the ClientSynchronize field value if set, zero value otherwise.
+func (o *Permission) GetClientSynchronize() bool {
+	if o == nil || IsNil(o.ClientSynchronize) {
+		var ret bool
+		return ret
+	}
+	return *o.ClientSynchronize
+}
+
+// GetClientSynchronizeOk returns a tuple with the ClientSynchronize field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *Permission) GetClientSynchronizeOk() (*bool, bool) {
+	if o == nil || IsNil(o.ClientSynchronize) {
+		return nil, false
+	}
+	return o.ClientSynchronize, true
+}
+
+// HasClientSynchronize returns a boolean if a field has been set.
+func (o *Permission) HasClientSynchronize() bool {
+	if o != nil && !IsNil(o.ClientSynchronize) {
+		return true
+	}
+
+	return false
+}
+
+// SetClientSynchronize gets a reference to the given bool and assigns it to the ClientSynchronize field.
+func (o *Permission) SetClientSynchronize(v bool) {
+	o.ClientSynchronize = &v
+}
+
+// GetUiHidden returns the UiHidden field value if set, zero value otherwise.
+func (o *Permission) GetUiHidden() bool {
+	if o == nil || IsNil(o.UiHidden) {
+		var ret bool
 		return ret
 	}
-	return *o.Invitation
+	return *o.UiHidden
 }
 
-// GetInvitationOk returns a tuple with the Invitation field value if set, nil otherwise
+// GetUiHiddenOk returns a tuple with the UiHidden field value if set, nil otherwise
 // and a boolean to check if the value has been set.
-func (o *Permission) GetInvitationOk() (*SharingInvitation, bool) {
-	if o == nil || IsNil(o.Invitation) {
+func (o *Permission) GetUiHiddenOk() (*bool, bool) {
+	if o == nil || IsNil(o.UiHidden) {
 		return nil, false
 	}
-	return o.Invitation, true
+	return o.UiHidden, true
 }
 
-// HasInvitation returns a boolean if a field has been set.
-func (o *Permission) HasInvitation() bool {
-	if o != nil && !IsNil(o.Invitation) {
+// HasUiHidden returns a boolean if a field has been set.
+func (o *Permission) HasUiHidden() bool {
+	if o != nil && !IsNil(o.UiHidden) {
 		return true
 	}
 
 	return false
 }
 
-// SetInvitation gets a reference to the given SharingInvitation and assigns it to the Invitation field.
-func (o *Permission) SetInvitation(v SharingInvitation) {
-	o.Invitation = &v
+// SetUiHidden gets a reference to the given bool and assigns it to the UiHidden field.
+func (o *Permission) SetUiHidden(v bool) {
+	o.UiHidden = &v
 }
 
 func (o Permission) MarshalJSON() ([]byte, error) {
@@ -390,8 +425,11 @@ func (o Permission) ToMap() (map[string]interface{}, error) {
 	if !IsNil(o.LibreGraphPermissionsActions) {
 		toSerialize["@libre.graph.permissions.actions"] = o.LibreGraphPermissionsActions
 	}
-	if !IsNil(o.Invitation) {
-		toSerialize["invitation"] = o.Invitation
+	if !IsNil(o.ClientSynchronize) {
+		toSerialize["@client.synchronize"] = o.ClientSynchronize
+	}
+	if !IsNil(o.UiHidden) {
+		toSerialize["@ui.hidden"] = o.UiHidden
 	}
 	return toSerialize, nil
 }
diff --git a/vendor/github.com/owncloud/libre-graph-api-go/model_remote_item.go b/vendor/github.com/owncloud/libre-graph-api-go/model_remote_item.go
index 53c2d50a867..a188a36a6f9 100644
--- a/vendor/github.com/owncloud/libre-graph-api-go/model_remote_item.go
+++ b/vendor/github.com/owncloud/libre-graph-api-go/model_remote_item.go
@@ -45,6 +45,7 @@ type RemoteItem struct {
 	// An eTag for the content of the item. This eTag is not changed if only the metadata is changed. Note This property is not returned if the item is a folder. Read-only.
 	CTag            *string        `json:"cTag,omitempty"`
 	ParentReference *ItemReference `json:"parentReference,omitempty"`
+	Shared          *Shared        `json:"shared,omitempty"`
 	// The set of permissions for the item. Read-only. Nullable.
 	Permissions []Permission `json:"permissions,omitempty"`
 	// Size of the remote item. Read-only.
@@ -585,6 +586,38 @@ func (o *RemoteItem) SetParentReference(v ItemReference) {
 	o.ParentReference = &v
 }
 
+// GetShared returns the Shared field value if set, zero value otherwise.
+func (o *RemoteItem) GetShared() Shared {
+	if o == nil || IsNil(o.Shared) {
+		var ret Shared
+		return ret
+	}
+	return *o.Shared
+}
+
+// GetSharedOk returns a tuple with the Shared field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *RemoteItem) GetSharedOk() (*Shared, bool) {
+	if o == nil || IsNil(o.Shared) {
+		return nil, false
+	}
+	return o.Shared, true
+}
+
+// HasShared returns a boolean if a field has been set.
+func (o *RemoteItem) HasShared() bool {
+	if o != nil && !IsNil(o.Shared) {
+		return true
+	}
+
+	return false
+}
+
+// SetShared gets a reference to the given Shared and assigns it to the Shared field.
+func (o *RemoteItem) SetShared(v Shared) {
+	o.Shared = &v
+}
+
 // GetPermissions returns the Permissions field value if set, zero value otherwise.
 func (o *RemoteItem) GetPermissions() []Permission {
 	if o == nil || IsNil(o.Permissions) {
@@ -803,6 +836,9 @@ func (o RemoteItem) ToMap() (map[string]interface{}, error) {
 	if !IsNil(o.ParentReference) {
 		toSerialize["parentReference"] = o.ParentReference
 	}
+	if !IsNil(o.Shared) {
+		toSerialize["shared"] = o.Shared
+	}
 	if !IsNil(o.Permissions) {
 		toSerialize["permissions"] = o.Permissions
 	}
diff --git a/vendor/github.com/owncloud/libre-graph-api-go/model_shared.go b/vendor/github.com/owncloud/libre-graph-api-go/model_shared.go
new file mode 100644
index 00000000000..183048c9a3f
--- /dev/null
+++ b/vendor/github.com/owncloud/libre-graph-api-go/model_shared.go
@@ -0,0 +1,235 @@
+/*
+Libre Graph API
+
+Libre Graph is a free API for cloud collaboration inspired by the MS Graph API.
+
+API version: v1.0.4
+*/
+
+// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
+
+package libregraph
+
+import (
+	"encoding/json"
+	"time"
+)
+
+// checks if the Shared type satisfies the MappedNullable interface at compile time
+var _ MappedNullable = &Shared{}
+
+// Shared struct for Shared
+type Shared struct {
+	Owner *IdentitySet `json:"owner,omitempty"`
+	// Indicates the scope of how the item is shared: anonymous, organization, or users. Read-only.
+	Scope    *string      `json:"scope,omitempty"`
+	SharedBy *IdentitySet `json:"sharedBy,omitempty"`
+	// The UTC date and time when the item was shared. Read-only.
+	SharedDateTime *time.Time `json:"sharedDateTime,omitempty"`
+}
+
+// NewShared instantiates a new Shared object
+// This constructor will assign default values to properties that have it defined,
+// and makes sure properties required by API are set, but the set of arguments
+// will change when the set of required properties is changed
+func NewShared() *Shared {
+	this := Shared{}
+	return &this
+}
+
+// NewSharedWithDefaults instantiates a new Shared object
+// This constructor will only assign default values to properties that have it defined,
+// but it doesn't guarantee that properties required by API are set
+func NewSharedWithDefaults() *Shared {
+	this := Shared{}
+	return &this
+}
+
+// GetOwner returns the Owner field value if set, zero value otherwise.
+func (o *Shared) GetOwner() IdentitySet {
+	if o == nil || IsNil(o.Owner) {
+		var ret IdentitySet
+		return ret
+	}
+	return *o.Owner
+}
+
+// GetOwnerOk returns a tuple with the Owner field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *Shared) GetOwnerOk() (*IdentitySet, bool) {
+	if o == nil || IsNil(o.Owner) {
+		return nil, false
+	}
+	return o.Owner, true
+}
+
+// HasOwner returns a boolean if a field has been set.
+func (o *Shared) HasOwner() bool {
+	if o != nil && !IsNil(o.Owner) {
+		return true
+	}
+
+	return false
+}
+
+// SetOwner gets a reference to the given IdentitySet and assigns it to the Owner field.
+func (o *Shared) SetOwner(v IdentitySet) {
+	o.Owner = &v
+}
+
+// GetScope returns the Scope field value if set, zero value otherwise.
+func (o *Shared) GetScope() string {
+	if o == nil || IsNil(o.Scope) {
+		var ret string
+		return ret
+	}
+	return *o.Scope
+}
+
+// GetScopeOk returns a tuple with the Scope field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *Shared) GetScopeOk() (*string, bool) {
+	if o == nil || IsNil(o.Scope) {
+		return nil, false
+	}
+	return o.Scope, true
+}
+
+// HasScope returns a boolean if a field has been set.
+func (o *Shared) HasScope() bool {
+	if o != nil && !IsNil(o.Scope) {
+		return true
+	}
+
+	return false
+}
+
+// SetScope gets a reference to the given string and assigns it to the Scope field.
+func (o *Shared) SetScope(v string) {
+	o.Scope = &v
+}
+
+// GetSharedBy returns the SharedBy field value if set, zero value otherwise.
+func (o *Shared) GetSharedBy() IdentitySet {
+	if o == nil || IsNil(o.SharedBy) {
+		var ret IdentitySet
+		return ret
+	}
+	return *o.SharedBy
+}
+
+// GetSharedByOk returns a tuple with the SharedBy field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *Shared) GetSharedByOk() (*IdentitySet, bool) {
+	if o == nil || IsNil(o.SharedBy) {
+		return nil, false
+	}
+	return o.SharedBy, true
+}
+
+// HasSharedBy returns a boolean if a field has been set.
+func (o *Shared) HasSharedBy() bool {
+	if o != nil && !IsNil(o.SharedBy) {
+		return true
+	}
+
+	return false
+}
+
+// SetSharedBy gets a reference to the given IdentitySet and assigns it to the SharedBy field.
+func (o *Shared) SetSharedBy(v IdentitySet) {
+	o.SharedBy = &v
+}
+
+// GetSharedDateTime returns the SharedDateTime field value if set, zero value otherwise.
+func (o *Shared) GetSharedDateTime() time.Time {
+	if o == nil || IsNil(o.SharedDateTime) {
+		var ret time.Time
+		return ret
+	}
+	return *o.SharedDateTime
+}
+
+// GetSharedDateTimeOk returns a tuple with the SharedDateTime field value if set, nil otherwise
+// and a boolean to check if the value has been set.
+func (o *Shared) GetSharedDateTimeOk() (*time.Time, bool) {
+	if o == nil || IsNil(o.SharedDateTime) {
+		return nil, false
+	}
+	return o.SharedDateTime, true
+}
+
+// HasSharedDateTime returns a boolean if a field has been set.
+func (o *Shared) HasSharedDateTime() bool {
+	if o != nil && !IsNil(o.SharedDateTime) {
+		return true
+	}
+
+	return false
+}
+
+// SetSharedDateTime gets a reference to the given time.Time and assigns it to the SharedDateTime field.
+func (o *Shared) SetSharedDateTime(v time.Time) {
+	o.SharedDateTime = &v
+}
+
+func (o Shared) MarshalJSON() ([]byte, error) {
+	toSerialize, err := o.ToMap()
+	if err != nil {
+		return []byte{}, err
+	}
+	return json.Marshal(toSerialize)
+}
+
+func (o Shared) ToMap() (map[string]interface{}, error) {
+	toSerialize := map[string]interface{}{}
+	if !IsNil(o.Owner) {
+		toSerialize["owner"] = o.Owner
+	}
+	if !IsNil(o.Scope) {
+		toSerialize["scope"] = o.Scope
+	}
+	if !IsNil(o.SharedBy) {
+		toSerialize["sharedBy"] = o.SharedBy
+	}
+	if !IsNil(o.SharedDateTime) {
+		toSerialize["sharedDateTime"] = o.SharedDateTime
+	}
+	return toSerialize, nil
+}
+
+type NullableShared struct {
+	value *Shared
+	isSet bool
+}
+
+func (v NullableShared) Get() *Shared {
+	return v.value
+}
+
+func (v *NullableShared) Set(val *Shared) {
+	v.value = val
+	v.isSet = true
+}
+
+func (v NullableShared) IsSet() bool {
+	return v.isSet
+}
+
+func (v *NullableShared) Unset() {
+	v.value = nil
+	v.isSet = false
+}
+
+func NewNullableShared(val *Shared) *NullableShared {
+	return &NullableShared{value: val, isSet: true}
+}
+
+func (v NullableShared) MarshalJSON() ([]byte, error) {
+	return json.Marshal(v.value)
+}
+
+func (v *NullableShared) UnmarshalJSON(src []byte) error {
+	v.isSet = true
+	return json.Unmarshal(src, &v.value)
+}
diff --git a/vendor/github.com/owncloud/libre-graph-api-go/model_sharing_invitation.go b/vendor/github.com/owncloud/libre-graph-api-go/model_sharing_invitation.go
deleted file mode 100644
index b4e14ed2d51..00000000000
--- a/vendor/github.com/owncloud/libre-graph-api-go/model_sharing_invitation.go
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
-Libre Graph API
-
-Libre Graph is a free API for cloud collaboration inspired by the MS Graph API.
-
-API version: v1.0.4
-*/
-
-// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
-
-package libregraph
-
-import (
-	"encoding/json"
-)
-
-// checks if the SharingInvitation type satisfies the MappedNullable interface at compile time
-var _ MappedNullable = &SharingInvitation{}
-
-// SharingInvitation invitation-related data items
-type SharingInvitation struct {
-	InvitedBy *IdentitySet `json:"invitedBy,omitempty"`
-}
-
-// NewSharingInvitation instantiates a new SharingInvitation object
-// This constructor will assign default values to properties that have it defined,
-// and makes sure properties required by API are set, but the set of arguments
-// will change when the set of required properties is changed
-func NewSharingInvitation() *SharingInvitation {
-	this := SharingInvitation{}
-	return &this
-}
-
-// NewSharingInvitationWithDefaults instantiates a new SharingInvitation object
-// This constructor will only assign default values to properties that have it defined,
-// but it doesn't guarantee that properties required by API are set
-func NewSharingInvitationWithDefaults() *SharingInvitation {
-	this := SharingInvitation{}
-	return &this
-}
-
-// GetInvitedBy returns the InvitedBy field value if set, zero value otherwise.
-func (o *SharingInvitation) GetInvitedBy() IdentitySet {
-	if o == nil || IsNil(o.InvitedBy) {
-		var ret IdentitySet
-		return ret
-	}
-	return *o.InvitedBy
-}
-
-// GetInvitedByOk returns a tuple with the InvitedBy field value if set, nil otherwise
-// and a boolean to check if the value has been set.
-func (o *SharingInvitation) GetInvitedByOk() (*IdentitySet, bool) {
-	if o == nil || IsNil(o.InvitedBy) {
-		return nil, false
-	}
-	return o.InvitedBy, true
-}
-
-// HasInvitedBy returns a boolean if a field has been set.
-func (o *SharingInvitation) HasInvitedBy() bool {
-	if o != nil && !IsNil(o.InvitedBy) {
-		return true
-	}
-
-	return false
-}
-
-// SetInvitedBy gets a reference to the given IdentitySet and assigns it to the InvitedBy field.
-func (o *SharingInvitation) SetInvitedBy(v IdentitySet) {
-	o.InvitedBy = &v
-}
-
-func (o SharingInvitation) MarshalJSON() ([]byte, error) {
-	toSerialize, err := o.ToMap()
-	if err != nil {
-		return []byte{}, err
-	}
-	return json.Marshal(toSerialize)
-}
-
-func (o SharingInvitation) ToMap() (map[string]interface{}, error) {
-	toSerialize := map[string]interface{}{}
-	if !IsNil(o.InvitedBy) {
-		toSerialize["invitedBy"] = o.InvitedBy
-	}
-	return toSerialize, nil
-}
-
-type NullableSharingInvitation struct {
-	value *SharingInvitation
-	isSet bool
-}
-
-func (v NullableSharingInvitation) Get() *SharingInvitation {
-	return v.value
-}
-
-func (v *NullableSharingInvitation) Set(val *SharingInvitation) {
-	v.value = val
-	v.isSet = true
-}
-
-func (v NullableSharingInvitation) IsSet() bool {
-	return v.isSet
-}
-
-func (v *NullableSharingInvitation) Unset() {
-	v.value = nil
-	v.isSet = false
-}
-
-func NewNullableSharingInvitation(val *SharingInvitation) *NullableSharingInvitation {
-	return &NullableSharingInvitation{value: val, isSet: true}
-}
-
-func (v NullableSharingInvitation) MarshalJSON() ([]byte, error) {
-	return json.Marshal(v.value)
-}
-
-func (v *NullableSharingInvitation) UnmarshalJSON(src []byte) error {
-	v.isSet = true
-	return json.Unmarshal(src, &v.value)
-}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 7c4aecdfb15..ca7d3f34282 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -1590,7 +1590,7 @@ github.com/opentracing/opentracing-go/log
 # github.com/orcaman/concurrent-map v1.0.0
 ## explicit
 github.com/orcaman/concurrent-map
-# github.com/owncloud/libre-graph-api-go v1.0.5-0.20240130152355-ac663a9002a1
+# github.com/owncloud/libre-graph-api-go v1.0.5-0.20240115110609-b018a896364e
 ## explicit; go 1.18
 github.com/owncloud/libre-graph-api-go
 # github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c


Test patch:
diff --git a/services/graph/pkg/identity/ldap_education_class_test.go b/services/graph/pkg/identity/ldap_education_class_test.go
index f579b0b4198..b6f34cc8a3a 100644
--- a/services/graph/pkg/identity/ldap_education_class_test.go
+++ b/services/graph/pkg/identity/ldap_education_class_test.go
@@ -7,7 +7,7 @@ import (
 
 	"github.com/go-ldap/ldap/v3"
 	libregraph "github.com/owncloud/libre-graph-api-go"
-	"github.com/owncloud/ocis/v2/services/graph/pkg/identity/mocks"
+	"github.com/owncloud/ocis/v2/services/graph/mocks"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/mock"
 )
diff --git a/services/graph/pkg/identity/ldap_education_school_test.go b/services/graph/pkg/identity/ldap_education_school_test.go
index b5efbf10b6e..336b310ad87 100644
--- a/services/graph/pkg/identity/ldap_education_school_test.go
+++ b/services/graph/pkg/identity/ldap_education_school_test.go
@@ -8,9 +8,9 @@ import (
 
 	"github.com/go-ldap/ldap/v3"
 	libregraph "github.com/owncloud/libre-graph-api-go"
+	"github.com/owncloud/ocis/v2/services/graph/mocks"
 	"github.com/owncloud/ocis/v2/services/graph/pkg/config"
 	"github.com/owncloud/ocis/v2/services/graph/pkg/errorcode"
-	"github.com/owncloud/ocis/v2/services/graph/pkg/identity/mocks"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/mock"
 )
diff --git a/services/graph/pkg/identity/ldap_education_user_test.go b/services/graph/pkg/identity/ldap_education_user_test.go
index 3662f8919b8..763f27b4f37 100644
--- a/services/graph/pkg/identity/ldap_education_user_test.go
+++ b/services/graph/pkg/identity/ldap_education_user_test.go
@@ -6,7 +6,7 @@ import (
 
 	"github.com/go-ldap/ldap/v3"
 	libregraph "github.com/owncloud/libre-graph-api-go"
-	"github.com/owncloud/ocis/v2/services/graph/pkg/identity/mocks"
+	"github.com/owncloud/ocis/v2/services/graph/mocks"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/mock"
 )
diff --git a/services/graph/pkg/identity/ldap_group_test.go b/services/graph/pkg/identity/ldap_group_test.go
index beb66d901bb..bb7adfa9f35 100644
--- a/services/graph/pkg/identity/ldap_group_test.go
+++ b/services/graph/pkg/identity/ldap_group_test.go
@@ -8,7 +8,7 @@ import (
 
 	"github.com/CiscoM31/godata"
 	"github.com/go-ldap/ldap/v3"
-	"github.com/owncloud/ocis/v2/services/graph/pkg/identity/mocks"
+	"github.com/owncloud/ocis/v2/services/graph/mocks"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/mock"
 )
diff --git a/services/graph/pkg/identity/ldap_test.go b/services/graph/pkg/identity/ldap_test.go
index a936a719036..3d95795426c 100644
--- a/services/graph/pkg/identity/ldap_test.go
+++ b/services/graph/pkg/identity/ldap_test.go
@@ -11,8 +11,8 @@ import (
 	"github.com/go-ldap/ldap/v3"
 	libregraph "github.com/owncloud/libre-graph-api-go"
 	"github.com/owncloud/ocis/v2/ocis-pkg/log"
+	"github.com/owncloud/ocis/v2/services/graph/mocks"
 	"github.com/owncloud/ocis/v2/services/graph/pkg/config"
-	"github.com/owncloud/ocis/v2/services/graph/pkg/identity/mocks"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/mock"
 )
diff --git a/services/graph/pkg/service/v0/password_test.go b/services/graph/pkg/service/v0/password_test.go
index e25bfea3ad3..cb54ab6e5b0 100644
--- a/services/graph/pkg/service/v0/password_test.go
+++ b/services/graph/pkg/service/v0/password_test.go
@@ -24,7 +24,6 @@ import (
 	"github.com/owncloud/ocis/v2/services/graph/pkg/config"
 	"github.com/owncloud/ocis/v2/services/graph/pkg/config/defaults"
 	"github.com/owncloud/ocis/v2/services/graph/pkg/identity"
-	identitymocks "github.com/owncloud/ocis/v2/services/graph/pkg/identity/mocks"
 	service "github.com/owncloud/ocis/v2/services/graph/pkg/service/v0"
 	"github.com/stretchr/testify/mock"
 	"google.golang.org/grpc"
@@ -35,7 +34,7 @@ var _ = Describe("Users changing their own password", func() {
 		svc             service.Service
 		gatewayClient   *cs3mocks.GatewayAPIClient
 		gatewaySelector pool.Selectable[gateway.GatewayAPIClient]
-		ldapClient      *identitymocks.Client
+		ldapClient      *mocks.Client
 		ldapConfig      config.LDAP
 		identityBackend identity.Backend
 		eventsPublisher mocks.Publisher
@@ -136,8 +135,8 @@ var _ = Describe("Users changing their own password", func() {
 	)
 })
 
-func mockedLDAPClient() *identitymocks.Client {
-	lm := &identitymocks.Client{}
+func mockedLDAPClient() *mocks.Client {
+	lm := &mocks.Client{}
 
 	userEntry := ldap.NewEntry("uid=test", map[string][]string{
 		"uid":         {"test"},
diff --git a/services/graph/pkg/service/v0/sharedwithme_test.go b/services/graph/pkg/service/v0/sharedwithme_test.go
index 7ba445f90de..3426fe93f15 100644
--- a/services/graph/pkg/service/v0/sharedwithme_test.go
+++ b/services/graph/pkg/service/v0/sharedwithme_test.go
@@ -2,13 +2,11 @@ package svc_test
 
 import (
 	"context"
-	"encoding/json"
 	"net/http"
 	"net/http/httptest"
 	"time"
 
 	gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
-	groupv1beta1 "github.com/cs3org/go-cs3apis/cs3/identity/group/v1beta1"
 	userv1beta1 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
 	collaborationv1beta1 "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1"
 	providerv1beta1 "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
@@ -25,7 +23,6 @@ import (
 	"github.com/tidwall/gjson"
 	"google.golang.org/grpc"
 
-	libregraph "github.com/owncloud/libre-graph-api-go"
 	"github.com/owncloud/ocis/v2/ocis-pkg/shared"
 	"github.com/owncloud/ocis/v2/services/graph/pkg/config"
 	"github.com/owncloud/ocis/v2/services/graph/pkg/config/defaults"
@@ -133,32 +130,11 @@ var _ = Describe("SharedWithMe", func() {
 				Return(getUserResponseShareCreator, nil)
 			gatewayClient.On("GetUser", mock.Anything, mock.Anything).Return(getUserResponseDefault, nil)
 
-			gatewayClient.On("GetGroup", mock.Anything, mock.Anything).
-				Return(
-					&groupv1beta1.GetGroupResponse{
-						Status: status.NewOK(ctx),
-						Group: &groupv1beta1.Group{
-							Id: &groupv1beta1.GroupId{
-								OpaqueId: "group-id",
-							},
-							DisplayName: "Group",
-						},
-					}, nil)
-
 			listReceivedSharesResponse = &collaborationv1beta1.ListReceivedSharesResponse{
 				Status: status.NewOK(ctx),
 				Shares: []*collaborationv1beta1.ReceivedShare{
 					{
-						Share: &collaborationv1beta1.Share{
-							ResourceId: toResourceID("1$2!3"),
-							Id: &collaborationv1beta1.ShareId{
-								OpaqueId: "sh:are:id",
-							},
-							Permissions: &collaborationv1beta1.SharePermissions{
-								Permissions: roleconversions.NewViewerRole(true).CS3ResourcePermissions(),
-							},
-							Creator: getUserResponseShareCreator.User.Id,
-						},
+						Share: &collaborationv1beta1.Share{ResourceId: toResourceID("1$2!3")},
 						MountPoint: &providerv1beta1.Reference{
 							ResourceId: &providerv1beta1.ResourceId{
 								StorageId: utils.ShareStorageProviderID,
@@ -233,6 +209,9 @@ var _ = Describe("SharedWithMe", func() {
 			share.Id = &collaborationv1beta1.ShareId{OpaqueId: "1:2:3"}
 			share.Ctime = &typesv1beta1.Timestamp{Seconds: 4001}
 			share.Mtime = &typesv1beta1.Timestamp{Seconds: 4002}
+			share.Creator = &userv1beta1.UserId{
+				OpaqueId: "share-creator-id",
+			}
 
 			resourceInfo := statResponse.Info
 			resourceInfo.Name = "some folder"
@@ -358,24 +337,72 @@ var _ = Describe("SharedWithMe", func() {
 				httptest.NewRequest(http.MethodGet, "/graph/v1beta1/me/drive/sharedWithMe", nil),
 			)
 
-			driveitemJSON := gjson.Get(tape.Body.String(), "value.0")
-			Expect(driveitemJSON.Get("@UI\\.Hidden").Exists()).To(BeTrue())
-			Expect(driveitemJSON.Get("@UI\\.Hidden").Bool()).To(BeFalse())
-			Expect(driveitemJSON.Get("@client\\.synchronize").Exists()).To(BeTrue())
-			Expect(driveitemJSON.Get("@client\\.synchronize").Bool()).To(BeTrue())
+			jsonData := gjson.Get(tape.Body.String(), "value.0.remoteItem.permissions.0")
+
+			Expect(jsonData.Get("roles.0").String()).To(Equal(unifiedrole.UnifiedRoleViewerID))
+			Expect(jsonData.Get("@ui\\.hidden").Exists()).To(BeTrue())
+			Expect(jsonData.Get("@ui\\.hidden").Bool()).To(BeFalse())
+			Expect(jsonData.Get("@client\\.synchronize").Exists()).To(BeTrue())
+			Expect(jsonData.Get("@client\\.synchronize").Bool()).To(BeTrue())
+		})
+
+		It("populates the driveItem.remoteItem.shared properties", func() {
+			share := listReceivedSharesResponse.Shares[0].Share
+			share.Ctime = &typesv1beta1.Timestamp{Seconds: 4000}
+
+			svc.ListSharedWithMe(
+				tape,
+				httptest.NewRequest(http.MethodGet, "/graph/v1beta1/me/drive/sharedWithMe", nil),
+			)
+
+			jsonData := gjson.Get(tape.Body.String(), "value.0.remoteItem.shared")
+
+			Expect(jsonData.Get("sharedDateTime").String()).To(Equal(utils.TSToTime(share.Ctime).Format(time.RFC3339Nano)))
+		})
+
+		It("populates the driveItem.remoteItem.shared.owner properties", func() {
+			shareOwner := getUserResponseDefault.User
+
+			share := listReceivedSharesResponse.Shares[0].Share
+			share.Owner = shareOwner.Id
+
+			svc.ListSharedWithMe(
+				tape,
+				httptest.NewRequest(http.MethodGet, "/graph/v1beta1/me/drive/sharedWithMe", nil),
+			)
+
+			jsonData := gjson.Get(tape.Body.String(), "value.0.remoteItem.shared.owner")
 
-			permissionsJSON := driveitemJSON.Get("remoteItem.permissions.0")
-			Expect(permissionsJSON.Get("id").String()).To(Equal(listReceivedSharesResponse.Shares[0].Share.Id.OpaqueId))
-			Expect(permissionsJSON.Get("roles.0").String()).To(Equal(unifiedrole.UnifiedRoleViewerID))
-			Expect(permissionsJSON.Get("invitation.invitedBy.user.id").String()).To(Equal(getUserResponseShareCreator.User.Id.OpaqueId))
+			Expect(jsonData.Get("user.displayName").String()).To(Equal(shareOwner.DisplayName))
+			Expect(jsonData.Get("user.id").String()).To(Equal(shareOwner.Id.OpaqueId))
+		})
+
+		It("populates the driveItem.remoteItem.shared.sharedBy properties", func() {
+			shareCreator := getUserResponseDefault.User
+
+			share := listReceivedSharesResponse.Shares[0].Share
+			share.Creator = shareCreator.Id
+
+			svc.ListSharedWithMe(
+				tape,
+				httptest.NewRequest(http.MethodGet, "/graph/v1beta1/me/drive/sharedWithMe", nil),
+			)
+
+			jsonData := gjson.Get(tape.Body.String(), "value.0.remoteItem.shared.sharedBy")
+
+			Expect(jsonData.Get("user.displayName").String()).To(Equal(shareCreator.DisplayName))
+			Expect(jsonData.Get("user.id").String()).To(Equal(shareCreator.Id.OpaqueId))
 		})
 
 		It("returns shares created on project space", func() {
+			shareCreator := getUserResponseDefault.User
+
 			ownerID := &userv1beta1.UserId{
 				OpaqueId: "project-space-id",
 				Type:     userv1beta1.UserType_USER_TYPE_SPACE_OWNER,
 			}
 			share := listReceivedSharesResponse.Shares[0].Share
+			share.Creator = shareCreator.Id
 			share.Owner = ownerID
 			resourceInfo := statResponse.Info
 			resourceInfo.Owner = ownerID
@@ -387,45 +414,14 @@ var _ = Describe("SharedWithMe", func() {
 
 			jsonData := gjson.Get(tape.Body.String(), "value.0.createdBy")
 
-			Expect(jsonData.String()).To(Equal(""))
-
-			jsonData = gjson.Get(tape.Body.String(), "value.0.remoteItem.permissions.0.invitation.invitedBy.user")
-			Expect(jsonData.Get("displayName").String()).To(Equal(getUserResponseShareCreator.User.DisplayName))
-			Expect(jsonData.Get("id").String()).To(Equal(getUserResponseShareCreator.User.Id.OpaqueId))
-		})
+			Expect(jsonData.Get("user.displayName").String()).To(Equal(""))
+			Expect(jsonData.Get("user.id").String()).To(Equal(ownerID.OpaqueId))
 
-		It("returns a single drive item when multiple shares exist for the same resource", func() {
-			anotherShare := &collaborationv1beta1.ReceivedShare{
-				Share: &collaborationv1beta1.Share{
-					ResourceId: toResourceID("1$2!3"),
-					Id: &collaborationv1beta1.ShareId{
-						OpaqueId: "sh:are:id2",
-					},
-					Permissions: &collaborationv1beta1.SharePermissions{
-						Permissions: roleconversions.NewViewerRole(true).CS3ResourcePermissions(),
-					},
-					Creator: getUserResponseShareCreator.User.Id,
-					Grantee: &providerv1beta1.Grantee{
-						Type: providerv1beta1.GranteeType_GRANTEE_TYPE_GROUP,
-						Id: &providerv1beta1.Grantee_GroupId{
-							GroupId: &groupv1beta1.GroupId{
-								OpaqueId: "group-id",
-							},
-						},
-					},
-				},
-			}
-			listReceivedSharesResponse.Shares = append(listReceivedSharesResponse.Shares, anotherShare)
-			svc.ListSharedWithMe(
-				tape,
-				httptest.NewRequest(http.MethodGet, "/graph/v1beta1/me/drive/sharedWithMe", nil),
-			)
-			driveItems := libregraph.CollectionOfDriveItems{}
-			err := json.Unmarshal(tape.Body.Bytes(), &driveItems)
-			Expect(err).To(BeNil())
-			Expect(len(driveItems.Value)).To(Equal(1))
-			ri := driveItems.GetValue()[0].GetRemoteItem()
-			Expect(len(ri.GetPermissions())).To(Equal(2))
+			jsonData = gjson.Get(tape.Body.String(), "value.0.remoteItem.shared")
+			Expect(jsonData.Get("sharedBy.user.displayName").String()).To(Equal(shareCreator.DisplayName))
+			Expect(jsonData.Get("sharedBy.user.id").String()).To(Equal(shareCreator.Id.OpaqueId))
+			Expect(jsonData.Get("owner.user.displayName").String()).To(Equal(""))
+			Expect(jsonData.Get("owner.user.id").String()).To(Equal(ownerID.OpaqueId))
 		})
 	})
 })
diff --git a/services/graph/pkg/service/v0/users_test.go b/services/graph/pkg/service/v0/users_test.go
index 80698251f37..20bc10aa5d8 100644
--- a/services/graph/pkg/service/v0/users_test.go
+++ b/services/graph/pkg/service/v0/users_test.go
@@ -28,7 +28,6 @@ import (
 	"github.com/owncloud/ocis/v2/ocis-pkg/shared"
 	settingsmsg "github.com/owncloud/ocis/v2/protogen/gen/ocis/messages/settings/v0"
 	settings "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/settings/v0"
-	settingsmocks "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/settings/v0/mocks"
 	"github.com/owncloud/ocis/v2/services/graph/mocks"
 	"github.com/owncloud/ocis/v2/services/graph/pkg/config"
 	"github.com/owncloud/ocis/v2/services/graph/pkg/config/defaults"
@@ -49,7 +48,7 @@ var _ = Describe("Users", func() {
 		gatewaySelector   pool.Selectable[gateway.GatewayAPIClient]
 		eventsPublisher   mocks.Publisher
 		roleService       *mocks.RoleService
-		valueService      *settingsmocks.ValueService
+		valueService      *mocks.ValueService
 		permissionService *mocks.Permissions
 		identityBackend   *identitymocks.Backend
 
@@ -77,7 +76,7 @@ var _ = Describe("Users", func() {
 
 		identityBackend = &identitymocks.Backend{}
 		roleService = &mocks.RoleService{}
-		valueService = &settingsmocks.ValueService{}
+		valueService = &mocks.ValueService{}
 		permissionService = &mocks.Permissions{}
 
 		rr = httptest.NewRecorder()
diff --git a/tests/acceptance/expected-failures-webUI-on-OCIS-storage.md b/tests/acceptance/expected-failures-webUI-on-OCIS-storage.md
index b264e2c85ae..7b5cee0b2b7 100644
--- a/tests/acceptance/expected-failures-webUI-on-OCIS-storage.md
+++ b/tests/acceptance/expected-failures-webUI-on-OCIS-storage.md
@@ -14,47 +14,12 @@ Other free text and Markdown formatting can be used elsewhere in the document if
 
 - [webUILogin/openidLogin.feature:50](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUILogin/openidLogin.feature#L50)
 
-### [Support for favorites](https://github.com/owncloud/ocis/issues/1228)
-
-- [webUIFavorites/favoritesFile.feature:12](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIFavorites/favoritesFile.feature#L12)
-- [webUIFavorites/favoritesFile.feature:28](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIFavorites/favoritesFile.feature#L28)
-- [webUIFavorites/favoritesFile.feature:44](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIFavorites/favoritesFile.feature#L44)
-- [webUIFavorites/favoritesFile.feature:56](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIFavorites/favoritesFile.feature#L56)
-- [webUIFavorites/favoritesFile.feature:65](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIFavorites/favoritesFile.feature#L65)
-- [webUIFavorites/favoritesFile.feature:73](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIFavorites/favoritesFile.feature#L73)
-- [webUIFavorites/favoritesFile.feature:80](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIFavorites/favoritesFile.feature#L80)
-- [webUIFavorites/favoritesFile.feature:105](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIFavorites/favoritesFile.feature#L105)
-- [webUIFavorites/favoritesFile.feature:126](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIFavorites/favoritesFile.feature#L126)
-- [webUIFavorites/unfavoriteFile.feature:12](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIFavorites/unfavoriteFile.feature#L12)
-- [webUIFavorites/unfavoriteFile.feature:33](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIFavorites/unfavoriteFile.feature#L33)
-- [webUIFavorites/unfavoriteFile.feature:54](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIFavorites/unfavoriteFile.feature#L53)
-- [webUIFavorites/unfavoriteFile.feature:70](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIFavorites/unfavoriteFile.feature#L70)
-- [webUIFavorites/unfavoriteFile.feature:86](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIFavorites/unfavoriteFile.feature#L87)
-- [webUIFavorites/unfavoriteFile.feature:101](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIFavorites/unfavoriteFile.feature#L102)
-- [webUIResharing1/reshareUsers.feature:68](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIResharing1/reshareUsers.feature#L68)
-
-### [when sharer renames the shared resource, sharee get the updated name](https://github.com/owncloud/ocis/issues/2256)
-
-- [webUIRenameFiles/renameFiles.feature:227](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIRenameFiles/renameFiles.feature#L227)
-
-### [Cannot create users with special characters](https://github.com/owncloud/ocis/issues/1417)
-
-- [webUISharingAutocompletion/shareAutocompletionSpecialChars.feature:35](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingAutocompletion/shareAutocompletionSpecialChars.feature#L35)
-- [webUISharingAutocompletion/shareAutocompletionSpecialChars.feature:36](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingAutocompletion/shareAutocompletionSpecialChars.feature#L36)
-- [webUISharingAutocompletion/shareAutocompletionSpecialChars.feature:37](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingAutocompletion/shareAutocompletionSpecialChars.feature#L37)
-- [webUISharingAutocompletion/shareAutocompletionSpecialChars.feature:38](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingAutocompletion/shareAutocompletionSpecialChars.feature#L38)
-
 ### [Share additional info](https://github.com/owncloud/ocis/issues/1253)
 
 - [webUISharingInternalUsersShareWithPage/shareWithUsers.feature:126](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingInternalUsersShareWithPage/shareWithUsers.feature#L126)
 
-### [Expiration date set is not implemented in user share](https://github.com/owncloud/ocis/issues/1250)
-
-- [webUISharingInternalGroups/shareWithGroups.feature:228](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingInternalGroups/shareWithGroups.feature#L228)
-
 ### [Implement expiration date for shares](https://github.com/owncloud/ocis/issues/1250)
 
-- [webUISharingInternalGroups/shareWithGroups.feature:208](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingInternalGroups/shareWithGroups.feature#L208)
 - [webUISharingExpirationDate/shareWithExpirationDate.feature:21](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingExpirationDate/shareWithExpirationDate.feature#L21)
 
 ### [Notifications endpoint](https://github.com/owncloud/ocis/issues/14)
@@ -77,21 +42,10 @@ Other free text and Markdown formatting can be used elsewhere in the document if
 
 - [webUITrashbinRestore/trashbinRestore.feature:176](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUITrashbinRestore/trashbinRestore.feature#L176)
 
-### [Blocked user is not logged out](https://github.com/owncloud/ocis/issues/902)
-
-- [webUILogin/adminBlocksUser.feature:13](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUILogin/adminBlocksUser.feature#L13)
-
 ### [Browser session deleted user should not be valid for newly created user of same name](https://github.com/owncloud/ocis/issues/904)
 
 - [webUILogin/openidLogin.feature:60](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUILogin/openidLogin.feature#L60)
 
-### [Comments in sidebar](https://github.com/owncloud/web/issues/1158)
-
-- [webUIFilesDetails/fileDetails.feature:84](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIFilesDetails/fileDetails.feature#L84)
-- [webUIFilesDetails/fileDetails.feature:98](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIFilesDetails/fileDetails.feature#L98)
-- [webUIFilesDetails/fileDetails.feature:113](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIFilesDetails/fileDetails.feature#L113)
-- [webUIFilesDetails/fileDetails.feature:128](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIFilesDetails/fileDetails.feature#L128)
-
 ### [Deletion of a recursive folder from trashbin is not possible](https://github.com/owncloud/product/issues/188)
 
 - [webUITrashbinDelete/trashbinDelete.feature:51](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUITrashbinDelete/trashbinDelete.feature#L51)
@@ -131,12 +85,6 @@ Other free text and Markdown formatting can be used elsewhere in the document if
 
 - [webUIUpload/upload.feature:43](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIUpload/upload.feature#L43)
 
-### [Favorites deactivated in ocis temporarily](https://github.com/owncloud/ocis/issues/1228)
-
-- [webUIFilesDetails/fileDetails.feature:47](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIFilesDetails/fileDetails.feature#L47)
-- [webUIFilesDetails/fileDetails.feature:67](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIFilesDetails/fileDetails.feature#L67)
-- [webUIRenameFiles/renameFiles.feature:250](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUIRenameFiles/renameFiles.feature#L250)
-
 ### [PROPFIND to sub-folder of a shared resources with same name gives 404](https://github.com/owncloud/ocis/issues/3859)
 
-- [webUISharingAcceptShares/acceptShares.feature:163](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingAcceptShares/acceptShares.feature#L163)
+- [webUISharingAcceptShares/acceptShares.feature:105](https://github.com/owncloud/web/blob/master/tests/acceptance/features/webUISharingAcceptShares/acceptShares.feature#L105)
diff --git a/tests/acceptance/features/apiSharingNg/sharedWithMe.feature b/tests/acceptance/features/apiSharingNg/sharedWithMe.feature
index 7078597f739..64dc7f2fe1c 100644
--- a/tests/acceptance/features/apiSharingNg/sharedWithMe.feature
+++ b/tests/acceptance/features/apiSharingNg/sharedWithMe.feature
@@ -119,6 +119,7 @@ Feature: an user gets the resources shared to them
                   "name",
                   "parentReference",
                   "permissions",
+                  "shared",
                   "size"
                 ],
                 "properties": {
@@ -175,107 +176,82 @@ Feature: an user gets the resources shared to them
                       "textfile0.txt"
                     ]
                   },
-                  "permissions": {
-                    "type": "array",
-                    "items": [
-                      {
+                  "shared": {
+                    "type": "object",
+                    "required": [
+                      "sharedBy",
+                      "owner"
+                    ],
+                    "properties": {
+                      "owner": {
+                        "type": "object",
+                        "required": [
+                          "user"
+                        ],
+                        "properties": {
+                          "user": {
+                            "type": "object",
+                            "required": [
+                              "id",
+                              "displayName"
+                            ],
+                            "properties": {
+                              "id": {
+                                "type": "string",
+                                "pattern": "^%user_id_pattern%$"
+                              },
+                              "displayName": {
+                                "type": "string",
+                                "enum": [
+                                  "Alice Hansen"
+                                ]
+                              }
+                            }
+                          }
+                        }
+                      },
+                      "sharedBy": {
                         "type": "object",
                         "required": [
-                           "grantedToV2",
-                           "id",
-                           "invitation"
-                         ],
-                         "properties": {
-                           "id": {
-                             "type": "string"
-                           },
-                           "grantedToV2": {
-                             "type": "object",
-                             "required": [
-                               "user"
-                             ],
-                             "properties": {
-                               "user": {
-                                 "type": "object",
-                                 "properties": {
-                                   "displayName": {
-                                     "type": "string"
-                                   },
-                                   "id": {
-                                     "type": "string"
-                                   }
-                                 },
-                                 "required": [
-                                   "displayName",
-                                   "id"
-                                 ]
-                               }
-                             }
-                           },
-                           "invitation": {
-                             "type": "object",
-                             "properties": {
-                               "invitedBy": {
-                                 "type": "object",
-                                 "properties": {
-                                   "user": {
-                                     "type": "object",
-                                     "properties": {
-                                       "displayName": {
-                                         "type": "string"
-                                       },
-                                       "id": {
-                                         "type": "string"
-                                       }
-                                     },
-                                     "required": [
-                                       "displayName",
-                                       "id"
-                                     ]
-                                   }
-                                 },
-                                 "required": [
-                                   "user"
-                                 ]
-                               }
-                             },
-                             "required": [
-                               "invitedBy"
-                             ]
-                           },
-                           "@libre.graph.permissions.actions": {
-                             "type": "array",
-                             "items": [
-                               {
-                                 "type": "string"
-                               }
-                             ]
-                           },
-                           "roles": {
-                             "type": "array",
-                             "items": [
-                               {
-                                 "type": "string"
-                               }
-                             ]
-                           }
-                         }
-                       }
-                     ]
-                   },
-                   "size": {
-                     "type": "number",
-                     "enum": [
-                       11
-                     ]
-                   }
-                 }
-               }
-             }
-           }
-         }
-       }
-     }
+                          "user"
+                        ],
+                        "properties": {
+                          "user": {
+                            "type": "object",
+                            "required": [
+                              "id",
+                              "displayName"
+                            ],
+                            "properties": {
+                              "id": {
+                                "type": "string",
+                                "pattern": "^%user_id_pattern%$"
+                              },
+                              "displayName": {
+                                "type": "string",
+                                "enum": [
+                                  "Alice Hansen"
+                                ]
+                              }
+                            }
+                          }
+                        }
+                      }
+                    }
+                  },
+                  "size": {
+                    "type": "number",
+                    "enum": [
+                      11
+                    ]
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
     """
 
 
@@ -380,7 +356,8 @@ Feature: an user gets the resources shared to them
                   "lastModifiedDateTime",
                   "name",
                   "parentReference",
-                  "permissions"
+                  "permissions",
+                  "shared"
                 ],
                 "properties": {
                   "createdBy": {
@@ -436,99 +413,74 @@ Feature: an user gets the resources shared to them
                       "folder"
                     ]
                   },
-                  "permissions": {
-                    "type": "array",
-                    "items": [
-                      {
+                  "shared": {
+                    "type": "object",
+                    "required": [
+                      "sharedBy",
+                      "owner"
+                    ],
+                    "properties": {
+                      "owner": {
                         "type": "object",
                         "required": [
-                           "grantedToV2",
-                           "id",
-                           "invitation"
-                         ],
-                         "properties": {
-                           "id": {
-                             "type": "string"
-                           },
-                           "grantedToV2": {
-                             "type": "object",
-                             "required": [
-                               "user"
-                             ],
-                             "properties": {
-                               "user": {
-                                 "type": "object",
-                                 "properties": {
-                                   "displayName": {
-                                     "type": "string"
-                                   },
-                                   "id": {
-                                     "type": "string"
-                                   }
-                                 },
-                                 "required": [
-                                   "displayName",
-                                   "id"
-                                 ]
-                               }
-                             }
-                           },
-                           "invitation": {
-                             "type": "object",
-                             "properties": {
-                               "invitedBy": {
-                                 "type": "object",
-                                 "properties": {
-                                   "user": {
-                                     "type": "object",
-                                     "properties": {
-                                       "displayName": {
-                                         "type": "string"
-                                       },
-                                       "id": {
-                                         "type": "string"
-                                       }
-                                     },
-                                     "required": [
-                                       "displayName",
-                                       "id"
-                                     ]
-                                   }
-                                 },
-                                 "required": [
-                                   "user"
-                                 ]
-                               }
-                             },
-                             "required": [
-                               "invitedBy"
-                             ]
-                           },
-                           "@libre.graph.permissions.actions": {
-                             "type": "array",
-                             "items": [
-                               {
-                                 "type": "string"
-                               }
-                             ]
-                           },
-                           "roles": {
-                             "type": "array",
-                             "items": [
-                               {
-                                 "type": "string"
-                               }
-                             ]
-                           }
-                         }
-                       }
-                     ]
-                   }
-                 }
-               }
-             }
-           }
-         }
-       }
-     }
+                          "user"
+                        ],
+                        "properties": {
+                          "user": {
+                            "type": "object",
+                            "required": [
+                              "id",
+                              "displayName"
+                            ],
+                            "properties": {
+                              "id": {
+                                "type": "string",
+                                "pattern": "^%user_id_pattern%$"
+                              },
+                              "displayName": {
+                                "type": "string",
+                                "enum": [
+                                  "Alice Hansen"
+                                ]
+                              }
+                            }
+                          }
+                        }
+                      },
+                      "sharedBy": {
+                        "type": "object",
+                        "required": [
+                          "user"
+                        ],
+                        "properties": {
+                          "user": {
+                            "type": "object",
+                            "required": [
+                              "id",
+                              "displayName"
+                            ],
+                            "properties": {
+                              "id": {
+                                "type": "string",
+                                "pattern": "^%user_id_pattern%$"
+                              },
+                              "displayName": {
+                                "type": "string",
+                                "enum": [
+                                  "Alice Hansen"
+                                ]
+                              }
+                            }
+                          }
+                        }
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
     """