Repository: owncloud/ocis
Pull request #3301 (2022-03-11 11:52:34)

Share events for audit logging
<!--
Thanks for submitting a change to ownCloud!

This is the bug tracker for the oCIS component. Find other components at https://github.com/owncloud/core/blob/master/.github/CONTRIBUTING.md#guidelines

For fixing potential security issues please see https://owncloud.org/security/

To make it possible for us to get your change reviewed and merged please carefully fill out the requested information below.

Please note that any kind of change needs first be submitted to the master branch which holds the next version of oCIS.

Please set the following labels:

- Set label "Status:Needs-Review" for review or "Status:In-Progress" if the PR still has open tasks.
- Assignment: assign to self
- Reviewers: pick at least one
-->

## Description
Adds sharing events to the audit logging service

## Related Issue
<!--- This project only accepts pull requests related to open issues -->
<!--- If suggesting a new feature or change, please discuss it in an issue first -->
<!--- If fixing a bug, there should be an issue describing it with steps to reproduce -->
<!--- Please link to the issue here: -->
- Fixes <issue_link>

## Motivation and Context
<!--- Why is this change required? What problem does it solve? -->

## How Has This Been Tested?
<!--- Please describe in detail how you tested your changes. -->
<!--- Include details of your testing environment, and the tests you ran to -->
<!--- see how your change affects other areas of the code, etc. -->
- unit tests run in ci-pipeline

## Screenshots (if appropriate):

## Types of changes
<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->
- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)
- [ ] Technical debt
- [ ] Tests only (no source changes)

## Checklist:
<!-- Tick the checkboxes when done. -->
<!-- Raise documentation ticket in owncloud.github.io/ -->
- [x] Code changes
- [x] Unit tests added
- [ ] Acceptance tests added
- [ ] Documentation ticket raised: <link> 



Patch:
diff --git a/.drone.env b/.drone.env
index 26a22530078..68a30862067 100644
--- a/.drone.env
+++ b/.drone.env
@@ -1,5 +1,5 @@
 # The test runner source for API tests
-CORE_COMMITID=a293d131eb9475542c72e048ddd44b8b6cbe2c01
+CORE_COMMITID=4512f46e7196a8c1f1cfc56ec397628cbf540407
 CORE_BRANCH=master
 
 # The test runner source for UI tests
