Repository: owncloud/ocis
Pull request #7511 (2023-10-17 09:49:59)

Pass docs pipeline requests through proxies
Hopefully fixes nasty `403` errors in docs pipeline

Fixes https://github.com/owncloud/ocis/issues/7509

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

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

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



Patch:
diff --git a/.drone.star b/.drone.star
index bb479d240d8..c31e9db1004 100644
--- a/.drone.star
+++ b/.drone.star
@@ -1818,6 +1818,14 @@ def docs():
             {
                 "name": "docs-generate",
                 "image": OC_CI_GOLANG,
+                "environment": {
+                    "HTTP_PROXY": {
+                        "from_secret": "drone_http_proxy",
+                    },
+                    "HTTPS_PROXY": {
+                        "from_secret": "drone_http_proxy",
+                    },
+                },
                 "commands": ["make docs-generate"],
             },
             {
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1c0e4ce7bb1..880073ed647 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,11 +9,9 @@ The following sections list the changes for unreleased.
 * Bugfix - Delete outdated userlog events: [#7410](https://github.com/owncloud/ocis/pull/7410)
 * Bugfix - Don't reload web config: [#7369](https://github.com/owncloud/ocis/pull/7369)
 * Bugfix - Fix the kql-bleve search: [#7290](https://github.com/owncloud/ocis/pull/7290)
-* Bugfix - Fix default language fallback: [#7465](https://github.com/owncloud/ocis/issues/7465)
 * Bugfix - Check school number for duplicates before adding a school: [#7351](https://github.com/owncloud/ocis/pull/7351)
 * Bugfix - Do not reset state of received shares when rebuilding the jsoncs3 index: [#7319](https://github.com/owncloud/ocis/issues/7319)
 * Bugfix - Deprecate redundant encryptions settings for notification service: [#7345](https://github.com/owncloud/ocis/issues/7345)
-* Bugfix - Fix preview request 500 error when made too early: [#7502](https://github.com/owncloud/ocis/issues/7502)
 * Bugfix - GetUserByClaim fixed for Active Directory: [#7476](https://github.com/owncloud/ocis/pull/7476)
 * Bugfix - Bring back the USERS_LDAP_USER_SCHEMA_ID variable: [#7312](https://github.com/owncloud/ocis/issues/7312)
 * Bugfix - Set the mountpoint on auto accept: [#7460](https://github.com/owncloud/ocis/pull/7460)
@@ -38,7 +36,6 @@ The following sections list the changes for unreleased.
 * Enhancement - Proxy uses service accounts for provisioning: [#7240](https://github.com/owncloud/ocis/pull/7240)
 * Enhancement - Introduce service accounts: [#6427](https://github.com/owncloud/ocis/pull/6427)
 * Enhancement - Make sse service scalable: [#7382](https://github.com/owncloud/ocis/pull/7382)
-* Enhancement - Thumbnail generation with image processors: [#7409](https://github.com/owncloud/ocis/pull/7409)
 
 ## Details
 
@@ -65,12 +62,6 @@ The following sections list the changes for unreleased.
    https://github.com/owncloud/ocis/issues/7282
    https://github.com/owncloud/ocis/pull/7290
 
-* Bugfix - Fix default language fallback: [#7465](https://github.com/owncloud/ocis/issues/7465)
-
-   Add the default language for the webui, the settings, userlog and notification service.
-
-   https://github.com/owncloud/ocis/issues/7465
-
 * Bugfix - Check school number for duplicates before adding a school: [#7351](https://github.com/owncloud/ocis/pull/7351)
 
    We fixed an issue that allowed to create two schools with the same school number
@@ -93,13 +84,6 @@ The following sections list the changes for unreleased.
 
    https://github.com/owncloud/ocis/issues/7345
 
-* Bugfix - Fix preview request 500 error when made too early: [#7502](https://github.com/owncloud/ocis/issues/7502)
-
-   Fix the status code and message when a thumbnail request is made too early.
-
-   https://github.com/owncloud/ocis/issues/7502
-   https://github.com/owncloud/ocis/pull/7507
-
 * Bugfix - GetUserByClaim fixed for Active Directory: [#7476](https://github.com/owncloud/ocis/pull/7476)
 
    The reva ldap backend for the users and groups service did not hex escape binary uuids in LDAP
@@ -325,34 +309,6 @@ The following sections list the changes for unreleased.
    fixed.
 
    https://github.com/owncloud/ocis/pull/7382
-
-* Enhancement - Thumbnail generation with image processors: [#7409](https://github.com/owncloud/ocis/pull/7409)
-
-   Thumbnails can now be changed during creation, previously the images were always scaled to fit
-   the given frame, but it could happen that the images were cut off because they could not be placed
-   better due to the aspect ratio.
-
-   This pr introduces the possibility of specifying how the behavior should be, following
-   processors are available
-
-  * resize
-  * fit
-  * fill
-  * thumbnail
-
-   The processor can be applied by adding the processor query param to the request, e.g.
-   `processor=fit`, `processor=fill`, ...
-
-   To find out more how the individual processors work please read
-   https://github.com/disintegration/imaging
-
-   If no processor is provided it behaves the same as before (resize for gif's and thumbnail for all
-   other)
-
-   https://github.com/owncloud/enterprise/issues/6057
-   https://github.com/owncloud/ocis/issues/5179
-   https://github.com/owncloud/web/issues/7728
-   https://github.com/owncloud/ocis/pull/7409
 # Changelog for [4.0.0] (2023-08-21)
 
 The following sections list the changes for 4.0.0.
diff --git a/changelog/unreleased/fix-default-mail-language-fallback.md b/changelog/unreleased/fix-default-mail-language-fallback.md
deleted file mode 100644
index 0d023f993ec..00000000000
--- a/changelog/unreleased/fix-default-mail-language-fallback.md
+++ /dev/null
@@ -1,6 +0,0 @@
-Bugfix: Fix default language fallback
-
-Add the default language for the webui,
-the settings, userlog and notification service.
-
-https://github.com/owncloud/ocis/issues/7465
diff --git a/changelog/unreleased/fix-docs-pipeline.md b/changelog/unreleased/fix-docs-pipeline.md
new file mode 100644
index 00000000000..7a6bb9ca853
--- /dev/null
+++ b/changelog/unreleased/fix-docs-pipeline.md
@@ -0,0 +1,6 @@
+Bugfix: Fix 403 in docs pipeline
+
+Docs pipeline was not routed through our proxies which could lead to requests being blacklisted
+
+https://github.com/owncloud/ocis/issues/7509
+https://github.com/owncloud/ocis/pull/7511
diff --git a/changelog/unreleased/fix-too-early-preview-request.md b/changelog/unreleased/fix-too-early-preview-request.md
deleted file mode 100644
index 22f77b3b9ad..00000000000
--- a/changelog/unreleased/fix-too-early-preview-request.md
+++ /dev/null
@@ -1,6 +0,0 @@
-Bugfix: Fix preview request 500 error when made too early
-
-Fix the status code and message when a thumbnail request is made too early.
-
-https://github.com/owncloud/ocis/issues/7502
-https://github.com/owncloud/ocis/pull/7507
diff --git a/changelog/unreleased/thumbnail-processors.md b/changelog/unreleased/thumbnail-processors.md
deleted file mode 100644
index fcd49ab21a1..00000000000
--- a/changelog/unreleased/thumbnail-processors.md
+++ /dev/null
@@ -1,22 +0,0 @@
-Enhancement: Thumbnail generation with image processors
-
-Thumbnails can now be changed during creation, previously the images were always scaled to fit the given frame,
-but it could happen that the images were cut off because they could not be placed better due to the aspect ratio.
-
-This pr introduces the possibility of specifying how the behavior should be, following processors are available
-
-* resize
-* fit
-* fill
-* thumbnail
-
-the processor can be applied by adding the processor query param to the request, e.g. `processor=fit`, `processor=fill`, ...
-
-to find out more how the individual processors work please read https://github.com/disintegration/imaging
-
-if no processor is provided it behaves the same as before (resize for gif's and thumbnail for all other)
-
-https://github.com/owncloud/ocis/pull/7409
-https://github.com/owncloud/enterprise/issues/6057
-https://github.com/owncloud/ocis/issues/5179
-https://github.com/owncloud/web/issues/7728
diff --git a/docs/services/app-registry/apps.md b/docs/services/app-registry/apps.md
index 719ac0a46a7..c8ac8451ace 100644
--- a/docs/services/app-registry/apps.md
+++ b/docs/services/app-registry/apps.md
@@ -493,4 +493,30 @@ App drivers represent apps, if the app is not able to register itself. Currently
 
 The CS3org WOPI server app driver is included in oCIS by default. It needs at least one WOPI compliant app (e.g. Collabora, OnlyOffice or Microsoft Online Server) or a CS3org WOPI bridge supported app (CodiMD or Etherpad) and the CS3org WOPI server.
 
-The configuration of the actual app provider in a docker-compose example can be found in the [full example](https://github.com/owncloud/ocis/blob/master/deployments/examples/ocis_wopi/docker-compose.yml) especially [ocis-appprovider-collabora](https://github.com/owncloud/ocis/blob/master/deployments/examples/ocis_wopi/docker-compose.yml#L102-L128) and [ocis-appprovider-onlyoffice](https://github.com/owncloud/ocis/blob/master/deployments/examples/ocis_wopi/docker-compose.yml#L130-L161)
+Here is a closer look at the configuration of the actual app provider in a docker-compose example (see also [full example](https://github.com/owncloud/ocis/blob/master/deployments/examples/ocis_wopi/docker-compose.yml)):
+
+```yaml
+services:
+  ocis:
+    image: owncloud/ocis:latest
+    ...
+    environment:
+      ...
+      GATEWAY_GRPC_ADDR: 0.0.0.0:9142 # make the REVA gateway accessible to the app drivers
+
+  ocis-appdriver-collabora:
+    image: owncloud/ocis:latest
+    command: storage-app-provider server # start only the app driver
+    environment:
+      STORAGE_GATEWAY_ENDPOINT: ocis:9142 # oCIS gateway endpoint
+      APP_PROVIDER_GRPC_ADDR: 0.0.0.0:9164
+      APP_PROVIDER_EXTERNAL_ADDR: ocis-appdriver-collabora:9164 # how oCIS can reach this app driver
+      OCIS_JWT_SECRET: ocis-jwt-secret
+      APP_PROVIDER_DRIVER: wopi
+      APP_PROVIDER_WOPI_DRIVER_APP_NAME: Collabora # will be used as name for this app
+      APP_PROVIDER_WOPI_DRIVER_APP_ICON_URI: https://www.collaboraoffice.com/wp-content/uploads/2019/01/CP-icon.png # will be used as icon for this app
+      APP_PROVIDER_WOPI_DRIVER_APP_URL: https://collabora.owncloud.test # endpoint of collabora
+      APP_PROVIDER_WOPI_DRIVER_INSECURE: false
+      APP_PROVIDER_WOPI_DRIVER_IOP_SECRET: wopi-iop-secret
+      APP_PROVIDER_WOPI_DRIVER_WOPI_URL: https://wopiserver.owncloud.test # endpoint of the CS3org WOPI server
+```
diff --git a/go.mod b/go.mod
index 50e8ab744bd..506d25bb518 100644
--- a/go.mod
+++ b/go.mod
@@ -92,14 +92,14 @@ require (
 	go.opentelemetry.io/otel/trace v1.19.0
 	golang.org/x/crypto v0.14.0
 	golang.org/x/exp v0.0.0-20230905200255-921286631fa9
-	golang.org/x/image v0.13.0
+	golang.org/x/image v0.12.0
 	golang.org/x/net v0.17.0
 	golang.org/x/oauth2 v0.12.0
 	golang.org/x/sync v0.3.0
 	golang.org/x/term v0.13.0
 	golang.org/x/text v0.13.0
 	google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d
-	google.golang.org/grpc v1.58.3
+	google.golang.org/grpc v1.58.2
 	google.golang.org/protobuf v1.31.0
 	gopkg.in/square/go-jose.v2 v2.6.0
 	gopkg.in/yaml.v2 v2.4.0
diff --git a/go.sum b/go.sum
index f93b6652af9..77e8ecaa0a5 100644
--- a/go.sum
+++ b/go.sum
@@ -2173,8 +2173,8 @@ golang.org/x/image v0.0.0-20210607152325-775e3b0c77b9/go.mod h1:023OzeP/+EPmXeap
 golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
 golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
 golang.org/x/image v0.0.0-20220302094943-723b81ca9867/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
-golang.org/x/image v0.13.0 h1:3cge/F/QTkNLauhf2QoE9zp+7sr+ZcL4HnoZmdwg9sg=
-golang.org/x/image v0.13.0/go.mod h1:6mmbMOeV28HuMTgA6OSRkdXKYw/t5W9Uwn2Yv1r3Yxk=
+golang.org/x/image v0.12.0 h1:w13vZbU4o5rKOFFR8y7M+c4A5jXDC0uXTdHYRP8X2DQ=
+golang.org/x/image v0.12.0/go.mod h1:Lu90jvHG7GfemOIcldsh9A2hS01ocl6oNO7ype5mEnk=
 golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
 golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
 golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@@ -2904,8 +2904,8 @@ google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGO
 google.golang.org/grpc v1.56.1/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s=
 google.golang.org/grpc v1.56.2/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s=
 google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo=
-google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ=
-google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0=
+google.golang.org/grpc v1.58.2 h1:SXUpjxeVF3FKrTYQI4f4KvbGD5u2xccdYdurwowix5I=
+google.golang.org/grpc v1.58.2/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0=
 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
 google.golang.org/grpc/examples v0.0.0-20211102180624-670c133e568e h1:m7aQHHqd0q89mRwhwS9Bx2rjyl/hsFAeta+uGrHsQaU=
 google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
diff --git a/protogen/gen/ocis/services/thumbnails/v0/thumbnails.pb.go b/protogen/gen/ocis/services/thumbnails/v0/thumbnails.pb.go
index 1b0aa92c6d3..25633f26e52 100644
--- a/protogen/gen/ocis/services/thumbnails/v0/thumbnails.pb.go
+++ b/protogen/gen/ocis/services/thumbnails/v0/thumbnails.pb.go
@@ -36,8 +36,6 @@ type GetThumbnailRequest struct {
 	Width int32 `protobuf:"varint,3,opt,name=width,proto3" json:"width,omitempty"`
 	// The height of the thumbnail
 	Height int32 `protobuf:"varint,4,opt,name=height,proto3" json:"height,omitempty"`
-	// Indicates which processor should be used
-	Processor string `protobuf:"bytes,5,opt,name=processor,proto3" json:"processor,omitempty"`
 	// Types that are assignable to Source:
 	//
 	//	*GetThumbnailRequest_WebdavSource
@@ -105,13 +103,6 @@ func (x *GetThumbnailRequest) GetHeight() int32 {
 	return 0
 }
 
-func (x *GetThumbnailRequest) GetProcessor() string {
-	if x != nil {
-		return x.Processor
-	}
-	return ""
-}
-
 func (m *GetThumbnailRequest) GetSource() isGetThumbnailRequest_Source {
 	if m != nil {
 		return m.Source
@@ -138,11 +129,11 @@ type isGetThumbnailRequest_Source interface {
 }
 
 type GetThumbnailRequest_WebdavSource struct {
-	WebdavSource *v0.WebdavSource `protobuf:"bytes,6,opt,name=webdav_source,json=webdavSource,proto3,oneof"`
+	WebdavSource *v0.WebdavSource `protobuf:"bytes,5,opt,name=webdav_source,json=webdavSource,proto3,oneof"`
 }
 
 type GetThumbnailRequest_Cs3Source struct {
-	Cs3Source *v0.CS3Source `protobuf:"bytes,7,opt,name=cs3_source,json=cs3Source,proto3,oneof"`
+	Cs3Source *v0.CS3Source `protobuf:"bytes,6,opt,name=cs3_source,json=cs3Source,proto3,oneof"`
 }
 
 func (*GetThumbnailRequest_WebdavSource) isGetThumbnailRequest_Source() {}
@@ -229,7 +220,7 @@ var file_ocis_services_thumbnails_v0_thumbnails_proto_rawDesc = []byte{
 	0x69, 0x6c, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
 	0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2f,
 	0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69,
-	0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf5, 0x02, 0x0a, 0x13, 0x47, 0x65,
+	0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xd7, 0x02, 0x0a, 0x13, 0x47, 0x65,
 	0x74, 0x54, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
 	0x74, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20,
 	0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x70, 0x61, 0x74, 0x68, 0x12, 0x51, 0x0a,
@@ -240,59 +231,58 @@ var file_ocis_services_thumbnails_v0_thumbnails_proto_rawDesc = []byte{
 	0x65, 0x52, 0x0d, 0x74, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x54, 0x79, 0x70, 0x65,
 	0x12, 0x14, 0x0a, 0x05, 0x77, 0x69, 0x64, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52,
 	0x05, 0x77, 0x69, 0x64, 0x74, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74,
-	0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x1c,
-	0x0a, 0x09, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x12, 0x50, 0x0a, 0x0d,
-	0x77, 0x65, 0x62, 0x64, 0x61, 0x76, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x06, 0x20,
-	0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x6f, 0x63, 0x69, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61,
-	0x67, 0x65, 0x73, 0x2e, 0x74, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x73, 0x2e, 0x76,
-	0x30, 0x2e, 0x57, 0x65, 0x62, 0x64, 0x61, 0x76, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x48, 0x00,
-	0x52, 0x0c, 0x77, 0x65, 0x62, 0x64, 0x61, 0x76, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x47,
-	0x0a, 0x0a, 0x63, 0x73, 0x33, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x07, 0x20, 0x01,
-	0x28, 0x0b, 0x32, 0x26, 0x2e, 0x6f, 0x63, 0x69, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67,
-	0x65, 0x73, 0x2e, 0x74, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x73, 0x2e, 0x76, 0x30,
-	0x2e, 0x43, 0x53, 0x33, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x48, 0x00, 0x52, 0x09, 0x63, 0x73,
-	0x33, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x42, 0x08, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63,
-	0x65, 0x22, 0x7e, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x54, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69,
-	0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x61, 0x74,
-	0x61, 0x5f, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x0c, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x25,
-	0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e,
-	0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72,
-	0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x69, 0x6d, 0x65, 0x74, 0x79, 0x70,
-	0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x69, 0x6d, 0x65, 0x74, 0x79, 0x70,
-	0x65, 0x32, 0x87, 0x01, 0x0a, 0x10, 0x54, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x53,
-	0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x73, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x54, 0x68, 0x75,
-	0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x12, 0x30, 0x2e, 0x6f, 0x63, 0x69, 0x73, 0x2e, 0x73, 0x65,
-	0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x74, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c,
-	0x73, 0x2e, 0x76, 0x30, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69,
-	0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x6f, 0x63, 0x69, 0x73, 0x2e,
+	0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x50,
+	0x0a, 0x0d, 0x77, 0x65, 0x62, 0x64, 0x61, 0x76, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18,
+	0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x6f, 0x63, 0x69, 0x73, 0x2e, 0x6d, 0x65, 0x73,
+	0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x74, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x73,
+	0x2e, 0x76, 0x30, 0x2e, 0x57, 0x65, 0x62, 0x64, 0x61, 0x76, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65,
+	0x48, 0x00, 0x52, 0x0c, 0x77, 0x65, 0x62, 0x64, 0x61, 0x76, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65,
+	0x12, 0x47, 0x0a, 0x0a, 0x63, 0x73, 0x33, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x06,
+	0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x6f, 0x63, 0x69, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73,
+	0x61, 0x67, 0x65, 0x73, 0x2e, 0x74, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x73, 0x2e,
+	0x76, 0x30, 0x2e, 0x43, 0x53, 0x33, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x48, 0x00, 0x52, 0x09,
+	0x63, 0x73, 0x33, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x42, 0x08, 0x0a, 0x06, 0x73, 0x6f, 0x75,
+	0x72, 0x63, 0x65, 0x22, 0x7e, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x54, 0x68, 0x75, 0x6d, 0x62, 0x6e,
+	0x61, 0x69, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x64,
+	0x61, 0x74, 0x61, 0x5f, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x0c, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74,
+	0x12, 0x25, 0x0a, 0x0e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x5f, 0x74, 0x6f, 0x6b,
+	0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66,
+	0x65, 0x72, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x69, 0x6d, 0x65, 0x74,
+	0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x69, 0x6d, 0x65, 0x74,
+	0x79, 0x70, 0x65, 0x32, 0x87, 0x01, 0x0a, 0x10, 0x54, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69,
+	0x6c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x73, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x54,
+	0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x12, 0x30, 0x2e, 0x6f, 0x63, 0x69, 0x73, 0x2e,
 	0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x74, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61,
 	0x69, 0x6c, 0x73, 0x2e, 0x76, 0x30, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x68, 0x75, 0x6d, 0x62, 0x6e,
-	0x61, 0x69, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0xe9, 0x02, 0x5a, 0x41,
-	0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x77, 0x6e, 0x63, 0x6c,
-	0x6f, 0x75, 0x64, 0x2f, 0x6f, 0x63, 0x69, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x67, 0x65,
-	0x6e, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x6f, 0x63, 0x69, 0x73, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69,
-	0x63, 0x65, 0x73, 0x2f, 0x74, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x73, 0x2f, 0x76,
-	0x30, 0x92, 0x41, 0xa2, 0x02, 0x12, 0xb8, 0x01, 0x0a, 0x22, 0x6f, 0x77, 0x6e, 0x43, 0x6c, 0x6f,
-	0x75, 0x64, 0x20, 0x49, 0x6e, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x65, 0x20, 0x53, 0x63, 0x61, 0x6c,
-	0x65, 0x20, 0x74, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x73, 0x22, 0x47, 0x0a, 0x0d,
-	0x6f, 0x77, 0x6e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x20, 0x47, 0x6d, 0x62, 0x48, 0x12, 0x20, 0x68,
-	0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
-	0x6d, 0x2f, 0x6f, 0x77, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6f, 0x63, 0x69, 0x73, 0x1a,
-	0x14, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x40, 0x6f, 0x77, 0x6e, 0x63, 0x6c, 0x6f, 0x75,
-	0x64, 0x2e, 0x63, 0x6f, 0x6d, 0x2a, 0x42, 0x0a, 0x0a, 0x41, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2d,
-	0x32, 0x2e, 0x30, 0x12, 0x34, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74,
-	0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x77, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64,
-	0x2f, 0x6f, 0x63, 0x69, 0x73, 0x2f, 0x62, 0x6c, 0x6f, 0x62, 0x2f, 0x6d, 0x61, 0x73, 0x74, 0x65,
-	0x72, 0x2f, 0x4c, 0x49, 0x43, 0x45, 0x4e, 0x53, 0x45, 0x32, 0x05, 0x31, 0x2e, 0x30, 0x2e, 0x30,
-	0x2a, 0x02, 0x01, 0x02, 0x32, 0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
-	0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x3a, 0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74,
-	0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x72, 0x3d, 0x0a, 0x10, 0x44, 0x65, 0x76, 0x65,
-	0x6c, 0x6f, 0x70, 0x65, 0x72, 0x20, 0x4d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x12, 0x29, 0x68, 0x74,
-	0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x6f, 0x77, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x64,
-	0x65, 0x76, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x74, 0x68, 0x75, 0x6d,
-	0x62, 0x6e, 0x61, 0x69, 0x6c, 0x73, 0x2f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x61, 0x69, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x6f, 0x63, 0x69,
+	0x73, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x74, 0x68, 0x75, 0x6d, 0x62,
+	0x6e, 0x61, 0x69, 0x6c, 0x73, 0x2e, 0x76, 0x30, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x68, 0x75, 0x6d,
+	0x62, 0x6e, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0xe9, 0x02,
+	0x5a, 0x41, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x77, 0x6e,
+	0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6f, 0x63, 0x69, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x67, 0x65, 0x6e, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x6f, 0x63, 0x69, 0x73, 0x2f, 0x73, 0x65, 0x72,
+	0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x74, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x73,
+	0x2f, 0x76, 0x30, 0x92, 0x41, 0xa2, 0x02, 0x12, 0xb8, 0x01, 0x0a, 0x22, 0x6f, 0x77, 0x6e, 0x43,
+	0x6c, 0x6f, 0x75, 0x64, 0x20, 0x49, 0x6e, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x65, 0x20, 0x53, 0x63,
+	0x61, 0x6c, 0x65, 0x20, 0x74, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x73, 0x22, 0x47,
+	0x0a, 0x0d, 0x6f, 0x77, 0x6e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x20, 0x47, 0x6d, 0x62, 0x48, 0x12,
+	0x20, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,
+	0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x77, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6f, 0x63, 0x69,
+	0x73, 0x1a, 0x14, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x40, 0x6f, 0x77, 0x6e, 0x63, 0x6c,
+	0x6f, 0x75, 0x64, 0x2e, 0x63, 0x6f, 0x6d, 0x2a, 0x42, 0x0a, 0x0a, 0x41, 0x70, 0x61, 0x63, 0x68,
+	0x65, 0x2d, 0x32, 0x2e, 0x30, 0x12, 0x34, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x67,
+	0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x77, 0x6e, 0x63, 0x6c, 0x6f,
+	0x75, 0x64, 0x2f, 0x6f, 0x63, 0x69, 0x73, 0x2f, 0x62, 0x6c, 0x6f, 0x62, 0x2f, 0x6d, 0x61, 0x73,
+	0x74, 0x65, 0x72, 0x2f, 0x4c, 0x49, 0x43, 0x45, 0x4e, 0x53, 0x45, 0x32, 0x05, 0x31, 0x2e, 0x30,
+	0x2e, 0x30, 0x2a, 0x02, 0x01, 0x02, 0x32, 0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74,
+	0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x3a, 0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63,
+	0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x72, 0x3d, 0x0a, 0x10, 0x44, 0x65,
+	0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x20, 0x4d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x12, 0x29,
+	0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x6f, 0x77, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64,
+	0x2e, 0x64, 0x65, 0x76, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x74, 0x68,
+	0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x73, 0x2f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+	0x33,
 }
 
 var (
diff --git a/protogen/proto/ocis/services/thumbnails/v0/thumbnails.proto b/protogen/proto/ocis/services/thumbnails/v0/thumbnails.proto
index f3499e9e91f..03c1dba60c0 100644
--- a/protogen/proto/ocis/services/thumbnails/v0/thumbnails.proto
+++ b/protogen/proto/ocis/services/thumbnails/v0/thumbnails.proto
@@ -47,11 +47,9 @@ message GetThumbnailRequest {
     int32 width = 3;
     // The height of the thumbnail
     int32 height = 4;
-    // Indicates which image processor to use
-    string processor = 5;
     oneof source {
-      ocis.messages.thumbnails.v0.WebdavSource webdav_source = 6;
-      ocis.messages.thumbnails.v0.CS3Source cs3_source = 7;
+      ocis.messages.thumbnails.v0.WebdavSource webdav_source = 5;
+      ocis.messages.thumbnails.v0.CS3Source cs3_source = 6;
     }
 }
 
diff --git a/services/idp/package.json b/services/idp/package.json
index 55774e6c1fa..84bfc1cbe6d 100644
--- a/services/idp/package.json
+++ b/services/idp/package.json
@@ -134,7 +134,7 @@
     "i18next-conv": "^14.0.0",
     "i18next-parser": "^8.7.0",
     "jest": "29.7.0",
-    "license-checker-rseidelsohn": "^4.2.10",
+    "license-checker-rseidelsohn": "^4.2.6",
     "mini-css-extract-plugin": "1.6.2",
     "optimize-css-assets-webpack-plugin": "6.0.1",
     "pnp-webpack-plugin": "1.7.0",
diff --git a/services/idp/pnpm-lock.yaml b/services/idp/pnpm-lock.yaml
index df2e937473e..5128fb384bf 100644
--- a/services/idp/pnpm-lock.yaml
+++ b/services/idp/pnpm-lock.yaml
@@ -191,8 +191,8 @@ devDependencies:
     specifier: 29.7.0
     version: 29.7.0(@types/node@20.5.9)
   license-checker-rseidelsohn:
-    specifier: ^4.2.10
-    version: 4.2.10
+    specifier: ^4.2.6
+    version: 4.2.6
   mini-css-extract-plugin:
     specifier: 1.6.2
     version: 1.6.2(webpack@4.47.0)
@@ -3364,9 +3364,8 @@ packages:
     resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==}
     dev: true
 
-  /abbrev@2.0.0:
-    resolution: {integrity: sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==}
-    engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
+  /abbrev@1.1.1:
+    resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==}
     dev: true
 
   /abort-controller@3.0.0:
@@ -8153,8 +8152,8 @@ packages:
       type-check: 0.4.0
     dev: true
 
-  /license-checker-rseidelsohn@4.2.10:
-    resolution: {integrity: sha512-phvcph9WTQ/Kb209kqwLxVA6CV8BAeUnFMIo+I+wBlp74El4ngbMwq49qSqqPYC5bfj49EWBXqwjvTFswGE2Fg==}
+  /license-checker-rseidelsohn@4.2.6:
+    resolution: {integrity: sha512-cV69Exm7y7stSVoYpFaQ1rEdmTtA7y1bMgTeeB1fqE0TZRkW1zpn8uIsIKeHK5rMvJYQzEuExNmLOTDXJMplgg==}
     engines: {node: '>=18', npm: '>=8'}
     hasBin: true
     dependencies:
@@ -8162,7 +8161,7 @@ packages:
       debug: 4.3.4
       lodash.clonedeep: 4.5.0
       mkdirp: 1.0.4
-      nopt: 7.2.0
+      nopt: 5.0.0
       read-installed-packages: 2.0.1
       semver: 7.5.4
       spdx-correct: 3.2.0
@@ -8683,12 +8682,12 @@ packages:
   /node-releases@2.0.13:
     resolution: {integrity: sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==}
 
-  /nopt@7.2.0:
-    resolution: {integrity: sha512-CVDtwCdhYIvnAzFoJ6NJ6dX3oga9/HyciQDnG1vQDjSLMeKLJ4A93ZqYKDrgYSr1FBY5/hMYC+2VCi24pgpkGA==}
-    engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
+  /nopt@5.0.0:
+    resolution: {integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==}
+    engines: {node: '>=6'}
     hasBin: true
     dependencies:
-      abbrev: 2.0.0
+      abbrev: 1.1.1
     dev: true
 
   /normalize-package-data@5.0.0:
diff --git a/services/notifications/README.md b/services/notifications/README.md
index 7b233e36cda..c75a6853946 100644
--- a/services/notifications/README.md
+++ b/services/notifications/README.md
@@ -66,7 +66,3 @@ Important: For the time being, the embedded ownCloud Web frontend only supports
 *   If a requested language code is not available, the service tries to fall back to the base language if available. For example, if the requested language-code `de_DE` is not available, the service tries to fall back to translations in the `de` folder.
 *   If the base language `de` is also not available, the service falls back to the system's default English (`en`),
 which is the source of the texts provided by the code.
-
-## Default Language
-
-The default language can be defined via the `OCIS_DEFAULT_LANGUAGE` environment variable. See the `settings` service for a detailed description.
diff --git a/services/notifications/pkg/command/server.go b/services/notifications/pkg/command/server.go
index a6355d11295..8887bf1ff61 100644
--- a/services/notifications/pkg/command/server.go
+++ b/services/notifications/pkg/command/server.go
@@ -116,7 +116,7 @@ func Server(cfg *config.Config) *cli.Command {
 				logger.Fatal().Err(err).Str("addr", cfg.Notifications.RevaGateway).Msg("could not get reva gateway selector")
 			}
 			valueService := settingssvc.NewValueService("com.owncloud.api.settings", grpcClient)
-			svc := service.NewEventsNotifier(evts, channel, logger, gatewaySelector, valueService, cfg.ServiceAccount.ServiceAccountID, cfg.ServiceAccount.ServiceAccountSecret, cfg.Notifications.EmailTemplatePath, cfg.Notifications.DefaultLanguage, cfg.WebUIURL)
+			svc := service.NewEventsNotifier(evts, channel, logger, gatewaySelector, valueService, cfg.ServiceAccount.ServiceAccountID, cfg.ServiceAccount.ServiceAccountSecret, cfg.Notifications.EmailTemplatePath, cfg.WebUIURL)
 
 			gr.Add(svc.Run, func(error) {
 				cancel()
diff --git a/services/notifications/pkg/config/config.go b/services/notifications/pkg/config/config.go
index 74908dda50c..2f805854079 100644
--- a/services/notifications/pkg/config/config.go
+++ b/services/notifications/pkg/config/config.go
@@ -1,4 +1,3 @@
-// Package config provides the service configuration.
 package config
 
 import (
@@ -32,7 +31,6 @@ type Notifications struct {
 	Events            Events                `yaml:"events"`
 	EmailTemplatePath string                `yaml:"email_template_path" env:"OCIS_EMAIL_TEMPLATE_PATH;NOTIFICATIONS_EMAIL_TEMPLATE_PATH" desc:"Path to Email notification templates overriding embedded ones."`
 	TranslationPath   string                `yaml:"translation_path" env:"OCIS_TRANSLATION_PATH,NOTIFICATIONS_TRANSLATION_PATH" desc:"(optional) Set this to a path with custom translations to overwrite the builtin translations. Note that file and folder naming rules apply, see the documentation for more details."`
-	DefaultLanguage   string                `yaml:"default_language" env:"OCIS_DEFAULT_LANGUAGE" desc:"The default language used by services and the WebUI. If not defined, English will be used as default. See the documentation for more details."`
 	RevaGateway       string                `yaml:"reva_gateway" env:"OCIS_REVA_GATEWAY" desc:"CS3 gateway used to look up user metadata"`
 	GRPCClientTLS     *shared.GRPCClientTLS `yaml:"grpc_client_tls"`
 }
diff --git a/services/notifications/pkg/email/composer.go b/services/notifications/pkg/email/composer.go
index 81f4cab1acb..8a9c61bc522 100644
--- a/services/notifications/pkg/email/composer.go
+++ b/services/notifications/pkg/email/composer.go
@@ -9,9 +9,9 @@ import (
 )
 
 // NewTextTemplate replace the body message template placeholders with the translated template
-func NewTextTemplate(mt MessageTemplate, locale, defaultLocale string, translationPath string, vars map[string]string) (MessageTemplate, error) {
+func NewTextTemplate(mt MessageTemplate, locale string, translationPath string, vars map[string]string) (MessageTemplate, error) {
 	var err error
-	t := l10n.NewTranslator(locale, defaultLocale, translationPath)
+	t := l10n.NewTranslator(locale, translationPath)
 	mt.Subject, err = composeMessage(t.Translate(mt.Subject), vars)
 	if err != nil {
 		return mt, err
@@ -32,9 +32,9 @@ func NewTextTemplate(mt MessageTemplate, locale, defaultLocale string, translati
 }
 
 // NewHTMLTemplate replace the body message template placeholders with the translated template
-func NewHTMLTemplate(mt MessageTemplate, locale, defaultLocale string, translationPath string, vars map[string]string) (MessageTemplate, error) {
+func NewHTMLTemplate(mt MessageTemplate, locale string, translationPath string, vars map[string]string) (MessageTemplate, error) {
 	var err error
-	t := l10n.NewTranslator(locale, defaultLocale, translationPath)
+	t := l10n.NewTranslator(locale, translationPath)
 	mt.Subject, err = composeMessage(t.Translate(mt.Subject), vars)
 	if err != nil {
 		return mt, err
diff --git a/services/notifications/pkg/email/email.go b/services/notifications/pkg/email/email.go
index b1b78931407..03a37b4992c 100644
--- a/services/notifications/pkg/email/email.go
+++ b/services/notifications/pkg/email/email.go
@@ -26,8 +26,8 @@ var (
 )
 
 // RenderEmailTemplate renders the email template for a new share
-func RenderEmailTemplate(mt MessageTemplate, locale, defaultLocale string, emailTemplatePath string, translationPath string, vars map[string]string) (*channels.Message, error) {
-	textMt, err := NewTextTemplate(mt, locale, defaultLocale, translationPath, vars)
+func RenderEmailTemplate(mt MessageTemplate, locale string, emailTemplatePath string, translationPath string, vars map[string]string) (*channels.Message, error) {
+	textMt, err := NewTextTemplate(mt, locale, translationPath, vars)
 	if err != nil {
 		return nil, err
 	}
@@ -39,7 +39,7 @@ func RenderEmailTemplate(mt MessageTemplate, locale, defaultLocale string, email
 	if err != nil {
 		return nil, err
 	}
-	htmlMt, err := NewHTMLTemplate(mt, locale, defaultLocale, translationPath, escapeStringMap(vars))
+	htmlMt, err := NewHTMLTemplate(mt, locale, translationPath, escapeStringMap(vars))
 	if err != nil {
 		return nil, err
 	}
diff --git a/services/notifications/pkg/email/l10n/locate.go b/services/notifications/pkg/email/l10n/locate.go
index 65ced721033..37d99f34f08 100644
--- a/services/notifications/pkg/email/l10n/locate.go
+++ b/services/notifications/pkg/email/l10n/locate.go
@@ -22,19 +22,11 @@ type Translator interface {
 }
 
 type translator struct {
-	locale *gotext.Locale
+	l *gotext.Locale
 }
 
 // NewTranslator Create Translator with library path and language code and load default domain
-func NewTranslator(locale, defaultLocale string, path string) Translator {
-	l := newLocate(locale, path)
-	if locale != "en" && len(l.GetTranslations()) == 0 {
-		l = newLocate(defaultLocale, path)
-	}
-	return &translator{locale: l}
-}
-
-func newLocate(local string, path string) *gotext.Locale {
+func NewTranslator(local string, path string) Translator {
 	var l *gotext.Locale
 	if path == "" {
 		filesystem, _ := fs.Sub(_translationFS, "locale")
@@ -43,9 +35,9 @@ func newLocate(local string, path string) *gotext.Locale {
 		l = gotext.NewLocale(path, local)
 	}
 	l.AddDomain(_domain) // make domain configurable only if needed
-	return l
+	return &translator{l: l}
 }
 
 func (t *translator) Translate(str string) string {
-	return t.locale.Get(str)
+	return t.l.Get(str)
 }
diff --git a/services/notifications/pkg/service/service.go b/services/notifications/pkg/service/service.go
index 8b4de702fb9..a8a3bf0e7ae 100644
--- a/services/notifications/pkg/service/service.go
+++ b/services/notifications/pkg/service/service.go
@@ -42,7 +42,7 @@ func NewEventsNotifier(
 	logger log.Logger,
 	gatewaySelector pool.Selectable[gateway.GatewayAPIClient],
 	valueService settingssvc.ValueService,
-	serviceAccountID, serviceAccountSecret, emailTemplatePath, defaultLanguage, ocisURL string) Service {
+	serviceAccountID, serviceAccountSecret, emailTemplatePath, ocisURL string) Service {
 
 	return eventsNotifier{
 		logger:               logger,
@@ -54,7 +54,6 @@ func NewEventsNotifier(
 		serviceAccountID:     serviceAccountID,
 		serviceAccountSecret: serviceAccountSecret,
 		emailTemplatePath:    emailTemplatePath,
-		defaultLanguage:      defaultLanguage,
 		ocisURL:              ocisURL,
 	}
 }
@@ -68,7 +67,6 @@ type eventsNotifier struct {
 	valueService         settingssvc.ValueService
 	emailTemplatePath    string
 	translationPath      string
-	defaultLanguage      string
 	ocisURL              string
 	serviceAccountID     string
 	serviceAccountSecret string
@@ -111,7 +109,7 @@ func (s eventsNotifier) render(ctx context.Context, template email.MessageTempla
 		locale := s.getUserLang(ctx, usr.GetId())
 		fields[granteeFieldName] = usr.GetDisplayName()
 
-		rendered, err := email.RenderEmailTemplate(template, locale, s.defaultLanguage, s.emailTemplatePath, s.translationPath, fields)
+		rendered, err := email.RenderEmailTemplate(template, locale, s.emailTemplatePath, s.translationPath, fields)
 		if err != nil {
 			return nil, err
 		}
diff --git a/services/settings/README.md b/services/settings/README.md
index afcc394773e..a22272cee6b 100644
--- a/services/settings/README.md
+++ b/services/settings/README.md
@@ -76,16 +76,6 @@ The settings service needs to know the ID's of service accounts but it doesn't n
 
 ## Default Language
 
-The default language can be defined via the `OCIS_DEFAULT_LANGUAGE` environment variable. If this variable is not defined, English will be used as default. The value has the ISO 639-1 format ("de", "en", etc.) and is limited by the list supported languages. This setting can be used to set the default language for notification and invitation emails.
+The default language can be defined via `SETTINGS_DEFAULT_LANGUAGE` environment variable. If this variable is not defined, English will be used as default. The value has the ISO 639-1 format ("de", "en", etc.) and is limited by the list supported languages. This setting can be used to set the default language for invitation emails.
 
-Important developer note: the list of supported languages is at the moment not easy defineable, as it is the minimum intersection of languages shown in the WebUI and languages defined in the ocis code for the use of notifications and userlog. Even more, not all languages where there are translations available on transifex, are available in the WebUI respectively for ocis notifications, and the translation rate for existing languages is partially not that high. You will see therefore quite often English default strings though a supported language may exist and was selected.
-
-The `OCIS_DEFAULT_LANGUAGE` setting impacts the `notification` and `userlog` services and the WebUI. Note that translations must exist for all named components to be presented correctly.
-
-*   If  `OCIS_DEFAULT_LANGUAGE` **is not set**, the expected behavior is:
-    *   The `notification` and `userlog` services and the WebUI use English by default until a user sets another language in the WebUI via _Account -> Language_.
-    *    If a user sets another language in the WebUI in _Account -> Language_, then the `notification` and `userlog` services and WebUI use the language defined by the user. If no translation is found, it falls back to English.
-
-*   If  `OCIS_DEFAULT_LANGUAGE` **is set**, the expected behavior is:
-    *   The `notification` and `userlog` services and the WebUI use `OCIS_DEFAULT_LANGUAGE`  by default until a user sets another language in the WebUI via _Account -> Language_.
-    *   If a user sets another language in the WebUI in _Account -> Language_, the `notification` and `userlog` services and WebUI use the language defined by the user. If no translation is found, it falls back to `OCIS_DEFAULT_LANGUAGE` and then to English.
+Important developer note: the list of supported languages is at the moment not easy defineable, as it is the minimum intersection of languages shown in the WebUI and languages defined in the ocis code for the use of notifications. Even more, not all languages where there are translations available on transifex, are available in the WebUI respectively for ocis notifications, and the translation rate for existing languages is partially not that high. You will see therefore quite often English default strings though a supported language may exist and was selected.
diff --git a/services/settings/pkg/config/config.go b/services/settings/pkg/config/config.go
index 1791a4ac6ec..7b75412021e 100644
--- a/services/settings/pkg/config/config.go
+++ b/services/settings/pkg/config/config.go
@@ -39,7 +39,7 @@ type Config struct {
 
 	ServiceAccountIDAdmin string `yaml:"service_account_id_admin" env:"OCIS_SERVICE_ACCOUNT_ID;SETTINGS_SERVICE_ACCOUNT_ID_ADMIN" desc:"The ID of the service account having the admin role. See the 'auth-service' service description for more details."`
 
-	DefaultLanguage string `yaml:"default_language" env:"OCIS_DEFAULT_LANGUAGE" desc:"The default language used by services and the WebUI. If not defined, English will be used as default. See the documentation for more details."`
+	DefaultLanguage string `yaml:"default_language" env:"SETTINGS_DEFAULT_LANGUAGE" desc:"The default language. If not defined, English will be used as default. See the documentation for more details."`
 
 	Context context.Context `yaml:"-"`
 }
diff --git a/services/thumbnails/README.md b/services/thumbnails/README.md
index 2d39563ee14..43dbc463d08 100644
--- a/services/thumbnails/README.md
+++ b/services/thumbnails/README.md
@@ -10,9 +10,9 @@ The relevant environment variables defining file locations are:
 -   (2) `STORAGE_USERS_OCIS_ROOT`
 -   (3) `THUMBNAILS_FILESYSTEMSTORAGE_ROOT`
 
-(1) ... Having a default set by the Infinite Scale code, but if defined, used as base path for other services.
-(2) ... Source files, defaults to (1) plus path component, but can be freely defined if required.
-(3) ... Target files, defaults to (1) plus path component, but can be freely defined if required.
+(1) ... Having a default set by the Infinite Scale code, but if defined, used as base path for other services.  
+(2) ... Source files, defaults to (1) plus path component, but can be freely defined if required.  
+(3) ... Target files, defaults to (1) plus path component, but can be freely defined if required.  
 
 For details and defaults for these environment variables see the ocis admin documentation.
 
@@ -45,20 +45,9 @@ Various resolutions can be defined via `THUMBNAILS_RESOLUTIONS`. A requestor can
 
 Example:
 
-Requested: 18x12
-Available: 30x20, 15x10, 9x6
-Returned: 15x10
-
-## Thumbnail Processors
-
-Image generation can be configured by defining different processors, following processors are available:
-
-*   `resize`
-*   `fit`
-*   `fill`
-*   `thumbnail`
-
-To apply one of those, a query parameter has to be added to the request, e.g. `?processor=fit`
+Requested: 18x12  
+Available: 30x20, 15x10, 9x6  
+Returned: 15x10  
 
 ## Deleting Thumbnails
 
diff --git a/services/thumbnails/pkg/service/grpc/v0/service.go b/services/thumbnails/pkg/service/grpc/v0/service.go
index fd97bfd897e..070613b0c03 100644
--- a/services/thumbnails/pkg/service/grpc/v0/service.go
+++ b/services/thumbnails/pkg/service/grpc/v0/service.go
@@ -16,10 +16,6 @@ import (
 	"github.com/cs3org/reva/v2/pkg/storagespace"
 	"github.com/cs3org/reva/v2/pkg/utils"
 	"github.com/golang-jwt/jwt/v4"
-	"github.com/pkg/errors"
-	merrors "go-micro.dev/v4/errors"
-	"google.golang.org/grpc/metadata"
-
 	"github.com/owncloud/ocis/v2/ocis-pkg/log"
 	thumbnailssvc "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/thumbnails/v0"
 	"github.com/owncloud/ocis/v2/services/thumbnails/pkg/preprocessor"
@@ -27,6 +23,9 @@ import (
 	tjwt "github.com/owncloud/ocis/v2/services/thumbnails/pkg/service/jwt"
 	"github.com/owncloud/ocis/v2/services/thumbnails/pkg/thumbnail"
 	"github.com/owncloud/ocis/v2/services/thumbnails/pkg/thumbnail/imgsource"
+	"github.com/pkg/errors"
+	merrors "go-micro.dev/v4/errors"
+	"google.golang.org/grpc/metadata"
 )
 
 // NewService returns a service implementation for Service.
@@ -125,7 +124,7 @@ func (g Thumbnail) handleCS3Source(ctx context.Context, req *thumbnailssvc.GetTh
 	if tType == "" {
 		tType = req.GetThumbnailType().String()
 	}
-	tr, err := thumbnail.PrepareRequest(int(req.Width), int(req.Height), tType, sRes.GetInfo().GetChecksum().GetSum(), req.Processor)
+	tr, err := thumbnail.PrepareRequest(int(req.Width), int(req.Height), tType, sRes.GetInfo().GetChecksum().GetSum())
 	if err != nil {
 		return "", merrors.BadRequest(g.serviceID, err.Error())
 	}
@@ -208,7 +207,7 @@ func (g Thumbnail) handleWebdavSource(ctx context.Context, req *thumbnailssvc.Ge
 	if tType == "" {
 		tType = req.GetThumbnailType().String()
 	}
-	tr, err := thumbnail.PrepareRequest(int(req.Width), int(req.Height), tType, sRes.GetInfo().GetChecksum().GetSum(), req.Processor)
+	tr, err := thumbnail.PrepareRequest(int(req.Width), int(req.Height), tType, sRes.GetInfo().GetChecksum().GetSum())
 	if err != nil {
 		return "", merrors.BadRequest(g.serviceID, err.Error())
 	}
diff --git a/services/thumbnails/pkg/thumbnail/encoding.go b/services/thumbnails/pkg/thumbnail/encoding.go
index 96f71074439..5126fd6af9b 100644
--- a/services/thumbnails/pkg/thumbnail/encoding.go
+++ b/services/thumbnails/pkg/thumbnail/encoding.go
@@ -114,8 +114,8 @@ func EncoderForType(fileType string) (Encoder, error) {
 }
 
 // GetExtForMime return the supported extension by mime
-func GetExtForMime(fileType string) string {
-	ext := strings.TrimPrefix(strings.TrimSpace(strings.ToLower(fileType)), "image/")
+func GetExtForMime(mime string) string {
+	ext := strings.TrimPrefix(strings.TrimSpace(strings.ToLower(mime)), "image/")
 	switch ext {
 	case typeJpg, typeJpeg, typePng, typeGif:
 		return ext
diff --git a/services/thumbnails/pkg/thumbnail/generator.go b/services/thumbnails/pkg/thumbnail/generator.go
index e8d967c4eb9..b22c15da458 100644
--- a/services/thumbnails/pkg/thumbnail/generator.go
+++ b/services/thumbnails/pkg/thumbnail/generator.go
@@ -1,6 +1,7 @@
 package thumbnail
 
 import (
+	"errors"
 	"image"
 	"image/color"
 	"image/draw"
@@ -10,34 +11,36 @@ import (
 	"github.com/disintegration/imaging"
 )
 
-// Generator generates a web friendly file version.
+var (
+	// ErrInvalidType represents the error when a type can't be encoded.
+	ErrInvalidType2 = errors.New("can't encode this type")
+	// ErrNoGeneratorForType represents the error when no generator could be found for a type.
+	ErrNoGeneratorForType = errors.New("no generator for this type found")
+)
+
 type Generator interface {
-	Generate(image.Rectangle, interface{}, Processor) (interface{}, error)
+	GenerateThumbnail(image.Rectangle, interface{}) (interface{}, error)
 }
 
-// SimpleGenerator is the default image generator and is used for all image types expect gif.
 type SimpleGenerator struct{}
 
-// Generate generates a alternative image version.
-func (g SimpleGenerator) Generate(size image.Rectangle, img interface{}, processor Processor) (interface{}, error) {
+func (g SimpleGenerator) GenerateThumbnail(size image.Rectangle, img interface{}) (interface{}, error) {
 	m, ok := img.(image.Image)
 	if !ok {
-		return nil, ErrInvalidType
+		return nil, ErrInvalidType2
 	}
 
-	return processor.Process(m, size.Dx(), size.Dy(), imaging.Lanczos), nil
+	return imaging.Thumbnail(m, size.Dx(), size.Dy(), imaging.Lanczos), nil
 }
 
-// GifGenerator is used to create a web friendly version of the provided gif image.
 type GifGenerator struct{}
 
-// Generate generates a alternative gif version.
-func (g GifGenerator) Generate(size image.Rectangle, img interface{}, processor Processor) (interface{}, error) {
+func (g GifGenerator) GenerateThumbnail(size image.Rectangle, img interface{}) (interface{}, error) {
 	// Code inspired by https://github.com/willnorris/gifresize/blob/db93a7e1dcb1c279f7eeb99cc6d90b9e2e23e871/gifresize.go
 
 	m, ok := img.(*gif.GIF)
 	if !ok {
-		return nil, ErrInvalidType
+		return nil, ErrInvalidType2
 	}
 	// Create a new RGBA image to hold the incremental frames.
 	srcX, srcY := m.Config.Width, m.Config.Height
@@ -48,8 +51,8 @@ func (g GifGenerator) Generate(size image.Rectangle, img interface{}, processor
 		bounds := frame.Bounds()
 		prev := tmp
 		draw.Draw(tmp, bounds, frame, bounds.Min, draw.Over)
-		processed := processor.Process(tmp, size.Dx(), size.Dy(), imaging.Lanczos)
-		m.Image[i] = g.imageToPaletted(processed, frame.Palette)
+		scaled := imaging.Resize(tmp, size.Dx(), size.Dy(), imaging.Lanczos)
+		m.Image[i] = g.imageToPaletted(scaled, frame.Palette)
 
 		switch m.Disposal[i] {
 		case gif.DisposalBackground:
diff --git a/services/thumbnails/pkg/thumbnail/processor.go b/services/thumbnails/pkg/thumbnail/processor.go
deleted file mode 100644
index 3782fac4fce..00000000000
--- a/services/thumbnails/pkg/thumbnail/processor.go
+++ /dev/null
@@ -1,51 +0,0 @@
-package thumbnail
-
-import (
-	"image"
-	"strings"
-
-	"github.com/disintegration/imaging"
-)
-
-// Processor processes the thumbnail by applying different transformations to it.
-type Processor interface {
-	ID() string
-	Process(img image.Image, width, height int, filter imaging.ResampleFilter) *image.NRGBA
-}
-
-// DefinableProcessor is the most simple processor, it holds a replaceable image converter function.
-type DefinableProcessor struct {
-	Slug      string
-	Converter func(img image.Image, width, height int, filter imaging.ResampleFilter) *image.NRGBA
-}
-
-// ID returns the processor identification.
-func (p DefinableProcessor) ID() string { return p.Slug }
-
-// Process transforms the given image.
-func (p DefinableProcessor) Process(img image.Image, width, height int, filter imaging.ResampleFilter) *image.NRGBA {
-	return p.Converter(img, width, height, filter)
-}
-
-// ProcessorFor returns a matching Processor
-func ProcessorFor(id, fileType string) (DefinableProcessor, error) {
-	switch strings.ToLower(id) {
-	case "fit":
-		return DefinableProcessor{Slug: strings.ToLower(id), Converter: imaging.Fit}, nil
-	case "resize":
-		return DefinableProcessor{Slug: strings.ToLower(id), Converter: imaging.Resize}, nil
-	case "fill":
-		return DefinableProcessor{Slug: strings.ToLower(id), Converter: func(img image.Image, width, height int, filter imaging.ResampleFilter) *image.NRGBA {
-			return imaging.Fill(img, width, height, imaging.Center, filter)
-		}}, nil
-	case "thumbnail":
-		return DefinableProcessor{Slug: strings.ToLower(id), Converter: imaging.Thumbnail}, nil
-	default:
-		switch strings.ToLower(fileType) {
-		case typeGif:
-			return DefinableProcessor{Converter: imaging.Resize}, nil
-		default:
-			return DefinableProcessor{Converter: imaging.Thumbnail}, nil
-		}
-	}
-}
diff --git a/services/thumbnails/pkg/thumbnail/storage/filesystem.go b/services/thumbnails/pkg/thumbnail/storage/filesystem.go
index dd18e88f577..692669d3024 100644
--- a/services/thumbnails/pkg/thumbnail/storage/filesystem.go
+++ b/services/thumbnails/pkg/thumbnail/storage/filesystem.go
@@ -5,12 +5,10 @@ import (
 	"os"
 	"path/filepath"
 	"strconv"
-	"strings"
-
-	"github.com/pkg/errors"
 
 	"github.com/owncloud/ocis/v2/ocis-pkg/log"
 	"github.com/owncloud/ocis/v2/services/thumbnails/pkg/config"
+	"github.com/pkg/errors"
 )
 
 const (
@@ -84,14 +82,7 @@ func (s FileSystem) Put(key string, img []byte) error {
 func (s FileSystem) BuildKey(r Request) string {
 	checksum := r.Checksum
 	filetype := r.Types[0]
+	filename := strconv.Itoa(r.Resolution.Dx()) + "x" + strconv.Itoa(r.Resolution.Dy()) + "." + filetype
 
-	parts := []string{strconv.Itoa(r.Resolution.Dx()), "x", strconv.Itoa(r.Resolution.Dy())}
-
-	if r.Characteristic != "" {
-		parts = append(parts, "-", r.Characteristic)
-	}
-
-	parts = append(parts, ".", filetype)
-
-	return filepath.Join(checksum[:2], checksum[2:4], checksum[4:], strings.Join(parts, ""))
+	return filepath.Join(checksum[:2], checksum[2:4], checksum[4:], filename)
 }
diff --git a/services/thumbnails/pkg/thumbnail/storage/inmemory.go b/services/thumbnails/pkg/thumbnail/storage/inmemory.go
index 17683185181..1c7befd888e 100644
--- a/services/thumbnails/pkg/thumbnail/storage/inmemory.go
+++ b/services/thumbnails/pkg/thumbnail/storage/inmemory.go
@@ -38,13 +38,7 @@ func (s InMemory) BuildKey(r Request) string {
 	parts := []string{
 		r.Checksum,
 		r.Resolution.String(),
+		strings.Join(r.Types, ","),
 	}
-
-	if r.Characteristic != "" {
-		parts = append(parts, r.Characteristic)
-	}
-
-	parts = append(parts, strings.Join(r.Types, ","))
-
 	return strings.Join(parts, "+")
 }
diff --git a/services/thumbnails/pkg/thumbnail/storage/storage.go b/services/thumbnails/pkg/thumbnail/storage/storage.go
index 591b05bdc12..691fdca5af3 100644
--- a/services/thumbnails/pkg/thumbnail/storage/storage.go
+++ b/services/thumbnails/pkg/thumbnail/storage/storage.go
@@ -15,12 +15,6 @@ type Request struct {
 	Types []string
 	// The resolution of the thumbnail
 	Resolution image.Rectangle
-	// Characteristic defines the different image characteristics,
-	// for example, if its scaled up to fit in the bounding box or not,
-	// is it a chroma version of the image, and so on...
-	// the main propose for this is to be able to differentiate between images which have
-	// the same resolution but different characteristics.
-	Characteristic string
 }
 
 // Storage defines the interface for a thumbnail store.
diff --git a/services/thumbnails/pkg/thumbnail/thumbnail.go b/services/thumbnails/pkg/thumbnail/thumbnail.go
index b3de987709d..70fcdc5b20e 100644
--- a/services/thumbnails/pkg/thumbnail/thumbnail.go
+++ b/services/thumbnails/pkg/thumbnail/thumbnail.go
@@ -30,7 +30,6 @@ type Request struct {
 	Encoder    Encoder
 	Generator  Generator
 	Checksum   string
-	Processor  Processor
 }
 
 // Manager is responsible for generating thumbnails
@@ -70,7 +69,7 @@ func (s SimpleManager) Generate(r Request, img interface{}) (string, error) {
 		match = s.resolutions.ClosestMatch(r.Resolution, m.Bounds())
 	}
 
-	thumbnail, err := r.Generator.Generate(match, img, r.Processor)
+	thumbnail, err := r.Generator.GenerateThumbnail(match, img)
 	if err != nil {
 		return "", err
 	}
@@ -99,10 +98,9 @@ func (s SimpleManager) GetThumbnail(key string) ([]byte, error) {
 
 func mapToStorageRequest(r Request) storage.Request {
 	return storage.Request{
-		Checksum:       r.Checksum,
-		Resolution:     r.Resolution,
-		Types:          r.Encoder.Types(),
-		Characteristic: r.Processor.ID(),
+		Checksum:   r.Checksum,
+		Resolution: r.Resolution,
+		Types:      r.Encoder.Types(),
 	}
 }
 
@@ -117,7 +115,7 @@ func IsMimeTypeSupported(m string) bool {
 }
 
 // PrepareRequest prepare the request based on image parameters
-func PrepareRequest(width, height int, tType, checksum, pID string) (Request, error) {
+func PrepareRequest(width, height int, tType, checksum string) (Request, error) {
 	generator, err := GeneratorForType(tType)
 	if err != nil {
 		return Request{}, err
@@ -126,16 +124,11 @@ func PrepareRequest(width, height int, tType, checksum, pID string) (Request, er
 	if err != nil {
 		return Request{}, err
 	}
-	processor, err := ProcessorFor(pID, tType)
-	if err != nil {
-		return Request{}, err
-	}
 
 	return Request{
 		Resolution: image.Rect(0, 0, width, height),
 		Generator:  generator,
 		Encoder:    encoder,
 		Checksum:   checksum,
-		Processor:  processor,
 	}, nil
 }
diff --git a/services/userlog/README.md b/services/userlog/README.md
index be9964ceb3d..0261b2ceea5 100644
--- a/services/userlog/README.md
+++ b/services/userlog/README.md
@@ -76,7 +76,3 @@ Important: For the time being, the embedded ownCloud Web frontend only supports
 *   If a requested language code is not available, the service tries to fall back to the base language if available. For example, if the requested language-code `de_DE` is not available, the service tries to fall back to translations in the `de` folder.
 *   If the base language `de` is also not available, the service falls back to the system's default English (`en`),
 which is the source of the texts provided by the code.
-
-## Default Language
-
-The default language can be defined via the `OCIS_DEFAULT_LANGUAGE` environment variable. See the `settings` service for a detailed description.
diff --git a/services/userlog/pkg/config/config.go b/services/userlog/pkg/config/config.go
index a29e0eeac8c..a2b71d9823c 100644
--- a/services/userlog/pkg/config/config.go
+++ b/services/userlog/pkg/config/config.go
@@ -24,7 +24,6 @@ type Config struct {
 
 	RevaGateway     string      `yaml:"reva_gateway" env:"OCIS_REVA_GATEWAY" desc:"CS3 gateway used to look up user metadata"`
 	TranslationPath string      `yaml:"translation_path" env:"OCIS_TRANSLATION_PATH;USERLOG_TRANSLATION_PATH" desc:"(optional) Set this to a path with custom translations to overwrite the builtin translations. Note that file and folder naming rules apply, see the documentation for more details."`
-	DefaultLanguage string      `yaml:"default_language" env:"OCIS_DEFAULT_LANGUAGE" desc:"The default language used by services and the WebUI. If not defined, English will be used as default. See the documentation for more details."`
 	Events          Events      `yaml:"events"`
 	Persistence     Persistence `yaml:"persistence"`
 
diff --git a/services/userlog/pkg/service/conversion.go b/services/userlog/pkg/service/conversion.go
index d84dd7bca56..c3cfc704375 100644
--- a/services/userlog/pkg/service/conversion.go
+++ b/services/userlog/pkg/service/conversion.go
@@ -55,7 +55,6 @@ type Converter struct {
 	gwc                   gateway.GatewayAPIClient
 	serviceName           string
 	translationPath       string
-	defaultLanguage       string
 	serviceAccountContext context.Context
 
 	// cached within one request not to query other service too much
@@ -65,13 +64,12 @@ type Converter struct {
 }
 
 // NewConverter returns a new Converter
-func NewConverter(ctx context.Context, loc string, gwc gateway.GatewayAPIClient, name, translationPath, defaultLanguage string) *Converter {
+func NewConverter(ctx context.Context, loc string, gwc gateway.GatewayAPIClient, name string, translationPath string) *Converter {
 	return &Converter{
 		locale:                loc,
 		gwc:                   gwc,
 		serviceName:           name,
 		translationPath:       translationPath,
-		defaultLanguage:       defaultLanguage,
 		serviceAccountContext: ctx,
 		spaces:                make(map[string]*storageprovider.StorageSpace),
 		users:                 make(map[string]*user.User),
@@ -139,7 +137,7 @@ func (c *Converter) spaceDeletedMessage(eventid string, executant *user.UserId,
 		return OC10Notification{}, err
 	}
 
-	subj, subjraw, msg, msgraw, err := composeMessage(SpaceDeleted, c.locale, c.defaultLanguage, c.translationPath, map[string]interface{}{
+	subj, subjraw, msg, msgraw, err := composeMessage(SpaceDeleted, c.locale, c.translationPath, map[string]interface{}{
 		"username":  usr.GetDisplayName(),
 		"spacename": spacename,
 	})
@@ -175,7 +173,7 @@ func (c *Converter) spaceMessage(eventid string, nt NotificationTemplate, execut
 		return OC10Notification{}, err
 	}
 
-	subj, subjraw, msg, msgraw, err := composeMessage(nt, c.locale, c.defaultLanguage, c.translationPath, map[string]interface{}{
+	subj, subjraw, msg, msgraw, err := composeMessage(nt, c.locale, c.translationPath, map[string]interface{}{
 		"username":  usr.GetDisplayName(),
 		"spacename": space.GetName(),
 	})
@@ -209,7 +207,7 @@ func (c *Converter) shareMessage(eventid string, nt NotificationTemplate, execut
 		return OC10Notification{}, err
 	}
 
-	subj, subjraw, msg, msgraw, err := composeMessage(nt, c.locale, c.defaultLanguage, c.translationPath, map[string]interface{}{
+	subj, subjraw, msg, msgraw, err := composeMessage(nt, c.locale, c.translationPath, map[string]interface{}{
 		"username":     usr.GetDisplayName(),
 		"resourcename": info.GetName(),
 	})
@@ -233,7 +231,7 @@ func (c *Converter) shareMessage(eventid string, nt NotificationTemplate, execut
 }
 
 func (c *Converter) virusMessage(eventid string, nt NotificationTemplate, executant *user.User, rid *storageprovider.ResourceId, filename string, virus string, ts time.Time) (OC10Notification, error) {
-	subj, subjraw, msg, msgraw, err := composeMessage(nt, c.locale, c.defaultLanguage, c.translationPath, map[string]interface{}{
+	subj, subjraw, msg, msgraw, err := composeMessage(nt, c.locale, c.translationPath, map[string]interface{}{
 		"resourcename":     filename,
 		"virusdescription": virus,
 	})
@@ -267,7 +265,7 @@ func (c *Converter) virusMessage(eventid string, nt NotificationTemplate, execut
 }
 
 func (c *Converter) policiesMessage(eventid string, nt NotificationTemplate, executant *user.User, filename string, ts time.Time) (OC10Notification, error) {
-	subj, subjraw, msg, msgraw, err := composeMessage(nt, c.locale, c.defaultLanguage, c.translationPath, map[string]interface{}{
+	subj, subjraw, msg, msgraw, err := composeMessage(nt, c.locale, c.translationPath, map[string]interface{}{
 		"resourcename": filename,
 	})
 	if err != nil {
@@ -295,7 +293,7 @@ func (c *Converter) policiesMessage(eventid string, nt NotificationTemplate, exe
 }
 
 func (c *Converter) deprovisionMessage(nt NotificationTemplate, deproDate string) (OC10Notification, error) {
-	subj, subjraw, msg, msgraw, err := composeMessage(nt, c.locale, c.defaultLanguage, c.translationPath, map[string]interface{}{
+	subj, subjraw, msg, msgraw, err := composeMessage(nt, c.locale, c.translationPath, map[string]interface{}{
 		"date": deproDate,
 	})
 	if err != nil {
@@ -349,8 +347,8 @@ func (c *Converter) getUser(ctx context.Context, userID *user.UserId) (*user.Use
 	return usr, err
 }
 
-func composeMessage(nt NotificationTemplate, locale, defaultLocale, path string, vars map[string]interface{}) (string, string, string, string, error) {
-	subjectraw, messageraw := loadTemplates(nt, locale, defaultLocale, path)
+func composeMessage(nt NotificationTemplate, locale string, path string, vars map[string]interface{}) (string, string, string, string, error) {
+	subjectraw, messageraw := loadTemplates(nt, locale, path)
 
 	subject, err := executeTemplate(subjectraw, vars)
 	if err != nil {
@@ -361,7 +359,7 @@ func composeMessage(nt NotificationTemplate, locale, defaultLocale, path string,
 	return subject, subjectraw, message, messageraw, err
 }
 
-func newLocate(locale string, path string) *gotext.Locale {
+func loadTemplates(nt NotificationTemplate, locale string, path string) (string, string) {
 	// Create Locale with library path and language code and load default domain
 	var l *gotext.Locale
 	if path == "" {
@@ -371,14 +369,6 @@ func newLocate(locale string, path string) *gotext.Locale {
 		l = gotext.NewLocale(path, locale)
 	}
 	l.AddDomain(_domain) // make domain configurable only if needed
-	return l
-}
-
-func loadTemplates(nt NotificationTemplate, locale, defaultLocale, path string) (string, string) {
-	l := newLocate(locale, path)
-	if locale != "en" && len(l.GetTranslations()) == 0 {
-		l = newLocate(defaultLocale, path)
-	}
 	return l.Get(nt.Subject), l.Get(nt.Message)
 }
 
diff --git a/services/userlog/pkg/service/http.go b/services/userlog/pkg/service/http.go
index 05dca5050fc..b869d3e1545 100644
--- a/services/userlog/pkg/service/http.go
+++ b/services/userlog/pkg/service/http.go
@@ -59,7 +59,7 @@ func (ul *UserlogService) HandleGetEvents(w http.ResponseWriter, r *http.Request
 		return
 	}
 
-	conv := NewConverter(ctx, r.Header.Get(HeaderAcceptLanguage), gwc, ul.cfg.Service.Name, ul.cfg.TranslationPath, ul.cfg.DefaultLanguage)
+	conv := NewConverter(ctx, r.Header.Get(HeaderAcceptLanguage), gwc, ul.cfg.Service.Name, ul.cfg.TranslationPath)
 
 	var outdatedEvents []string
 	resp := GetEventResponseOC10{}
diff --git a/services/userlog/pkg/service/service.go b/services/userlog/pkg/service/service.go
index 684b9c8f3d4..6e5897e9da2 100644
--- a/services/userlog/pkg/service/service.go
+++ b/services/userlog/pkg/service/service.go
@@ -337,7 +337,7 @@ func (ul *UserlogService) addEventToUser(ctx context.Context, userid string, eve
 }
 
 func (ul *UserlogService) sendSSE(ctx context.Context, userid string, event events.Event, gwc gateway.GatewayAPIClient) error {
-	ev, err := NewConverter(ctx, ul.getUserLocale(userid), gwc, ul.cfg.Service.Name, ul.cfg.TranslationPath, ul.cfg.DefaultLanguage).ConvertEvent(event.ID, event.Event)
+	ev, err := NewConverter(ctx, ul.getUserLocale(userid), gwc, ul.cfg.Service.Name, ul.cfg.TranslationPath).ConvertEvent(event.ID, event.Event)
 	if err != nil {
 		return err
 	}
diff --git a/services/webdav/pkg/dav/requests/thumbnail.go b/services/webdav/pkg/dav/requests/thumbnail.go
index 2a5aa7da57f..0c703d37253 100644
--- a/services/webdav/pkg/dav/requests/thumbnail.go
+++ b/services/webdav/pkg/dav/requests/thumbnail.go
@@ -36,8 +36,6 @@ type ThumbnailRequest struct {
 	Height int32
 	// In case of a public share the public link token.
 	PublicLinkToken string
-	// Indicates which image processor to use
-	Processor string
 	// The Identifier from the requested URL
 	Identifier string
 }
@@ -75,7 +73,6 @@ func ParseThumbnailRequest(r *http.Request) (*ThumbnailRequest, error) {
 		Extension:       filepath.Ext(fp),
 		Width:           int32(width),
 		Height:          int32(height),
-		Processor:       q.Get("processor"),
 		PublicLinkToken: chi.URLParam(r, "token"),
 		Identifier:      id,
 	}, nil
diff --git a/services/webdav/pkg/service/v0/service.go b/services/webdav/pkg/service/v0/service.go
index cbe3a74f5ab..4c1535f3fec 100644
--- a/services/webdav/pkg/service/v0/service.go
+++ b/services/webdav/pkg/service/v0/service.go
@@ -243,7 +243,6 @@ func (g Webdav) SpacesThumbnail(w http.ResponseWriter, r *http.Request) {
 		ThumbnailType: extensionToThumbnailType(strings.TrimLeft(tr.Extension, ".")),
 		Width:         tr.Width,
 		Height:        tr.Height,
-		Processor:     tr.Processor,
 		Source: &thumbnailssvc.GetThumbnailRequest_Cs3Source{
 			Cs3Source: &thumbnailsmsg.CS3Source{
 				Path:          fullPath,
@@ -260,7 +259,7 @@ func (g Webdav) SpacesThumbnail(w http.ResponseWriter, r *http.Request) {
 			return
 		case http.StatusTooEarly:
 			// StatusTooEarly if file is processing
-			renderError(w, r, errTooEarly(e.Detail))
+			renderError(w, r, errTooEarly(err.Error()))
 			return
 		case http.StatusBadRequest:
 			renderError(w, r, errBadRequest(e.Detail))
@@ -336,7 +335,6 @@ func (g Webdav) Thumbnail(w http.ResponseWriter, r *http.Request) {
 		ThumbnailType: extensionToThumbnailType(strings.TrimLeft(tr.Extension, ".")),
 		Width:         tr.Width,
 		Height:        tr.Height,
-		Processor:     tr.Processor,
 		Source: &thumbnailssvc.GetThumbnailRequest_Cs3Source{
 			Cs3Source: &thumbnailsmsg.CS3Source{
 				Path:          fullPath,
@@ -351,10 +349,6 @@ func (g Webdav) Thumbnail(w http.ResponseWriter, r *http.Request) {
 			// StatusNotFound is expected for unsupported files
 			renderError(w, r, errNotFound(notFoundMsg(tr.Filename)))
 			return
-		case http.StatusTooEarly:
-			// StatusTooEarly if file is processing
-			renderError(w, r, errTooEarly(e.Detail))
-			return
 		case http.StatusBadRequest:
 			renderError(w, r, errBadRequest(e.Detail))
 		default:
@@ -381,7 +375,6 @@ func (g Webdav) PublicThumbnail(w http.ResponseWriter, r *http.Request) {
 		ThumbnailType: extensionToThumbnailType(strings.TrimLeft(tr.Extension, ".")),
 		Width:         tr.Width,
 		Height:        tr.Height,
-		Processor:     tr.Processor,
 		Source: &thumbnailssvc.GetThumbnailRequest_WebdavSource{
 			WebdavSource: &thumbnailsmsg.WebdavSource{
 				Url:             g.config.OcisPublicURL + r.URL.RequestURI(),
@@ -423,7 +416,6 @@ func (g Webdav) PublicThumbnailHead(w http.ResponseWriter, r *http.Request) {
 		ThumbnailType: extensionToThumbnailType(strings.TrimLeft(tr.Extension, ".")),
 		Width:         tr.Width,
 		Height:        tr.Height,
-		Processor:     tr.Processor,
 		Source: &thumbnailssvc.GetThumbnailRequest_WebdavSource{
 			WebdavSource: &thumbnailsmsg.WebdavSource{
 				Url:             g.config.OcisPublicURL + r.URL.RequestURI(),
diff --git a/vendor/golang.org/x/image/tiff/fuzz.go b/vendor/golang.org/x/image/tiff/fuzz.go
index b388b6f421c..b27c5400483 100644
--- a/vendor/golang.org/x/image/tiff/fuzz.go
+++ b/vendor/golang.org/x/image/tiff/fuzz.go
@@ -3,6 +3,7 @@
 // license that can be found in the LICENSE file.
 
 //go:build gofuzz
+// +build gofuzz
 
 package tiff
 
diff --git a/vendor/golang.org/x/image/vector/acc_amd64.go b/vendor/golang.org/x/image/vector/acc_amd64.go
index 5b148c58598..a6fa0ca2635 100644
--- a/vendor/golang.org/x/image/vector/acc_amd64.go
+++ b/vendor/golang.org/x/image/vector/acc_amd64.go
@@ -3,6 +3,7 @@
 // license that can be found in the LICENSE file.
 
 //go:build !appengine && gc && !noasm
+// +build !appengine,gc,!noasm
 
 package vector
 
diff --git a/vendor/golang.org/x/image/vector/acc_other.go b/vendor/golang.org/x/image/vector/acc_other.go
index e383d52c73b..39022691b9b 100644
--- a/vendor/golang.org/x/image/vector/acc_other.go
+++ b/vendor/golang.org/x/image/vector/acc_other.go
@@ -3,6 +3,7 @@
 // license that can be found in the LICENSE file.
 
 //go:build !amd64 || appengine || !gc || noasm
+// +build !amd64 appengine !gc noasm
 
 package vector
 
diff --git a/vendor/google.golang.org/grpc/internal/transport/http2_server.go b/vendor/google.golang.org/grpc/internal/transport/http2_server.go
index c06db679d89..8d3a353c1d5 100644
--- a/vendor/google.golang.org/grpc/internal/transport/http2_server.go
+++ b/vendor/google.golang.org/grpc/internal/transport/http2_server.go
@@ -171,10 +171,15 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport,
 		ID:  http2.SettingMaxFrameSize,
 		Val: http2MaxFrameLen,
 	}}
-	if config.MaxStreams != math.MaxUint32 {
+	// TODO(zhaoq): Have a better way to signal "no limit" because 0 is
+	// permitted in the HTTP2 spec.
+	maxStreams := config.MaxStreams
+	if maxStreams == 0 {
+		maxStreams = math.MaxUint32
+	} else {
 		isettings = append(isettings, http2.Setting{
 			ID:  http2.SettingMaxConcurrentStreams,
-			Val: config.MaxStreams,
+			Val: maxStreams,
 		})
 	}
 	dynamicWindow := true
@@ -253,7 +258,7 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport,
 		framer:            framer,
 		readerDone:        make(chan struct{}),
 		writerDone:        make(chan struct{}),
-		maxStreams:        config.MaxStreams,
+		maxStreams:        maxStreams,
 		inTapHandle:       config.InTapHandle,
 		fc:                &trInFlow{limit: uint32(icwz)},
 		state:             reachable,
diff --git a/vendor/google.golang.org/grpc/server.go b/vendor/google.golang.org/grpc/server.go
index eeae92fbe02..244123c6c5a 100644
--- a/vendor/google.golang.org/grpc/server.go
+++ b/vendor/google.golang.org/grpc/server.go
@@ -115,6 +115,12 @@ type serviceInfo struct {
 	mdata       any
 }
 
+type serverWorkerData struct {
+	st     transport.ServerTransport
+	wg     *sync.WaitGroup
+	stream *transport.Stream
+}
+
 // Server is a gRPC server to serve RPC requests.
 type Server struct {
 	opts serverOptions
@@ -139,7 +145,7 @@ type Server struct {
 	channelzID *channelz.Identifier
 	czData     *channelzData
 
-	serverWorkerChannel chan func()
+	serverWorkerChannel chan *serverWorkerData
 }
 
 type serverOptions struct {
@@ -173,7 +179,6 @@ type serverOptions struct {
 }
 
 var defaultServerOptions = serverOptions{
-	maxConcurrentStreams:  math.MaxUint32,
 	maxReceiveMessageSize: defaultServerMaxReceiveMessageSize,
 	maxSendMessageSize:    defaultServerMaxSendMessageSize,
 	connectionTimeout:     120 * time.Second,
@@ -399,9 +404,6 @@ func MaxSendMsgSize(m int) ServerOption {
 // MaxConcurrentStreams returns a ServerOption that will apply a limit on the number
 // of concurrent streams to each ServerTransport.
 func MaxConcurrentStreams(n uint32) ServerOption {
-	if n == 0 {
-		n = math.MaxUint32
-	}
 	return newFuncServerOption(func(o *serverOptions) {
 		o.maxConcurrentStreams = n
 	})
@@ -603,19 +605,24 @@ const serverWorkerResetThreshold = 1 << 16
 // [1] https://github.com/golang/go/issues/18138
 func (s *Server) serverWorker() {
 	for completed := 0; completed < serverWorkerResetThreshold; completed++ {
-		f, ok := <-s.serverWorkerChannel
+		data, ok := <-s.serverWorkerChannel
 		if !ok {
 			return
 		}
-		f()
+		s.handleSingleStream(data)
 	}
 	go s.serverWorker()
 }
 
+func (s *Server) handleSingleStream(data *serverWorkerData) {
+	defer data.wg.Done()
+	s.handleStream(data.st, data.stream, s.traceInfo(data.st, data.stream))
+}
+
 // initServerWorkers creates worker goroutines and a channel to process incoming
 // connections to reduce the time spent overall on runtime.morestack.
 func (s *Server) initServerWorkers() {
-	s.serverWorkerChannel = make(chan func())
+	s.serverWorkerChannel = make(chan *serverWorkerData)
 	for i := uint32(0); i < s.opts.numServerWorkers; i++ {
 		go s.serverWorker()
 	}
@@ -975,26 +982,21 @@ func (s *Server) serveStreams(st transport.ServerTransport) {
 	defer st.Close(errors.New("finished serving streams for the server transport"))
 	var wg sync.WaitGroup
 
-	streamQuota := newHandlerQuota(s.opts.maxConcurrentStreams)
 	st.HandleStreams(func(stream *transport.Stream) {
 		wg.Add(1)
-
-		streamQuota.acquire()
-		f := func() {
-			defer streamQuota.release()
-			defer wg.Done()
-			s.handleStream(st, stream, s.traceInfo(st, stream))
-		}
-
 		if s.opts.numServerWorkers > 0 {
+			data := &serverWorkerData{st: st, wg: &wg, stream: stream}
 			select {
-			case s.serverWorkerChannel <- f:
+			case s.serverWorkerChannel <- data:
 				return
 			default:
 				// If all stream workers are busy, fallback to the default code path.
 			}
 		}
-		go f()
+		go func() {
+			defer wg.Done()
+			s.handleStream(st, stream, s.traceInfo(st, stream))
+		}()
 	}, func(ctx context.Context, method string) context.Context {
 		if !EnableTracing {
 			return ctx
@@ -2089,34 +2091,3 @@ func validateSendCompressor(name, clientCompressors string) error {
 	}
 	return fmt.Errorf("client does not support compressor %q", name)
 }
-
-// atomicSemaphore implements a blocking, counting semaphore. acquire should be
-// called synchronously; release may be called asynchronously.
-type atomicSemaphore struct {
-	n    atomic.Int64
-	wait chan struct{}
-}
-
-func (q *atomicSemaphore) acquire() {
-	if q.n.Add(-1) < 0 {
-		// We ran out of quota.  Block until a release happens.
-		<-q.wait
-	}
-}
-
-func (q *atomicSemaphore) release() {
-	// N.B. the "<= 0" check below should allow for this to work with multiple
-	// concurrent calls to acquire, but also note that with synchronous calls to
-	// acquire, as our system does, n will never be less than -1.  There are
-	// fairness issues (queuing) to consider if this was to be generalized.
-	if q.n.Add(1) <= 0 {
-		// An acquire was waiting on us.  Unblock it.
-		q.wait <- struct{}{}
-	}
-}
-
-func newHandlerQuota(n uint32) *atomicSemaphore {
-	a := &atomicSemaphore{wait: make(chan struct{}, 1)}
-	a.n.Store(int64(n))
-	return a
-}
diff --git a/vendor/google.golang.org/grpc/version.go b/vendor/google.golang.org/grpc/version.go
index 724ad210213..d3f5bcbfcef 100644
--- a/vendor/google.golang.org/grpc/version.go
+++ b/vendor/google.golang.org/grpc/version.go
@@ -19,4 +19,4 @@
 package grpc
 
 // Version is the current grpc version.
-const Version = "1.58.3"
+const Version = "1.58.2"
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 99368dcc0ef..bda735cde73 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -1976,8 +1976,8 @@ golang.org/x/crypto/ssh/knownhosts
 golang.org/x/exp/constraints
 golang.org/x/exp/maps
 golang.org/x/exp/slices
-# golang.org/x/image v0.13.0
-## explicit; go 1.18
+# golang.org/x/image v0.12.0
+## explicit; go 1.12
 golang.org/x/image/bmp
 golang.org/x/image/ccitt
 golang.org/x/image/font
@@ -2118,7 +2118,7 @@ google.golang.org/genproto/googleapis/api/httpbody
 ## explicit; go 1.19
 google.golang.org/genproto/googleapis/rpc/errdetails
 google.golang.org/genproto/googleapis/rpc/status
-# google.golang.org/grpc v1.58.3
+# google.golang.org/grpc v1.58.2
 ## explicit; go 1.19
 google.golang.org/grpc
 google.golang.org/grpc/attributes


Test patch:
diff --git a/services/notifications/pkg/service/service_test.go b/services/notifications/pkg/service/service_test.go
index afd7e51c4c0..056866391f8 100644
--- a/services/notifications/pkg/service/service_test.go
+++ b/services/notifications/pkg/service/service_test.go
@@ -77,7 +77,7 @@ var _ = Describe("Notifications", func() {
 			cfg := defaults.FullDefaultConfig()
 			cfg.GRPCClientTLS = &shared.GRPCClientTLS{}
 			ch := make(chan events.Event)
-			evts := service.NewEventsNotifier(ch, tc, log.NewLogger(), gatewaySelector, vs, "", "", "", "", "")
+			evts := service.NewEventsNotifier(ch, tc, log.NewLogger(), gatewaySelector, vs, "", "", "", "")
 			go evts.Run()
 
 			ch <- ev
@@ -275,7 +275,7 @@ var _ = Describe("Notifications X-Site Scripting", func() {
 			cfg := defaults.FullDefaultConfig()
 			cfg.GRPCClientTLS = &shared.GRPCClientTLS{}
 			ch := make(chan events.Event)
-			evts := service.NewEventsNotifier(ch, tc, log.NewLogger(), gatewaySelector, vs, "", "", "", "", "")
+			evts := service.NewEventsNotifier(ch, tc, log.NewLogger(), gatewaySelector, vs, "", "", "", "")
 			go evts.Run()
 
 			ch <- ev
diff --git a/services/thumbnails/pkg/thumbnail/processor_test.go b/services/thumbnails/pkg/thumbnail/processor_test.go
deleted file mode 100644
index febda33b817..00000000000
--- a/services/thumbnails/pkg/thumbnail/processor_test.go
+++ /dev/null
@@ -1,98 +0,0 @@
-package thumbnail_test
-
-import (
-	"testing"
-
-	"github.com/disintegration/imaging"
-	tAssert "github.com/stretchr/testify/assert"
-
-	"github.com/owncloud/ocis/v2/services/thumbnails/pkg/thumbnail"
-)
-
-func TestProcessorFor(t *testing.T) {
-	tests := []struct {
-		id       string
-		fileType string
-		wantP    thumbnail.Processor
-		wantE    error
-	}{
-		{
-			id:       "fit",
-			fileType: "",
-			wantP:    thumbnail.DefinableProcessor{Slug: "fit", Converter: imaging.Fit},
-			wantE:    nil,
-		},
-		{
-			id:       "fit",
-			fileType: "jpg",
-			wantP:    thumbnail.DefinableProcessor{Slug: "fit"},
-			wantE:    nil,
-		},
-		{
-			id:       "FIT",
-			fileType: "jpg",
-			wantP:    thumbnail.DefinableProcessor{Slug: "fit"},
-			wantE:    nil,
-		},
-		{
-			id:       "resize",
-			fileType: "jpg",
-			wantP:    thumbnail.DefinableProcessor{Slug: "resize"},
-			wantE:    nil,
-		},
-		{
-			id:       "RESIZE",
-			fileType: "jpg",
-			wantP:    thumbnail.DefinableProcessor{Slug: "resize"},
-			wantE:    nil,
-		},
-		{
-			id:       "fill",
-			fileType: "jpg",
-			wantP:    thumbnail.DefinableProcessor{Slug: "fill"},
-			wantE:    nil,
-		},
-		{
-			id:       "FILL",
-			fileType: "jpg",
-			wantP:    thumbnail.DefinableProcessor{Slug: "fill"},
-			wantE:    nil,
-		},
-		{
-			id:       "thumbnail",
-			fileType: "jpg",
-			wantP:    thumbnail.DefinableProcessor{Slug: "thumbnail"},
-			wantE:    nil,
-		},
-		{
-			id:       "THUMBNAIL",
-			fileType: "jpg",
-			wantP:    thumbnail.DefinableProcessor{Slug: "thumbnail"},
-			wantE:    nil,
-		},
-		{
-			id:       "",
-			fileType: "jpg",
-			wantP:    thumbnail.DefinableProcessor{},
-			wantE:    nil,
-		},
-		{
-			id:       "",
-			fileType: "gif",
-			wantP:    thumbnail.DefinableProcessor{},
-			wantE:    nil,
-		},
-	}
-
-	assert := tAssert.New(t)
-
-	for _, tt := range tests {
-		tt := tt
-		t.Run("", func(t *testing.T) {
-			p, e := thumbnail.ProcessorFor(tt.id, tt.fileType)
-			assert.Equal(p.ID(), tt.wantP.ID())
-			assert.Equal(e, tt.wantE)
-		})
-	}
-
-}
diff --git a/services/thumbnails/pkg/thumbnail/storage/filesystem_test.go b/services/thumbnails/pkg/thumbnail/storage/filesystem_test.go
deleted file mode 100644
index a139a9199b1..00000000000
--- a/services/thumbnails/pkg/thumbnail/storage/filesystem_test.go
+++ /dev/null
@@ -1,65 +0,0 @@
-package storage_test
-
-import (
-	"image"
-	"testing"
-
-	tAssert "github.com/stretchr/testify/assert"
-
-	"github.com/owncloud/ocis/v2/services/thumbnails/pkg/thumbnail/storage"
-)
-
-func TestFileSystem_BuildKey(t *testing.T) {
-	tests := []struct {
-		r    storage.Request
-		want string
-	}{
-		{
-			r: storage.Request{
-				Checksum: "120EA8A25E5D487BF68B5F7096440019",
-				Types:    []string{"png", "jpg"},
-				Resolution: image.Rectangle{
-					Min: image.Point{
-						X: 1,
-						Y: 2,
-					},
-					Max: image.Point{
-						X: 3,
-						Y: 4,
-					},
-				},
-				Characteristic: "",
-			},
-			want: "12/0E/A8A25E5D487BF68B5F7096440019/2x2.png",
-		},
-		{
-			r: storage.Request{
-				Checksum: "120EA8A25E5D487BF68B5F7096440019",
-				Types:    []string{"png", "jpg"},
-				Resolution: image.Rectangle{
-					Min: image.Point{
-						X: 1,
-						Y: 2,
-					},
-					Max: image.Point{
-						X: 3,
-						Y: 4,
-					},
-				},
-				Characteristic: "fill",
-			},
-			want: "12/0E/A8A25E5D487BF68B5F7096440019/2x2-fill.png",
-		},
-	}
-
-	s := storage.FileSystem{}
-	assert := tAssert.New(t)
-
-	for _, tt := range tests {
-		tt := tt
-		t.Run("", func(t *testing.T) {
-			assert.Equal(s.BuildKey(tt.r), tt.want)
-		})
-	}
-
-}
diff --git a/services/thumbnails/pkg/thumbnail/storage/inmemory_test.go b/services/thumbnails/pkg/thumbnail/storage/inmemory_test.go
deleted file mode 100644
index 9f33a6ae494..00000000000
--- a/services/thumbnails/pkg/thumbnail/storage/inmemory_test.go
+++ /dev/null
@@ -1,65 +0,0 @@
-package storage_test
-
-import (
-	"image"
-	"testing"
-
-	tAssert "github.com/stretchr/testify/assert"
-
-	"github.com/owncloud/ocis/v2/services/thumbnails/pkg/thumbnail/storage"
-)
-
-func TestInMemory_BuildKey(t *testing.T) {
-	tests := []struct {
-		r    storage.Request
-		want string
-	}{
-		{
-			r: storage.Request{
-				Checksum: "cs",
-				Types:    []string{"png", "jpg"},
-				Resolution: image.Rectangle{
-					Min: image.Point{
-						X: 1,
-						Y: 2,
-					},
-					Max: image.Point{
-						X: 3,
-						Y: 4,
-					},
-				},
-				Characteristic: "",
-			},
-			want: "cs+(1,2)-(3,4)+png,jpg",
-		},
-		{
-			r: storage.Request{
-				Checksum: "cs",
-				Types:    []string{"png", "jpg"},
-				Resolution: image.Rectangle{
-					Min: image.Point{
-						X: 1,
-						Y: 2,
-					},
-					Max: image.Point{
-						X: 3,
-						Y: 4,
-					},
-				},
-				Characteristic: "fill",
-			},
-			want: "cs+(1,2)-(3,4)+fill+png,jpg",
-		},
-	}
-
-	s := storage.InMemory{}
-	assert := tAssert.New(t)
-
-	for _, tt := range tests {
-		tt := tt
-		t.Run("", func(t *testing.T) {
-			assert.Equal(s.BuildKey(tt.r), tt.want)
-		})
-	}
-
-}
diff --git a/services/thumbnails/pkg/thumbnail/thumbnail_test.go b/services/thumbnails/pkg/thumbnail/thumbnail_test.go
index fc4c9796429..45303dcc871 100644
--- a/services/thumbnails/pkg/thumbnail/thumbnail_test.go
+++ b/services/thumbnails/pkg/thumbnail/thumbnail_test.go
@@ -4,11 +4,9 @@ import (
 	"image"
 	"os"
 	"path/filepath"
+	"reflect"
 	"testing"
 
-	"github.com/google/go-cmp/cmp"
-	"github.com/google/go-cmp/cmp/cmpopts"
-
 	"github.com/owncloud/ocis/v2/ocis-pkg/log"
 	"github.com/owncloud/ocis/v2/services/thumbnails/pkg/thumbnail/storage"
 )
@@ -120,15 +118,13 @@ func TestPrepareRequest(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			got, err := PrepareRequest(tt.args.width, tt.args.height, tt.args.tType, tt.args.checksum, "")
+			got, err := PrepareRequest(tt.args.width, tt.args.height, tt.args.tType, tt.args.checksum)
 			if (err != nil) != tt.wantErr {
 				t.Errorf("PrepareRequest() error = %v, wantErr %v", err, tt.wantErr)
 				return
 			}
-
-			// func's are not reflactable, ignore
-			if diff := cmp.Diff(tt.want, got, cmpopts.IgnoreFields(Request{}, "Processor")); diff != "" {
-				t.Errorf("PrepareRequest(): %v", diff)
+			if !reflect.DeepEqual(got, tt.want) {
+				t.Errorf("PrepareRequest() got = %v, want %v", got, tt.want)
 			}
 		})
 	}
diff --git a/tests/acceptance/expected-failures-API-on-OCIS-storage.md b/tests/acceptance/expected-failures-API-on-OCIS-storage.md
index b192aaba33b..a879e5f3563 100644
--- a/tests/acceptance/expected-failures-API-on-OCIS-storage.md
+++ b/tests/acceptance/expected-failures-API-on-OCIS-storage.md
@@ -284,10 +284,10 @@ cannot share a folder with create permission
 
 #### [Sharing folder and sub-folder with same user but different permission,the permission of sub-folder is not obeyed ](https://github.com/owncloud/ocis/issues/2440)
 
-- [coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature:220](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature#L220)
-- [coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature:350](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature#L350)
-- [coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature:251](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature#L251)
-- [coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature:381](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature#L381)
+- [coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature:221](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature#L221)
+- [coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature:351](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature#L351)
+- [coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature:252](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature#L252)
+- [coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature:382](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature#L382)
 
 #### [Empty OCS response for a share create request using a disabled user](https://github.com/owncloud/ocis/issues/2212)
 
diff --git a/tests/acceptance/features/apiGraph/addUserToGroup.feature b/tests/acceptance/features/apiGraph/addUserToGroup.feature
index f43df4b74f7..ec69869ce77 100644
--- a/tests/acceptance/features/apiGraph/addUserToGroup.feature
+++ b/tests/acceptance/features/apiGraph/addUserToGroup.feature
@@ -205,8 +205,8 @@ Feature: add users to group
 
   Scenario: admin tries to add a nonexistent user to a group
     Given group "groupA" has been created
-    When the administrator tries to add nonexistent user to group "groupA" using the Graph API
-    Then the HTTP status code should be "404"
+    When the administrator tries to add user "nonexistentuser" to group "groupA" using the provisioning API
+    Then the HTTP status code should be "405"
 
 
   Scenario: admin tries to add user to a group without sending the group
diff --git a/tests/acceptance/features/apiNotification/emailNotification.feature b/tests/acceptance/features/apiNotification/emailNotification.feature
index f921c4e9f9a..09b610a86a5 100644
--- a/tests/acceptance/features/apiNotification/emailNotification.feature
+++ b/tests/acceptance/features/apiNotification/emailNotification.feature
@@ -140,7 +140,7 @@ Feature: Email notification
     And user "Brian" has switched the system language to "es"
     And user "Carol" has switched the system language to "de"
     And user "Alice" has created a space "new-space" with the default quota using the GraphApi
-    When user "Alice" shares a space "new-space" with settings:
+    When user "Alice" has shared a space "new-space" with settings:
       | shareWith | group1 |
       | role      | viewer |
     Then the HTTP status code should be "200"
@@ -183,7 +183,7 @@ Feature: Email notification
 
   @env-config
   Scenario: group members get an email notification in default language when someone shares a file with the group
-    Given the config "OCIS_DEFAULT_LANGUAGE" has been set to "de"
+    Given the config "SETTINGS_DEFAULT_LANGUAGE" has been set to "de"
     And user "Carol" has been created with default attributes and without skeleton files
     And group "group1" has been created
     And user "Brian" has been added to group "group1"
diff --git a/tests/acceptance/features/apiNotification/notification.feature b/tests/acceptance/features/apiNotification/notification.feature
index 0289b548237..841b7782c68 100644
--- a/tests/acceptance/features/apiNotification/notification.feature
+++ b/tests/acceptance/features/apiNotification/notification.feature
@@ -270,7 +270,7 @@ Feature: Notification
 
   @env-config
   Scenario: get a notification about a file share in default languages
-    Given the config "OCIS_DEFAULT_LANGUAGE" has been set to "de"
+    Given the config "SETTINGS_DEFAULT_LANGUAGE" has been set to "de"
     And user "Alice" has shared entry "textfile1.txt" with user "Brian" with permissions "17"
     When user "Brian" lists all notifications
     Then the HTTP status code should be "200"
diff --git a/tests/acceptance/features/apiSpaces/changeSpaces.feature b/tests/acceptance/features/apiSpaces/changeSpaces.feature
index 5992d457eff..ca087a08ede 100644
--- a/tests/acceptance/features/apiSpaces/changeSpaces.feature
+++ b/tests/acceptance/features/apiSpaces/changeSpaces.feature
@@ -339,7 +339,6 @@ Feature: Change data of space
     When user "<user>" uploads a file inside space "Project Jupiter" owned by the user "Alice" with content "new content" to ".space/readme.md" using the WebDAV API
     Then the HTTP status code should be "<code>"
     And for user "<user>" the content of the file ".space/readme.md" of the space "Project Jupiter" should be "<expectedContent>"
-    When user "<user>" lists all available spaces via the GraphApi
     And the JSON response should contain space called "Project Jupiter" owned by "Alice" with description file ".space/readme.md" and match
     """
     {
@@ -423,7 +422,7 @@ Feature: Change data of space
     Given user "Alice" has created a folder ".space" in space "Project Jupiter"
     And user "Alice" has uploaded a file inside space "Project Jupiter" with content "" to ".space/spaceImage.jpeg"
     And user "Alice" has set the file ".space/spaceImage.jpeg" as a space image in a special section of the "Project Jupiter" space
-    When user "<user>" uploads a file inside space "Project Jupiter" with content "" to ".space/newSpaceImage.png" using the WebDAV API
+    When user "<user>" has uploaded a file inside space "Project Jupiter" with content "" to ".space/newSpaceImage.png"
     And user "<user>" sets the file ".space/newSpaceImage.png" as a space image in a special section of the "Project Jupiter" space
     Then the HTTP status code should be "200"
     And the JSON response should contain space called "Project Jupiter" owned by "Alice" with description file ".space/newSpaceImage.png" and match
diff --git a/tests/acceptance/features/bootstrap/GraphContext.php b/tests/acceptance/features/bootstrap/GraphContext.php
index 83eb0d73f95..9cda27ea320 100644
--- a/tests/acceptance/features/bootstrap/GraphContext.php
+++ b/tests/acceptance/features/bootstrap/GraphContext.php
@@ -762,7 +762,6 @@ class GraphContext implements Context {
 
 	/**
 	 * adds a user to a group
-	 * NOTE: If you want to make a request with non-existing user or group,provide "nonexistent" as their name
 	 *
 	 * @param string $group
 	 * @param string $user
@@ -773,16 +772,8 @@ class GraphContext implements Context {
 	 */
 	public function addUserToGroup(string $group, string $user, ?string $byUser = null): ResponseInterface {
 		$credentials = $this->getAdminOrUserCredentials($byUser);
-		if ($group === "nonexistent") {
-			$groupId = WebDavHelper::generateUUIDv4();
-		} else {
-			$groupId = $this->featureContext->getAttributeOfCreatedGroup($group, "id");
-		}
-		if ($user === "nonexistent") {
-			$userId = WebDavHelper::generateUUIDv4();
-		} else {
-			$userId = $this->featureContext->getAttributeOfCreatedUser($user, "id");
-		}
+		$groupId = $this->featureContext->getAttributeOfCreatedGroup($group, "id");
+		$userId = $this->featureContext->getAttributeOfCreatedUser($user, "id");
 		return GraphHelper::addUserToGroup(
 			$this->featureContext->getBaseUrl(),
 			$this->featureContext->getStepLineRef(),
@@ -809,8 +800,10 @@ class GraphContext implements Context {
 		string $group,
 		bool $checkResult = true
 	): void {
-		$response = $this->addUserToGroup($group, $user);
-		$this->featureContext->theHTTPStatusCodeShouldBe(204, '', $response);
+		$result = $this->addUserToGroup($group, $user);
+		if ($checkResult && ($result->getStatusCode() !== 204)) {
+			$this->throwHttpException($result, "Could not add user '$user' to group '$group'.");
+		}
 	}
 
 	/**
@@ -831,14 +824,15 @@ class GraphContext implements Context {
 	}
 
 	/**
-	 * @When the administrator tries to add nonexistent user to group :group using the Graph API
+	 * @When the administrator tries to add user :user to group :group using the Graph API
 	 *
+	 * @param string $user
 	 * @param string $group
 	 *
 	 * @return void
 	 */
-	public function theAdministratorTriesToAddNonExistentUserToGroupUsingTheGraphAPI(string $group): void {
-		$this->featureContext->setResponse($this->addUserToGroup($group, "nonexistent"));
+	public function theAdministratorTriesToAddUserToGroupUsingTheGraphAPI(string $user, string $group): void {
+		$this->featureContext->setResponse($this->addUserToGroup($group, $user));
 	}
 
 	/**
@@ -853,7 +847,19 @@ class GraphContext implements Context {
 	 * @throws GuzzleException | Exception
 	 */
 	public function theAdministratorTriesToAddUserToNonExistentGroupUsingTheGraphAPI(string $user, ?string $byUser = null): void {
-		$this->featureContext->setResponse($this->addUserToGroup("nonexistent", $user, $byUser));
+		$credentials = $this->getAdminOrUserCredentials($byUser);
+		$groupId = WebDavHelper::generateUUIDv4();
+		$userId = $this->featureContext->getAttributeOfCreatedUser($user, "id");
+		$this->featureContext->setResponse(
+			GraphHelper::addUserToGroup(
+				$this->featureContext->getBaseUrl(),
+				$this->featureContext->getStepLineRef(),
+				$credentials['username'],
+				$credentials['password'],
+				$userId,
+				$groupId
+			)
+		);
 	}
 
 	/**
@@ -1417,21 +1423,25 @@ class GraphContext implements Context {
 	 * @param string $user
 	 * @param array $userIds
 	 * @param string $groupId
+	 * @param TableNode $table
 	 *
 	 * @return void
 	 * @throws GuzzleException
 	 * @throws Exception
 	 */
-	public function addMultipleUsersToGroup(string $user, array $userIds, string $groupId): ResponseInterface {
+	public function addMultipleUsersToGroup(string $user, array $userIds, string $groupId, TableNode $table): void {
 		$credentials = $this->getAdminOrUserCredentials($user);
+		$this->featureContext->verifyTableNodeColumns($table, ['username']);
 
-		return GraphHelper::addUsersToGroup(
-			$this->featureContext->getBaseUrl(),
-			$this->featureContext->getStepLineRef(),
-			$credentials["username"],
-			$credentials["password"],
-			$groupId,
-			$userIds
+		$this->featureContext->setResponse(
+			GraphHelper::addUsersToGroup(
+				$this->featureContext->getBaseUrl(),
+				$this->featureContext->getStepLineRef(),
+				$credentials["username"],
+				$credentials["password"],
+				$groupId,
+				$userIds
+			)
 		);
 	}
 
@@ -1452,9 +1462,7 @@ class GraphContext implements Context {
 		foreach ($table->getHash() as $row) {
 			$userIds[] = $this->featureContext->getAttributeOfCreatedUser($row['username'], "id");
 		}
-		$this->featureContext->verifyTableNodeColumns($table, ['username']);
-		$response = $this->addMultipleUsersToGroup($user, $userIds, $groupId);
-		$this->featureContext->setResponse($response);
+		$this->addMultipleUsersToGroup($user, $userIds, $groupId, $table);
 	}
 
 	/**
@@ -1544,9 +1552,7 @@ class GraphContext implements Context {
 		foreach ($table->getHash() as $row) {
 			$userIds[] = $this->featureContext->getAttributeOfCreatedUser($row['username'], "id");
 		}
-		$this->featureContext->verifyTableNodeColumns($table, ['username']);
-		$response = $this->addMultipleUsersToGroup($user, $userIds, $groupId);
-		$this->featureContext->setResponse($response);
+		$this->addMultipleUsersToGroup($user, $userIds, $groupId, $table);
 	}
 
 	/**
@@ -1566,9 +1572,7 @@ class GraphContext implements Context {
 		foreach ($table->getHash() as $row) {
 			$userIds[] = WebDavHelper::generateUUIDv4();
 		}
-		$this->featureContext->verifyTableNodeColumns($table, ['username']);
-		$response = $this->addMultipleUsersToGroup($user, $userIds, $groupId);
-		$this->featureContext->setResponse($response);
+		$this->addMultipleUsersToGroup($user, $userIds, $groupId, $table);
 	}
 
 	/**
@@ -1590,9 +1594,7 @@ class GraphContext implements Context {
 			$userId = $this->featureContext->getAttributeOfCreatedUser($row['username'], "id");
 			$userIds[] = $userId ?: WebDavHelper::generateUUIDv4();
 		}
-		$this->featureContext->verifyTableNodeColumns($table, ['username']);
-		$response = $this->addMultipleUsersToGroup($user, $userIds, $groupId);
-		$this->featureContext->setResponse($response);
+		$this->addMultipleUsersToGroup($user, $userIds, $groupId, $table);
 	}
 
 	/**
@@ -1985,9 +1987,12 @@ class GraphContext implements Context {
 		foreach ($table->getHash() as $row) {
 			$userIds[] = $this->featureContext->getAttributeOfCreatedUser($row['username'], "id");
 		}
-		$this->featureContext->verifyTableNodeColumns($table, ['username']);
-		$response = $this->addMultipleUsersToGroup($user, $userIds, $groupId);
-		$this->featureContext->theHTTPStatusCodeShouldBe(204, '', $response);
+		$this->addMultipleUsersToGroup($user, $userIds, $groupId, $table);
+		$response = $this->featureContext->getResponse();
+		if ($response->getStatusCode() !== 204) {
+			$this->throwHttpException($response, "Cannot add users to group '$group'");
+		}
+		$this->featureContext->emptyLastHTTPStatusCodesArray();
 	}
 
 	/**
diff --git a/tests/acceptance/features/bootstrap/Provisioning.php b/tests/acceptance/features/bootstrap/Provisioning.php
index 27f47ebcb43..5508abff0e6 100644
--- a/tests/acceptance/features/bootstrap/Provisioning.php
+++ b/tests/acceptance/features/bootstrap/Provisioning.php
@@ -2966,8 +2966,82 @@ trait Provisioning {
 	 * @throws Exception
 	 */
 	public function adminAddsUserToGroupUsingTheProvisioningApi(string $user, string $group):void {
-		$response = $this->graphContext->addUserToGroup($group, $user);
-		$this->setResponse($response);
+		$this->addUserToGroup($user, $group, "api");
+	}
+
+	/**
+	 * @When the administrator adds the following users to the following groups using the provisioning API
+	 *
+	 * @param TableNode $table
+	 *
+	 * @return void
+	 * @throws Exception
+	 */
+	public function theAdministratorAddsUserToTheFollowingGroupsUsingTheProvisioningApi(TableNode $table):void {
+		$this->verifyTableNodeColumns($table, ["username", "groupname"], ["comment"]);
+		$rows = $table->getHash();
+		foreach ($rows as $row) {
+			$this->adminAddsUserToGroupUsingTheProvisioningApi($row["username"], $row["groupname"]);
+		}
+	}
+
+	/**
+	 * @When user :user tries to add user :otherUser to group :group using the provisioning API
+	 *
+	 * @param string $user
+	 * @param string $otherUser
+	 * @param string $group
+	 *
+	 * @return void
+	 * @throws Exception
+	 */
+	public function userTriesToAddUserToGroupUsingTheProvisioningApi(string $user, string $otherUser, string $group):void {
+		$actualUser = $this->getActualUsername($user);
+		$actualPassword = $this->getUserPassword($actualUser);
+		$actualOtherUser = $this->getActualUsername($otherUser);
+		$result = UserHelper::addUserToGroup(
+			$this->getBaseUrl(),
+			$actualOtherUser,
+			$group,
+			$actualUser,
+			$actualPassword,
+			$this->getStepLineRef(),
+			$this->ocsApiVersion
+		);
+		$this->response = $result;
+	}
+
+	/**
+	 * @When user :user tries to add himself to group :group using the provisioning API
+	 *
+	 * @param string $user
+	 * @param string $group
+	 *
+	 * @return void
+	 * @throws Exception
+	 */
+	public function userTriesToAddHimselfToGroupUsingTheProvisioningApi(string $user, string $group):void {
+		$this->userTriesToAddUserToGroupUsingTheProvisioningApi($user, $user, $group);
+	}
+
+	/**
+	 * @When the administrator tries to add user :user to group :group using the provisioning API
+	 *
+	 * @param string $user
+	 * @param string $group
+	 *
+	 * @return void
+	 * @throws Exception
+	 */
+	public function theAdministratorTriesToAddUserToGroupUsingTheProvisioningApi(
+		string $user,
+		string $group
+	):void {
+		$this->userTriesToAddUserToGroupUsingTheProvisioningApi(
+			$this->getAdminUsername(),
+			$user,
+			$group
+		);
 	}
 
 	/**
@@ -2981,21 +3055,7 @@ trait Provisioning {
 	 */
 	public function userHasBeenAddedToGroup(string $user, string $group):void {
 		$user = $this->getActualUsername($user);
-		if ($this->isTestingWithLdap()) {
-			try {
-				$this->addUserToLdapGroup(
-					$user,
-					$group
-				);
-			} catch (LdapException $exception) {
-				throw new Exception(
-					"User $user cannot be added to $group Error: $exception"
-				);
-			}
-		} else {
-			$response = $this->graphContext->addUserToGroup($group, $user);
-			$this->theHTTPStatusCodeShouldBe(204, '', $response);
-		}
+		$this->addUserToGroup($user, $group, null, true);
 	}
 
 	/**
@@ -3013,6 +3073,105 @@ trait Provisioning {
 		}
 	}
 
+	/**
+	 * @Given /^user "([^"]*)" has been added to database backend group "([^"]*)"$/
+	 *
+	 * @param string $user
+	 * @param string $group
+	 *
+	 * @return void
+	 * @throws Exception
+	 */
+	public function userHasBeenAddedToDatabaseBackendGroup(string $user, string $group):void {
+		$this->addUserToGroup($user, $group, 'api', true);
+	}
+
+	/**
+	 * @param string $user
+	 * @param string $group
+	 * @param string|null $method how to add the user to the group api|occ
+	 * @param bool $checkResult if true, then check the status of the operation. default false.
+	 * 			                for given step checkResult is expected to be set as true
+	 * 			                for when step checkResult is expected to be set as false
+	 *
+	 * @return void
+	 * @throws Exception
+	 */
+	public function addUserToGroup(string $user, string $group, ?string $method = null, bool $checkResult = false):void {
+		$user = $this->getActualUsername($user);
+		if ($method === null
+			&& $this->isTestingWithLdap()
+			&& !$this->isLocalAdminGroup($group)
+		) {
+			//guess yourself
+			$method = "ldap";
+		} elseif ($method === null && OcisHelper::isTestingWithGraphApi()) {
+			$method = "graph";
+		} elseif ($method === null) {
+			$method = "api";
+		}
+		$method = \trim(\strtolower($method));
+		switch ($method) {
+			case "api":
+				$result = UserHelper::addUserToGroup(
+					$this->getBaseUrl(),
+					$user,
+					$group,
+					$this->getAdminUsername(),
+					$this->getAdminPassword(),
+					$this->getStepLineRef(),
+					$this->ocsApiVersion
+				);
+				if ($checkResult && ($result->getStatusCode() !== 200)) {
+					throw new Exception(
+						"could not add user to group. "
+						. $result->getStatusCode() . " " . $result->getBody()
+					);
+				}
+				$this->response = $result;
+				if (!$checkResult) {
+					// for when step only
+					$this->pushToLastStatusCodesArrays();
+				}
+				break;
+			case "ldap":
+				try {
+					$this->addUserToLdapGroup(
+						$user,
+						$group
+					);
+				} catch (LdapException $exception) {
+					throw new Exception(
+						"User $user cannot be added to $group Error: $exception"
+					);
+				};
+				break;
+			case "graph":
+				$this->graphContext->adminHasAddedUserToGroupUsingTheGraphApi(
+					$user,
+					$group
+				);
+				break;
+			default:
+				throw new InvalidArgumentException(
+					"Invalid method to add a user to a group"
+				);
+		}
+	}
+
+	/**
+	 * @Given the administrator has been added to group :group
+	 *
+	 * @param string $group
+	 *
+	 * @return void
+	 * @throws Exception
+	 */
+	public function theAdministratorHasBeenAddedToGroup(string $group):void {
+		$admin = $this->getAdminUsername();
+		$this->addUserToGroup($admin, $group, null, true);
+	}
+
 	/**
 	 * @param string $group
 	 * @param bool $shouldExist - true if the group should exist
diff --git a/tests/acceptance/features/bootstrap/SpacesContext.php b/tests/acceptance/features/bootstrap/SpacesContext.php
index 4f1f13b6e76..1164ec3b795 100644
--- a/tests/acceptance/features/bootstrap/SpacesContext.php
+++ b/tests/acceptance/features/bootstrap/SpacesContext.php
@@ -159,18 +159,16 @@ class SpacesContext implements Context {
 	 * Get Space Array by name
 	 *
 	 * @param string $name
-	 * @param ResponseInterface|null $response
 	 *
 	 * @return array
 	 *
 	 * @throws Exception
 	 */
-	public function getSpaceByNameFromResponse(string $name, ?ResponseInterface $response = null): array {
-		$response = $response ?? $this->featureContext->getResponse();
-		$decodedResponse = $this->featureContext->getJsonDecodedResponse($response);
-		$spaceAsArray = $decodedResponse;
-		if (isset($decodedResponse['name']) && $decodedResponse['name'] === $name) {
-			return $decodedResponse;
+	public function getSpaceByNameFromResponse(string $name): array {
+		$response = json_decode((string)$this->featureContext->getResponse()->getBody(), true, 512, JSON_THROW_ON_ERROR);
+		$spaceAsArray = $response;
+		if (isset($response['name']) && $response['name'] === $name) {
+			return $response;
 		}
 		if (isset($spaceAsArray["value"])) {
 			foreach ($spaceAsArray["value"] as $spaceCandidate) {
@@ -196,9 +194,9 @@ class SpacesContext implements Context {
 			$spaceName = $this->featureContext->getUserDisplayName($user);
 		}
 		if (strtolower($user) === 'admin') {
-			$this->listAllAvailableSpaces($user);
+			$this->theUserListsAllAvailableSpacesUsingTheGraphApi($user);
 		} else {
-			$this->listAllAvailableSpacesOfUser($user);
+			$this->theUserListsAllHisAvailableSpacesUsingTheGraphApi($user);
 		}
 		$spaces = $this->getAvailableSpaces();
 		Assert::assertArrayHasKey($spaceName, $spaces, "Space with name $spaceName for user $user not found");
@@ -247,7 +245,7 @@ class SpacesContext implements Context {
 	 * @throws GuzzleException
 	 */
 	public function getSpaceByNameManager(string $user, string $spaceName): array {
-		$this->listAllAvailableSpaces($user);
+		$this->theUserListsAllAvailableSpacesUsingTheGraphApi($user);
 
 		$spaces = $this->getAvailableSpaces();
 		Assert::assertArrayHasKey($spaceName, $spaces, "Space with name '$spaceName' for user '$user' not found");
@@ -427,7 +425,7 @@ class SpacesContext implements Context {
 		$query = "\$filter=driveType eq project";
 		$userAdmin = $this->featureContext->getAdminUsername();
 
-		$this->listAllAvailableSpaces(
+		$this->theUserListsAllAvailableSpacesUsingTheGraphApi(
 			$userAdmin,
 			$query
 		);
@@ -503,27 +501,6 @@ class SpacesContext implements Context {
 		return HttpRequestHelper::sendRequest($fullUrl, $xRequestId, $method, $user, $password, $headers);
 	}
 
-	/**
-	 * @param string $user
-	 * @param string $query
-	 *
-	 * @return ResponseInterface
-	 *
-	 * @throws GuzzleException
-	 * @throws Exception
-	 */
-	public function listAllAvailableSpacesOfUser(string $user, string $query = ''): ResponseInterface {
-		$response = GraphHelper::getMySpaces(
-			$this->featureContext->getBaseUrl(),
-			$user,
-			$this->featureContext->getPasswordForUser($user),
-			"?" . $query,
-			$this->featureContext->getStepLineRef()
-		);
-		$this->rememberTheAvailableSpaces($response);
-		return $response;
-	}
-
 	/**
 	 * @When /^user "([^"]*)" lists all available spaces via the GraphApi$/
 	 * @When /^user "([^"]*)" lists all available spaces via the GraphApi with query "([^"]*)"$/
@@ -537,33 +514,21 @@ class SpacesContext implements Context {
 	 * @throws Exception
 	 */
 	public function theUserListsAllHisAvailableSpacesUsingTheGraphApi(string $user, string $query = ''): void {
-		$this->featureContext->setResponse($this->listAllAvailableSpacesOfUser($user, $query));
+		$this->featureContext->setResponse(
+			GraphHelper::getMySpaces(
+				$this->featureContext->getBaseUrl(),
+				$user,
+				$this->featureContext->getPasswordForUser($user),
+				"?" . $query,
+				$this->featureContext->getStepLineRef()
+			)
+		);
+		$this->rememberTheAvailableSpaces();
 	}
 
 	/**
 	 * The method is used on the administration setting tab, which only the Admin user and the Space admin user have access to
 	 *
-	 * @param string $user
-	 * @param string $query
-	 *
-	 * @return ResponseInterface
-	 *
-	 * @throws GuzzleException
-	 * @throws Exception
-	 */
-	public function listAllAvailableSpaces(string $user, string $query = ''): ResponseInterface {
-		$response = GraphHelper::getAllSpaces(
-			$this->featureContext->getBaseUrl(),
-			$user,
-			$this->featureContext->getPasswordForUser($user),
-			"?" . $query,
-			$this->featureContext->getStepLineRef()
-		);
-		$this->rememberTheAvailableSpaces($response);
-		return $response;
-	}
-
-	/**
 	 * @When /^user "([^"]*)" lists all spaces via the GraphApi$/
 	 * @When /^user "([^"]*)" lists all spaces via the GraphApi with query "([^"]*)"$/
 	 * @When /^user "([^"]*)" tries to list all spaces via the GraphApi$/
@@ -578,8 +543,15 @@ class SpacesContext implements Context {
 	 */
 	public function theUserListsAllAvailableSpacesUsingTheGraphApi(string $user, string $query = ''): void {
 		$this->featureContext->setResponse(
-			$this->listAllAvailableSpaces($user, $query)
+			GraphHelper::getAllSpaces(
+				$this->featureContext->getBaseUrl(),
+				$user,
+				$this->featureContext->getPasswordForUser($user),
+				"?" . $query,
+				$this->featureContext->getStepLineRef()
+			)
 		);
+		$this->rememberTheAvailableSpaces();
 	}
 
 	/**
@@ -900,6 +872,7 @@ class SpacesContext implements Context {
 			null,
 			$userName,
 		);
+
 		$this->featureContext->assertJsonDocumentMatchesSchema(
 			$responseBody,
 			$this->featureContext->getJSONSchema($schemaString)
@@ -923,13 +896,12 @@ class SpacesContext implements Context {
 		string $grantedUser,
 		string $role
 	): void {
-		$response = $this->listAllAvailableSpacesOfUser($user);
+		$this->theUserListsAllHisAvailableSpacesUsingTheGraphApi($user);
 		$this->featureContext->theHTTPStatusCodeShouldBe(
 			200,
-			"Expected response status code should be 200",
-			$response
+			"Expected response status code should be 200"
 		);
-		Assert::assertIsArray($spaceAsArray = $this->getSpaceByNameFromResponse($spaceName, $response), "No space with name $spaceName found");
+		Assert::assertIsArray($spaceAsArray = $this->getSpaceByNameFromResponse($spaceName), "No space with name $spaceName found");
 		$permissions = $spaceAsArray["root"]["permissions"];
 		$userId = $this->featureContext->getUserIdByUserName($grantedUser);
 
@@ -973,16 +945,15 @@ class SpacesContext implements Context {
 		string $shouldOrNot,
 		string $spaceName
 	): void {
-		$response = $this->listAllAvailableSpacesOfUser($user);
+		$this->theUserListsAllHisAvailableSpacesUsingTheGraphApi($user);
 		$this->featureContext->theHTTPStatusCodeShouldBe(
 			200,
-			"Expected response status code should be 200",
-			$response
+			"Expected response status code should be 200"
 		);
 		if (\trim($shouldOrNot) === "not") {
-			Assert::assertEmpty($this->getSpaceByNameFromResponse($spaceName, $response), "space $spaceName should not be available for a user");
+			$this->jsonRespondedShouldNotContain($spaceName);
 		} else {
-			Assert::assertNotEmpty($this->getSpaceByNameFromResponse($spaceName, $response), "space '$spaceName' should be available for a user '$user' but not found");
+			Assert::assertNotEmpty($this->getSpaceByNameFromResponse($spaceName), "space '$spaceName' should be available for a user '$user' but not found");
 		}
 	}
 
@@ -999,15 +970,14 @@ class SpacesContext implements Context {
 		string $user,
 		string $spaceName
 	): void {
-		$response = $this->listAllAvailableSpacesOfUser($user);
+		$this->theUserListsAllHisAvailableSpacesUsingTheGraphApi($user);
 		$this->featureContext->theHTTPStatusCodeShouldBe(
 			200,
-			"Expected response status code should be 200",
-			$response
+			"Expected response status code should be 200"
 		);
-		$decodedResponse = $this->featureContext->getJsonDecodedResponse($response);
-		if (isset($decodedResponse["value"])) {
-			foreach ($decodedResponse["value"] as $spaceCandidate) {
+		$response = json_decode((string)$this->featureContext->getResponse()->getBody(), true, 512, JSON_THROW_ON_ERROR);
+		if (isset($response["value"])) {
+			foreach ($response["value"] as $spaceCandidate) {
 				if ($spaceCandidate['name'] === $spaceName) {
 					if ($spaceCandidate['root']['deleted']['state'] !== 'trashed') {
 						throw new \Exception(
@@ -1385,12 +1355,10 @@ class SpacesContext implements Context {
 		string $spaceName,
 		string $newDescription
 	): void {
-		$bodyData = ["description" => $newDescription];
-		$response = $this->updateSpace($user, $spaceName, $bodyData, '');
+		$this->updateSpaceDescription($user, $spaceName, $newDescription);
 		$this->featureContext->theHTTPStatusCodeShouldBe(
 			200,
-			"Expected response status code should be 200",
-			$response
+			"Expected response status code should be 200"
 		);
 	}
 
@@ -1434,22 +1402,22 @@ class SpacesContext implements Context {
 		string $spaceName,
 		int $newQuota
 	): void {
-		$bodyData = ["quota" => ["total" => $newQuota]];
-		$response = $this->updateSpace($user, $spaceName, $bodyData, '');
+		$this->updateSpaceQuota($user, $spaceName, $newQuota);
 		$this->featureContext->theHTTPStatusCodeShouldBe(
 			200,
-			"Expected response status code should be 200",
-			$response
+			"Expected response status code should be 200"
 		);
 	}
 
 	/**
+	 * @When /^user "([^"]*)" sets the file "([^"]*)" as a (description|space image)\s? in a special section of the "([^"]*)" space$/
+	 *
 	 * @param string $user
 	 * @param string $file
 	 * @param string $type
 	 * @param string $spaceName
 	 *
-	 * @return ResponseInterface
+	 * @return void
 	 * @throws GuzzleException
 	 * @throws Exception
 	 */
@@ -1458,7 +1426,7 @@ class SpacesContext implements Context {
 		string $file,
 		string $type,
 		string $spaceName
-	): ResponseInterface {
+	): void {
 		$space = $this->getSpaceByName($user, $spaceName);
 		$spaceId = $space["id"];
 		$fileId = $this->getFileId($user, $spaceName, $file);
@@ -1471,40 +1439,15 @@ class SpacesContext implements Context {
 
 		$bodyData = ["special" => [["specialFolder" => ["name" => "$type"], "id" => "$fileId"]]];
 		$body = json_encode($bodyData, JSON_THROW_ON_ERROR);
-		return GraphHelper::updateSpace(
-			$this->featureContext->getBaseUrl(),
-			$user,
-			$this->featureContext->getPasswordForUser($user),
-			$body,
-			$spaceId,
-			$this->featureContext->getStepLineRef()
-		);
-	}
 
-	/**
-	 * @When /^user "([^"]*)" sets the file "([^"]*)" as a (description|space image)\s? in a special section of the "([^"]*)" space$/
-	 *
-	 * @param string $user
-	 * @param string $file
-	 * @param string $type
-	 * @param string $spaceName
-	 *
-	 * @return void
-	 * @throws GuzzleException
-	 * @throws Exception
-	 */
-	public function userSetsFileAsDescriptionOrImageInSpecialSectionOfSpace(
-		string $user,
-		string $file,
-		string $type,
-		string $spaceName
-	): void {
 		$this->featureContext->setResponse(
-			$this->updateSpaceSpecialSection(
+			GraphHelper::updateSpace(
+				$this->featureContext->getBaseUrl(),
 				$user,
-				$file,
-				$type,
-				$spaceName
+				$this->featureContext->getPasswordForUser($user),
+				$body,
+				$spaceId,
+				$this->featureContext->getStepLineRef()
 			)
 		);
 	}
@@ -1527,11 +1470,10 @@ class SpacesContext implements Context {
 		string $type,
 		string $spaceName
 	): void {
-		$response = $this->updateSpaceSpecialSection($user, $file, $type, $spaceName);
+		$this->updateSpaceSpecialSection($user, $file, $type, $spaceName);
 		$this->featureContext->theHTTPStatusCodeShouldBe(
 			200,
-			"Expected response status code should be 200",
-			$response
+			"Expected response status code should be 200"
 		);
 	}
 
@@ -1553,12 +1495,11 @@ class SpacesContext implements Context {
 		int $quota
 	): void {
 		$space = ["Name" => $spaceName, "driveType" => $spaceType, "quota" => ["total" => $quota]];
-		$response = $this->createSpace($user, $space);
+		$this->featureContext->setResponse($this->createSpace($user, $space));
 		$this->setSpaceCreator($spaceName, $user);
 		$this->featureContext->theHTTPStatusCodeShouldBe(
 			201,
-			"Expected response status code should be 201 (Created)",
-			$response
+			"Expected response status code should be 201 (Created)"
 		);
 	}
 
@@ -1578,12 +1519,11 @@ class SpacesContext implements Context {
 		string $spaceName
 	): void {
 		$space = ["Name" => $spaceName];
-		$response = $this->createSpace($user, $space);
+		$this->featureContext->setResponse($this->createSpace($user, $space));
 		$this->setSpaceCreator($spaceName, $user);
 		$this->featureContext->theHTTPStatusCodeShouldBe(
 			201,
-			"Expected response status code should be 201 (Created)",
-			$response
+			"Expected response status code should be 201 (Created)"
 		);
 	}
 
@@ -1638,20 +1578,22 @@ class SpacesContext implements Context {
 	}
 
 	/**
+	 * @When /^user "([^"]*)" moves (?:file|folder) "([^"]*)" to "([^"]*)" in space "([^"]*)" using the WebDAV API$/
+	 *
 	 * @param string $user
 	 * @param string $fileSource
 	 * @param string $fileDestination
 	 * @param string $spaceName
 	 *
-	 * @return ResponseInterface
+	 * @return void
 	 * @throws GuzzleException
 	 */
-	public function moveFileWithinSpace(
+	public function userMovesFileWithinSpaceUsingTheWebDAVAPI(
 		string $user,
 		string $fileSource,
 		string $fileDestination,
 		string $spaceName
-	):ResponseInterface {
+	):void {
 		$space = $this->getSpaceByName($user, $spaceName);
 		$headers['Destination'] = $this->destinationHeaderValueWithSpaceName(
 			$user,
@@ -1662,27 +1604,7 @@ class SpacesContext implements Context {
 
 		$fileSource = $this->escapePath(\trim($fileSource, "/"));
 		$fullUrl = $space["root"]["webDavUrl"] . '/' . $fileSource;
-		return $this->moveFilesAndFoldersRequest($user, $fullUrl, $headers);
-	}
-
-	/**
-	 * @When /^user "([^"]*)" moves (?:file|folder) "([^"]*)" to "([^"]*)" in space "([^"]*)" using the WebDAV API$/
-	 *
-	 * @param string $user
-	 * @param string $fileSource
-	 * @param string $fileDestination
-	 * @param string $spaceName
-	 *
-	 * @return void
-	 * @throws GuzzleException
-	 */
-	public function userMovesFileWithinSpaceUsingTheWebDAVAPI(
-		string $user,
-		string $fileSource,
-		string $fileDestination,
-		string $spaceName
-	):void {
-		$this->featureContext->setResponse($this->moveFileWithinSpace($user, $fileSource, $fileDestination, $spaceName));
+		$this->featureContext->setResponse($this->moveFilesAndFoldersRequest($user, $fullUrl, $headers));
 		$this->featureContext->pushToLastHttpStatusCodesArray();
 	}
 
@@ -1703,7 +1625,7 @@ class SpacesContext implements Context {
 		string $fileDestination,
 		string $spaceName
 	):void {
-		$response = $this->moveFileWithinSpace(
+		$this->userMovesFileWithinSpaceUsingTheWebDAVAPI(
 			$user,
 			$fileSource,
 			$fileDestination,
@@ -1712,9 +1634,8 @@ class SpacesContext implements Context {
 		$this->featureContext->theHTTPStatusCodeShouldBe(
 			201,
 			__METHOD__ . "Expected response status code should be 201 (Created)\n" .
-			"Actual response status code was: " . $response->getStatusCode() . "\n" .
-			"Actual response body was: " . $response->getBody(),
-			$response
+			"Actual response status code was: " . $this->featureContext->getResponse()->getStatusCode() . "\n" .
+			"Actual response body was: " . $this->featureContext->getResponse()->getBody()
 		);
 	}
 
@@ -1947,8 +1868,7 @@ class SpacesContext implements Context {
 		string $fileContent,
 		string $destination
 	): array {
-		$response = $this->listAllAvailableSpacesOfUser($user);
-		$this->featureContext->theHTTPStatusCodeShouldBe(200, "", $response);
+		$this->theUserListsAllHisAvailableSpacesUsingTheGraphApi($user);
 		$this->setSpaceIDByName($user, $spaceName);
 		$response = $this->featureContext->uploadFileWithContent($user, $fileContent, $destination, true);
 		$this->featureContext->theHTTPStatusCodeShouldBe(['201', '204'], "", $response);
@@ -2033,18 +1953,20 @@ class SpacesContext implements Context {
 	}
 
 	/**
+	 * @When /^user "([^"]*)" creates a share inside of space "([^"]*)" with settings:$/
+	 *
 	 * @param  string $user
 	 * @param  string $spaceName
 	 * @param TableNode $table
 	 *
-	 * @return ResponseInterface
+	 * @return void
 	 * @throws GuzzleException
 	 */
 	public function createShareResource(
 		string $user,
 		string $spaceName,
 		TableNode $table
-	): ResponseInterface {
+	): void {
 		$rows = $table->getRowsHash();
 		$rows["path"] = \array_key_exists("path", $rows) ? $rows["path"] : null;
 		$rows["shareType"] = \array_key_exists("shareType", $rows) ? $rows["shareType"] : 0;
@@ -2060,36 +1982,17 @@ class SpacesContext implements Context {
 		];
 
 		$fullUrl = $this->baseUrl . $this->ocsApiUrl;
-		$response = $this->sendPostRequestToUrl(
-			$fullUrl,
-			$user,
-			$this->featureContext->getPasswordForUser($user),
-			$body,
-			$this->featureContext->getStepLineRef()
-		);
-		$responseXml = $this->featureContext->getResponseXml($response, __METHOD__);
-		$this->featureContext->addToCreatedPublicShares($responseXml->data);
-		return $response;
-	}
-
-	/**
-	 * @When /^user "([^"]*)" creates a share inside of space "([^"]*)" with settings:$/
-	 *
-	 * @param  string $user
-	 * @param  string $spaceName
-	 * @param TableNode $table
-	 *
-	 * @return void
-	 * @throws GuzzleException
-	 */
-	public function userCreatesShareInsideOfSpaceWithSettings(
-		string $user,
-		string $spaceName,
-		TableNode $table
-	): void {
 		$this->featureContext->setResponse(
-			$this->createShareResource($user, $spaceName, $table)
+			$this->sendPostRequestToUrl(
+				$fullUrl,
+				$user,
+				$this->featureContext->getPasswordForUser($user),
+				$body,
+				$this->featureContext->getStepLineRef()
+			)
 		);
+		$response = $this->featureContext->getResponseXml(null, __METHOD__);
+		$this->featureContext->addToCreatedPublicShares($response->data);
 	}
 
 	/**
@@ -2102,13 +2005,17 @@ class SpacesContext implements Context {
 	 * @return void
 	 * @throws GuzzleException
 	 */
-	public function userHasSharedTheFollowingEntityInsideOfSpace(
+	public function hasSharedTheFollowingEntityInsideOfSpace(
 		string $user,
 		string $spaceName,
 		TableNode $table
 	): void {
-		$response = $this->createShareResource($user, $spaceName, $table);
-		$this->featureContext->theHTTPStatusCodeShouldBe(200, "", $response);
+		$this->createShareResource($user, $spaceName, $table);
+		Assert::assertEquals(
+			$this->featureContext->getResponse()->getStatusCode(),
+			200,
+			"Expected response status code should be 200"
+		);
 	}
 
 	/**
@@ -2163,20 +2070,21 @@ class SpacesContext implements Context {
 		$rows['expireDate'] = $dateTime->format('Y-m-d\\TH:i:sP');
 		$this->featureContext->setResponse($this->updateSharedResource($user, $rows));
 	}
-
 	/**
+	 * @When /^user "([^"]*)" creates a public link share inside of space "([^"]*)" with settings:$/
+	 *
 	 * @param  string $user
 	 * @param  string $spaceName
 	 * @param TableNode $table
 	 *
-	 * @return ResponseInterface
+	 * @return void
 	 * @throws GuzzleException
 	 */
 	public function createPublicLinkToEntityInsideOfSpaceRequest(
 		string $user,
 		string $spaceName,
 		TableNode $table
-	): ResponseInterface {
+	): void {
 		$space = $this->getSpaceByName($user, $spaceName);
 		$rows = $table->getRowsHash();
 
@@ -2198,37 +2106,18 @@ class SpacesContext implements Context {
 
 		$fullUrl = $this->baseUrl . $this->ocsApiUrl;
 
-		$response =  $this->sendPostRequestToUrl(
-			$fullUrl,
-			$user,
-			$this->featureContext->getPasswordForUser($user),
-			$body,
-			$this->featureContext->getStepLineRef()
-		);
-
-		$responseXml = $this->featureContext->getResponseXml($response, __METHOD__);
-		$this->featureContext->addToCreatedPublicShares($responseXml->data);
-		return $response;
-	}
-
-	/**
-	 * @When /^user "([^"]*)" creates a public link share inside of space "([^"]*)" with settings:$/
-	 *
-	 * @param  string $user
-	 * @param  string $spaceName
-	 * @param TableNode $table
-	 *
-	 * @return void
-	 * @throws GuzzleException
-	 */
-	public function userCreatesPublicLinkShareInsideOfSpaceWithSettings(
-		string $user,
-		string $spaceName,
-		TableNode $table
-	): void {
 		$this->featureContext->setResponse(
-			$this->createPublicLinkToEntityInsideOfSpaceRequest($user, $spaceName, $table)
+			$this->sendPostRequestToUrl(
+				$fullUrl,
+				$user,
+				$this->featureContext->getPasswordForUser($user),
+				$body,
+				$this->featureContext->getStepLineRef()
+			)
 		);
+
+		$response = $this->featureContext->getResponseXml(null, __METHOD__);
+		$this->featureContext->addToCreatedPublicShares($response->data);
 	}
 
 	/**
@@ -2246,12 +2135,12 @@ class SpacesContext implements Context {
 		string $spaceName,
 		TableNode $table
 	): void {
-		$response = $this->createPublicLinkToEntityInsideOfSpaceRequest($user, $spaceName, $table);
+		$this->createPublicLinkToEntityInsideOfSpaceRequest($user, $spaceName, $table);
 
+		$expectedHTTPStatus = "200";
 		$this->featureContext->theHTTPStatusCodeShouldBe(
-			200,
-			"Expected response status code should be 200",
-			$response
+			$expectedHTTPStatus,
+			"Expected response status code should be $expectedHTTPStatus"
 		);
 	}
 
@@ -2270,16 +2159,14 @@ class SpacesContext implements Context {
 		string $spaceName,
 		TableNode $tableNode
 	): void {
-		$rows = $tableNode->getRowsHash();
-		$response = $this->shareSpace($user, $spaceName, $rows);
+		$this->sendShareSpaceRequest($user, $spaceName, $tableNode);
 		$expectedHTTPStatus = "200";
 		$this->featureContext->theHTTPStatusCodeShouldBe(
 			$expectedHTTPStatus,
-			"Expected response status code should be $expectedHTTPStatus",
-			$response
+			"Expected response status code should be $expectedHTTPStatus"
 		);
 		$expectedOCSStatus = "200";
-		$this->ocsContext->theOCSStatusCodeShouldBe($expectedOCSStatus, "Expected OCS response status code $expectedOCSStatus", $response);
+		$this->ocsContext->theOCSStatusCodeShouldBe($expectedOCSStatus, "Expected OCS response status code $expectedOCSStatus");
 	}
 
 	/**
@@ -2297,35 +2184,10 @@ class SpacesContext implements Context {
 		string $spaceName,
 		string $recipient
 	): void {
-		$response = $this->sendUnshareSpaceRequest($user, $spaceName, $recipient);
+		$this->sendUnshareSpaceRequest($user, $spaceName, $recipient);
 		$this->featureContext->theHTTPStatusCodeShouldBe(
 			200,
-			"Expected response status code should be 200",
-			$response
-		);
-	}
-
-	/**
-	 * @param  string $user
-	 * @param  string $spaceName
-	 * @param  string $recipient
-	 *
-	 * @return ResponseInterface
-	 * @throws GuzzleException
-	 */
-	public function sendUnshareSpaceRequest(
-		string $user,
-		string $spaceName,
-		string $recipient
-	): ResponseInterface {
-		$space = $this->getSpaceByName($user, $spaceName);
-		$fullUrl = $this->baseUrl . $this->ocsApiUrl . "/" . $space['id'] . "?shareWith=" . $recipient;
-
-		return HttpRequestHelper::delete(
-			$fullUrl,
-			$this->featureContext->getStepLineRef(),
-			$user,
-			$this->featureContext->getPasswordForUser($user)
+			"Expected response status code should be 200"
 		);
 	}
 
@@ -2339,36 +2201,21 @@ class SpacesContext implements Context {
 	 * @return void
 	 * @throws GuzzleException
 	 */
-	public function userUnsharesSpace(
+	public function sendUnshareSpaceRequest(
 		string $user,
 		string $spaceName,
 		string $recipient
 	): void {
-		$this->featureContext->setResponse(
-			$this->sendUnshareSpaceRequest($user, $spaceName, $recipient)
-		);
-	}
-
-	/**
-	 * @param  string $user
-	 * @param  string $object
-	 * @param  string $spaceName
-	 *
-	 * @return ResponseInterface
-	 * @throws GuzzleException
-	 */
-	public function removeObjectFromSpace(
-		string $user,
-		string $object,
-		string $spaceName
-	): ResponseInterface {
 		$space = $this->getSpaceByName($user, $spaceName);
-		$spaceWebDavUrl = $space["root"]["webDavUrl"] . '/' . ltrim($object, "/");
-		return HttpRequestHelper::delete(
-			$spaceWebDavUrl,
-			$this->featureContext->getStepLineRef(),
-			$user,
-			$this->featureContext->getPasswordForUser($user)
+		$fullUrl = $this->baseUrl . $this->ocsApiUrl . "/" . $space['id'] . "?shareWith=" . $recipient;
+
+		$this->featureContext->setResponse(
+			HttpRequestHelper::delete(
+				$fullUrl,
+				$this->featureContext->getStepLineRef(),
+				$user,
+				$this->featureContext->getPasswordForUser($user)
+			)
 		);
 	}
 
@@ -2382,13 +2229,20 @@ class SpacesContext implements Context {
 	 * @return void
 	 * @throws GuzzleException
 	 */
-	public function userRemovesFileOrFolderFromSpace(
+	public function sendRemoveObjectFromSpaceRequest(
 		string $user,
 		string $object,
 		string $spaceName
 	): void {
+		$space = $this->getSpaceByName($user, $spaceName);
+		$spaceWebDavUrl = $space["root"]["webDavUrl"] . '/' . ltrim($object, "/");
 		$this->featureContext->setResponse(
-			$this->removeObjectFromSpace($user, $object, $spaceName)
+			HttpRequestHelper::delete(
+				$spaceWebDavUrl,
+				$this->featureContext->getStepLineRef(),
+				$user,
+				$this->featureContext->getPasswordForUser($user)
+			)
 		);
 	}
 
@@ -2405,34 +2259,10 @@ class SpacesContext implements Context {
 		string $user,
 		string $spaceName
 	):void {
-		$response = $this->deleteSpace($user, $spaceName);
+		$this->sendDeleteSpaceRequest($user, $spaceName);
 		$this->featureContext->theHTTPStatusCodeShouldBe(
 			204,
-			"Expected response status code should be 200",
-			$response
-		);
-	}
-
-	/**
-	 * @param  string $user
-	 * @param  string $spaceName
-	 * @param  string $owner
-	 *
-	 * @return ResponseInterface
-	 * @throws GuzzleException
-	 */
-	public function disableSpace(
-		string $user,
-		string $spaceName,
-		string $owner = ''
-	): ResponseInterface {
-		$space = $this->getSpaceByName(($owner !== "") ? $owner : $user, $spaceName);
-		return GraphHelper::disableSpace(
-			$this->featureContext->getBaseUrl(),
-			$user,
-			$this->featureContext->getPasswordForUser($user),
-			$space["id"],
-			$this->featureContext->getStepLineRef()
+			"Expected response status code should be 200"
 		);
 	}
 
@@ -2447,13 +2277,20 @@ class SpacesContext implements Context {
 	 * @return void
 	 * @throws GuzzleException
 	 */
-	public function userDisablesSpace(
+	public function sendDisableSpaceRequest(
 		string $user,
 		string $spaceName,
 		string $owner = ''
 	): void {
+		$space = $this->getSpaceByName(($owner !== "") ? $owner : $user, $spaceName);
 		$this->featureContext->setResponse(
-			$this->disableSpace($user, $spaceName, $owner)
+			GraphHelper::disableSpace(
+				$this->featureContext->getBaseUrl(),
+				$user,
+				$this->featureContext->getPasswordForUser($user),
+				$space["id"],
+				$this->featureContext->getStepLineRef()
+			)
 		);
 	}
 
@@ -2467,17 +2304,16 @@ class SpacesContext implements Context {
 	 * @return void
 	 * @throws GuzzleException
 	 */
-	public function userHasRemovedFileOrFolderFromSpace(
+	public function sendUserHasRemovedObjectFromSpaceRequest(
 		string $user,
 		string $object,
 		string $spaceName
 	): void {
-		$response = $this->removeObjectFromSpace($user, $object, $spaceName);
+		$this->sendRemoveObjectFromSpaceRequest($user, $object, $spaceName);
 		$expectedHTTPStatus = "204";
 		$this->featureContext->theHTTPStatusCodeShouldBe(
 			$expectedHTTPStatus,
-			"Expected response status code should be $expectedHTTPStatus",
-			$response
+			"Expected response status code should be $expectedHTTPStatus"
 		);
 	}
 
@@ -2494,36 +2330,11 @@ class SpacesContext implements Context {
 		string $user,
 		string $spaceName
 	): void {
-		$response = $this->disableSpace($user, $spaceName);
+		$this->sendDisableSpaceRequest($user, $spaceName);
 		$expectedHTTPStatus = "204";
 		$this->featureContext->theHTTPStatusCodeShouldBe(
 			$expectedHTTPStatus,
-			"Expected response status code should be $expectedHTTPStatus",
-			$response
-		);
-	}
-
-	/**
-	 * @param  string $user
-	 * @param  string $spaceName
-	 * @param string $owner
-	 *
-	 * @return ResponseInterface
-	 * @throws GuzzleException
-	 */
-	public function deleteSpace(
-		string $user,
-		string $spaceName,
-		string $owner = ''
-	): ResponseInterface {
-		$space = $this->getSpaceByName(($owner !== "") ? $owner : $user, $spaceName);
-
-		return GraphHelper::deleteSpace(
-			$this->featureContext->getBaseUrl(),
-			$user,
-			$this->featureContext->getPasswordForUser($user),
-			$space["id"],
-			$this->featureContext->getStepLineRef()
+			"Expected response status code should be $expectedHTTPStatus"
 		);
 	}
 
@@ -2538,36 +2349,21 @@ class SpacesContext implements Context {
 	 * @return void
 	 * @throws GuzzleException
 	 */
-	public function userDeletesSpace(
+	public function sendDeleteSpaceRequest(
 		string $user,
 		string $spaceName,
 		string $owner = ''
 	): void {
-		$this->featureContext->setResponse(
-			$this->deleteSpace($user, $spaceName, $owner)
-		);
-	}
-
-	/**
-	 * @param  string $user
-	 * @param  string $spaceName
-	 * @param  string $owner
-	 *
-	 * @return ResponseInterface
-	 * @throws GuzzleException
-	 */
-	public function restoreSpace(
-		string $user,
-		string $spaceName,
-		string $owner = ''
-	): ResponseInterface {
 		$space = $this->getSpaceByName(($owner !== "") ? $owner : $user, $spaceName);
-		return GraphHelper::restoreSpace(
-			$this->featureContext->getBaseUrl(),
-			$user,
-			$this->featureContext->getPasswordForUser($user),
-			$space["id"],
-			$this->featureContext->getStepLineRef()
+
+		$this->featureContext->setResponse(
+			GraphHelper::deleteSpace(
+				$this->featureContext->getBaseUrl(),
+				$user,
+				$this->featureContext->getPasswordForUser($user),
+				$space["id"],
+				$this->featureContext->getStepLineRef()
+			)
 		);
 	}
 
@@ -2582,13 +2378,20 @@ class SpacesContext implements Context {
 	 * @return void
 	 * @throws GuzzleException
 	 */
-	public function userRestoresADisabledSpace(
+	public function sendRestoreSpaceRequest(
 		string $user,
 		string $spaceName,
 		string $owner = ''
 	): void {
+		$space = $this->getSpaceByName(($owner !== "") ? $owner : $user, $spaceName);
 		$this->featureContext->setResponse(
-			$this->restoreSpace($user, $spaceName, $owner)
+			GraphHelper::restoreSpace(
+				$this->featureContext->getBaseUrl(),
+				$user,
+				$this->featureContext->getPasswordForUser($user),
+				$space["id"],
+				$this->featureContext->getStepLineRef()
+			)
 		);
 	}
 
@@ -2605,34 +2408,11 @@ class SpacesContext implements Context {
 		string $user,
 		string $spaceName
 	): void {
-		$response = $this->restoreSpace($user, $spaceName);
+		$this->sendRestoreSpaceRequest($user, $spaceName);
 		$expectedHTTPStatus = "200";
 		$this->featureContext->theHTTPStatusCodeShouldBe(
 			$expectedHTTPStatus,
-			"Expected response status code should be $expectedHTTPStatus",
-			$response
-		);
-	}
-
-	/**
-	 * @param  string $user
-	 * @param  string $spaceName
-	 *
-	 * @return ResponseInterface
-	 * @throws GuzzleException
-	 */
-	public function listAllDeletedFilesFromTrash(
-		string $user,
-		string $spaceName
-	): ResponseInterface {
-		$space = $this->getSpaceByName($user, $spaceName);
-		$fullUrl = $this->baseUrl . $this->davSpacesUrl . "trash-bin/" . $space["id"];
-		return HttpRequestHelper::sendRequest(
-			$fullUrl,
-			$this->featureContext->getStepLineRef(),
-			'PROPFIND',
-			$user,
-			$this->featureContext->getPasswordForUser($user)
+			"Expected response status code should be $expectedHTTPStatus"
 		);
 	}
 
@@ -2649,8 +2429,10 @@ class SpacesContext implements Context {
 		string $user,
 		string $spaceName
 	): void {
+		$space = $this->getSpaceByName($user, $spaceName);
+		$fullUrl = $this->baseUrl . $this->davSpacesUrl . "trash-bin/" . $space["id"];
 		$this->featureContext->setResponse(
-			$this->listAllDeletedFilesFromTrash($user, $spaceName)
+			HttpRequestHelper::sendRequest($fullUrl, $this->featureContext->getStepLineRef(), 'PROPFIND', $user, $this->featureContext->getPasswordForUser($user))
 		);
 	}
 
@@ -2697,14 +2479,13 @@ class SpacesContext implements Context {
 		string $user,
 		string $spaceName
 	): array {
-		$response = $this->listAllDeletedFilesFromTrash($user, $spaceName);
+		$this->userListAllDeletedFilesInTrash($user, $spaceName);
 		$this->featureContext->theHTTPStatusCodeShouldBe(
 			207,
-			"Expected response status code should be 207",
-			$response
+			"Expected response status code should be 207"
 		);
 		return $this->trashbinContext->getTrashbinContentFromResponseXml(
-			$this->featureContext->getResponseXml($response)
+			$this->featureContext->getResponseXml($this->featureContext->getResponse())
 		);
 	}
 
@@ -3129,18 +2910,20 @@ class SpacesContext implements Context {
 	}
 
 	/**
+	 * @When /^user "([^"]*)" creates a public link share of the space "([^"]*)" with settings:$/
+	 *
 	 * @param  string $user
 	 * @param  string $spaceName
 	 * @param TableNode|null $table
 	 *
-	 * @return ResponseInterface
+	 * @return void
 	 * @throws GuzzleException
 	 */
 	public function sendShareSpaceViaLinkRequest(
 		string $user,
 		string $spaceName,
 		?TableNode $table
-	): ResponseInterface {
+	): void {
 		$space = $this->getSpaceByName($user, $spaceName);
 		$rows = $table->getRowsHash();
 
@@ -3161,41 +2944,18 @@ class SpacesContext implements Context {
 
 		$fullUrl = $this->baseUrl . $this->ocsApiUrl;
 
-		$response = $this->sendPostRequestToUrl(
-			$fullUrl,
-			$user,
-			$this->featureContext->getPasswordForUser($user),
-			$body,
-			$this->featureContext->getStepLineRef()
-		);
-
-		$responseXml = $this->featureContext->getResponseXml($response, __METHOD__);
-		$this->featureContext->addToCreatedPublicShares($responseXml->data);
-		return $response;
-	}
-
-	/**
-	 * @When /^user "([^"]*)" creates a public link share of the space "([^"]*)" with settings:$/
-	 *
-	 * @param  string $user
-	 * @param  string $spaceName
-	 * @param TableNode|null $table
-	 *
-	 * @return void
-	 * @throws GuzzleException
-	 */
-	public function userCreatesAPublicLinkShareOfSpaceWithSettings(
-		string $user,
-		string $spaceName,
-		?TableNode $table
-	): void {
 		$this->featureContext->setResponse(
-			$this->sendShareSpaceViaLinkRequest(
+			$this->sendPostRequestToUrl(
+				$fullUrl,
 				$user,
-				$spaceName,
-				$table
+				$this->featureContext->getPasswordForUser($user),
+				$body,
+				$this->featureContext->getStepLineRef()
 			)
 		);
+
+		$response = $this->featureContext->getResponseXml(null, __METHOD__);
+		$this->featureContext->addToCreatedPublicShares($response->data);
 	}
 
 	/**
@@ -3213,13 +2973,12 @@ class SpacesContext implements Context {
 		string $spaceName,
 		?TableNode $table
 	): void {
-		$response = $this->sendShareSpaceViaLinkRequest($user, $spaceName, $table);
+		$this->sendShareSpaceViaLinkRequest($user, $spaceName, $table);
 
 		$expectedHTTPStatus = "200";
 		$this->featureContext->theHTTPStatusCodeShouldBe(
 			$expectedHTTPStatus,
-			"Expected response status code should be $expectedHTTPStatus",
-			$response
+			"Expected response status code should be $expectedHTTPStatus"
 		);
 	}
 
@@ -3615,13 +3374,12 @@ class SpacesContext implements Context {
 		string $role,
 		string $expirationDate = null
 	): void {
-		$response = $this->listAllAvailableSpacesOfUser($user);
+		$this->theUserListsAllHisAvailableSpacesUsingTheGraphApi($user);
 		$this->featureContext->theHTTPStatusCodeShouldBe(
 			200,
-			"Expected response status code should be 200",
-			$response
+			"Expected response status code should be 200"
 		);
-		Assert::assertIsArray($spaceAsArray = $this->getSpaceByNameFromResponse($spaceName, $response), "No space with name $spaceName found");
+		Assert::assertIsArray($spaceAsArray = $this->getSpaceByNameFromResponse($spaceName), "No space with name $spaceName found");
 		$recipientType === 'user' ? $recipientId = $this->featureContext->getUserIdByUserName($recipient) : $recipientId = $this->featureContext->getGroupIdByGroupName($recipient);
 		$foundRoleInResponse = false;
 		foreach ($spaceAsArray['root']['permissions'] as $permission) {
diff --git a/tests/acceptance/features/coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature b/tests/acceptance/features/coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature
index ef7f4171438..de3b4e97abd 100644
--- a/tests/acceptance/features/coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature
+++ b/tests/acceptance/features/coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature
@@ -160,7 +160,7 @@ Feature: share resources where the sharee receives the share in multiple ways
       | 1               | 100             |
       | 2               | 200             |
 
-  @skipOnReva
+  @skipOnGraph
   Scenario Outline: share with a group and then add a user to that group that already has a file with the shared name
     Given using OCS API version "<ocs_api_version>"
     And user "Carol" has been created with default attributes and without skeleton files
@@ -176,15 +176,16 @@ Feature: share resources where the sharee receives the share in multiple ways
       | shareWith | grp1       |
     And user "Brian" has accepted share "/lorem.txt" offered by user "Alice"
     When the administrator adds user "Carol" to group "grp1" using the provisioning API
-    Then the HTTP status code should be "204"
+    Then the OCS status code should be "<ocs_status_code>"
+    And the HTTP status code should be "200"
     And user "Carol" should be able to accept pending share "/lorem.txt" offered by user "Alice"
     And the content of file "Shares/lorem.txt" for user "Brian" should be "Shared content"
     And the content of file "lorem.txt" for user "Carol" should be "My content"
     And the content of file "Shares/lorem.txt" for user "Carol" should be "Shared content"
     Examples:
-      | ocs_api_version |
-      | 1               |
-      | 2               |
+      | ocs_api_version | ocs_status_code |
+      | 1               | 100             |
+      | 2               | 200             |
 
   @issue-2440
   Scenario: sharing parent folder to user with all permissions and its child folder to group with read permission then check create operation
diff --git a/tests/acceptance/features/coreApiShareManagementBasicToShares/createShareToSharesFolder.feature b/tests/acceptance/features/coreApiShareManagementBasicToShares/createShareToSharesFolder.feature
index c7457e9ae04..c2408a0ffaa 100644
--- a/tests/acceptance/features/coreApiShareManagementBasicToShares/createShareToSharesFolder.feature
+++ b/tests/acceptance/features/coreApiShareManagementBasicToShares/createShareToSharesFolder.feature
@@ -466,7 +466,7 @@ Feature: sharing
       | 1               | 100             |
       | 2               | 200             |
 
-  @skipOnReva
+  @skipOnGraph
   Scenario Outline: share with a group and then add a user to that group
     Given using OCS API version "<ocs_api_version>"
     And these users have been created with default attributes and without skeleton files: