From 34e4f0f1dcf2ea18cd26d2615d9e66115d4471ac Mon Sep 17 00:00:00 2001 From: Viktor Scharf Date: Fri, 18 Nov 2022 17:17:32 +0100 Subject: [PATCH] assign role to user --- tests/acceptance/config/behat.yml | 6 + ...ected-failures-localAPI-on-OCIS-storage.md | 8 + .../assignRole.feature | 64 +++++ .../bootstrap/RoleAssignmentContext.php | 258 ++++++++++++++++++ .../features/bootstrap/SpacesContext.php | 70 ----- 5 files changed, 336 insertions(+), 70 deletions(-) create mode 100644 tests/acceptance/features/apiAccountsHashDifficulty/assignRole.feature create mode 100644 tests/acceptance/features/bootstrap/RoleAssignmentContext.php diff --git a/tests/acceptance/config/behat.yml b/tests/acceptance/config/behat.yml index 488b5d87d7..01c570a28b 100644 --- a/tests/acceptance/config/behat.yml +++ b/tests/acceptance/config/behat.yml @@ -13,6 +13,7 @@ default: ldapGroupsOU: TestGroups ldapInitialUserFilePath: /../../config/ldap-users.ldif contexts: + - RoleAssignmentContext: - GraphContext: - SpacesContext: - OccContext: @@ -36,6 +37,7 @@ default: - '%paths.base%/../features/apiSpaces' context: *common_ldap_suite_context contexts: + - RoleAssignmentContext: - SpacesContext: - OccContext: - FeatureContext: *common_feature_context_params @@ -56,6 +58,7 @@ default: - '%paths.base%/../features/apiSpacesShares' context: *common_ldap_suite_context contexts: + - RoleAssignmentContext: - SpacesContext: - OccContext: - FeatureContext: *common_feature_context_params @@ -76,6 +79,7 @@ default: - '%paths.base%/../features/apiContract' context: *common_ldap_suite_context contexts: + - RoleAssignmentContext: - SpacesContext: - OccContext: - FeatureContext: *common_feature_context_params @@ -96,6 +100,7 @@ default: - '%paths.base%/../features/apiArchiver' context: *common_ldap_suite_context contexts: + - RoleAssignmentContext: - ArchiverContext: - SpacesContext: - OccContext: @@ -114,6 +119,7 @@ default: - '%paths.base%/../features/apiGraph' context: *common_ldap_suite_context contexts: + - RoleAssignmentContext: - GraphContext: - SpacesContext: - OccContext: diff --git a/tests/acceptance/expected-failures-localAPI-on-OCIS-storage.md b/tests/acceptance/expected-failures-localAPI-on-OCIS-storage.md index 9980be4901..76a9d44ebb 100644 --- a/tests/acceptance/expected-failures-localAPI-on-OCIS-storage.md +++ b/tests/acceptance/expected-failures-localAPI-on-OCIS-storage.md @@ -44,3 +44,11 @@ The expected failures in this file are from features in the owncloud/ocis repo. ### [Creating group with empty name returns status code 200](https://github.com/owncloud/ocis/issues/5050) - [apiGraph/createGroup.feature:40](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiGraph/createGroup.feature#L40) + +### [Settings service user can list other peoples assignments](https://github.com/owncloud/ocis/issues/5032) +- [apiAccountsHashDifficulty/assignRole.feature:27](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiAccountsHashDifficulty/assignRole.feature#L27) +- [apiAccountsHashDifficulty/assignRole.feature:28](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiAccountsHashDifficulty/assignRole.feature#L28) + +### [Settings service user can see roles list](https://github.com/owncloud/ocis/issues/5079) +- [apiAccountsHashDifficulty/assignRole.feature:15](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiAccountsHashDifficulty/assignRole.feature#L15) +- [apiAccountsHashDifficulty/assignRole.feature:16](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiAccountsHashDifficulty/assignRole.feature#L16) diff --git a/tests/acceptance/features/apiAccountsHashDifficulty/assignRole.feature b/tests/acceptance/features/apiAccountsHashDifficulty/assignRole.feature new file mode 100644 index 0000000000..4eaefb9827 --- /dev/null +++ b/tests/acceptance/features/apiAccountsHashDifficulty/assignRole.feature @@ -0,0 +1,64 @@ +@api +Feature: assign role + As an admin, I want to assign roles to users. + I cannot change my own role. + Users without an admin role cannot get the list of roles, assignments list and assign roles to users + + Scenario Outline: only admin user can see all existing roles + Given user "Alice" has been created with default attributes and without skeleton files + And the administrator has given "Alice" the role "" using the settings api + When user "Alice" tries to get all existing roles + Then the HTTP status code should be "" + Examples: + | userRole | statusCode | + | Admin | 201 | + | Space Admin | 401 | + | User | 401 | + + + Scenario Outline: only admin user can see assignments list + Given user "Alice" has been created with default attributes and without skeleton files + And the administrator has given "Alice" the role "" using the settings api + When user "Alice" tries to get list of assignment + Then the HTTP status code should be "" + Examples: + | userRole | statusCode | + | Admin | 201 | + | Space Admin | 401 | + | User | 401 | + + + Scenario Outline: a user cannot change own role + Given user "Alice" has been created with default attributes and without skeleton files + And the administrator has given "Alice" the role "" using the settings api + When user "Alice" changes his own role to "" + Then the HTTP status code should be "400" + And user "Alice" should have the role "" + Examples: + | userRole | desiredRole | + | Admin | User | + | Admin | Space Admin | + | Space Admin | Admin | + | Space Admin | Space Admin | + | User | Admin | + | User | Space Admin | + + + Scenario Outline: only admin user can change the role for another user + Given these users have been created with default attributes and without skeleton files: + | username | + | Alice | + | Brian | + And the administrator has given "Alice" the role "" using the settings api + When user "Alice" changes the role "" for user "Brian" + Then the HTTP status code should be "" + And user "Brian" should have the role "" + Examples: + | userRole | desiredRole | statusCode | expectedRole | + | Admin | User | 201 | User | + | Admin | Space Admin | 201 | Space Admin | + | Admin | Admin | 201 | Admin | + | Space Admin | Admin | 400 | User | + | Space Admin | Space Admin | 400 | User | + | User | Admin | 400 | User | + | User | Space Admin | 400 | User | diff --git a/tests/acceptance/features/bootstrap/RoleAssignmentContext.php b/tests/acceptance/features/bootstrap/RoleAssignmentContext.php new file mode 100644 index 0000000000..b89791df4f --- /dev/null +++ b/tests/acceptance/features/bootstrap/RoleAssignmentContext.php @@ -0,0 +1,258 @@ + + * @copyright Copyright (c) 2022 Viktor Scharf v.scharf@owncloud.com + */ + +use Behat\Behat\Context\Context; +use GuzzleHttp\Exception\GuzzleException; +use Behat\Behat\Hook\Scope\BeforeScenarioScope; +use PHPUnit\Framework\Assert; + +require_once 'bootstrap.php'; + +/** + * Context for the TUS-specific steps using the Graph API + */ +class RoleAssignmentContext implements Context { + + /** + * @var FeatureContext + */ + private FeatureContext $featureContext; + + /** + * @var SpacesContext + */ + private SpacesContext $spacesContext; + + /** + * @var string + */ + private string $baseUrl; + + /** + * @var string + */ + private string $setttingsUrl = '/api/v0/settings/'; + + /** + * This will run before EVERY scenario. + * It will set the properties for this object. + * + * @BeforeScenario + * + * @param BeforeScenarioScope $scope + * + * @return void + */ + public function before(BeforeScenarioScope $scope): void { + // Get the environment + $environment = $scope->getEnvironment(); + // Get all the contexts you need in this context from here + $this->featureContext = $environment->getContext('FeatureContext'); + $this->spacesContext = $environment->getContext('SpacesContext'); + $this->baseUrl = \trim($this->featureContext->getBaseUrl(), "/"); + } + + /** + * @When /^user "([^"]*)" tries to get all existing roles$/ + * + * @param string $user + * + * @return void + * + * @throws GuzzleException + * @throws Exception + */ + public function getAllExistingRoles(string $user): void { + $fullUrl = $this->baseUrl . $this->setttingsUrl . "roles-list"; + $this->featureContext->setResponse( + $this->spacesContext->sendPostRequestToUrl($fullUrl, $user, $this->featureContext->getPasswordForUser($user), "{}") + ); + } + + /** + * @param string $user + * @param string $userId + * @param string $roleId + * + * @return void + * + * @throws GuzzleException + * @throws Exception + */ + public function sendRequestToAssignRoleToUser(string $user, string $userId, string $roleId): void { + $fullUrl = $this->baseUrl . $this->setttingsUrl . "assignments-add"; + $body = json_encode(["account_uuid" => $userId, "role_id" => $roleId], JSON_THROW_ON_ERROR); + + $this->featureContext->setResponse( + $this->spacesContext->sendPostRequestToUrl($fullUrl, $user, $this->featureContext->getPasswordForUser($user), $body) + ); + } + + /** + * @param string $user + * @param string $userId + * + * @return void + * + * @throws GuzzleException + * @throws Exception + */ + public function sendRequestAssignmentsList(string $user, string $userId): void { + $fullUrl = $this->baseUrl . $this->setttingsUrl . "assignments-list"; + $body = json_encode(["account_uuid" => $userId], JSON_THROW_ON_ERROR); + + $this->featureContext->setResponse( + $this->spacesContext->sendPostRequestToUrl($fullUrl, $user, $this->featureContext->getPasswordForUser($user), $body) + ); + } + + /** + * @When /^the administrator has given "([^"]*)" the role "([^"]*)" using the settings api$/ + * + * @param string $user + * @param string $role + * + * @return void + * + * @throws GuzzleException + * @throws Exception + */ + public function theAdministratorHasGivenUserTheRole(string $user, string $role): void { + $admin = $this->featureContext->getAdminUserName(); + $roleId = $this->userGetRoleIdByRoleName($admin, $role); + $userId = $this->featureContext->getAttributeOfCreatedUser($user, 'id'); + $this->setRoleToUser($admin, $userId, $roleId); + } + + /** + * @param string $user + * @param string $role + * + * @return string + */ + public function userGetRoleIdByRoleName($user, $role): string { + $this->getAllExistingRoles($user); + + if ($this->featureContext->getResponse()) { + $rawBody = $this->featureContext->getResponse()->getBody()->getContents(); + $decodedBody = \json_decode($rawBody, true, 512, JSON_THROW_ON_ERROR); + Assert::assertArrayHasKey( + 'bundles', + $decodedBody, + __METHOD__ . " could not find bundles in body" + ); + $bundles = $decodedBody["bundles"]; + } + + $roleToAssign = ""; + foreach ($bundles as $value) { + // find the selected role + if ($value["displayName"] === $role) { + $roleToAssign = $value; + break; + } + } + Assert::assertNotEmpty($roleToAssign, "The selected role $role could not be found"); + return $roleToAssign["id"]; + } + + /** + * @param string $user + * @param string $userId + * @param string $roleId + * + * @return void + * @throws Exception + */ + public function setRoleToUser($user, $userId, $roleId): void { + $this->sendRequestToAssignRoleToUser($user, $userId, $roleId); + + if ($this->featureContext->getResponse()) { + $rawBody = $this->featureContext->getResponse()->getBody()->getContents(); + $decodedBody = \json_decode($rawBody, true, 512, JSON_THROW_ON_ERROR); + Assert::assertArrayHasKey( + 'assignment', + $decodedBody, + __METHOD__ . " could not find assignment in body" + ); + $assignment = $decodedBody["assignment"]; + } + + Assert::assertEquals($userId, $assignment["accountUuid"]); + Assert::assertEquals($roleId, $assignment["roleId"]); + } + + /** + * @When /^user "([^"]*)" changes his own role to "([^"]*)"$/ + * + * @param string $user + * @param string $role + * + * @return void + * @throws GuzzleException + */ + public function userChangeOwnRole(string $user, string $role): void { + // we assume that the user knows uuid role. + $roleId = $this->userGetRoleIdByRoleName($this->featureContext->getAdminUserName(), $role); + $userId = $this->featureContext->getAttributeOfCreatedUser($user, 'id'); + $this->sendRequestToAssignRoleToUser($user, $userId, $roleId); + } + + /** + * @When /^user "([^"]*)" changes the role "([^"]*)" for user "([^"]*)"$/ + * + * @param string $user + * @param string $role + * @param string $assignedUser + * + * @return void + * @throws GuzzleException + */ + public function userChangeRoleAnotherUser(string $user, string $role, string $assignedUser): void { + // we assume that the user knows uuid role. + $roleId = $this->userGetRoleIdByRoleName($this->featureContext->getAdminUserName(), $role); + $userId = $this->featureContext->getAttributeOfCreatedUser($assignedUser, 'id'); + $this->sendRequestToAssignRoleToUser($user, $userId, $roleId); + } + + /** + * @When /^user "([^"]*)" tries to get list of assignment$/ + * + * @param string $user + * + * @return void + * + * @throws GuzzleException + * @throws Exception + */ + public function userGetAssignmentsList(string $user): void { + $userId = $this->featureContext->getAttributeOfCreatedUser($user, 'id'); + $this->sendRequestAssignmentsList($user, $userId); + } + + /** + * @When /^user "([^"]*)" should have the role "([^"]*)"$/ + * + * @param string $user + * @param string $role + * + * @return void + * + * @throws GuzzleException + * @throws Exception + */ + public function userShouldHaveRole(string $user, string $role): void { + $userId = $this->featureContext->getAttributeOfCreatedUser($user, 'id'); + $this->sendRequestAssignmentsList($this->featureContext->getAdminUserName(), $userId); + $rawBody = $this->featureContext->getResponse()->getBody()->getContents(); + $assignmentRoleId = \json_decode($rawBody, true, 512, JSON_THROW_ON_ERROR)["assignments"][0]["roleId"]; + Assert::assertEquals($this->userGetRoleIdByRoleName($this->featureContext->getAdminUserName(), $role), $assignmentRoleId, "user $user has no role $role"); + } +} diff --git a/tests/acceptance/features/bootstrap/SpacesContext.php b/tests/acceptance/features/bootstrap/SpacesContext.php index 9dfafcadb2..9ab90311d3 100644 --- a/tests/acceptance/features/bootstrap/SpacesContext.php +++ b/tests/acceptance/features/bootstrap/SpacesContext.php @@ -687,76 +687,6 @@ class SpacesContext implements Context { $this->setSpaceCreator($spaceName, $user); } - /** - * @When /^the administrator has given "([^"]*)" the role "([^"]*)" using the settings api$/ - * - * @param string $user - * @param string $role - * - * @return void - * - * @throws GuzzleException - * @throws Exception - */ - public function theAdministratorGivesUserTheRole(string $user, string $role): void { - $admin = $this->featureContext->getAdminUsername(); - $password = $this->featureContext->getAdminPassword(); - $bundles = []; - $assignment = []; - - // get the roles list first - $fullUrl = $this->baseUrl . "/api/v0/settings/roles-list"; - $this->featureContext->setResponse($this->sendPostRequestToUrl($fullUrl, $admin, $password, "{}")); - - if ($this->featureContext->getResponse()) { - $rawBody = $this->featureContext->getResponse()->getBody()->getContents(); - if (isset(\json_decode($rawBody, true, 512, JSON_THROW_ON_ERROR)["bundles"])) { - $bundles = \json_decode($rawBody, true, 512, JSON_THROW_ON_ERROR)["bundles"]; - } - } - $roleToAssign = ""; - foreach ($bundles as $value) { - // find the selected role - if ($value["displayName"] === $role) { - $roleToAssign = $value; - } - } - Assert::assertNotEmpty($roleToAssign, "The selected role $role could not be found"); - - $this->featureContext->setResponse( - GraphHelper::getUser( - $this->featureContext->getBaseUrl(), - $this->featureContext->getStepLineRef(), - $this->featureContext->getAdminUsername(), - $this->featureContext->getAdminPassword(), - $user - ) - ); - if ($this->featureContext->getResponse()) { - $rawBody = $this->featureContext->getResponse()->getBody()->getContents(); - if (isset(\json_decode($rawBody, true, 512, JSON_THROW_ON_ERROR)["id"])) { - $accountToChange = \json_decode($rawBody, true, 512, JSON_THROW_ON_ERROR); - } - } - - Assert::assertNotEmpty($accountToChange, "The selected account $user does not exist"); - - // set the new role - $fullUrl = $this->baseUrl . "/api/v0/settings/assignments-add"; - $body = json_encode(["account_uuid" => $accountToChange["id"], "role_id" => $roleToAssign["id"]], JSON_THROW_ON_ERROR); - - $this->featureContext->setResponse($this->sendPostRequestToUrl($fullUrl, $admin, $password, $body)); - if ($this->featureContext->getResponse()) { - $rawBody = $this->featureContext->getResponse()->getBody()->getContents(); - if (isset(\json_decode($rawBody, true, 512, JSON_THROW_ON_ERROR)["assignment"])) { - $assignment = \json_decode($rawBody, true, 512, JSON_THROW_ON_ERROR)["assignment"]; - } - } - - Assert::assertEquals($accountToChange["id"], $assignment["accountUuid"]); - Assert::assertEquals($roleToAssign["id"], $assignment["roleId"]); - } - /** * Remember the available Spaces *