diff --git a/.drone.star b/.drone.star
index a501e467995..0bddbb7b946 100644
--- a/.drone.star
+++ b/.drone.star
@@ -16,6 +16,7 @@ config = {
     "modules": [
         # if you add a module here please also add it to the root level Makefile
         "accounts",
+        "audit",
         "glauth",
         "graph-explorer",
         "graph",
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5c63f4722db..5d05de6f690 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,27 +6,12 @@ The following sections list the changes for unreleased.
 
 ## Summary
 
-* Bugfix - Network configuration in individiual_services example: [#3238](https://github.com/owncloud/ocis/pull/3238)
-* Bugfix - Improve gif thumbnails: [#3305](https://github.com/owncloud/ocis/pull/3305)
 * Enhancement - Include etags in drives listing: [#3267](https://github.com/owncloud/ocis/pull/3267)
 * Enhancement - Improve thumbnails API: [#3272](https://github.com/owncloud/ocis/pull/3272)
 * Enhancement - Update ownCloud Web to v5.3.0-rc.1: [#6561](https://github.com/owncloud/web/pull/6561)
 
 ## Details
 
-* Bugfix - Network configuration in individiual_services example: [#3238](https://github.com/owncloud/ocis/pull/3238)
-
-   Tidy up the deployments/examples/ocis_individual_services example so that the
-   instructions work.
-
-   https://github.com/owncloud/ocis/pull/3238
-
-* Bugfix - Improve gif thumbnails: [#3305](https://github.com/owncloud/ocis/pull/3305)
-
-   Improved the gif thumbnail generation for gifs with different disposal strategies.
-
-   https://github.com/owncloud/ocis/pull/3305
-
 * Enhancement - Include etags in drives listing: [#3267](https://github.com/owncloud/ocis/pull/3267)
 
    Added etags in the response of list drives.
diff --git a/Makefile b/Makefile
index de9c6924ba6..2bffcac2114 100644
--- a/Makefile
+++ b/Makefile
@@ -17,6 +17,7 @@ L10N_MODULES := $(shell find . -path '*.tx*' -name 'config' | sed 's|/[^/]*$$||'
 # if you add a module here please also add it to the .drone.star file
 OCIS_MODULES = \
 	accounts \
+	audit \
 	glauth \
 	graph \
 	graph-explorer \
diff --git a/accounts/pkg/service/v0/service.go b/accounts/pkg/service/v0/service.go
index f709b70f20b..21e3a58dd13 100644
--- a/accounts/pkg/service/v0/service.go
+++ b/accounts/pkg/service/v0/service.go
@@ -253,25 +253,6 @@ func (s Service) createDefaultAccounts(withDemoAccounts bool) (err error) {
 				{Id: "509a9dcd-bb37-4f4f-a01a-19dca27d9cfa"}, // users
 			},
 		},
-		{
-			Id:                       "534bb038-6f9d-4093-946f-133be61fa4e7",
-			PreferredName:            "katherine",
-			OnPremisesSamAccountName: "katherine",
-			Mail:                     "katherine@example.org",
-			DisplayName:              "Katherine Johnson",
-			UidNumber:                20005,
-			GidNumber:                30000,
-			PasswordProfile: &accountsmsg.PasswordProfile{
-				Password: "$2a$11$6SIBlZ.8BzjBsDTRrThUyuz6OvP.XLo7101oFiwHHB.jufKGS9.Ji",
-			},
-			AccountEnabled: true,
-			MemberOf: []*accountsmsg.Group{
-				{Id: "509a9dcd-bb37-4f4f-a01a-19dca27d9cfa"}, // users
-				{Id: "6040aa17-9c64-4fef-9bd0-77234d71bad0"}, // sailing-lovers
-				{Id: "a1726108-01f8-4c30-88df-2b1a9d1cba1a"}, // quantum-lovers
-				{Id: "262982c1-2362-4afa-bfdf-8cbfef64a06e"}, // physics-lovers
-			},
-		},
 		// technical users for kopano and reva
 		{
 			Id:                       "820ba2a1-3f54-4538-80a4-2d73007e30bf",
@@ -372,11 +353,9 @@ func (s Service) createDefaultGroups(withDemoGroups bool) (err error) {
 			{Id: "4c510ada-c86b-4815-8820-42cdf82c3d51"}, // einstein
 			{Id: "f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c"}, // marie
 			{Id: "932b4540-8d16-481e-8ef4-588e4b6b151c"}, // feynman
-			{Id: "534bb038-6f9d-4093-946f-133be61fa4e7"}, // katherine
 		}},
 		{Id: "6040aa17-9c64-4fef-9bd0-77234d71bad0", GidNumber: 30001, OnPremisesSamAccountName: "sailing-lovers", DisplayName: "Sailing lovers", Members: []*accountsmsg.Account{
 			{Id: "4c510ada-c86b-4815-8820-42cdf82c3d51"}, // einstein
-			{Id: "534bb038-6f9d-4093-946f-133be61fa4e7"}, // katherine
 		}},
 		{Id: "dd58e5ec-842e-498b-8800-61f2ec6f911f", GidNumber: 30002, OnPremisesSamAccountName: "violin-haters", DisplayName: "Violin haters", Members: []*accountsmsg.Account{
 			{Id: "4c510ada-c86b-4815-8820-42cdf82c3d51"}, // einstein
@@ -389,7 +368,6 @@ func (s Service) createDefaultGroups(withDemoGroups bool) (err error) {
 		}},
 		{Id: "a1726108-01f8-4c30-88df-2b1a9d1cba1a", GidNumber: 30005, OnPremisesSamAccountName: "quantum-lovers", DisplayName: "Quantum lovers", Members: []*accountsmsg.Account{
 			{Id: "932b4540-8d16-481e-8ef4-588e4b6b151c"}, // feynman
-			{Id: "534bb038-6f9d-4093-946f-133be61fa4e7"}, // katherine
 		}},
 		{Id: "167cbee2-0518-455a-bfb2-031fe0621e5d", GidNumber: 30006, OnPremisesSamAccountName: "philosophy-haters", DisplayName: "Philosophy haters", Members: []*accountsmsg.Account{
 			{Id: "932b4540-8d16-481e-8ef4-588e4b6b151c"}, // feynman
@@ -398,7 +376,6 @@ func (s Service) createDefaultGroups(withDemoGroups bool) (err error) {
 			{Id: "4c510ada-c86b-4815-8820-42cdf82c3d51"}, // einstein
 			{Id: "f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c"}, // marie
 			{Id: "932b4540-8d16-481e-8ef4-588e4b6b151c"}, // feynman
-			{Id: "534bb038-6f9d-4093-946f-133be61fa4e7"}, // katherine
 		}},
 	}
 
diff --git a/audit/Makefile b/audit/Makefile
new file mode 100644
index 00000000000..b2661463c75
--- /dev/null
+++ b/audit/Makefile
@@ -0,0 +1,55 @@
+SHELL := bash
+NAME := audit
+
+include ../.make/recursion.mk
+
+.PHONY: test-acceptance-webui
+test-acceptance-webui:
+	./ui/tests/run-acceptance-test.sh $(FEATURE_PATH)
+
+
+############ tooling ############
+ifneq (, $(shell which go 2> /dev/null)) # suppress `command not found warnings` for non go targets in CI
+include ../.bingo/Variables.mk
+endif
+
+############ go tooling ############
+include ../.make/go.mk
+
+############ release ############
+include ../.make/release.mk
+
+############ docs generate ############
+include ../.make/docs.mk
+
+############ l10n ############
+include ../.make/l10n.mk
+
+.PHONY: docs-generate
+docs-generate: config-docs-generate \
+			   grpc-docs-generate
+
+############ generate ############
+include ../.make/generate.mk
+
+.PHONY: ci-go-generate
+ci-go-generate: protobuf # CI runs ci-node-generate automatically before this target
+
+.PHONY: ci-node-generate
+ci-node-generate: yarn-build
+
+.PHONY: yarn-build
+yarn-build: node_modules
+	yarn lint
+	yarn test
+	yarn build
+
+.PHONY: node_modules
+node_modules:
+	yarn install --immutable
+
+############ protobuf ############
+include ../.make/protobuf.mk
+
+.PHONY: protobuf
+protobuf: buf-generate
diff --git a/audit/pkg/service/service.go b/audit/pkg/service/service.go
index 4f1f4b1aab2..905e251ee51 100644
--- a/audit/pkg/service/service.go
+++ b/audit/pkg/service/service.go
@@ -45,6 +45,22 @@ func StartAuditLogger(ctx context.Context, ch <-chan interface{}, log log.Logger
 			switch ev := i.(type) {
 			case events.ShareCreated:
 				auditEvent = types.ShareCreated(ev)
+			case events.LinkCreated:
+				auditEvent = types.LinkCreated(ev)
+			case events.ShareUpdated:
+				auditEvent = types.ShareUpdated(ev)
+			case events.LinkUpdated:
+				auditEvent = types.LinkUpdated(ev)
+			case events.ShareRemoved:
+				auditEvent = types.ShareRemoved(ev)
+			case events.LinkRemoved:
+				auditEvent = types.LinkRemoved(ev)
+			case events.ReceivedShareUpdated:
+				auditEvent = types.ReceivedShareUpdated(ev)
+			case events.LinkAccessed:
+				auditEvent = types.LinkAccessed(ev)
+			case events.LinkAccessFailed:
+				auditEvent = types.LinkAccessFailed(ev)
 			default:
 				log.Error().Interface("event", ev).Msg(fmt.Sprintf("can't handle event of type '%T'", ev))
 				continue
@@ -95,5 +111,20 @@ func Marshal(format string, log log.Logger) Marshaller {
 		return nil
 	case "json":
 		return json.Marshal
+	case "minimal":
+		return func(ev interface{}) ([]byte, error) {
+			b, err := json.Marshal(ev)
+			if err != nil {
+				return nil, err
+			}
+
+			m := make(map[string]interface{})
+			if err := json.Unmarshal(b, &m); err != nil {
+				return nil, err
+			}
+
+			format := fmt.Sprintf("%s)\n   %s", m["Action"], m["Message"])
+			return []byte(format), nil
+		}
 	}
 }
diff --git a/audit/pkg/types/constants.go b/audit/pkg/types/constants.go
new file mode 100644
index 00000000000..663996241dd
--- /dev/null
+++ b/audit/pkg/types/constants.go
@@ -0,0 +1,61 @@
+package types
+
+import "fmt"
+
+// short identifiers for audit actions
+const (
+	ActionShareCreated            = "file_shared"
+	ActionSharePermissionUpdated  = "share_permission_updated"
+	ActionShareDisplayNameUpdated = "share_name_updated"
+	ActionSharePasswordUpdated    = "share_password_updated"
+	ActionShareExpirationUpdated  = "share_expiration_updated"
+	ActionShareRemoved            = "file_unshared"
+	ActionShareAccepted           = "share_accepted"
+	ActionShareDeclined           = "share_declined"
+	ActionLinkAccessed            = "public_link_accessed"
+)
+
+// MessageShareCreated returns the human readable string that describes the action
+func MessageShareCreated(sharer, item, grantee string) string {
+	return fmt.Sprintf("user '%s' shared file '%s' with '%s'", sharer, item, grantee)
+}
+
+// MessageLinkCreated returns the human readable string that describes the action
+func MessageLinkCreated(sharer, item, shareid string) string {
+	return fmt.Sprintf("user '%s' created a public to file '%s' with id '%s'", sharer, item, shareid)
+}
+
+// MessageShareUpdated returns the human readable string that describes the action
+func MessageShareUpdated(sharer, shareID, fieldUpdated string) string {
+	return fmt.Sprintf("user '%s' updated field '%s' of share '%s'", sharer, fieldUpdated, shareID)
+}
+
+// MessageLinkUpdated returns the human readable string that describes the action
+func MessageLinkUpdated(sharer, shareid, fieldUpdated string) string {
+	return fmt.Sprintf("user '%s' updated field '%s' of public link '%s'", sharer, fieldUpdated, shareid)
+}
+
+// MessageShareRemoved returns the human readable string that describes the action
+func MessageShareRemoved(sharer, shareid, itemid string) string {
+	return fmt.Sprintf("share id:'%s' uid:'%s' item-id:'%s' was removed", shareid, sharer, itemid)
+}
+
+// MessageLinkRemoved returns the human readable string that describes the action
+func MessageLinkRemoved(shareid string) string {
+	return fmt.Sprintf("public link id:'%s' was removed", shareid)
+}
+
+// MessageShareAccepted returns the human readable string that describes the action
+func MessageShareAccepted(userid, shareid, sharerid string) string {
+	return fmt.Sprintf("user '%s' accepted share '%s' from user '%s'", userid, shareid, sharerid)
+}
+
+// MessageShareDeclined returns the human readable string that describes the action
+func MessageShareDeclined(userid, shareid, sharerid string) string {
+	return fmt.Sprintf("user '%s' declined share '%s' from user '%s'", userid, shareid, sharerid)
+}
+
+// MessageLinkAccessed returns the human readable string that describes the action
+func MessageLinkAccessed(linkid string, success bool) string {
+	return fmt.Sprintf("link '%s' was accessed. Success: %v", linkid, success)
+}
diff --git a/audit/pkg/types/conversion.go b/audit/pkg/types/conversion.go
index c4ab66f5e40..c90ab0eec43 100644
--- a/audit/pkg/types/conversion.go
+++ b/audit/pkg/types/conversion.go
@@ -5,16 +5,10 @@ import (
 	"time"
 
 	"github.com/cs3org/reva/v2/pkg/events"
-)
-
-// actions
-const (
-	actionShareCreated = "file_shared"
-)
 
-// messages
-const (
-	messageShareCreated = "user '%s' shared file '%s' with '%s'"
+	group "github.com/cs3org/go-cs3apis/cs3/identity/group/v1beta1"
+	user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
+	types "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
 )
 
 // BasicAuditEvent creates an AuditEvent from given values
@@ -37,39 +31,30 @@ func BasicAuditEvent(uid string, ctime string, msg string, action string) AuditE
 }
 
 // SharingAuditEvent creates an AuditEventSharing from given values
-func SharingAuditEvent(fileid string, uid string, base AuditEvent) AuditEventSharing {
+func SharingAuditEvent(shareid string, fileid string, uid string, base AuditEvent) AuditEventSharing {
 	return AuditEventSharing{
 		AuditEvent: base,
 		FileID:     fileid,
 		Owner:      uid,
+		ShareID:    shareid,
 
 		// NOTE: those values are not in the events and can therefore not be filled at the moment
-		ShareID: "",
-		Path:    "",
+		Path: "",
 	}
 }
 
 // ShareCreated converts a ShareCreated Event to an AuditEventShareCreated
 func ShareCreated(ev events.ShareCreated) AuditEventShareCreated {
-	with := ""
-	typ := ""
-	if ev.GranteeUserID != nil && ev.GranteeUserID.OpaqueId != "" {
-		with = ev.GranteeUserID.OpaqueId
-		typ = "user"
-	} else if ev.GranteeGroupID != nil && ev.GranteeGroupID.OpaqueId != "" {
-		with = ev.GranteeGroupID.OpaqueId
-		typ = "group"
-	}
 	uid := ev.Sharer.OpaqueId
-	t := time.Unix(int64(ev.CTime.Seconds), int64(ev.CTime.Nanos)).Format(time.RFC3339)
-	base := BasicAuditEvent(uid, t, fmt.Sprintf(messageShareCreated, uid, ev.ItemID.OpaqueId, with), actionShareCreated)
+	with, typ := extractGrantee(ev.GranteeUserID, ev.GranteeGroupID)
+	base := BasicAuditEvent(uid, formatTime(ev.CTime), MessageShareCreated(uid, ev.ItemID.OpaqueId, with), ActionShareCreated)
 	return AuditEventShareCreated{
-		AuditEventSharing: SharingAuditEvent(ev.ItemID.OpaqueId, uid, base),
+		AuditEventSharing: SharingAuditEvent("", ev.ItemID.OpaqueId, uid, base),
 		ShareOwner:        uid,
 		ShareWith:         with,
 		ShareType:         typ,
 
-		// NOTE: those values are not in the events and can therefore not be filled at the moment
+		// NOTE: those values are not in the event and can therefore not be filled at the moment
 		ItemType:       "",
 		ExpirationDate: "",
 		SharePass:      false,
@@ -77,3 +62,198 @@ func ShareCreated(ev events.ShareCreated) AuditEventShareCreated {
 		ShareToken:     "",
 	}
 }
+
+// LinkCreated converts a ShareCreated Event to an AuditEventShareCreated
+func LinkCreated(ev events.LinkCreated) AuditEventShareCreated {
+	uid := ev.Sharer.OpaqueId
+	with, typ := "", "link"
+	base := BasicAuditEvent(uid, formatTime(ev.CTime), MessageLinkCreated(uid, ev.ItemID.OpaqueId, ev.ShareID.OpaqueId), ActionShareCreated)
+	return AuditEventShareCreated{
+		AuditEventSharing: SharingAuditEvent("", ev.ItemID.OpaqueId, uid, base),
+		ShareOwner:        uid,
+		ShareWith:         with,
+		ShareType:         typ,
+		ExpirationDate:    formatTime(ev.Expiration),
+		SharePass:         ev.PasswordProtected,
+		Permissions:       ev.Permissions.String(),
+		ShareToken:        ev.Token,
+
+		// NOTE: those values are not in the event and can therefore not be filled at the moment
+		ItemType: "",
+	}
+}
+
+// ShareUpdated converts a ShareUpdated event to an AuditEventShareUpdated
+func ShareUpdated(ev events.ShareUpdated) AuditEventShareUpdated {
+	uid := ev.Sharer.OpaqueId
+	with, typ := extractGrantee(ev.GranteeUserID, ev.GranteeGroupID)
+	base := BasicAuditEvent(uid, formatTime(ev.MTime), MessageShareUpdated(uid, ev.ShareID.OpaqueId, ev.Updated), updateType(ev.Updated))
+	return AuditEventShareUpdated{
+		AuditEventSharing: SharingAuditEvent(ev.ShareID.GetOpaqueId(), ev.ItemID.OpaqueId, uid, base),
+		ShareOwner:        uid,
+		ShareWith:         with,
+		ShareType:         typ,
+		Permissions:       ev.Permissions.Permissions.String(),
+
+		// NOTE: those values are not in the event and can therefore not be filled at the moment
+		ItemType:       "",
+		ExpirationDate: "",
+		SharePass:      false,
+		ShareToken:     "",
+	}
+}
+
+// LinkUpdated converts a LinkUpdated event to an AuditEventShareUpdated
+func LinkUpdated(ev events.LinkUpdated) AuditEventShareUpdated {
+	uid := ev.Sharer.OpaqueId
+	with, typ := "", "link"
+	base := BasicAuditEvent(uid, formatTime(ev.CTime), MessageLinkUpdated(uid, ev.ShareID.OpaqueId, ev.FieldUpdated), updateType(ev.FieldUpdated))
+	return AuditEventShareUpdated{
+		AuditEventSharing: SharingAuditEvent(ev.ShareID.GetOpaqueId(), ev.ItemID.OpaqueId, uid, base),
+		ShareOwner:        uid,
+		ShareWith:         with,
+		ShareType:         typ,
+		Permissions:       ev.Permissions.Permissions.String(),
+		ExpirationDate:    formatTime(ev.Expiration),
+		SharePass:         ev.PasswordProtected,
+		ShareToken:        ev.Token,
+
+		// NOTE: those values are not in the event and can therefore not be filled at the moment
+		ItemType: "",
+	}
+}
+
+// ShareRemoved converts a ShareRemoved event to an AuditEventShareRemoved
+func ShareRemoved(ev events.ShareRemoved) AuditEventShareRemoved {
+	sid, uid, iid, with, typ := "", "", "", "", ""
+	if ev.ShareID != nil {
+		sid = ev.ShareID.GetOpaqueId()
+	}
+
+	if ev.ShareKey != nil {
+		uid = ev.ShareKey.GetOwner().GetOpaqueId()
+		iid = ev.ShareKey.GetResourceId().GetOpaqueId()
+		with, typ = extractGrantee(ev.ShareKey.GetGrantee().GetUserId(), ev.ShareKey.GetGrantee().GetGroupId())
+	}
+	base := BasicAuditEvent(uid, "", MessageShareRemoved(uid, sid, iid), ActionShareRemoved)
+	return AuditEventShareRemoved{
+		AuditEventSharing: SharingAuditEvent(sid, iid, uid, base),
+		ShareWith:         with,
+		ShareType:         typ,
+
+		// NOTE: those values are not in the event and can therefore not be filled at the moment
+		ItemType: "",
+	}
+}
+
+// LinkRemoved converts a LinkRemoved event to an AuditEventShareRemoved
+func LinkRemoved(ev events.LinkRemoved) AuditEventShareRemoved {
+	uid, sid, typ := "", "", "link"
+	if ev.ShareID != nil {
+		sid = ev.ShareID.GetOpaqueId()
+	} else {
+		sid = ev.ShareToken
+	}
+
+	base := BasicAuditEvent(uid, "", MessageLinkRemoved(sid), ActionShareRemoved)
+	return AuditEventShareRemoved{
+		AuditEventSharing: SharingAuditEvent(sid, "", uid, base),
+		ShareWith:         "",
+		ShareType:         typ,
+
+		// NOTE: those values are not in the event and can therefore not be filled at the moment
+		ItemType: "",
+	}
+}
+
+// ReceivedShareUpdated converts a ReceivedShareUpdated event to an AuditEventReceivedShareUpdated
+func ReceivedShareUpdated(ev events.ReceivedShareUpdated) AuditEventReceivedShareUpdated {
+	uid := ev.Sharer.GetOpaqueId()
+	sid := ev.ShareID.GetOpaqueId()
+	with, typ := extractGrantee(ev.GranteeUserID, ev.GranteeGroupID)
+	itemID := ev.ItemID.GetOpaqueId()
+
+	msg, utype := "", ""
+	switch ev.State {
+	case "SHARE_STATE_ACCEPTED":
+		msg = MessageShareAccepted(with, sid, uid)
+		utype = ActionShareAccepted
+	case "SHARE_STATE_DECLINED":
+		msg = MessageShareDeclined(with, sid, uid)
+		utype = ActionShareDeclined
+	}
+	base := BasicAuditEvent(with, formatTime(ev.MTime), msg, utype)
+	return AuditEventReceivedShareUpdated{
+		AuditEventSharing: SharingAuditEvent(sid, itemID, uid, base),
+		ShareType:         typ,
+		ShareWith:         with,
+
+		// NOTE: those values are not in the event and can therefore not be filled at the moment
+		ItemType: "",
+	}
+}
+
+// LinkAccessed converts a LinkAccessed event to an AuditEventLinkAccessed
+func LinkAccessed(ev events.LinkAccessed) AuditEventLinkAccessed {
+	uid := ev.Sharer.OpaqueId
+	base := BasicAuditEvent(uid, formatTime(ev.CTime), MessageLinkAccessed(ev.ShareID.GetOpaqueId(), true), ActionLinkAccessed)
+	return AuditEventLinkAccessed{
+		AuditEventSharing: SharingAuditEvent(ev.ShareID.GetOpaqueId(), ev.ItemID.OpaqueId, uid, base),
+		ShareToken:        ev.Token,
+		Success:           true,
+
+		// NOTE: those values are not in the event and can therefore not be filled at the moment
+		ItemType: "",
+	}
+}
+
+// LinkAccessFailed converts a LinkAccessFailed event to an AuditEventLinkAccessed
+func LinkAccessFailed(ev events.LinkAccessFailed) AuditEventLinkAccessed {
+	base := BasicAuditEvent("", "", MessageLinkAccessed(ev.ShareID.GetOpaqueId(), false), ActionLinkAccessed)
+	return AuditEventLinkAccessed{
+		AuditEventSharing: SharingAuditEvent(ev.ShareID.GetOpaqueId(), "", "", base),
+		ShareToken:        ev.Token,
+		Success:           false,
+
+		// NOTE: those values are not in the event and can therefore not be filled at the moment
+		ItemType: "",
+	}
+}
+
+func extractGrantee(uid *user.UserId, gid *group.GroupId) (string, string) {
+	switch {
+	case uid != nil && uid.OpaqueId != "":
+		return uid.OpaqueId, "user"
+	case gid != nil && gid.OpaqueId != "":
+		return gid.OpaqueId, "group"
+	}
+
+	return "", ""
+}
+
+func formatTime(t *types.Timestamp) string {
+	if t == nil {
+		return ""
+	}
+	return time.Unix(int64(t.Seconds), int64(t.Nanos)).UTC().Format(time.RFC3339)
+}
+
+func updateType(u string) string {
+	switch {
+	case u == "permissions":
+		return ActionSharePermissionUpdated
+	case u == "displayname":
+		return ActionShareDisplayNameUpdated
+	case u == "TYPE_PERMISSIONS":
+		return ActionSharePermissionUpdated
+	case u == "TYPE_DISPLAYNAME":
+		return ActionShareDisplayNameUpdated
+	case u == "TYPE_PASSWORD":
+		return ActionSharePasswordUpdated
+	case u == "TYPE_EXPIRATION":
+		return ActionShareExpirationUpdated
+	default:
+		fmt.Println("Unknown update type", u)
+		return ""
+	}
+}
diff --git a/audit/pkg/types/events.go b/audit/pkg/types/events.go
index 7a9825ef0f5..801dd41790d 100644
--- a/audit/pkg/types/events.go
+++ b/audit/pkg/types/events.go
@@ -8,5 +8,13 @@ import (
 func RegisteredEvents() []events.Unmarshaller {
 	return []events.Unmarshaller{
 		events.ShareCreated{},
+		events.ShareUpdated{},
+		events.LinkCreated{},
+		events.LinkUpdated{},
+		events.ShareRemoved{},
+		events.LinkRemoved{},
+		events.ReceivedShareUpdated{},
+		events.LinkAccessed{},
+		events.LinkAccessFailed{},
 	}
 }
diff --git a/audit/pkg/types/types.go b/audit/pkg/types/types.go
index cd07e994f08..17e2d0a3e16 100644
--- a/audit/pkg/types/types.go
+++ b/audit/pkg/types/types.go
@@ -38,3 +38,41 @@ type AuditEventShareCreated struct {
 	ShareOwner     string // The UID of the share owner.
 	ShareToken     string // For link shares the unique token, else null
 }
+
+// AuditEventShareUpdated is the event logged when a share is updated
+type AuditEventShareUpdated struct {
+	AuditEventSharing
+
+	ItemType       string // file or folder
+	ExpirationDate string // The text expiration date in format 'yyyy-mm-dd'
+	SharePass      bool   // If the share is password protected.
+	Permissions    string // The permissions string eg: "READ"
+	ShareType      string // group user or link
+	ShareWith      string // The UID or GID of the share recipient. (not available for public link)
+	ShareOwner     string // The UID of the share owner.
+	ShareToken     string // For link shares the unique token, else null
+}
+
+// AuditEventShareRemoved is the event logged when a share is removed
+type AuditEventShareRemoved struct {
+	AuditEventSharing
+	ItemType  string // file or folder
+	ShareType string // group user or link
+	ShareWith string // The UID or GID of the share recipient.
+}
+
+// AuditEventReceivedShareUpdated is the event logged when a share is accepted or declined
+type AuditEventReceivedShareUpdated struct {
+	AuditEventSharing
+	ItemType  string // file or folder
+	ShareType string // group user or link
+	ShareWith string // The UID or GID of the share recipient.
+}
+
+// AuditEventLinkAccessed is the event logged when a link is accessed
+type AuditEventLinkAccessed struct {
+	AuditEventSharing
+	ShareToken string // The share token.
+	Success    bool   // If the request was successful.
+	ItemType   string // file or folder
+}
diff --git a/changelog/unreleased/fix-network-on-individual-services.md b/changelog/unreleased/fix-network-on-individual-services.md
deleted file mode 100644
index 3f7d42b69df..00000000000
--- a/changelog/unreleased/fix-network-on-individual-services.md
+++ /dev/null
@@ -1,5 +0,0 @@
-Bugfix: Network configuration in individiual_services example
-
-Tidy up the deployments/examples/ocis_individual_services example so that the instructions work.
-
-https://github.com/owncloud/ocis/pull/3238
diff --git a/changelog/unreleased/gif-thumbnails.md b/changelog/unreleased/gif-thumbnails.md
deleted file mode 100644
index 188d8f5bdb9..00000000000
--- a/changelog/unreleased/gif-thumbnails.md
+++ /dev/null
@@ -1,5 +0,0 @@
-Bugfix: Improve gif thumbnails
-
-Improved the gif thumbnail generation for gifs with different disposal strategies.
-
-https://github.com/owncloud/ocis/pull/3305
diff --git a/changelog/unreleased/sharing-audit-events.md b/changelog/unreleased/sharing-audit-events.md
new file mode 100644
index 00000000000..5065e2d8351
--- /dev/null
+++ b/changelog/unreleased/sharing-audit-events.md
@@ -0,0 +1,5 @@
+Enhancement: log sharing events in audit service
+
+Contains sharing related events. See full list in audit/pkg/types/events.go
+
+https://github.com/owncloud/ocis/pull/3301
diff --git a/deployments/examples/ocis_individual_services/docker-compose.yml b/deployments/examples/ocis_individual_services/docker-compose.yml
index dda52fb6359..27ec4754325 100644
--- a/deployments/examples/ocis_individual_services/docker-compose.yml
+++ b/deployments/examples/ocis_individual_services/docker-compose.yml
@@ -47,7 +47,7 @@ services:
     deploy:
       replicas: ${OCIS_SCALE:-1}
     networks:
-      ocis-net:
+      ocis-net: null
     entrypoint:
       - ocis
       - proxy
@@ -90,7 +90,7 @@ services:
     deploy:
       replicas: 1
     networks:
-      ocis-net:
+      ocis-net: null
     entrypoint:
       - ocis
       - nats-server
@@ -111,7 +111,7 @@ services:
     deploy:
       replicas: 1
     networks:
-      ocis-net:
+      ocis-net: null
     entrypoint:
       - /bin/sh
       - /entrypoint-override.sh
@@ -145,7 +145,7 @@ services:
     deploy:
       replicas: ${OCIS_SCALE:-1}
     networks:
-      ocis-net:
+      ocis-net: null
     entrypoint:
       - ocis
       - glauth
@@ -168,7 +168,7 @@ services:
     deploy:
       replicas: 1
     networks:
-      ocis-net:
+      ocis-net: null
     entrypoint:
       - ocis
       - idp
@@ -194,7 +194,7 @@ services:
     deploy:
       replicas: ${OCIS_SCALE:-1}
     networks:
-      ocis-net:
+      ocis-net: null
     entrypoint:
       - ocis
       - ocs
@@ -222,7 +222,7 @@ services:
     deploy:
       replicas: 1
     networks:
-      ocis-net:
+      ocis-net: null
     entrypoint:
       - ocis
       - settings
@@ -247,7 +247,7 @@ services:
     deploy:
       replicas: 1
     networks:
-      ocis-net:
+      ocis-net: null
     entrypoint:
       - ocis
       - store
@@ -269,7 +269,7 @@ services:
     deploy:
       replicas: ${OCIS_SCALE:-1}
     networks:
-      ocis-net:
+      ocis-net: null
     entrypoint:
       - ocis
       - thumbnails
@@ -296,7 +296,7 @@ services:
     deploy:
       replicas: ${OCIS_SCALE:-1}
     networks:
-      ocis-net:
+      ocis-net: null
     entrypoint:
       - ocis
       - web
@@ -320,7 +320,7 @@ services:
     deploy:
       replicas: ${OCIS_SCALE:-1}
     networks:
-      ocis-net:
+      ocis-net: null
     entrypoint:
       - ocis
       - webdav
@@ -343,7 +343,7 @@ services:
     deploy:
       replicas: ${OCIS_SCALE:-1}
     networks:
-      ocis-net:
+      ocis-net: null
     entrypoint:
       - ocis
       - graph
@@ -369,7 +369,7 @@ services:
     deploy:
       replicas: 1
     networks:
-      ocis-net:
+      ocis-net: null
     entrypoint:
       - ocis
       - storage-metadata
@@ -402,7 +402,7 @@ services:
     deploy:
       replicas: ${OCIS_SCALE:-1}
     networks:
-      ocis-net:
+      ocis-net: null
     entrypoint:
       - ocis
       - storage-auth-basic
@@ -426,7 +426,7 @@ services:
     deploy:
       replicas: ${OCIS_SCALE:-1}
     networks:
-      ocis-net:
+      ocis-net: null
     entrypoint:
       - ocis
       - storage-auth-machine
@@ -450,7 +450,7 @@ services:
     deploy:
       replicas: ${OCIS_SCALE:-1}
     networks:
-      ocis-net:
+      ocis-net: null
     entrypoint:
       - ocis
       - storage-auth-bearer
@@ -474,7 +474,7 @@ services:
     deploy:
       replicas: ${OCIS_SCALE:-1}
     networks:
-      ocis-net:
+      ocis-net: null
     entrypoint:
       - ocis
       - storage-shares
@@ -501,7 +501,7 @@ services:
     deploy:
       replicas: 1
     networks:
-      ocis-net:
+      ocis-net: null
     entrypoint:
       - ocis
       - storage-users
@@ -535,7 +535,7 @@ services:
     deploy:
       replicas: ${OCIS_SCALE:-1}
     networks:
-      ocis-net:
+      ocis-net: null
     entrypoint:
       - ocis
       - storage-public-link
@@ -559,7 +559,7 @@ services:
     deploy:
       replicas: 1
     networks:
-      ocis-net:
+      ocis-net: null
     entrypoint:
       - ocis
       - storage-sharing
@@ -592,7 +592,7 @@ services:
     deploy:
       replicas: ${OCIS_SCALE:-1}
     networks:
-      ocis-net:
+      ocis-net: null
     entrypoint:
       - ocis
       - storage-userprovider
@@ -623,7 +623,7 @@ services:
     deploy:
       replicas: ${OCIS_SCALE:-1}
     networks:
-      ocis-net:
+      ocis-net: null
     entrypoint:
       - ocis
       - storage-groupprovider
@@ -654,7 +654,7 @@ services:
     deploy:
       replicas: ${OCIS_SCALE:-1}
     networks:
-      ocis-net:
+      ocis-net: null
     entrypoint:
       - ocis
       - storage-frontend
@@ -684,7 +684,7 @@ services:
     deploy:
       replicas: ${OCIS_SCALE:-1}
     networks:
-      ocis-net:
+      ocis-net: null
     entrypoint:
       - ocis
       - storage-gateway
@@ -731,3 +731,4 @@ volumes:
 
 networks:
   ocis-net:
+    external: true
diff --git a/docs/ocis/deployment/basic-remote-setup.md b/docs/ocis/deployment/basic-remote-setup.md
index 4227a88e1f1..efa76e1fdf5 100644
--- a/docs/ocis/deployment/basic-remote-setup.md
+++ b/docs/ocis/deployment/basic-remote-setup.md
@@ -15,12 +15,10 @@ If you need to access oCIS running in a docker container, on a VM or a remote ma
 
 ## Start the oCIS fullstack server from binary
 
-Upon first start of the oCIS fullstack server with `./bin/ocis server` it will generate a directory tree skeleton in `$HOME/.ocis`. If that is already existing it will not be overwritten as it contains all relevant data for oCIS.
-
-In `$HOME/.ocis/idp` is a file `identifier-registration.yaml`. It is used to configure the built-in identity provider and therefore contains the OpenID Connect issuer and also information about relying parties, for example ownCloud Web and our desktop and mobile applications.
+Upon first start of the oCIS fullstack server with `./bin/ocis server` it will generate a file `identifier-registration.yml` in the config folder in your current working directory. This file is used to configure the built-in identity provider and therefore contains the OpenID Connect issuer and also information about relying parties, for example ownCloud Web and our desktop and mobile applications.
 
 {{< hint warning >}}
-The `identifier-registration.yaml` file will only be generated if it does not exist yet. If you want to change certain environment variables like `OCIS_URL`, please delete this file first before doing so. Otherwise your changes will not be applied correctly and you will run into errors.
+The `identifier-registration.yml` file will only be generated if it does not exist yet. If you want to change certain environment variables like `OCIS_URL`, please delete this file first before doing so. Otherwise your changes will not be applied correctly and you will run into errors.
 {{< /hint >}}
 
 {{< hint warning >}}
diff --git a/docs/ocis/deployment/bridge.md b/docs/ocis/deployment/bridge.md
index 2551ac0440f..b291b1bfde1 100644
--- a/docs/ocis/deployment/bridge.md
+++ b/docs/ocis/deployment/bridge.md
@@ -92,9 +92,9 @@ basedn = "dc=ocis,dc=test"                               # base dn to construct
 
 {{< hint >}}
 There is a bug in the config merging for environment variables, cli flags and config files causing log settings not to be picked up from the config file when specifying `--extensions`. That is why I will
-* configure most of the config in a file,
+* configure most of the config in a file, 
 * adjust logging using `OCIS_LOG_*` environment variables and
-* specify which extension to run using `ocis/bin/ocis server --extensions "comma, separated, list, of, extensions"`.
+* specify which extension to run using `ocis/bin/ocis server --extensions "comma, separated, list, of, extensions"`. 
 {{< /hint >}}
 
 #### Run it!
@@ -129,7 +129,7 @@ To configure LDAP to use our glauth we add this section to the config file:
 ```toml
 [storage.reva.ldap]
 idp = "https://ocis.ocis.test"
-basedn = "dc=ocis,dc=test"
+basedn = "dc=ocis,dc=test" 
 binddn = "cn=admin,dc=ocis,dc=test" # an admin user in your oc10
 bindpassword = "secret"
 userschema = { uid = "uid", displayname = "givenname" } # TODO make glauth return an ownclouduuid and displayname attribute
@@ -158,7 +158,7 @@ Please use `exit` or `Ctrl-D` to exit this program.
 username: jfd
 password: OK
 >> whoami
-id:<idp:"https://ocis.ocis.test" opaque_id:"jfd" type:USER_TYPE_PRIMARY > username:"jfd" mail:"jfd@butonic.de" display_name:"J\303\266rn" uid_number:99 gid_number:99
+id:<idp:"https://ocis.ocis.test" opaque_id:"jfd" type:USER_TYPE_PRIMARY > username:"jfd" mail:"jfd@butonic.de" display_name:"J\303\266rn" uid_number:99 gid_number:99 
 >> exit
 ```
 
diff --git a/docs/ocis/getting-started/demo-users.md b/docs/ocis/getting-started/demo-users.md
index 2023d4c6e1b..39da4f92c43 100644
--- a/docs/ocis/getting-started/demo-users.md
+++ b/docs/ocis/getting-started/demo-users.md
@@ -16,13 +16,12 @@ To skip the generation of demo users, run the inital setup step with an addition
 
 Following users are available in the demo set:
 
-| username  | password      | email                 | role                | groups                                                                  |
-| --------- | ------------- | --------------------- | ------------------- | ----------------------------------------------------------------------- |
-| admin     | admin         | admin@example.org     | admin               | users                                                                   |
-| einstein  | relativity    | einstein@example.org  | user                | users, philosophy-haters, physics-lovers, sailing-lovers, violin-haters |
-| marie     | radioactivity | marie@example.org     | user                | users, physics-lovers, polonium-lovers, radium-lovers                   |
-| moss      | vista         | moss@example.org      | admin               | users                                                                   |
-| richard   | superfluidity | richard@example.org   | user                | users, philosophy-haters, physics-lovers, quantum-lovers                |
-| katherine | gemini        | katherine@example.org | user, space-manager | users, sailing-lovers, physics-lovers, quantum-lovers                   |
+| username | password      | email                | role  | groups                                                                  |
+| -------- | ------------- | -------------------- | ----- | ----------------------------------------------------------------------- |
+| admin    | admin         | admin@example.org    | admin | users                                                                   |
+| einstein | relativity    | einstein@example.org | user  | users, philosophy-haters, physics-lovers, sailing-lovers, violin-haters |
+| marie    | radioactivity | marie@example.org    | user  | users, physics-lovers, polonium-lovers, radium-lovers                   |
+| moss     | vista         | moss@example.org     | admin | users                                                                   |
+| richard  | superfluidity | richard@example.org  | user  | users, philosophy-haters, physics-lovers, quantum-lovers                |
 
 You may also want to run oCIS with only your custom users by [deleting the demo users]({{< ref "../deployment#delete-demo-users" >}}).
diff --git a/go.mod b/go.mod
index 829dead3e48..c07f3109e2b 100644
--- a/go.mod
+++ b/go.mod
@@ -22,7 +22,7 @@ require (
 	github.com/blevesearch/bleve/v2 v2.3.1
 	github.com/coreos/go-oidc/v3 v3.1.0
 	github.com/cs3org/go-cs3apis v0.0.0-20220126114148-64c025ccdd19
-	github.com/cs3org/reva/v2 v2.0.0-20220304131900-b8be80d1ba81
+	github.com/cs3org/reva/v2 v2.0.0-20220314085001-8e5b22a20a3f
 	github.com/disintegration/imaging v1.6.2
 	github.com/glauth/glauth/v2 v2.0.0-20211021011345-ef3151c28733
 	github.com/go-chi/chi/v5 v5.0.7
diff --git a/go.sum b/go.sum
index ac07e635c50..a4f60af138b 100644
--- a/go.sum
+++ b/go.sum
@@ -342,8 +342,8 @@ github.com/crewjam/saml v0.4.5/go.mod h1:qCJQpUtZte9R1ZjUBcW8qtCNlinbO363ooNl02S
 github.com/cs3org/cato v0.0.0-20200828125504-e418fc54dd5e/go.mod h1:XJEZ3/EQuI3BXTp/6DUzFr850vlxq11I6satRtz0YQ4=
 github.com/cs3org/go-cs3apis v0.0.0-20220126114148-64c025ccdd19 h1:1jqPH58jCxvbaJ9WLIJ7W2/m622bWS6ChptzljSG6IQ=
 github.com/cs3org/go-cs3apis v0.0.0-20220126114148-64c025ccdd19/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY=
-github.com/cs3org/reva/v2 v2.0.0-20220304131900-b8be80d1ba81 h1:g6c1HYGTSpDnf6uNPXYIOySVk0P545zWUPmdPWEcMps=
-github.com/cs3org/reva/v2 v2.0.0-20220304131900-b8be80d1ba81/go.mod h1:XNtK1HEClNzmz5vyQa2DUw4KH3oqBjQoEsV1LhAGlV0=
+github.com/cs3org/reva/v2 v2.0.0-20220314085001-8e5b22a20a3f h1:tv7v6OjbFoDFNB2ikGC+LLaWEOIAJnrZjyO5LRTDL0g=
+github.com/cs3org/reva/v2 v2.0.0-20220314085001-8e5b22a20a3f/go.mod h1:XNtK1HEClNzmz5vyQa2DUw4KH3oqBjQoEsV1LhAGlV0=
 github.com/cubewise-code/go-mime v0.0.0-20200519001935-8c5762b177d8 h1:Z9lwXumT5ACSmJ7WGnFl+OMLLjpz5uR2fyz7dC255FI=
 github.com/cubewise-code/go-mime v0.0.0-20200519001935-8c5762b177d8/go.mod h1:4abs/jPXcmJzYoYGF91JF9Uq9s/KL5n1jvFDix8KcqY=
 github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4=
diff --git a/settings/pkg/service/v0/settings.go b/settings/pkg/service/v0/settings.go
index 07dd4887e8a..338e4d44daa 100644
--- a/settings/pkg/service/v0/settings.go
+++ b/settings/pkg/service/v0/settings.go
@@ -12,9 +12,6 @@ const (
 	// BundleUUIDRoleAdmin represents the admin role
 	BundleUUIDRoleAdmin = "71881883-1768-46bd-a24d-a356a2afdf7f"
 
-	// BundleUUIDRoleSpaceManager represents the space manager role
-	BundleUUIDRoleSpaceManager = "2aadd357-682c-406b-8874-293091995fdd"
-
 	// BundleUUIDRoleUser represents the user role.
 	BundleUUIDRoleUser = "d7beeea8-8ff4-406b-8fb6-ab2dd81e6b11"
 
@@ -66,7 +63,6 @@ const (
 func generateBundlesDefaultRoles() []*settingsmsg.Bundle {
 	return []*settingsmsg.Bundle{
 		generateBundleAdminRole(),
-		generateBundleSpaceManagerRole(),
 		generateBundleUserRole(),
 		generateBundleGuestRole(),
 		generateBundleProfileRequest(),
@@ -87,20 +83,6 @@ func generateBundleAdminRole() *settingsmsg.Bundle {
 	}
 }
 
-func generateBundleSpaceManagerRole() *settingsmsg.Bundle {
-	return &settingsmsg.Bundle{
-		Id:          BundleUUIDRoleSpaceManager,
-		Name:        "spacemanager",
-		Type:        settingsmsg.Bundle_TYPE_ROLE,
-		Extension:   "ocis-roles",
-		DisplayName: "Spacemanager",
-		Resource: &settingsmsg.Resource{
-			Type: settingsmsg.Resource_TYPE_SYSTEM,
-		},
-		Settings: []*settingsmsg.Setting{},
-	}
-}
-
 func generateBundleUserRole() *settingsmsg.Bundle {
 	return &settingsmsg.Bundle{
 		Id:          BundleUUIDRoleUser,
@@ -441,97 +423,6 @@ func generatePermissionRequests() []*settingssvc.AddSettingToBundleRequest {
 				},
 			},
 		},
-		{
-			BundleId: BundleUUIDRoleSpaceManager,
-			Setting: &settingsmsg.Setting{
-				Id:          CreateSpacePermissionID,
-				Name:        CreateSpacePermissionName,
-				DisplayName: "Create Space",
-				Description: "This permission allows to create new spaces.",
-				Resource: &settingsmsg.Resource{
-					Type: settingsmsg.Resource_TYPE_SYSTEM,
-				},
-				Value: &settingsmsg.Setting_PermissionValue{
-					PermissionValue: &settingsmsg.Permission{
-						Operation:  settingsmsg.Permission_OPERATION_READWRITE,
-						Constraint: settingsmsg.Permission_CONSTRAINT_ALL,
-					},
-				},
-			},
-		},
-		{
-			BundleId: BundleUUIDRoleSpaceManager,
-			Setting: &settingsmsg.Setting{
-				Id:          SetSpaceQuotaPermissionID,
-				Name:        SetSpaceQuotaPermissionName,
-				DisplayName: "Set Space Quota",
-				Description: "This permission allows to manage space quotas.",
-				Resource: &settingsmsg.Resource{
-					Type: settingsmsg.Resource_TYPE_SYSTEM,
-				},
-				Value: &settingsmsg.Setting_PermissionValue{
-					PermissionValue: &settingsmsg.Permission{
-						Operation:  settingsmsg.Permission_OPERATION_READWRITE,
-						Constraint: settingsmsg.Permission_CONSTRAINT_ALL,
-					},
-				},
-			},
-		},
-		{
-			BundleId: BundleUUIDRoleSpaceManager,
-			Setting: &settingsmsg.Setting{
-				Id:          ListAllSpacesPermissionID,
-				Name:        ListAllSpacesPermissionName,
-				DisplayName: "List All Spaces",
-				Description: "This permission allows list all spaces.",
-				Resource: &settingsmsg.Resource{
-					Type: settingsmsg.Resource_TYPE_SYSTEM,
-				},
-				Value: &settingsmsg.Setting_PermissionValue{
-					PermissionValue: &settingsmsg.Permission{
-						Operation:  settingsmsg.Permission_OPERATION_READ,
-						Constraint: settingsmsg.Permission_CONSTRAINT_ALL,
-					},
-				},
-			},
-		},
-		{
-			BundleId: BundleUUIDRoleSpaceManager,
-			Setting: &settingsmsg.Setting{
-				Id:          "640e00d2-4df8-41bd-b1c2-9f30a01e0e99",
-				Name:        "language-readwrite",
-				DisplayName: "Permission to read and set the language (self)",
-				Resource: &settingsmsg.Resource{
-					Type: settingsmsg.Resource_TYPE_SETTING,
-					Id:   settingUUIDProfileLanguage,
-				},
-				Value: &settingsmsg.Setting_PermissionValue{
-					PermissionValue: &settingsmsg.Permission{
-						Operation:  settingsmsg.Permission_OPERATION_READWRITE,
-						Constraint: settingsmsg.Permission_CONSTRAINT_OWN,
-					},
-				},
-			},
-		},
-		{
-			BundleId: BundleUUIDRoleSpaceManager,
-			Setting: &settingsmsg.Setting{
-				Id:          SelfManagementPermissionID,
-				Name:        SelfManagementPermissionName,
-				DisplayName: "Self Management",
-				Description: "This permission gives access to self management.",
-				Resource: &settingsmsg.Resource{
-					Type: settingsmsg.Resource_TYPE_USER,
-					Id:   "me",
-				},
-				Value: &settingsmsg.Setting_PermissionValue{
-					PermissionValue: &settingsmsg.Permission{
-						Operation:  settingsmsg.Permission_OPERATION_READWRITE,
-						Constraint: settingsmsg.Permission_CONSTRAINT_OWN,
-					},
-				},
-			},
-		},
 		{
 			BundleId: BundleUUIDRoleMetadata,
 			Setting: &settingsmsg.Setting{
@@ -556,6 +447,7 @@ func generatePermissionRequests() []*settingssvc.AddSettingToBundleRequest {
 func defaultRoleAssignments() []*settingsmsg.UserRoleAssignment {
 	return []*settingsmsg.UserRoleAssignment{
 		// accounts service user for the metadata user is allowed to create spaces
+
 		{
 			AccountUuid: "95cb8724-03b2-11eb-a0a6-c33ef8ef53ad",
 			RoleId:      BundleUUIDRoleAdmin,
@@ -584,14 +476,6 @@ func defaultRoleAssignments() []*settingsmsg.UserRoleAssignment {
 		}, {
 			AccountUuid: "932b4540-8d16-481e-8ef4-588e4b6b151c",
 			RoleId:      BundleUUIDRoleUser,
-		}, {
-			AccountUuid: "534bb038-6f9d-4093-946f-133be61fa4e7",
-			RoleId:      BundleUUIDRoleUser,
-		},
-		// default users with role "spacemanager"
-		{
-			AccountUuid: "534bb038-6f9d-4093-946f-133be61fa4e7",
-			RoleId:      BundleUUIDRoleSpaceManager,
 		},
 	}
 }
diff --git a/thumbnails/pkg/thumbnail/generator.go b/thumbnails/pkg/thumbnail/generator.go
index b22c15da458..6bea9b87a3b 100644
--- a/thumbnails/pkg/thumbnail/generator.go
+++ b/thumbnails/pkg/thumbnail/generator.go
@@ -3,7 +3,6 @@ package thumbnail
 import (
 	"errors"
 	"image"
-	"image/color"
 	"image/draw"
 	"image/gif"
 	"strings"
@@ -36,44 +35,22 @@ func (g SimpleGenerator) GenerateThumbnail(size image.Rectangle, img interface{}
 type GifGenerator struct{}
 
 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, ErrInvalidType2
 	}
-	// Create a new RGBA image to hold the incremental frames.
-	srcX, srcY := m.Config.Width, m.Config.Height
-	b := image.Rect(0, 0, srcX, srcY)
-	tmp := image.NewRGBA(b)
-
-	for i, frame := range m.Image {
-		bounds := frame.Bounds()
-		prev := tmp
-		draw.Draw(tmp, bounds, frame, bounds.Min, draw.Over)
-		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:
-			tmp = image.NewRGBA(b)
-		case gif.DisposalPrevious:
-			tmp = prev
-		}
+	var bounds image.Rectangle
+	for i := range m.Image {
+		img := imaging.Resize(m.Image[i], size.Dx(), size.Dy(), imaging.Lanczos)
+		bounds = image.Rect(0, 0, size.Dx(), size.Dy())
+		m.Image[i] = image.NewPaletted(bounds, m.Image[i].Palette)
+		draw.Draw(m.Image[i], bounds, img, image.Pt(0, 0), draw.Src)
 	}
-	m.Config.Width = size.Dx()
-	m.Config.Height = size.Dy()
-
+	m.Config.Height = bounds.Dy()
+	m.Config.Width = bounds.Dx()
 	return m, nil
 }
 
-func (g GifGenerator) imageToPaletted(img image.Image, p color.Palette) *image.Paletted {
-	b := img.Bounds()
-	pm := image.NewPaletted(b, p)
-	draw.FloydSteinberg.Draw(pm, b, img, image.Point{})
-	return pm
-}
-
 // GeneratorForType returns the generator for a given file type
 // or nil if the type is not supported.
 func GeneratorForType(fileType string) (Generator, error) {


Test patch:
diff --git a/audit/pkg/service/service_test.go b/audit/pkg/service/service_test.go
index 0724acc3975..8bdcac5cd45 100644
--- a/audit/pkg/service/service_test.go
+++ b/audit/pkg/service/service_test.go
@@ -12,6 +12,8 @@ import (
 
 	group "github.com/cs3org/go-cs3apis/cs3/identity/group/v1beta1"
 	user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
+	collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1"
+	link "github.com/cs3org/go-cs3apis/cs3/sharing/link/v1beta1"
 	provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
 	rtypes "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
 )
@@ -22,37 +24,275 @@ var testCases = []struct {
 	CheckAuditEvent func(*testing.T, []byte)
 }{
 	{
-		Alias: "ShareCreated",
+		Alias: "ShareCreated - user",
 		SystemEvent: events.ShareCreated{
-			Sharer: &user.UserId{
-				OpaqueId: "sharing-userid",
-				Idp:      "idp",
-			},
-			GranteeUserID: &user.UserId{
-				OpaqueId: "beshared-userid",
-				Idp:      "idp",
-			},
-			GranteeGroupID: &group.GroupId{},
-			Sharee:         &provider.Grantee{},
-			ItemID: &provider.ResourceId{
-				StorageId: "storage-1",
-				OpaqueId:  "itemid-1",
-			},
-			CTime: &rtypes.Timestamp{
-				Seconds: 0,
-				Nanos:   0,
-			},
+			Sharer:         userID("sharing-userid"),
+			GranteeUserID:  userID("beshared-userid"),
+			GranteeGroupID: nil,
+			ItemID:         resourceID("storage-1", "itemid-1"),
+			CTime:          timestamp(0),
 		},
 		CheckAuditEvent: func(t *testing.T, b []byte) {
 			ev := types.AuditEventShareCreated{}
-			err := json.Unmarshal(b, &ev)
-			require.NoError(t, err)
+			require.NoError(t, json.Unmarshal(b, &ev))
 
-			require.Equal(t, ev.User, "sharing-userid")
-			require.Equal(t, ev.ShareWith, "beshared-userid")
-			require.Equal(t, ev.FileID, "itemid-1")
-			require.Equal(t, ev.Time, "1970-01-01T01:00:00+01:00")
+			// AuditEvent fields
+			checkBaseAuditEvent(t, ev.AuditEvent, "sharing-userid", "1970-01-01T00:00:00Z", "user 'sharing-userid' shared file 'itemid-1' with 'beshared-userid'", "file_shared")
+			// AuditEventSharing fields
+			checkSharingAuditEvent(t, ev.AuditEventSharing, "itemid-1", "sharing-userid", "")
+			// AuditEventShareCreated fields
+			require.Equal(t, "", ev.ItemType)
+			require.Equal(t, "", ev.ExpirationDate)
+			require.Equal(t, false, ev.SharePass)
+			//require.Equal(t, "stat:true ", ev.Permissions) // TODO: BUG! Should work
+			require.Equal(t, "user", ev.ShareType)
+			require.Equal(t, "beshared-userid", ev.ShareWith)
+			require.Equal(t, "sharing-userid", ev.ShareOwner)
+			require.Equal(t, "", ev.ShareToken)
+		},
+	}, {
+		Alias: "ShareCreated - group",
+		SystemEvent: events.ShareCreated{
+			Sharer:         userID("sharing-userid"),
+			GranteeUserID:  nil,
+			GranteeGroupID: groupID("beshared-groupid"),
+			ItemID:         resourceID("storage-1", "itemid-1"),
+			CTime:          timestamp(10e8),
+		},
+		CheckAuditEvent: func(t *testing.T, b []byte) {
+			ev := types.AuditEventShareCreated{}
+			require.NoError(t, json.Unmarshal(b, &ev))
+
+			// AuditEvent fields
+			checkBaseAuditEvent(t, ev.AuditEvent, "sharing-userid", "2001-09-09T01:46:40Z", "user 'sharing-userid' shared file 'itemid-1' with 'beshared-groupid'", "file_shared")
+			// AuditEventSharing fields
+			checkSharingAuditEvent(t, ev.AuditEventSharing, "itemid-1", "sharing-userid", "")
+			// AuditEventShareCreated fields
+			require.Equal(t, "", ev.ItemType)
+			require.Equal(t, "", ev.ExpirationDate)
+			require.Equal(t, false, ev.SharePass)
+			//require.Equal(t, "stat:true ", ev.Permissions) // TODO: BUG! Should work
+			require.Equal(t, "group", ev.ShareType)
+			require.Equal(t, "beshared-groupid", ev.ShareWith)
+			require.Equal(t, "sharing-userid", ev.ShareOwner)
+			require.Equal(t, "", ev.ShareToken)
+
+		},
+	}, {
+		Alias: "ShareUpdated",
+		SystemEvent: events.ShareUpdated{
+			ShareID:        shareID("shareid"),
+			Sharer:         userID("sharing-userid"),
+			GranteeUserID:  nil,
+			GranteeGroupID: groupID("beshared-groupid"),
+			ItemID:         resourceID("storage-1", "itemid-1"),
+			Permissions:    sharePermissions("stat", "get_quota"),
+			MTime:          timestamp(10e8),
+			Updated:        "permissions",
+		},
+		CheckAuditEvent: func(t *testing.T, b []byte) {
+			ev := types.AuditEventShareUpdated{}
+			require.NoError(t, json.Unmarshal(b, &ev))
+
+			// AuditEvent fields
+			checkBaseAuditEvent(t, ev.AuditEvent, "sharing-userid", "2001-09-09T01:46:40Z", "user 'sharing-userid' updated field 'permissions' of share 'shareid'", "share_permission_updated")
+			// AuditEventSharing fields
+			checkSharingAuditEvent(t, ev.AuditEventSharing, "itemid-1", "sharing-userid", "shareid")
+			// AuditEventShareUpdated fields
+			require.Equal(t, "", ev.ItemType)       // not implemented atm
+			require.Equal(t, "", ev.ExpirationDate) // no expiration for shares
+			require.Equal(t, false, ev.SharePass)
+			require.Equal(t, "get_quota:true stat:true ", ev.Permissions)
+			require.Equal(t, "group", ev.ShareType)
+			require.Equal(t, "beshared-groupid", ev.ShareWith)
+			require.Equal(t, "sharing-userid", ev.ShareOwner)
+			require.Equal(t, "", ev.ShareToken) // token not filled for shares
+		},
+	}, {
+		Alias: "LinkUpdated - permissions",
+		SystemEvent: events.LinkUpdated{
+			ShareID:           linkID("shareid"),
+			Sharer:            userID("sharing-userid"),
+			ItemID:            resourceID("storage-1", "itemid-1"),
+			Permissions:       linkPermissions("stat"),
+			CTime:             timestamp(10e8),
+			DisplayName:       "link",
+			Expiration:        timestamp(10e8 + 10e5),
+			PasswordProtected: true,
+			Token:             "token-123",
+			FieldUpdated:      "permissions",
+		},
+		CheckAuditEvent: func(t *testing.T, b []byte) {
+			ev := types.AuditEventShareUpdated{}
+			require.NoError(t, json.Unmarshal(b, &ev))
+
+			// AuditEvent fields
+			checkBaseAuditEvent(t, ev.AuditEvent, "sharing-userid", "2001-09-09T01:46:40Z", "user 'sharing-userid' updated field 'permissions' of public link 'shareid'", "share_permission_updated")
+			// AuditEventSharing fields
+			checkSharingAuditEvent(t, ev.AuditEventSharing, "itemid-1", "sharing-userid", "shareid")
+			// AuditEventShareUpdated fields
+			require.Equal(t, "", ev.ItemType) // not implemented atm
+			require.Equal(t, "2001-09-20T15:33:20Z", ev.ExpirationDate)
+			require.Equal(t, true, ev.SharePass)
+			require.Equal(t, "stat:true ", ev.Permissions)
+			require.Equal(t, "link", ev.ShareType)
+			require.Equal(t, "", ev.ShareWith) // not filled on links
+			require.Equal(t, "sharing-userid", ev.ShareOwner)
+			require.Equal(t, "token-123", ev.ShareToken)
+		},
+	}, {
+		Alias: "ShareRemoved",
+		SystemEvent: events.ShareRemoved{
+			ShareID:  shareID("shareid"),
+			ShareKey: nil,
+		},
+		CheckAuditEvent: func(t *testing.T, b []byte) {
+			ev := types.AuditEventShareRemoved{}
+			require.NoError(t, json.Unmarshal(b, &ev))
+
+			// AuditEvent fields
+			checkBaseAuditEvent(t, ev.AuditEvent, "", "", "share id:'shareid' uid:'' item-id:'' was removed", "file_unshared")
+			// AuditEventSharing fields
+			checkSharingAuditEvent(t, ev.AuditEventSharing, "", "", "shareid")
+			// AuditEventShareUpdated fields
+			require.Equal(t, "", ev.ItemType) // not implemented atm
+			require.Equal(t, "", ev.ShareType)
+			require.Equal(t, "", ev.ShareWith) // not filled on links
+		},
+	}, {
+		Alias: "LinkRemoved - id",
+		SystemEvent: events.LinkRemoved{
+			ShareID:    linkID("shareid"),
+			ShareToken: "",
+		},
+		CheckAuditEvent: func(t *testing.T, b []byte) {
+			ev := types.AuditEventShareRemoved{}
+			require.NoError(t, json.Unmarshal(b, &ev))
+
+			// AuditEvent fields
+			checkBaseAuditEvent(t, ev.AuditEvent, "", "", "public link id:'shareid' was removed", "file_unshared")
+			// AuditEventSharing fields
+			checkSharingAuditEvent(t, ev.AuditEventSharing, "", "", "shareid")
+			// AuditEventShareUpdated fields
+			require.Equal(t, "", ev.ItemType) // not implemented atm
+			require.Equal(t, "link", ev.ShareType)
+			require.Equal(t, "", ev.ShareWith) // not filled on links
+		},
+	}, {
+		Alias: "LinkRemoved - token",
+		SystemEvent: events.LinkRemoved{
+			ShareID:    nil,
+			ShareToken: "token-123",
+		},
+		CheckAuditEvent: func(t *testing.T, b []byte) {
+			ev := types.AuditEventShareRemoved{}
+			require.NoError(t, json.Unmarshal(b, &ev))
+
+			// AuditEvent fields
+			checkBaseAuditEvent(t, ev.AuditEvent, "", "", "public link id:'token-123' was removed", "file_unshared")
+			// AuditEventSharing fields
+			checkSharingAuditEvent(t, ev.AuditEventSharing, "", "", "token-123")
+			// AuditEventShareUpdated fields
+			require.Equal(t, "", ev.ItemType) // not implemented atm
+			require.Equal(t, "link", ev.ShareType)
+			require.Equal(t, "", ev.ShareWith) // not filled on links
+		},
+	}, {
+		Alias: "Share accepted",
+		SystemEvent: events.ReceivedShareUpdated{
+			ShareID:        shareID("shareid"),
+			ItemID:         resourceID("storageid-1", "itemid-1"),
+			Permissions:    sharePermissions("get_quota"),
+			GranteeUserID:  userID("beshared-userid"),
+			GranteeGroupID: nil,
+			Sharer:         userID("sharing-userid"),
+			MTime:          timestamp(10e8),
+			State:          "SHARE_STATE_ACCEPTED",
+		},
+		CheckAuditEvent: func(t *testing.T, b []byte) {
+			ev := types.AuditEventReceivedShareUpdated{}
+			require.NoError(t, json.Unmarshal(b, &ev))
+
+			// AuditEvent fields
+			checkBaseAuditEvent(t, ev.AuditEvent, "beshared-userid", "2001-09-09T01:46:40Z", "user 'beshared-userid' accepted share 'shareid' from user 'sharing-userid'", "share_accepted")
+			// AuditEventSharing fields
+			checkSharingAuditEvent(t, ev.AuditEventSharing, "itemid-1", "sharing-userid", "shareid")
+			// AuditEventShareUpdated fields
+			require.Equal(t, "", ev.ItemType)
+			require.Equal(t, "user", ev.ShareType)
+			require.Equal(t, "beshared-userid", ev.ShareWith)
+		},
+	}, {
+		Alias: "Share declined",
+		SystemEvent: events.ReceivedShareUpdated{
+			ShareID:        shareID("shareid"),
+			ItemID:         resourceID("storageid-1", "itemid-1"),
+			Permissions:    sharePermissions("get_quota"),
+			GranteeUserID:  userID("beshared-userid"),
+			GranteeGroupID: nil,
+			Sharer:         userID("sharing-userid"),
+			MTime:          timestamp(10e8),
+			State:          "SHARE_STATE_DECLINED",
+		},
+		CheckAuditEvent: func(t *testing.T, b []byte) {
+			ev := types.AuditEventReceivedShareUpdated{}
+			require.NoError(t, json.Unmarshal(b, &ev))
+
+			// AuditEvent fields
+			checkBaseAuditEvent(t, ev.AuditEvent, "beshared-userid", "2001-09-09T01:46:40Z", "user 'beshared-userid' declined share 'shareid' from user 'sharing-userid'", "share_declined")
+			// AuditEventSharing fields
+			checkSharingAuditEvent(t, ev.AuditEventSharing, "itemid-1", "sharing-userid", "shareid")
+			// AuditEventShareUpdated fields
+			require.Equal(t, "", ev.ItemType)
+			require.Equal(t, "user", ev.ShareType)
+			require.Equal(t, "beshared-userid", ev.ShareWith)
+		},
+	}, {
+		Alias: "Link accessed - success",
+		SystemEvent: events.LinkAccessed{
+			ShareID:           linkID("shareid"),
+			Sharer:            userID("sharing-userid"),
+			ItemID:            resourceID("storage-1", "itemid-1"),
+			Permissions:       linkPermissions("stat"),
+			DisplayName:       "link",
+			Expiration:        timestamp(10e8 + 10e5),
+			PasswordProtected: true,
+			CTime:             timestamp(10e8),
+			Token:             "token-123",
+		},
+		CheckAuditEvent: func(t *testing.T, b []byte) {
+			ev := types.AuditEventLinkAccessed{}
+			require.NoError(t, json.Unmarshal(b, &ev))
 
+			// AuditEvent fields
+			checkBaseAuditEvent(t, ev.AuditEvent, "sharing-userid", "2001-09-09T01:46:40Z", "link 'shareid' was accessed. Success: true", "public_link_accessed")
+			// AuditEventSharing fields
+			checkSharingAuditEvent(t, ev.AuditEventSharing, "itemid-1", "sharing-userid", "shareid")
+			// AuditEventShareUpdated fields
+			require.Equal(t, "", ev.ItemType) // not implemented atm
+			require.Equal(t, "token-123", ev.ShareToken)
+			require.Equal(t, true, ev.Success)
+		},
+	}, {
+		Alias: "Link accessed - failure",
+		SystemEvent: events.LinkAccessFailed{
+			ShareID: linkID("shareid"),
+			Token:   "token-123",
+			Status:  8,
+			Message: "access denied",
+		},
+		CheckAuditEvent: func(t *testing.T, b []byte) {
+			ev := types.AuditEventLinkAccessed{}
+			require.NoError(t, json.Unmarshal(b, &ev))
+
+			// AuditEvent fields
+			checkBaseAuditEvent(t, ev.AuditEvent, "", "", "link 'shareid' was accessed. Success: false", "public_link_accessed")
+			// AuditEventSharing fields
+			checkSharingAuditEvent(t, ev.AuditEventSharing, "", "", "shareid")
+			// AuditEventShareUpdated fields
+			require.Equal(t, "", ev.ItemType) // not implemented atm
+			require.Equal(t, "token-123", ev.ShareToken)
+			require.Equal(t, false, ev.Success)
 		},
 	},
 }
@@ -73,8 +313,103 @@ func TestAuditLogging(t *testing.T) {
 		outch <- b
 	})
 
-	for _, tc := range testCases {
-		inch <- tc.SystemEvent
-		tc.CheckAuditEvent(t, <-outch)
+	for i := range testCases {
+		tc := testCases[i]
+		t.Run(tc.Alias, func(t *testing.T) {
+			inch <- tc.SystemEvent
+			tc.CheckAuditEvent(t, <-outch)
+		})
 	}
 }
+
+func checkBaseAuditEvent(t *testing.T, ev types.AuditEvent, user string, time string, message string, action string) {
+	require.Equal(t, "", ev.RemoteAddr) // not implemented atm
+	require.Equal(t, user, ev.User)
+	require.Equal(t, "", ev.URL)       // not implemented atm
+	require.Equal(t, "", ev.Method)    // not implemented atm
+	require.Equal(t, "", ev.UserAgent) // not implemented atm
+	require.Equal(t, time, ev.Time)
+	require.Equal(t, "admin_audit", ev.App)
+	require.Equal(t, message, ev.Message)
+	require.Equal(t, action, ev.Action)
+	require.Equal(t, false, ev.CLI) // not implemented atm
+	require.Equal(t, 1, ev.Level)
+}
+
+func checkSharingAuditEvent(t *testing.T, ev types.AuditEventSharing, itemID string, owner string, shareID string) {
+	require.Equal(t, itemID, ev.FileID)
+	require.Equal(t, owner, ev.Owner)
+	require.Equal(t, "", ev.Path) // not implemented atm
+	require.Equal(t, shareID, ev.ShareID)
+}
+
+func shareID(id string) *collaboration.ShareId {
+	return &collaboration.ShareId{
+		OpaqueId: id,
+	}
+}
+
+func linkID(id string) *link.PublicShareId {
+	return &link.PublicShareId{
+		OpaqueId: id,
+	}
+}
+
+func userID(id string) *user.UserId {
+	return &user.UserId{
+		OpaqueId: id,
+		Idp:      "idp",
+	}
+}
+
+func groupID(id string) *group.GroupId {
+	return &group.GroupId{
+		OpaqueId: id,
+		Idp:      "idp",
+	}
+}
+
+func resourceID(sid, oid string) *provider.ResourceId {
+	return &provider.ResourceId{
+		StorageId: sid,
+		OpaqueId:  oid,
+	}
+}
+
+func timestamp(seconds uint64) *rtypes.Timestamp {
+	return &rtypes.Timestamp{
+		Seconds: seconds,
+		Nanos:   0,
+	}
+}
+
+func sharePermissions(perms ...string) *collaboration.SharePermissions {
+	return &collaboration.SharePermissions{
+		Permissions: permissions(perms...),
+	}
+}
+
+func linkPermissions(perms ...string) *link.PublicSharePermissions {
+	return &link.PublicSharePermissions{
+		Permissions: permissions(perms...),
+	}
+}
+func permissions(permissions ...string) *provider.ResourcePermissions {
+	perms := &provider.ResourcePermissions{}
+
+	for _, p := range permissions {
+		switch p {
+		case "stat":
+			perms.Stat = true
+		case "get_path":
+			perms.GetPath = true
+		case "list_container":
+			perms.ListContainer = true
+		case "get_quota":
+			perms.GetQuota = true
+
+		}
+	}
+
+	return perms
+}
diff --git a/ocs/pkg/server/http/svc_test.go b/ocs/pkg/server/http/svc_test.go
index a8158dc1be6..410b7143178 100644
--- a/ocs/pkg/server/http/svc_test.go
+++ b/ocs/pkg/server/http/svc_test.go
@@ -49,14 +49,13 @@ const (
 )
 
 const (
-	userEinstein  string = "einstein"
-	userMarie     string = "marie"
-	userRichard   string = "richard"
-	userIDP       string = "idp"
-	userReva      string = "reva"
-	userMoss      string = "moss"
-	userAdmin     string = "admin"
-	userKatherine string = "katherine"
+	userEinstein string = "einstein"
+	userMarie    string = "marie"
+	userRichard  string = "richard"
+	userIDP      string = "idp"
+	userReva     string = "reva"
+	userMoss     string = "moss"
+	userAdmin    string = "admin"
 )
 const (
 	groupPhilosophyHaters string = "philosophy-haters"
@@ -101,12 +100,6 @@ var defaultMemberOf = map[string][]string{
 	userAdmin: {
 		groupUsers,
 	},
-	userKatherine: {
-		groupUsers,
-		groupSailingLovers,
-		groupQuantumLovers,
-		groupPhysicsLovers,
-	},
 }
 
 var defaultMembers = map[string][]string{
@@ -118,11 +111,9 @@ var defaultMembers = map[string][]string{
 		userEinstein,
 		userMarie,
 		userRichard,
-		userKatherine,
 	},
 	groupSailingLovers: {
 		userEinstein,
-		userKatherine,
 	},
 	groupViolinHaters: {
 		userEinstein,
@@ -132,7 +123,6 @@ var defaultMembers = map[string][]string{
 	},
 	groupQuantumLovers: {
 		userRichard,
-		userKatherine,
 	},
 	groupPhilosophyHaters: {
 		userRichard,
@@ -141,20 +131,18 @@ var defaultMembers = map[string][]string{
 		userEinstein,
 		userMarie,
 		userRichard,
-		userKatherine,
 	},
 }
 
 // These account ids are only needed for cleanup
 const (
-	userIDEinstein  string = "4c510ada-c86b-4815-8820-42cdf82c3d51"
-	userIDMarie     string = "f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c"
-	userIDFeynman   string = "932b4540-8d16-481e-8ef4-588e4b6b151c"
-	userIDIDP       string = "820ba2a1-3f54-4538-80a4-2d73007e30bf"
-	userIDReva      string = "bc596f3c-c955-4328-80a0-60d018b4ad57"
-	userIDMoss      string = "058bff95-6708-4fe5-91e4-9ea3d377588b"
-	userIDAdmin     string = "ddc2004c-0977-11eb-9d3f-a793888cd0f8"
-	userIDKatherine string = "534bb038-6f9d-4093-946f-133be61fa4e7"
+	userIDEinstein string = "4c510ada-c86b-4815-8820-42cdf82c3d51"
+	userIDMarie    string = "f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c"
+	userIDFeynman  string = "932b4540-8d16-481e-8ef4-588e4b6b151c"
+	userIDIDP      string = "820ba2a1-3f54-4538-80a4-2d73007e30bf"
+	userIDReva     string = "bc596f3c-c955-4328-80a0-60d018b4ad57"
+	userIDMoss     string = "058bff95-6708-4fe5-91e4-9ea3d377588b"
+	userIDAdmin    string = "ddc2004c-0977-11eb-9d3f-a793888cd0f8"
 )
 
 // These group ids are only needed for cleanup
@@ -193,7 +181,6 @@ var defaultUsers = []string{
 	userMarie,
 	userMoss,
 	userAdmin,
-	userKatherine,
 }
 var defaultUserIDs = []string{
 	userIDEinstein,
@@ -203,7 +190,6 @@ var defaultUserIDs = []string{
 	userIDMarie,
 	userIDMoss,
 	userIDAdmin,
-	userIDKatherine,
 }
 
 var defaultGroups = []string{
diff --git a/tests/acceptance/expected-failures-API-on-OCIS-storage.md b/tests/acceptance/expected-failures-API-on-OCIS-storage.md
index 055affef0a6..2e6b4260848 100644
--- a/tests/acceptance/expected-failures-API-on-OCIS-storage.md
+++ b/tests/acceptance/expected-failures-API-on-OCIS-storage.md
@@ -140,42 +140,42 @@ Synchronization features like etag propagation, setting mtime and locking files
 - [apiWebdavLocks/folder.feature:138](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/folder.feature#L138)
 - [apiWebdavLocks/folder.feature:144](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/folder.feature#L144)
 - [apiWebdavLocks/folder.feature:143](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/folder.feature#L143)
+- [apiWebdavLocks/folder.feature:160](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/folder.feature#L160)
 - [apiWebdavLocks/folder.feature:161](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/folder.feature#L161)
 - [apiWebdavLocks/folder.feature:162](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/folder.feature#L162)
 - [apiWebdavLocks/folder.feature:163](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/folder.feature#L163)
-- [apiWebdavLocks/folder.feature:164](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/folder.feature#L164)
+- [apiWebdavLocks/folder.feature:168](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/folder.feature#L168)
 - [apiWebdavLocks/folder.feature:169](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/folder.feature#L169)
-- [apiWebdavLocks/folder.feature:170](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/folder.feature#L170)
+- [apiWebdavLocks/publicLink.feature:32](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/publicLink.feature#L32)
 - [apiWebdavLocks/publicLink.feature:33](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/publicLink.feature#L33)
 - [apiWebdavLocks/publicLink.feature:34](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/publicLink.feature#L34)
 - [apiWebdavLocks/publicLink.feature:35](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/publicLink.feature#L35)
-- [apiWebdavLocks/publicLink.feature:36](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/publicLink.feature#L36)
+- [apiWebdavLocks/publicLink.feature:40](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/publicLink.feature#L40)
 - [apiWebdavLocks/publicLink.feature:41](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/publicLink.feature#L41)
 - [apiWebdavLocks/publicLink.feature:42](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/publicLink.feature#L42)
 - [apiWebdavLocks/publicLink.feature:43](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/publicLink.feature#L43)
-- [apiWebdavLocks/publicLink.feature:44](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/publicLink.feature#L44)
+- [apiWebdavLocks/publicLink.feature:59](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/publicLink.feature#L59)
 - [apiWebdavLocks/publicLink.feature:60](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/publicLink.feature#L60)
-- [apiWebdavLocks/publicLink.feature:61](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/publicLink.feature#L61)
+- [apiWebdavLocks/publicLink.feature:77](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/publicLink.feature#L77)
 - [apiWebdavLocks/publicLink.feature:78](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/publicLink.feature#L78)
-- [apiWebdavLocks/publicLink.feature:79](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/publicLink.feature#L79)
+- [apiWebdavLocks/publicLink.feature:97](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/publicLink.feature#L97)
 - [apiWebdavLocks/publicLink.feature:98](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/publicLink.feature#L98)
-- [apiWebdavLocks/publicLink.feature:99](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/publicLink.feature#L99)
+- [apiWebdavLocks/publicLink.feature:116](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/publicLink.feature#L116)
 - [apiWebdavLocks/publicLink.feature:117](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/publicLink.feature#L117)
-- [apiWebdavLocks/publicLink.feature:118](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/publicLink.feature#L118)
+- [apiWebdavLocks/publicLinkLockdiscovery.feature:22](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/publicLinkLockdiscovery.feature#L22)
 - [apiWebdavLocks/publicLinkLockdiscovery.feature:23](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/publicLinkLockdiscovery.feature#L23)
-- [apiWebdavLocks/publicLinkLockdiscovery.feature:24](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/publicLinkLockdiscovery.feature#L24)
-- [apiWebdavLocks/publicLinkLockdiscovery.feature:39](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/publicLinkLockdiscovery.feature#L39)
-- [apiWebdavLocks/publicLinkLockdiscovery.feature:40](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/publicLinkLockdiscovery.feature#L40)
-- [apiWebdavLocks/publicLinkLockdiscovery.feature:55](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/publicLinkLockdiscovery.feature#L55)
-- [apiWebdavLocks/publicLinkLockdiscovery.feature:56](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/publicLinkLockdiscovery.feature#L56)
-- [apiWebdavLocks/publicLinkLockdiscovery.feature:71](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/publicLinkLockdiscovery.feature#L71)
-- [apiWebdavLocks/publicLinkLockdiscovery.feature:72](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/publicLinkLockdiscovery.feature#L72)
-- [apiWebdavLocks/publicLinkLockdiscovery.feature:87](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/publicLinkLockdiscovery.feature#L87)
-- [apiWebdavLocks/publicLinkLockdiscovery.feature:88](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/publicLinkLockdiscovery.feature#L88)
-- [apiWebdavLocks/publicLinkLockdiscovery.feature:103](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/publicLinkLockdiscovery.feature#L103)
-- [apiWebdavLocks/publicLinkLockdiscovery.feature:104](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/publicLinkLockdiscovery.feature#L104)
-- [apiWebdavLocks/publicLinkLockdiscovery.feature:119](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/publicLinkLockdiscovery.feature#L119)
-- [apiWebdavLocks/publicLinkLockdiscovery.feature:120](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/publicLinkLockdiscovery.feature#L120)
+- [apiWebdavLocks/publicLinkLockdiscovery.feature:37](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/publicLinkLockdiscovery.feature#L37)
+- [apiWebdavLocks/publicLinkLockdiscovery.feature:38](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/publicLinkLockdiscovery.feature#L38)
+- [apiWebdavLocks/publicLinkLockdiscovery.feature:52](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/publicLinkLockdiscovery.feature#L52)
+- [apiWebdavLocks/publicLinkLockdiscovery.feature:53](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/publicLinkLockdiscovery.feature#L53)
+- [apiWebdavLocks/publicLinkLockdiscovery.feature:67](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/publicLinkLockdiscovery.feature#L67)
+- [apiWebdavLocks/publicLinkLockdiscovery.feature:68](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/publicLinkLockdiscovery.feature#L68)
+- [apiWebdavLocks/publicLinkLockdiscovery.feature:82](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/publicLinkLockdiscovery.feature#L82)
+- [apiWebdavLocks/publicLinkLockdiscovery.feature:83](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/publicLinkLockdiscovery.feature#L83)
+- [apiWebdavLocks/publicLinkLockdiscovery.feature:97](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/publicLinkLockdiscovery.feature#L97)
+- [apiWebdavLocks/publicLinkLockdiscovery.feature:98](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/publicLinkLockdiscovery.feature#L98)
+- [apiWebdavLocks/publicLinkLockdiscovery.feature:112](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/publicLinkLockdiscovery.feature#L112)
+- [apiWebdavLocks/publicLinkLockdiscovery.feature:113](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/publicLinkLockdiscovery.feature#L113)
 - [apiWebdavLocks/requestsWithToken.feature:73](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/requestsWithToken.feature#L73)
 - [apiWebdavLocks/requestsWithToken.feature:74](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/requestsWithToken.feature#L74)
 - [apiWebdavLocks/requestsWithToken.feature:75](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavLocks/requestsWithToken.feature#L75)
@@ -497,7 +497,7 @@ cannot share a folder with create permission
 - [apiSharePublicLink1/accessToPublicLinkShare.feature:10](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiSharePublicLink1/accessToPublicLinkShare.feature#L10)
 - [apiSharePublicLink1/accessToPublicLinkShare.feature:20](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiSharePublicLink1/accessToPublicLinkShare.feature#L20)
 - [apiSharePublicLink1/accessToPublicLinkShare.feature:30](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiSharePublicLink1/accessToPublicLinkShare.feature#L30)
-- [apiSharePublicLink1/accessToPublicLinkShare.feature:45](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiSharePublicLink1/accessToPublicLinkShare.feature#L45)
+- [apiSharePublicLink1/accessToPublicLinkShare.feature:44](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiSharePublicLink1/accessToPublicLinkShare.feature#L44)
 - [apiSharePublicLink1/createPublicLinkShare.feature:587](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiSharePublicLink1/createPublicLinkShare.feature#L587)
 - [apiSharePublicLink1/createPublicLinkShare.feature:608](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiSharePublicLink1/createPublicLinkShare.feature#L608)
 
@@ -516,11 +516,11 @@ cannot share a folder with create permission
 #### [Cannot set/unset maximum and minimum preview dimensions](https://github.com/owncloud/ocis/issues/2070)
 
 - [apiWebdavPreviews/previews.feature:133](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavPreviews/previews.feature#L133)
-- [apiWebdavPreviews/previews.feature:161](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavPreviews/previews.feature#L161)
 - [apiWebdavPreviews/previews.feature:162](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavPreviews/previews.feature#L162)
 - [apiWebdavPreviews/previews.feature:163](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavPreviews/previews.feature#L163)
-- [apiWebdavPreviews/previews.feature:175](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavPreviews/previews.feature#L175)
+- [apiWebdavPreviews/previews.feature:164](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavPreviews/previews.feature#L164)
 - [apiWebdavPreviews/previews.feature:176](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavPreviews/previews.feature#L176)
+- [apiWebdavPreviews/previews.feature:177](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavPreviews/previews.feature#L177)
 
 #### [creating public links with permissions fails](https://github.com/owncloud/product/issues/252)
 
@@ -573,16 +573,17 @@ cannot share a folder with create permission
 #### [Upload-only shares must not overwrite but create a separate file](https://github.com/owncloud/ocis-reva/issues/286)
 
 - [apiSharePublicLink2/uploadToPublicLinkShare.feature:24](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiSharePublicLink2/uploadToPublicLinkShare.feature#L24)
-- [apiSharePublicLink2/uploadToPublicLinkShare.feature:277](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiSharePublicLink2/uploadToPublicLinkShare.feature#L277)
+- [apiSharePublicLink2/uploadToPublicLinkShare.feature:273](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiSharePublicLink2/uploadToPublicLinkShare.feature#L273)
 
 #### [Set quota over settings](https://github.com/owncloud/ocis/issues/1290)
 
-- [apiSharePublicLink2/uploadToPublicLinkShare.feature:160](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiSharePublicLink2/uploadToPublicLinkShare.feature#L160)
-- [apiSharePublicLink2/uploadToPublicLinkShare.feature:179](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiSharePublicLink2/uploadToPublicLinkShare.feature#L179)
+- [apiSharePublicLink2/uploadToPublicLinkShare.feature:158](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiSharePublicLink2/uploadToPublicLinkShare.feature#L158)
+- [apiSharePublicLink2/uploadToPublicLinkShare.feature:177](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiSharePublicLink2/uploadToPublicLinkShare.feature#L177)
 
 #### [various sharing settings cannot be set](https://github.com/owncloud/ocis/issues/1328)
 
-- [apiSharePublicLink2/uploadToPublicLinkShare.feature:198](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiSharePublicLink2/uploadToPublicLinkShare.feature#L198)
+- [apiSharePublicLink2/uploadToPublicLinkShare.feature:196](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiSharePublicLink2/uploadToPublicLinkShare.feature#L196)
+- [apiSharePublicLink2/uploadToPublicLinkShare.feature:215](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiSharePublicLink2/uploadToPublicLinkShare.feature#L215)
 
 #### [Resharing does not work with ocis storage](https://github.com/owncloud/product/issues/265)
 
@@ -728,19 +729,19 @@ _getting and setting quota_
 Scenario Outline: Moving a file into a shared folder as the sharee and as the sharer
 
 - [apiWebdavMove2/moveShareOnOcis.feature:30](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavMove2/moveShareOnOcis.feature#L30)
-- [apiWebdavMove2/moveShareOnOcis.feature:32](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavMove2/moveShareOnOcis.feature#L32)
+- [apiWebdavMove2/moveShareOnOcis.feature:31](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavMove2/moveShareOnOcis.feature#L31)
   Scenario Outline: Moving a file out of a shared folder as the sharee and as the sharer
 - [apiWebdavMove2/moveShareOnOcis.feature:60](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavMove2/moveShareOnOcis.feature#L60)
-- [apiWebdavMove2/moveShareOnOcis.feature:62](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavMove2/moveShareOnOcis.feature#L62)
+- [apiWebdavMove2/moveShareOnOcis.feature:61](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavMove2/moveShareOnOcis.feature#L61)
   Scenario Outline: Moving a folder into a shared folder as the sharee and as the sharer
 - [apiWebdavMove2/moveShareOnOcis.feature:91](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavMove2/moveShareOnOcis.feature#L91)
-- [apiWebdavMove2/moveShareOnOcis.feature:93](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavMove2/moveShareOnOcis.feature#L93)
+- [apiWebdavMove2/moveShareOnOcis.feature:92](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavMove2/moveShareOnOcis.feature#L92)
   Scenario Outline: Moving a folder out of a shared folder as the sharee and as the sharer
-- [apiWebdavMove2/moveShareOnOcis.feature:124](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavMove2/moveShareOnOcis.feature#L124)
-- [apiWebdavMove2/moveShareOnOcis.feature:126](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavMove2/moveShareOnOcis.feature#L126)
+- [apiWebdavMove2/moveShareOnOcis.feature:122](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavMove2/moveShareOnOcis.feature#L122)
+- [apiWebdavMove2/moveShareOnOcis.feature:123](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavMove2/moveShareOnOcis.feature#L123)
   Scenario Outline: Moving a file to a shared folder with no permissions
+- [apiWebdavMove2/moveShareOnOcis.feature:151](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavMove2/moveShareOnOcis.feature#L151)
 - [apiWebdavMove2/moveShareOnOcis.feature:152](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavMove2/moveShareOnOcis.feature#L152)
-- [apiWebdavMove2/moveShareOnOcis.feature:153](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavMove2/moveShareOnOcis.feature#L153)
 
 #### [restoring an older version of a shared file deletes the share](https://github.com/owncloud/ocis/issues/765)
 
@@ -1039,10 +1040,10 @@ special character username not valid
 - [apiProvisioning-v1/editUser.feature:57](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiProvisioning-v1/editUser.feature#L57)
 - [apiProvisioning-v1/editUser.feature:129](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiProvisioning-v1/editUser.feature#L129)
 - [apiProvisioning-v2/editUser.feature:58](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiProvisioning-v2/editUser.feature#L58)
-- [apiProvisioning-v2/editUser.feature:130](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiProvisioning-v2/editUser.feature#L130)
+- [apiProvisioning-v2/editUser.feature:128](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiProvisioning-v2/editUser.feature#L128)
 - [apiProvisioning-v2/enableUser.feature:40](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiProvisioning-v2/enableUser.feature#L40)
 - [apiProvisioning-v2/enableUser.feature:62](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiProvisioning-v2/enableUser.feature#L62)
-- [apiProvisioning-v2/enableUser.feature:72](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiProvisioning-v2/enableUser.feature#L72)
+- [apiProvisioning-v2/enableUser.feature:70](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiProvisioning-v2/enableUser.feature#L70)
 
 #### [user can get info of other users/ cloud/users endpoints not authenticated](https://github.com/owncloud/product/issues/248)
 
@@ -1286,6 +1287,7 @@ And other missing implementation of favorites
 - [apiFavorites/favoritesSharingToShares.feature:83](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiFavorites/favoritesSharingToShares.feature#L83)
 - [apiFavorites/favoritesSharingToShares.feature:108](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiFavorites/favoritesSharingToShares.feature#L108)
 - [apiMain/checksums.feature:211](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiMain/checksums.feature#L211)
+- [apiMain/checksums.feature:233](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiMain/checksums.feature#L233)
 - [apiShareOperationsToShares2/getWebDAVSharePermissions.feature:49](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareOperationsToShares2/getWebDAVSharePermissions.feature#L49)
 - [apiShareOperationsToShares2/getWebDAVSharePermissions.feature:75](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareOperationsToShares2/getWebDAVSharePermissions.feature#L75)
 - [apiShareOperationsToShares2/getWebDAVSharePermissions.feature:94](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiShareOperationsToShares2/getWebDAVSharePermissions.feature#L94)
@@ -1378,10 +1380,10 @@ And other missing implementation of favorites
 - [apiWebdavMove2/moveShareOnOcis.feature:68](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavMove2/moveShareOnOcis.feature#L68)
 - [apiWebdavMove2/moveShareOnOcis.feature:99](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavMove2/moveShareOnOcis.feature#L99)
 - [apiWebdavMove2/moveShareOnOcis.feature:100](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavMove2/moveShareOnOcis.feature#L100)
-- [apiWebdavMove2/moveShareOnOcis.feature:132](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavMove2/moveShareOnOcis.feature#L132)
-- [apiWebdavMove2/moveShareOnOcis.feature:158](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavMove2/moveShareOnOcis.feature#L158)
-- [apiWebdavMove2/moveShareOnOcis.feature:185](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavMove2/moveShareOnOcis.feature#L185)
-- [apiWebdavMove2/moveShareOnOcis.feature:220](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavMove2/moveShareOnOcis.feature#L220)
+- [apiWebdavMove2/moveShareOnOcis.feature:130](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavMove2/moveShareOnOcis.feature#L130)
+- [apiWebdavMove2/moveShareOnOcis.feature:157](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavMove2/moveShareOnOcis.feature#L157)
+- [apiWebdavMove2/moveShareOnOcis.feature:184](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavMove2/moveShareOnOcis.feature#L184)
+- [apiWebdavMove2/moveShareOnOcis.feature:216](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavMove2/moveShareOnOcis.feature#L216)
 
 #### [WWW-Authenticate header for unauthenticated requests is not clear](https://github.com/owncloud/ocis/issues/2285)
 
@@ -1702,9 +1704,9 @@ Not everything needs to be implemented for ocis. While the oc10 testsuite covers
 - [apiWebdavUpload2/uploadFileToExcludedDirectoryUsingOldChunking.feature:38](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavUpload2/uploadFileToExcludedDirectoryUsingOldChunking.feature#L38)
 - [apiWebdavUpload2/uploadFileToExcludedDirectoryUsingOldChunking.feature:39](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavUpload2/uploadFileToExcludedDirectoryUsingOldChunking.feature#L39)
 - [apiWebdavUpload2/uploadFileToExcludedDirectoryUsingOldChunking.feature:40](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavUpload2/uploadFileToExcludedDirectoryUsingOldChunking.feature#L40)
+- [apiWebdavMove2/moveFile.feature:286](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavMove2/moveFile.feature#L286)
 - [apiWebdavMove2/moveFile.feature:287](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavMove2/moveFile.feature#L287)
-- [apiWebdavMove2/moveFile.feature:288](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavMove2/moveFile.feature#L288)
-- [apiWebdavMove2/moveFile.feature:293](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavMove2/moveFile.feature#L293)
+- [apiWebdavMove2/moveFile.feature:292](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavMove2/moveFile.feature#L292)
 
 #### [cannot set blacklisted file names](https://github.com/owncloud/product/issues/260)
 
@@ -1758,12 +1760,12 @@ Not everything needs to be implemented for ocis. While the oc10 testsuite covers
 
 #### [Cannot download preview of shared received file after the shareowner has changed the file content](https://github.com/owncloud/ocis/issues/2538)
 
-- [apiWebdavPreviews/previews.feature:219](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavPreviews/previews.feature#L219)
-- [apiWebdavPreviews/previews.feature:237](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavPreviews/previews.feature#L237)
+- [apiWebdavPreviews/previews.feature:217](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavPreviews/previews.feature#L217)
+- [apiWebdavPreviews/previews.feature:233](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavPreviews/previews.feature#L233)
 
 #### [Preview of text file with UTF content does not render correctly](https://github.com/owncloud/ocis/issues/2570)
 
-- [apiWebdavPreviews/previews.feature:210](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavPreviews/previews.feature#L210)
+- [apiWebdavPreviews/previews.feature:208](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavPreviews/previews.feature#L208)
 
 #### [Share path in the response is different between share states](https://github.com/owncloud/ocis/issues/2540)
 
@@ -1814,7 +1816,7 @@ Not everything needs to be implemented for ocis. While the oc10 testsuite covers
 - [apiWebdavMove1/moveFolder.feature:27](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavMove1/moveFolder.feature#L27)
 - [apiWebdavMove1/moveFolder.feature:45](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavMove1/moveFolder.feature#L45)
 - [apiWebdavMove1/moveFolder.feature:63](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavMove1/moveFolder.feature#L63)
-- [apiWebdavMove2/moveFile.feature:224](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavMove2/moveFile.feature#L224)
+- [apiWebdavMove2/moveFile.feature:225](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavMove2/moveFile.feature#L225)
 - [apiWebdavMove2/moveFileToBlacklistedName.feature:25](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavMove2/moveFileToBlacklistedName.feature#L25)
 - [apiWebdavMove2/moveFileToBlacklistedName.feature:41](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavMove2/moveFileToBlacklistedName.feature#L41)
 - [apiWebdavMove2/moveFileToBlacklistedName.feature:80](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiWebdavMove2/moveFileToBlacklistedName.feature#L80)
@@ -1857,9 +1859,5 @@ Not everything needs to be implemented for ocis. While the oc10 testsuite covers
 #### [OCS response is not returned when a disabled user tries to enable himself](https://github.com/owncloud/ocis/issues/3254)
 
 - [apiProvisioning-v1/enableUser.feature:62](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiProvisioning-v1/enableUser.feature#L62)
-
-#### [Trying to modify a shared file using spaces end-point returns 409 HTTP status code](https://github.com/owncloud/ocis/issues/3241)
-
-- [apiMain/checksums.feature:233](https://github.com/owncloud/core/blob/master/tests/acceptance/features/apiMain/checksums.feature#L233)
   Note: always have an empty line at the end of this file.
   The bash script that processes this file requires that the last line has a newline on the end.