Repository: owncloud/ocis
Pull request #5605 (2023-02-21 06:36:22)

[full-ci][tests-only]Api tests for updating the expiration date of a space
<!--
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
This PR adds scenarios to update the expiration date of the space in user and group share.

## 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: -->
- Part of: https://github.com/owncloud/ocis/issues/5413

## 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. -->
- locally
- CI

## 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)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)
- [ ] Technical debt
- [x] Tests only (no source changes)

## Checklist:
<!-- Tick the checkboxes when done. -->
<!-- Raise documentation ticket in owncloud.github.io/ -->
- [ ] Code changes
- [ ] Unit tests added
- [x] Acceptance tests added
- [ ] Documentation ticket raised: <link> 



Patch:
diff --git a/.drone.star b/.drone.star
index bae39f81046..cd87aa5fb0e 100644
--- a/.drone.star
+++ b/.drone.star
@@ -58,6 +58,7 @@ config = {
         "services/auth-basic",
         "services/auth-bearer",
         "services/auth-machine",
+        "services/eventhistory",
         "services/frontend",
         "services/gateway",
         "services/graph",
@@ -848,7 +849,7 @@ def wopiValidatorTests(ctx, storage, accounts_hash_difficulty = 4):
 
 def coreApiTests(ctx, part_number = 1, number_of_parts = 1, storage = "ocis", accounts_hash_difficulty = 4):
     early_fail = config["apiTests"]["earlyFail"] if "earlyFail" in config["apiTests"] else False
-    filterTags = "~@skipOnGraph&&~@skipOnOcis&&~@toImplementOnOCIS&&~comments-app-required&&~@federation-app-required&&~@notifications-app-required&&~systemtags-app-required&&~@local_storage&&~@skipOnOcis-%s-Storage&&~@caldav&&~@carddav" % ("OC" if storage == "owncloud" else "OCIS")
+    filterTags = "~@skipOnGraph&&~@toImplementOnOCIS&&~comments-app-required&&~@federation-app-required&&~@notifications-app-required&&~systemtags-app-required&&~@local_storage&&~@skipOnOcis-%s-Storage&&~@caldav&&~@carddav" % ("OC" if storage == "owncloud" else "OCIS")
     expectedFailuresFile = "%s/tests/acceptance/expected-failures-API-on-%s-storage.md" % (dirs["base"], storage.upper())
 
     return {
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9664c58efdc..f448f3e7b2a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -26,6 +26,7 @@ The following sections list the changes for unreleased.
 * Enhancement - Display surname and givenName attributes: [#5388](https://github.com/owncloud/ocis/pull/5388)
 * Enhancement - Extended search: [#5221](https://github.com/owncloud/ocis/pull/5221)
 * Enhancement - Resource tags: [#5227](https://github.com/owncloud/ocis/pull/5227)
+* Enhancement - Eventhistory service: [#5600](https://github.com/owncloud/ocis/pull/5600)
 * Enhancement - Expiration Notifications: [#5330](https://github.com/owncloud/ocis/pull/5330)
 * Enhancement - Add endpoint to list permissions: [#5594](https://github.com/owncloud/ocis/pull/5594)
 * Enhancement - Better config for postprocessing service: [#5457](https://github.com/owncloud/ocis/pull/5457)
diff --git a/Makefile b/Makefile
index 767d353aac4..b32ec49a085 100644
--- a/Makefile
+++ b/Makefile
@@ -22,6 +22,7 @@ OCIS_MODULES = \
 	services/auth-basic \
 	services/auth-bearer \
 	services/auth-machine \
+	services/eventhistory \
 	services/frontend \
 	services/gateway \
 	services/graph \
diff --git a/changelog/unreleased/configure-bundles.md b/changelog/unreleased/configure-bundles.md
index c69b9845ef5..c0317555612 100644
--- a/changelog/unreleased/configure-bundles.md
+++ b/changelog/unreleased/configure-bundles.md
@@ -1,5 +1,6 @@
 Enhancement: Make the settings bundles part of the service config
 
-We added the settings bundles to the config. The default roles are still unchanged. You can now override the defaults by replacing the whole bundles list via the yaml config files. An example can be found in the Service Configuration documentation.
+We added the settings bundles to the config. The default roles are still unchanged. You can now override the defaults by replacing the whole bundles list via json config files. The config file is loaded from a specified path which can be configured with `SETTINGS_BUNDLES_PATH`.
 
 https://github.com/owncloud/ocis/pull/5589
+https://github.com/owncloud/ocis/pull/5607
diff --git a/changelog/unreleased/event-history.md b/changelog/unreleased/event-history.md
new file mode 100644
index 00000000000..e2a44501214
--- /dev/null
+++ b/changelog/unreleased/event-history.md
@@ -0,0 +1,5 @@
+Enhancement: Eventhistory service
+
+Introduces the `eventhistory` service. It is a service that stores events and provides a grpc API to retrieve them.
+
+https://github.com/owncloud/ocis/pull/5600
diff --git a/go.mod b/go.mod
index 11a39e07d48..a04c4b22b49 100644
--- a/go.mod
+++ b/go.mod
@@ -44,7 +44,7 @@ require (
 	github.com/jellydator/ttlcache/v2 v2.11.1
 	github.com/jellydator/ttlcache/v3 v3.0.1
 	github.com/justinas/alice v1.2.0
-	github.com/libregraph/idm v0.4.1-0.20230202151932-ed881827cd10
+	github.com/libregraph/idm v0.4.1-0.20230221143410-3503963047a5
 	github.com/libregraph/lico v0.54.1-0.20220325072321-31efc3995d63
 	github.com/mitchellh/mapstructure v1.5.0
 	github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826
diff --git a/go.sum b/go.sum
index c6ed746d9c0..d4b1293fb79 100644
--- a/go.sum
+++ b/go.sum
@@ -894,8 +894,8 @@ github.com/labbsr0x/goh v1.0.1/go.mod h1:8K2UhVoaWXcCU7Lxoa2omWnC8gyW8px7/lmO61c
 github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g=
 github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
 github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
-github.com/libregraph/idm v0.4.1-0.20230202151932-ed881827cd10 h1:0E8+tTiAzHgex9K5FkCJLl6DoNRKBJ8b1PFE2sgiJok=
-github.com/libregraph/idm v0.4.1-0.20230202151932-ed881827cd10/go.mod h1:aT29SWLoTxRbHBGuB7lSRS8YOHlEHQ2TPgxYq9qfjJU=
+github.com/libregraph/idm v0.4.1-0.20230221143410-3503963047a5 h1:brLMXSjWoWhGXs8LpK+Lx+FQCtGLUa51Mq/ggHv9AV0=
+github.com/libregraph/idm v0.4.1-0.20230221143410-3503963047a5/go.mod h1:Tnm4pyVJTEbHm3GUNmceWT1DHzdrYqrJmZyt/xh7L+A=
 github.com/libregraph/lico v0.54.1-0.20220325072321-31efc3995d63 h1:oPqyRePmq+59YF1tAur7WXuM/z/epRd+HGGyPPx2Vv8=
 github.com/libregraph/lico v0.54.1-0.20220325072321-31efc3995d63/go.mod h1:KZ4X+bEbOQMSV6iPysZEqVO/Pa5Mvo7xhhcLwUNPjmw=
 github.com/linode/linodego v0.25.3/go.mod h1:GSBKPpjoQfxEfryoCRcgkuUOCuVtGHWhzI8OMdycNTE=
diff --git a/ocis-pkg/config/config.go b/ocis-pkg/config/config.go
index aa3af173757..76ba265f073 100644
--- a/ocis-pkg/config/config.go
+++ b/ocis-pkg/config/config.go
@@ -9,6 +9,7 @@ import (
 	authbasic "github.com/owncloud/ocis/v2/services/auth-basic/pkg/config"
 	authbearer "github.com/owncloud/ocis/v2/services/auth-bearer/pkg/config"
 	authmachine "github.com/owncloud/ocis/v2/services/auth-machine/pkg/config"
+	eventhistory "github.com/owncloud/ocis/v2/services/eventhistory/pkg/config"
 	frontend "github.com/owncloud/ocis/v2/services/frontend/pkg/config"
 	gateway "github.com/owncloud/ocis/v2/services/gateway/pkg/config"
 	graph "github.com/owncloud/ocis/v2/services/graph/pkg/config"
@@ -84,6 +85,7 @@ type Config struct {
 	AuthBasic         *authbasic.Config      `yaml:"auth_basic"`
 	AuthBearer        *authbearer.Config     `yaml:"auth_bearer"`
 	AuthMachine       *authmachine.Config    `yaml:"auth_machine"`
+	EventHistory      *eventhistory.Config   `yaml:"eventhistory"`
 	Frontend          *frontend.Config       `yaml:"frontend"`
 	Gateway           *gateway.Config        `yaml:"gateway"`
 	Graph             *graph.Config          `yaml:"graph"`
diff --git a/ocis-pkg/config/defaultconfig.go b/ocis-pkg/config/defaultconfig.go
index fd527e95109..67d056eaf59 100644
--- a/ocis-pkg/config/defaultconfig.go
+++ b/ocis-pkg/config/defaultconfig.go
@@ -7,6 +7,7 @@ import (
 	authbasic "github.com/owncloud/ocis/v2/services/auth-basic/pkg/config/defaults"
 	authbearer "github.com/owncloud/ocis/v2/services/auth-bearer/pkg/config/defaults"
 	authmachine "github.com/owncloud/ocis/v2/services/auth-machine/pkg/config/defaults"
+	eventhistory "github.com/owncloud/ocis/v2/services/eventhistory/pkg/config/defaults"
 	frontend "github.com/owncloud/ocis/v2/services/frontend/pkg/config/defaults"
 	gateway "github.com/owncloud/ocis/v2/services/gateway/pkg/config/defaults"
 	graph "github.com/owncloud/ocis/v2/services/graph/pkg/config/defaults"
@@ -48,6 +49,7 @@ func DefaultConfig() *Config {
 		AuthBasic:         authbasic.DefaultConfig(),
 		AuthBearer:        authbearer.DefaultConfig(),
 		AuthMachine:       authmachine.DefaultConfig(),
+		EventHistory:      eventhistory.DefaultConfig(),
 		Frontend:          frontend.DefaultConfig(),
 		Gateway:           gateway.DefaultConfig(),
 		Graph:             graph.DefaultConfig(),
diff --git a/ocis-pkg/roles/manager.go b/ocis-pkg/roles/manager.go
index 651970a9252..b92132e9214 100644
--- a/ocis-pkg/roles/manager.go
+++ b/ocis-pkg/roles/manager.go
@@ -29,7 +29,7 @@ type Manager struct {
 func NewManager(o ...Option) Manager {
 	opts := newOptions(o...)
 
-	nStore := ocisstore.GetStore(opts.storeOptions)
+	nStore := ocisstore.Create(opts.storeOptions...)
 	return Manager{
 		cache:       nStore,
 		roleService: opts.roleService,
diff --git a/ocis-pkg/roles/option.go b/ocis-pkg/roles/option.go
index 772f0ef6477..ede1d403271 100644
--- a/ocis-pkg/roles/option.go
+++ b/ocis-pkg/roles/option.go
@@ -8,7 +8,7 @@ import (
 
 // Options are all the possible options.
 type Options struct {
-	storeOptions ocisstore.OcisStoreOptions
+	storeOptions []ocisstore.Option
 	logger       log.Logger
 	roleService  settingssvc.RoleService
 }
@@ -30,7 +30,8 @@ func RoleService(rs settingssvc.RoleService) Option {
 	}
 }
 
-func StoreOptions(storeOpts ocisstore.OcisStoreOptions) Option {
+// StoreOptions are the options for the store
+func StoreOptions(storeOpts []ocisstore.Option) Option {
 	return func(o *Options) {
 		o.storeOptions = storeOpts
 	}
diff --git a/ocis-pkg/store/options.go b/ocis-pkg/store/options.go
new file mode 100644
index 00000000000..f2671211613
--- /dev/null
+++ b/ocis-pkg/store/options.go
@@ -0,0 +1,50 @@
+package store
+
+import "time"
+
+// Option provides an option to configure the store
+type Option func(*Options)
+
+// Type defines the type of the store
+func Type(typ string) Option {
+	return func(o *Options) {
+		o.Type = typ
+	}
+}
+
+// Addresses defines the addresses where the store can be reached
+func Addresses(addrs ...string) Option {
+	return func(o *Options) {
+		o.Addresses = addrs
+	}
+}
+
+// Database defines the Database the store should use
+func Database(db string) Option {
+	return func(o *Options) {
+		o.Database = db
+	}
+}
+
+// Table defines the table the store should use
+func Table(t string) Option {
+	return func(o *Options) {
+		o.Table = t
+	}
+}
+
+// Size defines the maximum capacity of the store.
+// Only applicable when using "ocmem" store
+func Size(s int) Option {
+	return func(o *Options) {
+		o.Size = s
+	}
+}
+
+// TTL defines the time to life for elements in the store.
+// Only applicable when using "natsjs" store
+func TTL(t time.Duration) Option {
+	return func(o *Options) {
+		o.TTL = t
+	}
+}
diff --git a/ocis-pkg/store/store.go b/ocis-pkg/store/store.go
index 14d91d28793..380e0952832 100644
--- a/ocis-pkg/store/store.go
+++ b/ocis-pkg/store/store.go
@@ -2,8 +2,11 @@ package store
 
 import (
 	"context"
-	"strings"
+	"time"
 
+	natsjs "github.com/go-micro/plugins/v4/store/nats-js"
+	"github.com/go-micro/plugins/v4/store/redis"
+	"github.com/nats-io/nats.go"
 	"github.com/owncloud/ocis/v2/ocis-pkg/store/etcd"
 	"github.com/owncloud/ocis/v2/ocis-pkg/store/memory"
 	"go-micro.dev/v4/store"
@@ -11,7 +14,8 @@ import (
 
 var ocMemStore *store.Store
 
-type OcisStoreOptions struct {
+// Options are the options to configure the store
+type Options struct {
 	// Type determines the implementation:
 	// * "noop", for a noop store (it does nothing)
 	// * "etcd", for etcd
@@ -20,10 +24,8 @@ type OcisStoreOptions struct {
 	// * "memory", for a in-memory implementation, which is the default if noone matches
 	Type string
 
-	// Address is a comma-separated list of nodes that the store
-	// will use. This is currently usable only with the etcd implementation. If it
-	// isn't provided, "127.0.0.1:2379" will be the only node used.
-	Address string
+	// Address is a list of nodes that the store will use.
+	Addresses []string
 
 	// Size configures the maximum capacity of the cache for
 	// the "ocmem" implementation, in number of items that the cache can hold per table.
@@ -31,33 +33,50 @@ type OcisStoreOptions struct {
 	// The parameter only affects to the "ocmem" implementation, the rest will ignore it.
 	// If an invalid value is used, the default of 512 will be used instead.
 	Size int
+
+	// Database the store should use (optional)
+	Database string
+
+	// Table the store should use (optional)
+	Table string
+
+	// TTL is the time to life for documents stored in the store
+	TTL time.Duration
 }
 
-// GetStore returns a configured key-value store
+// Create returns a configured key-value store
 //
 // Each microservice (or whatever piece is using the store) should use the
 // options available in the interface's operations to choose the right database
 // and table to prevent collisions with other microservices.
 // Recommended approach is to use "services" or "ocis-pkg" for the database,
 // and "services/<service-name>/" or "ocis-pkg/<pkg>/" for the package name.
-func GetStore(ocisOpts OcisStoreOptions) store.Store {
-	var s store.Store
-
-	addresses := strings.Split(ocisOpts.Address, ",")
-	opts := []store.Option{
-		store.Nodes(addresses...),
+func Create(opts ...Option) store.Store {
+	options := &Options{}
+	for _, o := range opts {
+		o(options)
 	}
 
-	switch ocisOpts.Type {
+	storeopts := storeOptions(options)
+
+	switch options.Type {
+	default:
+		// TODO: better to error in default case?
+		fallthrough
+	case "mem":
+		return store.NewMemoryStore(storeopts...)
 	case "noop":
-		s = store.NewNoopStore(opts...)
+		return store.NewNoopStore(storeopts...)
 	case "etcd":
-		s = etcd.NewEtcdStore(opts...)
+		return etcd.NewEtcdStore(storeopts...)
+	case "redis":
+		// FIXME redis plugin does not support redis cluster, sentinel or ring -> needs upstream patch or our implementation
+		return redis.NewStore(storeopts...)
 	case "ocmem":
 		if ocMemStore == nil {
 			var memStore store.Store
 
-			sizeNum := ocisOpts.Size
+			sizeNum := options.Size
 			if sizeNum <= 0 {
 				memStore = memory.NewMultiMemStore()
 			} else {
@@ -73,9 +92,37 @@ func GetStore(ocisOpts OcisStoreOptions) store.Store {
 			}
 			ocMemStore = &memStore
 		}
-		s = *ocMemStore
-	default:
-		s = store.NewMemoryStore(opts...)
+		return *ocMemStore
+	case "nats-js":
+		// TODO nats needs a DefaultTTL option as it does not support per Write TTL ...
+		// FIXME nats has restrictions on the key, we cannot use slashes AFAICT
+		// host, port, clusterid
+		return natsjs.NewStore(
+			append(storeopts,
+				natsjs.NatsOptions(nats.Options{Name: "TODO"}),
+				natsjs.DefaultTTL(options.TTL),
+			)...,
+		) // TODO test with ocis nats
 	}
-	return s
+}
+
+func storeOptions(o *Options) []store.Option {
+	var opts []store.Option
+
+	if o.Addresses != nil {
+		opts = append(opts, store.Nodes(o.Addresses...))
+	}
+
+	if o.Database != "" {
+		opts = append(opts, store.Database(o.Database))
+
+	}
+
+	if o.Table != "" {
+		opts = append(opts, store.Table(o.Table))
+
+	}
+
+	return opts
+
 }
diff --git a/ocis/pkg/runtime/service/service.go b/ocis/pkg/runtime/service/service.go
index 84a25679f34..517d6418d0b 100644
--- a/ocis/pkg/runtime/service/service.go
+++ b/ocis/pkg/runtime/service/service.go
@@ -24,6 +24,7 @@ import (
 	appRegistry "github.com/owncloud/ocis/v2/services/app-registry/pkg/command"
 	authbasic "github.com/owncloud/ocis/v2/services/auth-basic/pkg/command"
 	authmachine "github.com/owncloud/ocis/v2/services/auth-machine/pkg/command"
+	eventhistory "github.com/owncloud/ocis/v2/services/eventhistory/pkg/command"
 	frontend "github.com/owncloud/ocis/v2/services/frontend/pkg/command"
 	gateway "github.com/owncloud/ocis/v2/services/gateway/pkg/command"
 	graph "github.com/owncloud/ocis/v2/services/graph/pkg/command"
@@ -129,6 +130,7 @@ func NewService(options ...Option) (*Service, error) {
 	s.ServicesRegistry[opts.Config.Notifications.Service.Name] = notifications.NewSutureService
 	s.ServicesRegistry[opts.Config.Search.Service.Name] = search.NewSutureService
 	s.ServicesRegistry[opts.Config.Postprocessing.Service.Name] = postprocessing.NewSutureService
+	s.ServicesRegistry[opts.Config.EventHistory.Service.Name] = eventhistory.NewSutureService
 
 	// populate delayed services
 	s.Delayed[opts.Config.Sharing.Service.Name] = sharing.NewSutureService
diff --git a/protogen/gen/ocis/messages/eventhistory/v0/eventhistory.pb.go b/protogen/gen/ocis/messages/eventhistory/v0/eventhistory.pb.go
new file mode 100644
index 00000000000..3722b7ec0b8
--- /dev/null
+++ b/protogen/gen/ocis/messages/eventhistory/v0/eventhistory.pb.go
@@ -0,0 +1,170 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// 	protoc-gen-go v1.28.1
+// 	protoc        (unknown)
+// source: ocis/messages/eventhistory/v0/eventhistory.proto
+
+package v0
+
+import (
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	reflect "reflect"
+	sync "sync"
+)
+
+const (
+	// Verify that this generated code is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+	// Verify that runtime/protoimpl is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+type Event struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// REQUIRED.
+	Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"`
+	// REQUIRED.
+	Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"`
+	// REQUIRED
+	Event []byte `protobuf:"bytes,3,opt,name=event,proto3" json:"event,omitempty"`
+}
+
+func (x *Event) Reset() {
+	*x = Event{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_ocis_messages_eventhistory_v0_eventhistory_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *Event) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Event) ProtoMessage() {}
+
+func (x *Event) ProtoReflect() protoreflect.Message {
+	mi := &file_ocis_messages_eventhistory_v0_eventhistory_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use Event.ProtoReflect.Descriptor instead.
+func (*Event) Descriptor() ([]byte, []int) {
+	return file_ocis_messages_eventhistory_v0_eventhistory_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *Event) GetType() string {
+	if x != nil {
+		return x.Type
+	}
+	return ""
+}
+
+func (x *Event) GetId() string {
+	if x != nil {
+		return x.Id
+	}
+	return ""
+}
+
+func (x *Event) GetEvent() []byte {
+	if x != nil {
+		return x.Event
+	}
+	return nil
+}
+
+var File_ocis_messages_eventhistory_v0_eventhistory_proto protoreflect.FileDescriptor
+
+var file_ocis_messages_eventhistory_v0_eventhistory_proto_rawDesc = []byte{
+	0x0a, 0x30, 0x6f, 0x63, 0x69, 0x73, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2f,
+	0x65, 0x76, 0x65, 0x6e, 0x74, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x76, 0x30, 0x2f,
+	0x65, 0x76, 0x65, 0x6e, 0x74, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f,
+	0x74, 0x6f, 0x12, 0x1d, 0x6f, 0x63, 0x69, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
+	0x73, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x76,
+	0x30, 0x22, 0x41, 0x0a, 0x05, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79,
+	0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x0e,
+	0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14,
+	0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x65,
+	0x76, 0x65, 0x6e, 0x74, 0x42, 0x48, 0x5a, 0x46, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63,
+	0x6f, 0x6d, 0x2f, 0x6f, 0x77, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6f, 0x63, 0x69, 0x73,
+	0x2f, 0x76, 0x32, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x67, 0x65, 0x6e, 0x2f, 0x67, 0x65, 0x6e,
+	0x2f, 0x6f, 0x63, 0x69, 0x73, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2f, 0x65,
+	0x76, 0x65, 0x6e, 0x74, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x76, 0x30, 0x62, 0x06,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+	file_ocis_messages_eventhistory_v0_eventhistory_proto_rawDescOnce sync.Once
+	file_ocis_messages_eventhistory_v0_eventhistory_proto_rawDescData = file_ocis_messages_eventhistory_v0_eventhistory_proto_rawDesc
+)
+
+func file_ocis_messages_eventhistory_v0_eventhistory_proto_rawDescGZIP() []byte {
+	file_ocis_messages_eventhistory_v0_eventhistory_proto_rawDescOnce.Do(func() {
+		file_ocis_messages_eventhistory_v0_eventhistory_proto_rawDescData = protoimpl.X.CompressGZIP(file_ocis_messages_eventhistory_v0_eventhistory_proto_rawDescData)
+	})
+	return file_ocis_messages_eventhistory_v0_eventhistory_proto_rawDescData
+}
+
+var file_ocis_messages_eventhistory_v0_eventhistory_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
+var file_ocis_messages_eventhistory_v0_eventhistory_proto_goTypes = []interface{}{
+	(*Event)(nil), // 0: ocis.messages.eventhistory.v0.Event
+}
+var file_ocis_messages_eventhistory_v0_eventhistory_proto_depIdxs = []int32{
+	0, // [0:0] is the sub-list for method output_type
+	0, // [0:0] is the sub-list for method input_type
+	0, // [0:0] is the sub-list for extension type_name
+	0, // [0:0] is the sub-list for extension extendee
+	0, // [0:0] is the sub-list for field type_name
+}
+
+func init() { file_ocis_messages_eventhistory_v0_eventhistory_proto_init() }
+func file_ocis_messages_eventhistory_v0_eventhistory_proto_init() {
+	if File_ocis_messages_eventhistory_v0_eventhistory_proto != nil {
+		return
+	}
+	if !protoimpl.UnsafeEnabled {
+		file_ocis_messages_eventhistory_v0_eventhistory_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Event); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_ocis_messages_eventhistory_v0_eventhistory_proto_rawDesc,
+			NumEnums:      0,
+			NumMessages:   1,
+			NumExtensions: 0,
+			NumServices:   0,
+		},
+		GoTypes:           file_ocis_messages_eventhistory_v0_eventhistory_proto_goTypes,
+		DependencyIndexes: file_ocis_messages_eventhistory_v0_eventhistory_proto_depIdxs,
+		MessageInfos:      file_ocis_messages_eventhistory_v0_eventhistory_proto_msgTypes,
+	}.Build()
+	File_ocis_messages_eventhistory_v0_eventhistory_proto = out.File
+	file_ocis_messages_eventhistory_v0_eventhistory_proto_rawDesc = nil
+	file_ocis_messages_eventhistory_v0_eventhistory_proto_goTypes = nil
+	file_ocis_messages_eventhistory_v0_eventhistory_proto_depIdxs = nil
+}
diff --git a/protogen/gen/ocis/messages/eventhistory/v0/eventhistory.pb.micro.go b/protogen/gen/ocis/messages/eventhistory/v0/eventhistory.pb.micro.go
new file mode 100644
index 00000000000..78778e77887
--- /dev/null
+++ b/protogen/gen/ocis/messages/eventhistory/v0/eventhistory.pb.micro.go
@@ -0,0 +1,15 @@
+// Code generated by protoc-gen-micro. DO NOT EDIT.
+// source: ocis/messages/eventhistory/v0/eventhistory.proto
+
+package v0
+
+import (
+	fmt "fmt"
+	proto "google.golang.org/protobuf/proto"
+	math "math"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
diff --git a/protogen/gen/ocis/messages/eventhistory/v0/eventhistory.swagger.json b/protogen/gen/ocis/messages/eventhistory/v0/eventhistory.swagger.json
new file mode 100644
index 00000000000..a70931e4eee
--- /dev/null
+++ b/protogen/gen/ocis/messages/eventhistory/v0/eventhistory.swagger.json
@@ -0,0 +1,43 @@
+{
+  "swagger": "2.0",
+  "info": {
+    "title": "ocis/messages/eventhistory/v0/eventhistory.proto",
+    "version": "version not set"
+  },
+  "consumes": [
+    "application/json"
+  ],
+  "produces": [
+    "application/json"
+  ],
+  "paths": {},
+  "definitions": {
+    "protobufAny": {
+      "type": "object",
+      "properties": {
+        "@type": {
+          "type": "string"
+        }
+      },
+      "additionalProperties": {}
+    },
+    "rpcStatus": {
+      "type": "object",
+      "properties": {
+        "code": {
+          "type": "integer",
+          "format": "int32"
+        },
+        "message": {
+          "type": "string"
+        },
+        "details": {
+          "type": "array",
+          "items": {
+            "$ref": "#/definitions/protobufAny"
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/protogen/gen/ocis/services/eventhistory/v0/eventhistory.pb.go b/protogen/gen/ocis/services/eventhistory/v0/eventhistory.pb.go
new file mode 100644
index 00000000000..b52f403a437
--- /dev/null
+++ b/protogen/gen/ocis/services/eventhistory/v0/eventhistory.pb.go
@@ -0,0 +1,256 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// 	protoc-gen-go v1.28.1
+// 	protoc        (unknown)
+// source: ocis/services/eventhistory/v0/eventhistory.proto
+
+package v0
+
+import (
+	_ "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options"
+	v0 "github.com/owncloud/ocis/v2/protogen/gen/ocis/messages/eventhistory/v0"
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	reflect "reflect"
+	sync "sync"
+)
+
+const (
+	// Verify that this generated code is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+	// Verify that runtime/protoimpl is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+// A request to retrieve events
+type GetEventsRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// the ids of the events we want to get
+	Ids []string `protobuf:"bytes,1,rep,name=ids,proto3" json:"ids,omitempty"`
+}
+
+func (x *GetEventsRequest) Reset() {
+	*x = GetEventsRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_ocis_services_eventhistory_v0_eventhistory_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GetEventsRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetEventsRequest) ProtoMessage() {}
+
+func (x *GetEventsRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_ocis_services_eventhistory_v0_eventhistory_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetEventsRequest.ProtoReflect.Descriptor instead.
+func (*GetEventsRequest) Descriptor() ([]byte, []int) {
+	return file_ocis_services_eventhistory_v0_eventhistory_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *GetEventsRequest) GetIds() []string {
+	if x != nil {
+		return x.Ids
+	}
+	return nil
+}
+
+// The service response
+type GetEventsResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Events []*v0.Event `protobuf:"bytes,1,rep,name=events,proto3" json:"events,omitempty"`
+}
+
+func (x *GetEventsResponse) Reset() {
+	*x = GetEventsResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_ocis_services_eventhistory_v0_eventhistory_proto_msgTypes[1]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GetEventsResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetEventsResponse) ProtoMessage() {}
+
+func (x *GetEventsResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_ocis_services_eventhistory_v0_eventhistory_proto_msgTypes[1]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetEventsResponse.ProtoReflect.Descriptor instead.
+func (*GetEventsResponse) Descriptor() ([]byte, []int) {
+	return file_ocis_services_eventhistory_v0_eventhistory_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *GetEventsResponse) GetEvents() []*v0.Event {
+	if x != nil {
+		return x.Events
+	}
+	return nil
+}
+
+var File_ocis_services_eventhistory_v0_eventhistory_proto protoreflect.FileDescriptor
+
+var file_ocis_services_eventhistory_v0_eventhistory_proto_rawDesc = []byte{
+	0x0a, 0x30, 0x6f, 0x63, 0x69, 0x73, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f,
+	0x65, 0x76, 0x65, 0x6e, 0x74, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x76, 0x30, 0x2f,
+	0x65, 0x76, 0x65, 0x6e, 0x74, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x70, 0x72, 0x6f,
+	0x74, 0x6f, 0x12, 0x1d, 0x6f, 0x63, 0x69, 0x73, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
+	0x73, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x76,
+	0x30, 0x1a, 0x30, 0x6f, 0x63, 0x69, 0x73, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73,
+	0x2f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x76, 0x30,
+	0x2f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d,
+	0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e,
+	0x73, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x22, 0x24, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73,
+	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x69, 0x64, 0x73, 0x18, 0x01,
+	0x20, 0x03, 0x28, 0x09, 0x52, 0x03, 0x69, 0x64, 0x73, 0x22, 0x51, 0x0a, 0x11, 0x47, 0x65, 0x74,
+	0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3c,
+	0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24,
+	0x2e, 0x6f, 0x63, 0x69, 0x73, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x65,
+	0x76, 0x65, 0x6e, 0x74, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x76, 0x30, 0x2e, 0x45,
+	0x76, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x32, 0x85, 0x01, 0x0a,
+	0x13, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x53, 0x65, 0x72,
+	0x76, 0x69, 0x63, 0x65, 0x12, 0x6e, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74,
+	0x73, 0x12, 0x2f, 0x2e, 0x6f, 0x63, 0x69, 0x73, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
+	0x73, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x76,
+	0x30, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
+	0x73, 0x74, 0x1a, 0x30, 0x2e, 0x6f, 0x63, 0x69, 0x73, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
+	0x65, 0x73, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x2e,
+	0x76, 0x30, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x42, 0xeb, 0x02, 0x5a, 0x43, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,
+	0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x77, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6f, 0x63, 0x69,
+	0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x67, 0x65, 0x6e, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x6f,
+	0x63, 0x69, 0x73, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x65, 0x76, 0x65,
+	0x6e, 0x74, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x76, 0x30, 0x92, 0x41, 0xa2, 0x02,
+	0x12, 0xb8, 0x01, 0x0a, 0x22, 0x6f, 0x77, 0x6e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x20, 0x49, 0x6e,
+	0x66, 0x69, 0x6e, 0x69, 0x74, 0x65, 0x20, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x20, 0x74, 0x68, 0x75,
+	0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x73, 0x22, 0x47, 0x0a, 0x0d, 0x6f, 0x77, 0x6e, 0x43, 0x6c,
+	0x6f, 0x75, 0x64, 0x20, 0x47, 0x6d, 0x62, 0x48, 0x12, 0x20, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a,
+	0x2f, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x77, 0x6e,
+	0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6f, 0x63, 0x69, 0x73, 0x1a, 0x14, 0x73, 0x75, 0x70, 0x70,
+	0x6f, 0x72, 0x74, 0x40, 0x6f, 0x77, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x63, 0x6f, 0x6d,
+	0x2a, 0x42, 0x0a, 0x0a, 0x41, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2d, 0x32, 0x2e, 0x30, 0x12, 0x34,
+	0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63,
+	0x6f, 0x6d, 0x2f, 0x6f, 0x77, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x6f, 0x63, 0x69, 0x73,
+	0x2f, 0x62, 0x6c, 0x6f, 0x62, 0x2f, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x2f, 0x4c, 0x49, 0x43,
+	0x45, 0x4e, 0x53, 0x45, 0x32, 0x05, 0x31, 0x2e, 0x30, 0x2e, 0x30, 0x2a, 0x02, 0x01, 0x02, 0x32,
+	0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f,
+	0x6e, 0x3a, 0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a,
+	0x73, 0x6f, 0x6e, 0x72, 0x3d, 0x0a, 0x10, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72,
+	0x20, 0x4d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x12, 0x29, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f,
+	0x2f, 0x6f, 0x77, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x64, 0x65, 0x76, 0x2f, 0x73, 0x65,
+	0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x74, 0x68, 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c,
+	0x73, 0x2f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+	file_ocis_services_eventhistory_v0_eventhistory_proto_rawDescOnce sync.Once
+	file_ocis_services_eventhistory_v0_eventhistory_proto_rawDescData = file_ocis_services_eventhistory_v0_eventhistory_proto_rawDesc
+)
+
+func file_ocis_services_eventhistory_v0_eventhistory_proto_rawDescGZIP() []byte {
+	file_ocis_services_eventhistory_v0_eventhistory_proto_rawDescOnce.Do(func() {
+		file_ocis_services_eventhistory_v0_eventhistory_proto_rawDescData = protoimpl.X.CompressGZIP(file_ocis_services_eventhistory_v0_eventhistory_proto_rawDescData)
+	})
+	return file_ocis_services_eventhistory_v0_eventhistory_proto_rawDescData
+}
+
+var file_ocis_services_eventhistory_v0_eventhistory_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
+var file_ocis_services_eventhistory_v0_eventhistory_proto_goTypes = []interface{}{
+	(*GetEventsRequest)(nil),  // 0: ocis.services.eventhistory.v0.GetEventsRequest
+	(*GetEventsResponse)(nil), // 1: ocis.services.eventhistory.v0.GetEventsResponse
+	(*v0.Event)(nil),          // 2: ocis.messages.eventhistory.v0.Event
+}
+var file_ocis_services_eventhistory_v0_eventhistory_proto_depIdxs = []int32{
+	2, // 0: ocis.services.eventhistory.v0.GetEventsResponse.events:type_name -> ocis.messages.eventhistory.v0.Event
+	0, // 1: ocis.services.eventhistory.v0.EventHistoryService.GetEvents:input_type -> ocis.services.eventhistory.v0.GetEventsRequest
+	1, // 2: ocis.services.eventhistory.v0.EventHistoryService.GetEvents:output_type -> ocis.services.eventhistory.v0.GetEventsResponse
+	2, // [2:3] is the sub-list for method output_type
+	1, // [1:2] is the sub-list for method input_type
+	1, // [1:1] is the sub-list for extension type_name
+	1, // [1:1] is the sub-list for extension extendee
+	0, // [0:1] is the sub-list for field type_name
+}
+
+func init() { file_ocis_services_eventhistory_v0_eventhistory_proto_init() }
+func file_ocis_services_eventhistory_v0_eventhistory_proto_init() {
+	if File_ocis_services_eventhistory_v0_eventhistory_proto != nil {
+		return
+	}
+	if !protoimpl.UnsafeEnabled {
+		file_ocis_services_eventhistory_v0_eventhistory_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetEventsRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_ocis_services_eventhistory_v0_eventhistory_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetEventsResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_ocis_services_eventhistory_v0_eventhistory_proto_rawDesc,
+			NumEnums:      0,
+			NumMessages:   2,
+			NumExtensions: 0,
+			NumServices:   1,
+		},
+		GoTypes:           file_ocis_services_eventhistory_v0_eventhistory_proto_goTypes,
+		DependencyIndexes: file_ocis_services_eventhistory_v0_eventhistory_proto_depIdxs,
+		MessageInfos:      file_ocis_services_eventhistory_v0_eventhistory_proto_msgTypes,
+	}.Build()
+	File_ocis_services_eventhistory_v0_eventhistory_proto = out.File
+	file_ocis_services_eventhistory_v0_eventhistory_proto_rawDesc = nil
+	file_ocis_services_eventhistory_v0_eventhistory_proto_goTypes = nil
+	file_ocis_services_eventhistory_v0_eventhistory_proto_depIdxs = nil
+}
diff --git a/protogen/gen/ocis/services/eventhistory/v0/eventhistory.pb.micro.go b/protogen/gen/ocis/services/eventhistory/v0/eventhistory.pb.micro.go
new file mode 100644
index 00000000000..194b6445cd2
--- /dev/null
+++ b/protogen/gen/ocis/services/eventhistory/v0/eventhistory.pb.micro.go
@@ -0,0 +1,91 @@
+// Code generated by protoc-gen-micro. DO NOT EDIT.
+// source: ocis/services/eventhistory/v0/eventhistory.proto
+
+package v0
+
+import (
+	fmt "fmt"
+	_ "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options"
+	_ "github.com/owncloud/ocis/v2/protogen/gen/ocis/messages/eventhistory/v0"
+	proto "google.golang.org/protobuf/proto"
+	math "math"
+)
+
+import (
+	context "context"
+	api "go-micro.dev/v4/api"
+	client "go-micro.dev/v4/client"
+	server "go-micro.dev/v4/server"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ api.Endpoint
+var _ context.Context
+var _ client.Option
+var _ server.Option
+
+// Api Endpoints for EventHistoryService service
+
+func NewEventHistoryServiceEndpoints() []*api.Endpoint {
+	return []*api.Endpoint{}
+}
+
+// Client API for EventHistoryService service
+
+type EventHistoryService interface {
+	// returns the specified events
+	GetEvents(ctx context.Context, in *GetEventsRequest, opts ...client.CallOption) (*GetEventsResponse, error)
+}
+
+type eventHistoryService struct {
+	c    client.Client
+	name string
+}
+
+func NewEventHistoryService(name string, c client.Client) EventHistoryService {
+	return &eventHistoryService{
+		c:    c,
+		name: name,
+	}
+}
+
+func (c *eventHistoryService) GetEvents(ctx context.Context, in *GetEventsRequest, opts ...client.CallOption) (*GetEventsResponse, error) {
+	req := c.c.NewRequest(c.name, "EventHistoryService.GetEvents", in)
+	out := new(GetEventsResponse)
+	err := c.c.Call(ctx, req, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+// Server API for EventHistoryService service
+
+type EventHistoryServiceHandler interface {
+	// returns the specified events
+	GetEvents(context.Context, *GetEventsRequest, *GetEventsResponse) error
+}
+
+func RegisterEventHistoryServiceHandler(s server.Server, hdlr EventHistoryServiceHandler, opts ...server.HandlerOption) error {
+	type eventHistoryService interface {
+		GetEvents(ctx context.Context, in *GetEventsRequest, out *GetEventsResponse) error
+	}
+	type EventHistoryService struct {
+		eventHistoryService
+	}
+	h := &eventHistoryServiceHandler{hdlr}
+	return s.Handle(s.NewHandler(&EventHistoryService{h}, opts...))
+}
+
+type eventHistoryServiceHandler struct {
+	EventHistoryServiceHandler
+}
+
+func (h *eventHistoryServiceHandler) GetEvents(ctx context.Context, in *GetEventsRequest, out *GetEventsResponse) error {
+	return h.EventHistoryServiceHandler.GetEvents(ctx, in, out)
+}
diff --git a/protogen/gen/ocis/services/eventhistory/v0/eventhistory.swagger.json b/protogen/gen/ocis/services/eventhistory/v0/eventhistory.swagger.json
new file mode 100644
index 00000000000..5e39ce4c828
--- /dev/null
+++ b/protogen/gen/ocis/services/eventhistory/v0/eventhistory.swagger.json
@@ -0,0 +1,95 @@
+{
+  "swagger": "2.0",
+  "info": {
+    "title": "ownCloud Infinite Scale thumbnails",
+    "version": "1.0.0",
+    "contact": {
+      "name": "ownCloud GmbH",
+      "url": "https://github.com/owncloud/ocis",
+      "email": "support@owncloud.com"
+    },
+    "license": {
+      "name": "Apache-2.0",
+      "url": "https://github.com/owncloud/ocis/blob/master/LICENSE"
+    }
+  },
+  "tags": [
+    {
+      "name": "EventHistoryService"
+    }
+  ],
+  "schemes": [
+    "http",
+    "https"
+  ],
+  "consumes": [
+    "application/json"
+  ],
+  "produces": [
+    "application/json"
+  ],
+  "paths": {},
+  "definitions": {
+    "protobufAny": {
+      "type": "object",
+      "properties": {
+        "@type": {
+          "type": "string"
+        }
+      },
+      "additionalProperties": {}
+    },
+    "rpcStatus": {
+      "type": "object",
+      "properties": {
+        "code": {
+          "type": "integer",
+          "format": "int32"
+        },
+        "message": {
+          "type": "string"
+        },
+        "details": {
+          "type": "array",
+          "items": {
+            "$ref": "#/definitions/protobufAny"
+          }
+        }
+      }
+    },
+    "v0Event": {
+      "type": "object",
+      "properties": {
+        "type": {
+          "type": "string",
+          "description": "REQUIRED."
+        },
+        "id": {
+          "type": "string",
+          "description": "REQUIRED."
+        },
+        "event": {
+          "type": "string",
+          "format": "byte",
+          "title": "REQUIRED"
+        }
+      }
+    },
+    "v0GetEventsResponse": {
+      "type": "object",
+      "properties": {
+        "events": {
+          "type": "array",
+          "items": {
+            "$ref": "#/definitions/v0Event"
+          }
+        }
+      },
+      "title": "The service response"
+    }
+  },
+  "externalDocs": {
+    "description": "Developer Manual",
+    "url": "https://owncloud.dev/services/thumbnails/"
+  }
+}
diff --git a/protogen/proto/buf.gen.yaml b/protogen/proto/buf.gen.yaml
index c71c259a979..37f05fce272 100644
--- a/protogen/proto/buf.gen.yaml
+++ b/protogen/proto/buf.gen.yaml
@@ -21,7 +21,9 @@ plugins:
          ocis.services.thumbnails.v0;\
          ocis.messages.thumbnails.v0;\
          ocis.services.store.v0;\
-         ocis.messages.store.v0"
+         ocis.messages.store.v0;\
+         ocis.services.eventhistory.v0;\
+         ocis.messages.eventhistory.v0"
 
   - name: openapiv2
     path: ../../.bingo/protoc-gen-openapiv2
diff --git a/protogen/proto/ocis/messages/eventhistory/v0/eventhistory.proto b/protogen/proto/ocis/messages/eventhistory/v0/eventhistory.proto
new file mode 100644
index 00000000000..39faedd7207
--- /dev/null
+++ b/protogen/proto/ocis/messages/eventhistory/v0/eventhistory.proto
@@ -0,0 +1,16 @@
+syntax = "proto3";
+
+package ocis.messages.eventhistory.v0;
+
+option go_package = "github.com/owncloud/ocis/v2/protogen/gen/ocis/messages/eventhistory/v0";
+
+message Event {
+    // REQUIRED.
+    string type = 1;
+    // REQUIRED.
+    string id = 2;
+    // REQUIRED
+    bytes event = 3;
+    
+}
+
diff --git a/protogen/proto/ocis/services/eventhistory/v0/eventhistory.proto b/protogen/proto/ocis/services/eventhistory/v0/eventhistory.proto
new file mode 100644
index 00000000000..ae80681b9c7
--- /dev/null
+++ b/protogen/proto/ocis/services/eventhistory/v0/eventhistory.proto
@@ -0,0 +1,50 @@
+
+syntax = "proto3";
+
+package ocis.services.eventhistory.v0;
+
+option go_package = "github.com/owncloud/ocis/protogen/gen/ocis/services/eventhistory/v0";
+
+import "ocis/messages/eventhistory/v0/eventhistory.proto";
+import "protoc-gen-openapiv2/options/annotations.proto";
+
+option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
+  info: {
+    title: "ownCloud Infinite Scale thumbnails";
+    version: "1.0.0";
+    contact: {
+      name: "ownCloud GmbH";
+      url: "https://github.com/owncloud/ocis";
+      email: "support@owncloud.com";
+    };
+    license: {
+      name: "Apache-2.0";
+      url: "https://github.com/owncloud/ocis/blob/master/LICENSE";
+    };
+  };
+  schemes: HTTP;
+  schemes: HTTPS;
+  consumes: "application/json";
+  produces: "application/json";
+  external_docs: {
+    description: "Developer Manual";
+    url: "https://owncloud.dev/services/thumbnails/";
+  };
+};
+
+// A Service for storing events
+service EventHistoryService {
+    // returns the specified events
+    rpc GetEvents(GetEventsRequest) returns (GetEventsResponse);
+}
+
+// A request to retrieve events
+message GetEventsRequest {
+    // the ids of the events we want to get
+    repeated string ids = 1;
+}
+
+// The service response
+message GetEventsResponse {
+    repeated ocis.messages.eventhistory.v0.Event events = 1;
+}
diff --git a/services/eventhistory/Makefile b/services/eventhistory/Makefile
new file mode 100644
index 00000000000..067ddff4e8a
--- /dev/null
+++ b/services/eventhistory/Makefile
@@ -0,0 +1,37 @@
+SHELL := bash
+NAME := eventhistory
+
+include ../../.make/recursion.mk
+
+############ tooling ############
+ifneq (, $(shell command -v 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
+
+.PHONY: docs-generate
+docs-generate: config-docs-generate
+
+############ generate ############
+include ../../.make/generate.mk
+
+.PHONY: ci-go-generate
+ci-go-generate: # CI runs ci-node-generate automatically before this target
+
+.PHONY: ci-node-generate
+ci-node-generate:
+
+############ licenses ############
+.PHONY: ci-node-check-licenses
+ci-node-check-licenses:
+
+.PHONY: ci-node-save-licenses
+ci-node-save-licenses:
diff --git a/services/eventhistory/README.md b/services/eventhistory/README.md
new file mode 100644
index 00000000000..08dc4527370
--- /dev/null
+++ b/services/eventhistory/README.md
@@ -0,0 +1,30 @@
+# Eventhistory Service
+
+The `eventhistory` consumes all events from the configured event system like NATS, stores them and allows other services to retrieve them via an eventid.
+
+## Prerequisites
+
+Running the eventhistory service without an event sytem like NATS is not possible.
+
+## Consuming
+
+The `eventhistory` services consumes all events from the configured event sytem.
+
+## Storing
+
+The `eventhistory` service stores each consumed event via the configured store in `EVENTHISTORY_STORE_TYPE`. Possible stores are:
+  -   `mem`: Basic in-memory store and the default.
+  -   `ocmem`: Advanced in-memory store allowing max size.
+  -   `redis`: Stores data in a configured redis cluster.
+  -   `etcd`: Stores data in a configured etcd cluster.
+  -   `nats-js`: Stores data using key-value-store feature of [nats jetstream](https://docs.nats.io/nats-concepts/jetstream/key-value-store)
+  -   `noop`: Stores nothing. Useful for testing. Not recommended in productive enviroments.
+
+1.  Note that in-memory stores are by nature not reboot persistent.
+2.  Though usually not necessary, a database name and a database table can be configured for event stores if the event store supports this. Generally not applicapable for stores of type `in-memory`. These settings are blank by default which means that the standard settings of the configured store applies.
+3.  Events stay in the store for 2 weeks by default. Use `EVENTHISTORY_RECORD_EXPIRY` to adjust this value.
+4.  The eventhistory service can be scaled if not using `in-memory` stores and the stores are configured identically over all instances.
+
+## Retrieving
+
+Other services can call the `eventhistory` service via a grpc call to retrieve events. The request must contain the eventid that should be retrieved.
diff --git a/services/eventhistory/cmd/eventhistory/main.go b/services/eventhistory/cmd/eventhistory/main.go
new file mode 100644
index 00000000000..d2172949bc6
--- /dev/null
+++ b/services/eventhistory/cmd/eventhistory/main.go
@@ -0,0 +1,14 @@
+package main
+
+import (
+	"os"
+
+	"github.com/owncloud/ocis/v2/services/eventhistory/pkg/command"
+	"github.com/owncloud/ocis/v2/services/eventhistory/pkg/config/defaults"
+)
+
+func main() {
+	if err := command.Execute(defaults.DefaultConfig()); err != nil {
+		os.Exit(1)
+	}
+}
diff --git a/services/eventhistory/pkg/command/health.go b/services/eventhistory/pkg/command/health.go
new file mode 100644
index 00000000000..2d39a1d5130
--- /dev/null
+++ b/services/eventhistory/pkg/command/health.go
@@ -0,0 +1,18 @@
+package command
+
+import (
+	"github.com/owncloud/ocis/v2/services/eventhistory/pkg/config"
+	"github.com/urfave/cli/v2"
+)
+
+// Health is the entrypoint for the health command.
+func Health(cfg *config.Config) *cli.Command {
+	return &cli.Command{
+		Name:  "health",
+		Usage: "Check health status",
+		Action: func(c *cli.Context) error {
+			// Not implemented
+			return nil
+		},
+	}
+}
diff --git a/services/eventhistory/pkg/command/root.go b/services/eventhistory/pkg/command/root.go
new file mode 100644
index 00000000000..73107f10856
--- /dev/null
+++ b/services/eventhistory/pkg/command/root.go
@@ -0,0 +1,59 @@
+package command
+
+import (
+	"context"
+	"os"
+
+	"github.com/owncloud/ocis/v2/ocis-pkg/clihelper"
+	ociscfg "github.com/owncloud/ocis/v2/ocis-pkg/config"
+	"github.com/owncloud/ocis/v2/services/eventhistory/pkg/config"
+	"github.com/thejerf/suture/v4"
+	"github.com/urfave/cli/v2"
+)
+
+// GetCommands provides all commands for this service
+func GetCommands(cfg *config.Config) cli.Commands {
+	return []*cli.Command{
+		// start this service
+		Server(cfg),
+
+		// interaction with this service
+
+		// infos about this service
+		Health(cfg),
+		Version(cfg),
+	}
+}
+
+// Execute is the entry point for the eventhistory command.
+func Execute(cfg *config.Config) error {
+	app := clihelper.DefaultApp(&cli.App{
+		Name:     "eventhistory",
+		Usage:    "starts eventhistory service",
+		Commands: GetCommands(cfg),
+	})
+
+	return app.Run(os.Args)
+}
+
+// SutureService allows for the eventhistory command to be embedded and supervised by a suture supervisor tree.
+type SutureService struct {
+	cfg *config.Config
+}
+
+// NewSutureService creates a new eventhistory.SutureService
+func NewSutureService(cfg *ociscfg.Config) suture.Service {
+	cfg.Notifications.Commons = cfg.Commons
+	return SutureService{
+		cfg: cfg.EventHistory,
+	}
+}
+
+func (s SutureService) Serve(ctx context.Context) error {
+	s.cfg.Context = ctx
+	if err := Execute(s.cfg); err != nil {
+		return err
+	}
+
+	return nil
+}
diff --git a/services/eventhistory/pkg/command/server.go b/services/eventhistory/pkg/command/server.go
new file mode 100644
index 00000000000..cbf1678c903
--- /dev/null
+++ b/services/eventhistory/pkg/command/server.go
@@ -0,0 +1,91 @@
+package command
+
+import (
+	"context"
+	"fmt"
+	"strings"
+
+	"github.com/cs3org/reva/v2/pkg/events/stream"
+	"github.com/oklog/run"
+	"github.com/owncloud/ocis/v2/ocis-pkg/config/configlog"
+	ogrpc "github.com/owncloud/ocis/v2/ocis-pkg/service/grpc"
+	"github.com/owncloud/ocis/v2/ocis-pkg/store"
+	"github.com/owncloud/ocis/v2/ocis-pkg/version"
+	"github.com/owncloud/ocis/v2/services/eventhistory/pkg/config"
+	"github.com/owncloud/ocis/v2/services/eventhistory/pkg/config/parser"
+	"github.com/owncloud/ocis/v2/services/eventhistory/pkg/logging"
+	"github.com/owncloud/ocis/v2/services/eventhistory/pkg/metrics"
+	"github.com/owncloud/ocis/v2/services/eventhistory/pkg/server/grpc"
+	"github.com/urfave/cli/v2"
+)
+
+// Server is the entrypoint for the server command.
+func Server(cfg *config.Config) *cli.Command {
+	return &cli.Command{
+		Name:     "server",
+		Usage:    fmt.Sprintf("start the %s service without runtime (unsupervised mode)", cfg.Service.Name),
+		Category: "server",
+		Before: func(c *cli.Context) error {
+			return configlog.ReturnFatal(parser.ParseConfig(cfg))
+		},
+		Action: func(c *cli.Context) error {
+			logger := logging.Configure(cfg.Service.Name, cfg.Log)
+			err := ogrpc.Configure(ogrpc.GetClientOptions(cfg.GRPCClientTLS)...)
+			if err != nil {
+				return err
+			}
+
+			var (
+				gr          = run.Group{}
+				ctx, cancel = func() (context.Context, context.CancelFunc) {
+					if cfg.Context == nil {
+						return context.WithCancel(context.Background())
+					}
+					return context.WithCancel(cfg.Context)
+				}()
+				metrics = metrics.New()
+			)
+
+			defer cancel()
+
+			metrics.BuildInfo.WithLabelValues(version.GetString()).Set(1)
+
+			consumer, err := stream.NatsFromConfig(stream.NatsConfig(cfg.Events))
+			if err != nil {
+				return err
+			}
+
+			st := store.Create(
+				store.Type(cfg.Store.Type),
+				store.Addresses(strings.Split(cfg.Store.Addresses, ",")...),
+				store.Database(cfg.Store.Database),
+				store.Table(cfg.Store.Table),
+				store.TTL(cfg.Store.RecordExpiry),
+			)
+
+			service := grpc.NewService(
+				grpc.Logger(logger),
+				grpc.Context(ctx),
+				grpc.Config(cfg),
+				grpc.Name(cfg.Service.Name),
+				grpc.Namespace(cfg.GRPC.Namespace),
+				grpc.Address(cfg.GRPC.Addr),
+				grpc.Metrics(metrics),
+				grpc.Consumer(consumer),
+				grpc.Store(st),
+			)
+
+			gr.Add(service.Run, func(err error) {
+				logger.Error().
+					Err(err).
+					Str("server", "grpc").
+					Msg("Shutting Down server")
+
+				cancel()
+			})
+
+			return gr.Run()
+
+		},
+	}
+}
diff --git a/services/eventhistory/pkg/command/version.go b/services/eventhistory/pkg/command/version.go
new file mode 100644
index 00000000000..8962d1a21b6
--- /dev/null
+++ b/services/eventhistory/pkg/command/version.go
@@ -0,0 +1,19 @@
+package command
+
+import (
+	"github.com/owncloud/ocis/v2/services/eventhistory/pkg/config"
+	"github.com/urfave/cli/v2"
+)
+
+// Version prints the service versions of all running instances.
+func Version(cfg *config.Config) *cli.Command {
+	return &cli.Command{
+		Name:     "version",
+		Usage:    "print the version of this binary and the running service instances",
+		Category: "info",
+		Action: func(c *cli.Context) error {
+			// not implemented
+			return nil
+		},
+	}
+}
diff --git a/services/eventhistory/pkg/config/config.go b/services/eventhistory/pkg/config/config.go
new file mode 100644
index 00000000000..aef20002d4f
--- /dev/null
+++ b/services/eventhistory/pkg/config/config.go
@@ -0,0 +1,52 @@
+package config
+
+import (
+	"context"
+	"time"
+
+	"github.com/owncloud/ocis/v2/ocis-pkg/shared"
+)
+
+// Config combines all available configuration parts.
+type Config struct {
+	Commons *shared.Commons `yaml:"-"` // don't use this directly as configuration for a service
+
+	Service Service `yaml:"-"`
+
+	Log   *Log  `yaml:"log"`
+	Debug Debug `yaml:"debug"`
+
+	GRPC          GRPCConfig            `yaml:"grpc"`
+	GRPCClientTLS *shared.GRPCClientTLS `yaml:"grpc_client_tls"`
+
+	Events Events `yaml:"events"`
+	Store  Store  `yaml:"store"`
+
+	Context context.Context `yaml:"-"`
+}
+
+// GRPCConfig defines the available grpc configuration.
+type GRPCConfig struct {
+	Addr      string                 `ocisConfig:"addr" env:"EVENTHISTORY_GRPC_ADDR" desc:"The bind address of the GRPC service."`
+	Namespace string                 `ocisConfig:"-" yaml:"-"`
+	TLS       *shared.GRPCServiceTLS `yaml:"tls"`
+}
+
+// Store configures the store to use
+type Store struct {
+	Type         string        `yaml:"type" env:"EVENTHISTORY_STORE_TYPE" desc:"The type of the eventhistory store. Supported values are: 'mem', 'ocmem', 'etcd', 'redis', 'nats-js', 'noop'. See the text description for details."`
+	Addresses    string        `yaml:"addresses" env:"EVENTHISTORY_STORE_ADDRESSES" desc:"A comma separated list of addresses to access the configured store. This has no effect when 'in-memory' stores are configured. Note that the behaviour how addresses are used is dependent on the library of the configured store."`
+	Database     string        `yaml:"database" env:"EVENTHISTORY_STORE_DATABASE" desc:"(optional) The database name the configured store should use. This has no effect when 'in-memory' stores are configured."`
+	Table        string        `yaml:"table" env:"EVENTHISTORY_STORE_TABLE" desc:"(optional) The database table the store should use. This has no effect when 'in-memory' stores are configured."`
+	RecordExpiry time.Duration `yaml:"record_expiry" env:"EVENTHISTORY_RECORD_EXPIRY" desc:"Time to life for events in the store. The duration can be set as number followed by a unit identifier like s, m or h. Defaults to '336h' (2 weeks)."`
+	Size         int           `yaml:"size" env:"EVENTHISTORY_STORE_SIZE" desc:"The maximum quantity of items in the store. Only applies when store type 'ocmem' is configured. Defaults to 512."`
+}
+
+// Events combines the configuration options for the event bus.
+type Events struct {
+	Endpoint             string `yaml:"endpoint" env:"EVENTHISTORY_EVENTS_ENDPOINT" desc:"The address of the event system. The event system is the message queuing service. It is used as message broker for the microservice architecture."`
+	Cluster              string `yaml:"cluster" env:"EVENTHISTORY_EVENTS_CLUSTER" desc:"The clusterID of the event system. The event system is the message queuing service. It is used as message broker for the microservice architecture. Mandatory when using NATS as event system."`
+	TLSInsecure          bool   `yaml:"tls_insecure" env:"OCIS_INSECURE;EVENTHISTORY_EVENTS_TLS_INSECURE" desc:"Whether to verify the server TLS certificates."`
+	TLSRootCACertificate string `yaml:"tls_root_ca_certificate" env:"EVENTHISTORY_EVENTS_TLS_ROOT_CA_CERTIFICATE" desc:"The root CA certificate used to validate the server's TLS certificate. If provided NOTIFICATIONS_EVENTS_TLS_INSECURE will be seen as false."`
+	EnableTLS            bool   `yaml:"enable_tls" env:"OCIS_EVENTS_ENABLE_TLS;EVENTHISTORY_EVENTS_ENABLE_TLS" desc:"Enable TLS for the connection to the events broker. The events broker is the ocis service which receives and delivers events between the services.."`
+}
diff --git a/services/eventhistory/pkg/config/debug.go b/services/eventhistory/pkg/config/debug.go
new file mode 100644
index 00000000000..ea42a0f188c
--- /dev/null
+++ b/services/eventhistory/pkg/config/debug.go
@@ -0,0 +1,9 @@
+package config
+
+// Debug defines the available debug configuration.
+type Debug struct {
+	Addr   string `yaml:"addr" env:"EVENTHISTORY_DEBUG_ADDR" desc:"Bind address of the debug server, where metrics, health, config and debug endpoints will be exposed."`
+	Token  string `yaml:"token" env:"EVENTHISTORY_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint."`
+	Pprof  bool   `yaml:"pprof" env:"EVENTHISTORY_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling."`
+	Zpages bool   `yaml:"zpages" env:"EVENTHISTORY_DEBUG_ZPAGES" desc:"Enables zpages, which can be used for collecting and viewing in-memory traces."`
+}
diff --git a/services/eventhistory/pkg/config/defaults/defaultconfig.go b/services/eventhistory/pkg/config/defaults/defaultconfig.go
new file mode 100644
index 00000000000..a61d411c4b9
--- /dev/null
+++ b/services/eventhistory/pkg/config/defaults/defaultconfig.go
@@ -0,0 +1,74 @@
+package defaults
+
+import (
+	"time"
+
+	"github.com/owncloud/ocis/v2/ocis-pkg/shared"
+	"github.com/owncloud/ocis/v2/services/eventhistory/pkg/config"
+)
+
+// FullDefaultConfig returns the full default config
+func FullDefaultConfig() *config.Config {
+	cfg := DefaultConfig()
+	EnsureDefaults(cfg)
+	Sanitize(cfg)
+	return cfg
+}
+
+// DefaultConfig return the default configuration
+func DefaultConfig() *config.Config {
+	return &config.Config{
+		Service: config.Service{
+			Name: "eventhistory",
+		},
+		Events: config.Events{
+			Endpoint:  "127.0.0.1:9233",
+			Cluster:   "ocis-cluster",
+			EnableTLS: false,
+		},
+		Store: config.Store{
+			Type:         "mem",
+			RecordExpiry: 336 * time.Hour,
+		},
+		GRPC: config.GRPCConfig{
+			Addr:      "127.0.0.1:0",
+			Namespace: "com.owncloud.api",
+		},
+	}
+}
+
+// EnsureDefaults ensures the config contains default values
+func EnsureDefaults(cfg *config.Config) {
+	// provide with defaults for shared logging, since we need a valid destination address for "envdecode".
+	if cfg.Log == nil && cfg.Commons != nil && cfg.Commons.Log != nil {
+		cfg.Log = &config.Log{
+			Level:  cfg.Commons.Log.Level,
+			Pretty: cfg.Commons.Log.Pretty,
+			Color:  cfg.Commons.Log.Color,
+			File:   cfg.Commons.Log.File,
+		}
+	} else if cfg.Log == nil {
+		cfg.Log = &config.Log{}
+	}
+
+	if cfg.GRPCClientTLS == nil {
+		cfg.GRPCClientTLS = &shared.GRPCClientTLS{}
+		if cfg.Commons != nil && cfg.Commons.GRPCClientTLS != nil {
+			cfg.GRPCClientTLS = cfg.Commons.GRPCClientTLS
+		}
+	}
+
+	if cfg.GRPC.TLS == nil {
+		cfg.GRPC.TLS = &shared.GRPCServiceTLS{}
+		if cfg.Commons != nil && cfg.Commons.GRPCServiceTLS != nil {
+			cfg.GRPC.TLS.Enabled = cfg.Commons.GRPCServiceTLS.Enabled
+			cfg.GRPC.TLS.Cert = cfg.Commons.GRPCServiceTLS.Cert
+			cfg.GRPC.TLS.Key = cfg.Commons.GRPCServiceTLS.Key
+		}
+	}
+}
+
+// Sanitize sanitizes the config
+func Sanitize(cfg *config.Config) {
+	// nothing to sanitize here atm
+}
diff --git a/services/eventhistory/pkg/config/log.go b/services/eventhistory/pkg/config/log.go
new file mode 100644
index 00000000000..a420c6adbdd
--- /dev/null
+++ b/services/eventhistory/pkg/config/log.go
@@ -0,0 +1,9 @@
+package config
+
+// Log defines the available log configuration.
+type Log struct {
+	Level  string `mapstructure:"level" env:"OCIS_LOG_LEVEL;EVENTHISTORY_LOG_LEVEL" desc:"The log level. Valid values are: \"panic\", \"fatal\", \"error\", \"warn\", \"info\", \"debug\", \"trace\"."`
+	Pretty bool   `mapstructure:"pretty" env:"OCIS_LOG_PRETTY;EVENTHISTORY_LOG_PRETTY" desc:"Activates pretty log output."`
+	Color  bool   `mapstructure:"color" env:"OCIS_LOG_COLOR;EVENTHISTORY_LOG_COLOR" desc:"Activates colorized log output."`
+	File   string `mapstructure:"file" env:"OCIS_LOG_FILE;EVENTHISTORY_LOG_FILE" desc:"The path to the log file. Activates logging to this file if set."`
+}
diff --git a/services/eventhistory/pkg/config/parser/parse.go b/services/eventhistory/pkg/config/parser/parse.go
new file mode 100644
index 00000000000..196ef16a74f
--- /dev/null
+++ b/services/eventhistory/pkg/config/parser/parse.go
@@ -0,0 +1,38 @@
+package parser
+
+import (
+	"errors"
+
+	ociscfg "github.com/owncloud/ocis/v2/ocis-pkg/config"
+	"github.com/owncloud/ocis/v2/services/eventhistory/pkg/config"
+	"github.com/owncloud/ocis/v2/services/eventhistory/pkg/config/defaults"
+
+	"github.com/owncloud/ocis/v2/ocis-pkg/config/envdecode"
+)
+
+// ParseConfig loads configuration from known paths.
+func ParseConfig(cfg *config.Config) error {
+	_, err := ociscfg.BindSourcesToStructs(cfg.Service.Name, cfg)
+	if err != nil {
+		return err
+	}
+
+	defaults.EnsureDefaults(cfg)
+
+	// load all env variables relevant to the config in the current context.
+	if err := envdecode.Decode(cfg); err != nil {
+		// no environment variable set for this config is an expected "error"
+		if !errors.Is(err, envdecode.ErrNoTargetFieldsAreSet) {
+			return err
+		}
+	}
+
+	defaults.Sanitize(cfg)
+
+	return Validate(cfg)
+}
+
+// Validate validates the config
+func Validate(cfg *config.Config) error {
+	return nil
+}
diff --git a/services/eventhistory/pkg/config/service.go b/services/eventhistory/pkg/config/service.go
new file mode 100644
index 00000000000..d1eac383f0b
--- /dev/null
+++ b/services/eventhistory/pkg/config/service.go
@@ -0,0 +1,6 @@
+package config
+
+// Service defines the available service configuration.
+type Service struct {
+	Name string `yaml:"-"`
+}
diff --git a/services/eventhistory/pkg/logging/logging.go b/services/eventhistory/pkg/logging/logging.go
new file mode 100644
index 00000000000..ec867698c67
--- /dev/null
+++ b/services/eventhistory/pkg/logging/logging.go
@@ -0,0 +1,17 @@
+package logging
+
+import (
+	"github.com/owncloud/ocis/v2/ocis-pkg/log"
+	"github.com/owncloud/ocis/v2/services/eventhistory/pkg/config"
+)
+
+// LoggerFromConfig initializes a service-specific logger instance.
+func Configure(name string, cfg *config.Log) log.Logger {
+	return log.NewLogger(
+		log.Name(name),
+		log.Level(cfg.Level),
+		log.Pretty(cfg.Pretty),
+		log.Color(cfg.Color),
+		log.File(cfg.File),
+	)
+}
diff --git a/services/eventhistory/pkg/metrics/metrics.go b/services/eventhistory/pkg/metrics/metrics.go
new file mode 100644
index 00000000000..58fe68bc0a2
--- /dev/null
+++ b/services/eventhistory/pkg/metrics/metrics.go
@@ -0,0 +1,35 @@
+package metrics
+
+import "github.com/prometheus/client_golang/prometheus"
+
+var (
+	// Namespace defines the namespace for the defines metrics.
+	Namespace = "ocis"
+
+	// Subsystem defines the subsystem for the defines metrics.
+	Subsystem = "eventhistory"
+)
+
+// Metrics defines the available metrics of this service.
+type Metrics struct {
+	BuildInfo *prometheus.GaugeVec
+}
+
+// New initializes the available metrics.
+func New() *Metrics {
+	m := &Metrics{
+		BuildInfo: prometheus.NewGaugeVec(prometheus.GaugeOpts{
+			Namespace: Namespace,
+			Subsystem: Subsystem,
+			Name:      "build_info",
+			Help:      "Build information",
+		}, []string{"version"}),
+	}
+
+	_ = prometheus.Register(
+		m.BuildInfo,
+	)
+
+	// TODO: implement metrics
+	return m
+}
diff --git a/services/eventhistory/pkg/server/grpc/option.go b/services/eventhistory/pkg/server/grpc/option.go
new file mode 100644
index 00000000000..3653d8dae8a
--- /dev/null
+++ b/services/eventhistory/pkg/server/grpc/option.go
@@ -0,0 +1,110 @@
+package grpc
+
+import (
+	"context"
+
+	"github.com/cs3org/reva/v2/pkg/events"
+	"github.com/owncloud/ocis/v2/ocis-pkg/log"
+	"github.com/owncloud/ocis/v2/services/eventhistory/pkg/config"
+	"github.com/owncloud/ocis/v2/services/eventhistory/pkg/metrics"
+	"github.com/urfave/cli/v2"
+	"go-micro.dev/v4/store"
+)
+
+// Option defines a single option function.
+type Option func(o *Options)
+
+// Options defines the available options for this package.
+type Options struct {
+	Name      string
+	Address   string
+	Logger    log.Logger
+	Context   context.Context
+	Config    *config.Config
+	Metrics   *metrics.Metrics
+	Namespace string
+	Flags     []cli.Flag
+	Store     store.Store
+	Consumer  events.Consumer
+}
+
+// newOptions initializes the available default options.
+func newOptions(opts ...Option) Options {
+	opt := Options{}
+
+	for _, o := range opts {
+		o(&opt)
+	}
+
+	return opt
+}
+
+// Logger provides a function to set the logger option.
+func Logger(val log.Logger) Option {
+	return func(o *Options) {
+		o.Logger = val
+	}
+}
+
+// Name provides a name for the service.
+func Name(val string) Option {
+	return func(o *Options) {
+		o.Name = val
+	}
+}
+
+// Address provides an address for the service.
+func Address(val string) Option {
+	return func(o *Options) {
+		o.Address = val
+	}
+}
+
+// Context provides a function to set the context option.
+func Context(val context.Context) Option {
+	return func(o *Options) {
+		o.Context = val
+	}
+}
+
+// Config provides a function to set the config option.
+func Config(val *config.Config) Option {
+	return func(o *Options) {
+		o.Config = val
+	}
+}
+
+// Metrics provides a function to set the metrics option.
+func Metrics(val *metrics.Metrics) Option {
+	return func(o *Options) {
+		o.Metrics = val
+	}
+}
+
+// Namespace provides a function to set the namespace option.
+func Namespace(val string) Option {
+	return func(o *Options) {
+		o.Namespace = val
+	}
+}
+
+// Flags provides a function to set the flags option.
+func Flags(flags []cli.Flag) Option {
+	return func(o *Options) {
+		o.Flags = append(o.Flags, flags...)
+	}
+}
+
+// Store provides a function to configure the store
+func Store(store store.Store) Option {
+	return func(o *Options) {
+		o.Store = store
+	}
+}
+
+// Consumer provides a function to configure the consumer
+func Consumer(consumer events.Consumer) Option {
+	return func(o *Options) {
+		o.Consumer = consumer
+	}
+}
diff --git a/services/eventhistory/pkg/server/grpc/server.go b/services/eventhistory/pkg/server/grpc/server.go
new file mode 100644
index 00000000000..38b06713038
--- /dev/null
+++ b/services/eventhistory/pkg/server/grpc/server.go
@@ -0,0 +1,46 @@
+package grpc
+
+import (
+	"github.com/owncloud/ocis/v2/ocis-pkg/service/grpc"
+	"github.com/owncloud/ocis/v2/ocis-pkg/version"
+	ehsvc "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/eventhistory/v0"
+	svc "github.com/owncloud/ocis/v2/services/eventhistory/pkg/service"
+)
+
+// NewService initializes the grpc service and server.
+func NewService(opts ...Option) grpc.Service {
+	options := newOptions(opts...)
+
+	service, err := grpc.NewService(
+		grpc.TLSEnabled(options.Config.GRPC.TLS.Enabled),
+		grpc.TLSCert(
+			options.Config.GRPC.TLS.Cert,
+			options.Config.GRPC.TLS.Key,
+		),
+		grpc.Logger(options.Logger),
+		grpc.Namespace(options.Namespace),
+		grpc.Name(options.Name),
+		grpc.Version(version.GetString()),
+		grpc.Address(options.Address),
+		grpc.Context(options.Context),
+		grpc.Flags(options.Flags...),
+		grpc.Version(version.GetString()),
+	)
+	if err != nil {
+		options.Logger.Fatal().Err(err).Msg("Error creating event history service")
+		return grpc.Service{}
+	}
+
+	eh, err := svc.NewEventHistoryService(options.Config, options.Consumer, options.Store, options.Logger)
+	if err != nil {
+		options.Logger.Fatal().Err(err).Msg("Error creating event history service")
+		return grpc.Service{}
+	}
+
+	_ = ehsvc.RegisterEventHistoryServiceHandler(
+		service.Server(),
+		eh,
+	)
+
+	return service
+}
diff --git a/services/eventhistory/pkg/service/service.go b/services/eventhistory/pkg/service/service.go
new file mode 100644
index 00000000000..9a34f1d7491
--- /dev/null
+++ b/services/eventhistory/pkg/service/service.go
@@ -0,0 +1,77 @@
+package service
+
+import (
+	"context"
+	"fmt"
+
+	"github.com/cs3org/reva/v2/pkg/events"
+	"github.com/owncloud/ocis/v2/ocis-pkg/log"
+	ehmsg "github.com/owncloud/ocis/v2/protogen/gen/ocis/messages/eventhistory/v0"
+	ehsvc "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/eventhistory/v0"
+	"github.com/owncloud/ocis/v2/services/eventhistory/pkg/config"
+	"go-micro.dev/v4/store"
+)
+
+// EventHistoryService is the service responsible for event history
+type EventHistoryService struct {
+	ch    <-chan events.Event
+	store store.Store
+	cfg   *config.Config
+	log   log.Logger
+}
+
+// NewEventHistoryService returns an EventHistory service
+func NewEventHistoryService(cfg *config.Config, consumer events.Consumer, store store.Store, log log.Logger) (*EventHistoryService, error) {
+	if consumer == nil || store == nil {
+		return nil, fmt.Errorf("Need non nil consumer (%v) and store (%v) to work properly", consumer, store)
+	}
+
+	ch, err := events.ConsumeAll(consumer, "evhistory")
+	if err != nil {
+		return nil, err
+	}
+
+	eh := &EventHistoryService{ch: ch, store: store, cfg: cfg, log: log}
+	go eh.StoreEvents()
+
+	return eh, nil
+}
+
+// StoreEvents consumes all events and stores them in the store. Will block
+func (eh *EventHistoryService) StoreEvents() {
+	for event := range eh.ch {
+		if err := eh.store.Write(&store.Record{
+			Key:    event.ID,
+			Value:  event.Event.([]byte),
+			Expiry: eh.cfg.Store.RecordExpiry,
+			Metadata: map[string]interface{}{
+				"type": event.Type,
+			},
+		}); err != nil {
+			// we can't store. That's it for us.
+			eh.log.Error().Err(err).Str("eventid", event.ID).Msg("could not store event")
+			return
+		}
+	}
+}
+
+// GetEvents allows to retrieve events from the eventstore by id
+func (eh *EventHistoryService) GetEvents(ctx context.Context, req *ehsvc.GetEventsRequest, resp *ehsvc.GetEventsResponse) error {
+	for _, id := range req.Ids {
+		evs, err := eh.store.Read(id)
+		if err != nil {
+			if err != store.ErrNotFound {
+				eh.log.Error().Err(err).Str("eventid", id).Msg("could not read event")
+			}
+			continue
+		}
+
+		resp.Events = append(resp.Events, &ehmsg.Event{
+			Id:    id,
+			Event: evs[0].Value,
+			Type:  evs[0].Metadata["type"].(string),
+		})
+	}
+
+	return nil
+}
diff --git a/services/graph/pkg/service/v0/service.go b/services/graph/pkg/service/v0/service.go
index ad6705e78a9..9cc30c0ba90 100644
--- a/services/graph/pkg/service/v0/service.go
+++ b/services/graph/pkg/service/v0/service.go
@@ -7,6 +7,7 @@ import (
 	"net/http"
 	"os"
 	"strconv"
+	"strings"
 	"time"
 
 	"github.com/go-chi/chi/v5"
@@ -156,10 +157,10 @@ func NewService(opts ...Option) (Graph, error) {
 
 	roleManager := options.RoleManager
 	if roleManager == nil {
-		storeOptions := store.OcisStoreOptions{
-			Type:    options.Config.CacheStore.Type,
-			Address: options.Config.CacheStore.Address,
-			Size:    options.Config.CacheStore.Size,
+		storeOptions := []store.Option{
+			store.Type(options.Config.CacheStore.Type),
+			store.Addresses(strings.Split(options.Config.CacheStore.Address, ",")...),
+			store.Size(options.Config.CacheStore.Size),
 		}
 		m := roles.NewManager(
 			roles.StoreOptions(storeOptions),
diff --git a/services/graph/pkg/service/v0/users_filter.go b/services/graph/pkg/service/v0/users_filter.go
index 63a6579cd5f..a836f5378a7 100644
--- a/services/graph/pkg/service/v0/users_filter.go
+++ b/services/graph/pkg/service/v0/users_filter.go
@@ -8,6 +8,10 @@ import (
 	libregraph "github.com/owncloud/libre-graph-api-go"
 )
 
+const (
+	appRoleID = "appRoleId"
+)
+
 func invalidFilterError() error {
 	return godata.BadRequestError("invalid filter")
 }
@@ -53,22 +57,51 @@ func (g Graph) applyFilterLogical(ctx context.Context, req *godata.GoDataRequest
 
 func (g Graph) applyFilterLogicalAnd(ctx context.Context, req *godata.GoDataRequest, operand1 *godata.ParseNode, operand2 *godata.ParseNode) (users []*libregraph.User, err error) {
 	logger := g.logger.SubloggerWithRequestID(ctx)
-	results := make([][]*libregraph.User, 0, 2)
+	var res1, res2 []*libregraph.User
 
-	for _, node := range []*godata.ParseNode{operand1, operand2} {
-		res, err := g.applyUserFilter(ctx, req, node)
+	// The appRoleAssignmentFilter requires a full list of user, get try to avoid a full user listing and
+	// process the other part of the filter first, if that is an appRoleAssignmentFilter as well, we have
+	// to bite the bullet and get a full user listing anyway
+	if matched, property, value := g.isAppRoleAssignmentFilter(ctx, operand1); matched {
+		logger.Debug().Str("property", property).Str("value", value).Msg("delay processing of approleAssignments filter")
+		if property != appRoleID {
+			return users, unsupportedFilterError()
+		}
+		res2, err = g.applyUserFilter(ctx, req, operand2)
 		if err != nil {
-			return users, err
+			return []*libregraph.User{}, err
+		}
+		logger.Debug().Str("property", property).Str("value", value).Msg("applying approleAssignments filter on result set")
+		return g.filterUsersByAppRoleID(ctx, value, res2)
+	}
+
+	// 1st part is no appRoleAssignmentFilter, run the filter query
+	res1, err = g.applyUserFilter(ctx, req, operand1)
+	if err != nil {
+		return []*libregraph.User{}, err
+	}
+
+	// Now check 2nd part for appRoleAssignmentFilter and apply that using the result return from the first
+	// filter
+	if matched, property, value := g.isAppRoleAssignmentFilter(ctx, operand2); matched {
+		if property != appRoleID {
+			return users, unsupportedFilterError()
 		}
-		logger.Debug().Interface("subfilter", res).Msg("result part")
-		results = append(results, res)
+		logger.Debug().Str("property", property).Str("value", value).Msg("applying approleAssignments filter on result set")
+		return g.filterUsersByAppRoleID(ctx, value, res1)
+	}
+
+	// 2nd part is no appRoleAssignmentFilter either
+	res2, err = g.applyUserFilter(ctx, req, operand2)
+	if err != nil {
+		return []*libregraph.User{}, err
 	}
 
-	// 'results' contains two slices of libregraph.Users now turn one of them
+	// We now have two slice with results of the subfilters. Now turn one of them
 	// into a map for efficiently getting the intersection of both slices
-	userSet := userSliceToMap(results[0])
+	userSet := userSliceToMap(res1)
 	var filteredUsers []*libregraph.User
-	for _, user := range results[1] {
+	for _, user := range res2 {
 		if _, found := userSet[user.GetId()]; found {
 			filteredUsers = append(filteredUsers, user)
 		}
@@ -81,16 +114,22 @@ func (g Graph) applyFilterLambda(ctx context.Context, req *godata.GoDataRequest,
 	if len(nodes) != 2 {
 		return users, invalidFilterError()
 	}
-	// We only support memberOf/any queries for now
-	if nodes[0].Token.Type != godata.ExpressionTokenLiteral || nodes[0].Token.Value != "memberOf" {
-		logger.Debug().Str("Token", nodes[0].Token.Value).Msg("unsupported relation for lambda filter")
-		return users, unsupportedFilterError()
-	}
+	// We only support the "any" operator for lambda queries for now
 	if nodes[1].Token.Type != godata.ExpressionTokenLambda || nodes[1].Token.Value != "any" {
 		logger.Debug().Str("Token", nodes[1].Token.Value).Msg("unsupported lambda filter")
 		return users, unsupportedFilterError()
 	}
-	return g.applyLambdaMemberOfAny(ctx, req, nodes[1].Children)
+	if nodes[0].Token.Type != godata.ExpressionTokenLiteral {
+		return users, unsupportedFilterError()
+	}
+	switch nodes[0].Token.Value {
+	case "memberOf":
+		return g.applyLambdaMemberOfAny(ctx, req, nodes[1].Children)
+	case "appRoleAssignments":
+		return g.applyLambdaAppRoleAssignmentAny(ctx, req, nodes[1].Children)
+	}
+	logger.Debug().Str("Token", nodes[0].Token.Value).Msg("unsupported relation for lambda filter")
+	return users, unsupportedFilterError()
 }
 
 func (g Graph) applyLambdaMemberOfAny(ctx context.Context, req *godata.GoDataRequest, nodes []*godata.ParseNode) (users []*libregraph.User, err error) {
@@ -126,22 +165,150 @@ func (g Graph) applyMemberOfEq(ctx context.Context, req *godata.GoDataRequest, n
 
 	switch nodes[0].Children[1].Token.Value {
 	case "id":
-		var filterValue string
-		switch nodes[1].Token.Type {
-		case godata.ExpressionTokenGuid:
-			filterValue = nodes[1].Token.Value
-		case godata.ExpressionTokenString:
-			// unquote
-			filterValue = strings.Trim(nodes[1].Token.Value, "'")
-		default:
+		filterValue, err := g.getUUIDTokenValue(ctx, nodes[1])
+		if err != nil {
 			return users, unsupportedFilterError()
 		}
+
 		logger.Debug().Str("property", nodes[0].Children[1].Token.Value).Str("value", filterValue).Msg("Filtering memberOf by group id")
 		return g.identityBackend.GetGroupMembers(ctx, filterValue, req)
 	default:
 		return users, unsupportedFilterError()
 	}
+}
+
+func (g Graph) applyLambdaAppRoleAssignmentAny(ctx context.Context, req *godata.GoDataRequest, nodes []*godata.ParseNode) (users []*libregraph.User, err error) {
+	if len(nodes) != 2 {
+		return users, invalidFilterError()
+	}
+
+	// First element is the "name" of the lambda function's parameter
+	if nodes[0].Token.Type != godata.ExpressionTokenLiteral {
+		return users, invalidFilterError()
+	}
+
+	// We only support the 'eq' expression for now
+	if nodes[1].Token.Type != godata.ExpressionTokenLogical || nodes[1].Token.Value != "eq" {
+		return users, unsupportedFilterError()
+	}
+	return g.applyAppRoleAssignmentEq(ctx, req, nodes[1].Children)
+}
+
+func (g Graph) applyAppRoleAssignmentEq(ctx context.Context, req *godata.GoDataRequest, nodes []*godata.ParseNode) (users []*libregraph.User, err error) {
+	logger := g.logger.SubloggerWithRequestID(ctx)
+	if len(nodes) != 2 {
+		return users, invalidFilterError()
+	}
+
+	if nodes[0].Token.Type != godata.ExpressionTokenNav {
+		return users, invalidFilterError()
+	}
 
+	if len(nodes[0].Children) != 2 {
+		return users, invalidFilterError()
+	}
+
+	if nodes[0].Children[1].Token.Value == appRoleID {
+		filterValue, err := g.getUUIDTokenValue(ctx, nodes[1])
+		if err != nil {
+			return users, unsupportedFilterError()
+		}
+
+		logger.Debug().Str("property", nodes[0].Children[1].Token.Value).Str("value", filterValue).Msg("Filtering appRoleAssignments by appRoleId")
+		if users, err = g.identityBackend.GetUsers(ctx, req); err != nil {
+			return users, err
+		}
+
+		return g.filterUsersByAppRoleID(ctx, filterValue, users)
+	}
+	return users, unsupportedFilterError()
+}
+
+func (g Graph) filterUsersByAppRoleID(ctx context.Context, id string, users []*libregraph.User) ([]*libregraph.User, error) {
+	// We're using a map for the results here, in order to avoid returning
+	// a user twice. The settings API, still has an issue that causes it to
+	// duplicate some assignments on restart:
+	// https://github.com/owncloud/ocis/issues/3432
+	resultUsersMap := make(map[string]*libregraph.User, len(users))
+	for _, user := range users {
+		assignments, err := g.fetchAppRoleAssignments(ctx, user.GetId())
+		if err != nil {
+			return users, err
+		}
+		for _, assignment := range assignments {
+			if assignment.GetAppRoleId() == id {
+				if _, ok := resultUsersMap[user.GetId()]; !ok {
+					resultUsersMap[user.GetId()] = user
+				}
+			}
+		}
+	}
+	resultUsers := make([]*libregraph.User, 0, len(resultUsersMap))
+	for _, user := range resultUsersMap {
+		resultUsers = append(resultUsers, user)
+	}
+	return resultUsers, nil
+}
+
+func (g Graph) getUUIDTokenValue(ctx context.Context, node *godata.ParseNode) (string, error) {
+	var value string
+	switch node.Token.Type {
+	case godata.ExpressionTokenGuid:
+		value = node.Token.Value
+	case godata.ExpressionTokenString:
+		// unquote
+		value = strings.Trim(node.Token.Value, "'")
+	default:
+		return "", unsupportedFilterError()
+	}
+	return value, nil
+}
+
+func (g Graph) isAppRoleAssignmentFilter(ctx context.Context, node *godata.ParseNode) (match bool, property string, filter string) {
+	if node.Token.Type != godata.ExpressionTokenLambdaNav {
+		return false, "", ""
+	}
+
+	if len(node.Children) != 2 {
+		return false, "", ""
+	}
+
+	if node.Children[0].Token.Type != godata.ExpressionTokenLiteral || node.Children[0].Token.Value != "appRoleAssignments" {
+		return false, "", ""
+	}
+
+	if node.Children[1].Token.Type != godata.ExpressionTokenLambda || node.Children[1].Token.Value != "any" {
+		return false, "", ""
+	}
+
+	if len(node.Children[1].Children) != 2 {
+		return false, "", ""
+	}
+	lambdaParam := node.Children[1].Children
+	// We only support the 'eq' expression for now
+	if lambdaParam[1].Token.Type != godata.ExpressionTokenLogical || lambdaParam[1].Token.Value != "eq" {
+		return false, "", ""
+	}
+
+	if len(lambdaParam[1].Children) != 2 {
+		return false, "", ""
+	}
+	expression := lambdaParam[1].Children
+	if expression[0].Token.Type != godata.ExpressionTokenNav || expression[0].Token.Value != "/" {
+		return false, "", ""
+	}
+
+	if len(expression[0].Children) != 2 {
+		return false, "", ""
+	}
+	if expression[0].Children[1].Token.Value != appRoleID {
+		return false, "", ""
+	}
+	filterValue, err := g.getUUIDTokenValue(ctx, expression[1])
+	if err != nil {
+		return false, "", ""
+	}
+	return true, appRoleID, filterValue
 }
 
 func userSliceToMap(users []*libregraph.User) map[string]*libregraph.User {
diff --git a/services/proxy/pkg/user/backend/cs3.go b/services/proxy/pkg/user/backend/cs3.go
index 13cb1bb4ed9..b37cd481336 100644
--- a/services/proxy/pkg/user/backend/cs3.go
+++ b/services/proxy/pkg/user/backend/cs3.go
@@ -3,7 +3,6 @@ package backend
 import (
 	"context"
 	"encoding/json"
-	"errors"
 	"fmt"
 	"io"
 	"net/http"
@@ -23,7 +22,6 @@ import (
 	settingssvc "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/settings/v0"
 	"github.com/owncloud/ocis/v2/services/graph/pkg/service/v0/errorcode"
 	settingsService "github.com/owncloud/ocis/v2/services/settings/pkg/service/v0"
-	merrors "go-micro.dev/v4/errors"
 	"go-micro.dev/v4/metadata"
 	"go-micro.dev/v4/selector"
 )
@@ -80,27 +78,26 @@ func (c *cs3backend) GetUserByClaims(ctx context.Context, claim, value string, w
 	if user.Id.Type != cs3.UserType_USER_TYPE_LIGHTWEIGHT {
 		roleIDs, err = loadRolesIDs(ctx, user.Id.OpaqueId, c.settingsRoleService)
 		if err != nil {
-			var merr *merrors.Error
-			if errors.As(err, &merr) && merr.Code == http.StatusNotFound {
-				// This user doesn't have a role assignment yet. Assign a
-				// default user role. At least until proper roles are provided. See
-				// https://github.com/owncloud/ocis/v2/issues/1825 for more context.
-				if user.Id.Type == cs3.UserType_USER_TYPE_PRIMARY {
-					c.logger.Info().Str("userid", user.Id.OpaqueId).Msg("user has no role assigned, assigning default user role")
-					ctx = metadata.Set(ctx, middleware.AccountID, user.Id.OpaqueId)
-					_, err := c.settingsRoleService.AssignRoleToUser(ctx, &settingssvc.AssignRoleToUserRequest{
-						AccountUuid: user.Id.OpaqueId,
-						RoleId:      settingsService.BundleUUIDRoleUser,
-					})
-					if err != nil {
-						c.logger.Error().Err(err).Msg("Could not add default role")
-						return nil, "", err
-					}
-					roleIDs = append(roleIDs, settingsService.BundleUUIDRoleUser)
+			c.logger.Error().Err(err).Msgf("Could not load roles")
+			return nil, "", err
+		}
+
+		if len(roleIDs) == 0 {
+			// This user doesn't have a role assignment yet. Assign a
+			// default user role. At least until proper roles are provided. See
+			// https://github.com/owncloud/ocis/v2/issues/1825 for more context.
+			if user.Id.Type == cs3.UserType_USER_TYPE_PRIMARY {
+				c.logger.Info().Str("userid", user.Id.OpaqueId).Msg("user has no role assigned, assigning default user role")
+				ctx = metadata.Set(ctx, middleware.AccountID, user.Id.OpaqueId)
+				_, err := c.settingsRoleService.AssignRoleToUser(ctx, &settingssvc.AssignRoleToUserRequest{
+					AccountUuid: user.Id.OpaqueId,
+					RoleId:      settingsService.BundleUUIDRoleUser,
+				})
+				if err != nil {
+					c.logger.Error().Err(err).Msg("Could not add default role")
+					return nil, "", err
 				}
-			} else {
-				c.logger.Error().Err(err).Msgf("Could not load roles")
-				return nil, "", err
+				roleIDs = append(roleIDs, settingsService.BundleUUIDRoleUser)
 			}
 		}
 	}
diff --git a/services/settings/pkg/config/config.go b/services/settings/pkg/config/config.go
index 390c740af0c..031cc7f5dca 100644
--- a/services/settings/pkg/config/config.go
+++ b/services/settings/pkg/config/config.go
@@ -22,10 +22,11 @@ type Config struct {
 
 	GRPCClientTLS *shared.GRPCClientTLS `yaml:"grpc_client_tls"`
 
-	StoreType string                `yaml:"store_type" env:"SETTINGS_STORE_TYPE" desc:"Store type configures the persistency driver. Supported values are \"metadata\" and \"filesystem\"."`
-	DataPath  string                `yaml:"data_path" env:"SETTINGS_DATA_PATH" desc:"The directory where the filesystem storage will store ocis settings. If not definied, the root directory derives from $OCIS_BASE_DATA_PATH:/settings."`
-	Metadata  Metadata              `yaml:"metadata_config"`
-	Bundles   []*settingsmsg.Bundle `yaml:"bundles"`
+	StoreType   string                `yaml:"store_type" env:"SETTINGS_STORE_TYPE" desc:"Store type configures the persistency driver. Supported values are \"metadata\" and \"filesystem\"."`
+	DataPath    string                `yaml:"data_path" env:"SETTINGS_DATA_PATH" desc:"The directory where the filesystem storage will store ocis settings. If not definied, the root directory derives from $OCIS_BASE_DATA_PATH:/settings."`
+	Metadata    Metadata              `yaml:"metadata_config"`
+	BundlesPath string                `yaml:"bundles_path" env:"SETTINGS_BUNDLES_PATH" desc:"The path to a JSON file with a list of bundles. If not definied, the default bundles will be loaded."`
+	Bundles     []*settingsmsg.Bundle `yaml:"-"`
 
 	AdminUserID string `yaml:"admin_user_id" env:"OCIS_ADMIN_USER_ID;SETTINGS_ADMIN_USER_ID" desc:"ID of the user that should receive admin privileges. Consider that the UUID can be encoded in some LDAP deployment configurations like in .ldif files. These need to be decoded beforehand."`
 
diff --git a/services/settings/pkg/config/defaults/defaultconfig.go b/services/settings/pkg/config/defaults/defaultconfig.go
index 7b0e91d70ad..1c07e7005a5 100644
--- a/services/settings/pkg/config/defaults/defaultconfig.go
+++ b/services/settings/pkg/config/defaults/defaultconfig.go
@@ -1,14 +1,16 @@
 package defaults
 
 import (
+	"encoding/json"
+	"os"
 	"path"
 	"strings"
 
 	"github.com/owncloud/ocis/v2/ocis-pkg/config/defaults"
 	"github.com/owncloud/ocis/v2/ocis-pkg/shared"
-	v0 "github.com/owncloud/ocis/v2/protogen/gen/ocis/messages/settings/v0"
 	"github.com/owncloud/ocis/v2/services/settings/pkg/config"
 	rdefaults "github.com/owncloud/ocis/v2/services/settings/pkg/store/defaults"
+	"github.com/pkg/errors"
 )
 
 func FullDefaultConfig() *config.Config {
@@ -53,7 +55,8 @@ func DefaultConfig() *config.Config {
 			StorageAddress: "127.0.0.1:9215",
 			SystemUserIDP:  "internal",
 		},
-		Bundles: []*v0.Bundle{},
+		BundlesPath: "",
+		Bundles:     nil,
 	}
 }
 
@@ -123,12 +126,23 @@ func EnsureDefaults(cfg *config.Config) {
 }
 
 func Sanitize(cfg *config.Config) {
-	if len(cfg.Bundles) == 0 {
-		cfg.Bundles = rdefaults.GenerateBundlesDefaultRoles()
-	}
-
 	// sanitize config
 	if cfg.HTTP.Root != "/" {
 		cfg.HTTP.Root = strings.TrimSuffix(cfg.HTTP.Root, "/")
 	}
 }
+
+// LoadBundles loads setting bundles from a file or from defaults
+func LoadBundles(cfg *config.Config) error {
+	if cfg.BundlesPath != "" {
+		data, _ := os.ReadFile(cfg.BundlesPath)
+		err := json.Unmarshal(data, &cfg.Bundles)
+		if err != nil {
+			return errors.Wrapf(err, "Could not load bundles from path %s", cfg.BundlesPath)
+		}
+	}
+	if len(cfg.Bundles) == 0 {
+		cfg.Bundles = rdefaults.GenerateBundlesDefaultRoles()
+	}
+	return nil
+}
diff --git a/services/settings/pkg/config/parser/parse.go b/services/settings/pkg/config/parser/parse.go
index 1e9071a78a4..4478629a6bd 100644
--- a/services/settings/pkg/config/parser/parse.go
+++ b/services/settings/pkg/config/parser/parse.go
@@ -29,6 +29,10 @@ func ParseConfig(cfg *config.Config) error {
 
 	defaults.Sanitize(cfg)
 
+	if err := defaults.LoadBundles(cfg); err != nil {
+		return err
+	}
+
 	return Validate(cfg)
 }
 


Test patch:
diff --git a/services/eventhistory/pkg/service/service_suit_test.go b/services/eventhistory/pkg/service/service_suit_test.go
new file mode 100644
index 00000000000..5ad83d80f4e
--- /dev/null
+++ b/services/eventhistory/pkg/service/service_suit_test.go
@@ -0,0 +1,13 @@
+package service_test
+
+import (
+	"testing"
+
+	. "github.com/onsi/ginkgo/v2"
+	. "github.com/onsi/gomega"
+)
+
+func TestSearch(t *testing.T) {
+	RegisterFailHandler(Fail)
+	RunSpecs(t, "Service Suite")
+}
diff --git a/services/eventhistory/pkg/service/service_test.go b/services/eventhistory/pkg/service/service_test.go
new file mode 100644
index 00000000000..da13eae9dc7
--- /dev/null
+++ b/services/eventhistory/pkg/service/service_test.go
@@ -0,0 +1,89 @@
+package service_test
+
+import (
+	"context"
+	"encoding/json"
+	"reflect"
+	"time"
+
+	"github.com/cs3org/reva/v2/pkg/events"
+	"github.com/google/uuid"
+	. "github.com/onsi/ginkgo/v2"
+	. "github.com/onsi/gomega"
+	"github.com/owncloud/ocis/v2/ocis-pkg/log"
+	"github.com/owncloud/ocis/v2/ocis-pkg/store"
+	ehsvc "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/eventhistory/v0"
+	"github.com/owncloud/ocis/v2/services/eventhistory/pkg/config"
+	"github.com/owncloud/ocis/v2/services/eventhistory/pkg/service"
+	microevents "go-micro.dev/v4/events"
+	microstore "go-micro.dev/v4/store"
+)
+
+var _ = Describe("EventHistoryService", func() {
+	var (
+		cfg = &config.Config{}
+
+		eh  *service.EventHistoryService
+		bus testBus
+		sto microstore.Store
+	)
+
+	BeforeEach(func() {
+		var err error
+		sto = store.Create()
+		bus = testBus(make(chan events.Event))
+		eh, err = service.NewEventHistoryService(cfg, bus, sto, log.Logger{})
+		Expect(err).ToNot(HaveOccurred())
+
+	})
+
+	AfterEach(func() {
+		close(bus)
+	})
+
+	It("Records events, stores them and allows to retrieve them", func() {
+		id := bus.Publish(events.UploadReady{})
+
+		// service will store eventually
+		time.Sleep(500 * time.Millisecond)
+
+		resp := &ehsvc.GetEventsResponse{}
+		err := eh.GetEvents(context.Background(), &ehsvc.GetEventsRequest{Ids: []string{id}}, resp)
+		Expect(err).ToNot(HaveOccurred())
+		Expect(resp).ToNot(BeNil())
+
+		Expect(len(resp.Events)).To(Equal(1))
+		Expect(resp.Events[0].Id).To(Equal(id))
+
+	})
+})
+
+type testBus chan events.Event
+
+func (tb testBus) Consume(_ string, _ ...microevents.ConsumeOption) (<-chan microevents.Event, error) {
+	ch := make(chan microevents.Event)
+	go func() {
+		for ev := range tb {
+			b, _ := json.Marshal(ev.Event)
+			ch <- microevents.Event{
+				Payload: b,
+				Metadata: map[string]string{
+					events.MetadatakeyEventID:   ev.ID,
+					events.MetadatakeyEventType: ev.Type,
+				},
+			}
+		}
+	}()
+	return ch, nil
+}
+
+func (tb testBus) Publish(e interface{}) string {
+	ev := events.Event{
+		ID:    uuid.New().String(),
+		Type:  reflect.TypeOf(e).String(),
+		Event: e,
+	}
+
+	tb <- ev
+	return ev.ID
+}
diff --git a/services/graph/pkg/service/v0/users_test.go b/services/graph/pkg/service/v0/users_test.go
index 870368d3da6..b020ef20732 100644
--- a/services/graph/pkg/service/v0/users_test.go
+++ b/services/graph/pkg/service/v0/users_test.go
@@ -340,16 +340,36 @@ var _ = Describe("Users", func() {
 		Entry("with unsupported lambda token ", "memberOf/all(n:n/id eq 1)", http.StatusNotImplemented),
 		Entry("with unsupported filter operation ", "memberOf/any(n:n/id ne 1)", http.StatusNotImplemented),
 		Entry("with unsupported filter operand type", "memberOf/any(n:n/id eq 1)", http.StatusNotImplemented),
-		Entry("with unsupported lambda filter property", "memberOf/any(n:n/name eq 'name')", http.StatusNotImplemented),
+		Entry("with unsupported memberOf lambda filter property", "memberOf/any(n:n/name eq 'name')", http.StatusNotImplemented),
+		Entry("with unsupported appRoleAssignments lambda filter property", "appRoleAssignments/any(n:n/id eq 'id')", http.StatusNotImplemented),
+		Entry("with unsupported appRoleAssignments lambda filter property",
+			"appRoleAssignments/any(n:n/id eq 'id') and appRoleAssignments/any(n:n/id eq 'id')", http.StatusNotImplemented),
+		Entry("with unsupported appRoleAssignments lambda filter operation",
+			"appRoleAssignments/all(n:n/appRoleId eq 'id') and appRoleAssignments/any(n:n/appRoleId eq 'id')", http.StatusNotImplemented),
+		Entry("with unsupported appRoleAssignments lambda filter operation",
+			"appRoleAssignments/any(n:n/appRoleId ne 'id') and appRoleAssignments/any(n:n/appRoleId eq 'id')", http.StatusNotImplemented),
+		Entry("with unsupported appRoleAssignments lambda filter operation",
+			"appRoleAssignments/any(n:n/appRoleId eq 1) and appRoleAssignments/any(n:n/appRoleId eq 'id')", http.StatusNotImplemented),
 	)
 
-	DescribeTable("With a valid memberOf filter",
+	DescribeTable("With a valid filter",
 		func(filter string, status int) {
 			user := &libregraph.User{}
 			user.SetId("25cb7bc0-3168-4a0c-adbe-396f478ad494")
 			users := []*libregraph.User{user}
 			identityBackend.On("GetGroupMembers", mock.Anything, "25cb7bc0-3168-4a0c-adbe-396f478ad494", mock.Anything).Return(users, nil)
 			identityBackend.On("GetGroupMembers", mock.Anything, "2713f1d5-6822-42bd-ad56-9f6c55a3a8fa", mock.Anything).Return([]*libregraph.User{}, nil)
+			identityBackend.On("GetUsers", mock.Anything, mock.Anything).Return([]*libregraph.User{user}, nil)
+			roleService.On("ListRoleAssignments", mock.Anything, mock.Anything, mock.Anything).
+				Return(func(ctx context.Context, in *settings.ListRoleAssignmentsRequest, opts ...client.CallOption) *settings.ListRoleAssignmentsResponse {
+					return &settings.ListRoleAssignmentsResponse{Assignments: []*settingsmsg.UserRoleAssignment{
+						{
+							Id:          "some-appRoleAssignment-ID",
+							AccountUuid: user.GetId(),
+							RoleId:      "some-appRole-ID",
+						},
+					}}
+				}, nil)
 			r := httptest.NewRequest(http.MethodGet, "/graph/v1.0/users?$filter="+url.QueryEscape(filter), nil)
 			svc.GetUsers(rr, r)
 
@@ -357,9 +377,13 @@ var _ = Describe("Users", func() {
 		},
 		Entry("with memberOf lambda filter with UUID", "memberOf/any(n:n/id eq 25cb7bc0-3168-4a0c-adbe-396f478ad494)", http.StatusOK),
 		Entry("with memberOf lambda filter with UUID string", "memberOf/any(n:n/id eq '25cb7bc0-3168-4a0c-adbe-396f478ad494')", http.StatusOK),
+		Entry("with appRoleAssignments lambda filter with appRoleId", "appRoleAssignments/any(n:n/appRoleId eq 'some-appRole-ID')", http.StatusOK),
 		Entry("with two memberOf lambda filters",
 			"memberOf/any(n:n/id eq 25cb7bc0-3168-4a0c-adbe-396f478ad494) and memberOf/any(n:n/id eq 2713f1d5-6822-42bd-ad56-9f6c55a3a8fa)",
 			http.StatusOK),
+		Entry("with supported appRoleAssignments lambda filter property",
+			"appRoleAssignments/any(n:n/appRoleId eq 'some-appRoleAssignment-ID') and memberOf/any(n:n/id eq 2713f1d5-6822-42bd-ad56-9f6c55a3a8fa)",
+			http.StatusOK),
 	)
 
 	Describe("GetUser", func() {
diff --git a/tests/acceptance/config/behat-core.yml b/tests/acceptance/config/behat-core.yml
index f0bc9ff95ec..827eb6a46c3 100644
--- a/tests/acceptance/config/behat-core.yml
+++ b/tests/acceptance/config/behat-core.yml
@@ -432,13 +432,6 @@ default:
         - WebDavPropertiesContext:
         - AppConfigurationContext:
 
-    coreApiTranslation:
-      paths:
-        - "%paths.base%/../features/coreApiTranslation"
-      context: *common_ldap_suite_context
-      contexts:
-        - FeatureContext: *common_feature_context_params
-
   extensions:
     rdx\behatvars\BehatVariablesExtension: ~
 
diff --git a/tests/acceptance/expected-failures-API-on-OCIS-storage.md b/tests/acceptance/expected-failures-API-on-OCIS-storage.md
index 9dcd37e8715..481f86af165 100644
--- a/tests/acceptance/expected-failures-API-on-OCIS-storage.md
+++ b/tests/acceptance/expected-failures-API-on-OCIS-storage.md
@@ -26,12 +26,12 @@ _ocdav: double-check the webdav property parsing when custom namespaces are used
 
 #### [Cannot set custom webDav properties](https://github.com/owncloud/product/issues/264)
 
-- [coreApiWebdavProperties2/getFileProperties.feature:348](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiWebdavProperties2/getFileProperties.feature#L348)
-- [coreApiWebdavProperties2/getFileProperties.feature:353](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiWebdavProperties2/getFileProperties.feature#L353)
-- [coreApiWebdavProperties2/getFileProperties.feature:358](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiWebdavProperties2/getFileProperties.feature#L358)
-- [coreApiWebdavProperties2/getFileProperties.feature:388](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiWebdavProperties2/getFileProperties.feature#L388)
-- [coreApiWebdavProperties2/getFileProperties.feature:393](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiWebdavProperties2/getFileProperties.feature#L393)
-- [coreApiWebdavProperties2/getFileProperties.feature:398](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiWebdavProperties2/getFileProperties.feature#L398)
+- [coreApiWebdavProperties2/getFileProperties.feature:341](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiWebdavProperties2/getFileProperties.feature#L341)
+- [coreApiWebdavProperties2/getFileProperties.feature:346](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiWebdavProperties2/getFileProperties.feature#L346)
+- [coreApiWebdavProperties2/getFileProperties.feature:351](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiWebdavProperties2/getFileProperties.feature#L351)
+- [coreApiWebdavProperties2/getFileProperties.feature:381](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiWebdavProperties2/getFileProperties.feature#L381)
+- [coreApiWebdavProperties2/getFileProperties.feature:386](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiWebdavProperties2/getFileProperties.feature#L386)
+- [coreApiWebdavProperties2/getFileProperties.feature:391](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiWebdavProperties2/getFileProperties.feature#L391)
 
 #### [file versions do not report the version author](https://github.com/owncloud/ocis/issues/2914)
 
@@ -178,25 +178,25 @@ File and sync features in a shared scenario
 - [coreApiShareManagementToShares/acceptShares.feature:230](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareManagementToShares/acceptShares.feature#L230)
 - [coreApiShareManagementToShares/acceptShares.feature:495](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareManagementToShares/acceptShares.feature#L495)
 - [coreApiShareManagementToShares/acceptShares.feature:560](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareManagementToShares/acceptShares.feature#L560)
-- [coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature:141](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature#L141)
-- [coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature:142](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature#L142)
-- [coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature:181](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature#L181)
-- [coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature:182](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature#L182)
-- [coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature:45](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature#L45)
-- [coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature:46](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature#L46)
+- [coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature:129](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature#L129)
+- [coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature:130](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature#L130)
+- [coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature:164](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature#L164)
+- [coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature:165](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature#L165)
+- [coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature:38](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature#L38)
+- [coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature:39](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature#L39)
 
 #### [sharing the shares folder to users exits with different status code than in oc10 backend](https://github.com/owncloud/ocis/issues/2215)
 
-- [coreApiShareManagementBasicToShares/createShareToSharesFolder.feature:747](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareManagementBasicToShares/createShareToSharesFolder.feature#L747)
-- [coreApiShareManagementBasicToShares/createShareToSharesFolder.feature:748](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareManagementBasicToShares/createShareToSharesFolder.feature#L748)
-- [coreApiShareManagementBasicToShares/createShareToSharesFolder.feature:766](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareManagementBasicToShares/createShareToSharesFolder.feature#L766)
-- [coreApiShareManagementBasicToShares/createShareToSharesFolder.feature:767](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareManagementBasicToShares/createShareToSharesFolder.feature#L767)
-- [coreApiShareManagementBasicToShares/createShareToSharesFolder.feature:782](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareManagementBasicToShares/createShareToSharesFolder.feature#L782)
-- [coreApiShareManagementBasicToShares/createShareToSharesFolder.feature:783](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareManagementBasicToShares/createShareToSharesFolder.feature#L783)
+- [coreApiShareManagementBasicToShares/createShareToSharesFolder.feature:742](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareManagementBasicToShares/createShareToSharesFolder.feature#L742)
+- [coreApiShareManagementBasicToShares/createShareToSharesFolder.feature:743](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareManagementBasicToShares/createShareToSharesFolder.feature#L743)
+- [coreApiShareManagementBasicToShares/createShareToSharesFolder.feature:761](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareManagementBasicToShares/createShareToSharesFolder.feature#L761)
+- [coreApiShareManagementBasicToShares/createShareToSharesFolder.feature:762](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareManagementBasicToShares/createShareToSharesFolder.feature#L762)
+- [coreApiShareManagementBasicToShares/createShareToSharesFolder.feature:777](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareManagementBasicToShares/createShareToSharesFolder.feature#L777)
+- [coreApiShareManagementBasicToShares/createShareToSharesFolder.feature:778](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareManagementBasicToShares/createShareToSharesFolder.feature#L778)
 
 #### [file_target of an auto-renamed file is not correct directly after sharing](https://github.com/owncloud/core/issues/32322)
 
-- [coreApiShareManagementToShares/mergeShare.feature:121](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareManagementToShares/mergeShare.feature#L121)
+- [coreApiShareManagementToShares/mergeShare.feature:116](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareManagementToShares/mergeShare.feature#L116)
 
 #### [File deletion using dav gives unique string in filename in the trashbin](https://github.com/owncloud/product/issues/178)
 
@@ -213,13 +213,13 @@ cannot share a folder with create permission
 
 #### [OCS error message for attempting to access share via share id as an unauthorized user is not informative](https://github.com/owncloud/ocis/issues/1233)
 
-- [coreApiShareOperationsToShares1/gettingShares.feature:184](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareOperationsToShares1/gettingShares.feature#L184)
-- [coreApiShareOperationsToShares1/gettingShares.feature:185](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareOperationsToShares1/gettingShares.feature#L185)
+- [coreApiShareOperationsToShares1/gettingShares.feature:151](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareOperationsToShares1/gettingShares.feature#L151)
+- [coreApiShareOperationsToShares1/gettingShares.feature:152](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareOperationsToShares1/gettingShares.feature#L152)
 
 #### [Listing shares via ocs API does not show path for parent folders](https://github.com/owncloud/ocis/issues/1231)
 
-- [coreApiShareOperationsToShares1/gettingShares.feature:221](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareOperationsToShares1/gettingShares.feature#L221)
-- [coreApiShareOperationsToShares1/gettingShares.feature:222](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareOperationsToShares1/gettingShares.feature#L222)
+- [coreApiShareOperationsToShares1/gettingShares.feature:188](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareOperationsToShares1/gettingShares.feature#L188)
+- [coreApiShareOperationsToShares1/gettingShares.feature:189](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareOperationsToShares1/gettingShares.feature#L189)
 
 #### [Public link enforce permissions](https://github.com/owncloud/ocis/issues/1269)
 - [coreApiSharePublicLink1/createPublicLinkShare.feature:353](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiSharePublicLink1/createPublicLinkShare.feature#L353)
@@ -296,7 +296,7 @@ cannot share a folder with create permission
 - [coreApiShareOperationsToShares1/changingFilesShare.feature:70](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareOperationsToShares1/changingFilesShare.feature#L70)
 - [coreApiShareOperationsToShares1/changingFilesShare.feature:91](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareOperationsToShares1/changingFilesShare.feature#L91)
 - [coreApiShareOperationsToShares1/changingFilesShare.feature:92](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareOperationsToShares1/changingFilesShare.feature#L92)
-- [coreApiShareManagementBasicToShares/createShareToSharesFolder.feature:538](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareManagementBasicToShares/createShareToSharesFolder.feature#L538)
+- [coreApiShareManagementBasicToShares/createShareToSharesFolder.feature:533](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareManagementBasicToShares/createShareToSharesFolder.feature#L533)
 - [coreApiWebdavMove2/moveShareOnOcis.feature:30](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiWebdavMove2/moveShareOnOcis.feature#L30)
 - [coreApiWebdavMove2/moveShareOnOcis.feature:32](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiWebdavMove2/moveShareOnOcis.feature#L32)
 - [coreApiWebdavMove2/moveShareOnOcis.feature:98](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiWebdavMove2/moveShareOnOcis.feature#L98)
@@ -352,16 +352,16 @@ cannot share a folder with create permission
 
 #### [Cannot move folder/file from one received share to another](https://github.com/owncloud/ocis/issues/2442)
 
-- [coreApiShareUpdateToShares/updateShare.feature:201](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareUpdateToShares/updateShare.feature#L201)
+- [coreApiShareUpdateToShares/updateShare.feature:196](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareUpdateToShares/updateShare.feature#L196)
 - [coreApiShareUpdateToShares/updateShare.feature:160](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareUpdateToShares/updateShare.feature#L160)
-- [coreApiShareManagementToShares/mergeShare.feature:141](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareManagementToShares/mergeShare.feature#L141)
+- [coreApiShareManagementToShares/mergeShare.feature:136](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareManagementToShares/mergeShare.feature#L136)
 
 #### [Sharing folder and sub-folder with same user but different permission,the permission of sub-folder is not obeyed ](https://github.com/owncloud/ocis/issues/2440)
 
-- [coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature:278](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature#L278)
-- [coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature:313](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature#L313)
-- [coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature:422](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature#L422)
-- [coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature:457](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature#L457)
+- [coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature:261](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature#L261)
+- [coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature:296](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature#L296)
+- [coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature:405](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature#L405)
+- [coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature:440](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature#L440)
 
 #### [Empty OCS response for a share create request using a disabled user](https://github.com/owncloud/ocis/issues/2212)
 
@@ -371,8 +371,8 @@ cannot share a folder with create permission
 
 #### [Edit user share response has a "name" field](https://github.com/owncloud/ocis/issues/1225)
 
-- [coreApiShareUpdateToShares/updateShare.feature:247](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareUpdateToShares/updateShare.feature#L247)
-- [coreApiShareUpdateToShares/updateShare.feature:248](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareUpdateToShares/updateShare.feature#L248)
+- [coreApiShareUpdateToShares/updateShare.feature:242](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareUpdateToShares/updateShare.feature#L242)
+- [coreApiShareUpdateToShares/updateShare.feature:243](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareUpdateToShares/updateShare.feature#L243)
 
 #### [user can access version metadata of a received share before accepting it](https://github.com/owncloud/ocis/issues/760)
 
@@ -380,8 +380,8 @@ cannot share a folder with create permission
 
 #### [Share lists deleted user as 'user'](https://github.com/owncloud/ocis/issues/903)
 
-- [coreApiShareManagementBasicToShares/createShareToSharesFolder.feature:682](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareManagementBasicToShares/createShareToSharesFolder.feature#L682)
-- [coreApiShareManagementBasicToShares/createShareToSharesFolder.feature:683](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareManagementBasicToShares/createShareToSharesFolder.feature#L683)
+- [coreApiShareManagementBasicToShares/createShareToSharesFolder.feature:677](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareManagementBasicToShares/createShareToSharesFolder.feature#L677)
+- [coreApiShareManagementBasicToShares/createShareToSharesFolder.feature:678](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareManagementBasicToShares/createShareToSharesFolder.feature#L678)
 
 #### [deleting a share with wrong authentication returns OCS status 996 / HTTP 500](https://github.com/owncloud/ocis/issues/1229)
 
@@ -525,8 +525,8 @@ And other missing implementation of favorites
 
 #### [Sharing a same file twice to the same group](https://github.com/owncloud/ocis/issues/1710)
 
-- [coreApiShareManagementBasicToShares/createShareToSharesFolder.feature:730](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareManagementBasicToShares/createShareToSharesFolder.feature#L730)
-- [coreApiShareManagementBasicToShares/createShareToSharesFolder.feature:731](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareManagementBasicToShares/createShareToSharesFolder.feature#L731)
+- [coreApiShareManagementBasicToShares/createShareToSharesFolder.feature:725](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareManagementBasicToShares/createShareToSharesFolder.feature#L725)
+- [coreApiShareManagementBasicToShares/createShareToSharesFolder.feature:726](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareManagementBasicToShares/createShareToSharesFolder.feature#L726)
 
 #### [PATCH request for TUS upload with wrong checksum gives incorrect response](https://github.com/owncloud/ocis/issues/1755)
 
@@ -599,8 +599,8 @@ And other missing implementation of favorites
 
 #### [Shares to deleted group listed in the response](https://github.com/owncloud/ocis/issues/2441)
 
-- [coreApiShareManagementBasicToShares/createShareToSharesFolder.feature:534](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareManagementBasicToShares/createShareToSharesFolder.feature#L534)
-- [coreApiShareManagementBasicToShares/createShareToSharesFolder.feature:535](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareManagementBasicToShares/createShareToSharesFolder.feature#L535)
+- [coreApiShareManagementBasicToShares/createShareToSharesFolder.feature:529](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareManagementBasicToShares/createShareToSharesFolder.feature#L529)
+- [coreApiShareManagementBasicToShares/createShareToSharesFolder.feature:530](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiShareManagementBasicToShares/createShareToSharesFolder.feature#L530)
 
 #### [copying the file inside Shares folder returns 404](https://github.com/owncloud/ocis/issues/3874)
 
@@ -650,9 +650,9 @@ Not everything needs to be implemented for ocis. While the oc10 testsuite covers
 - [coreApiWebdavUpload2/uploadFileToExcludedDirectoryUsingOldChunking.feature:38](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiWebdavUpload2/uploadFileToExcludedDirectoryUsingOldChunking.feature#L38)
 - [coreApiWebdavUpload2/uploadFileToExcludedDirectoryUsingOldChunking.feature:39](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiWebdavUpload2/uploadFileToExcludedDirectoryUsingOldChunking.feature#L39)
 - [coreApiWebdavUpload2/uploadFileToExcludedDirectoryUsingOldChunking.feature:40](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiWebdavUpload2/uploadFileToExcludedDirectoryUsingOldChunking.feature#L40)
-- [coreApiWebdavMove2/moveFile.feature:287](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiWebdavMove2/moveFile.feature#L287)
-- [coreApiWebdavMove2/moveFile.feature:288](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiWebdavMove2/moveFile.feature#L288)
-- [coreApiWebdavMove2/moveFile.feature:293](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiWebdavMove2/moveFile.feature#L293)
+- [coreApiWebdavMove2/moveFile.feature:176](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiWebdavMove2/moveFile.feature#L176)
+- [coreApiWebdavMove2/moveFile.feature:177](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiWebdavMove2/moveFile.feature#L177)
+- [coreApiWebdavMove2/moveFile.feature:182](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiWebdavMove2/moveFile.feature#L182)
 
 #### [cannot set blacklisted file names](https://github.com/owncloud/product/issues/260)
 
@@ -740,7 +740,7 @@ Not everything needs to be implemented for ocis. While the oc10 testsuite covers
 - [coreApiWebdavMove1/moveFolder.feature:27](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiWebdavMove1/moveFolder.feature#L27)
 - [coreApiWebdavMove1/moveFolder.feature:45](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiWebdavMove1/moveFolder.feature#L45)
 - [coreApiWebdavMove1/moveFolder.feature:63](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiWebdavMove1/moveFolder.feature#L63)
-- [coreApiWebdavMove2/moveFile.feature:224](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiWebdavMove2/moveFile.feature#L224)
+- [coreApiWebdavMove2/moveFile.feature:138](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiWebdavMove2/moveFile.feature#L138)
 - [coreApiWebdavMove2/moveFileToBlacklistedName.feature:25](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiWebdavMove2/moveFileToBlacklistedName.feature#L25)
 - [coreApiWebdavMove2/moveFileToBlacklistedName.feature:41](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiWebdavMove2/moveFileToBlacklistedName.feature#L41)
 - [coreApiWebdavMove2/moveFileToBlacklistedName.feature:80](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiWebdavMove2/moveFileToBlacklistedName.feature#L80)
@@ -780,7 +780,7 @@ Not everything needs to be implemented for ocis. While the oc10 testsuite covers
 
 #### [HTTP status code differ while deleting file of another user's trash bin](https://github.com/owncloud/ocis/issues/3544)
 
-- [coreApiTrashbin/trashbinDelete.feature:109](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinDelete.feature#L109)
+- [coreApiTrashbin/trashbinDelete.feature:105](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinDelete.feature#L105)
 
 #### [Problem accessing trashbin with personal space id](https://github.com/owncloud/ocis/issues/3639)
 
@@ -788,13 +788,13 @@ Not everything needs to be implemented for ocis. While the oc10 testsuite covers
 - [coreApiTrashbin/trashbinDelete.feature:36](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinDelete.feature#L36)
 - [coreApiTrashbin/trashbinDelete.feature:58](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinDelete.feature#L58)
 - [coreApiTrashbin/trashbinDelete.feature:85](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinDelete.feature#L85)
-- [coreApiTrashbin/trashbinDelete.feature:132](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinDelete.feature#L132)
-- [coreApiTrashbin/trashbinDelete.feature:155](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinDelete.feature#L155)
-- [coreApiTrashbin/trashbinDelete.feature:180](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinDelete.feature#L180)
-- [coreApiTrashbin/trashbinDelete.feature:205](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinDelete.feature#L205)
-- [coreApiTrashbin/trashbinDelete.feature:242](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinDelete.feature#L242)
-- [coreApiTrashbin/trashbinDelete.feature:279](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinDelete.feature#L279)
-- [coreApiTrashbin/trashbinDelete.feature:328](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinDelete.feature#L328)
+- [coreApiTrashbin/trashbinDelete.feature:128](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinDelete.feature#L128)
+- [coreApiTrashbin/trashbinDelete.feature:151](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinDelete.feature#L151)
+- [coreApiTrashbin/trashbinDelete.feature:176](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinDelete.feature#L176)
+- [coreApiTrashbin/trashbinDelete.feature:201](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinDelete.feature#L201)
+- [coreApiTrashbin/trashbinDelete.feature:238](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinDelete.feature#L238)
+- [coreApiTrashbin/trashbinDelete.feature:275](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinDelete.feature#L275)
+- [coreApiTrashbin/trashbinDelete.feature:324](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinDelete.feature#L324)
 - [coreApiTrashbin/trashbinFilesFolders.feature:25](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinFilesFolders.feature#L25)
 - [coreApiTrashbin/trashbinFilesFolders.feature:41](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinFilesFolders.feature#L41)
 - [coreApiTrashbin/trashbinFilesFolders.feature:60](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinFilesFolders.feature#L60)
@@ -802,19 +802,23 @@ Not everything needs to be implemented for ocis. While the oc10 testsuite covers
 - [coreApiTrashbin/trashbinFilesFolders.feature:100](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinFilesFolders.feature#L100)
 - [coreApiTrashbin/trashbinFilesFolders.feature:136](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinFilesFolders.feature#L136)
 - [coreApiTrashbin/trashbinFilesFolders.feature:159](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinFilesFolders.feature#L159)
-- [coreApiTrashbin/trashbinFilesFolders.feature:339](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinFilesFolders.feature#L339)
-- [coreApiTrashbin/trashbinFilesFolders.feature:340](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinFilesFolders.feature#L340)
-- [coreApiTrashbin/trashbinFilesFolders.feature:341](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinFilesFolders.feature#L341)
-- [coreApiTrashbin/trashbinFilesFolders.feature:346](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinFilesFolders.feature#L346)
-- [coreApiTrashbin/trashbinFilesFolders.feature:347](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinFilesFolders.feature#L347)
-- [coreApiTrashbin/trashbinFilesFolders.feature:348](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinFilesFolders.feature#L348)
-- [coreApiTrashbin/trashbinFilesFolders.feature:349](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinFilesFolders.feature#L349)
-- [coreApiTrashbin/trashbinFilesFolders.feature:350](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinFilesFolders.feature#L350)
-- [coreApiTrashbin/trashbinFilesFolders.feature:351](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinFilesFolders.feature#L351)
-- [coreApiTrashbin/trashbinFilesFolders.feature:368](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinFilesFolders.feature#L368)
-- [coreApiTrashbin/trashbinFilesFolders.feature:388](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinFilesFolders.feature#L388)
-- [coreApiTrashbin/trashbinFilesFolders.feature:442](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinFilesFolders.feature#L442)
-- [coreApiTrashbin/trashbinFilesFolders.feature:479](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinFilesFolders.feature#L479)
-
+- [coreApiTrashbin/trashbinFilesFolders.feature:323](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinFilesFolders.feature#L323)
+- [coreApiTrashbin/trashbinFilesFolders.feature:324](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinFilesFolders.feature#L324)
+- [coreApiTrashbin/trashbinFilesFolders.feature:325](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinFilesFolders.feature#L325)
+- [coreApiTrashbin/trashbinFilesFolders.feature:330](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinFilesFolders.feature#L330)
+- [coreApiTrashbin/trashbinFilesFolders.feature:331](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinFilesFolders.feature#L331)
+- [coreApiTrashbin/trashbinFilesFolders.feature:332](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinFilesFolders.feature#L332)
+- [coreApiTrashbin/trashbinFilesFolders.feature:333](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinFilesFolders.feature#L333)
+- [coreApiTrashbin/trashbinFilesFolders.feature:334](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinFilesFolders.feature#L334)
+- [coreApiTrashbin/trashbinFilesFolders.feature:335](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinFilesFolders.feature#L335)
+- [coreApiTrashbin/trashbinFilesFolders.feature:352](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinFilesFolders.feature#L352)
+- [coreApiTrashbin/trashbinFilesFolders.feature:372](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinFilesFolders.feature#L372)
+- [coreApiTrashbin/trashbinFilesFolders.feature:426](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinFilesFolders.feature#L426)
+- [coreApiTrashbin/trashbinFilesFolders.feature:463](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiTrashbin/trashbinFilesFolders.feature#L463)
+
+#### [Default capabilities for normal user and admin user not same as in oC-core](https://github.com/owncloud/ocis/issues/1285)
+- [coreApiCapabilities/capabilities.feature:8](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiCapabilities/capabilities.feature#L8)
+- [coreApiCapabilities/capabilities.feature:35](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiCapabilities/capabilities.feature#L35)
+- [coreApiCapabilities/capabilities.feature:44](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/coreApiCapabilities/capabilities.feature#L44)
 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.
diff --git a/tests/acceptance/features/apiSpacesShares/shareSpaces.feature b/tests/acceptance/features/apiSpacesShares/shareSpaces.feature
index 3ce7b96bd3e..254ab8a7ebf 100644
--- a/tests/acceptance/features/apiSpacesShares/shareSpaces.feature
+++ b/tests/acceptance/features/apiSpacesShares/shareSpaces.feature
@@ -294,7 +294,7 @@ Feature: Share spaces
       | role      | viewer |
     When user "Brian" uploads a file inside space "share space" with content "Test" to "test.txt" using the WebDAV API
     Then the HTTP status code should be "403"
-    When user "Alice" has shared a space "share space" with settings:
+    When user "Alice" shares a space "share space" with settings:
       | shareWith | Brian  |
       | role      | editor |
     Then the HTTP status code should be "200"
@@ -310,7 +310,7 @@ Feature: Share spaces
       | role      | viewer |
     When user "Brian" uploads a file inside space "share space" with content "Test" to "test.txt" using the WebDAV API
     Then the HTTP status code should be "403"
-    When user "Alice" has shared a space "share space" with settings:
+    When user "Alice" shares a space "share space" with settings:
       | shareWith | sales  |
       | shareType | 8      |
       | role      | editor |
@@ -347,4 +347,44 @@ Feature: Share spaces
       | role    |
       | manager |
       | editor  |
-      | viewer  |
\ No newline at end of file
+      | viewer  |
+
+
+  Scenario Outline: update the expiration date of a space in user share
+    Given user "Alice" has shared a space "share space" with settings:
+      | shareWith  | Brian                    |
+      | role       | <role>                   |
+      | expireDate | 2042-03-25T23:59:59+0100 |
+    When user "Alice" updates the space "share space" with settings:
+      | shareWith  | Brian                         |
+      | expireDate | 2044-01-01T23:59:59.999+01:00 |
+      | role       | <role>                        |
+    Then the HTTP status code should be "200"
+    And the user "Brian" should have a space called "share space" granted to user "Brian" with role "<role>" and expiration date "2044-01-01"
+    Examples:
+      | role    |
+      | manager |
+      | editor  |
+      | viewer  |
+
+
+  Scenario Outline: update the expiration date of a space in group share
+    Given group "sales" has been created
+    And the administrator has added a user "Brian" to the group "sales" using GraphApi
+    And user "Alice" has shared a space "share space" with settings:
+      | shareWith  | sales                    |
+      | shareType  | 8                        |
+      | role       | <role>                   |
+      | expireDate | 2042-03-25T23:59:59+0100 |
+    When user "Alice" updates the space "share space" with settings:
+      | shareWith  | sales                         |
+      | shareType  | 8                             |
+      | expireDate | 2044-01-01T23:59:59.999+01:00 |
+      | role       | <role>                        |
+    Then the HTTP status code should be "200"
+    And the user "Brian" should have a space called "share space" granted to group "sales" with role "<role>" and expiration date "2044-01-01"
+    Examples:
+      | role    |
+      | manager |
+      | editor  |
+      | viewer  |
diff --git a/tests/acceptance/features/bootstrap/SpacesContext.php b/tests/acceptance/features/bootstrap/SpacesContext.php
index 1d02a421781..ab77c6ddab1 100644
--- a/tests/acceptance/features/bootstrap/SpacesContext.php
+++ b/tests/acceptance/features/bootstrap/SpacesContext.php
@@ -69,7 +69,7 @@ class SpacesContext implements Context {
 	 * @var ChecksumContext
 	 */
 	private ChecksumContext $checksumContext;
-	
+
 	/**
 	 * @var FilesVersionsContext
 	 */
@@ -1906,9 +1906,10 @@ class SpacesContext implements Context {
 		$space = $this->getSpaceByName($user, $spaceName);
 		$availableRoleToAssignToShareSpace = ['manager', 'editor', 'viewer'];
 		$rows = $table->getRowsHash();
-		if (!\in_array(\strtolower($rows['role']), $availableRoleToAssignToShareSpace)) {
+		if (isset($rows['role']) && !\in_array(\strtolower($rows['role']), $availableRoleToAssignToShareSpace)) {
 			throw new Error("The Selected " . $rows['role'] . " Cannot be Found");
 		}
+		$rows["role"] = \array_key_exists("role", $rows) ? $rows["role"] : "viewer";
 		$rows["shareType"] = \array_key_exists("shareType", $rows) ? $rows["shareType"] : 7;
 		$rows["expireDate"] = \array_key_exists("expireDate", $rows) ? $rows["expireDate"] : null;
 
diff --git a/tests/acceptance/features/coreApiCapabilities/capabilities.feature b/tests/acceptance/features/coreApiCapabilities/capabilities.feature
index c34004a8228..f6045c8ac82 100644
--- a/tests/acceptance/features/coreApiCapabilities/capabilities.feature
+++ b/tests/acceptance/features/coreApiCapabilities/capabilities.feature
@@ -1,132 +1,10 @@
-@api @files_sharing-app-required @issue-ocis-reva-41
+@api @files_sharing-app-required
 Feature: capabilities
 
   Background:
     Given using OCS API version "1"
 
-  @smokeTest @skipOnOcis
-  Scenario: Check that the sharing API can be enabled
-    Given parameter "shareapi_enabled" of app "core" has been set to "no"
-    And the capabilities setting of "files_sharing" path "api_enabled" has been confirmed to be ""
-    When the administrator sets parameter "shareapi_enabled" of app "core" to "yes"
-    Then the capabilities setting of "files_sharing" path "api_enabled" should be "1"
-
-  @smokeTest @skipOnOcis
-  Scenario: Check that the sharing API can be disabled
-    Given parameter "shareapi_enabled" of app "core" has been set to "yes"
-    And the capabilities setting of "files_sharing" path "api_enabled" has been confirmed to be "1"
-    When the administrator sets parameter "shareapi_enabled" of app "core" to "no"
-    Then the capabilities setting of "files_sharing" path "api_enabled" should be ""
-
-  @skipOnOcis
-  Scenario: Check that group sharing can be enabled
-    Given parameter "shareapi_allow_group_sharing" of app "core" has been set to "no"
-    And the capabilities setting of "files_sharing" path "group_sharing" has been confirmed to be ""
-    When the administrator sets parameter "shareapi_allow_group_sharing" of app "core" to "yes"
-    Then the capabilities setting of "files_sharing" path "group_sharing" should be "1"
-
-  @skipOnOcis
-  Scenario: Check that group sharing can be disabled
-    Given parameter "shareapi_allow_group_sharing" of app "core" has been set to "yes"
-    And the capabilities setting of "files_sharing" path "group_sharing" has been confirmed to be "1"
-    When the administrator sets parameter "shareapi_allow_group_sharing" of app "core" to "no"
-    Then the capabilities setting of "files_sharing" path "group_sharing" should be ""
-
-  @smokeTest @skipOnOcis
-  Scenario: getting default capabilities with admin user
-    When the administrator retrieves the capabilities using the capabilities API
-    Then the OCS status code should be "100"
-    And the HTTP status code should be "200"
-    And the capabilities should contain
-      | capability    | path_to_element                           | value             |
-      | core          | pollinterval                              | 30000             |
-      | core          | webdav-root                               | remote.php/webdav |
-      | core          | status@@@edition                          | %edition%         |
-      | core          | status@@@productname                      | %productname%     |
-      | core          | status@@@version                          | %version%         |
-      | core          | status@@@versionstring                    | %versionstring%   |
-      | files_sharing | api_enabled                               | 1                 |
-      | files_sharing | default_permissions                       | 31                |
-      | files_sharing | search_min_length                         | 2                 |
-      | files_sharing | public@@@enabled                          | 1                 |
-      | files_sharing | public@@@multiple                         | 1                 |
-      | files_sharing | public@@@upload                           | 1                 |
-      | files_sharing | public@@@supports_upload_only             | 1                 |
-      | files_sharing | public@@@send_mail                        | EMPTY             |
-      | files_sharing | public@@@social_share                     | 1                 |
-      | files_sharing | public@@@enforced                         | EMPTY             |
-      | files_sharing | public@@@enforced_for@@@read_only         | EMPTY             |
-      | files_sharing | public@@@enforced_for@@@read_write        | EMPTY             |
-      | files_sharing | public@@@enforced_for@@@upload_only       | EMPTY             |
-      | files_sharing | public@@@enforced_for@@@read_write_delete | EMPTY             |
-      | files_sharing | public@@@expire_date@@@enabled            | EMPTY             |
-      | files_sharing | public@@@defaultPublicLinkShareName       | Public link       |
-      | files_sharing | resharing                                 | 1                 |
-      | files_sharing | federation@@@outgoing                     | 1                 |
-      | files_sharing | federation@@@incoming                     | 1                 |
-      | files_sharing | group_sharing                             | 1                 |
-      | files_sharing | share_with_group_members_only             | EMPTY             |
-      | files_sharing | share_with_membership_groups_only         | EMPTY             |
-      | files_sharing | auto_accept_share                         | 1                 |
-      | files_sharing | user_enumeration@@@enabled                | 1                 |
-      | files_sharing | user_enumeration@@@group_members_only     | EMPTY             |
-      | files_sharing | user@@@send_mail                          | EMPTY             |
-      | files         | bigfilechunking                           | 1                 |
-      | files         | privateLinks                              | 1                 |
-      | files         | privateLinksDetailsParam                  | 1                 |
-
-  @smokeTest @skipOnOcis
-  Scenario: getting default capabilities with admin user with new values
-    When the administrator retrieves the capabilities using the capabilities API
-    Then the OCS status code should be "100"
-    And the HTTP status code should be "200"
-    And the capabilities should contain
-      | capability    | path_to_element                                          | value             |
-      | files_sharing | user@@@expire_date@@@enabled                             | EMPTY             |
-      | files_sharing | group@@@expire_date@@@enabled                            | EMPTY             |
-      | files_sharing | providers_capabilities@@@ocinternal@@@user@@@element[0]  | shareExpiration   |
-      | files_sharing | providers_capabilities@@@ocinternal@@@group@@@element[0] | shareExpiration   |
-      | files_sharing | providers_capabilities@@@ocinternal@@@link@@@element[0]  | shareExpiration   |
-      | files_sharing | providers_capabilities@@@ocinternal@@@link@@@element[1]  | passwordProtected |
-
-  @smokeTest @skipOnOcis
-  Scenario: the default capabilities should include share expiration for all of user, group, link and remote (federated)
-    When the administrator retrieves the capabilities using the capabilities API
-    Then the OCS status code should be "100"
-    And the HTTP status code should be "200"
-    And the capabilities should contain
-      | capability    | path_to_element                                                   | value           |
-      | files_sharing | user@@@expire_date@@@enabled                                      | EMPTY           |
-      | files_sharing | group@@@expire_date@@@enabled                                     | EMPTY           |
-      | files_sharing | remote@@@expire_date@@@enabled                                    | EMPTY           |
-      | files_sharing | providers_capabilities@@@ocinternal@@@user@@@element[0]           | shareExpiration |
-      | files_sharing | providers_capabilities@@@ocinternal@@@group@@@element[0]          | shareExpiration |
-      | files_sharing | providers_capabilities@@@ocinternal@@@link@@@element[0]           | shareExpiration |
-      | files_sharing | providers_capabilities@@@ocFederatedSharing@@@remote@@@element[0] | shareExpiration |
-
-  @smokeTest @skipOnOcis
-  Scenario: getting new default capabilities in versions after 10.5.0 with admin user
-    When the administrator retrieves the capabilities using the capabilities API
-    Then the OCS status code should be "100"
-    And the HTTP status code should be "200"
-    And the capabilities should contain
-      | capability | path_to_element                 | value |
-      | files      | favorites                       | 1     |
-      | files      | file_locking_support            | 1     |
-      | files      | file_locking_enable_file_action | EMPTY |
-
-  @smokeTest @skipOnOcis
-  Scenario: lock file action can be enabled
-    Given parameter "enable_lock_file_action" of app "files" has been set to "yes"
-    When the administrator retrieves the capabilities using the capabilities API
-    Then the OCS status code should be "100"
-    And the HTTP status code should be "200"
-    And the capabilities should contain
-      | capability | path_to_element                 | value |
-      | files      | file_locking_support            | 1     |
-      | files      | file_locking_enable_file_action | 1     |
-
-  @smokeTest @skipOnOcis
+  @smokeTest @issue-ocis-1285
   Scenario: getting default capabilities with admin user
     When the administrator retrieves the capabilities using the capabilities API
     Then the OCS status code should be "100"
@@ -153,7 +31,7 @@ Feature: capabilities
       | capability | path_to_element | value |
       | files      | versioning      | 1     |
 
-  @skipOnOcis
+  @issue-ocis-1285
   Scenario: getting default_permissions capability with admin user
     When the administrator retrieves the capabilities using the capabilities API
     Then the OCS status code should be "100"
@@ -162,17 +40,7 @@ Feature: capabilities
       | capability    | path_to_element     | value |
       | files_sharing | default_permissions | 31    |
 
-  @skipOnOcis
-  Scenario: default_permissions capability can be changed
-    Given parameter "shareapi_default_permissions" of app "core" has been set to "7"
-    When the administrator retrieves the capabilities using the capabilities API
-    Then the OCS status code should be "100"
-    And the HTTP status code should be "200"
-    And the capabilities should contain
-      | capability    | path_to_element     | value |
-      | files_sharing | default_permissions | 7     |
-
-  @skipOnOcis
+  @issue-ocis-1285
   Scenario: .htaccess is reported as a blacklisted file by default
     When the administrator retrieves the capabilities using the capabilities API
     Then the OCS status code should be "100"
@@ -181,768 +49,6 @@ Feature: capabilities
       | capability | path_to_element                | value     |
       | files      | blacklisted_files@@@element[0] | .htaccess |
 
-  @skipOnOcis
-  Scenario: multiple files can be reported as blacklisted
-    Given the administrator has updated system config key "blacklisted_files" with value '["test.txt",".htaccess"]' and type "json"
-    When the administrator retrieves the capabilities using the capabilities API
-    Then the OCS status code should be "100"
-    And the HTTP status code should be "200"
-    And the capabilities should contain
-      | capability | path_to_element                | value     |
-      | files      | blacklisted_files@@@element[0] | test.txt  |
-      | files      | blacklisted_files@@@element[1] | .htaccess |
-
-  @skipOnOcis
-  Scenario: user expire date can be enabled
-    Given parameter "shareapi_default_expire_date_user_share" of app "core" has been set to "yes"
-    When the administrator retrieves the capabilities using the capabilities API
-    Then the OCS status code should be "100"
-    And the HTTP status code should be "200"
-    And the capabilities should contain
-      | capability    | path_to_element               | value |
-      | files_sharing | user@@@expire_date@@@enabled  | 1     |
-      | files_sharing | user@@@expire_date@@@days     | 7     |
-      | files_sharing | user@@@expire_date@@@enforced | EMPTY |
-
-  @skipOnOcis
-  Scenario: user expire date can be enforced
-    Given parameter "shareapi_default_expire_date_user_share" of app "core" has been set to "yes"
-    And parameter "shareapi_enforce_expire_date_user_share" of app "core" has been set to "yes"
-    When the administrator retrieves the capabilities using the capabilities API
-    Then the OCS status code should be "100"
-    And the HTTP status code should be "200"
-    And the capabilities should contain
-      | capability    | path_to_element               | value |
-      | files_sharing | user@@@expire_date@@@enabled  | 1     |
-      | files_sharing | user@@@expire_date@@@days     | 7     |
-      | files_sharing | user@@@expire_date@@@enforced | 1     |
-
-  @skipOnOcis
-  Scenario: user expire date days can be set
-    Given parameter "shareapi_default_expire_date_user_share" of app "core" has been set to "yes"
-    And parameter "shareapi_expire_after_n_days_user_share" of app "core" has been set to "14"
-    When the administrator retrieves the capabilities using the capabilities API
-    Then the OCS status code should be "100"
-    And the HTTP status code should be "200"
-    And the capabilities should contain
-      | capability    | path_to_element               | value |
-      | files_sharing | user@@@expire_date@@@enabled  | 1     |
-      | files_sharing | user@@@expire_date@@@days     | 14    |
-      | files_sharing | user@@@expire_date@@@enforced | EMPTY |
-
-  @skipOnOcis
-  Scenario: group expire date can be enabled
-    Given parameter "shareapi_default_expire_date_group_share" of app "core" has been set to "yes"
-    When the administrator retrieves the capabilities using the capabilities API
-    Then the OCS status code should be "100"
-    And the HTTP status code should be "200"
-    And the capabilities should contain
-      | capability    | path_to_element                | value |
-      | files_sharing | group@@@expire_date@@@enabled  | 1     |
-      | files_sharing | group@@@expire_date@@@days     | 7     |
-      | files_sharing | group@@@expire_date@@@enforced | EMPTY |
-
-  @skipOnOcis
-  Scenario: group expire date can be enforced
-    Given parameter "shareapi_default_expire_date_group_share" of app "core" has been set to "yes"
-    And parameter "shareapi_enforce_expire_date_group_share" of app "core" has been set to "yes"
-    When the administrator retrieves the capabilities using the capabilities API
-    Then the OCS status code should be "100"
-    And the HTTP status code should be "200"
-    And the capabilities should contain
-      | capability    | path_to_element                | value |
-      | files_sharing | group@@@expire_date@@@enabled  | 1     |
-      | files_sharing | group@@@expire_date@@@days     | 7     |
-      | files_sharing | group@@@expire_date@@@enforced | 1     |
-
-  @skipOnOcis
-  Scenario: group expire date days can be set
-    Given parameter "shareapi_default_expire_date_group_share" of app "core" has been set to "yes"
-    And parameter "shareapi_expire_after_n_days_group_share" of app "core" has been set to "14"
-    When the administrator retrieves the capabilities using the capabilities API
-    Then the OCS status code should be "100"
-    And the HTTP status code should be "200"
-    And the capabilities should contain
-      | capability    | path_to_element                | value |
-      | files_sharing | group@@@expire_date@@@enabled  | 1     |
-      | files_sharing | group@@@expire_date@@@days     | 14    |
-      | files_sharing | group@@@expire_date@@@enforced | EMPTY |
-
-  #feature added in #31824 released in 10.0.10
-  @smokeTest @skipOnOcis
-  Scenario: getting capabilities with admin user
-    When the administrator retrieves the capabilities using the capabilities API
-    Then the OCS status code should be "100"
-    And the HTTP status code should be "200"
-    And the capabilities should contain
-      | capability    | path_to_element | value |
-      | files_sharing | can_share       | 1     |
-
-  #feature added in #32414 released in 10.0.10
-  @skipOnOcis
-  Scenario: getting async capabilities when async operations are enabled
-    Given the administrator has enabled async operations
-    When the administrator retrieves the capabilities using the capabilities API
-    Then the OCS status code should be "100"
-    And the HTTP status code should be "200"
-    And the capabilities should contain
-      | capability | path_to_element | value |
-      | async      |                 | 1.0   |
-
-
-  Scenario: getting async capabilities when async operations are disabled
-    Given the administrator has disabled async operations
-    When the administrator retrieves the capabilities using the capabilities API
-    Then the capabilities should contain
-      | capability | path_to_element | value |
-      | async      |                 | EMPTY |
-
-  @skipOnOcis
-  Scenario: Changing public upload
-    Given parameter "shareapi_allow_public_upload" of app "core" has been set to "no"
-    When the administrator retrieves the capabilities using the capabilities API
-    Then the OCS status code should be "100"
-    And the HTTP status code should be "200"
-    And the capabilities should contain
-      | capability    | path_to_element                       | value             |
-      | core          | pollinterval                          | 30000             |
-      | core          | webdav-root                           | remote.php/webdav |
-      | files_sharing | api_enabled                           | 1                 |
-      | files_sharing | can_share                             | 1                 |
-      | files_sharing | public@@@enabled                      | 1                 |
-      | files_sharing | public@@@multiple                     | 1                 |
-      | files_sharing | public@@@upload                       | EMPTY             |
-      | files_sharing | public@@@send_mail                    | EMPTY             |
-      | files_sharing | public@@@social_share                 | 1                 |
-      | files_sharing | resharing                             | 1                 |
-      | files_sharing | federation@@@outgoing                 | 1                 |
-      | files_sharing | federation@@@incoming                 | 1                 |
-      | files_sharing | group_sharing                         | 1                 |
-      | files_sharing | share_with_group_members_only         | EMPTY             |
-      | files_sharing | user_enumeration@@@enabled            | 1                 |
-      | files_sharing | user_enumeration@@@group_members_only | EMPTY             |
-      | files         | bigfilechunking                       | 1                 |
-
-  @skipOnOcis
-  Scenario: Disabling share api
-    Given parameter "shareapi_enabled" of app "core" has been set to "no"
-    When the administrator retrieves the capabilities using the capabilities API
-    Then the OCS status code should be "100"
-    And the HTTP status code should be "200"
-    And the capabilities should contain
-      | capability    | path_to_element       | value             |
-      | core          | pollinterval          | 30000             |
-      | core          | webdav-root           | remote.php/webdav |
-      | files_sharing | api_enabled           | EMPTY             |
-      | files_sharing | can_share             | EMPTY             |
-      | files_sharing | public@@@enabled      | EMPTY             |
-      | files_sharing | public@@@multiple     | EMPTY             |
-      | files_sharing | public@@@upload       | EMPTY             |
-      | files_sharing | resharing             | EMPTY             |
-      | files_sharing | federation@@@outgoing | 1                 |
-      | files_sharing | federation@@@incoming | 1                 |
-      | files         | bigfilechunking       | 1                 |
-
-  @skipOnOcis
-  Scenario: Disabling public links
-    Given parameter "shareapi_allow_links" of app "core" has been set to "no"
-    When the administrator retrieves the capabilities using the capabilities API
-    Then the OCS status code should be "100"
-    And the HTTP status code should be "200"
-    And the capabilities should contain
-      | capability    | path_to_element                       | value             |
-      | core          | pollinterval                          | 30000             |
-      | core          | webdav-root                           | remote.php/webdav |
-      | files_sharing | api_enabled                           | 1                 |
-      | files_sharing | can_share                             | 1                 |
-      | files_sharing | public@@@enabled                      | EMPTY             |
-      | files_sharing | public@@@multiple                     | EMPTY             |
-      | files_sharing | public@@@upload                       | EMPTY             |
-      | files_sharing | resharing                             | 1                 |
-      | files_sharing | federation@@@outgoing                 | 1                 |
-      | files_sharing | federation@@@incoming                 | 1                 |
-      | files_sharing | group_sharing                         | 1                 |
-      | files_sharing | share_with_group_members_only         | EMPTY             |
-      | files_sharing | user_enumeration@@@enabled            | 1                 |
-      | files_sharing | user_enumeration@@@group_members_only | EMPTY             |
-      | files         | bigfilechunking                       | 1                 |
-
-  @skipOnOcis
-  Scenario: Changing resharing
-    Given parameter "shareapi_allow_resharing" of app "core" has been set to "no"
-    When the administrator retrieves the capabilities using the capabilities API
-    Then the OCS status code should be "100"
-    And the HTTP status code should be "200"
-    And the capabilities should contain
-      | capability    | path_to_element                       | value             |
-      | core          | pollinterval                          | 30000             |
-      | core          | webdav-root                           | remote.php/webdav |
-      | files_sharing | api_enabled                           | 1                 |
-      | files_sharing | can_share                             | 1                 |
-      | files_sharing | public@@@enabled                      | 1                 |
-      | files_sharing | public@@@upload                       | 1                 |
-      | files_sharing | public@@@send_mail                    | EMPTY             |
-      | files_sharing | public@@@social_share                 | 1                 |
-      | files_sharing | resharing                             | EMPTY             |
-      | files_sharing | federation@@@outgoing                 | 1                 |
-      | files_sharing | federation@@@incoming                 | 1                 |
-      | files_sharing | group_sharing                         | 1                 |
-      | files_sharing | share_with_group_members_only         | EMPTY             |
-      | files_sharing | user_enumeration@@@enabled            | 1                 |
-      | files_sharing | user_enumeration@@@group_members_only | EMPTY             |
-      | files         | bigfilechunking                       | 1                 |
-
-  @skipOnOcis
-  Scenario: Changing federation outgoing
-    Given parameter "outgoing_server2server_share_enabled" of app "files_sharing" has been set to "no"
-    When the administrator retrieves the capabilities using the capabilities API
-    Then the OCS status code should be "100"
-    And the HTTP status code should be "200"
-    And the capabilities should contain
-      | capability    | path_to_element                       | value             |
-      | core          | pollinterval                          | 30000             |
-      | core          | webdav-root                           | remote.php/webdav |
-      | files_sharing | api_enabled                           | 1                 |
-      | files_sharing | can_share                             | 1                 |
-      | files_sharing | public@@@enabled                      | 1                 |
-      | files_sharing | public@@@upload                       | 1                 |
-      | files_sharing | public@@@send_mail                    | EMPTY             |
-      | files_sharing | public@@@social_share                 | 1                 |
-      | files_sharing | resharing                             | 1                 |
-      | files_sharing | federation@@@outgoing                 | EMPTY             |
-      | files_sharing | federation@@@incoming                 | 1                 |
-      | files_sharing | group_sharing                         | 1                 |
-      | files_sharing | share_with_group_members_only         | EMPTY             |
-      | files_sharing | user_enumeration@@@enabled            | 1                 |
-      | files_sharing | user_enumeration@@@group_members_only | EMPTY             |
-      | files         | bigfilechunking                       | 1                 |
-
-  @skipOnOcis
-  Scenario: Changing federation incoming
-    Given parameter "incoming_server2server_share_enabled" of app "files_sharing" has been set to "no"
-    When the administrator retrieves the capabilities using the capabilities API
-    Then the OCS status code should be "100"
-    And the HTTP status code should be "200"
-    And the capabilities should contain
-      | capability    | path_to_element                       | value             |
-      | core          | pollinterval                          | 30000             |
-      | core          | webdav-root                           | remote.php/webdav |
-      | files_sharing | api_enabled                           | 1                 |
-      | files_sharing | can_share                             | 1                 |
-      | files_sharing | public@@@enabled                      | 1                 |
-      | files_sharing | public@@@upload                       | 1                 |
-      | files_sharing | public@@@send_mail                    | EMPTY             |
-      | files_sharing | public@@@social_share                 | 1                 |
-      | files_sharing | resharing                             | 1                 |
-      | files_sharing | federation@@@outgoing                 | 1                 |
-      | files_sharing | federation@@@incoming                 | EMPTY             |
-      | files_sharing | group_sharing                         | 1                 |
-      | files_sharing | share_with_group_members_only         | EMPTY             |
-      | files_sharing | user_enumeration@@@enabled            | 1                 |
-      | files_sharing | user_enumeration@@@group_members_only | EMPTY             |
-      | files         | bigfilechunking                       | 1                 |
-
-  @skipOnOcis
-  Scenario: Changing "password enforced for read-only public link shares"
-    Given parameter "shareapi_enforce_links_password_read_only" of app "core" has been set to "yes"
-    When the administrator retrieves the capabilities using the capabilities API
-    Then the OCS status code should be "100"
-    And the HTTP status code should be "200"
-    And the capabilities should contain
-      | capability    | path_to_element                                | value             |
-      | core          | pollinterval                                   | 30000             |
-      | core          | webdav-root                                    | remote.php/webdav |
-      | files_sharing | api_enabled                                    | 1                 |
-      | files_sharing | can_share                                      | 1                 |
-      | files_sharing | public@@@enabled                               | 1                 |
-      | files_sharing | public@@@upload                                | 1                 |
-      | files_sharing | public@@@send_mail                             | EMPTY             |
-      | files_sharing | public@@@social_share                          | 1                 |
-      | files_sharing | public@@@password@@@enforced_for@@@read_only   | 1                 |
-      | files_sharing | public@@@password@@@enforced_for@@@read_write  | EMPTY             |
-      | files_sharing | public@@@password@@@enforced_for@@@upload_only | EMPTY             |
-      | files_sharing | resharing                                      | 1                 |
-      | files_sharing | federation@@@outgoing                          | 1                 |
-      | files_sharing | federation@@@incoming                          | 1                 |
-      | files_sharing | group_sharing                                  | 1                 |
-      | files_sharing | share_with_group_members_only                  | EMPTY             |
-      | files_sharing | user_enumeration@@@enabled                     | 1                 |
-      | files_sharing | user_enumeration@@@group_members_only          | EMPTY             |
-      | files         | bigfilechunking                                | 1                 |
-
-  @skipOnOcis
-  Scenario: Changing "password enforced for read-write public link shares"
-    Given parameter "shareapi_enforce_links_password_read_write" of app "core" has been set to "yes"
-    When the administrator retrieves the capabilities using the capabilities API
-    Then the OCS status code should be "100"
-    And the HTTP status code should be "200"
-    And the capabilities should contain
-      | capability    | path_to_element                                | value             |
-      | core          | pollinterval                                   | 30000             |
-      | core          | webdav-root                                    | remote.php/webdav |
-      | files_sharing | api_enabled                                    | 1                 |
-      | files_sharing | can_share                                      | 1                 |
-      | files_sharing | public@@@enabled                               | 1                 |
-      | files_sharing | public@@@upload                                | 1                 |
-      | files_sharing | public@@@send_mail                             | EMPTY             |
-      | files_sharing | public@@@social_share                          | 1                 |
-      | files_sharing | public@@@password@@@enforced_for@@@read_only   | EMPTY             |
-      | files_sharing | public@@@password@@@enforced_for@@@read_write  | 1                 |
-      | files_sharing | public@@@password@@@enforced_for@@@upload_only | EMPTY             |
-      | files_sharing | resharing                                      | 1                 |
-      | files_sharing | federation@@@outgoing                          | 1                 |
-      | files_sharing | federation@@@incoming                          | 1                 |
-      | files_sharing | group_sharing                                  | 1                 |
-      | files_sharing | share_with_group_members_only                  | EMPTY             |
-      | files_sharing | user_enumeration@@@enabled                     | 1                 |
-      | files_sharing | user_enumeration@@@group_members_only          | EMPTY             |
-      | files         | bigfilechunking                                | 1                 |
-
-  @skipOnOcis
-  Scenario: Changing "password enforced for write-only public link shares"
-    Given parameter "shareapi_enforce_links_password_write_only" of app "core" has been set to "yes"
-    When the administrator retrieves the capabilities using the capabilities API
-    Then the OCS status code should be "100"
-    And the HTTP status code should be "200"
-    And the capabilities should contain
-      | capability    | path_to_element                                | value             |
-      | core          | pollinterval                                   | 30000             |
-      | core          | webdav-root                                    | remote.php/webdav |
-      | files_sharing | api_enabled                                    | 1                 |
-      | files_sharing | can_share                                      | 1                 |
-      | files_sharing | public@@@enabled                               | 1                 |
-      | files_sharing | public@@@upload                                | 1                 |
-      | files_sharing | public@@@send_mail                             | EMPTY             |
-      | files_sharing | public@@@social_share                          | 1                 |
-      | files_sharing | public@@@password@@@enforced_for@@@read_only   | EMPTY             |
-      | files_sharing | public@@@password@@@enforced_for@@@read_write  | EMPTY             |
-      | files_sharing | public@@@password@@@enforced_for@@@upload_only | 1                 |
-      | files_sharing | resharing                                      | 1                 |
-      | files_sharing | federation@@@outgoing                          | 1                 |
-      | files_sharing | federation@@@incoming                          | 1                 |
-      | files_sharing | group_sharing                                  | 1                 |
-      | files_sharing | share_with_group_members_only                  | EMPTY             |
-      | files_sharing | user_enumeration@@@enabled                     | 1                 |
-      | files_sharing | user_enumeration@@@group_members_only          | EMPTY             |
-      | files         | bigfilechunking                                | 1                 |
-
-  @skipOnOcis
-  Scenario: Changing public notifications
-    Given parameter "shareapi_allow_public_notification" of app "core" has been set to "yes"
-    When the administrator retrieves the capabilities using the capabilities API
-    Then the OCS status code should be "100"
-    And the HTTP status code should be "200"
-    And the capabilities should contain
-      | capability    | path_to_element                       | value             |
-      | core          | pollinterval                          | 30000             |
-      | core          | webdav-root                           | remote.php/webdav |
-      | files_sharing | api_enabled                           | 1                 |
-      | files_sharing | can_share                             | 1                 |
-      | files_sharing | public@@@enabled                      | 1                 |
-      | files_sharing | public@@@upload                       | 1                 |
-      | files_sharing | public@@@send_mail                    | 1                 |
-      | files_sharing | public@@@social_share                 | 1                 |
-      | files_sharing | resharing                             | 1                 |
-      | files_sharing | federation@@@outgoing                 | 1                 |
-      | files_sharing | federation@@@incoming                 | 1                 |
-      | files_sharing | group_sharing                         | 1                 |
-      | files_sharing | share_with_group_members_only         | EMPTY             |
-      | files_sharing | user_enumeration@@@enabled            | 1                 |
-      | files_sharing | user_enumeration@@@group_members_only | EMPTY             |
-      | files         | bigfilechunking                       | 1                 |
-
-  @skipOnOcis
-  Scenario: Changing public social share
-    Given parameter "shareapi_allow_social_share" of app "core" has been set to "no"
-    When the administrator retrieves the capabilities using the capabilities API
-    Then the OCS status code should be "100"
-    And the HTTP status code should be "200"
-    And the capabilities should contain
-      | capability    | path_to_element                       | value             |
-      | core          | pollinterval                          | 30000             |
-      | core          | webdav-root                           | remote.php/webdav |
-      | files_sharing | api_enabled                           | 1                 |
-      | files_sharing | can_share                             | 1                 |
-      | files_sharing | public@@@enabled                      | 1                 |
-      | files_sharing | public@@@upload                       | 1                 |
-      | files_sharing | public@@@send_mail                    | EMPTY             |
-      | files_sharing | public@@@social_share                 | EMPTY             |
-      | files_sharing | resharing                             | 1                 |
-      | files_sharing | federation@@@outgoing                 | 1                 |
-      | files_sharing | federation@@@incoming                 | 1                 |
-      | files_sharing | group_sharing                         | 1                 |
-      | files_sharing | share_with_group_members_only         | EMPTY             |
-      | files_sharing | user_enumeration@@@enabled            | 1                 |
-      | files_sharing | user_enumeration@@@group_members_only | EMPTY             |
-      | files         | bigfilechunking                       | 1                 |
-
-  @skipOnOcis
-  Scenario: Changing expire date
-    Given parameter "shareapi_default_expire_date" of app "core" has been set to "yes"
-    When the administrator retrieves the capabilities using the capabilities API
-    Then the OCS status code should be "100"
-    And the HTTP status code should be "200"
-    And the capabilities should contain
-      | capability    | path_to_element                       | value             |
-      | core          | pollinterval                          | 30000             |
-      | core          | webdav-root                           | remote.php/webdav |
-      | files_sharing | api_enabled                           | 1                 |
-      | files_sharing | can_share                             | 1                 |
-      | files_sharing | public@@@enabled                      | 1                 |
-      | files_sharing | public@@@upload                       | 1                 |
-      | files_sharing | public@@@send_mail                    | EMPTY             |
-      | files_sharing | public@@@social_share                 | 1                 |
-      | files_sharing | public@@@expire_date@@@enabled        | 1                 |
-      | files_sharing | resharing                             | 1                 |
-      | files_sharing | federation@@@outgoing                 | 1                 |
-      | files_sharing | federation@@@incoming                 | 1                 |
-      | files_sharing | group_sharing                         | 1                 |
-      | files_sharing | share_with_group_members_only         | EMPTY             |
-      | files_sharing | user_enumeration@@@enabled            | 1                 |
-      | files_sharing | user_enumeration@@@group_members_only | EMPTY             |
-      | files         | bigfilechunking                       | 1                 |
-
-  @skipOnOcis
-  Scenario: Changing expire date enforcing
-    Given parameter "shareapi_default_expire_date" of app "core" has been set to "yes"
-    And parameter "shareapi_enforce_expire_date" of app "core" has been set to "yes"
-    When the administrator retrieves the capabilities using the capabilities API
-    Then the OCS status code should be "100"
-    And the HTTP status code should be "200"
-    And the capabilities should contain
-      | capability    | path_to_element                       | value             |
-      | core          | pollinterval                          | 30000             |
-      | core          | webdav-root                           | remote.php/webdav |
-      | files_sharing | api_enabled                           | 1                 |
-      | files_sharing | can_share                             | 1                 |
-      | files_sharing | public@@@enabled                      | 1                 |
-      | files_sharing | public@@@upload                       | 1                 |
-      | files_sharing | public@@@send_mail                    | EMPTY             |
-      | files_sharing | public@@@social_share                 | 1                 |
-      | files_sharing | public@@@expire_date@@@enabled        | 1                 |
-      | files_sharing | public@@@expire_date@@@enforced       | 1                 |
-      | files_sharing | resharing                             | 1                 |
-      | files_sharing | federation@@@outgoing                 | 1                 |
-      | files_sharing | federation@@@incoming                 | 1                 |
-      | files_sharing | group_sharing                         | 1                 |
-      | files_sharing | share_with_group_members_only         | EMPTY             |
-      | files_sharing | user_enumeration@@@enabled            | 1                 |
-      | files_sharing | user_enumeration@@@group_members_only | EMPTY             |
-      | files         | bigfilechunking                       | 1                 |
-
-  @skipOnOcis
-  Scenario: Changing group sharing allowed
-    Given parameter "shareapi_allow_group_sharing" of app "core" has been set to "no"
-    When the administrator retrieves the capabilities using the capabilities API
-    Then the OCS status code should be "100"
-    And the HTTP status code should be "200"
-    And the capabilities should contain
-      | capability    | path_to_element                       | value             |
-      | core          | pollinterval                          | 30000             |
-      | core          | webdav-root                           | remote.php/webdav |
-      | files_sharing | api_enabled                           | 1                 |
-      | files_sharing | can_share                             | 1                 |
-      | files_sharing | public@@@enabled                      | 1                 |
-      | files_sharing | public@@@upload                       | 1                 |
-      | files_sharing | public@@@send_mail                    | EMPTY             |
-      | files_sharing | public@@@social_share                 | 1                 |
-      | files_sharing | resharing                             | 1                 |
-      | files_sharing | federation@@@outgoing                 | 1                 |
-      | files_sharing | federation@@@incoming                 | 1                 |
-      | files_sharing | group_sharing                         | EMPTY             |
-      | files_sharing | share_with_group_members_only         | EMPTY             |
-      | files_sharing | user_enumeration@@@enabled            | 1                 |
-      | files_sharing | user_enumeration@@@group_members_only | EMPTY             |
-      | files         | bigfilechunking                       | 1                 |
-
-  @skipOnOcis
-  Scenario: Changing only share with group member
-    Given parameter "shareapi_only_share_with_group_members" of app "core" has been set to "yes"
-    When the administrator retrieves the capabilities using the capabilities API
-    Then the OCS status code should be "100"
-    And the HTTP status code should be "200"
-    And the capabilities should contain
-      | capability    | path_to_element                       | value             |
-      | core          | pollinterval                          | 30000             |
-      | core          | webdav-root                           | remote.php/webdav |
-      | files_sharing | api_enabled                           | 1                 |
-      | files_sharing | can_share                             | 1                 |
-      | files_sharing | public@@@enabled                      | 1                 |
-      | files_sharing | public@@@upload                       | 1                 |
-      | files_sharing | public@@@send_mail                    | EMPTY             |
-      | files_sharing | public@@@social_share                 | 1                 |
-      | files_sharing | resharing                             | 1                 |
-      | files_sharing | federation@@@outgoing                 | 1                 |
-      | files_sharing | federation@@@incoming                 | 1                 |
-      | files_sharing | group_sharing                         | 1                 |
-      | files_sharing | share_with_group_members_only         | 1                 |
-      | files_sharing | user_enumeration@@@enabled            | 1                 |
-      | files_sharing | user_enumeration@@@group_members_only | EMPTY             |
-      | files         | bigfilechunking                       | 1                 |
-
-  @skipOnOcis
-  Scenario: Changing only share with membership groups
-    Given parameter "shareapi_only_share_with_membership_groups" of app "core" has been set to "yes"
-    When the administrator retrieves the capabilities using the capabilities API
-    Then the OCS status code should be "100"
-    And the HTTP status code should be "200"
-    And the capabilities should contain
-      | capability    | path_to_element                       | value             |
-      | core          | pollinterval                          | 30000             |
-      | core          | webdav-root                           | remote.php/webdav |
-      | files_sharing | api_enabled                           | 1                 |
-      | files_sharing | can_share                             | 1                 |
-      | files_sharing | public@@@enabled                      | 1                 |
-      | files_sharing | public@@@upload                       | 1                 |
-      | files_sharing | public@@@send_mail                    | EMPTY             |
-      | files_sharing | public@@@social_share                 | 1                 |
-      | files_sharing | resharing                             | 1                 |
-      | files_sharing | federation@@@outgoing                 | 1                 |
-      | files_sharing | federation@@@incoming                 | 1                 |
-      | files_sharing | group_sharing                         | 1                 |
-      | files_sharing | share_with_group_members_only         | EMPTY             |
-      | files_sharing | share_with_membership_groups_only     | 1                 |
-      | files_sharing | user_enumeration@@@enabled            | 1                 |
-      | files_sharing | user_enumeration@@@group_members_only | EMPTY             |
-      | files         | bigfilechunking                       | 1                 |
-
-  @skipOnOcis
-  Scenario: Changing auto accept share
-    Given parameter "shareapi_auto_accept_share" of app "core" has been set to "no"
-    When the administrator retrieves the capabilities using the capabilities API
-    Then the OCS status code should be "100"
-    And the HTTP status code should be "200"
-    And the capabilities should contain
-      | capability    | path_to_element                       | value             |
-      | core          | pollinterval                          | 30000             |
-      | core          | webdav-root                           | remote.php/webdav |
-      | files_sharing | api_enabled                           | 1                 |
-      | files_sharing | can_share                             | 1                 |
-      | files_sharing | public@@@enabled                      | 1                 |
-      | files_sharing | public@@@upload                       | 1                 |
-      | files_sharing | public@@@send_mail                    | EMPTY             |
-      | files_sharing | public@@@social_share                 | 1                 |
-      | files_sharing | resharing                             | 1                 |
-      | files_sharing | federation@@@outgoing                 | 1                 |
-      | files_sharing | federation@@@incoming                 | 1                 |
-      | files_sharing | group_sharing                         | 1                 |
-      | files_sharing | share_with_group_members_only         | EMPTY             |
-      | files_sharing | share_with_membership_groups_only     | EMPTY             |
-      | files_sharing | auto_accept_share                     | EMPTY             |
-      | files_sharing | user_enumeration@@@enabled            | 1                 |
-      | files_sharing | user_enumeration@@@group_members_only | EMPTY             |
-      | files         | bigfilechunking                       | 1                 |
-
-  @skipOnOcis
-  Scenario: Changing allow share dialog user enumeration
-    Given parameter "shareapi_allow_share_dialog_user_enumeration" of app "core" has been set to "no"
-    When the administrator retrieves the capabilities using the capabilities API
-    Then the OCS status code should be "100"
-    And the HTTP status code should be "200"
-    And the capabilities should contain
-      | capability    | path_to_element               | value             |
-      | core          | pollinterval                  | 30000             |
-      | core          | webdav-root                   | remote.php/webdav |
-      | files_sharing | api_enabled                   | 1                 |
-      | files_sharing | can_share                     | 1                 |
-      | files_sharing | public@@@enabled              | 1                 |
-      | files_sharing | public@@@upload               | 1                 |
-      | files_sharing | public@@@send_mail            | EMPTY             |
-      | files_sharing | public@@@social_share         | 1                 |
-      | files_sharing | resharing                     | 1                 |
-      | files_sharing | federation@@@outgoing         | 1                 |
-      | files_sharing | federation@@@incoming         | 1                 |
-      | files_sharing | group_sharing                 | 1                 |
-      | files_sharing | share_with_group_members_only | EMPTY             |
-      | files_sharing | user_enumeration@@@enabled    | EMPTY             |
-      | files         | bigfilechunking               | 1                 |
-
-  @skipOnOcis
-  Scenario: Changing allow share dialog user enumeration for group members only
-    Given parameter "shareapi_share_dialog_user_enumeration_group_members" of app "core" has been set to "yes"
-    When the administrator retrieves the capabilities using the capabilities API
-    Then the OCS status code should be "100"
-    And the HTTP status code should be "200"
-    And the capabilities should contain
-      | capability    | path_to_element                       | value             |
-      | core          | pollinterval                          | 30000             |
-      | core          | webdav-root                           | remote.php/webdav |
-      | files_sharing | api_enabled                           | 1                 |
-      | files_sharing | can_share                             | 1                 |
-      | files_sharing | public@@@enabled                      | 1                 |
-      | files_sharing | public@@@upload                       | 1                 |
-      | files_sharing | public@@@send_mail                    | EMPTY             |
-      | files_sharing | public@@@social_share                 | 1                 |
-      | files_sharing | resharing                             | 1                 |
-      | files_sharing | federation@@@outgoing                 | 1                 |
-      | files_sharing | federation@@@incoming                 | 1                 |
-      | files_sharing | group_sharing                         | 1                 |
-      | files_sharing | share_with_group_members_only         | EMPTY             |
-      | files_sharing | user_enumeration@@@enabled            | 1                 |
-      | files_sharing | user_enumeration@@@group_members_only | 1                 |
-      | files         | bigfilechunking                       | 1                 |
-
-  @skipOnOcis
-  Scenario: Changing allow mail notification
-    Given parameter "shareapi_allow_mail_notification" of app "core" has been set to "yes"
-    When the administrator retrieves the capabilities using the capabilities API
-    Then the OCS status code should be "100"
-    And the HTTP status code should be "200"
-    And the capabilities should contain
-      | capability    | path_to_element                       | value             |
-      | core          | pollinterval                          | 30000             |
-      | core          | webdav-root                           | remote.php/webdav |
-      | files_sharing | api_enabled                           | 1                 |
-      | files_sharing | can_share                             | 1                 |
-      | files_sharing | public@@@enabled                      | 1                 |
-      | files_sharing | public@@@upload                       | 1                 |
-      | files_sharing | public@@@send_mail                    | EMPTY             |
-      | files_sharing | public@@@social_share                 | 1                 |
-      | files_sharing | resharing                             | 1                 |
-      | files_sharing | federation@@@outgoing                 | 1                 |
-      | files_sharing | federation@@@incoming                 | 1                 |
-      | files_sharing | group_sharing                         | 1                 |
-      | files_sharing | share_with_group_members_only         | EMPTY             |
-      | files_sharing | user_enumeration@@@enabled            | 1                 |
-      | files_sharing | user_enumeration@@@group_members_only | EMPTY             |
-      | files_sharing | user@@@send_mail                      | 1                 |
-      | files         | bigfilechunking                       | 1                 |
-
-  @skipOnOcis
-  Scenario: Changing exclude groups from sharing
-    Given parameter "shareapi_exclude_groups" of app "core" has been set to "yes"
-    And group "group1" has been created
-    And group "hash#group" has been created
-    And group "group-3" has been created
-    And parameter "shareapi_exclude_groups_list" of app "core" has been set to '["group1","hash#group","group-3"]'
-    When the administrator retrieves the capabilities using the capabilities API
-    Then the OCS status code should be "100"
-    And the HTTP status code should be "200"
-    And the capabilities should contain
-      | capability    | path_to_element                       | value             |
-      | core          | pollinterval                          | 30000             |
-      | core          | webdav-root                           | remote.php/webdav |
-      | files_sharing | api_enabled                           | 1                 |
-      | files_sharing | can_share                             | 1                 |
-      | files_sharing | public@@@enabled                      | 1                 |
-      | files_sharing | public@@@upload                       | 1                 |
-      | files_sharing | public@@@send_mail                    | EMPTY             |
-      | files_sharing | public@@@social_share                 | 1                 |
-      | files_sharing | resharing                             | 1                 |
-      | files_sharing | federation@@@outgoing                 | 1                 |
-      | files_sharing | federation@@@incoming                 | 1                 |
-      | files_sharing | group_sharing                         | 1                 |
-      | files_sharing | share_with_group_members_only         | EMPTY             |
-      | files_sharing | user_enumeration@@@enabled            | 1                 |
-      | files_sharing | user_enumeration@@@group_members_only | EMPTY             |
-      | files         | bigfilechunking                       | 1                 |
-
-  @skipOnOcis
-  Scenario: When in a group that is excluded from sharing, can_share is off
-    Given parameter "shareapi_exclude_groups" of app "core" has been set to "yes"
-    And user "Alice" has been created with default attributes and without skeleton files
-    And group "group1" has been created
-    And group "hash#group" has been created
-    And group "group-3" has been created
-    And group "ordinary-group" has been created
-    And user "Alice" has been added to group "hash#group"
-    And parameter "shareapi_exclude_groups_list" of app "core" has been set to '["group1","hash#group","group-3"]'
-    When user "Alice" retrieves the capabilities using the capabilities API
-    Then the OCS status code should be "100"
-    And the HTTP status code should be "200"
-    And the capabilities should contain
-      | capability    | path_to_element                       | value             |
-      | core          | pollinterval                          | 30000             |
-      | core          | webdav-root                           | remote.php/webdav |
-      | files_sharing | api_enabled                           | 1                 |
-      | files_sharing | can_share                             | EMPTY             |
-      | files_sharing | public@@@enabled                      | 1                 |
-      | files_sharing | public@@@upload                       | 1                 |
-      | files_sharing | public@@@send_mail                    | EMPTY             |
-      | files_sharing | public@@@social_share                 | 1                 |
-      | files_sharing | resharing                             | 1                 |
-      | files_sharing | federation@@@outgoing                 | 1                 |
-      | files_sharing | federation@@@incoming                 | 1                 |
-      | files_sharing | group_sharing                         | 1                 |
-      | files_sharing | share_with_group_members_only         | EMPTY             |
-      | files_sharing | user_enumeration@@@enabled            | 1                 |
-      | files_sharing | user_enumeration@@@group_members_only | EMPTY             |
-      | files         | bigfilechunking                       | 1                 |
-
-  @skipOnOcis
-  Scenario: When not in any group that is excluded from sharing, can_share is on
-    Given parameter "shareapi_exclude_groups" of app "core" has been set to "yes"
-    And user "Alice" has been created with default attributes and without skeleton files
-    And group "group1" has been created
-    And group "hash#group" has been created
-    And group "group-3" has been created
-    And group "ordinary-group" has been created
-    And user "Alice" has been added to group "ordinary-group"
-    And parameter "shareapi_exclude_groups_list" of app "core" has been set to '["group1","hash#group","group-3"]'
-    When user "Alice" retrieves the capabilities using the capabilities API
-    Then the OCS status code should be "100"
-    And the HTTP status code should be "200"
-    And the capabilities should contain
-      | capability    | path_to_element                       | value             |
-      | core          | pollinterval                          | 30000             |
-      | core          | webdav-root                           | remote.php/webdav |
-      | files_sharing | api_enabled                           | 1                 |
-      | files_sharing | can_share                             | 1                 |
-      | files_sharing | public@@@enabled                      | 1                 |
-      | files_sharing | public@@@upload                       | 1                 |
-      | files_sharing | public@@@send_mail                    | EMPTY             |
-      | files_sharing | public@@@social_share                 | 1                 |
-      | files_sharing | resharing                             | 1                 |
-      | files_sharing | federation@@@outgoing                 | 1                 |
-      | files_sharing | federation@@@incoming                 | 1                 |
-      | files_sharing | group_sharing                         | 1                 |
-      | files_sharing | share_with_group_members_only         | EMPTY             |
-      | files_sharing | user_enumeration@@@enabled            | 1                 |
-      | files_sharing | user_enumeration@@@group_members_only | EMPTY             |
-      | files         | bigfilechunking                       | 1                 |
-
-  @skipOnOcis
-  Scenario: When in a group that is excluded from sharing and in another group, can_share is off
-    Given parameter "shareapi_exclude_groups" of app "core" has been set to "yes"
-    And user "Alice" has been created with default attributes and without skeleton files
-    And group "group1" has been created
-    And group "hash#group" has been created
-    And group "group-3" has been created
-    And group "ordinary-group" has been created
-    And user "Alice" has been added to group "hash#group"
-    And user "Alice" has been added to group "ordinary-group"
-    And parameter "shareapi_exclude_groups_list" of app "core" has been set to '["group1","hash#group","group-3"]'
-    When user "Alice" retrieves the capabilities using the capabilities API
-    Then the OCS status code should be "100"
-    And the HTTP status code should be "200"
-    And the capabilities should contain
-      | capability    | path_to_element                       | value             |
-      | core          | pollinterval                          | 30000             |
-      | core          | webdav-root                           | remote.php/webdav |
-      | files_sharing | api_enabled                           | 1                 |
-      | files_sharing | can_share                             | EMPTY             |
-      | files_sharing | public@@@enabled                      | 1                 |
-      | files_sharing | public@@@upload                       | 1                 |
-      | files_sharing | public@@@send_mail                    | EMPTY             |
-      | files_sharing | public@@@social_share                 | 1                 |
-      | files_sharing | resharing                             | 1                 |
-      | files_sharing | federation@@@outgoing                 | 1                 |
-      | files_sharing | federation@@@incoming                 | 1                 |
-      | files_sharing | group_sharing                         | 1                 |
-      | files_sharing | share_with_group_members_only         | EMPTY             |
-      | files_sharing | user_enumeration@@@enabled            | 1                 |
-      | files_sharing | user_enumeration@@@group_members_only | EMPTY             |
-      | files         | bigfilechunking                       | 1                 |
-
-  @skipOnOcis
-  Scenario: blacklisted_files_regex is reported in capabilities
-    When the administrator retrieves the capabilities using the capabilities API
-    Then the OCS status code should be "100"
-    And the HTTP status code should be "200"
-    And the capabilities should contain
-      | capability | path_to_element         | value    |
-      | files      | blacklisted_files_regex | \.(part\|filepart)$ |
-
   @smokeTest
   Scenario: getting default capabilities with admin user
     When the administrator retrieves the capabilities using the capabilities API
diff --git a/tests/acceptance/features/coreApiShareCreateSpecialToShares1/createShareExpirationDate.feature b/tests/acceptance/features/coreApiShareCreateSpecialToShares1/createShareExpirationDate.feature
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/tests/acceptance/features/coreApiShareCreateSpecialToShares1/createShareUniqueReceivedNames.feature b/tests/acceptance/features/coreApiShareCreateSpecialToShares1/createShareUniqueReceivedNames.feature
index 15739b7042f..b2efa2f54a1 100644
--- a/tests/acceptance/features/coreApiShareCreateSpecialToShares1/createShareUniqueReceivedNames.feature
+++ b/tests/acceptance/features/coreApiShareCreateSpecialToShares1/createShareUniqueReceivedNames.feature
@@ -12,7 +12,7 @@ Feature: resources shared with the same name are received with unique names
       | Carol    |
 
   @smokeTest @issue-ocis-2131
-  Scenario Outline: unique target names for incoming shares
+  Scenario: unique target names for incoming shares
     Given user "Alice" has created folder "/foo"
     And user "Brian" has created folder "/foo"
     When user "Alice" shares folder "/foo" with user "Carol" using the sharing API
@@ -23,12 +23,4 @@ Feature: resources shared with the same name are received with unique names
     And the HTTP status code of responses on all endpoints should be "200"
     And user "Carol" should see the following elements
       | Shares/foo/ |
-      | <share>     |
-    @skipOnOcis
-    Examples:
-      | share            |
-      | /Shares/foo (2)/ |
-    @skipOnOcV10
-    Examples:
-      | share            |
-      | /Shares/foo (1)/ |
\ No newline at end of file
+      | /Shares/foo (1)/     |
diff --git a/tests/acceptance/features/coreApiShareCreateSpecialToShares1/createShareWhenExcludedFromSharing.feature b/tests/acceptance/features/coreApiShareCreateSpecialToShares1/createShareWhenExcludedFromSharing.feature
deleted file mode 100644
index 3b8da45500c..00000000000
--- a/tests/acceptance/features/coreApiShareCreateSpecialToShares1/createShareWhenExcludedFromSharing.feature
+++ /dev/null
@@ -1,83 +0,0 @@
-@api @files_sharing-app-required @issue-ocis-reva-41 @skipOnOcis
-Feature: cannot share resources when in a group that is excluded from sharing
-
-  Background:
-    Given the administrator has set the default folder for received shares to "Shares"
-    And auto-accept shares has been disabled
-    And user "Alice" has been created with default attributes and without skeleton files
-    And user "Brian" has been created with default attributes and without skeleton files
-    And group "grp1" has been created
-    And user "Brian" has been added to group "grp1"
-
-
-  Scenario Outline: user who is excluded from sharing tries to share a file with another user
-    Given using OCS API version "<ocs_api_version>"
-    And parameter "shareapi_exclude_groups" of app "core" has been set to "yes"
-    And parameter "shareapi_exclude_groups_list" of app "core" has been set to '["grp1"]'
-    And user "Brian" has uploaded file "filesForUpload/textfile.txt" to "/fileToShare.txt"
-    When user "Brian" shares file "fileToShare.txt" with user "Alice" using the sharing API
-    Then the OCS status code should be "403"
-    And the HTTP status code should be "<http_status_code>"
-    And the sharing API should report to user "Alice" that no shares are in the pending state
-    And as "Alice" file "Shares/fileToShare.txt" should not exist
-    And as "Alice" file "fileToShare.txt" should not exist
-    Examples:
-      | ocs_api_version | http_status_code |
-      | 1               | 200              |
-      | 2               | 403              |
-
-
-  Scenario Outline: user who is excluded from sharing tries to share a file with a group
-    Given using OCS API version "<ocs_api_version>"
-    And user "Carol" has been created with default attributes and without skeleton files
-    And group "grp2" has been created
-    And user "Carol" has been added to group "grp2"
-    And parameter "shareapi_exclude_groups" of app "core" has been set to "yes"
-    And parameter "shareapi_exclude_groups_list" of app "core" has been set to '["grp1"]'
-    And user "Brian" has uploaded file "filesForUpload/textfile.txt" to "/fileToShare.txt"
-    When user "Brian" shares file "fileToShare.txt" with group "grp2" using the sharing API
-    Then the OCS status code should be "403"
-    And the HTTP status code should be "<http_status_code>"
-    And the sharing API should report to user "Carol" that no shares are in the pending state
-    And as "Carol" file "Shares/fileToShare.txt" should not exist
-    And as "Carol" file "fileToShare.txt" should not exist
-    Examples:
-      | ocs_api_version | http_status_code |
-      | 1               | 200              |
-      | 2               | 403              |
-
-
-  Scenario Outline: user who is excluded from sharing tries to share a folder with another user
-    Given using OCS API version "<ocs_api_version>"
-    And parameter "shareapi_exclude_groups" of app "core" has been set to "yes"
-    And parameter "shareapi_exclude_groups_list" of app "core" has been set to '["grp1"]'
-    And user "Brian" has created folder "folderToShare"
-    When user "Brian" shares folder "folderToShare" with user "Alice" using the sharing API
-    Then the OCS status code should be "403"
-    And the HTTP status code should be "<http_status_code>"
-    And the sharing API should report to user "Alice" that no shares are in the pending state
-    And as "Alice" folder "Shares/folderToShare" should not exist
-    And as "Alice" folder "folderToShare" should not exist
-    Examples:
-      | ocs_api_version | http_status_code |
-      | 1               | 200              |
-      | 2               | 403              |
-
-
-  Scenario Outline: user who is excluded from sharing tries to share a folder with a group
-    Given using OCS API version "<ocs_api_version>"
-    And group "grp0" has been created
-    And user "Alice" has been added to group "grp0"
-    And parameter "shareapi_exclude_groups" of app "core" has been set to "yes"
-    And parameter "shareapi_exclude_groups_list" of app "core" has been set to '["grp0"]'
-    And user "Alice" has created folder "folderToShare"
-    When user "Alice" shares folder "folderToShare" with group "grp1" using the sharing API
-    Then the OCS status code should be "403"
-    And the HTTP status code should be "<http_status_code>"
-    And the sharing API should report to user "Brian" that no shares are in the pending state
-    And as "Brian" folder "Shares/folderToShare" should not exist
-    And as "Brian" folder "folderToShare" should not exist
-    Examples:
-      | ocs_api_version | http_status_code |
-      | 1               | 200              |
-      | 2               | 403              |
diff --git a/tests/acceptance/features/coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature b/tests/acceptance/features/coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature
index 4a2eb030078..ef445d86680 100644
--- a/tests/acceptance/features/coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature
+++ b/tests/acceptance/features/coreApiShareCreateSpecialToShares2/createShareReceivedInMultipleWays.feature
@@ -33,13 +33,6 @@ Feature: share resources where the sharee receives the share in multiple ways
       | mimetype               | text/plain                |
       | storage_id             | ANY_VALUE                 |
       | share_type             | user                      |
-    @skipOnOcis
-    Examples:
-      | ocs_api_version | ocs_status_code | file_target               |
-      | 1               | 100             | /Shares/textfile0 (2).txt |
-      | 2               | 200             | /Shares/textfile0 (2).txt |
-
-    @skipOnOcV10 @issue-2131
     Examples:
       | ocs_api_version | ocs_status_code | file_target        |
       | 1               | 100             | /textfile0 (2).txt |
@@ -129,13 +122,8 @@ Feature: share resources where the sharee receives the share in multiple ways
       | permissions | read,update     |
     And the content of file "/Shares/randomfile.txt" for user "Alice" should be "First data"
     And the content of file "/Shares/randomfile (2).txt" for user "Alice" should be "Second data"
-    @skipOnOcis
-    Examples:
-      | ocs_api_version | file_target_1          | file_target_2              |
-      | 1               | /Shares/randomfile.txt | /Shares/randomfile (2).txt |
-      | 2               | /Shares/randomfile.txt | /Shares/randomfile (2).txt |
 
-    @skipOnOcV10 @issue-ocis-2131
+    @issue-ocis-2131
     Examples:
       | ocs_api_version | file_target_1   | file_target_2       |
       | 1               | /randomfile.txt | /randomfile (2).txt |
@@ -169,13 +157,8 @@ Feature: share resources where the sharee receives the share in multiple ways
       | permissions | read,share      |
     And as "Alice" folder "/Shares/zzzfolder/Brian" should exist
     And as "Alice" folder "/Shares/zzzfolder (2)/Carol" should exist
-    @skipOnOcis
-    Examples:
-      | ocs_api_version | file_target_1     | file_target_2         | ocs_status_code |
-      | 1               | /Shares/zzzfolder | /Shares/zzzfolder (2) | 100             |
-      | 2               | /Shares/zzzfolder | /Shares/zzzfolder (2) | 200             |
 
-    @skipOnOcV10 @issue-ocis-2131
+    @issue-ocis-2131
     Examples:
       | ocs_api_version | file_target_1 | file_target_2  | ocs_status_code |
       | 1               | /zzzfolder    | /zzzfolder (2) | 100             |
diff --git a/tests/acceptance/features/coreApiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature b/tests/acceptance/features/coreApiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature
deleted file mode 100644
index 0ddcd246af9..00000000000
--- a/tests/acceptance/features/coreApiShareCreateSpecialToShares2/createShareWhenShareWithOnlyMembershipGroups.feature
+++ /dev/null
@@ -1,127 +0,0 @@
-@api @files_sharing-app-required @issue-ocis-1328
-Feature: cannot share resources outside the group when share with membership groups is enabled
-
-  Background:
-    Given the administrator has set the default folder for received shares to "Shares"
-    And auto-accept shares has been disabled
-    And user "Alice" has been created with default attributes and without skeleton files
-
-  @issue-ocis-1328 @skipOnOcis
-  Scenario Outline: sharer should not be able to share a folder to a group which he/she is not member of when share with only member group is enabled
-    Given using OCS API version "<ocs_api_version>"
-    And parameter "shareapi_only_share_with_membership_groups" of app "core" has been set to "yes"
-    And user "Brian" has been created with default attributes and without skeleton files
-    And group "grp0" has been created
-    And group "grp1" has been created
-    And user "Alice" has been added to group "grp0"
-    And user "Brian" has been added to group "grp1"
-    And user "Alice" has created folder "PARENT"
-    When user "Alice" shares folder "/PARENT" with group "grp1" using the sharing API
-    Then the OCS status code should be "<ocs_status_code>"
-    And the HTTP status code should be "<http_status_code>"
-    And as "Brian" folder "/PARENT" should not exist
-    And as "Brian" folder "/Shares/PARENT" should not exist
-    And the sharing API should report to user "Brian" that no shares are in the pending state
-    Examples:
-      | ocs_api_version | ocs_status_code | http_status_code |
-      | 1               | 403             | 200              |
-      | 2               | 403             | 403              |
-
-
-  Scenario Outline: sharer should be able to share a folder to a user who is not member of sharer group when share with only member group is enabled
-    Given using OCS API version "<ocs_api_version>"
-    And parameter "shareapi_only_share_with_membership_groups" of app "core" has been set to "yes"
-    And user "Brian" has been created with default attributes and without skeleton files
-    And group "grp0" has been created
-    And user "Alice" has been added to group "grp0"
-    And user "Alice" has created folder "PARENT"
-    When user "Alice" shares folder "/PARENT" with user "Brian" using the sharing API
-    And user "Brian" accepts share "/PARENT" offered by user "Alice" using the sharing API
-    Then the OCS status code of responses on all endpoints should be "<ocs_status_code>"
-    And the HTTP status code of responses on all endpoints should be "200"
-    And as "Brian" folder "/Shares/PARENT" should exist
-    But as "Brian" folder "/PARENT" should not exist
-    Examples:
-      | ocs_api_version | ocs_status_code |
-      | 1               | 100             |
-      | 2               | 200             |
-
-
-  Scenario Outline: sharer should be able to share a folder to a group which he/she is member of when share with only member group is enabled
-    Given using OCS API version "<ocs_api_version>"
-    And parameter "shareapi_only_share_with_membership_groups" of app "core" has been set to "yes"
-    And user "Brian" has been created with default attributes and without skeleton files
-    And group "grp0" has been created
-    And user "Alice" has been added to group "grp0"
-    And user "Brian" has been added to group "grp0"
-    And user "Alice" has created folder "PARENT"
-    When user "Alice" shares folder "/PARENT" with group "grp0" using the sharing API
-    And user "Brian" accepts share "/PARENT" offered by user "Alice" using the sharing API
-    Then the OCS status code of responses on all endpoints should be "<ocs_status_code>"
-    And the HTTP status code of responses on all endpoints should be "200"
-    And as "Brian" folder "/Shares/PARENT" should exist
-    But as "Brian" folder "/PARENT" should not exist
-    Examples:
-      | ocs_api_version | ocs_status_code |
-      | 1               | 100             |
-      | 2               | 200             |
-
-  @issue-ocis-1328 @skipOnOcis
-  Scenario Outline: sharer should not be able to share a file to a group which he/she is not member of when share with only member group is enabled
-    Given using OCS API version "<ocs_api_version>"
-    And parameter "shareapi_only_share_with_membership_groups" of app "core" has been set to "yes"
-    And user "Brian" has been created with default attributes and without skeleton files
-    And group "grp0" has been created
-    And group "grp1" has been created
-    And user "Alice" has been added to group "grp0"
-    And user "Brian" has been added to group "grp1"
-    And user "Alice" has uploaded file "filesForUpload/textfile.txt" to "/textfile0.txt"
-    When user "Alice" shares file "/textfile0.txt" with group "grp1" using the sharing API
-    Then the OCS status code should be "<ocs_status_code>"
-    And the HTTP status code should be "<http_status_code>"
-    And as "Brian" file "/textfile0.txt" should not exist
-    And as "Brian" file "/Shares/textfile0.txt" should not exist
-    And the sharing API should report to user "Brian" that no shares are in the pending state
-    Examples:
-      | ocs_api_version | ocs_status_code | http_status_code |
-      | 1               | 403             | 200              |
-      | 2               | 403             | 403              |
-
-
-  Scenario Outline: sharer should be able to share a file to a group which he/she is member of when share with only member group is enabled
-    Given using OCS API version "<ocs_api_version>"
-    And parameter "shareapi_only_share_with_membership_groups" of app "core" has been set to "yes"
-    And user "Brian" has been created with default attributes and without skeleton files
-    And group "grp0" has been created
-    And user "Alice" has been added to group "grp0"
-    And user "Brian" has been added to group "grp0"
-    And user "Alice" has uploaded file "filesForUpload/textfile.txt" to "/textfile0.txt"
-    When user "Alice" shares folder "/textfile0.txt" with group "grp0" using the sharing API
-    And user "Brian" accepts share "/textfile0.txt" offered by user "Alice" using the sharing API
-    Then the OCS status code of responses on all endpoints should be "<ocs_status_code>"
-    And the HTTP status code of responses on all endpoints should be "200"
-    And as "Brian" file "/Shares/textfile0.txt" should exist
-    But as "Brian" file "/textfile0.txt" should not exist
-    Examples:
-      | ocs_api_version | ocs_status_code |
-      | 1               | 100             |
-      | 2               | 200             |
-
-
-  Scenario Outline: sharer should be able to share a file to a user who is not a member of sharer group when share with only member group is enabled
-    Given using OCS API version "<ocs_api_version>"
-    And parameter "shareapi_only_share_with_membership_groups" of app "core" has been set to "yes"
-    And user "Brian" has been created with default attributes and without skeleton files
-    And group "grp0" has been created
-    And user "Alice" has been added to group "grp0"
-    And user "Alice" has uploaded file "filesForUpload/textfile.txt" to "/textfile0.txt"
-    When user "Alice" shares folder "/textfile0.txt" with user "Brian" using the sharing API
-    And user "Brian" accepts share "/textfile0.txt" offered by user "Alice" using the sharing API
-    Then the OCS status code of responses on all endpoints should be "<ocs_status_code>"
-    And the HTTP status code of responses on all endpoints should be "200"
-    And as "Brian" file "/Shares/textfile0.txt" should exist
-    But as "Brian" file "/textfile0.txt" should not exist
-    Examples:
-      | ocs_api_version | ocs_status_code |
-      | 1               | 100             |
-      | 2               | 200             |
diff --git a/tests/acceptance/features/coreApiShareManagementBasicToShares/createShareToSharesFolder.feature b/tests/acceptance/features/coreApiShareManagementBasicToShares/createShareToSharesFolder.feature
index a7931f60b74..abacfbc6f19 100644
--- a/tests/acceptance/features/coreApiShareManagementBasicToShares/createShareToSharesFolder.feature
+++ b/tests/acceptance/features/coreApiShareManagementBasicToShares/createShareToSharesFolder.feature
@@ -274,7 +274,7 @@ Feature: sharing
       | 1               | 100             |
       | 2               | 200             |
 
- 
+
   Scenario Outline: sharing again an own file while belonging to a group
     Given using OCS API version "<ocs_api_version>"
     And user "Brian" has been created with default attributes and without skeleton files
@@ -326,7 +326,7 @@ Feature: sharing
       | 1               | 100             |
       | 2               | 200             |
 
- 
+
   Scenario Outline: user shares a file with file name longer than 64 chars to another user
     Given using OCS API version "<ocs_api_version>"
     And user "Brian" has been created with default attributes and without skeleton files
@@ -342,7 +342,7 @@ Feature: sharing
       | 1               | 100             |
       | 2               | 200             |
 
- 
+
   Scenario Outline: user shares a file with file name longer than 64 chars to a group
     Given using OCS API version "<ocs_api_version>"
     And group "grp1" has been created
@@ -360,7 +360,7 @@ Feature: sharing
       | 1               | 100             |
       | 2               | 200             |
 
- 
+
   Scenario Outline: user shares a folder with folder name longer than 64 chars to another user
     Given using OCS API version "<ocs_api_version>"
     And user "Brian" has been created with default attributes and without skeleton files
@@ -377,7 +377,7 @@ Feature: sharing
       | 1               | 100             |
       | 2               | 200             |
 
- 
+
   Scenario Outline: user shares a folder with folder name longer than 64 chars to a group
     Given using OCS API version "<ocs_api_version>"
     And group "grp1" has been created
@@ -523,11 +523,6 @@ Feature: sharing
     And file "/textfile0.txt" should not be included as path in the response
     And as "Brian" file "/Shares/textfile0.txt" should not exist
     And as "Carol" file "/Shares/textfile0.txt" should not exist
-    @skipOnOcis
-    Examples:
-      | ocs_api_version | ocs_status_code | path                  |
-      | 1               | 100             | /Shares/textfile0.txt |
-      | 2               | 200             | /Shares/textfile0.txt |
     @skipOnOcV10 @issue-ocis-2441
     Examples:
       | ocs_api_version | ocs_status_code | path           |
diff --git a/tests/acceptance/features/coreApiShareManagementBasicToShares/excludeGroupFromReceivingSharesToSharesFolder.feature b/tests/acceptance/features/coreApiShareManagementBasicToShares/excludeGroupFromReceivingSharesToSharesFolder.feature
index 4cad03c72f5..4fa45a34b66 100644
--- a/tests/acceptance/features/coreApiShareManagementBasicToShares/excludeGroupFromReceivingSharesToSharesFolder.feature
+++ b/tests/acceptance/features/coreApiShareManagementBasicToShares/excludeGroupFromReceivingSharesToSharesFolder.feature
@@ -18,96 +18,6 @@ Feature: Exclude groups from receiving shares
     And user "Brian" has been added to group "grp1"
     And user "David" has been added to group "grp2"
 
-  @skipOnOcis
-  Scenario Outline: user cannot share with a group that is excluded from receiving shares but can share with other groups
-    Given using OCS API version "<ocs_api_version>"
-    And user "Alice" has created folder "PARENT"
-    And user "Alice" has uploaded file "filesForUpload/textfile.txt" to "fileToShare.txt"
-    And the administrator has added group "grp1" to the exclude groups from receiving shares list
-    When user "Alice" shares file "fileToShare.txt" with group "grp1" using the sharing API
-    Then the OCS status code should be "403"
-    And the HTTP status code should be "<http_status_code>"
-    And the OCS status message should be "The group is blacklisted for sharing"
-    And the sharing API should report to user "Brian" that no shares are in the pending state
-    When user "Alice" shares folder "PARENT" with group "grp1" using the sharing API
-    Then the OCS status code should be "403"
-    And the HTTP status code should be "<http_status_code>"
-    And the OCS status message should be "The group is blacklisted for sharing"
-    And the sharing API should report to user "Brian" that no shares are in the pending state
-    When user "Alice" shares file "fileToShare.txt" with group "grp2" using the sharing API
-    And user "Alice" shares folder "PARENT" with group "grp2" using the sharing API
-    And user "David" accepts share "/fileToShare.txt" offered by user "Alice" using the sharing API
-    And user "David" accepts share "/PARENT" offered by user "Alice" using the sharing API
-    Then as "David" file "/Shares/fileToShare.txt" should exist
-    And as "David" folder "/Shares/PARENT" should exist
-    Examples:
-      | ocs_api_version | http_status_code |
-      | 1               | 200              |
-      | 2               | 403              |
-
-  @skipOnOcis
-  Scenario Outline: exclude multiple groups from receiving shares stops the user to share with any of them
-    Given using OCS API version "<ocs_api_version>"
-    And group "grp3" has been created
-    And user "Brian" has been added to group "grp3"
-    And the administrator has added group "grp1, grp2, grp3" to the exclude group from sharing list
-    And user "Alice" has created folder "PARENT"
-    And user "Alice" has created folder "PARENT/CHILD"
-    And user "Alice" has uploaded file "filesForUpload/textfile.txt" to "fileToShare.txt"
-    And the administrator has added group "grp1" to the exclude groups from receiving shares list
-    And the administrator has added group "grp2" to the exclude groups from receiving shares list
-    And the administrator has added group "grp3" to the exclude groups from receiving shares list
-    When user "Alice" shares file "fileToShare.txt" with group "grp1" using the sharing API
-    Then the OCS status code should be "403"
-    And the HTTP status code should be "<http_status_code>"
-    And the OCS status message should be "The group is blacklisted for sharing"
-    And the sharing API should report to user "Brian" that no shares are in the pending state
-    When user "Alice" shares folder "PARENT" with group "grp2" using the sharing API
-    Then the OCS status code should be "403"
-    And the HTTP status code should be "<http_status_code>"
-    And the OCS status message should be "The group is blacklisted for sharing"
-    And the sharing API should report to user "David" that no shares are in the pending state
-    When user "Alice" shares folder "PARENT/CHILD" with group "grp3" using the sharing API
-    Then the OCS status code should be "403"
-    And the HTTP status code should be "<http_status_code>"
-    And the OCS status message should be "The group is blacklisted for sharing"
-    And the sharing API should report to user "Brian" that no shares are in the pending state
-    Examples:
-      | ocs_api_version | http_status_code |
-      | 1               | 200              |
-      | 2               | 403              |
-
-  @skipOnOcis
-  Scenario Outline: user cannot reshare a received share with a group that is excluded from receiving shares but can share with other groups
-    Given using OCS API version "<ocs_api_version>"
-    And user "Carol" has created folder "PARENT"
-    And user "Carol" has uploaded file "filesForUpload/textfile.txt" to "textfile0.txt"
-    And user "Carol" has shared file "textfile0.txt" with user "Alice"
-    And user "Alice" has accepted share "/textfile0.txt" offered by user "Carol"
-    And user "Carol" has shared folder "PARENT" with user "Alice"
-    And user "Alice" has accepted share "/PARENT" offered by user "Carol"
-    And the administrator has added group "grp1" to the exclude groups from receiving shares list
-    When user "Alice" shares file "/Shares/textfile0.txt" with group "grp1" using the sharing API
-    Then the OCS status code should be "403"
-    And the HTTP status code should be "<http_status_code>"
-    And the OCS status message should be "The group is blacklisted for sharing"
-    And the sharing API should report to user "Brian" that no shares are in the pending state
-    When user "Alice" shares folder "/Shares/PARENT" with group "grp1" using the sharing API
-    Then the OCS status code should be "403"
-    And the HTTP status code should be "<http_status_code>"
-    And the OCS status message should be "The group is blacklisted for sharing"
-    And the sharing API should report to user "Brian" that no shares are in the pending state
-    When user "Alice" shares file "/Shares/textfile0.txt" with group "grp2" using the sharing API
-    And user "Alice" shares folder "/Shares/PARENT" with group "grp2" using the sharing API
-    And user "David" accepts share "/textfile0.txt" offered by user "Alice" using the sharing API
-    And user "David" accepts share "/PARENT" offered by user "Alice" using the sharing API
-    Then as "David" file "/Shares/textfile0.txt" should exist
-    And as "David" folder "/Shares/PARENT" should exist
-    Examples:
-      | ocs_api_version | http_status_code |
-      | 1               | 200              |
-      | 2               | 403              |
-
 
   Scenario Outline: sharing with a user that is part of a group that is excluded from receiving shares still works
     Given using OCS API version "<ocs_api_version>"
diff --git a/tests/acceptance/features/coreApiShareManagementToShares/mergeShare.feature b/tests/acceptance/features/coreApiShareManagementToShares/mergeShare.feature
index a28b21edd25..0d195ba9af9 100644
--- a/tests/acceptance/features/coreApiShareManagementToShares/mergeShare.feature
+++ b/tests/acceptance/features/coreApiShareManagementToShares/mergeShare.feature
@@ -108,14 +108,9 @@ Feature: sharing
     And as user "Brian" folder "/merge-test-inside-twogroups-perms" should contain a property "oc:permissions" with value "<expected_permission_1>" or with value "<expected_permission_2>"
     And as "Brian" folder "/Shares/merge-test-inside-twogroups-perms" should not exist
     And as "Brian" folder "/Shares/merge-test-inside-twogroups-perms (2)" should not exist
-    @skipOnOcV10
     Examples:
       | expected_permission_1 | expected_permission_2 |
       | RDNVCKZ               | RMDNVCKZ              |
-    @skipOnOcis
-    Examples:
-      | expected_permission_1 | expected_permission_2 |
-      | RDNVCK                | RMDNVCK               |
 
 
   Scenario: Merging shares for recipient when shared from outside with group then user and recipient renames in between
diff --git a/tests/acceptance/features/coreApiShareOperationsToShares1/gettingShares.feature b/tests/acceptance/features/coreApiShareOperationsToShares1/gettingShares.feature
index 0018e5b2776..7a6c9859f41 100644
--- a/tests/acceptance/features/coreApiShareOperationsToShares1/gettingShares.feature
+++ b/tests/acceptance/features/coreApiShareOperationsToShares1/gettingShares.feature
@@ -106,8 +106,7 @@ Feature: sharing
       | 1               | 100             |
       | 2               | 200             |
 
-  @smokeTest @toFixOnOCIS @issue-ocis-reva-357 @issue-ocis-reva-301 @issue-ocis-reva-302
-  #after fixing all the issues merge this scenario with the one below
+  @smokeTest @issue-ocis-reva-357 @issue-ocis-reva-301 @issue-ocis-reva-302
   Scenario Outline: getting share info of a share
     Given using OCS API version "<ocs_api_version>"
     And user "Alice" has uploaded file with content "some data" to "/file_to_share.txt"
@@ -138,38 +137,6 @@ Feature: sharing
       | 1               | 100             |
       | 2               | 200             |
 
-  @smokeTest @toFixOnOCIS @issue-ocis-reva-357 @issue-ocis-reva-301 @issue-ocis-reva-302
-  #after fixing all the issues merge this scenario with the one above
-  Scenario Outline: getting share info of a share (Bug demonstration for ocis)
-    Given using OCS API version "<ocs_api_version>"
-    And user "Alice" has uploaded file with content "some data" to "/file_to_share.txt"
-    And user "Alice" has shared file "file_to_share.txt" with user "Brian"
-    And user "Brian" has accepted share "/file_to_share.txt" offered by user "Alice"
-    When user "Alice" gets the info of the last share using the sharing API
-    Then the OCS status code should be "<ocs_status_code>"
-    And the HTTP status code should be "200"
-    And the fields of the last response to user "Alice" sharing with user "Brian" should include
-      | id          | A_STRING                  |
-      | item_type   | file                      |
-      | item_source | A_STRING                  |
-      | share_type  | user                      |
-      | share_with  | %username%                |
-      | file_source | A_STRING                  |
-      | file_target | /Shares/file_to_share.txt |
-      | path        | /file_to_share.txt        |
-      | permissions | share,read,update         |
-      | stime       | A_NUMBER                  |
-      | storage     | A_STRING                  |
-      | mail_send   | 0                         |
-      | uid_owner   | %username%                |
-#      | share_with_displayname | %displayname%      |
-#      | displayname_owner      | %displayname%      |
-#      | mimetype               | text/plain         |
-    Examples:
-      | ocs_api_version | ocs_status_code |
-      | 1               | 100             |
-      | 2               | 200             |
-
   @issue-ocis-reva-374
   Scenario Outline: Get a share with a user that didn't receive the share
     Given using OCS API version "<ocs_api_version>"
diff --git a/tests/acceptance/features/coreApiSharePublicLink3/updatePublicLinkShare.feature b/tests/acceptance/features/coreApiSharePublicLink3/updatePublicLinkShare.feature
index 9eba9b1d4e0..299961af9a8 100644
--- a/tests/acceptance/features/coreApiSharePublicLink3/updatePublicLinkShare.feature
+++ b/tests/acceptance/features/coreApiSharePublicLink3/updatePublicLinkShare.feature
@@ -119,39 +119,6 @@ Feature: update a public link share
       | 1               | 100             |
       | 2               | 200             |
 
-  @issue-ocis-reva-336
-  Scenario Outline: Creating a new public link share, updating its expiration date and getting its info (ocis Bug demonstration)
-    Given using OCS API version "<ocs_api_version>"
-    And user "Alice" has created folder "FOLDER"
-    And user "Alice" has created a public link share with settings
-      | path | FOLDER |
-    And user "Alice" has updated the last public link share with
-      | expireDate | 2040-01-01T23:59:59+0100 |
-    When user "Alice" gets the info of the last public link share using the sharing API
-    Then the OCS status code should be "<ocs_status_code>"
-    And the HTTP status code should be "200"
-    And the fields of the last response to user "Alice" should include
-      | id                | A_STRING             |
-      | item_type         | folder               |
-      | item_source       | A_STRING             |
-      | share_type        | public_link          |
-      | file_source       | A_STRING             |
-      | file_target       | /FOLDER              |
-      | permissions       | read                 |
-      | stime             | A_NUMBER             |
-      | expiration        | 2040-01-01           |
-      | token             | A_TOKEN              |
-      | storage           | A_STRING             |
-      | mail_send         | 0                    |
-      | uid_owner         | %username%           |
-      | displayname_owner | %displayname%        |
-      | url               | AN_URL               |
-      | mimetype          | httpd/unix-directory |
-    Examples:
-      | ocs_api_version | ocs_status_code |
-      | 1               | 100             |
-      | 2               | 200             |
-
   @issue-ocis-reva-336
   Scenario Outline: Creating a new public link share, updating its password and getting its info
     Given using OCS API version "<ocs_api_version>"
@@ -305,6 +272,7 @@ Feature: update a public link share
       | 1               | 200              |
       | 2               | 404              |
 
+
   Scenario Outline: Adding public upload to a shared folder as recipient is allowed with permissions using the public API
     Given the administrator has set the default folder for received shares to "Shares"
     And auto-accept shares has been disabled
diff --git a/tests/acceptance/features/coreApiShareReshareToShares2/reShareDisabled.feature b/tests/acceptance/features/coreApiShareReshareToShares2/reShareDisabled.feature
index 1749f5f2b8e..54e43bc2e32 100644
--- a/tests/acceptance/features/coreApiShareReshareToShares2/reShareDisabled.feature
+++ b/tests/acceptance/features/coreApiShareReshareToShares2/reShareDisabled.feature
@@ -10,23 +10,6 @@ Feature: resharing can be disabled
       | Brian    |
     And user "Alice" has uploaded file "filesForUpload/textfile.txt" to "/textfile0.txt"
 
-  @smokeTest @skipOnOcis
-  Scenario Outline: resharing a file is not allowed when allow resharing has been disabled
-    Given using OCS API version "<ocs_api_version>"
-    And user "Carol" has been created with default attributes and without skeleton files
-    And user "Alice" has shared file "/textfile0.txt" with user "Brian" with permissions "share,update,read"
-    And user "Brian" has accepted share "/textfile0.txt" offered by user "Alice"
-    And parameter "shareapi_allow_resharing" of app "core" has been set to "no"
-    When user "Brian" shares file "/Shares/textfile0.txt" with user "Carol" with permissions "share,update,read" using the sharing API
-    Then the OCS status code should be "404"
-    And the HTTP status code should be "<http_status_code>"
-    And as "Carol" file "/Shares/textfile0.txt" should not exist
-    And the sharing API should report to user "Carol" that no shares are in the pending state
-    Examples:
-      | ocs_api_version | http_status_code |
-      | 1               | 200              |
-      | 2               | 404              |
-
 
   Scenario Outline: ordinary sharing is allowed when allow resharing has been disabled
     Given using OCS API version "<ocs_api_version>"
diff --git a/tests/acceptance/features/coreApiShareReshareToShares2/reShareWhenShareWithOnlyMembershipGroups.feature b/tests/acceptance/features/coreApiShareReshareToShares2/reShareWhenShareWithOnlyMembershipGroups.feature
deleted file mode 100644
index 0e4b2410faf..00000000000
--- a/tests/acceptance/features/coreApiShareReshareToShares2/reShareWhenShareWithOnlyMembershipGroups.feature
+++ /dev/null
@@ -1,48 +0,0 @@
-@api @files_sharing-app-required @issue-ocis-1289 @issue-ocis-reva-194 @issue-ocis-1328 @skipOnOcis
-Feature: resharing a resource with an expiration date
-
-  Background:
-    Given the administrator has set the default folder for received shares to "Shares"
-    And auto-accept shares has been disabled
-    And these users have been created with default attributes and without skeleton files:
-      | username |
-      | Alice    |
-      | Brian    |
-
-
-  Scenario Outline: User should not be able to re-share a folder to a group which he/she is not member of when share with only member group is enabled
-    Given using OCS API version "<ocs_api_version>"
-    And parameter "shareapi_only_share_with_membership_groups" of app "core" has been set to "yes"
-    And user "Carol" has been created with default attributes and without skeleton files
-    And group "grp1" has been created
-    And user "Carol" has been added to group "grp1"
-    And user "Alice" has created folder "/PARENT"
-    And user "Alice" has shared folder "/PARENT" with user "Brian"
-    And user "Brian" has accepted share "/PARENT" offered by user "Alice"
-    When user "Brian" shares folder "/Shares/PARENT" with group "grp1" using the sharing API
-    Then the OCS status code should be "<ocs_status_code>"
-    And the HTTP status code should be "<http_status_code>"
-    And as "Carol" folder "/Shares/PARENT" should not exist
-    Examples:
-      | ocs_api_version | ocs_status_code | http_status_code |
-      | 1               | 403             | 200              |
-      | 2               | 403             | 403              |
-
-
-  Scenario Outline: User should not be able to re-share a file to a group which he/she is not member of when share with only member group is enabled
-    Given using OCS API version "<ocs_api_version>"
-    And parameter "shareapi_only_share_with_membership_groups" of app "core" has been set to "yes"
-    And user "Carol" has been created with default attributes and without skeleton files
-    And group "grp1" has been created
-    And user "Carol" has been added to group "grp1"
-    And user "Alice" has uploaded file "filesForUpload/textfile.txt" to "/textfile0.txt"
-    And user "Alice" has shared file "/textfile0.txt" with user "Brian"
-    And user "Brian" has accepted share "/textfile0.txt" offered by user "Alice"
-    When user "Brian" shares folder "/Shares/textfile0.txt" with group "grp1" using the sharing API
-    Then the OCS status code should be "<ocs_status_code>"
-    And the HTTP status code should be "<http_status_code>"
-    And as "Carol" folder "/Shares/textfile0.txt" should not exist
-    Examples:
-      | ocs_api_version | ocs_status_code | http_status_code |
-      | 1               | 403             | 200              |
-      | 2               | 403             | 403              |
diff --git a/tests/acceptance/features/coreApiShareUpdateToShares/updateShare.feature b/tests/acceptance/features/coreApiShareUpdateToShares/updateShare.feature
index a0e49f8f5a1..37976edc4d3 100644
--- a/tests/acceptance/features/coreApiShareUpdateToShares/updateShare.feature
+++ b/tests/acceptance/features/coreApiShareUpdateToShares/updateShare.feature
@@ -190,12 +190,7 @@ Feature: sharing
       | mimetype          | httpd/unix-directory |
     And as "Alice" folder "/Alice-folder/folder2" should not exist
     And as "Carol" folder "/Carol-folder/folder2" should exist
-    @skipOnOcis
-    Examples:
-      | path                 |
-      | /Shares/Carol-folder |
-
-    @skipOnOcV10 @issue-2442
+    @issue-2442
     Examples:
       | path          |
       | /Carol-folder |
diff --git a/tests/acceptance/features/coreApiTranslation/translation.feature b/tests/acceptance/features/coreApiTranslation/translation.feature
deleted file mode 100644
index 290a9de9379..00000000000
--- a/tests/acceptance/features/coreApiTranslation/translation.feature
+++ /dev/null
@@ -1,36 +0,0 @@
-@api @skipOnLDAP @skipOnOcis
-Feature: translate messages in api response to preferred language
-  As a user
-  I want response messages to be translated in preferred language
-  So that I can see and understand the response messages in my language
-
-  Scenario Outline: user tries to get non existing share and uses some preferred language
-    Given these users have been created with default attributes and without skeleton files:
-      | username |
-      | Alice    |
-      | Brian    |
-      | Carol    |
-    And using <dav_version> DAV path
-    And user "Brian" has uploaded file "filesForUpload/textfile.txt" to "/textfile0.txt"
-    And user "Brian" has shared file "textfile0.txt" with user "Carol"
-    When user "Alice" gets the info of the last share in language "<language>" using the sharing API
-    Then the OCS status code should be "404"
-    And the OCS status message should be "Wrong share ID, share doesn't exist" in language "<language>"
-    Examples:
-      | dav_version | language |
-      | old         | de-DE    |
-      | old         | es-ES    |
-      | old         | zh-CN    |
-      | old         | fr-FR    |
-      | new         | de-DE    |
-      | new         | es-ES    |
-      | new         | zh-CN    |
-      | new         | fr-FR    |
-
-    @skipOnOcV10 @personalSpace
-    Examples:
-      | dav_version | language |
-      | spaces      | de-DE    |
-      | spaces      | es-ES    |
-      | spaces      | zh-CN    |
-      | spaces      | fr-FR    |
diff --git a/tests/acceptance/features/coreApiTrashbin/trashbinDelete.feature b/tests/acceptance/features/coreApiTrashbin/trashbinDelete.feature
index ae114b9e863..5d12f53d4d4 100644
--- a/tests/acceptance/features/coreApiTrashbin/trashbinDelete.feature
+++ b/tests/acceptance/features/coreApiTrashbin/trashbinDelete.feature
@@ -98,11 +98,7 @@ Feature: files and folders can be deleted from the trashbin
     And as "Alice" the file with original path "/textfile0.txt" should exist in the trashbin
     And as "Alice" the file with original path "/PARENT/parent.txt" should exist in the trashbin
     And as "Alice" the file with original path "/PARENT/CHILD/child.txt" should exist in the trashbin
-    @skipOnOcis
-    Examples:
-      | dav-path | status-code |
-      | new      | 401         |
-    @skipOnOcV10 @personalSpace
+    @personalSpace
     Examples:
       | dav-path | status-code |
       | new      | 404         |
diff --git a/tests/acceptance/features/coreApiTrashbin/trashbinFilesFolders.feature b/tests/acceptance/features/coreApiTrashbin/trashbinFilesFolders.feature
index c7e9dec76ab..314d05acf3c 100644
--- a/tests/acceptance/features/coreApiTrashbin/trashbinFilesFolders.feature
+++ b/tests/acceptance/features/coreApiTrashbin/trashbinFilesFolders.feature
@@ -188,11 +188,7 @@ Feature: files and folders exist in the trashbin after being deleted
     And the last webdav response should not contain the following elements
       | path          | user            |
       | textfile1.txt | testtrashbin100 |
-    @skipOnOcis
-    Examples:
-      | dav-path | status-code |
-      | new      | 401         |
-    @skipOnOcV10 @personalSpace
+    @personalSpace
     Examples:
       | dav-path | status-code |
       | new      | 404         |
@@ -213,11 +209,7 @@ Feature: files and folders exist in the trashbin after being deleted
       | path          | user            |
       | textfile0.txt | testtrashbin101 |
       | textfile2.txt | testtrashbin101 |
-    @skipOnOcis
-    Examples:
-      | dav-path | status-code |
-      | new      | 401         |
-    @skipOnOcV10 @personalSpace
+    @personalSpace
     Examples:
       | dav-path | status-code |
       | new      | 404         |
@@ -243,11 +235,7 @@ Feature: files and folders exist in the trashbin after being deleted
       | textfile0.txt | testtrashbin102 |
       | textfile2.txt | testtrashbin102 |
       | textfile3.txt | testtrashbin102 |
-    @skipOnOcis
-    Examples:
-      | dav-path | status-code |
-      | new      | 401         |
-    @skipOnOcV10 @personalSpace
+    @personalSpace
     Examples:
       | dav-path | status-code |
       | new      | 404         |
@@ -260,11 +248,7 @@ Feature: files and folders exist in the trashbin after being deleted
     And user "testtrashbinempty" has uploaded file "filesForUpload/textfile.txt" to "/textfile1.txt"
     When user "Alice" tries to list the trashbin content for user "testtrashbinempty"
     Then the HTTP status code should be "<status-code>"
-    @skipOnOcis
-    Examples:
-      | dav-path | status-code |
-      | new      | 401         |
-    @skipOnOcV10 @personalSpace
+    @personalSpace
     Examples:
       | dav-path | status-code |
       | new      | 404         |
diff --git a/tests/acceptance/features/coreApiTrashbinRestore/trashbinRestore.feature b/tests/acceptance/features/coreApiTrashbinRestore/trashbinRestore.feature
index f516c5c13f7..05a1b50c9c3 100644
--- a/tests/acceptance/features/coreApiTrashbinRestore/trashbinRestore.feature
+++ b/tests/acceptance/features/coreApiTrashbinRestore/trashbinRestore.feature
@@ -177,12 +177,6 @@ Feature: Restore deleted files/folders
     And as "Alice" the folder with original path "/textfile0.txt" should exist in the trashbin
     And user "Alice" should not see the following elements
       | /textfile0.txt |
-    @skipOnOcis
-    Examples:
-      | dav-path | status-code |
-      | old      | 401         |
-      | new      | 401         |
-    @skipOnOcV10
     Examples:
       | dav-path | status-code |
       | old      | 404         |
diff --git a/tests/acceptance/features/coreApiWebdavMove1/moveFolder.feature b/tests/acceptance/features/coreApiWebdavMove1/moveFolder.feature
index bd8cd64dacd..0ea0ef205e1 100644
--- a/tests/acceptance/features/coreApiWebdavMove1/moveFolder.feature
+++ b/tests/acceptance/features/coreApiWebdavMove1/moveFolder.feature
@@ -151,51 +151,3 @@ Feature: move (rename) folder
     Examples:
       | dav_version |
       | spaces      |
-
-  @files_sharing-app-required @skipOnOcis
-  Scenario Outline: Moving a folder out of a shared folder as the sharee and as the sharer
-    Given using <dav_version> DAV path
-    And user "Brian" has been created with default attributes and without skeleton files
-    And user "Brian" has created folder "/testshare"
-    And user "Brian" has created folder "/testshare/testsubfolder"
-    And user "Brian" has uploaded file with content "test data" to "/testshare/testsubfolder/testfile.txt"
-    And user "Brian" has created a share with settings
-      | path        | testshare |
-      | shareType   | user      |
-      | permissions | change    |
-      | shareWith   | Alice     |
-    When user "<mover>" moves folder "/testshare/testsubfolder" to "/testsubfolder" using the WebDAV API
-    Then the HTTP status code should be "201"
-    And the content of file "/testsubfolder/testfile.txt" for user "<mover>" should be "test data"
-    And as "Alice" folder "/testshare/testsubfolder" should not exist
-    And as "Brian" folder "/testshare/testsubfolder" should not exist
-    Examples:
-      | dav_version | mover |
-      | old         | Alice |
-      | old         | Brian |
-      | new         | Alice |
-      | new         | Brian |
-
-  @files_sharing-app-required @skipOnOcis
-  Scenario Outline: Moving a folder into a shared folder as the sharee and as the sharer
-    Given using <dav_version> DAV path
-    And user "Brian" has been created with default attributes and without skeleton files
-    And user "Brian" has created folder "/testshare"
-    And user "Brian" has created a share with settings
-      | path        | testshare |
-      | shareType   | user      |
-      | permissions | change    |
-      | shareWith   | Alice     |
-    And user "<mover>" has created folder "/testsubfolder"
-    And user "<mover>" has uploaded file with content "test data" to "/testsubfolder/testfile.txt"
-    When user "<mover>" moves folder "/testsubfolder" to "/testshare/testsubfolder" using the WebDAV API
-    Then the HTTP status code should be "201"
-    And the content of file "/testshare/testsubfolder/testfile.txt" for user "Alice" should be "test data"
-    And the content of file "/testshare/testsubfolder/testfile.txt" for user "Brian" should be "test data"
-    And as "<mover>" file "/testsubfolder" should not exist
-    Examples:
-      | dav_version | mover |
-      | old         | Alice |
-      | old         | Brian |
-      | new         | Alice |
-      | new         | Brian |
\ No newline at end of file
diff --git a/tests/acceptance/features/coreApiWebdavMove2/moveFile.feature b/tests/acceptance/features/coreApiWebdavMove2/moveFile.feature
index 9255feef2fd..72a518fbe21 100644
--- a/tests/acceptance/features/coreApiWebdavMove2/moveFile.feature
+++ b/tests/acceptance/features/coreApiWebdavMove2/moveFile.feature
@@ -105,92 +105,6 @@ Feature: move (rename) file
       | dav_version |
       | spaces      |
 
-  @files_sharing-app-required @skipOnOcis
-  Scenario Outline: Moving a file into a shared folder as the sharee and as the sharer
-    Given using <dav_version> DAV path
-    And user "Brian" has been created with default attributes and without skeleton files
-    And user "Brian" has created folder "/testshare"
-    And user "Brian" has created a share with settings
-      | path        | testshare |
-      | shareType   | user      |
-      | permissions | change    |
-      | shareWith   | Alice     |
-    And user "<mover>" has uploaded file with content "test data" to "/testfile.txt"
-    When user "<mover>" moves file "/testfile.txt" to "/testshare/testfile.txt" using the WebDAV API
-    Then the HTTP status code should be "201"
-    And the content of file "/testshare/testfile.txt" for user "Alice" should be "test data"
-    And the content of file "/testshare/testfile.txt" for user "Brian" should be "test data"
-    And as "<mover>" file "/testfile.txt" should not exist
-    Examples:
-      | dav_version | mover |
-      | old         | Alice |
-      | new         | Alice |
-      | old         | Brian |
-      | new         | Brian |
-
-  @files_sharing-app-required @skipOnOcis
-  Scenario Outline: Moving a file out of a shared folder as the sharee and as the sharer
-    Given using <dav_version> DAV path
-    And user "Brian" has been created with default attributes and without skeleton files
-    And user "Brian" has created folder "/testshare"
-    And user "Brian" has uploaded file with content "test data" to "/testshare/testfile.txt"
-    And user "Brian" has created a share with settings
-      | path        | testshare |
-      | shareType   | user      |
-      | permissions | change    |
-      | shareWith   | Alice     |
-    When user "<mover>" moves file "/testshare/testfile.txt" to "/testfile.txt" using the WebDAV API
-    Then the HTTP status code should be "201"
-    And the content of file "/testfile.txt" for user "<mover>" should be "test data"
-    And as "Alice" file "/testshare/testfile.txt" should not exist
-    And as "Brian" file "/testshare/testfile.txt" should not exist
-    Examples:
-      | dav_version | mover |
-      | old         | Alice |
-      | new         | Alice |
-      | old         | Brian |
-      | new         | Brian |
-
-  @files_sharing-app-required @skipOnOcis
-  Scenario Outline: Moving a file to a shared folder with no permissions
-    Given using <dav_version> DAV path
-    And user "Alice" has uploaded file "filesForUpload/textfile.txt" to "textfile0.txt"
-    And user "Brian" has been created with default attributes and without skeleton files
-    And user "Brian" has created folder "/testshare"
-    And user "Brian" has created a share with settings
-      | path        | testshare |
-      | shareType   | user      |
-      | permissions | read      |
-      | shareWith   | Alice     |
-    When user "Alice" moves file "/textfile0.txt" to "/testshare/textfile0.txt" using the WebDAV API
-    Then the HTTP status code should be "403"
-    And user "Alice" should not be able to download file "/testshare/textfile0.txt"
-    Examples:
-      | dav_version |
-      | old         |
-      | new         |
-
-  @files_sharing-app-required @skipOnOcis
-  Scenario Outline: Moving a file to overwrite a file in a shared folder with no permissions
-    Given using <dav_version> DAV path
-    And user "Alice" has uploaded file with content "ownCloud test text file 0" to "textfile0.txt"
-    And user "Brian" has been created with default attributes and without skeleton files
-    And user "Brian" has created folder "/testshare"
-    And user "Brian" has uploaded file with content "Welcome to ownCloud" to "fileToCopy.txt"
-    And user "Brian" has created a share with settings
-      | path        | testshare |
-      | shareType   | user      |
-      | permissions | read      |
-      | shareWith   | Alice     |
-    And user "Brian" has copied file "/fileToCopy.txt" to "/testshare/overwritethis.txt"
-    When user "Alice" moves file "/textfile0.txt" to "/testshare/overwritethis.txt" using the WebDAV API
-    Then the HTTP status code should be "403"
-    And the content of file "/testshare/overwritethis.txt" for user "Alice" should be "Welcome to ownCloud"
-    Examples:
-      | dav_version |
-      | old         |
-      | new         |
-
 
   Scenario Outline: move file into a not-existing folder
     Given using <dav_version> DAV path
@@ -244,31 +158,6 @@ Feature: move (rename) file
       | dav_version |
       | spaces      |
 
-  @files_sharing-app-required @skipOnOcis
-  Scenario Outline: Checking file id after a move between received shares
-    Given using <dav_version> DAV path
-    And user "Brian" has been created with default attributes and without skeleton files
-    And user "Alice" has created folder "/folderA"
-    And user "Alice" has created folder "/folderB"
-    And user "Alice" has shared folder "/folderA" with user "Brian"
-    And user "Alice" has shared folder "/folderB" with user "Brian"
-    And user "Brian" has created folder "/folderA/ONE"
-    And user "Brian" has stored id of folder "/folderA/ONE"
-    And user "Brian" has created folder "/folderA/ONE/TWO"
-    When user "Brian" moves folder "/folderA/ONE" to "/folderB/ONE" using the WebDAV API
-    Then the HTTP status code should be "201"
-    And as "Brian" folder "/folderA" should exist
-    And as "Brian" folder "/folderA/ONE" should not exist
-		# yes, a weird bug used to make this one fail
-    And as "Brian" folder "/folderA/ONE/TWO" should not exist
-    And as "Brian" folder "/folderB/ONE" should exist
-    And as "Brian" folder "/folderB/ONE/TWO" should exist
-    And user "Brian" folder "/folderB/ONE" should have the previously stored id
-    Examples:
-      | dav_version |
-      | old         |
-      | new         |
-
   @issue-ocis-reva-211
   Scenario Outline: Renaming a file to a path with extension .part should not be possible
     Given using <dav_version> DAV path
@@ -577,4 +466,4 @@ Feature: move (rename) file
     @skipOnOcV10 @personalSpace
     Examples:
       | dav_version |
-      | spaces      |
\ No newline at end of file
+      | spaces      |
diff --git a/tests/acceptance/features/coreApiWebdavPreviews/previewsAutoAdustedSizing.feature b/tests/acceptance/features/coreApiWebdavPreviews/previewsAutoAdustedSizing.feature
index 1246c1e91de..422a578d12a 100644
--- a/tests/acceptance/features/coreApiWebdavPreviews/previewsAutoAdustedSizing.feature
+++ b/tests/acceptance/features/coreApiWebdavPreviews/previewsAutoAdustedSizing.feature
@@ -10,7 +10,7 @@ Feature: sizing of previews of files downloaded through the webdav API
   Background:
     Given user "Alice" has been created with default attributes and without skeleton files
 
-  @skipOnOcV10
+
   Scenario Outline: download different sizes of previews of file
     Given user "Alice" has uploaded file "filesForUpload/lorem.txt" to "/parent.txt"
     When user "Alice" downloads the preview of "/parent.txt" with width <request_width> and height <request_height> using the WebDAV API
diff --git a/tests/acceptance/features/coreApiWebdavPreviews/previewsExactSizing.feature b/tests/acceptance/features/coreApiWebdavPreviews/previewsExactSizing.feature
deleted file mode 100644
index f113a170b79..00000000000
--- a/tests/acceptance/features/coreApiWebdavPreviews/previewsExactSizing.feature
+++ /dev/null
@@ -1,25 +0,0 @@
-@api @preview-extension-required
-Feature: sizing of previews of files downloaded through the webdav API
-  As a user
-  I want previews to be the exact requested size even when I ask for an unusual preview size combination
-  So that the previews always have the exact size that I want as a user/client.
-
-  This is optional behavior of an implementation. oC10 happens like this,
-  but OCIS does an auto-fix of the aspect ratio.
-
-  Background:
-    Given user "Alice" has been created with default attributes and without skeleton files
-
-  @skipOnOcis
-  Scenario Outline: download different sizes of previews of file
-    Given user "Alice" has uploaded file "filesForUpload/lorem.txt" to "/parent.txt"
-    When user "Alice" downloads the preview of "/parent.txt" with width <width> and height <height> using the WebDAV API
-    Then the HTTP status code should be "200"
-    And the downloaded image should be <width> pixels wide and <height> pixels high
-    Examples:
-      | width | height |
-      | 1     | 1      |
-      | 32    | 32     |
-      | 1024  | 1024   |
-      | 1     | 1024   |
-      | 1024  | 1      |
diff --git a/tests/acceptance/features/coreApiWebdavProperties2/getFileProperties.feature b/tests/acceptance/features/coreApiWebdavProperties2/getFileProperties.feature
index 9466c5d8390..1e991ff6354 100644
--- a/tests/acceptance/features/coreApiWebdavProperties2/getFileProperties.feature
+++ b/tests/acceptance/features/coreApiWebdavProperties2/getFileProperties.feature
@@ -306,19 +306,12 @@ Feature: get file properties
     And the value of the item "/d:error/s:message" in the response about user "Alice" should be "<message1>" or "<message2>"
     And the value of the item "/d:error/s:exception" in the response about user "Alice" should be "Sabre\DAV\Exception\NotFound"
 
-    @skipOnOcV10
     Examples:
       | url                                  | message1               | message2           |
       | /remote.php/dav/files/does-not-exist | Resource not found     | Resource not found |
       | /remote.php/dav/does-not-exist       | File not found in root |                    |
 
-    @skipOnOcis
-    Examples:
-      | url                                  | message1                                     | message2 |
-      | /remote.php/dav/files/does-not-exist | Principal with name does-not-exist not found |          |
-      | /remote.php/dav/does-not-exist       | File not found: does-not-exist in 'root'     |          |
-
-    @skipOnOcV10 @personalSpace
+    @personalSpace
     Examples:
       | url                                             | message1           | message2 |
       | /remote.php/dav/spaces/%spaceid%/does-not-exist | Resource not found |          |
diff --git a/tests/acceptance/lint-expected-failures.sh b/tests/acceptance/lint-expected-failures.sh
index a1f31ce4da0..c17be505956 100755
--- a/tests/acceptance/lint-expected-failures.sh
+++ b/tests/acceptance/lint-expected-failures.sh
@@ -1,15 +1,30 @@
 #!/usr/bin/env bash
 
 log_error() {
-	echo -e "\e[31m$1\e[0m"
+	if [ -n "${PLAIN_OUTPUT}" ]
+	then
+		echo -e "$1"
+	else
+		echo -e "\e[31m$1\e[0m"
+	fi
 }
 
 log_info() {
-	echo -e "\e[34m$1\e[0m"
+	if [ -n "${PLAIN_OUTPUT}" ]
+	then
+		echo -e "$1"
+	else
+		echo -e "\e[34m$1\e[0m"
+	fi
 }
 
 log_success() {
-	echo -e "\e[32m$1\e[0m"
+	if [ -n "${PLAIN_OUTPUT}" ]
+	then
+		echo -e "$1"
+	else
+		echo -e "\e[32m$1\e[0m"
+	fi
 }
 
 declare -A scenarioLines
diff --git a/tests/acceptance/run.sh b/tests/acceptance/run.sh
index 5d1af389686..45fa70b6d9a 100755
--- a/tests/acceptance/run.sh
+++ b/tests/acceptance/run.sh
@@ -22,6 +22,21 @@ then
 	STEP_THROUGH_OPTION="--step-through"
 fi
 
+if [ -n "${PLAIN_OUTPUT}" ]
+then
+	# explicitly tell Behat to not do colored output
+	COLORS_OPTION="--no-colors"
+	# Use the Bash "null" command to do nothing, rather than use tput to set a color
+	RED_COLOR = ":"
+	GREEN_COLOR = ":"
+	YELLOW_COLOR = ":"
+else
+	COLORS_OPTION="--colors"
+	RED_COLOR = "tput setaf 1"
+	GREEN_COLOR = "tput setaf 2"
+	YELLOW_COLOR = "tput setaf 3"
+fi
+
 # The following environment variables can be specified:
 #
 # ACCEPTANCE_TEST_TYPE - see "--type" description
@@ -180,7 +195,7 @@ function run_behat_tests() {
 	fi
 
 	echo "Using behat config '${BEHAT_YML}'"
-	${BEHAT} --colors --strict ${STEP_THROUGH_OPTION} -c ${BEHAT_YML} -f pretty ${BEHAT_SUITE_OPTION} --tags ${BEHAT_FILTER_TAGS} ${BEHAT_FEATURE} -v 2>&1 | tee -a ${TEST_LOG_FILE}
+	${BEHAT} ${COLORS_OPTION} --strict ${STEP_THROUGH_OPTION} -c ${BEHAT_YML} -f pretty ${BEHAT_SUITE_OPTION} --tags ${BEHAT_FILTER_TAGS} ${BEHAT_FEATURE} -v 2>&1 | tee -a ${TEST_LOG_FILE}
 
 	BEHAT_EXIT_STATUS=${PIPESTATUS[0]}
 
@@ -207,7 +222,7 @@ function run_behat_tests() {
 		# So exit the tests and do not lint expected failures when undefined steps exist.
 		if [[ ${SCENARIO_RESULTS} == *"undefined"* ]]
 		then
-			echo -e "\033[31m Undefined steps: There were some undefined steps found."
+			${RED_COLOR}; echo -e "Undefined steps: There were some undefined steps found."
 			exit 1
 		fi
 		# If there were no scenarios in the requested suite or feature that match
@@ -348,7 +363,7 @@ function run_behat_tests() {
 		# Big red error output is displayed if there are no matching scenarios - send it to null
 		DRY_RUN_FILE=$(mktemp)
 		SKIP_TAGS="${TEST_TYPE_TAG}&&@skip"
-		${BEHAT} --dry-run --colors -c ${BEHAT_YML} -f pretty ${BEHAT_SUITE_OPTION} --tags "${SKIP_TAGS}" ${BEHAT_FEATURE} 1>${DRY_RUN_FILE} 2>/dev/null
+		${BEHAT} --dry-run {$COLORS_OPTION} -c ${BEHAT_YML} -f pretty ${BEHAT_SUITE_OPTION} --tags "${SKIP_TAGS}" ${BEHAT_FEATURE} 1>${DRY_RUN_FILE} 2>/dev/null
 		if grep -q -m 1 'No scenarios' "${DRY_RUN_FILE}"
 		then
 			# If there are no skip scenarios, then no need to report that
@@ -636,24 +651,24 @@ fi
 
 if [ "${UNEXPECTED_FAILURE}" = true ]
 then
-	tput setaf 3; echo "runsh: Total unexpected failed scenarios throughout the test run:"
-	tput setaf 1; printf "%s\n" "${UNEXPECTED_FAILED_SCENARIOS[@]}"
+	${YELLOW_COLOR}; echo "runsh: Total unexpected failed scenarios throughout the test run:"
+	${RED_COLOR}; printf "%s\n" "${UNEXPECTED_FAILED_SCENARIOS[@]}"
 else
-	tput setaf 2; echo "runsh: There were no unexpected failures."
+	${GREEN_COLOR}; echo "runsh: There were no unexpected failures."
 fi
 
 if [ "${UNEXPECTED_SUCCESS}" = true ]
 then
-	tput setaf 3; echo "runsh: Total unexpected passed scenarios throughout the test run:"
-	tput setaf 1; printf "%s\n" "${ACTUAL_UNEXPECTED_PASS[@]}"
+	${YELLOW_COLOR}; echo "runsh: Total unexpected passed scenarios throughout the test run:"
+	${RED_COLOR}; printf "%s\n" "${ACTUAL_UNEXPECTED_PASS[@]}"
 else
-	tput setaf 2; echo "runsh: There were no unexpected success."
+	${GREEN_COLOR}; echo "runsh: There were no unexpected success."
 fi
 
 if [ "${UNEXPECTED_BEHAT_EXIT_STATUS}" = true ]
 then
-	tput setaf 3; echo "runsh: The following Behat test runs exited with non-zero status:"
-	tput setaf 1; printf "%s\n" "${UNEXPECTED_BEHAT_EXIT_STATUSES[@]}"
+	${YELLOW_COLOR}; echo "runsh: The following Behat test runs exited with non-zero status:"
+	${RED_COLOR}; printf "%s\n" "${UNEXPECTED_BEHAT_EXIT_STATUSES[@]}"
 fi
 
 # sync the file-system so all output will be flushed to storage.