Files
opencloud/tests/acceptance/features/bootstrap/Provisioning.php
Swikriti Tripathi 249adc7cd7 Seperate test steps for positive and negative cases (#5773)
fix php style

use the correct step

fix other steps

fix other php style

remove unwanted param

Refactor test function for handeling errors

fix return types

clean up code

address reviews
2023-03-09 16:21:50 +05:45

6138 lines
164 KiB
PHP

<?php declare(strict_types=1);
/**
* @author Sergio Bertolin <sbertolin@owncloud.com>
*
* @copyright Copyright (c) 2018, ownCloud GmbH
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* 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, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
use Behat\Gherkin\Node\TableNode;
use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Exception\GuzzleException;
use Psr\Http\Message\ResponseInterface;
use PHPUnit\Framework\Assert;
use TestHelpers\OcsApiHelper;
use TestHelpers\SetupHelper;
use TestHelpers\UserHelper;
use TestHelpers\HttpRequestHelper;
use TestHelpers\OcisHelper;
use TestHelpers\WebDavHelper;
use Laminas\Ldap\Exception\LdapException;
use Laminas\Ldap\Ldap;
/**
* Functions for provisioning of users and groups
*/
trait Provisioning {
/**
* list of users that were created on the local server during test runs
* key is the lowercase username, value is an array of user attributes
*
* @var array
*/
private $createdUsers = [];
/**
* list of users that were created on the remote server during test runs
* key is the lowercase username, value is an array of user attributes
*
* @var array
*/
private $createdRemoteUsers = [];
/**
* @var array
*/
private $enabledApps = [];
/**
* @var array
*/
private $disabledApps = [];
/**
* @var array
*/
private $startingGroups = [];
/**
* @var array
*/
private $createdRemoteGroups = [];
/**
* @var array
*/
private $createdGroups = [];
/**
* @var array
*/
private $userResponseFields = [
"enabled", "quota", "email", "displayname", "home", "two_factor_auth_enabled",
"quota definition", "quota free", "quota user", "quota total", "quota relative"
];
/**
* Check if this is the admin group. That group is always a local group in
* ownCloud10, even if other groups come from LDAP.
*
* @param string $groupname
*
* @return boolean
*/
public function isLocalAdminGroup(string $groupname):bool {
return ($groupname === "admin");
}
/**
* Usernames are not case-sensitive, and can generally be specified with any
* mix of upper and lower case. For remembering usernames use the normalized
* form so that "alice" and "Alice" are remembered as the same user.
*
* @param string|null $username
*
* @return string
*/
public function normalizeUsername(?string $username):string {
return \strtolower((string)$username);
}
/**
* @return array
*/
public function getCreatedUsers():array {
return $this->createdUsers;
}
/**
* @return boolean
*/
public function someUsersHaveBeenCreated():bool {
return (\count($this->createdUsers) > 0);
}
/**
* @return array
*/
public function getCreatedGroups():array {
return $this->createdGroups;
}
/**
* returns the display name of the current user
* if no "Display Name" is set the user-name is returned instead
*
* @return string
*/
public function getCurrentUserDisplayName():string {
return $this->getUserDisplayName($this->getCurrentUser());
}
/**
* returns the display name of a user
* if no "Display Name" is set the username is returned instead
*
* @param string $username
*
* @return string
*/
public function getUserDisplayName(string $username):string {
$normalizedUsername = $this->normalizeUsername($username);
if (isset($this->createdUsers[$normalizedUsername]['displayname'])) {
$displayName = (string) $this->createdUsers[$normalizedUsername]['displayname'];
if ($displayName !== '') {
return $displayName;
}
}
return $username;
}
/**
* @param string $user
* @param string $displayName
*
* @return void
* @throws Exception
*/
public function rememberUserDisplayName(string $user, string $displayName):void {
$normalizedUsername = $this->normalizeUsername($user);
if ($this->isAdminUsername($normalizedUsername)) {
$this->adminDisplayName = $displayName;
} else {
if ($this->currentServer === 'LOCAL') {
if (\array_key_exists($normalizedUsername, $this->createdUsers)) {
$this->createdUsers[$normalizedUsername]['displayname'] = $displayName;
} else {
throw new Exception(
__METHOD__ . " tried to remember display name '$displayName' for nonexistent local user '$user'"
);
}
} elseif ($this->currentServer === 'REMOTE') {
if (\array_key_exists($normalizedUsername, $this->createdRemoteUsers)) {
$this->createdRemoteUsers[$normalizedUsername]['displayname'] = $displayName;
} else {
throw new Exception(
__METHOD__ . " tried to remember display name '$displayName' for nonexistent federated user '$user'"
);
}
}
}
}
/**
* @param string $user
* @param string $emailAddress
*
* @return void
* @throws Exception
*/
public function rememberUserEmailAddress(string $user, string $emailAddress):void {
$normalizedUsername = $this->normalizeUsername($user);
if ($this->isAdminUsername($normalizedUsername)) {
$this->adminEmailAddress = $emailAddress;
} else {
if ($this->currentServer === 'LOCAL') {
if (\array_key_exists($normalizedUsername, $this->createdUsers)) {
$this->createdUsers[$normalizedUsername]['email'] = $emailAddress;
} else {
throw new Exception(
__METHOD__ . " tried to remember email address '$emailAddress' for nonexistent local user '$user'"
);
}
} elseif ($this->currentServer === 'REMOTE') {
if (\array_key_exists($normalizedUsername, $this->createdRemoteUsers)) {
$this->createdRemoteUsers[$normalizedUsername]['email'] = $emailAddress;
} else {
throw new Exception(
__METHOD__ . " tried to remember email address '$emailAddress' for nonexistent federated user '$user'"
);
}
}
}
}
/**
* returns an array of the user display names, keyed by normalized username
* if no "Display Name" is set the user-name is returned instead
*
* @return array
*/
public function getCreatedUserDisplayNames():array {
$result = [];
foreach ($this->getCreatedUsers() as $normalizedUsername => $user) {
$result[$normalizedUsername] = $this->getUserDisplayName($normalizedUsername);
}
return $result;
}
/**
* @param string $user
* @param string $attribute
*
* @return mixed
* @throws Exception
*/
public function getAttributeOfCreatedUser(string $user, string $attribute) {
$usersList = $this->getCreatedUsers();
$normalizedUsername = $this->normalizeUsername($user);
if (\array_key_exists($normalizedUsername, $usersList)) {
// provide attributes only if the user exists
if ($usersList[$normalizedUsername]["shouldExist"]) {
if (\array_key_exists($attribute, $usersList[$normalizedUsername])) {
return $usersList[$normalizedUsername][$attribute];
} else {
throw new Exception(
__METHOD__ . ": User '$user' has no attribute with name '$attribute'."
);
}
} else {
throw new Exception(
__METHOD__ . ": User '$user' has been deleted."
);
}
} else {
return false;
}
}
/**
* @param string $group
* @param string $attribute
*
* @return mixed
* @throws Exception
*/
public function getAttributeOfCreatedGroup(string $group, string $attribute) {
$groupsList = $this->getCreatedGroups();
if (\array_key_exists($group, $groupsList)) {
// provide attributes only if the group exists
if ($groupsList[$group]["shouldExist"]) {
if (\array_key_exists($attribute, $groupsList[$group])) {
return $groupsList[$group][$attribute];
} else {
throw new Exception(
__METHOD__ . ": Group '$group' has no attribute with name '$attribute'."
);
}
} else {
throw new Exception(
__METHOD__ . ": Group '$group' has been deleted."
);
}
} else {
return false;
}
}
/**
* returns an array of the group display names, keyed by group name
* currently group name and display name are always the same, so this
* function is a convenience for getting the group names in a similar
* format to what getCreatedUserDisplayNames() returns
*
* @return array
*/
public function getCreatedGroupDisplayNames():array {
$result = [];
foreach ($this->getCreatedGroups() as $groupName => $groupData) {
$result[$groupName] = $groupName;
}
return $result;
}
/**
*
* @param string $username
*
* @return string password
* @throws Exception
*/
public function getUserPassword(string $username):string {
$normalizedUsername = $this->normalizeUsername($username);
if ($normalizedUsername === $this->getAdminUsername()) {
$password = $this->getAdminPassword();
} elseif (\array_key_exists($normalizedUsername, $this->createdUsers)) {
$password = $this->createdUsers[$normalizedUsername]['password'];
} elseif (\array_key_exists($normalizedUsername, $this->createdRemoteUsers)) {
$password = $this->createdRemoteUsers[$normalizedUsername]['password'];
} else {
throw new Exception(
"user '$username' was not created by this test run"
);
}
//make sure the function always returns a string
return (string) $password;
}
/**
*
* @param string $username
*
* @return boolean
* @throws Exception
*/
public function theUserShouldExist(string $username):bool {
$normalizedUsername = $this->normalizeUsername($username);
if (\array_key_exists($normalizedUsername, $this->createdUsers)) {
return $this->createdUsers[$normalizedUsername]['shouldExist'];
}
if (\array_key_exists($normalizedUsername, $this->createdRemoteUsers)) {
return $this->createdRemoteUsers[$normalizedUsername]['shouldExist'];
}
throw new Exception(
__METHOD__
. " user '$username' was not created by this test run"
);
}
/**
*
* @param string $groupname
*
* @return boolean
* @throws Exception
*/
public function theGroupShouldExist(string $groupname):bool {
if (\array_key_exists($groupname, $this->createdGroups)) {
if (\array_key_exists('shouldExist', $this->createdGroups[$groupname])) {
return $this->createdGroups[$groupname]['shouldExist'];
}
return false;
}
if (\array_key_exists($groupname, $this->createdRemoteGroups)) {
if (\array_key_exists('shouldExist', $this->createdRemoteGroups[$groupname])) {
return $this->createdRemoteGroups[$groupname]['shouldExist'];
}
return false;
}
throw new Exception(
__METHOD__
. " group '$groupname' was not created by this test run"
);
}
/**
*
* @param string $groupname
*
* @return boolean
* @throws Exception
*/
public function theGroupShouldBeAbleToBeDeleted(string $groupname):bool {
if (\array_key_exists($groupname, $this->createdGroups)) {
return $this->createdGroups[$groupname]['possibleToDelete'] ?? true;
}
if (\array_key_exists($groupname, $this->createdRemoteGroups)) {
return $this->createdRemoteGroups[$groupname]['possibleToDelete'] ?? true;
}
throw new Exception(
__METHOD__
. " group '$groupname' was not created by this test run"
);
}
/**
* @When /^the administrator creates user "([^"]*)" using the provisioning API$/
*
* @param string|null $user
*
* @return void
* @throws Exception
*/
public function adminCreatesUserUsingTheProvisioningApi(?string $user):void {
$this->createUser(
$user,
null,
null,
null,
true,
'api'
);
$this->pushToLastStatusCodesArrays();
}
/**
* @Given /^user "([^"]*)" has been created with default attributes in the database user backend$/
*
* @param string|null $user
*
* @return void
* @throws Exception
*/
public function userHasBeenCreatedOnDatabaseBackend(?string $user):void {
$this->adminCreatesUserUsingTheProvisioningApi($user);
$this->userShouldExist($user);
}
/**
* @Given /^user "([^"]*)" has been created with default attributes and (tiny|small|large)\s?skeleton files$/
*
* @param string $user
* @param string $skeletonType
* @param boolean $skeleton
*
* @return void
* @throws Exception
*/
public function userHasBeenCreatedWithDefaultAttributes(
string $user,
string $skeletonType = "",
bool $skeleton = true
):void {
if ($skeletonType === "") {
$skeletonType = $this->getSmallestSkeletonDirName();
}
$originalSkeletonPath = $this->setSkeletonDirByType($skeletonType);
try {
$this->createUser(
$user,
null,
null,
null,
true,
null,
true,
$skeleton
);
$this->userShouldExist($user);
} finally {
$this->setSkeletonDir($originalSkeletonPath);
}
}
/**
* @Given /^user "([^"]*)" has been created with default attributes and without skeleton files$/
*
* @param string $user
*
* @return void
* @throws Exception
*/
public function userHasBeenCreatedWithDefaultAttributesAndWithoutSkeletonFiles(string $user):void {
$this->userHasBeenCreatedWithDefaultAttributes($user);
$this->resetOccLastCode();
}
/**
* @Given these users have been created with default attributes and without skeleton files:
* expects a table of users with the heading
* "|username|"
*
* @param TableNode $table
*
* @return void
* @throws Exception|GuzzleException
*/
public function theseUsersHaveBeenCreatedWithDefaultAttributesAndWithoutSkeletonFiles(TableNode $table):void {
$originalSkeletonPath = $this->setSkeletonDirByType($this->getSmallestSkeletonDirName());
try {
$this->createTheseUsers(true, true, true, $table);
} finally {
// restore skeleton directory even if user creation failed
$this->setSkeletonDir($originalSkeletonPath);
}
}
/**
* @Given /^these users have been created without skeleton files ?(and not initialized|):$/
* expects a table of users with the heading
* "|username|password|displayname|email|"
* password, displayname & email are optional
*
* @param TableNode $table
* @param string $doNotInitialize
*
* @return void
* @throws Exception
*/
public function theseUsersHaveBeenCreatedWithoutSkeletonFiles(TableNode $table, string $doNotInitialize):void {
$this->theseUsersHaveBeenCreated("", "", $doNotInitialize, $table);
}
/**
* @Given the administrator has set the system language to :defaultLanguage
*
* @param string $defaultLanguage
*
* @return void
* @throws Exception
*/
public function theAdministratorHasSetTheSystemLanguageTo(string $defaultLanguage):void {
$this->runOcc(
["config:system:set default_language --value $defaultLanguage"]
);
}
/**
*
* @param string $path
*
* @return void
*/
public function importLdifFile(string $path):void {
$ldifData = \file_get_contents($path);
$this->importLdifData($ldifData);
}
/**
* imports an ldif string
*
* @param string $ldifData
*
* @return void
*/
public function importLdifData(string $ldifData):void {
$items = Laminas\Ldap\Ldif\Encoder::decode($ldifData);
if (isset($items['dn'])) {
//only one item in the ldif data
$this->ldap->add($items['dn'], $items);
} else {
foreach ($items as $item) {
if (isset($item["objectclass"])) {
if (\in_array("posixGroup", $item["objectclass"])) {
\array_push($this->ldapCreatedGroups, $item["cn"][0]);
$this->addGroupToCreatedGroupsList($item["cn"][0]);
} elseif (\in_array("inetOrgPerson", $item["objectclass"])) {
\array_push($this->ldapCreatedUsers, $item["uid"][0]);
$this->addUserToCreatedUsersList($item["uid"][0], $item["userpassword"][0]);
}
}
$this->ldap->add($item['dn'], $item);
}
}
}
/**
* @param array $suiteParameters
*
* @return void
* @throws Exception
* @throws \LdapException
*/
public function connectToLdap(array $suiteParameters):void {
$useSsl = false;
$this->ldapBaseDN = OcisHelper::getBaseDN();
$this->ldapUsersOU = OcisHelper::getUsersOU();
$this->ldapGroupsOU = OcisHelper::getGroupsOU();
$this->ldapGroupSchema = OcisHelper::getGroupSchema();
$this->ldapHost = OcisHelper::getHostname();
$this->ldapPort = OcisHelper::getLdapPort();
$useSsl = OcisHelper::useSsl();
$this->ldapAdminUser = OcisHelper::getBindDN();
$this->ldapAdminPassword = OcisHelper::getBindPassword();
$this->skipImportLdif = (\getenv("REVA_LDAP_SKIP_LDIF_IMPORT") === "true");
if ($useSsl === true) {
\putenv('LDAPTLS_REQCERT=never');
}
if ($this->ldapAdminPassword === "") {
$this->ldapAdminPassword = (string)$suiteParameters['ldapAdminPassword'];
}
$options = [
'host' => $this->ldapHost,
'port' => $this->ldapPort,
'password' => $this->ldapAdminPassword,
'bindRequiresDn' => true,
'useSsl' => $useSsl,
'baseDn' => $this->ldapBaseDN,
'username' => $this->ldapAdminUser
];
$this->ldap = new Ldap($options);
$this->ldap->bind();
$ldifFile = __DIR__ . (string)$suiteParameters['ldapInitialUserFilePath'];
if (OcisHelper::isTestingParallelDeployment()) {
$behatYml = \getenv("BEHAT_YML");
if ($behatYml) {
$configPath = \dirname($behatYml);
$ldifFile = $configPath . "/" . \basename($ldifFile);
}
}
if (!$this->skipImportLdif) {
$this->importLdifFile($ldifFile);
}
$this->theLdapUsersHaveBeenResynced();
}
/**
* @Given the LDAP users have been resynced
*
* @return void
* @throws Exception
*/
public function theLdapUsersHaveBeenReSynced():void {
// we need to sync ldap users when testing for parallel deployment
if (!OcisHelper::isTestingOnOcisOrReva() || OcisHelper::isTestingParallelDeployment()) {
$occResult = SetupHelper::runOcc(
['user:sync', 'OCA\User_LDAP\User_Proxy', '-m', 'remove'],
$this->getStepLineRef()
);
if ($occResult['code'] !== "0") {
throw new Exception(__METHOD__ . " could not sync LDAP users " . $occResult['stdErr']);
}
}
}
/**
* prepares suitable nested array with user-attributes for multiple users to be created
*
* @param boolean $setDefaultAttributes
* @param array $table
*
* @return array
* @throws JsonException
*/
public function buildUsersAttributesArray(bool $setDefaultAttributes, array $table):array {
$usersAttributes = [];
foreach ($table as $row) {
$userAttribute['userid'] = $this->getActualUsername($row['username']);
if (isset($row['displayname'])) {
$userAttribute['displayName'] = $row['displayname'];
} elseif ($setDefaultAttributes) {
$userAttribute['displayName'] = $this->getDisplayNameForUser($row['username']);
if ($userAttribute['displayName'] === null) {
$userAttribute['displayName'] = $this->getDisplayNameForUser('regularuser');
}
} else {
$userAttribute['displayName'] = null;
}
if (isset($row['email'])) {
$userAttribute['email'] = $row['email'];
} elseif ($setDefaultAttributes) {
$userAttribute['email'] = $this->getEmailAddressForUser($row['username']);
if ($userAttribute['email'] === null) {
$userAttribute['email'] = $row['username'] . '@owncloud.com';
}
} else {
$userAttribute['email'] = null;
}
if (isset($row['password'])) {
$userAttribute['password'] = $this->getActualPassword($row['password']);
} else {
$userAttribute['password'] = $this->getPasswordForUser($row['username']);
}
// Add request body to the bodies array. we will use that later to loop through created users.
$usersAttributes[] = $userAttribute;
}
return $usersAttributes;
}
/**
* creates a user in the ldap server
* the created user is added to `createdUsersList`
* ldap users are re-synced after creating a new user
*
* @param array $setting
*
* @return void
* @throws Exception
*/
public function createLdapUser(array $setting):void {
$ou = $this->ldapUsersOU ;
// Some special characters need to be escaped in LDAP DN and attributes
// The special characters allowed in a username (UID) are +_.@-
// Of these, only + has to be escaped.
$userId = \str_replace('+', '\+', $setting["userid"]);
$newDN = 'uid=' . $userId . ',ou=' . $ou . ',' . $this->ldapBaseDN;
//pick a high number as uidnumber to make sure there are no conflicts with existing uidnumbers
$uidNumber = \count($this->ldapCreatedUsers) + 30000;
$entry = [];
$entry['cn'] = $userId;
$entry['sn'] = $userId;
$entry['uid'] = $setting["userid"];
$entry['homeDirectory'] = '/home/openldap/' . $setting["userid"];
$entry['objectclass'][] = 'posixAccount';
$entry['objectclass'][] = 'inetOrgPerson';
$entry['objectclass'][] = 'organizationalPerson';
$entry['objectclass'][] = 'person';
$entry['objectclass'][] = 'top';
$entry['userPassword'] = $setting["password"];
if (isset($setting["displayName"])) {
$entry['displayName'] = $setting["displayName"];
}
if (isset($setting["email"])) {
$entry['mail'] = $setting["email"];
} elseif (OcisHelper::isTestingOnOcis()) {
$entry['mail'] = $userId . '@owncloud.com';
}
$entry['gidNumber'] = 5000;
$entry['uidNumber'] = $uidNumber;
if (OcisHelper::isTestingOnOcis()) {
$entry['objectclass'][] = 'ownCloud';
$entry['ownCloudUUID'] = WebDavHelper::generateUUIDv4();
}
if (OcisHelper::isTestingParallelDeployment()) {
$entry['ownCloudSelector'] = $this->getOCSelector();
}
if ($this->federatedServerExists()) {
if (!\in_array($setting['userid'], $this->ldapCreatedUsers)) {
$this->ldap->add($newDN, $entry);
}
} else {
$this->ldap->add($newDN, $entry);
}
$this->ldapCreatedUsers[] = $setting["userid"];
$this->theLdapUsersHaveBeenReSynced();
}
/**
* @param string $group group name
*
* @return void
* @throws Exception
* @throws LdapException
*/
public function createLdapGroup(string $group):void {
$baseDN = $this->getLdapBaseDN();
$newDN = 'cn=' . $group . ',ou=' . $this->ldapGroupsOU . ',' . $baseDN;
$entry = [];
$entry['cn'] = $group;
$entry['objectclass'][] = 'top';
if ($this->ldapGroupSchema == "rfc2307") {
$entry['objectclass'][] = 'posixGroup';
$entry['gidNumber'] = 5000;
} else {
$entry['objectclass'][] = 'groupOfNames';
$entry['member'] = "";
}
if (OcisHelper::isTestingOnOcis()) {
$entry['objectclass'][] = 'ownCloud';
$entry['ownCloudUUID'] = WebDavHelper::generateUUIDv4();
}
$this->ldap->add($newDN, $entry);
$this->ldapCreatedGroups[] = $group;
}
/**
*
* @param string $configId
* @param string $configKey
* @param string $configValue
*
* @return void
* @throws Exception
*/
public function setLdapSetting(string $configId, string $configKey, string $configValue):void {
if ($configValue === "") {
$configValue = "''";
}
$substitutions = [
[
"code" => "%ldap_host_without_scheme%",
"function" => [
$this,
"getLdapHostWithoutScheme"
],
"parameter" => []
],
[
"code" => "%ldap_host%",
"function" => [
$this,
"getLdapHost"
],
"parameter" => []
],
[
"code" => "%ldap_port%",
"function" => [
$this,
"getLdapPort"
],
"parameter" => []
]
];
$configValue = $this->substituteInLineCodes(
$configValue,
null,
[],
$substitutions
);
$occResult = SetupHelper::runOcc(
['ldap:set-config', $configId, $configKey, $configValue],
$this->getStepLineRef()
);
if ($occResult['code'] !== "0") {
throw new Exception(
__METHOD__ . " could not set LDAP setting " . $occResult['stdErr']
);
}
}
/**
* deletes LDAP users|groups created during test
*
* @return void
* @throws Exception
*/
public function deleteLdapUsersAndGroups():void {
$isOcisOrReva = OcisHelper::isTestingOnOcisOrReva();
foreach ($this->ldapCreatedUsers as $user) {
if ($isOcisOrReva) {
$this->ldap->delete(
"uid=" . ldap_escape($user, "", LDAP_ESCAPE_DN) . ",ou=" . $this->ldapUsersOU . "," . $this->ldapBaseDN,
);
}
$this->rememberThatUserIsNotExpectedToExist($user);
}
foreach ($this->ldapCreatedGroups as $group) {
if ($isOcisOrReva) {
$this->ldap->delete(
"cn=" . ldap_escape($group, "", LDAP_ESCAPE_DN) . ",ou=" . $this->ldapGroupsOU . "," . $this->ldapBaseDN,
);
}
$this->rememberThatGroupIsNotExpectedToExist($group);
}
if (!$isOcisOrReva || !$this->skipImportLdif) {
//delete ou from LDIF import
$this->ldap->delete(
"ou=" . $this->ldapUsersOU . "," . $this->ldapBaseDN,
true
);
//delete all created ldap groups
$this->ldap->delete(
"ou=" . $this->ldapGroupsOU . "," . $this->ldapBaseDN,
true
);
}
$this->theLdapUsersHaveBeenResynced();
}
/**
* Sets back old settings
*
* @return void
* @throws Exception
*/
public function resetOldLdapConfig():void {
$toDeleteLdapConfig = $this->getToDeleteLdapConfigs();
foreach ($toDeleteLdapConfig as $configId) {
SetupHelper::runOcc(
['ldap:delete-config', $configId],
$this->getStepLineRef()
);
}
foreach ($this->oldLdapConfig as $configId => $settings) {
foreach ($settings as $configKey => $configValue) {
$this->setLdapSetting($configId, $configKey, $configValue);
}
}
foreach ($this->toDeleteDNs as $dn) {
$this->getLdap()->delete($dn, true);
}
}
/**
* Manually add skeleton files for a single user on OCIS and reva systems
*
* @param string $user
* @param string $password
*
* @return void
* @throws Exception
*/
public function manuallyAddSkeletonFilesForUser(string $user, string $password):void {
$settings = [];
$setting["userid"] = $user;
$setting["password"] = $password;
$settings[] = $setting;
$this->manuallyAddSkeletonFiles($settings);
}
/**
* Manually add skeleton files on OCIS and reva systems
*
* @param array $usersAttributes
*
* @return void
* @throws Exception
*/
public function manuallyAddSkeletonFiles(array $usersAttributes):void {
if ($this->isEmptySkeleton()) {
// The empty skeleton has no files. There is nothing to do so return early.
return;
}
$skeletonDir = \getenv("SKELETON_DIR");
$revaRoot = \getenv("OCIS_REVA_DATA_ROOT");
$skeletonStrategy = \getenv("OCIS_SKELETON_STRATEGY");
if (!$skeletonStrategy) {
$skeletonStrategy = 'upload'; //slower, but safer, so make it the default
}
if ($skeletonStrategy !== 'upload' && $skeletonStrategy !== 'copy') {
throw new Exception(
'Wrong OCIS_SKELETON_STRATEGY environment variable. ' .
'OCIS_SKELETON_STRATEGY has to be set to "upload" or "copy"'
);
}
if (!$skeletonDir) {
throw new Exception('Missing SKELETON_DIR environment variable, cannot copy skeleton files for OCIS');
}
if ($skeletonStrategy === 'copy' && !$revaRoot) {
throw new Exception(
'OCIS_SKELETON_STRATEGY is set to "copy" ' .
'but no "OCIS_REVA_DATA_ROOT" given'
);
}
if ($skeletonStrategy === 'upload') {
foreach ($usersAttributes as $userAttributes) {
OcisHelper::recurseUpload(
$this->getBaseUrl(),
$skeletonDir,
$userAttributes['userid'],
$userAttributes['password'],
$this->getStepLineRef()
);
}
}
if ($skeletonStrategy === 'copy') {
foreach ($usersAttributes as $userAttributes) {
$user = $userAttributes['userid'];
$dataDir = $revaRoot . "$user/files";
if (!\file_exists($dataDir)) {
\mkdir($dataDir, 0777, true);
}
OcisHelper::recurseCopy($skeletonDir, $dataDir);
}
}
}
/**
* This function will allow us to send user creation requests in parallel.
* This will be faster in comparison to waiting for each request to complete before sending another request.
*
* @param boolean $initialize
* @param array|null $usersAttributes
* @param string|null $method create the user with "ldap" or "api"
* @param boolean $skeleton
*
* @return void
* @throws Exception
* @throws GuzzleException
*/
public function usersHaveBeenCreated(
bool $initialize,
?array $usersAttributes,
?string $method = null,
?bool $skeleton = true
) {
$requests = [];
$client = HttpRequestHelper::createClient(
$this->getAdminUsername(),
$this->getAdminPassword()
);
$useLdap = false;
$useGraph = false;
if ($method === null) {
$useLdap = $this->isTestingWithLdap();
$useGraph = OcisHelper::isTestingWithGraphApi();
} elseif ($method === "ldap") {
$useLdap = true;
} elseif ($method === "graph") {
$useGraph = true;
}
foreach ($usersAttributes as $i => $userAttributes) {
if ($useLdap) {
$this->createLdapUser($userAttributes);
} else {
$attributesToCreateUser['userid'] = $userAttributes['userid'];
$attributesToCreateUser['password'] = $userAttributes['password'];
$attributesToCreateUser['displayname'] = $userAttributes['displayName'];
if (OcisHelper::isTestingOnOcisOrReva()) {
$attributesToCreateUser['username'] = $userAttributes['userid'];
if ($userAttributes['email'] === null) {
Assert::assertArrayHasKey(
'userid',
$userAttributes,
__METHOD__ . " userAttributes array does not have key 'userid'"
);
$attributesToCreateUser['email'] = $userAttributes['userid'] . '@owncloud.com';
} else {
$attributesToCreateUser['email'] = $userAttributes['email'];
}
}
if ($useGraph) {
$body = \TestHelpers\GraphHelper::prepareCreateUserPayload(
$attributesToCreateUser['userid'],
$attributesToCreateUser['password'],
$attributesToCreateUser['email'],
$attributesToCreateUser['displayname']
);
$request = \TestHelpers\GraphHelper::createRequest(
$this->getBaseUrl(),
$this->getStepLineRef(),
"POST",
'users',
$body,
);
} else {
// Create a OCS request for creating the user. The request is not sent to the server yet.
$request = OcsApiHelper::createOcsRequest(
$this->getBaseUrl(),
'POST',
"/cloud/users",
$this->stepLineRef,
$attributesToCreateUser
);
}
// Add the request to the $requests array so that they can be sent in parallel.
$requests[] = $request;
}
}
$exceptionToThrow = null;
if (!$useLdap) {
$results = HttpRequestHelper::sendBatchRequest($requests, $client);
// Check all requests to inspect failures.
foreach ($results as $key => $e) {
if ($e instanceof ClientException) {
if ($useGraph) {
$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 '" .
$usersAttributes[$key]['userid'] . "'" .
"\nHTTP status $httpStatusCode " .
"\nGraph status $graphStatusCode " .
"\nError message $messageText"
);
} else {
$responseXml = $this->getResponseXml($e->getResponse(), __METHOD__);
$messageText = (string) $responseXml->xpath("/ocs/meta/message")[0];
$ocsStatusCode = (string) $responseXml->xpath("/ocs/meta/statuscode")[0];
$httpStatusCode = $e->getResponse()->getStatusCode();
$reasonPhrase = $e->getResponse()->getReasonPhrase();
$exceptionToThrow = new Exception(
__METHOD__ . " Unexpected failure when creating the user '" .
$usersAttributes[$key]['userid'] . "': HTTP status $httpStatusCode " .
"HTTP reason $reasonPhrase OCS status $ocsStatusCode " .
"OCS message $messageText"
);
}
}
}
}
// 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.
$users = [];
$editData = [];
foreach ($usersAttributes as $userAttributes) {
$users[] = $userAttributes['userid'];
if ($useGraph) {
// 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
$this->graphContext->adminHasRetrievedUserUsingTheGraphApi($userAttributes['userid']);
$userAttributes['id'] = $this->getJsonDecodedResponse()['id'];
} else {
$userAttributes['id'] = null;
}
$this->addUserToCreatedUsersList(
$userAttributes['userid'],
$userAttributes['password'],
$userAttributes['displayName'],
$userAttributes['email'],
$userAttributes['id']
);
if (OcisHelper::isTestingOnOcisOrReva()) {
OcisHelper::createEOSStorageHome(
$this->getBaseUrl(),
$userAttributes['userid'],
$userAttributes['password'],
$this->getStepLineRef()
);
// We don't need to set displayName and email while running in oCIS
// As they are set when creating the user
continue;
}
if (isset($userAttributes['displayName'])) {
$editData[] = ['user' => $userAttributes['userid'], 'key' => 'displayname', 'value' => $userAttributes['displayName']];
}
if (isset($userAttributes['email'])) {
$editData[] = ['user' => $userAttributes['userid'], 'key' => 'email', 'value' => $userAttributes['email']];
}
}
// Edit the users in parallel to make the process faster.
if (!OcisHelper::isTestingOnOcisOrReva() && !$useLdap && \count($editData) > 0) {
UserHelper::editUserBatch(
$this->getBaseUrl(),
$editData,
$this->getAdminUsername(),
$this->getAdminPassword(),
$this->stepLineRef
);
}
if (isset($exceptionToThrow)) {
throw $exceptionToThrow;
}
// If the user should have skeleton files, and we are testing on OCIS
// then do some work to "manually" put the skeleton files in place.
// When testing on ownCloud 10 the user is already getting whatever
// skeleton dir is defined in the server-under-test.
if ($skeleton && OcisHelper::isTestingOnOcisOrReva()) {
$this->manuallyAddSkeletonFiles($usersAttributes);
}
if ($initialize && ($this->isEmptySkeleton() || !OcisHelper::isTestingOnOcis())) {
// We need to initialize each user using the individual authentication of each user.
// That is not possible in Guzzle6 batch mode. So we do it with normal requests in serial.
$this->initializeUsers($users);
}
}
/**
* @When /^the administrator creates these users with ?(default attributes and|) skeleton files ?(but not initialized|):$/
*
* expects a table of users with the heading
* "|username|password|displayname|email|"
* password, displayname & email are optional
*
* @param string $setDefaultAttributes
* @param string $doNotInitialize
* @param TableNode $table
*
* @return void
* @throws Exception
* @throws GuzzleException
*/
public function theAdministratorCreatesTheseUsers(
string $setDefaultAttributes,
string $doNotInitialize,
TableNode $table
): void {
$this->verifyTableNodeColumns($table, ['username'], ['displayname', 'email', 'password']);
$table = $table->getColumnsHash();
$setDefaultAttributes = $setDefaultAttributes !== "";
$initialize = $doNotInitialize === "";
$usersAttributes = $this->buildUsersAttributesArray($setDefaultAttributes, $table);
$this->usersHaveBeenCreated(
$initialize,
$usersAttributes
);
}
/**
* expects a table of users with the heading
* "|username|password|displayname|email|"
* password, displayname & email are optional
*
* @param boolean $setDefaultAttributes
* @param boolean $initialize
* @param boolean $skeleton
* @param TableNode $table
*
* @return void
* @throws Exception
* @throws GuzzleException
*/
public function createTheseUsers(bool $setDefaultAttributes, bool $initialize, bool $skeleton, TableNode $table):void {
$this->verifyTableNodeColumns($table, ['username'], ['displayname', 'email', 'password']);
$table = $table->getColumnsHash();
$usersAttributes = $this->buildUsersAttributesArray($setDefaultAttributes, $table);
$this->usersHaveBeenCreated(
$initialize,
$usersAttributes,
null,
$skeleton
);
foreach ($usersAttributes as $expectedUser) {
$this->userShouldExist($expectedUser["userid"]);
}
}
/**
* @Given /^these users have been created with ?(default attributes and|) (tiny|small|large)\s?skeleton files ?(but not initialized|):$/
*
* expects a table of users with the heading
* "|username|password|displayname|email|"
* password, displayname & email are optional
*
* @param string $defaultAttributesText
* @param string $skeletonType
* @param string $doNotInitialize
* @param TableNode $table
*
* @return void
* @throws Exception|GuzzleException
*/
public function theseUsersHaveBeenCreated(
string $defaultAttributesText,
string $skeletonType,
string $doNotInitialize,
TableNode $table
):void {
if ($skeletonType === "") {
$skeletonType = $this->getSmallestSkeletonDirName();
}
$originalSkeletonPath = $this->setSkeletonDirByType($skeletonType);
$setDefaultAttributes = $defaultAttributesText !== "";
$initialize = $doNotInitialize === "";
try {
$this->createTheseUsers($setDefaultAttributes, $initialize, true, $table);
} finally {
// The effective skeleton directory is the one when the user is initialized
// If we did not initialize the user on creation, then we need to leave
// the skeleton directory in effect so that it applies when some action
// happens later in the scenario that causes the user to be initialized.
if ($initialize) {
$this->setSkeletonDir($originalSkeletonPath);
}
}
}
/**
* @When the administrator changes the password of user :user to :password using the provisioning API
*
* @param string $user
* @param string $password
*
* @return void
* @throws Exception
*/
public function adminChangesPasswordOfUserToUsingTheProvisioningApi(
string $user,
string $password
):void {
$this->response = UserHelper::editUser(
$this->getBaseUrl(),
$user,
'password',
$password,
$this->getAdminUsername(),
$this->getAdminPassword(),
$this->getStepLineRef()
);
}
/**
* @Given the administrator has changed the password of user :user to :password
*
* @param string $user
* @param string $password
*
* @return void
* @throws Exception
*/
public function adminHasChangedPasswordOfUserTo(
string $user,
string $password
):void {
if (OcisHelper::isTestingWithGraphApi()) {
$this->graphContext->adminChangesPasswordOfUserToUsingTheGraphApi(
$user,
$password
);
} else {
$this->adminChangesPasswordOfUserToUsingTheProvisioningApi(
$user,
$password
);
}
$this->theHTTPStatusCodeShouldBe(
200,
"could not change password of user $user"
);
}
/**
* @When /^user "([^"]*)" (enables|disables) app "([^"]*)"$/
*
* @param string $user
* @param string $action enables or disables
* @param string $app
*
* @return void
*/
public function userEnablesOrDisablesApp(string $user, string $action, string $app):void {
$fullUrl = $this->getBaseUrl()
. "/ocs/v{$this->ocsApiVersion}.php/cloud/apps/$app";
if ($action === 'enables') {
$this->response = HttpRequestHelper::post(
$fullUrl,
$this->getStepLineRef(),
$user,
$this->getPasswordForUser($user)
);
} else {
$this->response = HttpRequestHelper::delete(
$fullUrl,
$this->getStepLineRef(),
$user,
$this->getPasswordForUser($user)
);
}
}
/**
* @When /^the administrator (enables|disables) app "([^"]*)"$/
*
* @param string $action enables or disables
* @param string $app
*
* @return void
*/
public function adminEnablesOrDisablesApp(string $action, string $app):void {
$this->userEnablesOrDisablesApp(
$this->getAdminUsername(),
$action,
$app
);
}
/**
* @Given /^app "([^"]*)" has been (enabled|disabled)$/
*
* @param string $app
* @param string $action enabled or disabled
*
* @return void
*/
public function appHasBeenDisabled(string $app, string $action):void {
if ($action === 'enabled') {
$action = 'enables';
} else {
$action = 'disables';
}
$this->userEnablesOrDisablesApp(
$this->getAdminUsername(),
$action,
$app
);
}
/**
* @When the administrator gets the info of app :app
*
* @param string $app
*
* @return void
*/
public function theAdministratorGetsTheInfoOfApp(string $app):void {
$this->ocsContext->userSendsToOcsApiEndpoint(
$this->getAdminUsername(),
"GET",
"/cloud/apps/$app"
);
}
/**
* @When the administrator gets all apps using the provisioning API
*
* @return void
*/
public function theAdministratorGetsAllAppsUsingTheProvisioningApi():void {
$this->getAllApps();
}
/**
* @When the administrator gets all enabled apps using the provisioning API
*
* @return void
*/
public function theAdministratorGetsAllEnabledAppsUsingTheProvisioningApi():void {
$this->getEnabledApps();
}
/**
* @When the administrator gets all disabled apps using the provisioning API
*
* @return void
*/
public function theAdministratorGetsAllDisabledAppsUsingTheProvisioningApi():void {
$this->getDisabledApps();
}
/**
* @When the administrator sends a user creation request with the following attributes using the provisioning API:
*
* @param TableNode $table
*
* @return void
* @throws Exception
*/
public function adminSendsUserCreationRequestWithFollowingAttributesUsingTheProvisioningApi(TableNode $table):void {
$this->verifyTableNodeRows($table, ["username", "password"], ["email", "displayname"]);
$table = $table->getRowsHash();
$username = $this->getActualUsername($table["username"]);
$password = $this->getActualPassword($table["password"]);
$displayname = \array_key_exists("displayname", $table) ? $table["displayname"] : null;
$email = \array_key_exists("email", $table) ? $table["email"] : null;
if (OcisHelper::isTestingOnOcisOrReva()) {
if ($email === null) {
$email = $username . '@owncloud.com';
}
}
$userAttributes = [
["userid", $username],
["password", $password],
];
if ($displayname !== null) {
$userAttributes[] = ["displayname", $displayname];
}
if ($email !== null) {
$userAttributes[] = ["email", $email];
}
if (OcisHelper::isTestingOnOcisOrReva()) {
$userAttributes[] = ["username", $username];
}
$this->ocsContext->userSendsHTTPMethodToOcsApiEndpointWithBody(
$this->getAdminUsername(),
"POST",
"/cloud/users",
new TableNode($userAttributes)
);
$this->addUserToCreatedUsersList(
$username,
$password,
$displayname,
$email,
null,
$this->theHTTPStatusCodeWasSuccess()
);
if (OcisHelper::isTestingOnOcisOrReva()) {
$this->manuallyAddSkeletonFilesForUser($username, $password);
}
}
/**
* @When /^the administrator sends a user creation request for user "([^"]*)" password "([^"]*)" using the provisioning API$/
*
* @param string $user
* @param string $password
*
* @return void
* @throws Exception
*/
public function adminSendsUserCreationRequestUsingTheProvisioningApi(string $user, string $password):void {
$user = $this->getActualUsername($user);
$password = $this->getActualPassword($password);
if (OcisHelper::isTestingOnOcisOrReva()) {
$email = $user . '@owncloud.com';
$bodyTable = new TableNode(
[
['userid', $user],
['password', $password],
['username', $user],
['email', $email]
]
);
} else {
$email = null;
$bodyTable = new TableNode([['userid', $user], ['password', $password]]);
}
$this->emptyLastHTTPStatusCodesArray();
$this->emptyLastOCSStatusCodesArray();
$this->ocsContext->userSendsHTTPMethodToOcsApiEndpointWithBody(
$this->getAdminUsername(),
"POST",
"/cloud/users",
$bodyTable
);
$this->pushToLastStatusCodesArrays();
$success = $this->theHTTPStatusCodeWasSuccess();
$this->addUserToCreatedUsersList(
$user,
$password,
null,
$email,
null,
$success
);
if (OcisHelper::isTestingOnOcisOrReva() && $success) {
OcisHelper::createEOSStorageHome(
$this->getBaseUrl(),
$user,
$password,
$this->getStepLineRef()
);
$this->manuallyAddSkeletonFilesForUser($user, $password);
}
}
/**
* @When /^the administrator sends a user creation request for the following users with password using the provisioning API$/
*
* @param TableNode $table
*
* @return void
* @throws Exception
*/
public function theAdministratorSendsAUserCreationRequestForTheFollowingUsersWithPasswordUsingTheProvisioningApi(TableNode $table):void {
$this->verifyTableNodeColumns($table, ["username", "password"], ["comment"]);
$users = $table->getHash();
foreach ($users as $user) {
$this->adminSendsUserCreationRequestUsingTheProvisioningApi($user["username"], $user["password"]);
}
}
/**
* @When /^unauthorized user "([^"]*)" tries to create new user "([^"]*)" with password "([^"]*)" using the provisioning API$/
*
* @param string $user
* @param string $userToCreate
* @param string $password
*
* @return void
* @throws Exception
*/
public function userSendsUserCreationRequestUsingTheProvisioningApi(string $user, string $userToCreate, string $password):void {
$userToCreate = $this->getActualUsername($userToCreate);
$password = $this->getActualPassword($password);
if (OcisHelper::isTestingOnOcisOrReva()) {
$email = $userToCreate . '@owncloud.com';
$bodyTable = new TableNode(
[
['userid', $userToCreate],
['password', $password],
['username', $userToCreate],
['email', $email]
]
);
} else {
$email = null;
$bodyTable = new TableNode([['userid', $userToCreate], ['password', $password]]);
}
$this->ocsContext->userSendsHTTPMethodToOcsApiEndpointWithBody(
$user,
"POST",
"/cloud/users",
$bodyTable
);
$this->addUserToCreatedUsersList(
$userToCreate,
$password,
null,
$email,
null,
$this->theHTTPStatusCodeWasSuccess()
);
}
/**
* @When /^the administrator sends a user creation request for user "([^"]*)" password "([^"]*)" group "([^"]*)" using the provisioning API$/
*
* @param string $user
* @param string $password
* @param string $group
*
* @return void
* @throws Exception
*/
public function theAdministratorCreatesUserPasswordGroupUsingTheProvisioningApi(
string $user,
string $password,
string $group
):void {
$user = $this->getActualUsername($user);
$password = $this->getActualPassword($password);
if (OcisHelper::isTestingOnOcisOrReva()) {
$email = $user . '@owncloud.com';
$bodyTable = new TableNode(
[
['userid', $user],
['password', $password],
['username', $user],
['email', $email],
['groups[]', $group],
]
);
} else {
$email = null;
$bodyTable = new TableNode(
[['userid', $user], ['password', $password], ['groups[]', $group]]
);
}
$this->ocsContext->userSendsHTTPMethodToOcsApiEndpointWithBody(
$this->getAdminUsername(),
"POST",
"/cloud/users",
$bodyTable
);
$this->addUserToCreatedUsersList(
$user,
$password,
null,
$email,
null,
$this->theHTTPStatusCodeWasSuccess()
);
if (OcisHelper::isTestingOnOcisOrReva()) {
$this->manuallyAddSkeletonFilesForUser($user, $password);
}
}
/**
* @When /^the groupadmin "([^"]*)" sends a user creation request for user "([^"]*)" password "([^"]*)" group "([^"]*)" using the provisioning API$/
*
* @param string $groupadmin
* @param string $userToCreate
* @param string $password
* @param string $group
*
* @return void
* @throws Exception
*/
public function theGroupAdminCreatesUserPasswordGroupUsingTheProvisioningApi(
string $groupadmin,
string $userToCreate,
string $password,
string $group
):void {
$userToCreate = $this->getActualUsername($userToCreate);
$password = $this->getActualPassword($password);
if (OcisHelper::isTestingOnOcisOrReva()) {
$email = $userToCreate . '@owncloud.com';
$bodyTable = new TableNode(
[
['userid', $userToCreate],
['password', $userToCreate],
['username', $userToCreate],
['email', $email],
['groups[]', $group],
]
);
} else {
$email = null;
$bodyTable = new TableNode(
[['userid', $userToCreate], ['password', $password], ['groups[]', $group]]
);
}
$this->ocsContext->userSendsHTTPMethodToOcsApiEndpointWithBody(
$groupadmin,
"POST",
"/cloud/users",
$bodyTable
);
$this->addUserToCreatedUsersList(
$userToCreate,
$password,
null,
$email,
null,
$this->theHTTPStatusCodeWasSuccess()
);
if (OcisHelper::isTestingOnOcisOrReva()) {
$this->manuallyAddSkeletonFilesForUser($userToCreate, $password);
}
}
/**
* @When /^the groupadmin "([^"]*)" tries to create new user "([^"]*)" password "([^"]*)" in other group "([^"]*)" using the provisioning API$/
*
* @param string $groupadmin
* @param string $userToCreate
* @param string|null $password
* @param string $group
*
* @return void
*/
public function theGroupAdminCreatesUserPasswordInOtherGroupUsingTheProvisioningApi(
string $groupadmin,
string $userToCreate,
?string $password,
string $group
):void {
$userToCreate = $this->getActualUsername($userToCreate);
$password = $this->getActualPassword($password);
if (OcisHelper::isTestingOnOcisOrReva()) {
$email = $userToCreate . '@owncloud.com';
$bodyTable = new TableNode(
[
['userid', $userToCreate],
['password', $userToCreate],
['username', $userToCreate],
['email', $email],
['groups[]', $group],
]
);
} else {
$email = null;
$bodyTable = new TableNode(
[['userid', $userToCreate], ['password', $password], ['groups[]', $group]]
);
}
$this->ocsContext->userSendsHTTPMethodToOcsApiEndpointWithBody(
$groupadmin,
"POST",
"/cloud/users",
$bodyTable
);
$this->addUserToCreatedUsersList(
$userToCreate,
$password,
null,
$email,
null,
$this->theHTTPStatusCodeWasSuccess()
);
}
/**
* @param string $username
* @param string|null $password
*
* @return void
*/
public function resetUserPasswordAsAdminUsingTheProvisioningApi(string $username, ?string $password):void {
$this->userResetUserPasswordUsingProvisioningApi(
$this->getAdminUsername(),
$username,
$password
);
}
/**
* @When the administrator resets the password of user :username to :password using the provisioning API
*
* @param string $username of the user whose password is reset
* @param string|null $password
*
* @return void
*/
public function adminResetsPasswordOfUserUsingTheProvisioningApi(string $username, ?string $password):void {
$this->resetUserPasswordAsAdminUsingTheProvisioningApi(
$username,
$password
);
}
/**
* @Given the administrator has reset the password of user :username to :password
*
* @param string $username of the user whose password is reset
* @param string $password
*
* @return void
*/
public function adminHasResetPasswordOfUserUsingTheProvisioningApi(string $username, ?string $password):void {
$this->resetUserPasswordAsAdminUsingTheProvisioningApi(
$username,
$password
);
$this->theHTTPStatusCodeShouldBeSuccess();
}
/**
* @param string|null $user
* @param string|null $username
* @param string|null $password
*
* @return void
*/
public function userResetUserPasswordUsingProvisioningApi(?string $user, ?string $username, ?string $password):void {
$targetUsername = $this->getActualUsername($username);
$password = $this->getActualPassword($password);
$this->userTriesToResetUserPasswordUsingTheProvisioningApi(
$user,
$targetUsername,
$password
);
$this->rememberUserPassword($targetUsername, $password);
}
/**
* @When user :user resets the password of user :username to :password using the provisioning API
*
* @param string|null $user that does the password reset
* @param string|null $username of the user whose password is reset
* @param string|null $password
*
* @return void
*/
public function userResetsPasswordOfUserUsingTheProvisioningApi(?string $user, ?string $username, ?string $password):void {
$this->userResetUserPasswordUsingProvisioningApi(
$user,
$username,
$password
);
}
/**
* @Given user :user has reset the password of user :username to :password
*
* @param string|null $user that does the password reset
* @param string|null $username of the user whose password is reset
* @param string|null $password
*
* @return void
*/
public function userHasResetPasswordOfUserUsingTheProvisioningApi(?string $user, ?string $username, ?string $password):void {
$this->userResetUserPasswordUsingProvisioningApi(
$user,
$username,
$password
);
$this->theHTTPStatusCodeShouldBeSuccess();
}
/**
* @param string|null $user
* @param string|null $username
* @param string|null $password
*
* @return void
*/
public function userTriesToResetUserPasswordUsingTheProvisioningApi(?string $user, ?string $username, ?string $password):void {
$password = $this->getActualPassword($password);
$bodyTable = new TableNode([['key', 'password'], ['value', $password]]);
$this->ocsContext->userSendsHTTPMethodToOcsApiEndpointWithBody(
$user,
"PUT",
"/cloud/users/$username",
$bodyTable
);
}
/**
* @When user :user tries to reset the password of user :username to :password using the provisioning API
*
* @param string|null $user that does the password reset
* @param string|null $username of the user whose password is reset
* @param string|null $password
*
* @return void
*/
public function userTriesToResetPasswordOfUserUsingTheProvisioningApi(?string $user, ?string $username, ?string $password):void {
$this->userTriesToResetUserPasswordUsingTheProvisioningApi(
$user,
$username,
$password
);
}
/**
* @Given user :user has tried to reset the password of user :username to :password
*
* @param string|null $user that does the password reset
* @param string|null $username of the user whose password is reset
* @param string|null $password
*
* @return void
*/
public function userHasTriedToResetPasswordOfUserUsingTheProvisioningApi(?string $user, ?string $username, ?string $password):void {
$this->userTriesToResetUserPasswordUsingTheProvisioningApi(
$user,
$username,
$password
);
$this->theHTTPStatusCodeShouldBeSuccess();
}
/**
* @Given /^the administrator has deleted user "([^"]*)" using the provisioning API$/
*
* @param string|null $user
*
* @return void
* @throws Exception
*/
public function theAdministratorHasDeletedUserUsingTheProvisioningApi(?string $user):void {
$user = $this->getActualUsername($user);
$this->deleteTheUserUsingTheProvisioningApi($user);
WebDavHelper::removeSpaceIdReferenceForUser($user);
$this->userShouldNotExist($user);
}
/**
* @When /^the administrator deletes user "([^"]*)" using the provisioning API$/
*
* @param string $user
*
* @return void
* @throws Exception
*/
public function theAdminDeletesUserUsingTheProvisioningApi(string $user):void {
$user = $this->getActualUsername($user);
$this->deleteTheUserUsingTheProvisioningApi($user);
$this->rememberThatUserIsNotExpectedToExist($user);
}
/**
* @When the administrator deletes the following users using the provisioning API
*
* @param TableNode $table
*
* @return void
* @throws Exception
*/
public function theAdministratorDeletesTheFollowingUsersUsingTheProvisioningApi(TableNode $table):void {
$this->verifyTableNodeColumns($table, ["username"]);
$usernames = $table->getHash();
foreach ($usernames as $username) {
$this->theAdminDeletesUserUsingTheProvisioningApi($username["username"]);
}
}
/**
* @When user :user deletes user :otherUser using the provisioning API
*
* @param string $user
* @param string $otherUser
*
* @return void
* @throws Exception
*/
public function userDeletesUserUsingTheProvisioningApi(
string $user,
string $otherUser
):void {
$actualUser = $this->getActualUsername($user);
$actualPassword = $this->getUserPassword($actualUser);
$actualOtherUser = $this->getActualUsername($otherUser);
$this->response = UserHelper::deleteUser(
$this->getBaseUrl(),
$actualOtherUser,
$actualUser,
$actualPassword,
$this->getStepLineRef(),
$this->ocsApiVersion
);
}
/**
* @When /^the administrator changes the email of user "([^"]*)" to "([^"]*)" using the provisioning API$/
*
* @param string $user
* @param string $email
*
* @return void
* @throws Exception
*/
public function adminChangesTheEmailOfUserToUsingTheProvisioningApi(
string $user,
string $email
):void {
$user = $this->getActualUsername($user);
$this->response = UserHelper::editUser(
$this->getBaseUrl(),
$user,
'email',
$email,
$this->getAdminUsername(),
$this->getAdminPassword(),
$this->getStepLineRef(),
$this->ocsApiVersion
);
$this->rememberUserEmailAddress($user, $email);
}
/**
* @Given /^the administrator has changed the email of user "([^"]*)" to "([^"]*)"$/
*
* @param string $user
* @param string $email
*
* @return void
* @throws Exception
*/
public function adminHasChangedTheEmailOfUserTo(string $user, string $email):void {
if (OcisHelper::isTestingWithGraphApi()) {
$this->graphContext->userHasBeenEditedUsingTheGraphApi(
$user,
null,
null,
$email
);
$updatedUserData = $this->getJsonDecodedResponse();
Assert::assertEquals(
$email,
$updatedUserData['mail']
);
} else {
$this->adminChangesTheEmailOfUserToUsingTheProvisioningApi(
$user,
$email
);
$this->theHTTPStatusCodeShouldBe(
200,
"could not change email of user $user"
);
}
}
/**
* @Given the administrator has changed their own email address to :email
*
* @param string|null $email
*
* @return void
* @throws Exception
*/
public function theAdministratorHasChangedTheirOwnEmailAddressTo(?string $email):void {
$admin = $this->getAdminUsername();
$this->adminHasChangedTheEmailOfUserTo($admin, $email);
}
/**
* @param string $requestingUser
* @param string $targetUser
* @param string $email
*
* @return void
* @throws JsonException
*/
public function userChangesUserEmailUsingProvisioningApi(
string $requestingUser,
string $targetUser,
string $email
):void {
$this->response = UserHelper::editUser(
$this->getBaseUrl(),
$this->getActualUsername($targetUser),
'email',
$email,
$this->getActualUsername($requestingUser),
$this->getPasswordForUser($requestingUser),
$this->getStepLineRef(),
$this->ocsApiVersion
);
}
/**
* @When /^user "([^"]*)" changes the email of user "([^"]*)" to "([^"]*)" using the provisioning API$/
*
* @param string $requestingUser
* @param string $targetUser
* @param string $email
*
* @return void
* @throws Exception
*/
public function userChangesTheEmailOfUserUsingTheProvisioningApi(
string $requestingUser,
string $targetUser,
string $email
):void {
$this->userTriesToChangeTheEmailOfUserUsingTheProvisioningApi(
$requestingUser,
$targetUser,
$email
);
$targetUser = $this->getActualUsername($targetUser);
$this->rememberUserEmailAddress($targetUser, $email);
$this->pushToLastStatusCodesArrays();
}
/**
* @When /^user "([^"]*)" tries to change the email of user "([^"]*)" to "([^"]*)" using the provisioning API$/
*
* @param string $requestingUser
* @param string $targetUser
* @param string $email
*
* @return void
*/
public function userTriesToChangeTheEmailOfUserUsingTheProvisioningApi(
string $requestingUser,
string $targetUser,
string $email
):void {
$requestingUser = $this->getActualUsername($requestingUser);
$targetUser = $this->getActualUsername($targetUser);
$this->userChangesUserEmailUsingProvisioningApi(
$requestingUser,
$targetUser,
$email
);
}
/**
* @Given /^user "([^"]*)" has changed the email of user "([^"]*)" to "([^"]*)"$/
*
* @param string $requestingUser
* @param string $targetUser
* @param string $email
*
* @return void
* @throws Exception
*/
public function userHasChangedTheEmailOfUserUsingTheProvisioningApi(
string $requestingUser,
string $targetUser,
string $email
):void {
$requestingUser = $this->getActualUsername($requestingUser);
$targetUser = $this->getActualUsername($targetUser);
if (OcisHelper::isTestingWithGraphApi()) {
$this->graphContext->userHasBeenEditedUsingTheGraphApi(
$targetUser,
null,
null,
$email,
null,
$requestingUser,
$this->getPasswordForUser($requestingUser)
);
$updatedUserData = $this->getJsonDecodedResponse();
Assert::assertEquals(
$email,
$updatedUserData['mail'],
);
} else {
$this->userChangesUserEmailUsingProvisioningApi(
$requestingUser,
$targetUser,
$email
);
$this->theHTTPStatusCodeShouldBeSuccess();
}
$this->rememberUserEmailAddress($targetUser, $email);
}
/**
* Edit the "display name" of a user by sending the key "displayname" to the API end point.
*
* This is the newer and consistent key name.
*
* @see https://github.com/owncloud/core/pull/33040
*
* @When /^the administrator changes the display name of user "([^"]*)" to "([^"]*)" using the provisioning API$/
*
* @param string $user
* @param string $displayName
*
* @return void
* @throws Exception
*/
public function adminChangesTheDisplayNameOfUserUsingTheProvisioningApi(
string $user,
string $displayName
):void {
$user = $this->getActualUsername($user);
$this->adminChangesTheDisplayNameOfUserUsingKey(
$user,
'displayname',
$displayName
);
$this->rememberUserDisplayName($user, $displayName);
}
/**
* @Given /^the administrator has changed the display name of user "([^"]*)" to "([^"]*)"$/
*
* @param string $user
* @param string $displayName
*
* @return void
* @throws Exception
*/
public function adminHasChangedTheDisplayNameOfUser(
string $user,
string $displayName
):void {
$user = $this->getActualUsername($user);
if ($this->isTestingWithLdap()) {
$this->editLdapUserDisplayName(
$user,
$displayName
);
} elseif (OcisHelper::isTestingWithGraphApi()) {
$this->graphContext->userHasBeenEditedUsingTheGraphApi(
$user,
null,
null,
null,
$displayName
);
$updatedUserData = $this->getJsonDecodedResponse();
Assert::assertEquals(
$displayName,
$updatedUserData['displayName']
);
} else {
$this->adminChangesTheDisplayNameOfUserUsingKey(
$user,
'displayname',
$displayName
);
$response = UserHelper::getUser(
$this->getBaseUrl(),
$user,
$this->getAdminUsername(),
$this->getAdminPassword(),
$this->getStepLineRef()
);
$this->setResponse($response);
$this->theDisplayNameReturnedByTheApiShouldBe($displayName);
}
$this->rememberUserDisplayName($user, $displayName);
}
/**
* As the administrator, edit the "display name" of a user by sending the key "display" to the API end point.
*
* This is the older and inconsistent key name, which remains for backward-compatibility.
*
* @see https://github.com/owncloud/core/pull/33040
*
* @When /^the administrator changes the display of user "([^"]*)" to "([^"]*)" using the provisioning API$/
*
* @param string $user
* @param string $displayName
*
* @return void
* @throws Exception
*/
public function adminChangesTheDisplayOfUserUsingTheProvisioningApi(
string $user,
string $displayName
):void {
$user = $this->getActualUsername($user);
$this->adminChangesTheDisplayNameOfUserUsingKey(
$user,
'display',
$displayName
);
$this->rememberUserDisplayName($user, $displayName);
}
/**
*
* @param string $user
* @param string $key
* @param string $displayName
*
* @return void
* @throws Exception
*/
public function adminChangesTheDisplayNameOfUserUsingKey(
string $user,
string $key,
string $displayName
):void {
$result = UserHelper::editUser(
$this->getBaseUrl(),
$this->getActualUsername($user),
$key,
$displayName,
$this->getAdminUsername(),
$this->getAdminPassword(),
$this->getStepLineRef(),
$this->ocsApiVersion
);
$this->response = $result;
if ($result->getStatusCode() !== 200) {
throw new Exception(
__METHOD__ . " could not change display name of user using key $key "
. $result->getStatusCode() . " " . $result->getBody()
);
}
}
/**
* As a user, edit the "display name" of a user by sending the key "displayname" to the API end point.
*
* This is the newer and consistent key name.
*
* @see https://github.com/owncloud/core/pull/33040
*
* @When /^user "([^"]*)" changes the display name of user "([^"]*)" to "([^"]*)" using the provisioning API$/
*
* @param string $requestingUser
* @param string $targetUser
* @param string $displayName
*
* @return void
* @throws Exception
*/
public function userChangesTheDisplayNameOfUserUsingTheProvisioningApi(
string $requestingUser,
string $targetUser,
string $displayName
):void {
$this->userTriesToChangeTheDisplayNameOfUserUsingTheProvisioningApi(
$requestingUser,
$targetUser,
$displayName
);
$targetUser = $this->getActualUsername($targetUser);
$this->rememberUserDisplayName($targetUser, $displayName);
}
/**
* As a user, try to edit the "display name" of a user by sending the key "displayname" to the API end point.
*
* This is the newer and consistent key name.
*
* @see https://github.com/owncloud/core/pull/33040
*
* @When /^user "([^"]*)" tries to change the display name of user "([^"]*)" to "([^"]*)" using the provisioning API$/
*
* @param string $requestingUser
* @param string $targetUser
* @param string $displayName
*
* @return void
*/
public function userTriesToChangeTheDisplayNameOfUserUsingTheProvisioningApi(
string $requestingUser,
string $targetUser,
string $displayName
):void {
$requestingUser = $this->getActualUsername($requestingUser);
$targetUser = $this->getActualUsername($targetUser);
$this->userChangesTheDisplayNameOfUserUsingKey(
$requestingUser,
$targetUser,
'displayname',
$displayName
);
$this->pushToLastStatusCodesArrays();
}
/**
* As a user, edit the "display name" of a user by sending the key "display" to the API end point.
*
* This is the older and inconsistent key name.
*
* @see https://github.com/owncloud/core/pull/33040
*
* @When /^user "([^"]*)" changes the display of user "([^"]*)" to "([^"]*)" using the provisioning API$/
*
* @param string $requestingUser
* @param string $targetUser
* @param string $displayName
*
* @return void
* @throws Exception
*/
public function userChangesTheDisplayOfUserUsingTheProvisioningApi(
string $requestingUser,
string $targetUser,
string $displayName
):void {
$requestingUser = $this->getActualUsername($requestingUser);
$targetUser = $this->getActualUsername($targetUser);
$this->userChangesTheDisplayNameOfUserUsingKey(
$requestingUser,
$targetUser,
'display',
$displayName
);
$this->rememberUserDisplayName($targetUser, $displayName);
$this->pushToLastStatusCodesArrays();
}
/**
* @Given /^user "([^"]*)" has changed the display name of user "([^"]*)" to "([^"]*)"$/
*
* @param string $requestingUser
* @param string $targetUser
* @param string $displayName
*
* @return void
* @throws Exception
*/
public function userHasChangedTheDisplayNameOfUserUsingTheProvisioningApi(
string $requestingUser,
string $targetUser,
string $displayName
):void {
$requestingUser = $this->getActualUsername($requestingUser);
$targetUser = $this->getActualUsername($targetUser);
if (OcisHelper::isTestingWithGraphApi()) {
$this->graphContext->userHasBeenEditedUsingTheGraphApi(
$targetUser,
null,
null,
null,
$displayName,
$requestingUser,
$this->getPasswordForUser($requestingUser)
);
$updatedUserData = $this->getJsonDecodedResponse();
Assert::assertEquals(
$displayName,
$updatedUserData['displayName']
);
} else {
$this->userChangesTheDisplayNameOfUserUsingKey(
$requestingUser,
$targetUser,
'displayname',
$displayName
);
$this->theHTTPStatusCodeShouldBeSuccess();
}
$this->rememberUserDisplayName($targetUser, $displayName);
}
/**
*
* @param string $requestingUser
* @param string $targetUser
* @param string $key
* @param string $displayName
*
* @return void
*/
public function userChangesTheDisplayNameOfUserUsingKey(
string $requestingUser,
string $targetUser,
string $key,
string $displayName
):void {
$result = UserHelper::editUser(
$this->getBaseUrl(),
$this->getActualUsername($targetUser),
$key,
$displayName,
$this->getActualUsername($requestingUser),
$this->getPasswordForUser($requestingUser),
$this->getStepLineRef(),
$this->ocsApiVersion
);
$this->response = $result;
}
/**
* @When /^the administrator changes the quota of user "([^"]*)" to "([^"]*)" using the provisioning API$/
*
* @param string $user
* @param string $quota
*
* @return void
*/
public function adminChangesTheQuotaOfUserUsingTheProvisioningApi(
string $user,
string $quota
):void {
$result = UserHelper::editUser(
$this->getBaseUrl(),
$this->getActualUsername($user),
'quota',
$quota,
$this->getAdminUsername(),
$this->getAdminPassword(),
$this->getStepLineRef(),
$this->ocsApiVersion
);
$this->response = $result;
}
/**
* @Given /^the administrator has (?:changed|set) the quota of user "([^"]*)" to "([^"]*)"$/
*
* @param string $user
* @param string $quota
*
* @return void
*/
public function adminHasChangedTheQuotaOfUserTo(
string $user,
string $quota
):void {
$user = $this->getActualUsername($user);
$this->adminChangesTheQuotaOfUserUsingTheProvisioningApi(
$user,
$quota
);
$this->theHTTPStatusCodeShouldBe(
200,
"could not change quota of user $user"
);
}
/**
* @param string $requestingUser
* @param string $targetUser
* @param string $quota
*
* @return void
*/
public function userChangeQuotaOfUserUsingProvisioningApi(
string $requestingUser,
string $targetUser,
string $quota
):void {
$result = UserHelper::editUser(
$this->getBaseUrl(),
$this->getActualUsername($targetUser),
'quota',
$quota,
$this->getActualUsername($requestingUser),
$this->getPasswordForUser($requestingUser),
$this->getStepLineRef(),
$this->ocsApiVersion
);
$this->response = $result;
}
/**
* @When /^user "([^"]*)" changes the quota of user "([^"]*)" to "([^"]*)" using the provisioning API$/
*
* @param string $requestingUser
* @param string $targetUser
* @param string $quota
*
* @return void
*/
public function userChangesTheQuotaOfUserUsingTheProvisioningApi(
string $requestingUser,
string $targetUser,
string $quota
):void {
$this->userChangeQuotaOfUserUsingProvisioningApi(
$requestingUser,
$targetUser,
$quota
);
$this->pushToLastStatusCodesArrays();
}
/**
* @Given /^user "([^"]*)" has changed the quota of user "([^"]*)" to "([^"]*)"$/
*
* @param string $requestingUser
* @param string $targetUser
* @param string $quota
*
* @return void
*/
public function userHasChangedTheQuotaOfUserUsingTheProvisioningApi(
string $requestingUser,
string $targetUser,
string $quota
):void {
$this->userChangeQuotaOfUserUsingProvisioningApi(
$requestingUser,
$targetUser,
$quota
);
$this->theHTTPStatusCodeShouldBeSuccess();
}
/**
* @param string $user
*
* @return void
* @throws JsonException
*/
public function retrieveUserInformationAsAdminUsingProvisioningApi(
string $user
):void {
$result = UserHelper::getUser(
$this->getBaseUrl(),
$this->getActualUsername($user),
$this->getAdminUsername(),
$this->getAdminPassword(),
$this->getStepLineRef(),
$this->ocsApiVersion
);
$this->response = $result;
}
/**
* @When /^the administrator retrieves the information of user "([^"]*)" using the provisioning API$/
*
* @param string $user
*
* @return void
* @throws JsonException
*/
public function adminRetrievesTheInformationOfUserUsingTheProvisioningApi(
string $user
):void {
$user = $this->getActualUsername($user);
$this->retrieveUserInformationAsAdminUsingProvisioningApi(
$user
);
}
/**
* @Given /^the administrator has retrieved the information of user "([^"]*)"$/
*
* @param string $user
*
* @return void
* @throws JsonException
*/
public function adminHasRetrievedTheInformationOfUserUsingTheProvisioningApi(
string $user
):void {
if (OcisHelper::isTestingWithGraphApi()) {
$this->graphContext->adminHasRetrievedUserUsingTheGraphApi($user);
} else {
$this->retrieveUserInformationAsAdminUsingProvisioningApi($user);
$this->theHTTPStatusCodeShouldBeSuccess();
}
}
/**
* @param string $requestingUser
* @param string $targetUser
*
* @return void
* @throws JsonException
*/
public function userRetrieveUserInformationUsingProvisioningApi(
string $requestingUser,
string $targetUser
):void {
$result = UserHelper::getUser(
$this->getBaseUrl(),
$this->getActualUsername($targetUser),
$this->getActualUsername($requestingUser),
$this->getPasswordForUser($requestingUser),
$this->getStepLineRef(),
$this->ocsApiVersion
);
$this->response = $result;
}
/**
* @When /^user "([^"]*)" retrieves the information of user "([^"]*)" using the provisioning API$/
*
* @param string $requestingUser
* @param string $targetUser
*
* @return void
* @throws JsonException
*/
public function userRetrievesTheInformationOfUserUsingTheProvisioningApi(
string $requestingUser,
string $targetUser
):void {
$this->userRetrieveUserInformationUsingProvisioningApi(
$requestingUser,
$targetUser
);
}
/**
* @Given /^user "([^"]*)" has retrieved the information of user "([^"]*)"$/
*
* @param string $requestingUser
* @param string $targetUser
*
* @return void
* @throws JsonException
*/
public function userHasRetrievedTheInformationOfUserUsingTheProvisioningApi(
string $requestingUser,
string $targetUser
):void {
if (OcisHelper::isTestingWithGraphApi()) {
$this->graphContext->userHasRetrievedUserUsingTheGraphApi(
$requestingUser,
$targetUser
);
} else {
$this->userRetrieveUserInformationUsingProvisioningApi(
$requestingUser,
$targetUser
);
$this->theHTTPStatusCodeShouldBeSuccess();
}
}
/**
* @Then /^user "([^"]*)" should exist$/
*
* @param string $user
*
* @return void
* @throws JsonException
*/
public function userShouldExist(string $user):void {
$user = $this->getActualUsername($user);
Assert::assertTrue(
$this->userExists($user),
"User '$user' should exist but does not exist"
);
}
/**
* @Then the following users should exist
*
* @param TableNode $table
*
* @return void
* @throws Exception
*/
public function theFollowingUsersShouldExist(TableNode $table):void {
$this->verifyTableNodeColumns($table, ["username"]);
$usernames = $table->getHash();
foreach ($usernames as $username) {
$this->userShouldExist($username["username"]);
}
}
/**
* @Then /^user "([^"]*)" should not exist$/
*
* @param string $user
*
* @return void
* @throws JsonException
*/
public function userShouldNotExist(string $user):void {
$user = $this->getActualUsername($user);
Assert::assertFalse(
$this->userExists($user),
"User '$user' should not exist but does exist"
);
$this->rememberThatUserIsNotExpectedToExist($user);
}
/**
* @Then the following users should not exist
*
* @param TableNode $table
*
* @return void
* @throws Exception
*/
public function theFollowingUsersShouldNotExist(TableNode $table):void {
$this->verifyTableNodeColumns($table, ["username"]);
$usernames = $table->getHash();
foreach ($usernames as $username) {
$this->userShouldNotExist($username["username"]);
}
}
/**
* @Then /^group "([^"]*)" should exist$/
*
* @param string $group
*
* @return void
* @throws Exception
* @throws GuzzleException
*/
public function groupShouldExist(string $group):void {
Assert::assertTrue(
$this->groupExists($group),
"Group '$group' should exist but does not exist"
);
}
/**
* @Then /^group "([^"]*)" should not exist$/
*
* @param string $group
*
* @return void
* @throws Exception
* @throws GuzzleException
*/
public function groupShouldNotExist(string $group):void {
Assert::assertFalse(
$this->groupExists($group),
"Group '$group' should not exist but does exist"
);
}
/**
* @Then the following groups should not exist
*
* @param TableNode $table
*
* @return void
* @throws Exception
*/
public function theFollowingGroupsShouldNotExist(TableNode $table):void {
$this->verifyTableNodeColumns($table, ["groupname"]);
$groups = $table->getHash();
foreach ($groups as $group) {
$this->groupShouldNotExist($group["groupname"]);
}
}
/**
* @Then /^these groups should (not|)\s?exist:$/
* expects a table of groups with the heading "groupname"
*
* @param string $shouldOrNot (not|)
* @param TableNode $table
*
* @return void
* @throws Exception
*/
public function theseGroupsShouldNotExist(string $shouldOrNot, TableNode $table):void {
$should = ($shouldOrNot !== "not");
$this->verifyTableNodeColumns($table, ['groupname']);
$useGraph = OcisHelper::isTestingWithGraphApi();
if ($useGraph) {
$this->graphContext->theseGroupsShouldNotExist($shouldOrNot, $table);
} else {
$groups = $this->getArrayOfGroupsResponded($this->getAllGroups());
foreach ($table as $row) {
if (\in_array($row['groupname'], $groups, true) !== $should) {
throw new Exception(
"group '" . $row['groupname'] .
"' does" . ($should ? " not" : "") .
" exist but should" . ($should ? "" : " not")
);
}
}
}
}
/**
* @Given /^user "([^"]*)" has been deleted$/
*
* @param string $user
*
* @return void
* @throws Exception
*/
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 {
$this->deleteTheUserUsingTheProvisioningApi($user);
}
}
$this->userShouldNotExist($user);
}
/**
* @Given the following users have been deleted
*
* @param TableNode $table
*
* @return void
* @throws Exception
*/
public function theFollowingUsersHaveBeenDeleted(TableNode $table):void {
$this->verifyTableNodeColumns($table, ["username"]);
$usernames = $table->getHash();
foreach ($usernames as $username) {
$this->userHasBeenDeleted($username["username"]);
}
}
/**
* @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
);
}
}
/**
* @When the administrator gets all the members of group :group using the provisioning API
*
* @param string $group
*
* @return void
*/
public function theAdministratorGetsAllTheMembersOfGroupUsingTheProvisioningApi(string $group):void {
$this->userGetsAllTheMembersOfGroupUsingTheProvisioningApi(
$this->getAdminUsername(),
$group
);
}
/**
* @When /^user "([^"]*)" gets all the members of group "([^"]*)" using the provisioning API$/
*
* @param string $user
* @param string $group
*
* @return void
*/
public function userGetsAllTheMembersOfGroupUsingTheProvisioningApi(string $user, string $group):void {
$fullUrl = $this->getBaseUrl() . "/ocs/v{$this->ocsApiVersion}.php/cloud/groups/$group";
$this->response = HttpRequestHelper::get(
$fullUrl,
$this->getStepLineRef(),
$this->getActualUsername($user),
$this->getPasswordForUser($user)
);
}
/**
* get all the existing groups
*
* @return ResponseInterface
*/
public function getAllGroups():ResponseInterface {
$fullUrl = $this->getBaseUrl() . "/ocs/v{$this->ocsApiVersion}.php/cloud/groups";
return HttpRequestHelper::get(
$fullUrl,
$this->getStepLineRef(),
$this->getAdminUsername(),
$this->getAdminPassword()
);
}
/**
* @When the administrator gets all the groups using the provisioning API
*
* @return void
*/
public function theAdministratorGetsAllTheGroupsUsingTheProvisioningApi():void {
$this->response = $this->getAllGroups();
}
/**
* @When /^user "([^"]*)" tries to get all the groups using the provisioning API$/
* @When /^user "([^"]*)" gets all the groups using the provisioning API$/
*
* @param string $user
*
* @return void
* @throws Exception
*/
public function userTriesToGetAllTheGroupsUsingTheProvisioningApi(string $user):void {
$fullUrl = $this->getBaseUrl() . "/ocs/v{$this->ocsApiVersion}.php/cloud/groups";
$actualUser = $this->getActualUsername($user);
$actualPassword = $this->getUserPassword($actualUser);
$this->response = HttpRequestHelper::get(
$fullUrl,
$this->getStepLineRef(),
$actualUser,
$actualPassword
);
}
/**
* @When the administrator gets all the groups of user :user using the provisioning API
*
* @param string $user
*
* @return void
* @throws Exception
*/
public function theAdministratorGetsAllTheGroupsOfUser(string $user):void {
$this->userGetsAllTheGroupsOfUser($this->getAdminUsername(), $user);
}
/**
* @When user :user gets all the groups of user :otherUser using the provisioning API
*
* @param string $user
* @param string $otherUser
*
* @return void
* @throws Exception
*/
public function userGetsAllTheGroupsOfUser(string $user, string $otherUser):void {
$actualOtherUser = $this->getActualUsername($otherUser);
$fullUrl = $this->getBaseUrl() . "/ocs/v{$this->ocsApiVersion}.php/cloud/users/$actualOtherUser/groups";
$actualUser = $this->getActualUsername($user);
$actualPassword = $this->getUserPassword($actualUser);
$this->response = HttpRequestHelper::get(
$fullUrl,
$this->getStepLineRef(),
$actualUser,
$actualPassword
);
}
/**
* @When the administrator gets the list of all users using the provisioning API
*
* @return void
*/
public function theAdministratorGetsTheListOfAllUsersUsingTheProvisioningApi():void {
$this->userGetsTheListOfAllUsersUsingTheProvisioningApi($this->getAdminUsername());
}
/**
* @When user :user gets the list of all users using the provisioning API
*
* @param string $user
*
* @return void
* @throws Exception
*/
public function userGetsTheListOfAllUsersUsingTheProvisioningApi(string $user):void {
$fullUrl = $this->getBaseUrl() . "/ocs/v{$this->ocsApiVersion}.php/cloud/users";
$actualUser = $this->getActualUsername($user);
$actualPassword = $this->getUserPassword($actualUser);
$this->response = HttpRequestHelper::get(
$fullUrl,
$this->getStepLineRef(),
$actualUser,
$actualPassword
);
}
/**
* Make a request about the user. That will force the server to fully
* initialize the user, including their skeleton files.
*
* @param string $user
* @param string $password
*
* @return void
*/
public function initializeUser(string $user, string $password):void {
$url = $this->getBaseUrl()
. "/ocs/v{$this->ocsApiVersion}.php/cloud/users/$user";
HttpRequestHelper::get(
$url,
$this->getStepLineRef(),
$user,
$password
);
$this->lastUploadTime = \time();
}
/**
* Touch an API end-point for each user so that their file-system gets setup
*
* @param array $users
*
* @return void
* @throws Exception
*/
public function initializeUsers(array $users):void {
$url = "/cloud/users/%s";
foreach ($users as $user) {
$response = OcsApiHelper::sendRequest(
$this->getBaseUrl(),
$user,
$this->getPasswordForUser($user),
'GET',
\sprintf($url, $user),
$this->getStepLineRef()
);
$this->setResponse($response);
$this->theHTTPStatusCodeShouldBe(200);
}
}
/**
* adds a user to the list of users that were created during test runs
* makes it possible to use this list in other test steps
* or to delete them at the end of the test
*
* @param string|null $user
* @param string|null $password
* @param string|null $displayName
* @param string|null $email
* @param string|null $userId only set for the users created using the Graph API
* @param bool $shouldExist
*
* @return void
* @throws JsonException
*/
public function addUserToCreatedUsersList(
?string $user,
?string $password,
?string $displayName = null,
?string $email = null,
?string $userId = null,
bool $shouldExist = true
):void {
$user = $this->getActualUsername($user);
$normalizedUsername = $this->normalizeUsername($user);
$userData = [
"password" => $password,
"displayname" => $displayName,
"email" => $email,
"shouldExist" => $shouldExist,
"actualUsername" => $user,
"id" => $userId
];
if ($this->currentServer === 'LOCAL') {
// Only remember this user creation if it was expected to have been successful
// or the user has not been processed before. Some tests create a user the
// first time (successfully) and then purposely try to create the user again.
// The 2nd user creation is expected to fail, and in that case we want to
// still remember the details of the first user creation.
if ($shouldExist || !\array_key_exists($normalizedUsername, $this->createdUsers)) {
$this->createdUsers[$normalizedUsername] = $userData;
}
} elseif ($this->currentServer === 'REMOTE') {
// See comment above about the LOCAL case. The logic is the same for the remote case.
if ($shouldExist || !\array_key_exists($normalizedUsername, $this->createdRemoteUsers)) {
$this->createdRemoteUsers[$normalizedUsername] = $userData;
}
}
}
/**
* remember the password of a user that already exists so that you can use
* ordinary test steps after changing their password.
*
* @param string $user
* @param string $password
*
* @return void
*/
public function rememberUserPassword(
string $user,
string $password
):void {
$normalizedUsername = $this->normalizeUsername($user);
if ($this->currentServer === 'LOCAL') {
if (\array_key_exists($normalizedUsername, $this->createdUsers)) {
$this->createdUsers[$normalizedUsername]['password'] = $password;
}
} elseif ($this->currentServer === 'REMOTE') {
if (\array_key_exists($normalizedUsername, $this->createdRemoteUsers)) {
$this->createdRemoteUsers[$user]['password'] = $password;
}
}
}
/**
* Remembers that a user from the list of users that were created during
* test runs is no longer expected to exist. Useful if a user was created
* during the setup phase but was deleted in a test run. We don't expect
* this user to exist in the tear-down phase, so remember that fact.
*
* @param string $user
*
* @return void
*/
public function rememberThatUserIsNotExpectedToExist(string $user):void {
$user = $this->getActualUsername($user);
$normalizedUsername = $this->normalizeUsername($user);
if (\array_key_exists($normalizedUsername, $this->createdUsers)) {
$this->createdUsers[$normalizedUsername]['shouldExist'] = false;
}
}
/**
* creates a single user
*
* @param string|null $user
* @param string|null $password if null, then select a password
* @param string|null $displayName
* @param string|null $email
* @param bool $initialize initialize the user skeleton files etc
* @param string|null $method how to create the user api|occ, default api
* @param bool $setDefault sets the missing values to some default
* @param bool $skeleton
*
* @return void
* @throws Exception
*/
public function createUser(
?string $user,
?string $password = null,
?string $displayName = null,
?string $email = null,
bool $initialize = true,
?string $method = null,
bool $setDefault = true,
bool $skeleton = true
):void {
$userId = null;
if ($password === null) {
$password = $this->getPasswordForUser($user);
}
if ($displayName === null && $setDefault === true) {
$displayName = $this->getDisplayNameForUser($user);
if ($displayName === null) {
$displayName = $this->getDisplayNameForUser('regularuser');
}
}
if ($email === null && $setDefault === true) {
$email = $this->getEmailAddressForUser($user);
if ($email === null) {
// escape @ & space if present in userId
$email = \str_replace(["@", " "], "", $user) . '@owncloud.com';
}
}
$user = $this->getActualUsername($user);
if ($method === null && $this->isTestingWithLdap()) {
//guess yourself
$method = "ldap";
} elseif (OcisHelper::isTestingWithGraphApi()) {
$method = "graph";
} elseif ($method === null) {
$method = "api";
}
$user = \trim($user);
$method = \trim(\strtolower($method));
switch ($method) {
case "occ":
$result = SetupHelper::createUser(
$user,
$password,
$this->getStepLineRef(),
$displayName,
$email
);
if ($result["code"] !== "0") {
throw new Exception(
__METHOD__ . " could not create user. {$result['stdOut']} {$result['stdErr']}"
);
}
break;
case "api":
case "ldap":
$settings = [];
$setting["userid"] = $user;
$setting["displayName"] = $displayName;
$setting["password"] = $password;
$setting["email"] = $email;
\array_push($settings, $setting);
try {
$this->usersHaveBeenCreated(
$initialize,
$settings,
$method,
$skeleton
);
} catch (LdapException $exception) {
throw new Exception(
__METHOD__ . " cannot create a LDAP user with provided data. Error: {$exception}"
);
}
break;
case "graph":
$this->graphContext->theAdminHasCreatedUser(
$user,
$password,
$email,
$displayName,
);
$newUser = $this->getJsonDecodedResponse();
$userId = $newUser['id'];
break;
default:
throw new InvalidArgumentException(
__METHOD__ . " Invalid method to create a user"
);
}
$this->addUserToCreatedUsersList($user, $password, $displayName, $email, $userId);
if ($initialize) {
$this->initializeUser($user, $password);
}
}
/**
* @param string $user
*
* @return void
* @throws Exception
*/
public function deleteUser(string $user):void {
$this->deleteTheUserUsingTheProvisioningApi($user);
$this->userShouldNotExist($user);
}
/**
* Try to delete the group, catching anything bad that might happen.
* Use this method only in places where you want to try as best you
* can to delete the group, but do not want to error if there is a problem.
*
* @param string $group
*
* @return void
* @throws Exception
*/
public function cleanupGroup(string $group):void {
try {
if (OcisHelper::isTestingWithGraphApi()) {
$this->graphContext->adminHasDeletedGroupUsingTheGraphApi($group);
} else {
$this->deleteTheGroupUsingTheProvisioningApi($group);
}
} catch (Exception $e) {
\error_log(
"INFORMATION: There was an unexpected problem trying to delete group " .
"'$group' message '" . $e->getMessage() . "'"
);
}
if ($this->theGroupShouldBeAbleToBeDeleted($group)
&& $this->groupExists($group)
) {
\error_log(
"INFORMATION: tried to delete group '$group'" .
" at the end of the scenario but it seems to still exist. " .
"There might be problems with later scenarios."
);
}
}
/**
* @param string|null $user
*
* @return bool
* @throws JsonException
*/
public function userExists(?string $user):bool {
// in OCIS there is no admin user and in oC10 there are issues when
// sending the username in lowercase in the auth but in uppercase in
// the URL see https://github.com/owncloud/core/issues/36822
$user = $this->getActualUsername($user);
if (OcisHelper::isTestingOnOcisOrReva()) {
// In OCIS an intermittent issue restricts users to list their own account
// So use admin account to list the user
// https://github.com/owncloud/ocis/issues/820
// The special code can be reverted once the issue is fixed
if (OcisHelper::isTestingParallelDeployment()) {
$requestingUser = $this->getActualUsername($user);
$requestingPassword = $this->getPasswordForUser($user);
} elseif (OcisHelper::isTestingWithGraphApi()) {
$requestingUser = $this->getAdminUsername();
$requestingPassword = $this->getAdminPassword();
} elseif (OcisHelper::isTestingOnOcis()) {
$requestingUser = 'moss';
$requestingPassword = 'vista';
} else {
$requestingUser = $this->getActualUsername($user);
$requestingPassword = $this->getPasswordForUser($requestingUser);
}
} else {
$requestingUser = $this->getAdminUsername();
$requestingPassword = $this->getAdminPassword();
}
$path = (OcisHelper::isTestingWithGraphApi())
? "/graph/v1.0"
: "/ocs/v2.php/cloud";
$fullUrl = $this->getBaseUrl() . $path . "/users/$user";
$this->response = HttpRequestHelper::get(
$fullUrl,
$this->getStepLineRef(),
$requestingUser,
$requestingPassword
);
if ($this->response->getStatusCode() >= 400) {
return false;
}
return true;
}
/**
* @Then /^user "([^"]*)" should belong to group "([^"]*)"$/
*
* @param string $user
* @param string $group
*
* @return void
* @throws Exception
*/
public function userShouldBelongToGroup(string $user, string $group):void {
$user = $this->getActualUsername($user);
$respondedArray = [];
if (OcisHelper::isTestingWithGraphApi()) {
$this->graphContext->userShouldBeMemberInGroupUsingTheGraphApi(
$user,
$group
);
} else {
$this->theAdministratorGetsAllTheGroupsOfUser($user);
$respondedArray = $this->getArrayOfGroupsResponded($this->response);
\sort($respondedArray);
Assert::assertContains(
$group,
$respondedArray,
__METHOD__ . " Group '$group' does not exist in '"
. \implode(', ', $respondedArray)
. "'"
);
Assert::assertEquals(
200,
$this->response->getStatusCode(),
__METHOD__
. " Expected status code is '200' but got '"
. $this->response->getStatusCode()
. "'"
);
}
}
/**
* @Then the following users should belong to the following groups
*
* @param TableNode $table
*
* @return void
* @throws Exception
*/
public function theTheFollowingUserShouldBelongToTheFollowingGroup(TableNode $table):void {
$this->verifyTableNodeColumns($table, ["username", "groupname"]);
$rows = $table->getHash();
foreach ($rows as $row) {
$this->userShouldBelongToGroup($row["username"], $row["groupname"]);
}
}
/**
* @param string $group
*
* @return array
*/
public function getUsersOfLdapGroup(string $group):array {
$ou = $this->getLdapGroupsOU();
$entry = 'cn=' . $group . ',ou=' . $ou . ',' . $this->ldapBaseDN;
$ldapResponse = $this->ldap->getEntry($entry);
return $ldapResponse["memberuid"];
}
/**
* @Then /^user "([^"]*)" should not belong to group "([^"]*)"$/
*
* @param string $user
* @param string $group
*
* @return void
* @throws JsonException
*/
public function userShouldNotBelongToGroup(string $user, string $group):void {
$user = $this->getActualUsername($user);
if (OcisHelper::isTestingWithGraphApi()) {
$this->graphContext->userShouldNotBeMemberInGroupUsingTheGraphApi($user, $group);
} else {
$fullUrl = $this->getBaseUrl() . "/ocs/v2.php/cloud/users/$user/groups";
$this->response = HttpRequestHelper::get(
$fullUrl,
$this->getStepLineRef(),
$this->getAdminUsername(),
$this->getAdminPassword()
);
$respondedArray = $this->getArrayOfGroupsResponded($this->response);
\sort($respondedArray);
Assert::assertNotContains($group, $respondedArray);
Assert::assertEquals(
200,
$this->response->getStatusCode()
);
}
}
/**
* @Then the following users should not belong to the following groups
*
* @param TableNode $table
*
* @return void
* @throws Exception
*/
public function theTheFollowingUserShouldNotBelongToTheFollowingGroup(TableNode $table):void {
$this->verifyTableNodeColumns($table, ["username", "groupname"]);
$rows = $table->getHash();
foreach ($rows as $row) {
$this->userShouldNotBelongToGroup($row["username"], $row["groupname"]);
}
}
/**
* @Then group :group should not contain user :username
*
* @param string $group
* @param string $username
*
* @return void
*/
public function groupShouldNotContainUser(string $group, string $username):void {
$username = $this->getActualUsername($username);
$fullUrl = $this->getBaseUrl() . "/ocs/v2.php/cloud/groups/$group";
$this->response = HttpRequestHelper::get(
$fullUrl,
$this->getStepLineRef(),
$this->getAdminUsername(),
$this->getAdminPassword()
);
$this->theUsersReturnedByTheApiShouldNotInclude($username);
}
/**
* @param string $user
* @param string $group
*
* @return bool
*/
public function userBelongsToGroup(string $user, string $group):bool {
$fullUrl = $this->getBaseUrl() . "/ocs/v2.php/cloud/users/$user/groups";
$this->response = HttpRequestHelper::get(
$fullUrl,
$this->getStepLineRef(),
$this->getAdminUsername(),
$this->getAdminPassword()
);
$respondedArray = $this->getArrayOfGroupsResponded($this->response);
if (\in_array($group, $respondedArray)) {
return true;
} else {
return false;
}
}
/**
* @When /^the administrator adds user "([^"]*)" to group "([^"]*)" using the provisioning API$/
*
* @param string $user
* @param string $group
*
* @return void
* @throws Exception
*/
public function adminAddsUserToGroupUsingTheProvisioningApi(string $user, string $group):void {
$this->addUserToGroup($user, $group, "api");
}
/**
* @When the administrator adds the following users to the following groups using the provisioning API
*
* @param TableNode $table
*
* @return void
* @throws Exception
*/
public function theAdministratorAddsUserToTheFollowingGroupsUsingTheProvisioningApi(TableNode $table):void {
$this->verifyTableNodeColumns($table, ["username", "groupname"], ["comment"]);
$rows = $table->getHash();
foreach ($rows as $row) {
$this->adminAddsUserToGroupUsingTheProvisioningApi($row["username"], $row["groupname"]);
}
}
/**
* @When user :user tries to add user :otherUser to group :group using the provisioning API
*
* @param string $user
* @param string $otherUser
* @param string $group
*
* @return void
* @throws Exception
*/
public function userTriesToAddUserToGroupUsingTheProvisioningApi(string $user, string $otherUser, string $group):void {
$actualUser = $this->getActualUsername($user);
$actualPassword = $this->getUserPassword($actualUser);
$actualOtherUser = $this->getActualUsername($otherUser);
$result = UserHelper::addUserToGroup(
$this->getBaseUrl(),
$actualOtherUser,
$group,
$actualUser,
$actualPassword,
$this->getStepLineRef(),
$this->ocsApiVersion
);
$this->response = $result;
}
/**
* @When user :user tries to add himself to group :group using the provisioning API
*
* @param string $user
* @param string $group
*
* @return void
* @throws Exception
*/
public function userTriesToAddHimselfToGroupUsingTheProvisioningApi(string $user, string $group):void {
$this->userTriesToAddUserToGroupUsingTheProvisioningApi($user, $user, $group);
}
/**
* @When the administrator tries to add user :user to group :group using the provisioning API
*
* @param string $user
* @param string $group
*
* @return void
* @throws Exception
*/
public function theAdministratorTriesToAddUserToGroupUsingTheProvisioningApi(
string $user,
string $group
):void {
$this->userTriesToAddUserToGroupUsingTheProvisioningApi(
$this->getAdminUsername(),
$user,
$group
);
}
/**
* @Given /^user "([^"]*)" has been added to group "([^"]*)"$/
*
* @param string $user
* @param string $group
*
* @return void
* @throws Exception
*/
public function userHasBeenAddedToGroup(string $user, string $group):void {
$user = $this->getActualUsername($user);
$this->addUserToGroup($user, $group, null, true);
}
/**
* @Given the following users have been added to the following groups
*
* @param TableNode $table
*
* @return void
* @throws Exception
*/
public function theFollowingUserHaveBeenAddedToTheFollowingGroup(TableNode $table):void {
$this->verifyTableNodeColumns($table, ['username', 'groupname']);
foreach ($table as $row) {
$this->userHasBeenAddedToGroup($row['username'], $row['groupname']);
}
}
/**
* @Given /^user "([^"]*)" has been added to database backend group "([^"]*)"$/
*
* @param string $user
* @param string $group
*
* @return void
* @throws Exception
*/
public function userHasBeenAddedToDatabaseBackendGroup(string $user, string $group):void {
$this->addUserToGroup($user, $group, 'api', true);
}
/**
* @param string $user
* @param string $group
* @param string|null $method how to add the user to the group api|occ
* @param bool $checkResult if true, then check the status of the operation. default false.
* for given step checkResult is expected to be set as true
* for when step checkResult is expected to be set as false
*
* @return void
* @throws Exception
*/
public function addUserToGroup(string $user, string $group, ?string $method = null, bool $checkResult = false):void {
$user = $this->getActualUsername($user);
if ($method === null
&& $this->isTestingWithLdap()
&& !$this->isLocalAdminGroup($group)
) {
//guess yourself
$method = "ldap";
} elseif ($method === null && OcisHelper::isTestingWithGraphApi()) {
$method = "graph";
} elseif ($method === null) {
$method = "api";
}
$method = \trim(\strtolower($method));
switch ($method) {
case "api":
$result = UserHelper::addUserToGroup(
$this->getBaseUrl(),
$user,
$group,
$this->getAdminUsername(),
$this->getAdminPassword(),
$this->getStepLineRef(),
$this->ocsApiVersion
);
if ($checkResult && ($result->getStatusCode() !== 200)) {
throw new Exception(
"could not add user to group. "
. $result->getStatusCode() . " " . $result->getBody()
);
}
$this->response = $result;
if (!$checkResult) {
// for when step only
$this->pushToLastStatusCodesArrays();
}
break;
case "occ":
$result = SetupHelper::addUserToGroup(
$group,
$user,
$this->getStepLineRef()
);
if ($checkResult && ($result["code"] !== "0")) {
throw new Exception(
"could not add user to group. {$result['stdOut']} {$result['stdErr']}"
);
}
break;
case "ldap":
try {
$this->addUserToLdapGroup(
$user,
$group
);
} catch (LdapException $exception) {
throw new Exception(
"User " . $user . " cannot be added to " . $group . " . Error: {$exception}"
);
};
break;
case "graph":
$this->graphContext->adminHasAddedUserToGroupUsingTheGraphApi(
$user,
$group
);
break;
default:
throw new InvalidArgumentException(
"Invalid method to add a user to a group"
);
}
}
/**
* @Given the administrator has been added to group :group
*
* @param string $group
*
* @return void
* @throws Exception
*/
public function theAdministratorHasBeenAddedToGroup(string $group):void {
$admin = $this->getAdminUsername();
$this->addUserToGroup($admin, $group, null, true);
}
/**
* @param string $group
* @param bool $shouldExist - true if the group should exist
* @param bool $possibleToDelete - true if it is possible to delete the group
* @param string|null $id - id of the group, only required for the groups created using the Graph API
*
* @return void
*/
public function addGroupToCreatedGroupsList(
string $group,
bool $shouldExist = true,
bool $possibleToDelete = true,
?string $id = null
):void {
$groupData = [
"shouldExist" => $shouldExist,
"possibleToDelete" => $possibleToDelete
];
if ($id !== null) {
$groupData["id"] = $id;
}
if ($this->currentServer === 'LOCAL') {
$this->createdGroups[$group] = $groupData;
} elseif ($this->currentServer === 'REMOTE') {
$this->createdRemoteGroups[$group] = $groupData;
}
}
/**
* Remembers that a group from the list of groups that were created during
* test runs is no longer expected to exist. Useful if a group was created
* during the setup phase but was deleted in a test run. We don't expect
* this group to exist in the tear-down phase, so remember that fact.
*
* @param string $group
*
* @return void
*/
public function rememberThatGroupIsNotExpectedToExist(string $group):void {
if (\array_key_exists($group, $this->createdGroups)) {
$this->createdGroups[$group]['shouldExist'] = false;
}
}
/**
* @When /^the administrator creates group "([^"]*)" using the provisioning API$/
*
* @param string $group
*
* @return void
* @throws Exception
*/
public function adminCreatesGroupUsingTheProvisioningApi(string $group):void {
if (!$this->groupExists($group)) {
$this->createTheGroup($group, 'api');
}
$this->groupShouldExist($group);
}
/**
* @Given /^group "([^"]*)" has been created$/
*
* @param string $group
*
* @return void
* @throws Exception
* @throws GuzzleException
*/
public function groupHasBeenCreated(string $group):void {
$this->createTheGroup($group);
$this->groupShouldExist($group);
}
/**
* @Given /^group "([^"]*)" has been created in the database user backend$/
*
* @param string $group
*
* @return void
* @throws Exception
*/
public function groupHasBeenCreatedOnDatabaseBackend(string $group):void {
$this->adminCreatesGroupUsingTheProvisioningApi($group);
}
/**
* @Given these groups have been created:
* expects a table of groups with the heading "groupname"
*
* @param TableNode $table
*
* @return void
* @throws Exception
*/
public function theseGroupsHaveBeenCreated(TableNode $table):void {
$this->verifyTableNodeColumns($table, ['groupname'], ['comment']);
foreach ($table as $row) {
$this->createTheGroup($row['groupname']);
}
}
/**
* @When /^the administrator sends a group creation request for group "([^"]*)" using the provisioning API$/
*
* @param string $group
* @param string|null $user
*
* @return void
*/
public function adminSendsGroupCreationRequestUsingTheProvisioningApi(
string $group,
?string $user = null
):void {
$bodyTable = new TableNode([['groupid', $group]]);
$user = $user === null ? $this->getAdminUsername() : $user;
$this->emptyLastHTTPStatusCodesArray();
$this->emptyLastOCSStatusCodesArray();
$this->ocsContext->userSendsHTTPMethodToOcsApiEndpointWithBody(
$user,
"POST",
"/cloud/groups",
$bodyTable
);
$this->pushToLastStatusCodesArrays();
$this->addGroupToCreatedGroupsList($group);
}
/**
* @When the administrator sends a group creation request for the following groups using the provisioning API
*
* @param TableNode $table
*
* @return void
* @throws Exception
*/
public function theAdministratorSendsAGroupCreationRequestForTheFollowingGroupUsingTheProvisioningApi(TableNode $table):void {
$this->verifyTableNodeColumns($table, ["groupname"], ["comment"]);
$groups = $table->getHash();
foreach ($groups as $group) {
$this->adminSendsGroupCreationRequestUsingTheProvisioningApi($group["groupname"]);
}
}
/**
* @When /^the administrator tries to send a group creation request for group "([^"]*)" using the provisioning API$/
*
* @param string $group
*
* @return void
*/
public function adminTriesToSendGroupCreationRequestUsingTheAPI(string $group):void {
$this->adminSendsGroupCreationRequestUsingTheProvisioningApi($group);
$this->rememberThatGroupIsNotExpectedToExist($group);
}
/**
* @When /^user "([^"]*)" tries to send a group creation request for group "([^"]*)" using the provisioning API$/
*
* @param string $user
* @param string $group
*
* @return void
*/
public function userTriesToSendGroupCreationRequestUsingTheAPI(string $user, string $group):void {
$this->adminSendsGroupCreationRequestUsingTheProvisioningApi($group, $user);
$this->rememberThatGroupIsNotExpectedToExist($group);
}
/**
* creates a single group
*
* @param string $group
* @param string|null $method how to create the group api|occ
*
* @return void
* @throws Exception
*/
public function createTheGroup(string $group, ?string $method = null):void {
//guess yourself
if ($method === null) {
if ($this->isTestingWithLdap()) {
$method = "ldap";
} elseif (OcisHelper::isTestingWithGraphApi()) {
$method = "graph";
} else {
$method = "api";
}
}
$group = \trim($group);
$method = \trim(\strtolower($method));
$groupCanBeDeleted = false;
$groupId = null;
switch ($method) {
case "api":
$result = UserHelper::createGroup(
$this->getBaseUrl(),
$group,
$this->getAdminUsername(),
$this->getAdminPassword(),
$this->getStepLineRef()
);
if ($result->getStatusCode() === 200) {
$groupCanBeDeleted = true;
} else {
throw new Exception(
"could not create group '$group'. "
. $result->getStatusCode() . " " . $result->getBody()
);
}
break;
case "occ":
$result = SetupHelper::createGroup(
$group,
$this->getStepLineRef()
);
if ($result["code"] == 0) {
$groupCanBeDeleted = true;
} else {
throw new Exception(
"could not create group '$group'. {$result['stdOut']} {$result['stdErr']}"
);
}
break;
case "ldap":
try {
$this->createLdapGroup($group);
} catch (LdapException $e) {
throw new Exception(
"could not create group '$group'. Error: {$e}"
);
}
break;
case "graph":
$newGroup = $this->graphContext->adminHasCreatedGroupUsingTheGraphApi($group);
$groupCanBeDeleted = true;
$groupId = $newGroup["id"];
break;
default:
throw new InvalidArgumentException(
"Invalid method to create group '$group'"
);
}
$this->addGroupToCreatedGroupsList($group, true, $groupCanBeDeleted, $groupId);
}
/**
* @param string $attribute
* @param string $entry
* @param string $value
* @param bool $append
*
* @return void
* @throws Exception
*/
public function setTheLdapAttributeOfTheEntryTo(
string $attribute,
string $entry,
string $value,
bool $append = false
):void {
$ldapEntry = $this->ldap->getEntry($entry . "," . $this->ldapBaseDN);
Laminas\Ldap\Attribute::setAttribute($ldapEntry, $attribute, $value, $append);
$this->ldap->update($entry . "," . $this->ldapBaseDN, $ldapEntry);
$this->theLdapUsersHaveBeenReSynced();
}
/**
* @param string $user
* @param string $group
* @param string|null $ou
*
* @return void
* @throws Exception
*/
public function addUserToLdapGroup(string $user, string $group, ?string $ou = null):void {
if ($ou === null) {
$ou = $this->getLdapGroupsOU();
}
$memberAttr = "";
$memberValue = "";
if ($this->ldapGroupSchema == "rfc2307") {
$memberAttr = "memberUID";
$memberValue = "$user";
} else {
$memberAttr = "member";
$userbase = "ou=" . $this->getLdapUsersOU() . "," . $this->ldapBaseDN;
$memberValue = "uid=$user" . "," . "$userbase";
}
$this->setTheLdapAttributeOfTheEntryTo(
$memberAttr,
"cn=$group,ou=$ou",
$memberValue,
true
);
}
/**
* @param string $value
* @param string $attribute
* @param string $entry
*
* @return void
*/
public function deleteValueFromLdapAttribute(string $value, string $attribute, string $entry):void {
$this->ldap->deleteAttributes(
$entry . "," . $this->ldapBaseDN,
[$attribute => [$value]]
);
}
/**
* @param string $user
* @param string $group
* @param string|null $ou
*
* @return void
* @throws Exception
*/
public function removeUserFromLdapGroup(string $user, string $group, ?string $ou = null):void {
if ($ou === null) {
$ou = $this->getLdapGroupsOU();
}
$memberAttr = "";
$memberValue = "";
if ($this->ldapGroupSchema == "rfc2307") {
$memberAttr = "memberUID";
$memberValue = "$user";
} else {
$memberAttr = "member";
$userbase = "ou=" . $this->getLdapUsersOU() . "," . $this->ldapBaseDN;
$memberValue = "uid=$user" . "," . "$userbase";
}
$this->deleteValueFromLdapAttribute(
$memberValue,
$memberAttr,
"cn=$group,ou=$ou"
);
$this->theLdapUsersHaveBeenReSynced();
}
/**
* @param string $entry
*
* @return void
* @throws Exception
*/
public function deleteTheLdapEntry(string $entry):void {
$this->ldap->delete($entry . "," . $this->ldapBaseDN);
$this->theLdapUsersHaveBeenReSynced();
}
/**
* @param string $group
* @param string|null $ou
*
* @return void
* @throws LdapException
* @throws Exception
*/
public function deleteLdapGroup(string $group, ?string $ou = null):void {
if ($ou === null) {
$ou = $this->getLdapGroupsOU();
}
$this->deleteTheLdapEntry("cn=$group,ou=$ou");
$this->theLdapUsersHaveBeenReSynced();
$key = \array_search($group, $this->ldapCreatedGroups);
if ($key !== false) {
unset($this->ldapCreatedGroups[$key]);
}
$this->rememberThatGroupIsNotExpectedToExist($group);
}
/**
* @param string|null $username
* @param string|null $ou
*
* @return void
* @throws Exception
*/
public function deleteLdapUser(?string $username, ?string $ou = null):void {
if (!\in_array($username, $this->ldapCreatedUsers)) {
throw new Error(
"User " . $username . " was not created using Ldap and does not exist as an Ldap User"
);
}
if ($ou === null) {
$ou = $this->getLdapUsersOU();
}
$entry = "uid=$username,ou=$ou";
$this->deleteTheLdapEntry($entry);
$key = \array_search($username, $this->ldapCreatedUsers);
if ($key !== false) {
unset($this->ldapCreatedUsers[$key]);
}
$this->rememberThatUserIsNotExpectedToExist($username);
}
/**
* @param string|null $user
* @param string|null $displayName
*
* @return void
* @throws Exception
*/
public function editLdapUserDisplayName(?string $user, ?string $displayName):void {
$entry = "uid=" . $user . ",ou=" . $this->getLdapUsersOU();
$this->setTheLdapAttributeOfTheEntryTo(
'displayname',
$entry,
$displayName
);
$this->theLdapUsersHaveBeenReSynced();
}
/**
* @When /^the administrator disables user "([^"]*)" using the provisioning API$/
*
* @param string|null $user
*
* @return void
*/
public function adminDisablesUserUsingTheProvisioningApi(?string $user):void {
$user = $this->getActualUsername($user);
$this->disableOrEnableUser($this->getAdminUsername(), $user, 'disable');
}
/**
* @When the administrator disables the following users using the provisioning API
*
* @param TableNode $table
*
* @return void
* @throws Exception
*/
public function theAdministratorDisablesTheFollowingUsersUsingTheProvisioningApi(TableNode $table):void {
$this->verifyTableNodeColumns($table, ["username"]);
$usernames = $table->getHash();
foreach ($usernames as $username) {
$this->adminDisablesUserUsingTheProvisioningApi($username["username"]);
}
}
/**
* @Given /^user "([^"]*)" has been disabled$/
*
* @param string|null $user
*
* @return void
* @throws Exception
*/
public function adminHasDisabledUserUsingTheProvisioningApi(?string $user):void {
$user = $this->getActualUsername($user);
$this->disableOrEnableUser($this->getAdminUsername(), $user, 'disable');
$this->theHTTPStatusCodeShouldBeSuccess();
$this->ocsContext->assertOCSResponseIndicatesSuccess();
}
/**
* @Given the following users have been disabled
*
* @param TableNode $table
*
* @return void
* @throws Exception
*/
public function theFollowingUsersHaveBeenDisabled(TableNode $table):void {
$this->verifyTableNodeColumns($table, ["username"]);
$usernames = $table->getHash();
foreach ($usernames as $username) {
$this->adminHasDisabledUserUsingTheProvisioningApi($username["username"]);
}
}
/**
* @When user :user disables user :otherUser using the provisioning API
*
* @param string $user
* @param string $otherUser
*
* @return void
*/
public function userDisablesUserUsingTheProvisioningApi(string $user, string $otherUser):void {
$user = $this->getActualUsername($user);
$actualOtherUser = $this->getActualUsername($otherUser);
$this->disableOrEnableUser($user, $actualOtherUser, 'disable');
}
/**
* @When the administrator enables user :user using the provisioning API
*
* @param string $user
*
* @return void
*/
public function theAdministratorEnablesUserUsingTheProvisioningApi(string $user):void {
$this->disableOrEnableUser($this->getAdminUsername(), $user, 'enable');
}
/**
* @When the administrator enables the following users using the provisioning API
*
* @param TableNode $table
*
* @return void
* @throws Exception
*/
public function theAdministratorEnablesTheFollowingUsersUsingTheProvisioningApi(TableNode $table):void {
$this->verifyTableNodeColumns($table, ["username"]);
$usernames = $table->getHash();
foreach ($usernames as $username) {
$this->theAdministratorEnablesUserUsingTheProvisioningApi($username["username"]);
}
}
/**
* @When /^user "([^"]*)" enables user "([^"]*)" using the provisioning API$/
* @When /^user "([^"]*)" tries to enable user "([^"]*)" using the provisioning API$/
*
* @param string $user
* @param string $otherUser
*
* @return void
*/
public function userTriesToEnableUserUsingTheProvisioningApi(
string $user,
string $otherUser
):void {
$this->disableOrEnableUser($user, $otherUser, 'enable');
}
/**
* @param string $user
*
* @return void
* @throws Exception
*/
public function deleteTheUserUsingTheProvisioningApi(string $user):void {
$this->emptyLastHTTPStatusCodesArray();
$this->emptyLastOCSStatusCodesArray();
// Always try to delete the user
if (OcisHelper::isTestingWithGraphApi()) {
// users can be deleted using the username in the GraphApi too
$this->graphContext->adminDeletesUserUsingTheGraphApi($user);
} else {
$this->response = UserHelper::deleteUser(
$this->getBaseUrl(),
$user,
$this->getAdminUsername(),
$this->getAdminPassword(),
$this->getStepLineRef(),
$this->ocsApiVersion
);
}
$this->pushToLastStatusCodesArrays();
// Only log a message if the test really expected the user to have been
// successfully created (i.e. the delete is expected to work) and
// there was a problem deleting the user. Because in this case there
// might be an effect on later tests.
if ($this->theUserShouldExist($user)
&& (!\in_array($this->response->getStatusCode(), [200, 204]))
) {
\error_log(
"INFORMATION: could not delete user '$user' "
. $this->response->getStatusCode() . " " . $this->response->getBody()
);
}
$this->rememberThatUserIsNotExpectedToExist($user);
}
/**
* @param string $group group name
*
* @return void
* @throws Exception
* @throws LdapException
*/
public function deleteGroup(string $group):void {
if ($this->groupExists($group)) {
if ($this->isTestingWithLdap() && \in_array($group, $this->ldapCreatedGroups)) {
$this->deleteLdapGroup($group);
} else {
$this->deleteTheGroupUsingTheProvisioningApi($group);
}
}
}
/**
* @Given /^group "([^"]*)" has been deleted$/
*
* @param string $group
*
* @return void
* @throws Exception
* @throws GuzzleException
*/
public function groupHasBeenDeleted(string $group):void {
if (OcisHelper::isTestingWithGraphApi()) {
$this->graphContext->adminHasDeletedGroupUsingTheGraphApi($group);
} else {
$this->deleteGroup($group);
}
$this->groupShouldNotExist($group);
}
/**
* @When /^the administrator deletes group "([^"]*)" from the default user backend$/
*
* @param string $group
*
* @return void
* @throws Exception
*/
public function adminDeletesGroup(string $group):void {
$this->deleteGroup($group);
$this->pushToLastStatusCodesArrays();
}
/**
* @When /^the administrator deletes group "([^"]*)" using the provisioning API$/
*
* @param string $group
*
* @return void
* @throws Exception
*/
public function deleteTheGroupUsingTheProvisioningApi(string $group):void {
$this->emptyLastHTTPStatusCodesArray();
$this->emptyLastOCSStatusCodesArray();
$this->response = UserHelper::deleteGroup(
$this->getBaseUrl(),
$group,
$this->getAdminUsername(),
$this->getAdminPassword(),
$this->getStepLineRef(),
$this->ocsApiVersion
);
$this->pushToLastStatusCodesArrays();
if ($this->theGroupShouldExist($group)
&& $this->theGroupShouldBeAbleToBeDeleted($group)
&& ($this->response->getStatusCode() !== 200)
) {
\error_log(
"INFORMATION: could not delete group '$group'"
. $this->response->getStatusCode() . " " . $this->response->getBody()
);
}
$this->rememberThatGroupIsNotExpectedToExist($group);
}
/**
* @When the administrator deletes the following groups using the provisioning API
*
* @param TableNode $table
*
* @return void
* @throws Exception
*/
public function theAdministratorDeletesTheFollowingGroupsUsingTheProvisioningApi(TableNode $table):void {
$this->verifyTableNodeColumns($table, ["groupname"]);
$groups = $table->getHash();
foreach ($groups as $group) {
$this->deleteTheGroupUsingTheProvisioningApi($group["groupname"]);
}
}
/**
* @When user :user tries to delete group :group using the provisioning API
*
* @param string $user
* @param string $group
*
* @return void
* @throws JsonException
*/
public function userTriesToDeleteGroupUsingTheProvisioningApi(string $user, string $group):void {
$this->response = UserHelper::deleteGroup(
$this->getBaseUrl(),
$group,
$this->getActualUsername($user),
$this->getActualPassword($user),
$this->getStepLineRef(),
$this->ocsApiVersion
);
}
/**
* @param string $group
*
* @return bool
* @throws Exception
* @throws GuzzleException
*/
public function groupExists(string $group):bool {
if ($this->isTestingWithLdap() && OcisHelper::isTestingOnOcisOrReva()) {
$baseDN = $this->getLdapBaseDN();
$newDN = 'cn=' . $group . ',ou=' . $this->ldapGroupsOU . ',' . $baseDN;
if ($this->ldap->getEntry($newDN) !== null) {
return true;
}
return false;
}
if (OcisHelper::isTestingWithGraphApi()) {
$base = '/graph/v1.0';
} else {
$base = '/ocs/v2.php/cloud';
}
$group = \rawurlencode($group);
$fullUrl = $this->getBaseUrl() . "$base/groups/$group";
$this->response = HttpRequestHelper::get(
$fullUrl,
$this->getStepLineRef(),
$this->getAdminUsername(),
$this->getAdminPassword()
);
if ($this->response->getStatusCode() >= 400) {
return false;
}
return true;
}
/**
* @param string $user
* @param string $group
*
* @return void
* @throws Exception
*/
public function removeUserFromGroupAsAdminUsingTheProvisioningApi(string $user, string $group):void {
$this->userRemovesUserFromGroupUsingTheProvisioningApi(
$this->getAdminUsername(),
$user,
$group
);
}
/**
* @When the administrator removes user :user from group :group using the provisioning API
*
* @param string $user
* @param string $group
*
* @return void
* @throws Exception
*/
public function adminRemovesUserFromGroupUsingTheProvisioningApi(string $user, string $group):void {
$user = $this->getActualUsername($user);
$this->removeUserFromGroupAsAdminUsingTheProvisioningApi(
$user,
$group
);
$this->pushToLastStatusCodesArrays();
}
/**
* @When the administrator removes the following users from the following groups using the provisioning API
*
* @param TableNode $table
*
* @return void
* @throws Exception
*/
public function theAdministratorRemovesTheFollowingUserFromTheFollowingGroupUsingTheProvisioningApi(TableNode $table):void {
$this->verifyTableNodeColumns($table, ['username', 'groupname']);
$this->emptyLastHTTPStatusCodesArray();
$this->emptyLastOCSStatusCodesArray();
foreach ($table as $row) {
$this->adminRemovesUserFromGroupUsingTheProvisioningApi($row['username'], $row['groupname']);
$this->pushToLastStatusCodesArrays();
}
}
/**
* @Given user :user has been removed from group :group
*
* @param string $user
* @param string $group
*
* @return void
* @throws Exception
*/
public function adminHasRemovedUserFromGroup(string $user, string $group):void {
if ($this->isTestingWithLdap()
&& !$this->isLocalAdminGroup($group)
&& \in_array($group, $this->ldapCreatedGroups)
) {
$this->removeUserFromLdapGroup($user, $group);
} elseif (OcisHelper::isTestingWithGraphApi()) {
$this->graphContext->adminHasRemovedUserFromGroupUsingTheGraphApi($user, $group);
} else {
$this->removeUserFromGroupAsAdminUsingTheProvisioningApi(
$user,
$group
);
}
$this->userShouldNotBelongToGroup($user, $group);
}
/**
* @When user :user removes user :otherUser from group :group using the provisioning API
*
* @param string $user
* @param string $otherUser
* @param string $group
*
* @return void
* @throws Exception
*/
public function userRemovesUserFromGroupUsingTheProvisioningApi(
string $user,
string $otherUser,
string $group
):void {
$this->userTriesToRemoveUserFromGroupUsingTheProvisioningApi(
$user,
$otherUser,
$group
);
if ($this->response->getStatusCode() !== 200) {
\error_log(
"INFORMATION: could not remove user '$user' from group '$group'"
. $this->response->getStatusCode() . " " . $this->response->getBody()
);
}
}
/**
* @When user :user tries to remove user :otherUser from group :group using the provisioning API
*
* @param string $user
* @param string $otherUser
* @param string $group
*
* @return void
* @throws Exception
*/
public function userTriesToRemoveUserFromGroupUsingTheProvisioningApi(
string $user,
string $otherUser,
string $group
):void {
$actualUser = $this->getActualUsername($user);
$actualPassword = $this->getUserPassword($actualUser);
$actualOtherUser = $this->getActualUsername($otherUser);
$this->response = UserHelper::removeUserFromGroup(
$this->getBaseUrl(),
$actualOtherUser,
$group,
$actualUser,
$actualPassword,
$this->getStepLineRef(),
$this->ocsApiVersion
);
}
/**
* @When /^the administrator makes user "([^"]*)" a subadmin of group "([^"]*)" using the provisioning API$/
*
* @param string $user
* @param string $group
*
* @return void
*/
public function adminMakesUserSubadminOfGroupUsingTheProvisioningApi(
string $user,
string $group
):void {
$user = $this->getActualUsername($user);
$this->userMakesUserASubadminOfGroupUsingTheProvisioningApi(
$this->getAdminUsername(),
$user,
$group
);
}
/**
* @When user :user makes user :otherUser a subadmin of group :group using the provisioning API
*
* @param string $user
* @param string $otherUser
* @param string $group
*
* @return void
* @throws Exception
*/
public function userMakesUserASubadminOfGroupUsingTheProvisioningApi(
string $user,
string $otherUser,
string $group
):void {
$actualUser = $this->getActualUsername($user);
$actualPassword = $this->getUserPassword($actualUser);
$actualSubadminUsername = $this->getActualUsername($otherUser);
$fullUrl = $this->getBaseUrl()
. "/ocs/v{$this->ocsApiVersion}.php/cloud/users/$actualSubadminUsername/subadmins";
$body = ['groupid' => $group];
$this->response = HttpRequestHelper::post(
$fullUrl,
$this->getStepLineRef(),
$actualUser,
$actualPassword,
null,
$body
);
}
/**
* @When the administrator gets all the groups where user :user is subadmin using the provisioning API
*
* @param string $user
*
* @return void
*/
public function theAdministratorGetsAllTheGroupsWhereUserIsSubadminUsingTheProvisioningApi(string $user):void {
$fullUrl = $this->getBaseUrl()
. "/ocs/v{$this->ocsApiVersion}.php/cloud/users/$user/subadmins";
$this->response = HttpRequestHelper::get(
$fullUrl,
$this->getStepLineRef(),
$this->getAdminUsername(),
$this->getAdminPassword()
);
}
/**
* @When /^user "([^"]*)" gets all the groups where user "([^"]*)" is subadmin using the provisioning API$/
* @When /^user "([^"]*)" tries to get all the groups where user "([^"]*)" is subadmin using the provisioning API$/
*
* @param string $user
* @param string $otherUser
*
* @return void
* @throws Exception
*/
public function userTriesToGetAllTheGroupsWhereUserIsSubadminUsingTheProvisioningApi(string $user, string $otherUser):void {
$actualOtherUser = $this->getActualUsername($otherUser);
$fullUrl = $this->getBaseUrl()
. "/ocs/v{$this->ocsApiVersion}.php/cloud/users/$actualOtherUser/subadmins";
$actualUser = $this->getActualUsername($user);
$actualPassword = $this->getUserPassword($actualUser);
$this->response = HttpRequestHelper::get(
$fullUrl,
$this->getStepLineRef(),
$actualUser,
$actualPassword
);
}
/**
* @Given /^user "([^"]*)" has been made a subadmin of group "([^"]*)"$/
*
* @param string $user
* @param string $group
*
* @return void
*/
public function userHasBeenMadeSubadminOfGroup(
string $user,
string $group
):void {
$this->adminMakesUserSubadminOfGroupUsingTheProvisioningApi(
$user,
$group
);
Assert::assertEquals(
200,
$this->response->getStatusCode()
);
}
/**
* @When the administrator gets all the subadmins of group :group using the provisioning API
*
* @param string $group
*
* @return void
* @throws Exception
*/
public function theAdministratorGetsAllTheSubadminsOfGroupUsingTheProvisioningApi(string $group):void {
$this->userGetsAllTheSubadminsOfGroupUsingTheProvisioningApi(
$this->getAdminUsername(),
$group
);
}
/**
* @When user :user gets all the subadmins of group :group using the provisioning API
*
* @param string $user
* @param string $group
*
* @return void
* @throws Exception
*/
public function userGetsAllTheSubadminsOfGroupUsingTheProvisioningApi(string $user, string $group):void {
$fullUrl = $this->getBaseUrl()
. "/ocs/v{$this->ocsApiVersion}.php/cloud/groups/$group/subadmins";
$actualUser = $this->getActualUsername($user);
$actualPassword = $this->getUserPassword($actualUser);
$this->response = HttpRequestHelper::get(
$fullUrl,
$this->getStepLineRef(),
$actualUser,
$actualPassword
);
}
/**
* @When the administrator removes user :user from being a subadmin of group :group using the provisioning API
*
* @param string $user
* @param string $group
*
* @return void
*/
public function theAdministratorRemovesUserFromBeingASubadminOfGroupUsingTheProvisioningApi(
string $user,
string $group
):void {
$this->userRemovesUserFromBeingASubadminOfGroupUsingTheProvisioningApi(
$this->getAdminUsername(),
$user,
$group
);
}
/**
* @When user :user removes user :otherUser from being a subadmin of group :group using the provisioning API
*
* @param string $user
* @param string $otherUser
* @param string $group
*
* @return void
* @throws Exception
*/
public function userRemovesUserFromBeingASubadminOfGroupUsingTheProvisioningApi(
string $user,
string $otherUser,
string $group
):void {
$actualOtherUser = $this->getActualUsername($otherUser);
$fullUrl = $this->getBaseUrl()
. "/ocs/v{$this->ocsApiVersion}.php/cloud/users/$actualOtherUser/subadmins";
$actualUser = $this->getActualUsername($user);
$actualPassword = $this->getUserPassword($actualUser);
$this->response = HttpRequestHelper::delete(
$fullUrl,
$this->getStepLineRef(),
$actualUser,
$actualPassword,
null,
['groupid' => $group]
);
}
/**
* @Then /^the users returned by the API should be$/
*
* @param TableNode $usersList
*
* @return void
* @throws Exception
*/
public function theUsersShouldBe(TableNode $usersList):void {
$this->verifyTableNodeColumnsCount($usersList, 1);
$users = $usersList->getRows();
$usersSimplified = \array_map(
function ($user) {
return $this->getActualUsername($user);
},
$this->simplifyArray($users)
);
if (OcisHelper::isTestingWithGraphApi()) {
$this->graphContext->theseUsersShouldBeInTheResponse($usersSimplified);
} else {
$respondedArray = $this->getArrayOfUsersResponded($this->response);
Assert::assertEqualsCanonicalizing(
$usersSimplified,
$respondedArray,
__METHOD__
. " Provided users do not match the users returned in the response."
);
}
}
/**
* @Then /^the users returned by the API should include$/
*
* @param TableNode $usersList
*
* @return void
* @throws Exception
*/
public function theUsersShouldInclude(TableNode $usersList):void {
$this->verifyTableNodeColumnsCount($usersList, 1);
$users = $usersList->getRows();
$usersSimplified = \array_map(
function ($user) {
return $this->getActualUsername($user);
},
$this->simplifyArray($users)
);
$respondedArray = $this->getArrayOfUsersResponded($this->response);
foreach ($usersSimplified as $userElement) {
Assert::assertContains(
$userElement,
$respondedArray,
__METHOD__
. " user $userElement is not present in the users list: \n"
. \join("\n", $respondedArray)
);
}
}
/**
* @Then /^the groups returned by the API should be$/
*
* @param TableNode $groupsList
*
* @return void
* @throws Exception
*/
public function theGroupsShouldBe(TableNode $groupsList):void {
$this->verifyTableNodeColumnsCount($groupsList, 1);
$groups = $groupsList->getRows();
$groupsSimplified = $this->simplifyArray($groups);
$respondedArray = $this->getArrayOfGroupsResponded($this->response);
if (OcisHelper::isTestingWithGraphApi()) {
$this->graphContext->theseGroupsShouldBeInTheResponse($groupsSimplified);
} else {
Assert::assertEqualsCanonicalizing(
$groupsSimplified,
$respondedArray,
__METHOD__
. " Provided groups do not match the groups returned in the response."
);
}
}
/**
* @Then /^the extra groups returned by the API should be$/
*
* @param TableNode $groupsList
*
* @return void
* @throws Exception
*/
public function theExtraGroupsShouldBe(TableNode $groupsList):void {
$this->verifyTableNodeColumnsCount($groupsList, 1);
$groups = $groupsList->getRows();
$groupsSimplified = $this->simplifyArray($groups);
if (OcisHelper::isTestingWithGraphApi()) {
$this->graphContext->theseGroupsShouldBeInTheResponse($groupsSimplified);
} else {
$expectedGroups = \array_merge($this->startingGroups, $groupsSimplified);
$respondedArray = $this->getArrayOfGroupsResponded($this->response);
Assert::assertEqualsCanonicalizing(
$expectedGroups,
$respondedArray,
__METHOD__
. " Provided groups do not match the groups returned in the response."
);
}
}
/**
* @Then /^the groups returned by the API should include "([^"]*)"$/
*
* @param string $group
*
* @return void
*/
public function theGroupsReturnedByTheApiShouldInclude(string $group):void {
$respondedArray = $this->getArrayOfGroupsResponded($this->response);
Assert::assertContains($group, $respondedArray);
}
/**
* @Then /^the groups returned by the API should not include "([^"]*)"$/
*
* @param string $group
*
* @return void
*/
public function theGroupsReturnedByTheApiShouldNotInclude(string $group):void {
$respondedArray = $this->getArrayOfGroupsResponded($this->response);
Assert::assertNotContains($group, $respondedArray);
}
/**
* @Then /^the users returned by the API should not include "([^"]*)"$/
*
* @param string $user
*
* @return void
*/
public function theUsersReturnedByTheApiShouldNotInclude(string $user):void {
$respondedArray = $this->getArrayOfUsersResponded($this->response);
Assert::assertNotContains($user, $respondedArray);
}
/**
* @param TableNode|null $groupsOrUsersList
*
* @return void
* @throws Exception
*/
public function checkSubadminGroupsOrUsersTable(?TableNode $groupsOrUsersList):void {
$this->verifyTableNodeColumnsCount($groupsOrUsersList, 1);
$tableRows = $groupsOrUsersList->getRows();
$simplifiedTableRows = $this->simplifyArray($tableRows);
$respondedArray = $this->getArrayOfSubadminsResponded($this->response);
Assert::assertEqualsCanonicalizing(
$simplifiedTableRows,
$respondedArray
);
}
/**
* @Then /^the subadmin groups returned by the API should be$/
*
* @param TableNode|null $groupsList
*
* @return void
* @throws Exception
*/
public function theSubadminGroupsShouldBe(?TableNode $groupsList):void {
$this->checkSubadminGroupsOrUsersTable($groupsList);
}
/**
* @Then /^the subadmin users returned by the API should be$/
*
* @param TableNode|null $usersList
*
* @return void
* @throws Exception
*/
public function theSubadminUsersShouldBe(?TableNode $usersList):void {
$this->checkSubadminGroupsOrUsersTable($usersList);
}
/**
* @Then /^the apps returned by the API should include$/
*
* @param TableNode|null $appList
*
* @return void
* @throws Exception
*/
public function theAppsShouldInclude(?TableNode $appList):void {
$this->verifyTableNodeColumnsCount($appList, 1);
$apps = $appList->getRows();
$appsSimplified = $this->simplifyArray($apps);
$respondedArray = $this->getArrayOfAppsResponded($this->response);
foreach ($appsSimplified as $app) {
Assert::assertContains(
$app,
$respondedArray,
"The apps returned by the API should include $app but $app was not included"
);
}
}
/**
* @Then /^the apps returned by the API should not include$/
*
* @param TableNode|null $appList
*
* @return void
* @throws Exception
*/
public function theAppsShouldNotInclude(?TableNode $appList):void {
$this->verifyTableNodeColumnsCount($appList, 1);
$apps = $appList->getRows();
$appsSimplified = $this->simplifyArray($apps);
$respondedArray = $this->getArrayOfAppsResponded($this->response);
foreach ($appsSimplified as $app) {
Assert::assertNotContains(
$app,
$respondedArray,
"The apps returned by the API should not include $app but $app was included"
);
}
}
/**
* @Then /^app "([^"]*)" should not be in the apps list$/
*
* @param string $appName
*
* @return void
*/
public function appShouldNotBeInTheAppsList(string $appName):void {
$fullUrl = $this->getBaseUrl() . "/ocs/v2.php/cloud/apps";
$this->response = HttpRequestHelper::get(
$fullUrl,
$this->getStepLineRef(),
$this->getAdminUsername(),
$this->getAdminPassword()
);
$respondedArray = $this->getArrayOfAppsResponded($this->response);
Assert::assertNotContains($appName, $respondedArray);
}
/**
* @Then /^user "([^"]*)" should be a subadmin of group "([^"]*)"$/
*
* @param string $user
* @param string $group
*
* @return void
* @throws Exception
*/
public function userShouldBeASubadminOfGroup(string $user, string $group):void {
$this->theAdministratorGetsAllTheSubadminsOfGroupUsingTheProvisioningApi($group);
Assert::assertEquals(
200,
$this->response->getStatusCode()
);
$listOfSubadmins = $this->getArrayOfSubadminsResponded($this->response);
Assert::assertContains(
$user,
$listOfSubadmins
);
}
/**
* @Then /^user "([^"]*)" should not be a subadmin of group "([^"]*)"$/
*
* @param string $user
* @param string $group
*
* @return void
* @throws Exception
*/
public function userShouldNotBeASubadminOfGroup(string $user, string $group):void {
$this->theAdministratorGetsAllTheSubadminsOfGroupUsingTheProvisioningApi($group);
$listOfSubadmins = $this->getArrayOfSubadminsResponded($this->response);
Assert::assertNotContains(
$user,
$listOfSubadmins
);
}
/**
* @Then /^the display name returned by the API should be "([^"]*)"$/
*
* @param string $expectedDisplayName
*
* @return void
* @throws Exception
*/
public function theDisplayNameReturnedByTheApiShouldBe(string $expectedDisplayName):void {
$responseDisplayName = (string) $this->getResponseXml(null, __METHOD__)->data[0]->displayname;
Assert::assertEquals(
$expectedDisplayName,
$responseDisplayName
);
}
/**
* @Then /^the display name of user "([^"]*)" should be "([^"]*)"$/
*
* @param string $user
* @param string $displayname
*
* @return void
* @throws Exception
*/
public function theDisplayNameOfUserShouldBe(string $user, string $displayname):void {
$actualUser = $this->getActualUsername($user);
$this->retrieveUserInformationAsAdminUsingProvisioningApi($actualUser);
$this->theDisplayNameReturnedByTheApiShouldBe($displayname);
}
/**
* @Then the display name of the following users should be
*
* @param TableNode $table
*
* @return void
* @throws Exception
*/
public function theDisplayNameOfTheFollowingUsersShouldBe(TableNode $table):void {
$this->verifyTableNodeColumns($table, ["name", "display-name"]);
$users = $table->getHash();
foreach ($users as $user) {
$this->theDisplayNameOfUserShouldBe($user["name"], $user["display-name"]);
}
}
/**
* @Then /^the display name of user "([^"]*)" should not have changed$/
*
* @param string $user
*
* @return void
* @throws Exception
*/
public function theDisplayNameOfUserShouldNotHaveChanged(string $user):void {
$actualUser = $this->getActualUsername($user);
$expectedDisplayName = $this->getDisplayNameForUser($user);
$this->retrieveUserInformationAsAdminUsingProvisioningApi($actualUser);
$this->theDisplayNameReturnedByTheApiShouldBe($expectedDisplayName);
}
/**
* @Then /^the email address returned by the API should be "([^"]*)"$/
*
* @param string $expectedEmailAddress
*
* @return void
* @throws Exception
*/
public function theEmailAddressReturnedByTheApiShouldBe(string $expectedEmailAddress):void {
$responseEmailAddress = (string) $this->getResponseXml(null, __METHOD__)->data[0]->email;
Assert::assertEquals(
$expectedEmailAddress,
$responseEmailAddress
);
}
/**
* @Then /^the email address of user "([^"]*)" should be "([^"]*)"$/
*
* @param string $user
* @param string $expectedEmailAddress
*
* @return void
* @throws Exception
*/
public function theEmailAddressOfUserShouldBe(string $user, string $expectedEmailAddress):void {
$user = $this->getActualUsername($user);
$this->retrieveUserInformationAsAdminUsingProvisioningApi($user);
$this->theEmailAddressReturnedByTheApiShouldBe($expectedEmailAddress);
}
/**
* @Then /^the email address of user "([^"]*)" should not have changed$/
*
* @param string $user
*
* @return void
* @throws Exception
*/
public function theEmailAddressOfUserShouldNotHaveChanged(string $user):void {
$user = $this->getActualUsername($user);
$expectedEmailAddress = $this->getEmailAddressForUser($user);
$this->retrieveUserInformationAsAdminUsingProvisioningApi($user);
$this->theEmailAddressReturnedByTheApiShouldBe($expectedEmailAddress);
}
/**
* @Then /^the free, used, total and relative quota returned by the API should exist and be valid numbers$/
*
* @return void
* @throws Exception
*/
public function theQuotaFieldsReturnedByTheApiShouldBValid():void {
$quotaData = $this->getResponseXml(null, __METHOD__)->data[0]->quota;
$missingQuotaDataString = "";
if (!isset($quotaData->free)) {
$missingQuotaDataString .= "free ";
}
if (!isset($quotaData->used)) {
$missingQuotaDataString .= "used ";
}
if (!isset($quotaData->total)) {
$missingQuotaDataString .= "total ";
}
if (!isset($quotaData->relative)) {
$missingQuotaDataString .= "relative ";
}
Assert::assertSame(
"",
$missingQuotaDataString,
"These quota data items are missing: $missingQuotaDataString"
);
$freeQuota = (string) $quotaData->free;
Assert::assertIsNumeric($freeQuota, "free quota '$freeQuota' is not numeric");
$usedQuota = (string) $quotaData->used;
Assert::assertIsNumeric($usedQuota, "used quota '$usedQuota' is not numeric");
$totalQuota = (string) $quotaData->total;
Assert::assertIsNumeric($totalQuota, "total quota '$totalQuota' is not numeric");
$relativeQuota = (string) $quotaData->relative;
Assert::assertIsNumeric($relativeQuota, "free quota '$relativeQuota' is not numeric");
Assert::assertSame(
(int) $freeQuota + (int) $usedQuota,
(int) $totalQuota,
"free $freeQuota plus used $usedQuota quota is not equal to total quota $totalQuota"
);
}
/**
* @Then /^the quota definition returned by the API should be "([^"]*)"$/
*
* @param string $expectedQuotaDefinition a string that describes the quota
*
* @return void
* @throws Exception
*/
public function theQuotaDefinitionReturnedByTheApiShouldBe(string $expectedQuotaDefinition):void {
$responseQuotaDefinition = (string) $this->getResponseXml(null, __METHOD__)->data[0]->quota->definition;
Assert::assertEquals(
$expectedQuotaDefinition,
$responseQuotaDefinition
);
}
/**
* @Then /^the quota definition of user "([^"]*)" should be "([^"]*)"$/
*
* @param string $user
* @param string $expectedQuotaDefinition
*
* @return void
* @throws Exception
*/
public function theQuotaDefinitionOfUserShouldBe(string $user, string $expectedQuotaDefinition):void {
$this->retrieveUserInformationAsAdminUsingProvisioningApi($user);
$this->theQuotaDefinitionReturnedByTheApiShouldBe($expectedQuotaDefinition);
}
/**
* @Then /^the last login returned by the API should be a current Unix timestamp$/
*
* @return void
* @throws Exception
*/
public function theLastLoginReturnedByTheApiShouldBe():void {
$responseLastLogin = (string) $this->getResponseXml(null, __METHOD__)->data[0]->last_login;
Assert::assertIsNumeric($responseLastLogin);
Assert::assertGreaterThan($this->scenarioStartTime, (int) $responseLastLogin);
}
/**
* Parses the xml answer to get the array of users returned.
*
* @param ResponseInterface $resp
*
* @return array
* @throws Exception
*/
public function getArrayOfUsersResponded(ResponseInterface $resp):array {
$listCheckedElements
= $this->getResponseXml($resp, __METHOD__)->data[0]->users[0]->element;
$extractedElementsArray
= \json_decode(\json_encode($listCheckedElements), true);
return $extractedElementsArray;
}
/**
* Parses the xml answer to get the array of groups returned.
*
* @param ResponseInterface $resp
*
* @return array
* @throws Exception
*/
public function getArrayOfGroupsResponded(ResponseInterface $resp):array {
$listCheckedElements
= $this->getResponseXml($resp, __METHOD__)->data[0]->groups[0]->element;
$extractedElementsArray
= \json_decode(\json_encode($listCheckedElements), true);
return $extractedElementsArray;
}
/**
* Parses the xml answer to get the array of apps returned.
*
* @param ResponseInterface $resp
*
* @return array
* @throws Exception
*/
public function getArrayOfAppsResponded(ResponseInterface $resp):array {
$listCheckedElements
= $this->getResponseXml($resp, __METHOD__)->data[0]->apps[0]->element;
$extractedElementsArray
= \json_decode(\json_encode($listCheckedElements), true);
return $extractedElementsArray;
}
/**
* Parses the xml answer to get the array of subadmins returned.
*
* @param ResponseInterface $resp
*
* @return array
* @throws Exception
*/
public function getArrayOfSubadminsResponded(ResponseInterface $resp):array {
$listCheckedElements
= $this->getResponseXml($resp, __METHOD__)->data[0]->element;
$extractedElementsArray
= \json_decode(\json_encode($listCheckedElements), true);
return $extractedElementsArray;
}
/**
* Parses the xml answer to get the array of app info returned for an app.
*
* @param ResponseInterface $resp
*
* @return array
* @throws Exception
*/
public function getArrayOfAppInfoResponded(ResponseInterface $resp):array {
$listCheckedElements
= $this->getResponseXml($resp, __METHOD__)->data[0];
$extractedElementsArray
= \json_decode(\json_encode($listCheckedElements), true);
return $extractedElementsArray;
}
/**
* @Then /^app "([^"]*)" should be disabled$/
*
* @param string $app
*
* @return void
* @throws Exception
*/
public function appShouldBeDisabled(string $app):void {
$fullUrl = $this->getBaseUrl()
. "/ocs/v2.php/cloud/apps?filter=disabled";
$this->response = HttpRequestHelper::get(
$fullUrl,
$this->getStepLineRef(),
$this->getAdminUsername(),
$this->getAdminPassword()
);
$respondedArray = $this->getArrayOfAppsResponded($this->response);
Assert::assertContains($app, $respondedArray);
Assert::assertEquals(
200,
$this->response->getStatusCode()
);
}
/**
* @Then /^app "([^"]*)" should be enabled$/
*
* @param string $app
*
* @return void
* @throws Exception
*/
public function appShouldBeEnabled(string $app):void {
$fullUrl = $this->getBaseUrl() . "/ocs/v2.php/cloud/apps?filter=enabled";
$this->response = HttpRequestHelper::get(
$fullUrl,
$this->getStepLineRef(),
$this->getAdminUsername(),
$this->getAdminPassword()
);
$respondedArray = $this->getArrayOfAppsResponded($this->response);
Assert::assertContains($app, $respondedArray);
Assert::assertEquals(
200,
$this->response->getStatusCode()
);
}
/**
* @Then /^the information for app "([^"]*)" should have a valid version$/
*
* @param string $app
*
* @return void
* @throws Exception
*/
public function theInformationForAppShouldHaveAValidVersion(string $app):void {
$fullUrl = $this->getBaseUrl() . "/ocs/v2.php/cloud/apps/$app";
$this->response = HttpRequestHelper::get(
$fullUrl,
$this->getStepLineRef(),
$this->getAdminUsername(),
$this->getAdminPassword()
);
Assert::assertEquals(
200,
$this->response->getStatusCode()
);
$respondedArray = $this->getArrayOfAppInfoResponded($this->response);
Assert::assertArrayHasKey(
'version',
$respondedArray,
"app info returned for $app app does not have a version"
);
$appVersion = $respondedArray['version'];
Assert::assertTrue(
\substr_count($appVersion, '.') > 1,
"app version '$appVersion' returned in app info is not a valid version string"
);
}
/**
* @Then /^user "([^"]*)" should be disabled$/
*
* @param string $user
*
* @return void
* @throws Exception
*/
public function userShouldBeDisabled(string $user):void {
$user = $this->getActualUsername($user);
$fullUrl = $this->getBaseUrl()
. "/ocs/v{$this->ocsApiVersion}.php/cloud/users/$user";
$this->response = HttpRequestHelper::get(
$fullUrl,
$this->getStepLineRef(),
$this->getAdminUsername(),
$this->getAdminPassword()
);
Assert::assertEquals(
"false",
$this->getResponseXml(null, __METHOD__)->data[0]->enabled
);
}
/**
* @Then the following users should be disabled
*
* @param TableNode $table
*
* @return void
* @throws Exception
*/
public function theFollowingUsersShouldBeDisabled(TableNode $table):void {
$this->verifyTableNodeColumns($table, ["username"]);
$usernames = $table->getHash();
foreach ($usernames as $username) {
$this->userShouldBeDisabled($username["username"]);
}
}
/**
* @Then /^user "([^"]*)" should be enabled$/
*
* @param string $user
*
* @return void
* @throws Exception
*/
public function userShouldBeEnabled(string $user):void {
$user = $this->getActualUsername($user);
$fullUrl = $this->getBaseUrl()
. "/ocs/v{$this->ocsApiVersion}.php/cloud/users/$user";
$this->response = HttpRequestHelper::get(
$fullUrl,
$this->getStepLineRef(),
$this->getAdminUsername(),
$this->getAdminPassword()
);
Assert::assertEquals(
"true",
$this->getResponseXml(null, __METHOD__)->data[0]->enabled
);
}
/**
* @Then the following users should be enabled
*
* @param TableNode $table
*
* @return void
* @throws Exception
*/
public function theFollowingUsersShouldBeEnabled(TableNode $table):void {
$this->verifyTableNodeColumns($table, ["username"]);
$usernames = $table->getHash();
foreach ($usernames as $username) {
$this->userShouldBeEnabled($username["username"]);
}
}
/**
* @When the administrator sets the quota of user :user to :quota using the provisioning API
*
* @param string $user
* @param string $quota
*
* @return void
*/
public function adminSetsUserQuotaToUsingTheProvisioningApi(string $user, string $quota):void {
$user = $this->getActualUsername($user);
$body
= [
'key' => 'quota',
'value' => $quota,
];
$this->response = OcsApiHelper::sendRequest(
$this->getBaseUrl(),
$this->getAdminUsername(),
$this->getAdminPassword(),
"PUT",
"/cloud/users/$user",
$this->getStepLineRef(),
$body,
2
);
}
/**
* @Given the quota of user :user has been set to :quota
*
* @param string $user
* @param string $quota
*
* @return void
*/
public function theQuotaOfUserHasBeenSetTo(string $user, string $quota):void {
$this->adminSetsUserQuotaToUsingTheProvisioningApi($user, $quota);
$this->theHTTPStatusCodeShouldBe(200);
}
/**
* @When the administrator gives unlimited quota to user :user using the provisioning API
*
* @param string $user
*
* @return void
*/
public function adminGivesUnlimitedQuotaToUserUsingTheProvisioningApi(string $user):void {
$this->adminSetsUserQuotaToUsingTheProvisioningApi($user, 'none');
}
/**
* @Given user :user has been given unlimited quota
*
* @param string $user
*
* @return void
*/
public function userHasBeenGivenUnlimitedQuota(string $user):void {
$this->theQuotaOfUserHasBeenSetTo($user, 'none');
}
/**
* Returns home path of the given user
*
* @param string $user
*
* @return string
* @throws Exception
*/
public function getUserHome(string $user):string {
$fullUrl = $this->getBaseUrl()
. "/ocs/v{$this->ocsApiVersion}.php/cloud/users/$user";
$this->response = HttpRequestHelper::get(
$fullUrl,
$this->getStepLineRef(),
$this->getAdminUsername(),
$this->getAdminPassword()
);
return $this->getResponseXml(null, __METHOD__)->data[0]->home;
}
/**
* @Then /^the user attributes returned by the API should include$/
*
* @param TableNode|null $body
*
* @return void
* @throws Exception
*/
public function checkUserAttributes(?TableNode $body):void {
$this->verifyTableNodeRows($body, [], $this->userResponseFields);
$bodyRows = $body->getRowsHash();
foreach ($bodyRows as $field => $value) {
$data = $this->getResponseXml(null, __METHOD__)->data[0];
$field_array = \explode(' ', $field);
foreach ($field_array as $field_name) {
$data = $data->$field_name;
}
if ($data != $value) {
Assert::fail(
"$field has value $data"
);
}
}
}
/**
* @Then the attributes of user :user returned by the API should include
*
* @param string $user
* @param TableNode $body
*
* @return void
* @throws Exception
*/
public function checkAttributesForUser(string $user, TableNode $body):void {
$user = $this->getActualUsername($user);
$this->verifyTableNodeColumnsCount($body, 2);
$this->ocsContext->userSendsHTTPMethodToOcsApiEndpointWithBody(
$this->getAdminUsername(),
"GET",
"/cloud/users/$user",
null
);
$this->checkUserAttributes($body);
}
/**
* @Then /^the API should not return any data$/
*
* @return void
* @throws Exception
*/
public function theApiShouldNotReturnAnyData():void {
$responseData = $this->getResponseXml(null, __METHOD__)->data[0];
Assert::assertEmpty(
$responseData,
"Response data is not empty but it should be empty"
);
}
/**
* @Then /^the list of users returned by the API should be empty$/
*
* @return void
* @throws Exception
*/
public function theListOfUsersReturnedByTheApiShouldBeEmpty():void {
$usersList = $this->getResponseXml(null, __METHOD__)->data[0]->users[0];
Assert::assertEmpty(
$usersList,
"Users list is not empty but it should be empty"
);
}
/**
* @Then /^the list of groups returned by the API should be empty$/
*
* @return void
* @throws Exception
*/
public function theListOfGroupsReturnedByTheApiShouldBeEmpty():void {
$groupsList = $this->getResponseXml(null, __METHOD__)->data[0]->groups[0];
Assert::assertEmpty(
$groupsList,
"Groups list is not empty but it should be empty"
);
}
/**
* @AfterScenario
*
* @return void
* @throws Exception
*/
public function afterScenario():void {
$this->waitForDavRequestsToFinish();
$this->restoreParametersAfterScenario();
if (OcisHelper::isTestingOnOcisOrReva() && $this->someUsersHaveBeenCreated()) {
foreach ($this->getCreatedUsers() as $user) {
OcisHelper::deleteRevaUserData($user["actualUsername"]);
}
} elseif (OcisHelper::isTestingOnOc10()) {
$this->resetAdminUserAttributes();
}
if ($this->isTestingWithLdap()) {
$this->deleteLdapUsersAndGroups();
}
$this->cleanupDatabaseUsers();
$this->cleanupDatabaseGroups();
}
/**
*
* @return void
* @throws Exception
*/
public function resetAdminUserAttributes():void {
if ($this->adminDisplayName !== '') {
$this->adminChangesTheDisplayNameOfUserUsingTheProvisioningApi(
$this->getAdminUsername(),
''
);
}
if ($this->adminEmailAddress !== '') {
$this->adminChangesTheEmailOfUserToUsingTheProvisioningApi(
$this->getAdminUsername(),
''
);
}
}
/**
*
* @return void
* @throws Exception
*/
public function cleanupDatabaseUsers():void {
$this->authContext->deleteTokenAuthEnforcedAfterScenario();
$previousServer = $this->currentServer;
$this->usingServer('LOCAL');
foreach ($this->createdUsers as $user => $userData) {
$this->deleteUser($userData['actualUsername']);
}
$this->usingServer('REMOTE');
foreach ($this->createdRemoteUsers as $remoteUser => $userData) {
$this->deleteUser($userData['actualUsername']);
}
$this->usingServer($previousServer);
}
/**
*
* @return void
* @throws Exception
*/
public function cleanupDatabaseGroups():void {
$this->authContext->deleteTokenAuthEnforcedAfterScenario();
$previousServer = $this->currentServer;
$this->usingServer('LOCAL');
foreach ($this->createdGroups as $group => $groupData) {
if (OcisHelper::isTestingWithGraphApi()) {
$this->graphContext->adminDeletesGroupWithGroupId(
$groupData['id']
);
} else {
$this->cleanupGroup((string)$group);
}
}
$this->usingServer('REMOTE');
foreach ($this->createdRemoteGroups as $remoteGroup => $groupData) {
if (OcisHelper::isTestingWithGraphApi()) {
$this->graphContext->adminDeletesGroupWithGroupId(
$groupData['id']
);
} else {
$this->cleanupGroup((string)$remoteGroup);
}
}
$this->usingServer($previousServer);
}
/**
* @BeforeScenario
*
* @return void
* @throws Exception
*/
public function rememberAppEnabledDisabledState():void {
if (!OcisHelper::isTestingOnOcisOrReva()) {
SetupHelper::init(
$this->getAdminUsername(),
$this->getAdminPassword(),
$this->getBaseUrl(),
$this->getOcPath()
);
$this->runOcc(['app:list', '--output json']);
$apps = \json_decode($this->getStdOutOfOccCommand(), true);
$this->enabledApps = \array_keys($apps["enabled"]);
$this->disabledApps = \array_keys($apps["disabled"]);
}
}
/**
* @BeforeScenario @rememberGroupsThatExist
*
* @return void
* @throws Exception
*/
public function rememberGroupsThatExistAtTheStartOfTheScenario():void {
$this->startingGroups = $this->getArrayOfGroupsResponded($this->getAllGroups());
}
/**
* @AfterScenario
*
* @return void
* @throws Exception
*/
public function restoreAppEnabledDisabledState():void {
if (!OcisHelper::isTestingOnOcisOrReva() && !$this->isRunningForDbConversion()) {
$this->runOcc(['app:list', '--output json']);
$apps = \json_decode($this->getStdOutOfOccCommand(), true);
$currentlyEnabledApps = \array_keys($apps["enabled"]);
$currentlyDisabledApps = \array_keys($apps["disabled"]);
foreach ($currentlyDisabledApps as $disabledApp) {
if (\in_array($disabledApp, $this->enabledApps)) {
$this->adminEnablesOrDisablesApp('enables', $disabledApp);
}
}
foreach ($currentlyEnabledApps as $enabledApp) {
if (\in_array($enabledApp, $this->disabledApps)) {
$this->adminEnablesOrDisablesApp('disables', $enabledApp);
}
}
}
}
/**
* disable or enable user
*
* @param string $user
* @param string $otherUser
* @param string $action
*
* @return void
*/
public function disableOrEnableUser(string $user, string $otherUser, string $action):void {
$actualUser = $this->getActualUsername($user);
$actualPassword = $this->getPasswordForUser($actualUser);
$actualOtherUser = $this->getActualUsername($otherUser);
$fullUrl = $this->getBaseUrl()
. "/ocs/v{$this->ocsApiVersion}.php/cloud/users/$actualOtherUser/$action";
$this->response = HttpRequestHelper::put(
$fullUrl,
$this->getStepLineRef(),
$actualUser,
$actualPassword
);
$this->pushToLastStatusCodesArrays();
}
/**
* Returns an array of all apps reported by the cloud/apps endpoint
*
* @return array
* @throws Exception
*/
public function getAllApps():array {
$fullUrl = $this->getBaseUrl()
. "/ocs/v{$this->ocsApiVersion}.php/cloud/apps";
$this->response = HttpRequestHelper::get(
$fullUrl,
$this->getStepLineRef(),
$this->getAdminUsername(),
$this->getAdminPassword()
);
return ($this->getArrayOfAppsResponded($this->response));
}
/**
* Returns array of enabled apps reported by the cloud/apps endpoint
*
* @return array
* @throws Exception
*/
public function getEnabledApps():array {
$fullUrl = $this->getBaseUrl()
. "/ocs/v{$this->ocsApiVersion}.php/cloud/apps?filter=enabled";
$this->response = HttpRequestHelper::get(
$fullUrl,
$this->getStepLineRef(),
$this->getAdminUsername(),
$this->getAdminPassword()
);
return ($this->getArrayOfAppsResponded($this->response));
}
/**
* Returns array of disabled apps reported by the cloud/apps endpoint
*
* @return array
* @throws Exception
*/
public function getDisabledApps():array {
$fullUrl = $this->getBaseUrl()
. "/ocs/v{$this->ocsApiVersion}.php/cloud/apps?filter=disabled";
$this->response = HttpRequestHelper::get(
$fullUrl,
$this->getStepLineRef(),
$this->getAdminUsername(),
$this->getAdminPassword()
);
return ($this->getArrayOfAppsResponded($this->response));
}
/**
* Removes skeleton directory config from config.php and returns the config value
*
* @param string|null $baseUrl
*
* @return string
* @throws Exception
*/
public function popSkeletonDirectoryConfig(?string $baseUrl = null):string {
$path = $this->getSkeletonDirectory($baseUrl);
$this->runOcc(
["config:system:delete skeletondirectory"],
null,
null,
$baseUrl
);
return $path;
}
/**
* @param string|null $baseUrl
*
* @return string
* @throws Exception
*/
private function getSkeletonDirectory(?string $baseUrl = null):string {
$this->runOcc(
["config:system:get skeletondirectory"],
null,
null,
$baseUrl
);
return \trim($this->getStdOutOfOccCommand());
}
/**
* Get the name of the smallest available skeleton, to "simulate" without skeleton.
*
* In ownCloud 10 there is always a skeleton directory. If none is specified
* then whatever is in core/skeleton is used. That contains different files
* and folders depending on the build that is being tested. So for testing
* we have "empty" skeleton that is created on-the-fly by the testing app.
* That provides a consistent skeleton for test scenarios that specify
* "without skeleton files"
*
* @return string name of the smallest skeleton folder
*/
private function getSmallestSkeletonDirName(): string {
return "empty";
}
/**
* @return bool
*/
private function isEmptySkeleton(): bool {
$skeletonDir = \getenv("SKELETON_DIR");
if (($skeletonDir !== false) && (\basename($skeletonDir) === $this->getSmallestSkeletonDirName() . "Skeleton")) {
return true;
}
return false;
}
/**
* sets the skeletondirectory according to the type
*
* @param string $skeletonType can be "tiny", "small", "large" OR empty.
* If an empty string is given, the current
* setting will not be changed
*
* @return string skeleton folder before the change
* @throws Exception
*/
private function setSkeletonDirByType(string $skeletonType): string {
if (OcisHelper::isTestingOnOcisOrReva()) {
$originalSkeletonPath = \getenv("SKELETON_DIR");
if ($originalSkeletonPath === false) {
$originalSkeletonPath = '';
}
if ($skeletonType !== '') {
$skeletonDirName = $skeletonType . "Skeleton";
$newSkeletonPath = \dirname($originalSkeletonPath) . '/' . $skeletonDirName;
\putenv(
"SKELETON_DIR=" . $newSkeletonPath
);
}
} else {
$baseUrl = $this->getBaseUrl();
$originalSkeletonPath = $this->getSkeletonDirectory($baseUrl);
if ($skeletonType !== '') {
OcsApiHelper::sendRequest(
$baseUrl,
$this->getAdminUsername(),
$this->getAdminPassword(),
'POST',
"/apps/testing/api/v1/testingskeletondirectory",
$this->getStepLineRef(),
[
'directory' => $skeletonType . "Skeleton"
],
$this->getOcsApiVersion()
);
}
}
return $originalSkeletonPath;
}
/**
* sets the skeletondirectory
*
* @param string $skeletonDir Full path of the skeleton directory
* If an empty string is given, the current
* setting will not be changed
*
* @return string skeleton folder before the change
* @throws Exception
*/
private function setSkeletonDir(string $skeletonDir): string {
if (OcisHelper::isTestingOnOcisOrReva()) {
$originalSkeletonPath = \getenv("SKELETON_DIR");
if ($skeletonDir !== '') {
\putenv("SKELETON_DIR=" . $skeletonDir);
}
} else {
$baseUrl = $this->getBaseUrl();
$originalSkeletonPath = $this->getSkeletonDirectory($baseUrl);
if ($skeletonDir !== '') {
$this->runOcc(
["config:system:set skeletondirectory --value $skeletonDir"],
null,
null,
$baseUrl
);
}
}
return $originalSkeletonPath;
}
}