Skip to content

Commit

Permalink
Introduce UserSearch utils
Browse files Browse the repository at this point in the history
  • Loading branch information
VicDeo committed Mar 29, 2018
1 parent 75aefcc commit b28153d
Show file tree
Hide file tree
Showing 10 changed files with 283 additions and 257 deletions.
17 changes: 15 additions & 2 deletions apps/files_sharing/lib/Capabilities.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

use OCP\Capabilities\ICapability;
use OCP\IConfig;
use OCP\Util\UserSearch;

/**
* Class Capabilities
Expand All @@ -33,8 +34,20 @@ class Capabilities implements ICapability {
/** @var IConfig */
private $config;

public function __construct(IConfig $config) {
/**
* @var UserSearch
*/
private $userSearch;

/**
* Capabilities constructor.
*
* @param IConfig $config
* @param UserSearch $userSearch
*/
public function __construct(IConfig $config, UserSearch $userSearch) {
$this->config = $config;
$this->userSearch = $userSearch;
}

/**
Expand Down Expand Up @@ -99,7 +112,7 @@ public function getCapabilities() {
'incoming' => $this->config->getAppValue('files_sharing', 'incoming_server2server_share_enabled', 'yes') === 'yes'
];

$res['search_min_length'] = \OC::$server->getUserManager()->getSearchMinLength();
$res['search_min_length'] = $this->userSearch->getSearchMinLength();

return [
'files_sharing' => $res,
Expand Down
20 changes: 19 additions & 1 deletion apps/files_sharing/tests/CapabilitiesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,24 @@
*/
class CapabilitiesTest extends \Test\TestCase {

/**
* @var \OCP\Util\UserSearch
*/
protected $userSearch;

/**
*
*/
protected function setUp() {
parent::setUp();
$this->userSearch = $this->getMockBuilder(\OCP\Util\UserSearch::class)
->disableOriginalConstructor()
->getMock();
$this->userSearch->expects($this->any())
->method('getSearchMinLength')
->willReturn(1);
}

/**
* Test for the general part in each return statement and assert.
* Strip off the general part on the way.
Expand All @@ -54,7 +72,7 @@ private function getFilesSharingPart(array $data) {
private function getResults(array $map) {
$stub = $this->getMockBuilder('\OCP\IConfig')->disableOriginalConstructor()->getMock();
$stub->method('getAppValue')->will($this->returnValueMap($map));
$cap = new Capabilities($stub);
$cap = new Capabilities($stub, $this->userSearch);
$result = $this->getFilesSharingPart($cap->getCapabilities());
return $result;
}
Expand Down
15 changes: 12 additions & 3 deletions lib/private/Group/Manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,10 @@
namespace OC\Group;

use OC\Hooks\PublicEmitter;
use OC\User\Manager as UserManager;
use OCP\GroupInterface;
use OCP\IGroupManager;
use OCP\Util\UserSearch;

/**
* Class Manager
Expand All @@ -61,10 +63,15 @@ class Manager extends PublicEmitter implements IGroupManager {
private $backends = [];

/**
* @var \OC\User\Manager $userManager
* @var UserManager $userManager
*/
private $userManager;

/**
* @var UserSearch $userSearch
*/
private $userSearch;

/**
* @var \OC\Group\Group[]
*/
Expand All @@ -80,9 +87,11 @@ class Manager extends PublicEmitter implements IGroupManager {

/**
* @param \OC\User\Manager $userManager
* @param UserSearch $userSearch
*/
public function __construct(\OC\User\Manager $userManager) {
public function __construct(UserManager $userManager, UserSearch $userSearch) {
$this->userManager = $userManager;
$this->userSearch = $userSearch;
$cachedGroups = & $this->cachedGroups;
$cachedUserGroups = & $this->cachedUserGroups;
$this->listen('\OC\Group', 'postDelete', function ($group) use (&$cachedGroups, &$cachedUserGroups) {
Expand Down Expand Up @@ -221,7 +230,7 @@ public function createGroup($gid) {
*/
public function search($search, $limit = null, $offset = null, $scope = null) {
$groups = [];
if ($this->userManager->isSearcheable($search)) {
if ($this->userSearch->isSearchable($search)) {
foreach ($this->backends as $backend) {
if (!$backend->isVisibleForScope($scope)) {
// skip backend
Expand Down
11 changes: 10 additions & 1 deletion lib/private/Server.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@
use OCP\IUser;
use OCP\Security\IContentSecurityPolicyManager;
use OCP\Theme\IThemeService;
use OCP\Util\UserSearch;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use OC\Files\External\StoragesBackendService;
Expand Down Expand Up @@ -248,11 +249,19 @@ public function __construct($webRoot, \OC\Config $config) {
$c->getConfig(),
$c->getLogger(),
$c->getAccountMapper()
),
new UserSearch(
$c->getConfig()
)
);
});
$this->registerService('GroupManager', function (Server $c) {
$groupManager = new \OC\Group\Manager($this->getUserManager());
$groupManager = new \OC\Group\Manager(
$this->getUserManager(),
new UserSearch(
$c->getConfig()
)
);
$groupManager->listen('\OC\Group', 'preCreate', function ($gid) {
\OC_Hook::emit('OC_Group', 'pre_createGroup', ['run' => true, 'gid' => $gid]);
});
Expand Down
46 changes: 25 additions & 21 deletions lib/private/User/Manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
use OCP\User\IProvidesEMailBackend;
use OCP\User\IProvidesQuotaBackend;
use OCP\UserInterface;
use OCP\Util\UserSearch;
use Symfony\Component\EventDispatcher\GenericEvent;

/**
Expand Down Expand Up @@ -81,23 +82,39 @@ class Manager extends PublicEmitter implements IUserManager {
/** @var SyncService */
private $syncService;

/**
* @var UserSearch
*/
private $userSearch;

/**
* @param IConfig $config
* @param ILogger $logger
* @param AccountMapper $accountMapper
* @param SyncService $syncService
* @param UserSearch $userSearch
*/
public function __construct(IConfig $config, ILogger $logger, AccountMapper $accountMapper, SyncService $syncService) {
public function __construct(
IConfig $config,
ILogger $logger,
AccountMapper $accountMapper,
SyncService $syncService,
UserSearch $userSearch
) {
$this->config = $config;
$this->logger = $logger;
$this->accountMapper = $accountMapper;
$this->cachedUsers = new CappedMemoryCache();
$this->syncService = $syncService;
$this->userSearch = $userSearch;
$cachedUsers = &$this->cachedUsers;
$this->listen('\OC\User', 'postDelete', function ($user) use (&$cachedUsers) {
/** @var \OC\User\User $user */
unset($cachedUsers[$user->getUID()]);
});
$this->listen(
'\OC\User', 'postDelete',
function ($user) use (&$cachedUsers) {
/** @var \OC\User\User $user */
unset($cachedUsers[$user->getUID()]);
}
);
}

/**
Expand Down Expand Up @@ -248,7 +265,7 @@ public function checkPassword($loginName, $password) {
public function search($pattern, $limit = null, $offset = null) {
$accounts = $this->accountMapper->search('user_id', $pattern, $limit, $offset);
$users = [];
if ($this->isSearcheable($pattern)) {
if ($this->userSearch->isSearchable($pattern)) {
foreach ($accounts as $account) {
$user = $this->getUserObject($account);
$users[$user->getUID()] = $user;
Expand All @@ -269,7 +286,7 @@ public function search($pattern, $limit = null, $offset = null) {
public function find($pattern, $limit = null, $offset = null) {
$accounts = $this->accountMapper->find($pattern, $limit, $offset);
$users = [];
if ($this->isSearcheable($pattern)) {
if ($this->userSearch->isSearchable($pattern)) {
foreach ($accounts as $account) {
$user = $this->getUserObject($account);
$users[$user->getUID()] = $user;
Expand All @@ -287,7 +304,7 @@ public function find($pattern, $limit = null, $offset = null) {
* @return \OC\User\User[]
*/
public function searchDisplayName($pattern, $limit = null, $offset = null) {
if ($this->isSearcheable($pattern)) {
if ($this->userSearch->isSearchable($pattern)) {
$accounts = $this->accountMapper->search('display_name', $pattern, $limit, $offset);
return array_map(function(Account $account) {
return $this->getUserObject($account);
Expand All @@ -297,19 +314,6 @@ public function searchDisplayName($pattern, $limit = null, $offset = null) {
return [];
}

/**
* @param string $pattern
* @return bool
*/
public function isSearcheable($pattern) {
$trimmed = trim($pattern);
return $trimmed === '' || strlen($trimmed) >= $this->getSearchMinLength();
}

public function getSearchMinLength() {
return $this->config->getSystemValue('user.search_min_length', 4);
}

/**
* @param string $uid
* @param string $password
Expand Down
68 changes: 68 additions & 0 deletions lib/public/Util/UserSearch.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php
/**
* @author Viktar Dubiniuk <dubiniuk@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/>
*
*/

/**
* Public interface of ownCloud for apps to use.
* App Class
*
*/


namespace OCP\Util;
use OCP\IConfig;

/**
* This class provides utility functions for searching users and groups
*
* @since 10.0.8
*/

class UserSearch {

protected $config;

/**
* UserSearch constructor.
*
* @param IConfig $config
*/
public function __construct(IConfig $config) {
$this->config = $config;
}

/**
* @param string $pattern
* @return bool
*/
public function isSearchable($pattern) {
$trimmed = trim($pattern);
return $trimmed === '' || strlen($trimmed) >= $this->getSearchMinLength();
}

/**
* Get minimal allowed size to search users
*
* @return mixed
*/
public function getSearchMinLength() {
return $this->config->getSystemValue('user.search_min_length', 4);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ So that I can efficiently share my files with other users or groups
| regularuser | 1234 | User Regular | regularuser@oc.com.np |
And these groups have been created:
|groupname|
|grp1 |
|grp2 |
|grp3 |
|grpuser |
|group1 |
|group2 |
|group3 |
|groupuser |
And the user has browsed to the login page
And the user has logged in with username "regularuser" and password "1234" using the webUI
And the user has browsed to the files page
Expand All @@ -31,8 +31,8 @@ So that I can efficiently share my files with other users or groups

Scenario: autocompletion of regular existing groups
Given the user has opened the share dialog for the folder "simple-folder"
When the user types "grp" in the share-with-field
Then all users and groups that contain the string "grp" in their name should be listed in the autocomplete list on the webUI
When the user types "grou" in the share-with-field
Then all users and groups that contain the string "grou" in their name should be listed in the autocomplete list on the webUI
And the users own name should not be listed in the autocomplete list on the webUI

Scenario: autocompletion for a pattern that does not match any user or group
Expand All @@ -50,23 +50,23 @@ So that I can efficiently share my files with other users or groups
And the users own name should not be listed in the autocomplete list on the webUI

@skipOnLDAP @user_ldap#175
Scenario: autocompletion of a pattern that matches regular existing users but also a user whith whom the item is already shared (file)
Scenario: autocompletion of a pattern that matches regular existing users but also a user with whom the item is already shared (file)
Given the user has shared the file "data.zip" with the user "User Grp" using the webUI
And the user has opened the share dialog for the file "data.zip"
When the user types "user" in the share-with-field
Then all users and groups that contain the string "user" in their name should be listed in the autocomplete list on the webUI except user "User Grp"
And the users own name should not be listed in the autocomplete list on the webUI

Scenario: autocompletion of a pattern that matches regular existing groups but also a group with whom the item is already shared (folder)
Given the user shares the folder "simple-folder" with the group "grp1" using the webUI
Given the user shares the folder "simple-folder" with the group "group1" using the webUI
And the user has opened the share dialog for the folder "simple-folder"
When the user types "grp" in the share-with-field
Then all users and groups that contain the string "grp" in their name should be listed in the autocomplete list on the webUI except group "grp1"
When the user types "grou" in the share-with-field
Then all users and groups that contain the string "grou" in their name should be listed in the autocomplete list on the webUI except group "group1"
And the users own name should not be listed in the autocomplete list on the webUI

Scenario: autocompletion of a pattern that matches regular existing groups but also a group whith whom the item is already shared (file)
Given the user shares the file "data.zip" with the group "grpuser" using the webUI
Scenario: autocompletion of a pattern that matches regular existing groups but also a group with whom the item is already shared (file)
Given the user shares the file "data.zip" with the group "groupuser" using the webUI
And the user has opened the share dialog for the file "data.zip"
When the user types "grp" in the share-with-field
Then all users and groups that contain the string "grp" in their name should be listed in the autocomplete list on the webUI except group "grpuser"
When the user types "grou" in the share-with-field
Then all users and groups that contain the string "grou" in their name should be listed in the autocomplete list on the webUI except group "groupuser"
And the users own name should not be listed in the autocomplete list on the webUI
Loading

0 comments on commit b28153d

Please sign in to comment.