diff --git a/.woodpecker.star b/.woodpecker.star index 2a7056aea..208fe7d51 100644 --- a/.woodpecker.star +++ b/.woodpecker.star @@ -338,6 +338,7 @@ config = { "FRONTEND_READONLY_USER_ATTRIBUTES": "user.onPremisesSamAccountName,user.displayName,user.mail,user.passwordProfile,user.accountEnabled,user.appRoleAssignments", "OC_LDAP_SERVER_WRITE_ENABLED": False, "OC_EXCLUDE_RUN_SERVICES": "idm", + "OC_LDAP_USER_ENABLED_ATTRIBUTE": "", }, }, }, @@ -1076,6 +1077,7 @@ def localApiTests(name, suites, storage = "decomposed", extra_environment = {}, "WITH_REMOTE_PHP": with_remote_php, "COLLABORATION_SERVICE_URL": "http://wopi-fakeoffice:9300", "OC_STORAGE_PATH": "$HOME/.opencloud/storage/users", + "USE_BEARER_TOKEN": True, } for item in extra_environment: diff --git a/tests/acceptance/TestHelpers/GraphHelper.php b/tests/acceptance/TestHelpers/GraphHelper.php index dcc8ad263..27432b658 100644 --- a/tests/acceptance/TestHelpers/GraphHelper.php +++ b/tests/acceptance/TestHelpers/GraphHelper.php @@ -197,34 +197,6 @@ class GraphHelper { return $baseUrl . '/graph/v1beta1/' . $path; } - /** - * @param string $baseUrl - * @param string $xRequestId - * @param string $method - * @param string $path - * @param string|null $body - * @param array|null $headers - * - * @return RequestInterface - */ - public static function createRequest( - string $baseUrl, - string $xRequestId, - string $method, - string $path, - ?string $body = null, - ?array $headers = [] - ): RequestInterface { - $fullUrl = self::getFullUrl($baseUrl, $path); - return HttpRequestHelper::createRequest( - $fullUrl, - $xRequestId, - $method, - $headers, - $body - ); - } - /** * @param string $baseUrl * @param string $xRequestId @@ -1908,7 +1880,7 @@ class GraphHelper { string $permissionsId ): ResponseInterface { $url = self::getBetaFullUrl($baseUrl, "drives/$spaceId/items/$itemId/permissions/$permissionsId"); - return HttpRequestHelper::sendRequestOnce( + return HttpRequestHelper::sendRequest( $url, $xRequestId, 'PATCH', @@ -2264,7 +2236,7 @@ class GraphHelper { ): ResponseInterface { $url = self::getBetaFullUrl($baseUrl, "drives/$spaceId/root/permissions/$permissionsId"); - return HttpRequestHelper::sendRequestOnce( + return HttpRequestHelper::sendRequest( $url, $xRequestId, 'PATCH', diff --git a/tests/acceptance/TestHelpers/HttpRequestHelper.php b/tests/acceptance/TestHelpers/HttpRequestHelper.php index 8946ba73d..51390a714 100644 --- a/tests/acceptance/TestHelpers/HttpRequestHelper.php +++ b/tests/acceptance/TestHelpers/HttpRequestHelper.php @@ -74,6 +74,7 @@ class HttpRequestHelper { * than download it all up-front. * @param int|null $timeout * @param Client|null $client + * @param string|null $bearerToken * * @return ResponseInterface * @throws GuzzleException @@ -90,7 +91,8 @@ class HttpRequestHelper { ?CookieJar $cookies = null, bool $stream = false, ?int $timeout = 0, - ?Client $client = null + ?Client $client = null, + ?string $bearerToken = null ): ResponseInterface { if ($client === null) { $client = self::createClient( @@ -99,7 +101,8 @@ class HttpRequestHelper { $config, $cookies, $stream, - $timeout + $timeout, + $bearerToken ); } @@ -200,6 +203,13 @@ class HttpRequestHelper { } else { $debugResponses = false; } + // use basic auth for 'public' user or no user + if ($user === 'public' || $user === null || $user === '') { + $bearerToken = null; + } else { + $useBearerToken = TokenHelper::useBearerToken(); + $bearerToken = $useBearerToken ? TokenHelper::getTokens($user, $password, $url)['access_token'] : null; + } $sendRetryLimit = self::numRetriesOnHttpTooEarly(); $sendCount = 0; @@ -217,7 +227,8 @@ class HttpRequestHelper { $cookies, $stream, $timeout, - $client + $client, + $bearerToken, ); if ($response->getStatusCode() >= 400 @@ -348,6 +359,7 @@ class HttpRequestHelper { * @param bool $stream Set to true to stream a response rather * than download it all up-front. * @param int|null $timeout + * @param string|null $bearerToken * * @return Client */ @@ -357,10 +369,13 @@ class HttpRequestHelper { ?array $config = null, ?CookieJar $cookies = null, ?bool $stream = false, - ?int $timeout = 0 + ?int $timeout = 0, + ?string $bearerToken = null ): Client { $options = []; - if ($user !== null) { + if ($bearerToken !== null) { + $options['headers']['Authorization'] = 'Bearer ' . $bearerToken; + } elseif ($user !== null) { $options['auth'] = [$user, $password]; } if ($config !== null) { diff --git a/tests/acceptance/TestHelpers/TokenHelper.php b/tests/acceptance/TestHelpers/TokenHelper.php new file mode 100644 index 000000000..432dcad08 --- /dev/null +++ b/tests/acceptance/TestHelpers/TokenHelper.php @@ -0,0 +1,403 @@ + + * @copyright Copyright (c) 2025 Viktor Scharf + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, + * as published by the Free Software Foundation; + * either version 3 of the License, or any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * + */ + +namespace TestHelpers; + +use GuzzleHttp\Client; +use GuzzleHttp\Cookie\CookieJar; +use GuzzleHttp\Exception\GuzzleException; +use Exception; + +/** + * Helper for obtaining bearer tokens for users + */ +class TokenHelper { + private const LOGON_URL = '/signin/v1/identifier/_/logon'; + private const REDIRECT_URL = '/oidc-callback.html'; + private const TOKEN_URL = '/konnect/v1/token'; + + // Static cache [username => token_data] + private static array $tokenCache = []; + + /** + * @return bool + */ + public static function useBearerToken(): bool { + return \getenv('USE_BEARER_TOKEN') === 'true'; + } + + /** + * Extracts base URL from a full URL + * + * @param string $url + * + * @return string the base URL + */ + private static function extractBaseUrl(string $url): string { + return preg_replace('#(https?://[^/]+).*#', '$1', $url); + } + + /** + * Get access and refresh tokens for a user + * Uses cache to avoid unnecessary requests + * + * @param string $username + * @param string $password + * @param string $url + * + * @return array ['access_token' => string, 'refresh_token' => string, 'expires_at' => int] + * @throws GuzzleException + * @throws Exception + */ + public static function getTokens(string $username, string $password, string $url): array { + // Extract base URL. I need to send $url to get correct server in case of multiple servers (ocm suite) + $baseUrl = self::extractBaseUrl($url); + $cacheKey = $username . '|' . $baseUrl; + + // Check cache + if (isset(self::$tokenCache[$cacheKey])) { + $cachedToken = self::$tokenCache[$cacheKey]; + + // Check if access token has expired + if (time() < $cachedToken['expires_at']) { + return $cachedToken; + } + + $refreshedToken = self::refreshToken($cachedToken['refresh_token'], $baseUrl); + $tokenData = [ + 'access_token' => $refreshedToken['access_token'], + 'refresh_token' => $refreshedToken['refresh_token'], + 'expires_at' => time() + 300 // 5 minutes + ]; + self::$tokenCache[$cacheKey] = $tokenData; + return $tokenData; + } + + // Get new tokens + $cookieJar = new CookieJar(); + + $continueUrl = self::getAuthorizedEndPoint($username, $password, $baseUrl, $cookieJar); + $code = self::getCode($continueUrl, $baseUrl, $cookieJar); + $tokens = self::getToken($code, $baseUrl, $cookieJar); + + $tokenData = [ + 'access_token' => $tokens['access_token'], + 'refresh_token' => $tokens['refresh_token'], + 'expires_at' => time() + 290 // set expiry to 290 seconds to allow for some buffer + ]; + + // Save to cache + self::$tokenCache[$cacheKey] = $tokenData; + + return $tokenData; + } + + /** + * Refresh token + * + * @param string $refreshToken + * @param string $baseUrl + * + * @return array + * @throws GuzzleException + * @throws Exception + */ + private static function refreshToken(string $refreshToken, string $baseUrl): array { + $client = new Client( + [ + 'verify' => false, + 'http_errors' => false, + 'allow_redirects' => false + ] + ); + + $response = $client->post( + $baseUrl . self::TOKEN_URL, + [ + 'form_params' => [ + 'client_id' => 'web', + 'refresh_token' => $refreshToken, + 'grant_type' => 'refresh_token' + ] + ] + ); + + if ($response->getStatusCode() !== 200) { + throw new Exception( + \sprintf( + 'Token refresh failed: Expected status code 200 but received %d. Message: %s', + $response->getStatusCode(), + $response->getReasonPhrase() + ) + ); + } + + $data = json_decode($response->getBody()->getContents(), true); + + if (!isset($data['access_token']) || !isset($data['refresh_token'])) { + throw new Exception('Missing tokens in refresh response'); + } + + return [ + 'access_token' => $data['access_token'], + 'refresh_token' => $data['refresh_token'] + ]; + } + + /** + * Clear cached tokens for a specific user + * + * @param string $username + * @param string $url + * + * @return void + */ + public static function clearUserTokens(string $username, string $url): void { + $baseUrl = self::extractBaseUrl($url); + $cacheKey = $username . '|' . $baseUrl; + unset(self::$tokenCache[$cacheKey]); + } + + /** + * Clear all cached tokens + * + * @return void + */ + public static function clearAllTokens(): void { + self::$tokenCache = []; + } + + /** + * @param string $username + * @param string $password + * @param string $baseUrl + * @param CookieJar $cookieJar + * + * @return \Psr\Http\Message\ResponseInterface + * @throws GuzzleException + */ + public static function makeLoginRequest( + string $username, + string $password, + string $baseUrl, + CookieJar $cookieJar + ): \Psr\Http\Message\ResponseInterface { + $client = new Client( + [ + 'verify' => false, + 'http_errors' => false, + 'allow_redirects' => false, + 'cookies' => $cookieJar + ] + ); + + return $client->post( + $baseUrl . self::LOGON_URL, + [ + 'headers' => [ + 'Kopano-Konnect-XSRF' => '1', + 'Referer' => $baseUrl, + 'Content-Type' => 'application/json' + ], + 'json' => [ + 'params' => [$username, $password, '1'], + 'hello' => [ + 'scope' => 'openid profile offline_access email', + 'client_id' => 'web', + 'redirect_uri' => $baseUrl . self::REDIRECT_URL, + 'flow' => 'oidc' + ] + ] + ] + ); + } + + /** + * Step 1: Login and get continue_uri + * + * @param string $username + * @param string $password + * @param string $baseUrl + * @param CookieJar $cookieJar + * + * @return string + * @throws GuzzleException + * @throws Exception + */ + private static function getAuthorizedEndPoint( + string $username, + string $password, + string $baseUrl, + CookieJar $cookieJar + ): string { + $response = self::makeLoginRequest($username, $password, $baseUrl, $cookieJar); + + if ($response->getStatusCode() !== 200) { + throw new Exception( + \sprintf( + 'Logon failed: Expected status code 200 but received %d. Message: %s', + $response->getStatusCode(), + $response->getReasonPhrase() + ) + ); + } + + $data = json_decode($response->getBody()->getContents(), true); + + if (!isset($data['hello']['continue_uri'])) { + throw new Exception('Missing continue_uri in logon response'); + } + + return $data['hello']['continue_uri']; + } + + /** + * Step 2: Authorization and get code + * + * @param string $continueUrl + * @param string $baseUrl + * @param CookieJar $cookieJar + * + * @return string + * @throws GuzzleException + * @throws Exception + */ + private static function getCode(string $continueUrl, string $baseUrl, CookieJar $cookieJar): string { + $client = new Client( + [ + 'verify' => false, + 'http_errors' => false, + 'allow_redirects' => false, // Disable automatic redirects + 'cookies' => $cookieJar + ] + ); + + $params = [ + 'client_id' => 'web', + 'prompt' => 'none', + 'redirect_uri' => $baseUrl . self::REDIRECT_URL, + 'response_mode' => 'query', + 'response_type' => 'code', + 'scope' => 'openid profile offline_access email' + ]; + + $response = $client->get( + $continueUrl, + [ + 'query' => $params + ] + ); + + if ($response->getStatusCode() !== 302) { + // Add debugging to understand what is happening + $body = $response->getBody()->getContents(); + throw new Exception( + \sprintf( + 'Authorization failed: Expected status code 302 but received %d. Message: %s. Body: %s', + $response->getStatusCode(), + $response->getReasonPhrase(), + $body + ) + ); + } + + $location = $response->getHeader('Location')[0] ?? ''; + + if (empty($location)) { + throw new Exception('Missing Location header in authorization response'); + } + + parse_str(parse_url($location, PHP_URL_QUERY), $queryParams); + + // Check for errors + if (isset($queryParams['error'])) { + throw new Exception( + \sprintf( + 'Authorization error: %s - %s', + $queryParams['error'], + urldecode($queryParams['error_description'] ?? 'No description') + ) + ); + } + + if (!isset($queryParams['code'])) { + throw new Exception('Missing auth code in redirect URL. Location: ' . $location); + } + + return $queryParams['code']; + } + + /** + * Step 3: Get token + * + * @param string $code + * @param string $baseUrl + * @param CookieJar $cookieJar + * + * @return array + * + * @throws GuzzleException + * @throws Exception + * + */ + private static function getToken(string $code, string $baseUrl, CookieJar $cookieJar): array { + $client = new Client( + [ + 'verify' => false, + 'http_errors' => false, + 'allow_redirects' => false, + 'cookies' => $cookieJar + ] + ); + + $response = $client->post( + $baseUrl . self::TOKEN_URL, + [ + 'form_params' => [ + 'client_id' => 'web', + 'code' => $code, + 'redirect_uri' => $baseUrl . self::REDIRECT_URL, + 'grant_type' => 'authorization_code' + ] + ] + ); + + if ($response->getStatusCode() !== 200) { + throw new Exception( + \sprintf( + 'Token request failed: Expected status code 200 but received %d. Message: %s', + $response->getStatusCode(), + $response->getReasonPhrase() + ) + ); + } + + $data = json_decode($response->getBody()->getContents(), true); + + if (!isset($data['access_token']) || !isset($data['refresh_token'])) { + throw new Exception('Missing tokens in response'); + } + + return [ + 'access_token' => $data['access_token'], + 'refresh_token' => $data['refresh_token'] + ]; + } +} diff --git a/tests/acceptance/bootstrap/AuthContext.php b/tests/acceptance/bootstrap/AuthContext.php index d0a256f1b..8d546b119 100644 --- a/tests/acceptance/bootstrap/AuthContext.php +++ b/tests/acceptance/bootstrap/AuthContext.php @@ -25,6 +25,7 @@ use Behat\Behat\Context\Context; use Psr\Http\Message\ResponseInterface; use TestHelpers\HttpRequestHelper; use TestHelpers\BehatHelper; +use TestHelpers\TokenHelper; use TestHelpers\WebDavHelper; /** @@ -714,4 +715,27 @@ class AuthContext implements Context { ); $this->featureContext->setResponse($response); } + + /** + * @When user :user should not be able to log in with wrong password :password + * + * @param string $user + * @param string $password + * + * @return void + */ + public function userShouldNotBeAbleToLogInWithWrongPassword( + string $user, + string $password + ): void { + TokenHelper::clearUserTokens($user, $this->featureContext->getBaseUrl()); + $response = TokenHelper::makeLoginRequest( + $user, + $password, + $this->featureContext->getBaseUrl(), + new \GuzzleHttp\Cookie\CookieJar() + ); + // why is not 401 returned? + $this->featureContext->theHTTPStatusCodeShouldBe(204, 'should not be able to log in', $response); + } } diff --git a/tests/acceptance/bootstrap/GraphContext.php b/tests/acceptance/bootstrap/GraphContext.php index c90796e24..483d42a1c 100644 --- a/tests/acceptance/bootstrap/GraphContext.php +++ b/tests/acceptance/bootstrap/GraphContext.php @@ -17,6 +17,7 @@ use TestHelpers\GraphHelper; use TestHelpers\WebDavHelper; use TestHelpers\HttpRequestHelper; use TestHelpers\BehatHelper; +use TestHelpers\TokenHelper; require_once 'bootstrap.php'; @@ -2864,6 +2865,7 @@ class GraphContext implements Context { ); $this->featureContext->theHTTPStatusCodeShouldBe(200, '', $response); $this->featureContext->updateUsernameInCreatedUserList($byUser, $userName); + TokenHelper::clearUserTokens($byUser, $this->featureContext->getBaseUrl()); } /** diff --git a/tests/acceptance/bootstrap/Provisioning.php b/tests/acceptance/bootstrap/Provisioning.php index da1187140..4e5e53046 100644 --- a/tests/acceptance/bootstrap/Provisioning.php +++ b/tests/acceptance/bootstrap/Provisioning.php @@ -31,6 +31,7 @@ use TestHelpers\WebDavHelper; use TestHelpers\GraphHelper; use Laminas\Ldap\Exception\LdapException; use Laminas\Ldap\Ldap; +use TestHelpers\TokenHelper; /** * Functions for provisioning of users and groups @@ -558,110 +559,65 @@ trait Provisioning { */ public function usersHaveBeenCreated( TableNode $table, - bool $useDefault=true, - bool $initialize=true + bool $useDefault = true, + bool $initialize = true ) { $this->verifyTableNodeColumns($table, ['username'], ['displayname', 'email', 'password']); $table = $table->getColumnsHash(); $users = $this->buildUsersAttributesArray($useDefault, $table); - $requests = []; - $client = HttpRequestHelper::createClient( - $this->getAdminUsername(), - $this->getAdminPassword() - ); - foreach ($users as $userAttributes) { + $userName = $userAttributes['userid']; + $password = $userAttributes['password']; + $displayName = $userAttributes['displayName']; + $email = $userAttributes['email']; + if ($this->isTestingWithLdap()) { - $this->createLdapUser($userAttributes); - } else { - $attributesToCreateUser['userid'] = $userAttributes['userid']; - $attributesToCreateUser['password'] = $userAttributes['password']; - $attributesToCreateUser['displayname'] = $userAttributes['displayName']; - if ($userAttributes['email'] === null) { - Assert::assertArrayHasKey( - 'userid', - $userAttributes, - __METHOD__ . " userAttributes array does not have key 'userid'" + try { + $this->createLdapUser($userAttributes); + } catch (LdapException $exception) { + throw new Exception( + __METHOD__ . " cannot create a LDAP user with provided data. Error: $exception" ); - $attributesToCreateUser['email'] = $userAttributes['userid'] . '@opencloud.eu'; - } else { - $attributesToCreateUser['email'] = $userAttributes['email']; } - $body = GraphHelper::prepareCreateUserPayload( - $attributesToCreateUser['userid'], - $attributesToCreateUser['password'], - $attributesToCreateUser['email'], - $attributesToCreateUser['displayname'] - ); - $request = GraphHelper::createRequest( + } else { + // Use the same logic as userHasBeenCreated for email generation + if ($email === null) { + $email = $this->getEmailAddressForUser($userName); + if ($email === null) { + // escape @ & space if present in userId + $email = \str_replace(["@", " "], "", $userName) . '@opencloud.eu'; + } + } + + $userName = $this->getActualUsername($userName); + $userName = \trim($userName); + + $response = GraphHelper::createUser( $this->getBaseUrl(), $this->getStepLineRef(), - "POST", - 'users', - $body, + $this->getAdminUsername(), + $this->getAdminPassword(), + $userName, + $password, + $email, + $displayName, ); - // Add the request to the $requests array so that they can be sent in parallel. - $requests[] = $request; + + Assert::assertEquals( + 201, + $response->getStatusCode(), + __METHOD__ . " cannot create user '$userName' using Graph API.\nResponse:" . + json_encode($this->getJsonDecodedResponse($response)) + ); + + $userId = $this->getJsonDecodedResponse($response)['id']; } - } - $exceptionToThrow = null; - if (!$this->isTestingWithLdap()) { - $results = HttpRequestHelper::sendBatchRequest($requests, $client); - // Check all requests to inspect failures. - foreach ($results as $key => $e) { - if ($e instanceof ClientException) { - $responseBody = $this->getJsonDecodedResponse($e->getResponse()); - $httpStatusCode = $e->getResponse()->getStatusCode(); - $graphStatusCode = $responseBody['error']['code']; - $messageText = $responseBody['error']['message']; - $exceptionToThrow = new Exception( - __METHOD__ . - " Unexpected failure when creating the user '" . - $users[$key]['userid'] . "'" . - "\nHTTP status $httpStatusCode " . - "\nGraph status $graphStatusCode " . - "\nError message $messageText" - ); - } - } - } + $this->addUserToCreatedUsersList($userName, $password, $displayName, $email, $userId ?? null); - // Create requests for setting displayname and email for the newly created users. - // These values cannot be set while creating the user, so we have to edit the newly created user to set these values. - foreach ($users as $userAttributes) { - if (!$this->isTestingWithLdap()) { - // for graph api, we need to save the user id to be able to add it in some group - // can be fetched with the "onPremisesSamAccountName" i.e. userid - $response = $this->graphContext->adminHasRetrievedUserUsingTheGraphApi($userAttributes['userid']); - $userAttributes['id'] = $this->getJsonDecodedResponse($response)['id']; - } else { - $userAttributes['id'] = null; - } - $this->addUserToCreatedUsersList( - $userAttributes['userid'], - $userAttributes['password'], - $userAttributes['displayName'], - $userAttributes['email'], - $userAttributes['id'] - ); - } - - if (isset($exceptionToThrow)) { - throw $exceptionToThrow; - } - - foreach ($users as $user) { - Assert::assertTrue( - $this->userExists($user["userid"]), - "User '" . $user["userid"] . "' should exist but does not exist" - ); - } - - if ($initialize) { - foreach ($users as $user) { - $this->initializeUser($user['userid'], $user['password']); + if ($initialize) { + $this->initializeUser($userName, $password); } } } @@ -841,45 +797,16 @@ trait Provisioning { */ public function userHasBeenDeleted(string $user): void { $user = $this->getActualUsername($user); - if ($this->userExists($user)) { - if ($this->isTestingWithLdap() && \in_array($user, $this->ldapCreatedUsers)) { - $this->deleteLdapUser($user); - } else { - $response = $this->deleteUser($user); - $this->theHTTPStatusCodeShouldBe(204, "", $response); - WebDavHelper::removeSpaceIdReferenceForUser($user); - } + if ($this->isTestingWithLdap() && \in_array($user, $this->ldapCreatedUsers)) { + $this->deleteLdapUser($user); + } else { + $response = $this->deleteUser($user); + $this->theHTTPStatusCodeShouldBe(204, "", $response); + WebDavHelper::removeSpaceIdReferenceForUser($user); } - Assert::assertFalse( - $this->userExists($user), - "User '$user' should not exist but does exist" - ); $this->rememberThatUserIsNotExpectedToExist($user); } - /** - * @Given these users have been initialized: - * expects a table of users with the heading - * "|username|password|" - * - * @param TableNode $table - * - * @return void - */ - public function theseUsersHaveBeenInitialized(TableNode $table): void { - foreach ($table as $row) { - if (!isset($row ['password'])) { - $password = $this->getPasswordForUser($row ['username']); - } else { - $password = $row ['password']; - } - $this->initializeUser( - $row ['username'], - $password - ); - } - } - /** * get all the existing groups * @@ -961,13 +888,14 @@ trait Provisioning { $url = $this->getBaseUrl() . "/ocs/v$this->ocsApiVersion.php/cloud/users/$user"; } - - HttpRequestHelper::get( - $url, - $this->getStepLineRef(), - $user, - $password - ); + if ($password !== '') { + HttpRequestHelper::get( + $url, + $this->getStepLineRef(), + $user, + $password + ); + } } /** @@ -1162,12 +1090,6 @@ trait Provisioning { } $this->addUserToCreatedUsersList($user, $password, $displayName, $email, $userId); - - Assert::assertTrue( - $this->userExists($user), - "User '$user' should exist but does not exist" - ); - $this->initializeUser($user, $password); } @@ -1999,21 +1921,15 @@ trait Provisioning { $this->usingServer('LOCAL'); foreach ($this->createdUsers as $userData) { $user = $userData['actualUsername']; + TokenHelper::clearUserTokens($user, $this->getBaseUrl()); $this->deleteUser($user); - Assert::assertFalse( - $this->userExists($user), - "User '$user' should not exist but does exist" - ); $this->rememberThatUserIsNotExpectedToExist($user); } $this->usingServer('REMOTE'); foreach ($this->createdRemoteUsers as $userData) { $user = $userData['actualUsername']; + TokenHelper::clearUserTokens($user, $this->getBaseUrl()); $this->deleteUser($user); - Assert::assertFalse( - $this->userExists($user), - "User '$user' should not exist but does exist" - ); $this->rememberThatUserIsNotExpectedToExist($user); } $this->usingServer($previousServer); diff --git a/tests/acceptance/features/apiGraphUserGroup/editUser.feature b/tests/acceptance/features/apiGraphUserGroup/editUser.feature index 2a4bc9b6e..98c615a98 100644 --- a/tests/acceptance/features/apiGraphUserGroup/editUser.feature +++ b/tests/acceptance/features/apiGraphUserGroup/editUser.feature @@ -219,7 +219,7 @@ Feature: edit user When the user "Brian" resets the password of user "Carol" to "newpassword" using the Graph API Then the HTTP status code should be "403" And the content of file "resetpassword.txt" for user "Carol" using password "1234" should be "test file for reset password" - But user "Carol" using password "newpassword" should not be able to download file "resetpassword.txt" + And user "Carol" should not be able to log in with wrong password "newpassword" Examples: | user-role | user-role-2 | | Space Admin | Space Admin | diff --git a/tests/acceptance/features/apiSharingNg1/enableDisableShareSync.feature b/tests/acceptance/features/apiSharingNg1/enableDisableShareSync.feature index abf805988..e88d27d04 100644 --- a/tests/acceptance/features/apiSharingNg1/enableDisableShareSync.feature +++ b/tests/acceptance/features/apiSharingNg1/enableDisableShareSync.feature @@ -542,6 +542,7 @@ Feature: enable or disable sync of incoming shares | sharee | Brian | | shareType | user | | permissionsRole | Viewer | + And user "Brian" has a share "textfile0.txt" synced And the user "Admin" has deleted a user "Alice" When user "Brian" disables sync of share "textfile0.txt" using the Graph API Then the HTTP status code should be "204" @@ -820,6 +821,7 @@ Feature: enable or disable sync of incoming shares | sharee | Brian | | shareType | user | | permissionsRole | Viewer | + And user "Brian" has a share "" synced And user "Brian" has disabled sync of last shared resource When user "Brian" disables sync of share "" using the Graph API Then the HTTP status code should be "409" diff --git a/tests/acceptance/features/cliCommands/resetUserPassword.feature b/tests/acceptance/features/cliCommands/resetUserPassword.feature index f1ad3d36e..cf0a8a526 100644 --- a/tests/acceptance/features/cliCommands/resetUserPassword.feature +++ b/tests/acceptance/features/cliCommands/resetUserPassword.feature @@ -14,7 +14,7 @@ Feature: reset user password via CLI command But the command output should not contain "Failed to update user password: entry does not exist" And the administrator has started the server And user "Alice" should be able to create folder "newFolder" using password "newpass" - But user "Alice" should not be able to create folder "anotherFolder" using password "%alt1%" + But user "Alice" should not be able to log in with wrong password "%alt1%" Scenario: try to reset password of non-existing user