mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-10-06 10:52:08 -04:00
feat: add new editor roles (#3637)
* feat: add new editor roles * add tests for additional roles * fix: disable new roles in config * adjust tests * fix listGrantsShareRole test --------- Co-authored-by: v.scharf <v.scharf@opencloud.eu>
This commit is contained in:
1 parent
4dec19089d
commit
b955c7c4f0
18 files changed
+2745
-32
No files matched your search
@@ -3,3 +3,5 @@ module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT
|
||||
go 1.23.4
|
||||
|
||||
require github.com/gosexy/gettext v0.0.0-20160830220431-74466a0a0c4a // go-xgettext
|
||||
|
||||
require github.com/jessevdk/go-flags v1.6.1 // indirect
|
||||
@@ -232,6 +232,12 @@ config = {
|
||||
],
|
||||
"skip": False,
|
||||
},
|
||||
"sharingNgAdditionalShareRole": {
|
||||
"suites": [
|
||||
"apiSharingNgAdditionalShareRole",
|
||||
],
|
||||
"skip": False,
|
||||
},
|
||||
"notification": {
|
||||
"suites": [
|
||||
"apiNotification",
|
||||
|
||||
@@ -17,9 +17,13 @@ var (
|
||||
unifiedrole.UnifiedRoleSecureViewerID,
|
||||
unifiedrole.UnifiedRoleSpaceViewerWithVersionsID,
|
||||
unifiedrole.UnifiedRoleSpaceEditorWithoutVersionsID,
|
||||
unifiedrole.UnifiedRoleSpaceEditorWithoutTrashbinID,
|
||||
unifiedrole.UnifiedRoleSpaceEditorWithoutVersionsWithoutTrashbinID,
|
||||
unifiedrole.UnifiedRoleViewerListGrantsID,
|
||||
unifiedrole.UnifiedRoleEditorListGrantsID,
|
||||
unifiedrole.UnifiedRoleEditorListGrantsWithVersionsID,
|
||||
unifiedrole.UnifiedRoleFileEditorListGrantsID,
|
||||
unifiedrole.UnifiedRoleFileEditorListGrantsWithVersionsID,
|
||||
unifiedrole.UnifiedRoleViewerWithVersionsID,
|
||||
unifiedrole.UnifiedRoleEditorWithVersionsID,
|
||||
unifiedrole.UnifiedRoleFileEditorWithVersionsID,
|
||||
|
||||
@@ -162,3 +162,28 @@ msgid "View, download, upload, edit, add, delete including the history."
|
||||
msgstr ""
|
||||
"Ansehen, herunterladen, hochladen, bearbeiten, hinzufügen, löschen - "
|
||||
"inklusive des Verlaufs."
|
||||
|
||||
#. UnifiedRole SpaceEditorWithoutTrashbin, Role DisplayName (resolves
|
||||
#. directly)
|
||||
#: pkg/unifiedrole/roles.go:183
|
||||
msgid "Can edit with versions"
|
||||
msgstr "Kann bearbeiten mit Historie"
|
||||
|
||||
#. UnifiedRole EditorListGrantsWithVersions, Role Description (resolves
|
||||
#. directly)
|
||||
#: pkg/unifiedrole/roles.go:162
|
||||
msgid ""
|
||||
"View, download, upload, edit, delete, show all versions and all invited "
|
||||
"people."
|
||||
msgstr ""
|
||||
"Ansehen, herunterladen, hochladen, bearbeiten, löschen und anzeigen aller "
|
||||
"Versionen und eingeladenen Personen."
|
||||
|
||||
#. UnifiedRole FileEditorListGrantsWithVersions, Role Description (resolves
|
||||
#. directly)
|
||||
#: pkg/unifiedrole/roles.go:201
|
||||
msgid ""
|
||||
"View, download, upload, edit, show all versions and all invited people."
|
||||
msgstr ""
|
||||
"Ansehen, herunterladen, hochladen, bearbeiten und anzeigen aller Versionen "
|
||||
"und eingeladenen Personen."
|
||||
@@ -219,16 +219,24 @@ func cs3RoleToDisplayName(role *conversions.Role) string {
|
||||
return _editorWithVersionsUnifiedRoleDisplayName
|
||||
case conversions.RoleEditorListGrants:
|
||||
return _editorListGrantsUnifiedRoleDisplayName
|
||||
case conversions.RoleEditorListGrantsWithVersions:
|
||||
return _editorListGrantsWithVersionsUnifiedRoleDisplayName
|
||||
case conversions.RoleSpaceEditor:
|
||||
return _spaceEditorUnifiedRoleDisplayName
|
||||
case conversions.RoleSpaceEditorWithoutVersions:
|
||||
return _spaceEditorWithoutVersionsUnifiedRoleDisplayName
|
||||
case conversions.RoleSpaceEditorWithoutTrashbin:
|
||||
return _spaceEditorWithoutTrashbinUnifiedRoleDisplayName
|
||||
case conversions.RoleSpaceEditorWithoutVersionsWithoutTrashbin:
|
||||
return _spaceEditorWithoutVersionsWithoutTrashbinUnifiedRoleDisplayName
|
||||
case conversions.RoleFileEditor:
|
||||
return _fileEditorUnifiedRoleDisplayName
|
||||
case conversions.RoleFileEditorWithVersions:
|
||||
return _fileEditorWithVersionsUnifiedRoleDisplayName
|
||||
case conversions.RoleFileEditorListGrants:
|
||||
return _fileEditorListGrantsUnifiedRoleDisplayName
|
||||
case conversions.RoleFileEditorListGrantsWithVersions:
|
||||
return _fileEditorListGrantsWithVersionsUnifiedRoleDisplayName
|
||||
case conversions.RoleEditorLite:
|
||||
return _editorLiteUnifiedRoleDisplayName
|
||||
case conversions.RoleManager:
|
||||
|
||||
@@ -1,23 +1,27 @@
|
||||
package unifiedrole
|
||||
|
||||
var (
|
||||
RoleViewer = roleViewer
|
||||
RoleViewerWithVersions = roleViewerWithVersions
|
||||
RoleViewerListGrants = roleViewerListGrants
|
||||
RoleSpaceViewer = roleSpaceViewer
|
||||
RoleSpaceViewerWithVersions = roleSpaceViewerWithVersions
|
||||
RoleEditor = roleEditor
|
||||
RoleEditorWithVersions = roleEditorWithVersions
|
||||
RoleEditorListGrants = roleEditorListGrants
|
||||
RoleSpaceEditor = roleSpaceEditor
|
||||
RoleSpaceEditorWithVersions = roleSpaceEditorWithVersions
|
||||
RoleFileEditor = roleFileEditor
|
||||
RoleFileEditorWithVersions = roleFileEditorWithVersions
|
||||
RoleFileEditorListGrants = roleFileEditorListGrants
|
||||
RoleEditorLite = roleEditorLite
|
||||
RoleManager = roleManager
|
||||
RoleSecureViewer = roleSecureViewer
|
||||
RoleDenied = roleDenied
|
||||
RoleViewer = roleViewer
|
||||
RoleViewerWithVersions = roleViewerWithVersions
|
||||
RoleViewerListGrants = roleViewerListGrants
|
||||
RoleSpaceViewer = roleSpaceViewer
|
||||
RoleSpaceViewerWithVersions = roleSpaceViewerWithVersions
|
||||
RoleEditor = roleEditor
|
||||
RoleEditorWithVersions = roleEditorWithVersions
|
||||
RoleEditorListGrants = roleEditorListGrants
|
||||
RoleEditorListGrantsWithVersions = roleEditorListGrantsWithVersions
|
||||
RoleSpaceEditor = roleSpaceEditor
|
||||
RoleSpaceEditorWithVersions = roleSpaceEditorWithVersions
|
||||
RoleSpaceEditorWithoutTrashbin = roleSpaceEditorWithoutTrashbin
|
||||
RoleSpaceEditorWithoutVersionsWithoutTrashbin = roleSpaceEditorWithoutVersionsWithoutTrashbin
|
||||
RoleFileEditor = roleFileEditor
|
||||
RoleFileEditorWithVersions = roleFileEditorWithVersions
|
||||
RoleFileEditorListGrants = roleFileEditorListGrants
|
||||
RoleFileEditorListGrantsWithVersions = roleFileEditorListGrantsWithVersions
|
||||
RoleEditorLite = roleEditorLite
|
||||
RoleManager = roleManager
|
||||
RoleSecureViewer = roleSecureViewer
|
||||
RoleDenied = roleDenied
|
||||
|
||||
BuildInRoles = buildInRoles
|
||||
|
||||
|
||||
@@ -32,16 +32,25 @@ const (
|
||||
UnifiedRoleEditorWithVersionsID = "b8c6e1c9-5d2a-4f0e-9c3b-1a2b3c4d5e6f"
|
||||
// UnifiedRoleEditorListGrantsID Unified role editor id.
|
||||
UnifiedRoleEditorListGrantsID = "e8ea8b21-abd4-45d2-b893-8d1546378e9e"
|
||||
// UnifiedRoleEditorListGrantsWithVersionsID Unified role editor with list grants and versions id.
|
||||
UnifiedRoleEditorListGrantsWithVersionsID = "0911d62b-1e3f-4778-8b1b-903b7e4e8476"
|
||||
// UnifiedRoleSpaceEditorID Unified role space editor id.
|
||||
UnifiedRoleSpaceEditorID = "58c63c02-1d89-4572-916a-870abc5a1b7d"
|
||||
// UnifiedRoleSpaceEditorWithoutVersionsID Unified role space editor without list/restore versions id.
|
||||
UnifiedRoleSpaceEditorWithoutVersionsID = "3284f2d5-0070-4ad8-ac40-c247f7c1fb27"
|
||||
// UnifiedRoleSpaceEditorWithoutTrashbinID Unified role space editor without list/restore resources in trashbin id.
|
||||
UnifiedRoleSpaceEditorWithoutTrashbinID = "8f4701d9-c68f-4109-a482-88e22ee32805"
|
||||
// UnifiedRoleSpaceEditorWithoutVersionsWithoutTrashbinID Unified role space editor without list/restore
|
||||
// versions and without list/restore resources in trashbin id.
|
||||
UnifiedRoleSpaceEditorWithoutVersionsWithoutTrashbinID = "a5f73816-4d4b-452d-8973-3b61c3d0bed4"
|
||||
// UnifiedRoleFileEditorID Unified role file editor id.
|
||||
UnifiedRoleFileEditorID = "2d00ce52-1fc2-4dbc-8b95-a73b73395f5a"
|
||||
// UnifiedRoleFileEditorWithVersionsID Unified role file editor id.
|
||||
UnifiedRoleFileEditorWithVersionsID = "3d00ce52-1fc2-4dbc-8b95-a73b73395f5a"
|
||||
// UnifiedRoleFileEditorListGrantsID Unified role file editor id.
|
||||
UnifiedRoleFileEditorListGrantsID = "c1235aea-d106-42db-8458-7d5610fb0a67"
|
||||
// UnifiedRoleFileEditorListGrantsWithVersionsID Unified role file editor with list grants and versions id.
|
||||
UnifiedRoleFileEditorListGrantsWithVersionsID = "b173329d-cf2e-42f0-a595-ee410645d840"
|
||||
// UnifiedRoleEditorLiteID Unified role editor-lite id.
|
||||
UnifiedRoleEditorLiteID = "1c996275-f1c9-4e71-abdf-a42f6495e960"
|
||||
// UnifiedRoleManagerID Unified role manager id.
|
||||
@@ -149,6 +158,12 @@ var (
|
||||
// UnifiedRole EditorListGrants, Role DisplayName (resolves directly)
|
||||
_editorListGrantsUnifiedRoleDisplayName = l10n.Template("Can edit")
|
||||
|
||||
// UnifiedRole EditorListGrantsWithVersions, Role Description (resolves directly)
|
||||
_editorListGrantsWithVersionsUnifiedRoleDescription = l10n.Template("View, download, upload, edit, delete, show all versions and all invited people.")
|
||||
|
||||
// UnifiedRole EditorListGrantsWithVersions, Role DisplayName (resolves directly)
|
||||
_editorListGrantsWithVersionsUnifiedRoleDisplayName = l10n.Template("Can edit")
|
||||
|
||||
// UnifiedRole SpaseEditor, Role Description (resolves directly)
|
||||
_spaceEditorUnifiedRoleDescription = l10n.Template("View, download, upload, edit, add, delete including the history.")
|
||||
|
||||
@@ -161,6 +176,18 @@ var (
|
||||
// UnifiedRole SpaseEditorWithoutVersions, Role DisplayName (resolves directly)
|
||||
_spaceEditorWithoutVersionsUnifiedRoleDisplayName = l10n.Template("Can edit without versions")
|
||||
|
||||
// UnifiedRole SpaceEditorWithoutTrashbin, Role Description (resolves directly)
|
||||
_spaceEditorWithoutTrashbinUnifiedRoleDescription = l10n.Template("View, download, upload, edit, add, delete including the history.")
|
||||
|
||||
// UnifiedRole SpaceEditorWithoutTrashbin, Role DisplayName (resolves directly)
|
||||
_spaceEditorWithoutTrashbinUnifiedRoleDisplayName = l10n.Template("Can edit with versions")
|
||||
|
||||
// UnifiedRole SpaceEditorWithoutVersionsWithoutTrashbin, Role Description (resolves directly)
|
||||
_spaceEditorWithoutVersionsWithoutTrashbinUnifiedRoleDescription = l10n.Template("View, download, upload, edit, add and delete.")
|
||||
|
||||
// UnifiedRole SpaceEditorWithoutVersionsWithoutTrashbin, Role DisplayName (resolves directly)
|
||||
_spaceEditorWithoutVersionsWithoutTrashbinUnifiedRoleDisplayName = l10n.Template("Can edit")
|
||||
|
||||
// UnifiedRole FileEditor, Role Description (resolves directly)
|
||||
_fileEditorUnifiedRoleDescription = l10n.Template("View, download and edit.")
|
||||
|
||||
@@ -170,6 +197,12 @@ var (
|
||||
// UnifiedRole FileEditorListGrants, Role Description (resolves directly)
|
||||
_fileEditorListGrantsUnifiedRoleDescription = l10n.Template("View, download, edit and show all invited people.")
|
||||
|
||||
// UnifiedRole FileEditorListGrantsWithVersions, Role Description (resolves directly)
|
||||
_fileEditorListGrantsWithVersionsUnifiedRoleDescription = l10n.Template("View, download, upload, edit, show all versions and all invited people.")
|
||||
|
||||
// UnifiedRole FileEditorListGrantsWithVersions, Role DisplayName (resolves directly)
|
||||
_fileEditorListGrantsWithVersionsUnifiedRoleDisplayName = l10n.Template("Can edit")
|
||||
|
||||
// UnifiedRole FileEditorWithVersions, Role DisplayName (resolves directly)
|
||||
_fileEditorWithVersionsUnifiedRoleDisplayName = l10n.Template("Can edit")
|
||||
|
||||
@@ -227,12 +260,16 @@ var (
|
||||
roleSpaceViewerWithVersions,
|
||||
roleEditor,
|
||||
roleEditorListGrants,
|
||||
roleEditorListGrantsWithVersions,
|
||||
roleEditorWithVersions,
|
||||
roleSpaceEditorWithVersions,
|
||||
roleSpaceEditor,
|
||||
roleSpaceEditorWithoutTrashbin,
|
||||
roleSpaceEditorWithoutVersionsWithoutTrashbin,
|
||||
roleFileEditor,
|
||||
roleFileEditorWithVersions,
|
||||
roleFileEditorListGrants,
|
||||
roleFileEditorListGrantsWithVersions,
|
||||
roleEditorLite,
|
||||
roleManager,
|
||||
roleSecureViewer,
|
||||
@@ -432,6 +469,27 @@ var (
|
||||
}
|
||||
}()
|
||||
|
||||
// roleEditorListGrantsWithVersions creates an editor role that can also list versions.
|
||||
roleEditorListGrantsWithVersions = func() *libregraph.UnifiedRoleDefinition {
|
||||
r := conversions.NewEditorListGrantsWithVersionsRole()
|
||||
return &libregraph.UnifiedRoleDefinition{
|
||||
Id: proto.String(UnifiedRoleEditorListGrantsWithVersionsID),
|
||||
Description: proto.String(_editorListGrantsWithVersionsUnifiedRoleDescription),
|
||||
DisplayName: proto.String(cs3RoleToDisplayName(r)),
|
||||
RolePermissions: []libregraph.UnifiedRolePermission{
|
||||
{
|
||||
AllowedResourceActions: CS3ResourcePermissionsToLibregraphActions(r.CS3ResourcePermissions()),
|
||||
Condition: proto.String(UnifiedRoleConditionFolder),
|
||||
},
|
||||
{
|
||||
AllowedResourceActions: CS3ResourcePermissionsToLibregraphActions(r.CS3ResourcePermissions()),
|
||||
Condition: proto.String(UnifiedRoleConditionFolderFederatedUser),
|
||||
},
|
||||
},
|
||||
LibreGraphWeight: proto.Int32(72),
|
||||
}
|
||||
}()
|
||||
|
||||
roleEditorWithVersions = func() *libregraph.UnifiedRoleDefinition {
|
||||
r := conversions.NewEditorWithVersionsRole()
|
||||
return &libregraph.UnifiedRoleDefinition{
|
||||
@@ -448,6 +506,42 @@ var (
|
||||
}
|
||||
}()
|
||||
|
||||
// roleSpaceEditorWithoutVersionsWithoutTrashbin creates a space editor role without
|
||||
// list/restore versions and without list/restore resources in the trashbin.
|
||||
roleSpaceEditorWithoutVersionsWithoutTrashbin = func() *libregraph.UnifiedRoleDefinition {
|
||||
r := conversions.NewSpaceEditorWithoutVersionsWithoutTrashbinRole()
|
||||
return &libregraph.UnifiedRoleDefinition{
|
||||
Id: proto.String(UnifiedRoleSpaceEditorWithoutVersionsWithoutTrashbinID),
|
||||
Description: proto.String(_spaceEditorWithoutVersionsWithoutTrashbinUnifiedRoleDescription),
|
||||
DisplayName: proto.String(cs3RoleToDisplayName(r)),
|
||||
RolePermissions: []libregraph.UnifiedRolePermission{
|
||||
{
|
||||
AllowedResourceActions: CS3ResourcePermissionsToLibregraphActions(r.CS3ResourcePermissions()),
|
||||
Condition: proto.String(UnifiedRoleConditionDrive),
|
||||
},
|
||||
},
|
||||
LibreGraphWeight: proto.Int32(78),
|
||||
}
|
||||
}()
|
||||
|
||||
// roleSpaceEditorWithoutTrashbin creates a space editor role without list/restore
|
||||
// resources in the trashbin.
|
||||
roleSpaceEditorWithoutTrashbin = func() *libregraph.UnifiedRoleDefinition {
|
||||
r := conversions.NewSpaceEditorWithoutTrashbinRole()
|
||||
return &libregraph.UnifiedRoleDefinition{
|
||||
Id: proto.String(UnifiedRoleSpaceEditorWithoutTrashbinID),
|
||||
Description: proto.String(_spaceEditorWithoutTrashbinUnifiedRoleDescription),
|
||||
DisplayName: proto.String(cs3RoleToDisplayName(r)),
|
||||
RolePermissions: []libregraph.UnifiedRolePermission{
|
||||
{
|
||||
AllowedResourceActions: CS3ResourcePermissionsToLibregraphActions(r.CS3ResourcePermissions()),
|
||||
Condition: proto.String(UnifiedRoleConditionDrive),
|
||||
},
|
||||
},
|
||||
LibreGraphWeight: proto.Int32(88),
|
||||
}
|
||||
}()
|
||||
|
||||
// roleSpaceEditor creates an editor without versions role
|
||||
roleSpaceEditor = func() *libregraph.UnifiedRoleDefinition {
|
||||
r := conversions.NewSpaceEditorWithoutVersionsRole()
|
||||
@@ -541,6 +635,27 @@ var (
|
||||
}
|
||||
}()
|
||||
|
||||
// roleFileEditorListGrantsWithVersions creates a file-editor role that can also list versions.
|
||||
roleFileEditorListGrantsWithVersions = func() *libregraph.UnifiedRoleDefinition {
|
||||
r := conversions.NewFileEditorListGrantsWithVersionsRole()
|
||||
return &libregraph.UnifiedRoleDefinition{
|
||||
Id: proto.String(UnifiedRoleFileEditorListGrantsWithVersionsID),
|
||||
Description: proto.String(_fileEditorListGrantsWithVersionsUnifiedRoleDescription),
|
||||
DisplayName: proto.String(cs3RoleToDisplayName(r)),
|
||||
RolePermissions: []libregraph.UnifiedRolePermission{
|
||||
{
|
||||
AllowedResourceActions: CS3ResourcePermissionsToLibregraphActions(r.CS3ResourcePermissions()),
|
||||
Condition: proto.String(UnifiedRoleConditionFile),
|
||||
},
|
||||
{
|
||||
AllowedResourceActions: CS3ResourcePermissionsToLibregraphActions(r.CS3ResourcePermissions()),
|
||||
Condition: proto.String(UnifiedRoleConditionFileFederatedUser),
|
||||
},
|
||||
},
|
||||
LibreGraphWeight: proto.Int32(111),
|
||||
}
|
||||
}()
|
||||
|
||||
// roleManager creates a manager role
|
||||
roleManager = func() *libregraph.UnifiedRoleDefinition {
|
||||
r := conversions.NewManagerRole()
|
||||
|
||||
@@ -185,6 +185,7 @@ func TestGetRolesByPermissions(t *testing.T) {
|
||||
unifiedrole.RoleFileEditor,
|
||||
unifiedrole.RoleFileEditorWithVersions,
|
||||
unifiedrole.RoleFileEditorListGrants,
|
||||
unifiedrole.RoleFileEditorListGrantsWithVersions,
|
||||
},
|
||||
},
|
||||
"BuildInRoles | folder": {
|
||||
@@ -199,6 +200,7 @@ func TestGetRolesByPermissions(t *testing.T) {
|
||||
unifiedrole.RoleEditor,
|
||||
unifiedrole.RoleEditorListGrants,
|
||||
unifiedrole.RoleEditorWithVersions,
|
||||
unifiedrole.RoleEditorListGrantsWithVersions,
|
||||
unifiedrole.RoleDenied,
|
||||
},
|
||||
},
|
||||
@@ -208,7 +210,9 @@ func TestGetRolesByPermissions(t *testing.T) {
|
||||
unifiedRoleDefinition: []*libregraph.UnifiedRoleDefinition{
|
||||
unifiedrole.RoleSpaceViewer,
|
||||
unifiedrole.RoleSpaceViewerWithVersions,
|
||||
unifiedrole.RoleSpaceEditorWithoutVersionsWithoutTrashbin,
|
||||
unifiedrole.RoleSpaceEditor,
|
||||
unifiedrole.RoleSpaceEditorWithoutTrashbin,
|
||||
unifiedrole.RoleSpaceEditorWithVersions,
|
||||
unifiedrole.RoleManager,
|
||||
},
|
||||
|
||||
@@ -49,6 +49,10 @@ class GraphHelper {
|
||||
'File Editor With Versions' => '3d00ce52-1fc2-4dbc-8b95-a73b73395f5a',
|
||||
'File Editor List Grants' => 'c1235aea-d106-42db-8458-7d5610fb0a67',
|
||||
'Denied' => '63e64e19-8d43-42ec-a738-2b6af2610efa',
|
||||
'Editor List Grants With Versions' => '0911d62b-1e3f-4778-8b1b-903b7e4e8476',
|
||||
'Space Editor Without Trashbin' => '8f4701d9-c68f-4109-a482-88e22ee32805',
|
||||
'Space Editor Without Versions Without Trashbin' => 'a5f73816-4d4b-452d-8973-3b61c3d0bed4',
|
||||
'File Editor List Grants With Versions' => 'b173329d-cf2e-42f0-a595-ee410645d840',
|
||||
];
|
||||
|
||||
public const SHARES_SPACE_ID = 'a0ca6a90-a365-4782-871e-d44447bbc668$a0ca6a90-a365-4782-871e-d44447bbc668';
|
||||
|
||||
@@ -2921,15 +2921,9 @@ class GraphContext implements Context {
|
||||
string $resource,
|
||||
string $spaceName
|
||||
): void {
|
||||
$resourceId = $this->featureContext->spacesContext->getResourceId($user, $spaceName, $resource);
|
||||
$response = GraphHelper::getActivities(
|
||||
$this->featureContext->getBaseUrl(),
|
||||
$this->featureContext->getStepLineRef(),
|
||||
$user,
|
||||
$this->featureContext->getPasswordForUser($user),
|
||||
$resourceId
|
||||
$this->featureContext->setResponse(
|
||||
$this->getActivities($user, $resource, $spaceName)
|
||||
);
|
||||
$this->featureContext->setResponse($response);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3490,4 +3484,107 @@ class GraphContext implements Context {
|
||||
$url = "/graph/$apiVersion/drives/$driveId/root:/$encoded";
|
||||
$this->sendGraphRequestAndCaptureResponse($user, "GET", $url);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $user
|
||||
* @param string $resource
|
||||
* @param string $spaceName
|
||||
*
|
||||
* @return ResponseInterface
|
||||
* @throws GuzzleException
|
||||
*/
|
||||
public function getActivities(
|
||||
string $user,
|
||||
string $resource,
|
||||
string $spaceName
|
||||
): ResponseInterface {
|
||||
if ($spaceName === "Shares") {
|
||||
$resourceId = $this->spacesContext->getSharesRemoteItemId($user, $resource);
|
||||
} else {
|
||||
$resourceId = $this->spacesContext->getResourceId($user, $spaceName, $resource);
|
||||
}
|
||||
return GraphHelper::getActivities(
|
||||
$this->featureContext->getBaseUrl(),
|
||||
$this->featureContext->getStepLineRef(),
|
||||
$user,
|
||||
$this->featureContext->getPasswordForUser($user),
|
||||
$resourceId
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $user
|
||||
* @param string $resource
|
||||
* @param string $spaceName
|
||||
* @param TableNode $table
|
||||
*
|
||||
* @return void
|
||||
* @throws GuzzleException
|
||||
*/
|
||||
#[Then('/^for user "([^"]*)" (?:folder|file) "([^"]*)" of the space "([^"]*)" should have the following activities:$/')]
|
||||
public function forUserFolderOrFileOfTheSpaceShouldHaveTheseActivities(
|
||||
string $user,
|
||||
string $resource,
|
||||
string $spaceName,
|
||||
TableNode $table
|
||||
): void {
|
||||
$expectedMessages = \array_map(fn ($row) => $row[0], $table->getRows());
|
||||
|
||||
// Activities are recorded asynchronously from events, so poll until every
|
||||
// expected activity shows up (or the wait times out).
|
||||
$actualMessages = [];
|
||||
WaitHelper::waitUntil(
|
||||
function () use ($user, $resource, $spaceName, &$actualMessages) {
|
||||
$activities = $this->featureContext->getJsonDecodedResponse(
|
||||
$this->getActivities($user, $resource, $spaceName)
|
||||
);
|
||||
$actualMessages = \array_map(
|
||||
fn ($activity) => $activity['template']['message'],
|
||||
$activities['value'] ?? []
|
||||
);
|
||||
},
|
||||
function () use ($expectedMessages, &$actualMessages) {
|
||||
foreach ($expectedMessages as $message) {
|
||||
if (!\in_array($message, $actualMessages, true)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
);
|
||||
|
||||
$errors = [];
|
||||
foreach ($expectedMessages as $message) {
|
||||
if (!\in_array($message, $actualMessages, true)) {
|
||||
$errors[] = "Expected activity '$message' was not found in the response. ";
|
||||
}
|
||||
}
|
||||
if (!empty($errors)) {
|
||||
Assert::fail(implode("\n", $errors));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $user
|
||||
* @param string $resource
|
||||
* @param string $spaceName
|
||||
*
|
||||
* @return void
|
||||
* @throws GuzzleException
|
||||
*/
|
||||
#[Then('/^for user "([^"]*)" (?:folder|file) "([^"]*)" of the space "([^"]*)" should not have any activity$/')]
|
||||
public function forUserFileOfTheSpaceShouldNotHaveAnyActivity(
|
||||
string $user,
|
||||
string $resource,
|
||||
string $spaceName
|
||||
): void {
|
||||
$response = $this->getActivities($user, $resource, $spaceName);
|
||||
$responseBody = $response->getBody()->getContents();
|
||||
Assert::assertEmpty(
|
||||
$responseBody,
|
||||
__METHOD__
|
||||
. "\nExpected no activity of resource '$resource' for user '$user', but some activities were found\n"
|
||||
. print_r(json_decode($responseBody, true), true)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -123,6 +123,36 @@ class OcConfigContext implements Context {
|
||||
$this->setEnabledPermissionsRoles($defaultRoles);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param TableNode $table
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
#[Given('the administrator has enabled the following share permissions roles:')]
|
||||
public function theAdministratorHasEnabledTheFollowingSharePermissionsRoles(TableNode $table): void {
|
||||
$defaultRoles = array_values(GraphHelper::DEFAULT_PERMISSIONS_ROLES);
|
||||
$roles = [];
|
||||
foreach ($table->getHash() as $row) {
|
||||
$roles[] = $row['permissions-role'];
|
||||
$roleId = GraphHelper::getPermissionsRoleIdByName($row['permissions-role']);
|
||||
if (!\in_array($roleId, $defaultRoles)) {
|
||||
$defaultRoles[] = $roleId;
|
||||
}
|
||||
}
|
||||
$envs = [
|
||||
"GRAPH_AVAILABLE_ROLES" => implode(',', $defaultRoles),
|
||||
];
|
||||
$response = OcConfigHelper::reConfigureOc($envs);
|
||||
Assert::assertEquals(
|
||||
200,
|
||||
$response->getStatusCode(),
|
||||
"Failed to enable roles: " . implode(', ', $roles)
|
||||
. ". Response: " . $response->getBody()->getContents()
|
||||
);
|
||||
$this->setEnabledPermissionsRoles($defaultRoles);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $role
|
||||
|
||||
@@ -26,6 +26,7 @@ use GuzzleHttp\Exception\GuzzleException;
|
||||
use PHPUnit\Framework\Assert;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use TestHelpers\GraphHelper;
|
||||
use TestHelpers\WaitHelper;
|
||||
use TestHelpers\WebDavHelper;
|
||||
use TestHelpers\HttpRequestHelper;
|
||||
use TestHelpers\BehatHelper;
|
||||
@@ -161,12 +162,18 @@ class SharingNgContext implements Context {
|
||||
?string $resource = '',
|
||||
?string $query = null
|
||||
): ResponseInterface {
|
||||
$spaceId = ($this->spacesContext->getSpaceByName($user, $space))["id"];
|
||||
|
||||
if ($fileOrFolder === 'folder') {
|
||||
$itemId = $this->spacesContext->getResourceId($user, $space, $resource);
|
||||
if ($space === "Shares" && $resource !== '') {
|
||||
// a shared resource lives in the owner's space; its permissions are
|
||||
// listed via the share's remote item id and its parent drive id
|
||||
$spaceId = $this->spacesContext->getSharesRemoteItemParentDriveId($user, $resource);
|
||||
$itemId = $this->spacesContext->getSharesRemoteItemId($user, $resource);
|
||||
} else {
|
||||
$itemId = $this->spacesContext->getFileId($user, $space, $resource);
|
||||
$spaceId = ($this->spacesContext->getSpaceByName($user, $space))["id"];
|
||||
if ($fileOrFolder === 'folder') {
|
||||
$itemId = $this->spacesContext->getResourceId($user, $space, $resource);
|
||||
} else {
|
||||
$itemId = $this->spacesContext->getFileId($user, $space, $resource);
|
||||
}
|
||||
}
|
||||
|
||||
return GraphHelper::getPermissionsList(
|
||||
@@ -233,6 +240,63 @@ class SharingNgContext implements Context {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $user
|
||||
* @param string $fileOrFolder (file|folder)
|
||||
* @param string $resource
|
||||
* @param TableNode $table
|
||||
*
|
||||
* @return void
|
||||
* @throws GuzzleException
|
||||
*/
|
||||
#[Then('/^for user "([^"]*)" (file|folder) "([^"]*)" should have the following shares:$/')]
|
||||
public function userGetsAllTheSharesOfTheResource(
|
||||
string $user,
|
||||
string $fileOrFolder,
|
||||
string $resource,
|
||||
TableNode $table
|
||||
): void {
|
||||
$permission = $this->getPermissionsList($user, $fileOrFolder, "Shares", $resource);
|
||||
$jsonBody = $this->featureContext->getJsonDecodedResponseBodyContent($permission);
|
||||
|
||||
$errors = [];
|
||||
foreach ($table->getHash() as $row) {
|
||||
$expectedRoleId = GraphHelper::getPermissionsRoleIdByName($row['permissionsRole']);
|
||||
if ($row['shareType'] === 'user') {
|
||||
$expectedSharee = $this->featureContext->getDisplayNameForUser($row['sharee']);
|
||||
} else {
|
||||
$expectedSharee = $row['sharee'];
|
||||
}
|
||||
$found = false;
|
||||
$actualSharee = '';
|
||||
foreach ($jsonBody->value as $share) {
|
||||
if ($row['shareType'] === 'user') {
|
||||
if (isset($share->grantedToV2->user->displayName)) {
|
||||
$actualSharee = $share->grantedToV2->user->displayName;
|
||||
}
|
||||
} else {
|
||||
if (isset($share->grantedToV2->group->displayName)) {
|
||||
$actualSharee = $share->grantedToV2->group->displayName;
|
||||
}
|
||||
}
|
||||
if ($actualSharee === $expectedSharee) {
|
||||
$found = true;
|
||||
if ($share->roles[0] !== $expectedRoleId) {
|
||||
$errors[] = "Expected user $actualSharee share role id to be '$expectedRoleId'"
|
||||
. " but found '{$share->roles[0]}'";
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!$found) {
|
||||
$errors[] = "Expected sharee '$expectedSharee' to be present but found '$actualSharee'";
|
||||
}
|
||||
}
|
||||
if (!empty($errors)) {
|
||||
Assert::fail(implode("\n", $errors));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $user
|
||||
@@ -458,10 +522,30 @@ class SharingNgContext implements Context {
|
||||
$rows,
|
||||
"'resource' should be provided in the data-table while sharing a resource"
|
||||
);
|
||||
$response = $this->sendShareInvitation($user, $rows);
|
||||
$response = WaitHelper::waitUntil(
|
||||
fn () => $this->sendShareInvitation($user, $rows),
|
||||
fn ($response) => !self::isShareManagerMigrating($response),
|
||||
null,
|
||||
30
|
||||
);
|
||||
$this->featureContext->theHTTPStatusCodeShouldBe(200, "", $response);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ResponseInterface $response
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private static function isShareManagerMigrating(ResponseInterface $response): bool {
|
||||
if ($response->getStatusCode() !== 500) {
|
||||
return false;
|
||||
}
|
||||
return \str_contains(
|
||||
(string)$response->getBody(),
|
||||
"share manager is currently migrating"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $user
|
||||
|
||||
@@ -307,6 +307,38 @@ class SpacesContext implements Context {
|
||||
throw new Exception("Cannot find share: $share");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $user
|
||||
* @param string $share
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws Exception|GuzzleException
|
||||
*/
|
||||
public function getSharesRemoteItemParentDriveId(string $user, string $share): string {
|
||||
$credentials = $this->featureContext->graphContext->getAdminOrUserCredentials($user);
|
||||
$response = GraphHelper::getSharesSharedWithMe(
|
||||
$this->featureContext->getBaseUrl(),
|
||||
$this->featureContext->getStepLineRef(),
|
||||
$credentials['username'],
|
||||
$credentials['password']
|
||||
);
|
||||
|
||||
$jsonBody = $this->featureContext->getJsonDecodedResponseBodyContent($response);
|
||||
|
||||
// Search parent driveId of a given share's remoteItem
|
||||
foreach ($jsonBody->value as $item) {
|
||||
if (isset($item->name) && $item->name === $share) {
|
||||
if (isset($item->remoteItem->parentReference->driveId)) {
|
||||
return $item->remoteItem->parentReference->driveId;
|
||||
}
|
||||
throw new Exception("Failed to find remoteItem parent driveId for share: $share");
|
||||
}
|
||||
}
|
||||
|
||||
throw new Exception("Cannot find share: $share");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $user
|
||||
* @param string $share
|
||||
@@ -3145,6 +3177,7 @@ class SpacesContext implements Context {
|
||||
* @throws GuzzleException
|
||||
*/
|
||||
#[When('user :user lists all deleted files in the trash bin of the space :spaceName')]
|
||||
#[When('user :user tries to list all deleted files in the trash bin of the space :spaceName')]
|
||||
public function userListAllDeletedFilesInTrash(
|
||||
string $user,
|
||||
string $spaceName
|
||||
@@ -3264,6 +3297,7 @@ class SpacesContext implements Context {
|
||||
* @throws Exception
|
||||
*/
|
||||
#[When('/^user "([^"]*)" restores the (?:file|folder) "([^"]*)" from the trash of the space "([^"]*)" to "([^"]*)"$/')]
|
||||
#[When('/^user "([^"]*)" tries to restore the (?:file|folder) "([^"]*)" from the trash of the space "([^"]*)" to "([^"]*)"$/')]
|
||||
public function userRestoresSpaceObjectsFromTrashRequest(
|
||||
string $user,
|
||||
string $object,
|
||||
@@ -3271,9 +3305,10 @@ class SpacesContext implements Context {
|
||||
string $destination
|
||||
): void {
|
||||
$space = $this->getSpaceByName($user, $spaceName);
|
||||
$spaceOwner = $this->getSpaceCreator($spaceName);
|
||||
|
||||
// find object in trash
|
||||
$objectsInTrash = $this->getObjectsInTrashbin($user, $spaceName);
|
||||
$objectsInTrash = $this->getObjectsInTrashbin($spaceOwner, $spaceName);
|
||||
$pathToDeletedObject = "";
|
||||
foreach ($objectsInTrash as $objectInTrash) {
|
||||
if ($objectInTrash["name"] === $object) {
|
||||
|
||||
@@ -383,6 +383,18 @@ default:
|
||||
- SharingNgContext:
|
||||
- PublicWebDavContext:
|
||||
- OcConfigContext:
|
||||
|
||||
apiSharingNgAdditionalShareRole:
|
||||
paths:
|
||||
- "%paths.base%/../features/apiSharingNgAdditionalShareRole"
|
||||
context: *common_ldap_suite_context
|
||||
contexts:
|
||||
- FeatureContext: *common_feature_context_params
|
||||
- SpacesContext:
|
||||
- GraphContext:
|
||||
- SharingNgContext:
|
||||
- FilesVersionsContext:
|
||||
- OcConfigContext:
|
||||
|
||||
apiOcm:
|
||||
paths:
|
||||
|
||||
+1047
File diff suppressed because it is too large.
Load diff
+1175
File diff suppressed because it is too large.
Load diff
+28
@@ -0,0 +1,28 @@
|
||||
@env-config
|
||||
Feature: an user shares resources
|
||||
As a user
|
||||
I don't want space editor to access deleted files
|
||||
So that they can't restore them
|
||||
|
||||
|
||||
Scenario: sharee checks trashbin after file is deleted
|
||||
Given these users have been created with default attributes:
|
||||
| username |
|
||||
| Alice |
|
||||
| Brian |
|
||||
And using spaces DAV path
|
||||
And the administrator has enabled the permissions role "Space Editor Without Trashbin"
|
||||
And the administrator has assigned the role "Space Admin" to user "Alice" using the Graph API
|
||||
And user "Alice" has created a space "new-space" with the default quota using the Graph API
|
||||
And user "Alice" has uploaded a file inside space "new-space" with content "hello world" to "textfile.txt"
|
||||
And user "Alice" has sent the following space share invitation:
|
||||
| space | new-space |
|
||||
| sharee | Brian |
|
||||
| shareType | user |
|
||||
| permissionsRole | Space Editor Without Trashbin |
|
||||
And user "Brian" has removed the file "textfile.txt" from space "new-space"
|
||||
When user "Brian" tries to list all deleted files in the trash bin of the space "new-space"
|
||||
Then the HTTP status code should be "403"
|
||||
When user "Brian" tries to restore the file "textfile.txt" from the trash of the space "new-space" to "/textfile.txt"
|
||||
Then the HTTP status code should be "403"
|
||||
And as "Alice" file "textfile.txt" should exist in the trashbin of the space "new-space"
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
@env-config
|
||||
Feature: an user shares resources
|
||||
As a user
|
||||
I don't want space editor to access file versions or the trash bin
|
||||
So that they can't see the versions or restore deleted files
|
||||
|
||||
|
||||
Scenario: space editor without versions without trash bin permissions cannot access versions or restore deleted files
|
||||
Given these users have been created with default attributes:
|
||||
| username |
|
||||
| Alice |
|
||||
| Brian |
|
||||
And using spaces DAV path
|
||||
And the administrator has enabled the permissions role "Space Editor Without Versions Without Trashbin"
|
||||
And the administrator has assigned the role "Space Admin" to user "Alice" using the Graph API
|
||||
And user "Alice" has created a space "new-space" with the default quota using the Graph API
|
||||
And user "Alice" has uploaded a file inside space "new-space" with content "new content" to "textfile.txt"
|
||||
And user "Alice" has uploaded a file inside space "new-space" with content "newest content" to "textfile.txt"
|
||||
And user "Alice" has sent the following space share invitation:
|
||||
| space | new-space |
|
||||
| sharee | Brian |
|
||||
| shareType | user |
|
||||
| permissionsRole | Space Editor Without Versions Without Trashbin |
|
||||
When user "Brian" tries to get versions of the file "textfile.txt" from the space "new-space" using the WebDAV API
|
||||
Then the HTTP status code should be "403"
|
||||
When user "Brian" tries to download version of the file "textfile.txt" with the index "1" of the space "new-space" using the WebDAV API
|
||||
Then the HTTP status code should be "403"
|
||||
When user "Brian" removes the file "textfile.txt" from space "new-space"
|
||||
And user "Brian" tries to list all deleted files in the trash bin of the space "new-space"
|
||||
Then the HTTP status code should be "403"
|
||||
When user "Brian" tries to restore the file "textfile.txt" from the trash of the space "new-space" to "/textfile.txt"
|
||||
Then the HTTP status code should be "403"
|
||||
And as "Alice" file "textfile.txt" should exist in the trashbin of the space "new-space"
|
||||
Reference in new issue
Block a user