diff --git a/apps/user_ldap/lib/Group_LDAP.php b/apps/user_ldap/lib/Group_LDAP.php index cd4bd18cb4..0780e28f74 100644 --- a/apps/user_ldap/lib/Group_LDAP.php +++ b/apps/user_ldap/lib/Group_LDAP.php @@ -129,7 +129,6 @@ class Group_LDAP extends BackendUtility implements \OCP\GroupInterface, IGroupLD //usually, LDAP attributes are said to be case insensitive. But there are exceptions of course. $members = $this->_groupMembers($groupDN); - $members = array_keys($members); // uids are returned as keys if(!is_array($members) || count($members) === 0) { $this->access->connection->writeToCache($cacheKey, false); return false; diff --git a/build/integration/config/behat.yml b/build/integration/config/behat.yml index 7fd3686b8b..51b749360e 100644 --- a/build/integration/config/behat.yml +++ b/build/integration/config/behat.yml @@ -84,7 +84,7 @@ default: admin: - admin - admin - regular_user_password: what_for + regular_user_password: 123456 remoteapi: paths: - "%paths.base%/../remoteapi_features" diff --git a/build/integration/features/bootstrap/AppConfiguration.php b/build/integration/features/bootstrap/AppConfiguration.php index faf80d85e1..d39c51e387 100644 --- a/build/integration/features/bootstrap/AppConfiguration.php +++ b/build/integration/features/bootstrap/AppConfiguration.php @@ -23,8 +23,8 @@ */ use Behat\Behat\Hook\Scope\AfterScenarioScope; use Behat\Behat\Hook\Scope\BeforeScenarioScope; -use GuzzleHttp\Message\ResponseInterface; use PHPUnit\Framework\Assert; +use Psr\Http\Message\ResponseInterface; require __DIR__ . '/../../vendor/autoload.php'; diff --git a/build/integration/features/bootstrap/BasicStructure.php b/build/integration/features/bootstrap/BasicStructure.php index f6c93aa517..3f4f70115b 100644 --- a/build/integration/features/bootstrap/BasicStructure.php +++ b/build/integration/features/bootstrap/BasicStructure.php @@ -29,6 +29,7 @@ * */ +use Behat\Gherkin\Node\TableNode; use GuzzleHttp\Client; use GuzzleHttp\Cookie\CookieJar; use GuzzleHttp\Exception\ClientException; @@ -165,7 +166,7 @@ trait BasicStructure { * @When /^sending "([^"]*)" to "([^"]*)" with$/ * @param string $verb * @param string $url - * @param \Behat\Gherkin\Node\TableNode $body + * @param TableNode $body */ public function sendingToWith($verb, $url, $body) { $fullUrl = $this->baseUrl . "v{$this->apiVersion}.php" . $url; @@ -179,7 +180,7 @@ trait BasicStructure { $options['headers'] = [ 'OCS_APIREQUEST' => 'true' ]; - if ($body instanceof \Behat\Gherkin\Node\TableNode) { + if ($body instanceof TableNode) { $fd = $body->getRowsHash(); $options['form_params'] = $fd; } @@ -216,7 +217,7 @@ trait BasicStructure { } else { $options['auth'] = [$this->currentUser, $this->regularUser]; } - if ($body instanceof \Behat\Gherkin\Node\TableNode) { + if ($body instanceof TableNode) { $fd = $body->getRowsHash(); $options['form_params'] = $fd; } @@ -504,4 +505,27 @@ trait BasicStructure { public function cookiesAreReset() { $this->cookieJar = new CookieJar(); } + + /** + * @Then The following headers should be set + * @param TableNode $table + * @throws \Exception + */ + public function theFollowingHeadersShouldBeSet(TableNode $table) { + foreach($table->getTable() as $header) { + $headerName = $header[0]; + $expectedHeaderValue = $header[1]; + $returnedHeader = $this->response->getHeader($headerName)[0]; + if($returnedHeader !== $expectedHeaderValue) { + throw new \Exception( + sprintf( + "Expected value '%s' for header '%s', got '%s'", + $expectedHeaderValue, + $headerName, + $returnedHeader + ) + ); + } + } + } } diff --git a/build/integration/features/bootstrap/CalDavContext.php b/build/integration/features/bootstrap/CalDavContext.php index cbd29a4fbf..1c64c74c03 100644 --- a/build/integration/features/bootstrap/CalDavContext.php +++ b/build/integration/features/bootstrap/CalDavContext.php @@ -25,7 +25,7 @@ require __DIR__ . '/../../vendor/autoload.php'; use GuzzleHttp\Client; -use GuzzleHttp\Message\ResponseInterface; +use Psr\Http\Message\ResponseInterface; class CalDavContext implements \Behat\Behat\Context\Context { /** @var string */ diff --git a/build/integration/features/bootstrap/LDAPContext.php b/build/integration/features/bootstrap/LDAPContext.php index 2ad737bf8b..4932eaa36a 100644 --- a/build/integration/features/bootstrap/LDAPContext.php +++ b/build/integration/features/bootstrap/LDAPContext.php @@ -26,8 +26,9 @@ use Behat\Gherkin\Node\TableNode; use PHPUnit\Framework\Assert; class LDAPContext implements Context { - use BasicStructure; - use CommandLine; + use AppConfiguration, + CommandLine, + Sharing; // Pulls in BasicStructure protected $configID; @@ -204,4 +205,8 @@ class LDAPContext implements Context { $configKey = $this->configID . 'ldap_configuration_active'; $this->invokingTheCommand('config:app:set user_ldap ' . $configKey . ' --value="0"'); } + + protected function resetAppConfigs() { + // not implemented + } } diff --git a/build/integration/features/bootstrap/ShareesContext.php b/build/integration/features/bootstrap/ShareesContext.php index 41980e2cd2..ee4d942058 100644 --- a/build/integration/features/bootstrap/ShareesContext.php +++ b/build/integration/features/bootstrap/ShareesContext.php @@ -33,60 +33,9 @@ require __DIR__ . '/../../vendor/autoload.php'; * Features context. */ class ShareesContext implements Context, SnippetAcceptingContext { - use Provisioning; + use Sharing; use AppConfiguration; - /** - * @When /^getting sharees for$/ - * @param \Behat\Gherkin\Node\TableNode $body - */ - public function whenGettingShareesFor($body) { - $url = '/apps/files_sharing/api/v1/sharees'; - if ($body instanceof \Behat\Gherkin\Node\TableNode) { - $parameters = []; - foreach ($body->getRowsHash() as $key => $value) { - $parameters[] = $key . '=' . $value; - } - if (!empty($parameters)) { - $url .= '?' . implode('&', $parameters); - } - } - - $this->sendingTo('GET', $url); - } - - /** - * @Then /^"([^"]*)" sharees returned (are|is empty)$/ - * @param string $shareeType - * @param string $isEmpty - * @param \Behat\Gherkin\Node\TableNode|null $shareesList - */ - public function thenListOfSharees($shareeType, $isEmpty, $shareesList = null) { - if ($isEmpty !== 'is empty') { - $sharees = $shareesList->getRows(); - $respondedArray = $this->getArrayOfShareesResponded($this->response, $shareeType); - Assert::assertEquals($sharees, $respondedArray); - } else { - $respondedArray = $this->getArrayOfShareesResponded($this->response, $shareeType); - Assert::assertEmpty($respondedArray); - } - } - - public function getArrayOfShareesResponded(ResponseInterface $response, $shareeType) { - $elements = simplexml_load_string($response->getBody())->data; - $elements = json_decode(json_encode($elements), 1); - if (strpos($shareeType, 'exact ') === 0) { - $elements = $elements['exact']; - $shareeType = substr($shareeType, 6); - } - - $sharees = []; - foreach ($elements[$shareeType] as $element) { - $sharees[] = [$element['label'], $element['value']['shareType'], $element['value']['shareWith']]; - } - return $sharees; - } - protected function resetAppConfigs() { $this->modifyServerConfig('core', 'shareapi_only_share_with_group_members', 'no'); $this->modifyServerConfig('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes'); diff --git a/build/integration/features/bootstrap/Sharing.php b/build/integration/features/bootstrap/Sharing.php index 9a3c00af48..efacc6e415 100644 --- a/build/integration/features/bootstrap/Sharing.php +++ b/build/integration/features/bootstrap/Sharing.php @@ -26,8 +26,8 @@ * */ use GuzzleHttp\Client; -use GuzzleHttp\Message\ResponseInterface; use PHPUnit\Framework\Assert; +use Psr\Http\Message\ResponseInterface; require __DIR__ . '/../../vendor/autoload.php'; @@ -45,7 +45,7 @@ trait Sharing { /** @var int */ private $savedShareId = null; - /** @var \Psr\Http\Message\ResponseInterface */ + /** @var ResponseInterface */ private $response; /** @@ -529,26 +529,54 @@ trait Sharing { } /** - * @Then The following headers should be set - * @param \Behat\Gherkin\Node\TableNode $table - * @throws \Exception + * @When /^getting sharees for$/ + * @param \Behat\Gherkin\Node\TableNode $body */ - public function theFollowingHeadersShouldBeSet(\Behat\Gherkin\Node\TableNode $table) { - foreach($table->getTable() as $header) { - $headerName = $header[0]; - $expectedHeaderValue = $header[1]; - $returnedHeader = $this->response->getHeader($headerName)[0]; - if($returnedHeader !== $expectedHeaderValue) { - throw new \Exception( - sprintf( - "Expected value '%s' for header '%s', got '%s'", - $expectedHeaderValue, - $headerName, - $returnedHeader - ) - ); + public function whenGettingShareesFor($body) { + $url = '/apps/files_sharing/api/v1/sharees'; + if ($body instanceof \Behat\Gherkin\Node\TableNode) { + $parameters = []; + foreach ($body->getRowsHash() as $key => $value) { + $parameters[] = $key . '=' . $value; + } + if (!empty($parameters)) { + $url .= '?' . implode('&', $parameters); } } + + $this->sendingTo('GET', $url); + } + + /** + * @Then /^"([^"]*)" sharees returned (are|is empty)$/ + * @param string $shareeType + * @param string $isEmpty + * @param \Behat\Gherkin\Node\TableNode|null $shareesList + */ + public function thenListOfSharees($shareeType, $isEmpty, $shareesList = null) { + if ($isEmpty !== 'is empty') { + $sharees = $shareesList->getRows(); + $respondedArray = $this->getArrayOfShareesResponded($this->response, $shareeType); + Assert::assertEquals($sharees, $respondedArray); + } else { + $respondedArray = $this->getArrayOfShareesResponded($this->response, $shareeType); + Assert::assertEmpty($respondedArray); + } + } + + public function getArrayOfShareesResponded(ResponseInterface $response, $shareeType) { + $elements = simplexml_load_string($response->getBody())->data; + $elements = json_decode(json_encode($elements), 1); + if (strpos($shareeType, 'exact ') === 0) { + $elements = $elements['exact']; + $shareeType = substr($shareeType, 6); + } + + $sharees = []; + foreach ($elements[$shareeType] as $element) { + $sharees[] = [$element['label'], $element['value']['shareType'], $element['value']['shareWith']]; + } + return $sharees; } } diff --git a/build/integration/features/bootstrap/WebDav.php b/build/integration/features/bootstrap/WebDav.php index b36cdfaea6..6bc808c3bc 100644 --- a/build/integration/features/bootstrap/WebDav.php +++ b/build/integration/features/bootstrap/WebDav.php @@ -226,29 +226,6 @@ trait WebDav { } } - /** - * @Then The following headers should be set - * @param \Behat\Gherkin\Node\TableNode $table - * @throws \Exception - */ - public function theFollowingHeadersShouldBeSet(\Behat\Gherkin\Node\TableNode $table) { - foreach ($table->getTable() as $header) { - $headerName = $header[0]; - $expectedHeaderValue = $header[1]; - $returnedHeader = $this->response->getHeader($headerName)[0]; - if ($returnedHeader !== $expectedHeaderValue) { - throw new \Exception( - sprintf( - "Expected value '%s' for header '%s', got '%s'", - $expectedHeaderValue, - $headerName, - $returnedHeader - ) - ); - } - } - } - /** * @Then Downloaded content should start with :start * @param int $start diff --git a/build/integration/ldap_features/openldap-uid-username.feature b/build/integration/ldap_features/openldap-uid-username.feature index e120d0316d..1790106ad5 100644 --- a/build/integration/ldap_features/openldap-uid-username.feature +++ b/build/integration/ldap_features/openldap-uid-username.feature @@ -118,3 +118,24 @@ Feature: LDAP And the command output contains the text "Clean up the user's remnants by" And invoking occ with "user:delete alice" Then the command output contains the text "The specified user was deleted" + + Scenario: Search only with group members - allowed + Given modify LDAP configuration + | ldapGroupFilter | cn=Orcharding | + | ldapGroupMemberAssocAttr | member | + | ldapBaseGroups | ou=OtherGroups,dc=nextcloud,dc=ci | + | ldapAttributesForUserSearch | employeeNumber | + | useMemberOfToDetectMembership | 1 | + And parameter "shareapi_only_share_with_group_members" of app "core" is set to "yes" + And As an "alice" + When getting sharees for + # "5" is part of the employee number of some LDAP records + | search | 5 | + | itemType | file | + Then the OCS status code should be "200" + And the HTTP status code should be "200" + And "exact users" sharees returned is empty + And "users" sharees returned are + | Elisa | 0 | elisa | + And "exact groups" sharees returned is empty +