Skip to content

Commit

Permalink
Merge pull request #9488 from nextcloud/disabled-users-fix
Browse files Browse the repository at this point in the history
Added disabled count per groups & fixed disabled users query
  • Loading branch information
blizzz committed May 25, 2018
2 parents d4a0af7 + 4644841 commit 760b28b
Show file tree
Hide file tree
Showing 25 changed files with 370 additions and 105 deletions.
4 changes: 2 additions & 2 deletions apps/provisioning_api/lib/Controller/AUserData.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,12 @@ protected function getUserData(string $userId): array {
}

// Should be at least Admin Or SubAdmin!
if( $this->groupManager->isAdmin($currentLoggedInUser->getUID())
if ($this->groupManager->isAdmin($currentLoggedInUser->getUID())
|| $this->groupManager->getSubAdmin()->isUserAccessible($currentLoggedInUser, $targetUserObject)) {
$data['enabled'] = $this->config->getUserValue($targetUserObject->getUID(), 'core', 'enabled', 'true') === 'true';
} else {
// Check they are looking up themselves
if($currentLoggedInUser->getUID() !== $targetUserObject->getUID()) {
if ($currentLoggedInUser->getUID() !== $targetUserObject->getUID()) {
return $data;
}
}
Expand Down
11 changes: 10 additions & 1 deletion apps/provisioning_api/lib/Controller/GroupsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,12 @@ public function getGroupsDetails(string $search = '', int $limit = null, int $of
$groups = $this->groupManager->search($search, $limit, $offset);
$groups = array_map(function($group) {
/** @var IGroup $group */
return ['id' => $group->getGID(), 'displayname' => $group->getDisplayName()];
return [
'id' => $group->getGID(),
'displayname' => $group->getDisplayName(),
'usercount' => $group->count(),
'disabled' => $group->countDisabled()
];
}, $groups);

return new DataResponse(['groups' => $groups]);
Expand Down Expand Up @@ -202,6 +207,10 @@ public function getGroupUsersDetails(string $groupId, int $limit = null, int $of
// Do not insert empty entry
if(!empty($userData)) {
$usersDetails[$userId] = $userData;
} else {
// Logged user does not have permissions to see this user
// only showing its id
$usersDetails[$userId] = ['id' => $userId];
}
}
return new DataResponse(['users' => $usersDetails]);
Expand Down
4 changes: 4 additions & 0 deletions apps/provisioning_api/lib/Controller/UsersController.php
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,10 @@ public function getUsersDetails(string $search = '', $limit = null, $offset = 0)
// Do not insert empty entry
if (!empty($userData)) {
$usersDetails[$userId] = $userData;
} else {
// Logged user does not have permissions to see this user
// only showing its id
$usersDetails[$userId] = ['id' => $userId];
}
}

Expand Down
20 changes: 18 additions & 2 deletions apps/provisioning_api/tests/Controller/GroupsControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,12 @@ private function createGroup($gid) {
$group
->method('getDisplayName')
->willReturn($gid.'-name');
$group
->method('count')
->willReturn(123);
$group
->method('countDisabled')
->willReturn(11);

return $group;
}
Expand Down Expand Up @@ -205,8 +211,18 @@ public function testGetGroupsDetails($search, $limit, $offset) {

$result = $this->api->getGroupsDetails($search, $limit, $offset);
$this->assertEquals(['groups' => [
Array('id' => 'group1', 'displayname' => 'group1-name'),
Array('id' => 'group2', 'displayname' => 'group2-name')
Array(
'id' => 'group1',
'displayname' => 'group1-name',
'usercount' => 123,
'disabled' => 11
),
Array(
'id' => 'group2',
'displayname' => 'group2-name',
'usercount' => 123,
'disabled' => 11
)
]], $result->getData());

}
Expand Down
1 change: 1 addition & 0 deletions lib/composer/composer/autoload_classmap.php
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@
'OCP\\GroupInterface' => $baseDir . '/lib/public/GroupInterface.php',
'OCP\\Group\\Backend\\ABackend' => $baseDir . '/lib/public/Group/Backend/ABackend.php',
'OCP\\Group\\Backend\\IAddToGroupBackend' => $baseDir . '/lib/public/Group/Backend/IAddToGroupBackend.php',
'OCP\\Group\\Backend\\ICountDisabledInGroup' => $baseDir . '/lib/public/Group/Backend/ICountDisabledInGroup.php',
'OCP\\Group\\Backend\\ICountUsersBackend' => $baseDir . '/lib/public/Group/Backend/ICountUsersBackend.php',
'OCP\\Group\\Backend\\ICreateGroupBackend' => $baseDir . '/lib/public/Group/Backend/ICreateGroupBackend.php',
'OCP\\Group\\Backend\\IDeleteGroupBackend' => $baseDir . '/lib/public/Group/Backend/IDeleteGroupBackend.php',
Expand Down
1 change: 1 addition & 0 deletions lib/composer/composer/autoload_static.php
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
'OCP\\GroupInterface' => __DIR__ . '/../../..' . '/lib/public/GroupInterface.php',
'OCP\\Group\\Backend\\ABackend' => __DIR__ . '/../../..' . '/lib/public/Group/Backend/ABackend.php',
'OCP\\Group\\Backend\\IAddToGroupBackend' => __DIR__ . '/../../..' . '/lib/public/Group/Backend/IAddToGroupBackend.php',
'OCP\\Group\\Backend\\ICountDisabledInGroup' => __DIR__ . '/../../..' . '/lib/public/Group/Backend/ICountDisabledInGroup.php',
'OCP\\Group\\Backend\\ICountUsersBackend' => __DIR__ . '/../../..' . '/lib/public/Group/Backend/ICountUsersBackend.php',
'OCP\\Group\\Backend\\ICreateGroupBackend' => __DIR__ . '/../../..' . '/lib/public/Group/Backend/ICreateGroupBackend.php',
'OCP\\Group\\Backend\\IDeleteGroupBackend' => __DIR__ . '/../../..' . '/lib/public/Group/Backend/IDeleteGroupBackend.php',
Expand Down
35 changes: 35 additions & 0 deletions lib/private/Group/Database.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* @author Aaron Wood <aaronjwood@gmail.com>
* @author Loki3000 <github@labcms.ru>
* @author Roeland Jago Douma <roeland@famdouma.nl>
* @author John Molakvoæ <skjnldsv@protonmail.com>
*
* @license AGPL-3.0
*
Expand Down Expand Up @@ -40,8 +41,10 @@

namespace OC\Group;

use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\Group\Backend\ABackend;
use OCP\Group\Backend\IAddToGroupBackend;
use OCP\Group\Backend\ICountDisabledInGroup;
use OCP\Group\Backend\ICountUsersBackend;
use OCP\Group\Backend\ICreateGroupBackend;
use OCP\Group\Backend\IDeleteGroupBackend;
Expand All @@ -53,6 +56,7 @@
*/
class Database extends ABackend
implements IAddToGroupBackend,
ICountDisabledInGroup,
ICountUsersBackend,
ICreateGroupBackend,
IDeleteGroupBackend,
Expand Down Expand Up @@ -373,4 +377,35 @@ public function countUsersInGroup(string $gid, string $search = ''): int {
return $count;
}

/**
* get the number of disabled users in a group
*
* @param string $search
* @return int|bool
*/
public function countDisabledInGroup(string $gid): int {
$this->fixDI();

$query = $this->dbConn->getQueryBuilder();
$query->select($query->createFunction('COUNT(Distinct uid)'))
->from('preferences', 'p')
->innerJoin('p', 'group_user', 'g', 'p.userid = g.uid')
->where($query->expr()->eq('appid', $query->createNamedParameter('core')))
->andWhere($query->expr()->eq('configkey', $query->createNamedParameter('enabled')))
->andWhere($query->expr()->eq('configvalue', $query->createNamedParameter('false'), IQueryBuilder::PARAM_STR))
->andWhere($query->expr()->eq('gid', $query->createNamedParameter($gid), IQueryBuilder::PARAM_STR));

$result = $query->execute();
$count = $result->fetchColumn();
$result->closeCursor();

if ($count !== false) {
$count = (int)$count;
} else {
$count = 0;
}

return $count;
}

}
22 changes: 22 additions & 0 deletions lib/private/Group/Group.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
* @author Robin McCorkell <robin@mccorkell.me.uk>
* @author Roeland Jago Douma <roeland@famdouma.nl>
* @author Vincent Petry <pvince81@owncloud.com>
* @author John Molakvoæ <skjnldsv@protonmail.com>
*
* @license AGPL-3.0
*
Expand All @@ -31,6 +32,7 @@

use OCP\IGroup;
use OCP\IUser;
use OCP\Group\Backend\ICountDisabledInGroup;

class Group implements IGroup {
/** @var null|string */
Expand Down Expand Up @@ -236,6 +238,26 @@ public function count($search = '') {
return $users;
}

/**
* returns the number of disabled users
*
* @return int|bool
*/
public function countDisabled() {
$users = false;
foreach ($this->backends as $backend) {
if($backend instanceOf ICountDisabledInGroup) {
if($users === false) {
//we could directly add to a bool variable, but this would
//be ugly
$users = 0;
}
$users += $backend->countDisabledInGroup($this->gid);
}
}
return $users;
}

/**
* search for users in the group by displayname
*
Expand Down
14 changes: 9 additions & 5 deletions lib/private/Group/MetaData.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
* @author Morris Jobke <hey@morrisjobke.de>
* @author Stephan Peijnik <speijnik@anexia-it.com>
* @author Thomas Müller <thomas.mueller@tmit.eu>
* @author John Molakvoæ <skjnldsv@protonmail.com>
*
* @license AGPL-3.0
*
Expand All @@ -28,6 +29,7 @@
namespace OC\Group;

use OCP\IUserSession;
use OCP\IGroupManager;

class MetaData {
const SORT_NONE = 0;
Expand All @@ -40,7 +42,7 @@ class MetaData {
protected $isAdmin;
/** @var array */
protected $metaData = array();
/** @var \OCP\IGroupManager */
/** @var IGroupManager */
protected $groupManager;
/** @var bool */
protected $sorting = false;
Expand All @@ -50,13 +52,14 @@ class MetaData {
/**
* @param string $user the uid of the current user
* @param bool $isAdmin whether the current users is an admin
* @param \OCP\IGroupManager $groupManager
* @param IGroupManager $groupManager
* @param IUserManager $userManager
* @param IUserSession $userSession
*/
public function __construct(
$user,
$isAdmin,
\OCP\IGroupManager $groupManager,
IGroupManager $groupManager,
IUserSession $userSession
) {
$this->user = $user;
Expand Down Expand Up @@ -155,13 +158,14 @@ private function addEntry(&$entries, &$sortKeys, &$sortIndex, $data) {
* creates an array containing the group meta data
* @param \OCP\IGroup $group
* @param string $userSearch
* @return array with the keys 'id', 'name' and 'usercount'
* @return array with the keys 'id', 'name', 'usercount' and 'disabled'
*/
private function generateGroupMetaData(\OCP\IGroup $group, $userSearch) {
return array(
'id' => $group->getGID(),
'name' => $group->getDisplayName(),
'usercount' => $this->sorting === self::SORT_USERCOUNT ? $group->count($userSearch) : 0,
'disabled' => $group->countDisabled()
);
}

Expand All @@ -184,7 +188,7 @@ private function sort(&$entries, $sortKeys) {
* @param string $search a search string
* @return \OCP\IGroup[]
*/
protected function getGroups($search = '') {
public function getGroups($search = '') {
if($this->isAdmin) {
return $this->groupManager->search($search);
} else {
Expand Down
67 changes: 61 additions & 6 deletions lib/private/User/Manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
use OC\Hooks\PublicEmitter;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IUser;
use OCP\IGroup;
use OCP\IUserBackend;
use OCP\IUserManager;
use OCP\IConfig;
Expand Down Expand Up @@ -384,6 +385,24 @@ public function countUsers($hasLoggedIn = false) {
return $userCountStatistics;
}

/**
* returns how many users per backend exist in the requested groups (if supported by backend)
*
* @param IGroup[] $groups an array of gid to search in
* @return array|int an array of backend class as key and count number as value
* if $hasLoggedIn is true only an int is returned
*/
public function countUsersOfGroups(array $groups) {
$users = [];
foreach($groups as $group) {
$usersIds = array_map(function($user) {
return $user->getUID();
}, $group->getUsers());
$users = array_merge($users, $usersIds);
}
return count(array_unique($users));
}

/**
* The callback is executed for each user on each backend.
* If the callback returns false no further users will be retrieved.
Expand Down Expand Up @@ -420,25 +439,61 @@ public function callForAllUsers(\Closure $callback, $search = '', $onlySeen = fa
}

/**
* returns how many users have logged in once
* returns how many users are disabled
*
* @return int
* @since 12.0.0
*/
public function countDisabledUsers() {
public function countDisabledUsers(): int {
$queryBuilder = \OC::$server->getDatabaseConnection()->getQueryBuilder();
$queryBuilder->select($queryBuilder->createFunction('COUNT(*)'))
->from('preferences')
->where($queryBuilder->expr()->eq('appid', $queryBuilder->createNamedParameter('core')))
->andWhere($queryBuilder->expr()->eq('configkey', $queryBuilder->createNamedParameter('enabled')))
->andWhere($queryBuilder->expr()->eq('configvalue', $queryBuilder->createNamedParameter('false'), IQueryBuilder::PARAM_STR));

$query = $queryBuilder->execute();

$result = $queryBuilder->execute();
$count = $result->fetchColumn();
$result->closeCursor();

if ($count !== false) {
$count = (int)$count;
} else {
$count = 0;
}

$result = (int)$query->fetchColumn();
$query->closeCursor();
return $count;
}

return $result;
/**
* returns how many users are disabled in the requested groups
*
* @param array $groups groupids to search
* @return int
* @since 14.0.0
*/
public function countDisabledUsersOfGroups(array $groups): int {
$queryBuilder = \OC::$server->getDatabaseConnection()->getQueryBuilder();
$queryBuilder->select($queryBuilder->createFunction('COUNT(Distinct uid)'))
->from('preferences', 'p')
->innerJoin('p', 'group_user', 'g', 'p.userid = g.uid')
->where($queryBuilder->expr()->eq('appid', $queryBuilder->createNamedParameter('core')))
->andWhere($queryBuilder->expr()->eq('configkey', $queryBuilder->createNamedParameter('enabled')))
->andWhere($queryBuilder->expr()->eq('configvalue', $queryBuilder->createNamedParameter('false'), IQueryBuilder::PARAM_STR))
->andWhere($queryBuilder->expr()->in('gid', $queryBuilder->createNamedParameter($groups, IQueryBuilder::PARAM_STR_ARRAY)));

$result = $queryBuilder->execute();
$count = $result->fetchColumn();
$result->closeCursor();

if ($count !== false) {
$count = (int)$count;
} else {
$count = 0;
}

return $count;
}

/**
Expand Down
Loading

0 comments on commit 760b28b

Please sign in to comment.