Merge pull request #5149 from owncloud/getUserWithGraph

[tests-only][full-ci]Added test for getting user information by admin or normal user using Graph API
This commit is contained in:
Phil Davis
2022-12-31 10:51:25 +05:45
committed by GitHub
4 changed files with 339 additions and 10 deletions

View File

@@ -26,14 +26,54 @@ class GraphHelper {
];
}
/**
*
* @return string
*/
public static function getUUIDv4Regex(): string {
return '[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}';
}
/**
* @param string $id
*
* @return int (1 = true | 0 = false)
* @return bool
*/
public static function isUUIDv4(string $id): int {
$regex = '/^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i';
return preg_match($regex, $id);
public static function isUUIDv4(string $id): bool {
$regex = "/^" . self::getUUIDv4Regex() . "$/i";
return (bool)preg_match($regex, $id);
}
/**
* @param string $spaceId
*
* @return bool
*/
public static function isSpaceId(string $spaceId): bool {
$regex = "/^" . self::getUUIDv4Regex() . '\\$' . self::getUUIDv4Regex() . "$/i";
return (bool)preg_match($regex, $spaceId);
}
/**
* Key name can consist of @@@
* This function separate such key and return its actual value from actual drive response which can be used for assertion
*
* @param string $keyName
* @param array $actualDriveInformation
*
* @return string
*/
public static function separateAndGetValueForKey(string $keyName, array $actualDriveInformation): string {
// break the segment with @@@ to find the actual value from the actual drive information
$separatedKey = explode("@@@", $keyName);
// this stores the actual value of each key from drive information response used for assertion
$actualKeyValue = $actualDriveInformation;
foreach ($separatedKey as $key) {
$actualKeyValue = $actualKeyValue[$key];
}
return $actualKeyValue;
}
/**
@@ -242,6 +282,32 @@ class GraphHelper {
);
}
/**
* @param string $baseUrl
* @param string $xRequestId
* @param string $byUser
* @param string $userPassword
* @param string|null $user
*
* @return ResponseInterface
* @throws GuzzleException
*/
public static function getUserWithDriveInformation(
string $baseUrl,
string $xRequestId,
string $byUser,
string $userPassword,
?string $user = null
): ResponseInterface {
$url = self::getFullUrl($baseUrl, 'users/' . $user . '?%24select=&%24expand=drive');
return HttpRequestHelper::get(
$url,
$xRequestId,
$byUser,
$userPassword,
);
}
/**
* @param string $baseUrl
* @param string $xRequestId

View File

@@ -78,3 +78,6 @@ The expected failures in this file are from features in the owncloud/ocis repo.
#### [Requests with invalid credentials do not return CORS headers](https://github.com/owncloud/ocis/issues/5194)
- [apiCors/cors.feature:67](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiCors/cors.feature#L67)
- [apiCors/cors.feature:68](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiCors/cors.feature#L68)
#### [A User can get information of another user with Graph API](https://github.com/owncloud/ocis/issues/5125)
- [apiGraph/getUser.feature:23](https://github.com/owncloud/ocis/blob/master/tests/acceptance/features/apiGraph/getUser.feature#L23)

View File

@@ -0,0 +1,77 @@
@api @skipOnOcV10
Feature: get users
As an admin
I want to be able to retrieve user information
So that I can see the information
Background:
Given these users have been created with default attributes and without skeleton files:
| username |
| Alice |
| Brian |
And the administrator has given "Alice" the role "Admin" using the settings api
Scenario: admin user gets the information of a user
When user "Alice" gets information of user "Brian" using Graph API
Then the HTTP status code should be "200"
And the user retrieve API response should contain the following information:
| displayName | id | mail | onPremisesSamAccountName |
| Brian Murphy | %uuid_v4% | brian@example.org | Brian |
Scenario: non-admin user tries to get the information of a user
When user "Brian" tries to get information of user "Alice" using Graph API
Then the HTTP status code should be "401"
And the last response should be an unauthorized response
Scenario: admin user gets all users
When user "Alice" gets all users using the Graph API
Then the HTTP status code should be "200"
And the API response should contain all users with the following information:
| displayName | id | mail | onPremisesSamAccountName |
| Alice Hansen | %uuid_v4% | alice@example.org | Alice |
| Brian Murphy | %uuid_v4% | brian@example.org | Brian |
Scenario: non-admin user tries to get all users
When user "Brian" tries to get all users using the Graph API
Then the HTTP status code should be "401"
And the last response should be an unauthorized response
Scenario: admin user gets the drive information of a user
When the user "Alice" gets user "Brian" along with his drive information using Graph API
Then the HTTP status code should be "200"
And the user retrieve API response should contain the following information:
| displayName | id | mail | onPremisesSamAccountName |
| Brian Murphy | %uuid_v4% | brian@example.org | Brian |
And the user retrieve API response should contain the following drive information:
| driveType | personal |
| driveAlias | personal/brian |
| id | %space_id% |
| name | Brian Murphy |
| owner@@@user@@@id | %user_id% |
| quota@@@state | normal |
| root@@@id | %space_id% |
| root@@@webDavUrl | %base_url%/dav/spaces/%space_id% |
| webUrl | %base_url%/f/%space_id% |
Scenario: normal user gets his/her own drive information
When the user "Brian" gets his drive information using Graph API
Then the HTTP status code should be "200"
And the user retrieve API response should contain the following information:
| displayName | id | mail | onPremisesSamAccountName |
| Brian Murphy | %uuid_v4% | brian@example.org | Brian |
And the user retrieve API response should contain the following drive information:
| driveType | personal |
| driveAlias | personal/brian |
| id | %space_id% |
| name | Brian Murphy |
| owner@@@user@@@id | %user_id% |
| quota@@@state | normal |
| root@@@id | %space_id% |
| root@@@webDavUrl | %base_url%/dav/spaces/%space_id% |
| webUrl | %base_url%/f/%space_id% |

View File

@@ -28,6 +28,11 @@ class GraphContext implements Context {
*/
private FeatureContext $featureContext;
/**
* @var SpacesContext
*/
private SpacesContext $spacesContext;
/**
* This will run before EVERY scenario.
* It will set the properties for this object.
@@ -1221,12 +1226,7 @@ class GraphContext implements Context {
. trim($expectedValue[$keyName], '%')
);
}
Assert::assertEquals(
1,
GraphHelper::isUUIDv4($actualValue['id']),
__METHOD__ .
' Expected user_id to have UUIDv4 pattern but found: ' . $actualValue['id']
);
Assert::assertTrue(GraphHelper::isUUIDv4($actualValue['id']), __METHOD__ . ' Expected user_id to have UUIDv4 pattern but found: ' . $actualValue['id']);
break;
default:
Assert::assertEquals(
@@ -1240,4 +1240,187 @@ class GraphContext implements Context {
}
}
}
/**
* @When user :byUser tries to get information of user :user using Graph API
* @When user :byUser gets information of user :user using Graph API
*
* @param string $byUser
* @param string $user
*
* @return void
* @throws GuzzleException
*/
public function userTriesToGetInformationOfUser(string $byUser, string $user): void {
$credentials = $this->getAdminOrUserCredentials($byUser);
$response = GraphHelper::getUser(
$this->featureContext->getBaseUrl(),
$this->featureContext->getStepLineRef(),
$credentials['username'],
$credentials['password'],
$user
);
$this->featureContext->setResponse($response);
}
/**
* @When user :user tries to get all users using the Graph API
* @When user :user gets all users using the Graph API
*
* @param string $user
*
* @return void
* @throws GuzzleException
*/
public function userGetsAllUserUsingTheGraphApi(string $user) {
$credentials = $this->getAdminOrUserCredentials($user);
$response = GraphHelper::getUsers(
$this->featureContext->getBaseUrl(),
$this->featureContext->getStepLineRef(),
$credentials['username'],
$credentials['password'],
);
$this->featureContext->setResponse($response);
}
/**
* @Then the API response should contain all users with the following information:
*
* @param TableNode $table
*
* @throws Exception
* @return void
*/
public function theApiResponseShouldContainAllUserWithFollowingInformation(TableNode $table): void {
$values = $table->getHash();
$apiResponse = $this->featureContext->getJsonDecodedResponse($this->featureContext->getResponse())['value'];
foreach ($values as $expectedValue) {
$found = false;
foreach ($apiResponse as $key => $actualResponseValue) {
if ($expectedValue["displayName"] === $actualResponseValue["displayName"]) {
$found = true;
$this->checkUserInformation($expectedValue, $actualResponseValue);
unset($apiResponse[$key]);
break;
}
}
if (!$found) {
throw new Exception('User ' . $expectedValue["displayName"] . ' could not be found in the response.');
}
}
}
/**
* @param string $byUser
* @param string|null $user
*
* @return ResponseInterface
* @throws JsonException
* @throws GuzzleException
*/
public function retrieveUserInformationAlongWithDriveUsingGraphApi(
string $byUser,
?string $user = null
):ResponseInterface {
$user = $user ?? $byUser;
$credentials = $this->getAdminOrUserCredentials($user);
return GraphHelper::getUserWithDriveInformation(
$this->featureContext->getBaseUrl(),
$this->featureContext->getStepLineRef(),
$credentials["username"],
$credentials["password"],
$user
);
}
/**
* @When /^the user "([^"]*)" gets user "([^"]*)" along with (his|her) drive information using Graph API$/
*
* @param string $byUser
* @param string $user
*
* @return void
*/
public function userTriesToGetInformationOfUserAlongWithHisDriveData(string $byUser, string $user) {
$response = $this->retrieveUserInformationAlongWithDriveUsingGraphApi($byUser, $user);
$this->featureContext->setResponse($response);
}
/**
*
* @When /^the user "([^"]*)" gets (his|her) drive information using Graph API$/
*
* @param string $user
*
* @return void
*/
public function userTriesToGetOwnDriveInformation(string $user) {
$response = $this->retrieveUserInformationAlongWithDriveUsingGraphApi($user);
$this->featureContext->setResponse($response);
}
/**
* @param array $driveInformation
*
* @return string
*/
public static function getSpaceIdFromActualDriveinformation(array $driveInformation): string {
return $driveInformation['id'];
}
/**
* check if single drive information is correct
*
* @param array $expectedDriveInformation
* @param array $actualDriveInformation
*
* @return void
*/
public function checkUserDriveInformation(array $expectedDriveInformation, array $actualDriveInformation):void {
foreach (array_keys($expectedDriveInformation) as $keyName) {
$actualKeyValue = GraphHelper::separateAndGetValueForKey($keyName, $actualDriveInformation);
switch ($expectedDriveInformation[$keyName]) {
case '%user_id%':
Assert::assertTrue(GraphHelper::isUUIDv4($actualKeyValue), __METHOD__ . ' Expected user_id to have UUIDv4 pattern but found: ' . $actualKeyValue);
break;
case '%space_id%':
Assert::assertTrue(GraphHelper::isSpaceId($actualKeyValue), __METHOD__ . ' Expected space_id to have a UUIDv4:UUIDv4 pattern but found: ' . $actualKeyValue);
break;
default:
$expectedDriveInformation[$keyName] = $this->featureContext->substituteInLineCodes(
$expectedDriveInformation[$keyName],
$this->featureContext->getCurrentUser(),
[],
[
[
// the actual space_id is substituted from the actual drive information rather than making an API request and substituting
"code" => "%space_id%",
"function" =>
[$this, "getSpaceIdFromActualDriveinformation"],
"parameter" => [$actualDriveInformation]
],
]
);
Assert::assertEquals($expectedDriveInformation[$keyName], $actualKeyValue);
}
}
}
/**
* @param TableNode $table
*
* @Then the user retrieve API response should contain the following drive information:
*
* @return void
*/
public function theResponseShouldContainTheFollowingDriveInformation(TableNode $table): void {
$expectedDriveInformation = $table->getRowsHash();
// array of user drive information (Personal Drive Information Only)
$actualDriveInformation = $this->featureContext->getJsonDecodedResponse($this->featureContext->getResponse());
if (\is_array($actualDriveInformation) && \array_key_exists('drive', $actualDriveInformation)) {
$this->checkUserDriveInformation($expectedDriveInformation, $actualDriveInformation['drive']);
} else {
throw new Error('Response is not an array or the array does not consist key "drive"');
}
}
}