mirror of
https://github.com/nextcloud/server.git
synced 2026-05-28 04:32:30 -04:00
feat(users): Add support for admin delegation for users and groups management
Signed-off-by: Louis Chemineau <louis@chmn.me>
This commit is contained in:
parent
1af827fdb3
commit
dff8815449
13 changed files with 182 additions and 53 deletions
|
|
@ -98,7 +98,9 @@ abstract class AUserData extends OCSController {
|
|||
}
|
||||
|
||||
$isAdmin = $this->groupManager->isAdmin($currentLoggedInUser->getUID());
|
||||
$isDelegatedAdmin = $this->groupManager->isDelegatedAdmin($currentLoggedInUser->getUID());
|
||||
if ($isAdmin
|
||||
|| $isDelegatedAdmin
|
||||
|| $this->groupManager->getSubAdmin()->isUserAccessible($currentLoggedInUser, $targetUserObject)) {
|
||||
$data['enabled'] = $this->config->getUserValue($targetUserObject->getUID(), 'core', 'enabled', 'true') === 'true';
|
||||
} else {
|
||||
|
|
@ -116,7 +118,7 @@ abstract class AUserData extends OCSController {
|
|||
$gids[] = $group->getGID();
|
||||
}
|
||||
|
||||
if ($isAdmin) {
|
||||
if ($isAdmin || $isDelegatedAdmin) {
|
||||
try {
|
||||
# might be thrown by LDAP due to handling of users disappears
|
||||
# from the external source (reasons unknown to us)
|
||||
|
|
|
|||
|
|
@ -9,8 +9,10 @@ declare(strict_types=1);
|
|||
namespace OCA\Provisioning_API\Controller;
|
||||
|
||||
use OCA\Provisioning_API\ResponseDefinitions;
|
||||
use OCA\Settings\Settings\Admin\Users;
|
||||
use OCP\Accounts\IAccountManager;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\Attribute\AuthorizedAdminSetting;
|
||||
use OCP\AppFramework\Http\DataResponse;
|
||||
use OCP\AppFramework\OCS\OCSException;
|
||||
use OCP\AppFramework\OCS\OCSForbiddenException;
|
||||
|
|
@ -154,8 +156,9 @@ class GroupsController extends AUserData {
|
|||
}
|
||||
|
||||
// Check subadmin has access to this group
|
||||
if ($this->groupManager->isAdmin($user->getUID())
|
||||
|| $isSubadminOfGroup) {
|
||||
$isAdmin = $this->groupManager->isAdmin($user->getUID());
|
||||
$isDelegatedAdmin = $this->groupManager->isDelegatedAdmin($user->getUID());
|
||||
if ($isAdmin || $isDelegatedAdmin || $isSubadminOfGroup) {
|
||||
$users = $this->groupManager->get($groupId)->getUsers();
|
||||
$users = array_map(function ($user) {
|
||||
/** @var IUser $user */
|
||||
|
|
@ -197,7 +200,9 @@ class GroupsController extends AUserData {
|
|||
}
|
||||
|
||||
// Check subadmin has access to this group
|
||||
if ($this->groupManager->isAdmin($currentUser->getUID()) || $isSubadminOfGroup) {
|
||||
$isAdmin = $this->groupManager->isAdmin($currentUser->getUID());
|
||||
$isDelegatedAdmin = $this->groupManager->isDelegatedAdmin($currentUser->getUID());
|
||||
if ($isAdmin || $isDelegatedAdmin || $isSubadminOfGroup) {
|
||||
$users = $group->searchUsers($search, $limit, $offset);
|
||||
|
||||
// Extract required number
|
||||
|
|
@ -237,6 +242,7 @@ class GroupsController extends AUserData {
|
|||
*
|
||||
* 200: Group created successfully
|
||||
*/
|
||||
#[AuthorizedAdminSetting(settings:Users::class)]
|
||||
public function addGroup(string $groupid, string $displayname = ''): DataResponse {
|
||||
// Validate name
|
||||
if (empty($groupid)) {
|
||||
|
|
@ -270,6 +276,7 @@ class GroupsController extends AUserData {
|
|||
*
|
||||
* 200: Group updated successfully
|
||||
*/
|
||||
#[AuthorizedAdminSetting(settings:Users::class)]
|
||||
public function updateGroup(string $groupId, string $key, string $value): DataResponse {
|
||||
$groupId = urldecode($groupId);
|
||||
|
||||
|
|
@ -299,6 +306,7 @@ class GroupsController extends AUserData {
|
|||
*
|
||||
* 200: Group deleted successfully
|
||||
*/
|
||||
#[AuthorizedAdminSetting(settings:Users::class)]
|
||||
public function deleteGroup(string $groupId): DataResponse {
|
||||
$groupId = urldecode($groupId);
|
||||
|
||||
|
|
@ -322,6 +330,7 @@ class GroupsController extends AUserData {
|
|||
*
|
||||
* 200: Sub admins returned
|
||||
*/
|
||||
#[AuthorizedAdminSetting(settings:Users::class)]
|
||||
public function getSubAdminsOfGroup(string $groupId): DataResponse {
|
||||
// Check group exists
|
||||
$targetGroup = $this->groupManager->get($groupId);
|
||||
|
|
|
|||
|
|
@ -16,10 +16,12 @@ use OC\KnownUser\KnownUserService;
|
|||
use OC\User\Backend;
|
||||
use OCA\Provisioning_API\ResponseDefinitions;
|
||||
use OCA\Settings\Mailer\NewUserMailHelper;
|
||||
use OCA\Settings\Settings\Admin\Users;
|
||||
use OCP\Accounts\IAccountManager;
|
||||
use OCP\Accounts\IAccountProperty;
|
||||
use OCP\Accounts\PropertyDoesNotExistException;
|
||||
use OCP\AppFramework\Http;
|
||||
use OCP\AppFramework\Http\Attribute\AuthorizedAdminSetting;
|
||||
use OCP\AppFramework\Http\DataResponse;
|
||||
use OCP\AppFramework\OCS\OCSException;
|
||||
use OCP\AppFramework\OCS\OCSForbiddenException;
|
||||
|
|
@ -101,7 +103,9 @@ class UsersController extends AUserData {
|
|||
// Admin? Or SubAdmin?
|
||||
$uid = $user->getUID();
|
||||
$subAdminManager = $this->groupManager->getSubAdmin();
|
||||
if ($this->groupManager->isAdmin($uid)) {
|
||||
$isAdmin = $this->groupManager->isAdmin($uid);
|
||||
$isDelegatedAdmin = $this->groupManager->isDelegatedAdmin($uid);
|
||||
if ($isAdmin || $isDelegatedAdmin) {
|
||||
$users = $this->userManager->search($search, $limit, $offset);
|
||||
} elseif ($subAdminManager->isSubAdmin($user)) {
|
||||
$subAdminOfGroups = $subAdminManager->getSubAdminsGroups($user);
|
||||
|
|
@ -142,7 +146,9 @@ class UsersController extends AUserData {
|
|||
// Admin? Or SubAdmin?
|
||||
$uid = $currentUser->getUID();
|
||||
$subAdminManager = $this->groupManager->getSubAdmin();
|
||||
if ($this->groupManager->isAdmin($uid)) {
|
||||
$isAdmin = $this->groupManager->isAdmin($uid);
|
||||
$isDelegatedAdmin = $this->groupManager->isDelegatedAdmin($uid);
|
||||
if ($isAdmin || $isDelegatedAdmin) {
|
||||
$users = $this->userManager->search($search, $limit, $offset);
|
||||
$users = array_keys($users);
|
||||
} elseif ($subAdminManager->isSubAdmin($currentUser)) {
|
||||
|
|
@ -213,7 +219,9 @@ class UsersController extends AUserData {
|
|||
// Admin? Or SubAdmin?
|
||||
$uid = $currentUser->getUID();
|
||||
$subAdminManager = $this->groupManager->getSubAdmin();
|
||||
if ($this->groupManager->isAdmin($uid)) {
|
||||
$isAdmin = $this->groupManager->isAdmin($uid);
|
||||
$isDelegatedAdmin = $this->groupManager->isDelegatedAdmin($uid);
|
||||
if ($isAdmin || $isDelegatedAdmin) {
|
||||
$users = $this->userManager->getDisabledUsers($limit, $offset, $search);
|
||||
$users = array_map(fn (IUser $user): string => $user->getUID(), $users);
|
||||
} elseif ($subAdminManager->isSubAdmin($currentUser)) {
|
||||
|
|
@ -275,6 +283,7 @@ class UsersController extends AUserData {
|
|||
*
|
||||
* 200: Users details returned based on last logged in information
|
||||
*/
|
||||
#[AuthorizedAdminSetting(settings:Users::class)]
|
||||
public function getLastLoggedInUsers(string $search = '',
|
||||
?int $limit = null,
|
||||
int $offset = 0,
|
||||
|
|
@ -447,6 +456,7 @@ class UsersController extends AUserData {
|
|||
): DataResponse {
|
||||
$user = $this->userSession->getUser();
|
||||
$isAdmin = $this->groupManager->isAdmin($user->getUID());
|
||||
$isDelegatedAdmin = $this->groupManager->isDelegatedAdmin($user->getUID());
|
||||
$subAdminManager = $this->groupManager->getSubAdmin();
|
||||
|
||||
if (empty($userid) && $this->config->getAppValue('core', 'newUser.generateUserID', 'no') === 'yes') {
|
||||
|
|
@ -463,12 +473,12 @@ class UsersController extends AUserData {
|
|||
if (!$this->groupManager->groupExists($group)) {
|
||||
throw new OCSException($this->l10n->t('Group %1$s does not exist', [$group]), 104);
|
||||
}
|
||||
if (!$isAdmin && !$subAdminManager->isSubAdminOfGroup($user, $this->groupManager->get($group))) {
|
||||
if (!$isAdmin && !($isDelegatedAdmin && $group !== 'admin') && !$subAdminManager->isSubAdminOfGroup($user, $this->groupManager->get($group))) {
|
||||
throw new OCSException($this->l10n->t('Insufficient privileges for group %1$s', [$group]), 105);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!$isAdmin) {
|
||||
if (!$isAdmin && !$isDelegatedAdmin) {
|
||||
throw new OCSException($this->l10n->t('No group specified (required for sub-admins)'), 106);
|
||||
}
|
||||
}
|
||||
|
|
@ -486,7 +496,7 @@ class UsersController extends AUserData {
|
|||
throw new OCSException($this->l10n->t('Cannot create sub-admins for admin group'), 103);
|
||||
}
|
||||
// Check if has permission to promote subadmins
|
||||
if (!$subAdminManager->isSubAdminOfGroup($user, $group) && !$isAdmin) {
|
||||
if (!$subAdminManager->isSubAdminOfGroup($user, $group) && !$isAdmin && !$isDelegatedAdmin) {
|
||||
throw new OCSForbiddenException($this->l10n->t('No permissions to promote sub-admins'));
|
||||
}
|
||||
$subadminGroups[] = $group;
|
||||
|
|
@ -718,8 +728,10 @@ class UsersController extends AUserData {
|
|||
}
|
||||
|
||||
$subAdminManager = $this->groupManager->getSubAdmin();
|
||||
$isAdmin = $this->groupManager->isAdmin($currentLoggedInUser->getUID());
|
||||
$isDelegatedAdmin = $this->groupManager->isDelegatedAdmin($currentLoggedInUser->getUID());
|
||||
if (
|
||||
!$this->groupManager->isAdmin($currentLoggedInUser->getUID())
|
||||
!($isAdmin || $isDelegatedAdmin)
|
||||
&& !$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)
|
||||
) {
|
||||
throw new OCSException('', OCSController::RESPOND_NOT_FOUND);
|
||||
|
|
@ -788,6 +800,7 @@ class UsersController extends AUserData {
|
|||
}
|
||||
|
||||
$subAdminManager = $this->groupManager->getSubAdmin();
|
||||
$isDelegatedAdmin = $this->groupManager->isDelegatedAdmin($currentLoggedInUser->getUID());
|
||||
$isAdminOrSubadmin = $this->groupManager->isAdmin($currentLoggedInUser->getUID())
|
||||
|| $subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser);
|
||||
|
||||
|
|
@ -798,7 +811,7 @@ class UsersController extends AUserData {
|
|||
$permittedFields[] = IAccountManager::COLLECTION_EMAIL . self::SCOPE_SUFFIX;
|
||||
} else {
|
||||
// Check if admin / subadmin
|
||||
if ($isAdminOrSubadmin) {
|
||||
if ($isAdminOrSubadmin || $isDelegatedAdmin && !$this->groupManager->isInGroup($targetUser->getUID(), 'admin')) {
|
||||
// They have permissions over the user
|
||||
$permittedFields[] = IAccountManager::COLLECTION_EMAIL;
|
||||
} else {
|
||||
|
|
@ -903,14 +916,16 @@ class UsersController extends AUserData {
|
|||
$permittedFields[] = self::USER_FIELD_NOTIFICATION_EMAIL;
|
||||
if (
|
||||
$this->config->getSystemValue('force_language', false) === false ||
|
||||
$this->groupManager->isAdmin($currentLoggedInUser->getUID())
|
||||
$this->groupManager->isAdmin($currentLoggedInUser->getUID()) ||
|
||||
$this->groupManager->isDelegatedAdmin($currentLoggedInUser->getUID())
|
||||
) {
|
||||
$permittedFields[] = self::USER_FIELD_LANGUAGE;
|
||||
}
|
||||
|
||||
if (
|
||||
$this->config->getSystemValue('force_locale', false) === false ||
|
||||
$this->groupManager->isAdmin($currentLoggedInUser->getUID())
|
||||
$this->groupManager->isAdmin($currentLoggedInUser->getUID()) ||
|
||||
$this->groupManager->isDelegatedAdmin($currentLoggedInUser->getUID())
|
||||
) {
|
||||
$permittedFields[] = self::USER_FIELD_LOCALE;
|
||||
}
|
||||
|
|
@ -941,7 +956,9 @@ class UsersController extends AUserData {
|
|||
$permittedFields[] = IAccountManager::PROPERTY_AVATAR . self::SCOPE_SUFFIX;
|
||||
|
||||
// If admin they can edit their own quota and manager
|
||||
if ($this->groupManager->isAdmin($currentLoggedInUser->getUID())) {
|
||||
$isAdmin = $this->groupManager->isAdmin($currentLoggedInUser->getUID());
|
||||
$isDelegatedAdmin = $this->groupManager->isDelegatedAdmin($currentLoggedInUser->getUID());
|
||||
if ($isAdmin || $isDelegatedAdmin) {
|
||||
$permittedFields[] = self::USER_FIELD_QUOTA;
|
||||
$permittedFields[] = self::USER_FIELD_MANAGER;
|
||||
}
|
||||
|
|
@ -949,7 +966,8 @@ class UsersController extends AUserData {
|
|||
// Check if admin / subadmin
|
||||
$subAdminManager = $this->groupManager->getSubAdmin();
|
||||
if (
|
||||
$this->groupManager->isAdmin($currentLoggedInUser->getUID())
|
||||
$this->groupManager->isAdmin($currentLoggedInUser->getUID()) ||
|
||||
$this->groupManager->isDelegatedAdmin($currentLoggedInUser->getUID()) && !$this->groupManager->isInGroup($targetUser->getUID(), 'admin')
|
||||
|| $subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)
|
||||
) {
|
||||
// They have permissions over the user
|
||||
|
|
@ -1204,7 +1222,9 @@ class UsersController extends AUserData {
|
|||
|
||||
// If not permitted
|
||||
$subAdminManager = $this->groupManager->getSubAdmin();
|
||||
if (!$this->groupManager->isAdmin($currentLoggedInUser->getUID()) && !$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)) {
|
||||
$isAdmin = $this->groupManager->isAdmin($currentLoggedInUser->getUID());
|
||||
$isDelegatedAdmin = $this->groupManager->isDelegatedAdmin($currentLoggedInUser->getUID());
|
||||
if (!$isAdmin && !($isDelegatedAdmin && !$this->groupManager->isInGroup($targetUser->getUID(), 'admin')) && !$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)) {
|
||||
throw new OCSException('', OCSController::RESPOND_NOT_FOUND);
|
||||
}
|
||||
|
||||
|
|
@ -1240,7 +1260,9 @@ class UsersController extends AUserData {
|
|||
|
||||
// If not permitted
|
||||
$subAdminManager = $this->groupManager->getSubAdmin();
|
||||
if (!$this->groupManager->isAdmin($currentLoggedInUser->getUID()) && !$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)) {
|
||||
$isAdmin = $this->groupManager->isAdmin($currentLoggedInUser->getUID());
|
||||
$isDelegatedAdmin = $this->groupManager->isDelegatedAdmin($currentLoggedInUser->getUID());
|
||||
if (!$isAdmin && !($isDelegatedAdmin && !$this->groupManager->isInGroup($targetUser->getUID(), 'admin')) && !$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)) {
|
||||
throw new OCSException('', OCSController::RESPOND_NOT_FOUND);
|
||||
}
|
||||
|
||||
|
|
@ -1300,7 +1322,9 @@ class UsersController extends AUserData {
|
|||
|
||||
// If not permitted
|
||||
$subAdminManager = $this->groupManager->getSubAdmin();
|
||||
if (!$this->groupManager->isAdmin($currentLoggedInUser->getUID()) && !$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)) {
|
||||
$isAdmin = $this->groupManager->isAdmin($currentLoggedInUser->getUID());
|
||||
$isDelegatedAdmin = $this->groupManager->isDelegatedAdmin($currentLoggedInUser->getUID());
|
||||
if (!$isAdmin && !($isDelegatedAdmin && !$this->groupManager->isInGroup($targetUser->getUID(), 'admin')) && !$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)) {
|
||||
throw new OCSException('', OCSController::RESPOND_NOT_FOUND);
|
||||
}
|
||||
|
||||
|
|
@ -1329,7 +1353,9 @@ class UsersController extends AUserData {
|
|||
throw new OCSException('', OCSController::RESPOND_NOT_FOUND);
|
||||
}
|
||||
|
||||
if ($targetUser->getUID() === $loggedInUser->getUID() || $this->groupManager->isAdmin($loggedInUser->getUID())) {
|
||||
$isAdmin = $this->groupManager->isAdmin($loggedInUser->getUID());
|
||||
$isDelegatedAdmin = $this->groupManager->isDelegatedAdmin($loggedInUser->getUID());
|
||||
if ($targetUser->getUID() === $loggedInUser->getUID() || $isAdmin || $isDelegatedAdmin) {
|
||||
// Self lookup or admin lookup
|
||||
return new DataResponse([
|
||||
'groups' => $this->groupManager->getUserGroupIds($targetUser)
|
||||
|
|
@ -1388,7 +1414,9 @@ class UsersController extends AUserData {
|
|||
// If they're not an admin, check they are a subadmin of the group in question
|
||||
$loggedInUser = $this->userSession->getUser();
|
||||
$subAdminManager = $this->groupManager->getSubAdmin();
|
||||
if (!$this->groupManager->isAdmin($loggedInUser->getUID()) && !$subAdminManager->isSubAdminOfGroup($loggedInUser, $group)) {
|
||||
$isAdmin = $this->groupManager->isAdmin($loggedInUser->getUID());
|
||||
$isDelegatedAdmin = $this->groupManager->isDelegatedAdmin($loggedInUser->getUID());
|
||||
if (!$isAdmin && !($isDelegatedAdmin && $groupid !== 'admin') && !$subAdminManager->isSubAdminOfGroup($loggedInUser, $group)) {
|
||||
throw new OCSException('', 104);
|
||||
}
|
||||
|
||||
|
|
@ -1429,13 +1457,15 @@ class UsersController extends AUserData {
|
|||
|
||||
// If they're not an admin, check they are a subadmin of the group in question
|
||||
$subAdminManager = $this->groupManager->getSubAdmin();
|
||||
if (!$this->groupManager->isAdmin($loggedInUser->getUID()) && !$subAdminManager->isSubAdminOfGroup($loggedInUser, $group)) {
|
||||
$isAdmin = $this->groupManager->isAdmin($loggedInUser->getUID());
|
||||
$isDelegatedAdmin = $this->groupManager->isDelegatedAdmin($loggedInUser->getUID());
|
||||
if (!$isAdmin && !($isDelegatedAdmin && $groupid !== 'admin') && !$subAdminManager->isSubAdminOfGroup($loggedInUser, $group)) {
|
||||
throw new OCSException('', 104);
|
||||
}
|
||||
|
||||
// Check they aren't removing themselves from 'admin' or their 'subadmin; group
|
||||
if ($targetUser->getUID() === $loggedInUser->getUID()) {
|
||||
if ($this->groupManager->isAdmin($loggedInUser->getUID())) {
|
||||
if ($isAdmin || $isDelegatedAdmin) {
|
||||
if ($group->getGID() === 'admin') {
|
||||
throw new OCSException($this->l10n->t('Cannot remove yourself from the admin group'), 105);
|
||||
}
|
||||
|
|
@ -1443,7 +1473,7 @@ class UsersController extends AUserData {
|
|||
// Not an admin, so the user must be a subadmin of this group, but that is not allowed.
|
||||
throw new OCSException($this->l10n->t('Cannot remove yourself from this group as you are a sub-admin'), 105);
|
||||
}
|
||||
} elseif (!$this->groupManager->isAdmin($loggedInUser->getUID())) {
|
||||
} elseif (!($isAdmin || $isDelegatedAdmin)) {
|
||||
/** @var IGroup[] $subAdminGroups */
|
||||
$subAdminGroups = $subAdminManager->getSubAdminsGroups($loggedInUser);
|
||||
$subAdminGroups = array_map(function (IGroup $subAdminGroup) {
|
||||
|
|
@ -1475,6 +1505,7 @@ class UsersController extends AUserData {
|
|||
*
|
||||
* 200: User added as group subadmin successfully
|
||||
*/
|
||||
#[AuthorizedAdminSetting(settings:Users::class)]
|
||||
public function addSubAdmin(string $userId, string $groupid): DataResponse {
|
||||
$group = $this->groupManager->get($groupid);
|
||||
$user = $this->userManager->get($userId);
|
||||
|
|
@ -1515,6 +1546,7 @@ class UsersController extends AUserData {
|
|||
*
|
||||
* 200: User removed as group subadmin successfully
|
||||
*/
|
||||
#[AuthorizedAdminSetting(settings:Users::class)]
|
||||
public function removeSubAdmin(string $userId, string $groupid): DataResponse {
|
||||
$group = $this->groupManager->get($groupid);
|
||||
$user = $this->userManager->get($userId);
|
||||
|
|
@ -1547,6 +1579,7 @@ class UsersController extends AUserData {
|
|||
*
|
||||
* 200: User subadmin groups returned
|
||||
*/
|
||||
#[AuthorizedAdminSetting(settings:Users::class)]
|
||||
public function getUserSubAdminGroups(string $userId): DataResponse {
|
||||
$groups = $this->getUserSubAdminGroupsData($userId);
|
||||
return new DataResponse($groups);
|
||||
|
|
@ -1574,9 +1607,11 @@ class UsersController extends AUserData {
|
|||
|
||||
// Check if admin / subadmin
|
||||
$subAdminManager = $this->groupManager->getSubAdmin();
|
||||
$isAdmin = $this->groupManager->isAdmin($currentLoggedInUser->getUID());
|
||||
$isDelegatedAdmin = $this->groupManager->isDelegatedAdmin($currentLoggedInUser->getUID());
|
||||
if (
|
||||
!$subAdminManager->isUserAccessible($currentLoggedInUser, $targetUser)
|
||||
&& !$this->groupManager->isAdmin($currentLoggedInUser->getUID())
|
||||
&& !($isAdmin || $isDelegatedAdmin)
|
||||
) {
|
||||
// No rights
|
||||
throw new OCSException('', OCSController::RESPOND_NOT_FOUND);
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
<admin>OCA\Settings\Settings\Admin\Sharing</admin>
|
||||
<admin>OCA\Settings\Settings\Admin\Security</admin>
|
||||
<admin>OCA\Settings\Settings\Admin\Delegation</admin>
|
||||
<admin>OCA\Settings\Settings\Admin\Users</admin>
|
||||
<admin-section>OCA\Settings\Sections\Admin\Additional</admin-section>
|
||||
<admin-section>OCA\Settings\Sections\Admin\Delegation</admin-section>
|
||||
<admin-section>OCA\Settings\Sections\Admin\Groupware</admin-section>
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ return array(
|
|||
'OCA\\Settings\\Settings\\Admin\\Security' => $baseDir . '/../lib/Settings/Admin/Security.php',
|
||||
'OCA\\Settings\\Settings\\Admin\\Server' => $baseDir . '/../lib/Settings/Admin/Server.php',
|
||||
'OCA\\Settings\\Settings\\Admin\\Sharing' => $baseDir . '/../lib/Settings/Admin/Sharing.php',
|
||||
'OCA\\Settings\\Settings\\Admin\\Users' => $baseDir . '/../lib/Settings/Admin/Users.php',
|
||||
'OCA\\Settings\\Settings\\Personal\\Additional' => $baseDir . '/../lib/Settings/Personal/Additional.php',
|
||||
'OCA\\Settings\\Settings\\Personal\\PersonalInfo' => $baseDir . '/../lib/Settings/Personal/PersonalInfo.php',
|
||||
'OCA\\Settings\\Settings\\Personal\\Security\\Authtokens' => $baseDir . '/../lib/Settings/Personal/Security/Authtokens.php',
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@ class ComposerStaticInitSettings
|
|||
'OCA\\Settings\\Settings\\Admin\\Security' => __DIR__ . '/..' . '/../lib/Settings/Admin/Security.php',
|
||||
'OCA\\Settings\\Settings\\Admin\\Server' => __DIR__ . '/..' . '/../lib/Settings/Admin/Server.php',
|
||||
'OCA\\Settings\\Settings\\Admin\\Sharing' => __DIR__ . '/..' . '/../lib/Settings/Admin/Sharing.php',
|
||||
'OCA\\Settings\\Settings\\Admin\\Users' => __DIR__ . '/..' . '/../lib/Settings/Admin/Users.php',
|
||||
'OCA\\Settings\\Settings\\Personal\\Additional' => __DIR__ . '/..' . '/../lib/Settings/Personal/Additional.php',
|
||||
'OCA\\Settings\\Settings\\Personal\\PersonalInfo' => __DIR__ . '/..' . '/../lib/Settings/Personal/PersonalInfo.php',
|
||||
'OCA\\Settings\\Settings\\Personal\\Security\\Authtokens' => __DIR__ . '/..' . '/../lib/Settings/Personal/Security/Authtokens.php',
|
||||
|
|
|
|||
|
|
@ -19,12 +19,14 @@ use OC\Security\IdentityProof\Manager;
|
|||
use OC\User\Manager as UserManager;
|
||||
use OCA\Settings\BackgroundJobs\VerifyUserData;
|
||||
use OCA\Settings\Events\BeforeTemplateRenderedEvent;
|
||||
use OCA\Settings\Settings\Admin\Users;
|
||||
use OCA\User_LDAP\User_Proxy;
|
||||
use OCP\Accounts\IAccount;
|
||||
use OCP\Accounts\IAccountManager;
|
||||
use OCP\Accounts\PropertyDoesNotExistException;
|
||||
use OCP\App\IAppManager;
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http\Attribute\AuthorizedAdminSetting;
|
||||
use OCP\AppFramework\Http\Attribute\OpenAPI;
|
||||
use OCP\AppFramework\Http\DataResponse;
|
||||
use OCP\AppFramework\Http\JSONResponse;
|
||||
|
|
@ -93,6 +95,7 @@ class UsersController extends Controller {
|
|||
$user = $this->userSession->getUser();
|
||||
$uid = $user->getUID();
|
||||
$isAdmin = $this->groupManager->isAdmin($uid);
|
||||
$isDelegatedAdmin = $this->groupManager->isDelegatedAdmin($uid);
|
||||
|
||||
\OC::$server->getNavigationManager()->setActiveEntry('core_users');
|
||||
|
||||
|
|
@ -118,6 +121,7 @@ class UsersController extends Controller {
|
|||
$groupsInfo = new \OC\Group\MetaData(
|
||||
$uid,
|
||||
$isAdmin,
|
||||
$isDelegatedAdmin,
|
||||
$this->groupManager,
|
||||
$this->userSession
|
||||
);
|
||||
|
|
@ -135,7 +139,7 @@ class UsersController extends Controller {
|
|||
$userCount = 0;
|
||||
|
||||
if (!$isLDAPUsed) {
|
||||
if ($isAdmin) {
|
||||
if ($isAdmin || $isDelegatedAdmin) {
|
||||
$disabledUsers = $this->userManager->countDisabledUsers();
|
||||
$userCount = array_reduce($this->userManager->countUsers(), function ($v, $w) {
|
||||
return $v + (int)$w;
|
||||
|
|
@ -200,7 +204,8 @@ class UsersController extends Controller {
|
|||
// groups
|
||||
$serverData['groups'] = array_merge_recursive($adminGroup, [$recentUsersGroup, $disabledUsersGroup], $groups);
|
||||
// Various data
|
||||
$serverData['isAdmin'] = $isAdmin;
|
||||
$serverData['isAdmin'] = $isAdmin || $isDelegatedAdmin;
|
||||
$serverData['isDelegatedAdmin'] = $isDelegatedAdmin;
|
||||
$serverData['sortGroups'] = $forceSortGroupByName
|
||||
? \OC\Group\MetaData::SORT_GROUPNAME
|
||||
: (int)$this->config->getAppValue('core', 'group.sortBy', (string)\OC\Group\MetaData::SORT_USERCOUNT);
|
||||
|
|
@ -232,6 +237,7 @@ class UsersController extends Controller {
|
|||
*
|
||||
* @return JSONResponse
|
||||
*/
|
||||
#[AuthorizedAdminSetting(settings:Users::class)]
|
||||
public function setPreference(string $key, string $value): JSONResponse {
|
||||
$allowed = ['newUser.sendEmail', 'group.sortBy'];
|
||||
if (!in_array($key, $allowed, true)) {
|
||||
|
|
|
|||
61
apps/settings/lib/Settings/Admin/Users.php
Normal file
61
apps/settings/lib/Settings/Admin/Users.php
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OCA\Settings\Settings\Admin;
|
||||
|
||||
use OCP\AppFramework\Http\TemplateResponse;
|
||||
use OCP\IL10N;
|
||||
use OCP\Settings\IDelegatedSettings;
|
||||
|
||||
/**
|
||||
* Empty settings class, used only for admin delegation.
|
||||
*/
|
||||
class Users implements IDelegatedSettings {
|
||||
|
||||
public function __construct(
|
||||
protected string $appName,
|
||||
private IL10N $l10n,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty template response
|
||||
*/
|
||||
public function getForm(): TemplateResponse {
|
||||
|
||||
return new /** @template-extends TemplateResponse<\OCP\AppFramework\Http::STATUS_OK, array{}> */ class($this->appName, '') extends TemplateResponse {
|
||||
public function render(): string {
|
||||
return '';
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public function getSection(): ?string {
|
||||
return 'admindelegation';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int whether the form should be rather on the top or bottom of
|
||||
* the admin section. The forms are arranged in ascending order of the
|
||||
* priority values. It is required to return a value between 0 and 100.
|
||||
*
|
||||
* E.g.: 70
|
||||
*/
|
||||
public function getPriority(): int {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function getName(): string {
|
||||
return $this->l10n->t('Users');
|
||||
}
|
||||
|
||||
public function getAuthorizedAppConfig(): array {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
|
@ -8,6 +8,7 @@
|
|||
namespace OC\Group;
|
||||
|
||||
use OC\Hooks\PublicEmitter;
|
||||
use OC\Settings\AuthorizedGroupMapper;
|
||||
use OCP\EventDispatcher\IEventDispatcher;
|
||||
use OCP\Group\Backend\IBatchMethodsBackend;
|
||||
use OCP\Group\Backend\ICreateNamedGroupBackend;
|
||||
|
|
@ -333,6 +334,18 @@ class Manager extends PublicEmitter implements IGroupManager {
|
|||
return $this->isInGroup($userId, 'admin');
|
||||
}
|
||||
|
||||
public function isDelegatedAdmin(string $userId): bool {
|
||||
if (!$this->remoteAddress->allowsAdminActions()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if the user as admin delegation for users listing
|
||||
$authorizedGroupMapper = \OCP\Server::get(AuthorizedGroupMapper::class);
|
||||
$user = $this->userManager->get($userId);
|
||||
$authorizedClasses = $authorizedGroupMapper->findAllClassesForUser($user);
|
||||
return in_array(\OCA\Settings\Settings\Admin\Users::class, $authorizedClasses, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a userId is in a group
|
||||
*
|
||||
|
|
|
|||
|
|
@ -17,33 +17,22 @@ class MetaData {
|
|||
public const SORT_USERCOUNT = 1; // May have performance issues on LDAP backends
|
||||
public const SORT_GROUPNAME = 2;
|
||||
|
||||
/** @var string */
|
||||
protected $user;
|
||||
/** @var bool */
|
||||
protected $isAdmin;
|
||||
/** @var array */
|
||||
protected $metaData = [];
|
||||
/** @var GroupManager */
|
||||
protected $groupManager;
|
||||
/** @var int */
|
||||
protected $sorting = self::SORT_NONE;
|
||||
/** @var IUserSession */
|
||||
protected $userSession;
|
||||
|
||||
/**
|
||||
* @param string $user the uid of the current user
|
||||
* @param bool $isAdmin whether the current users is an admin
|
||||
*/
|
||||
public function __construct(
|
||||
string $user,
|
||||
bool $isAdmin,
|
||||
IGroupManager $groupManager,
|
||||
IUserSession $userSession
|
||||
private string $user,
|
||||
private bool $isAdmin,
|
||||
private bool $isDelegatedAdmin,
|
||||
private IGroupManager $groupManager,
|
||||
private IUserSession $userSession
|
||||
) {
|
||||
$this->user = $user;
|
||||
$this->isAdmin = $isAdmin;
|
||||
$this->groupManager = $groupManager;
|
||||
$this->userSession = $userSession;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -162,11 +151,11 @@ class MetaData {
|
|||
* @return IGroup[]
|
||||
*/
|
||||
public function getGroups(string $search = ''): array {
|
||||
if ($this->isAdmin) {
|
||||
if ($this->isAdmin || $this->isDelegatedAdmin) {
|
||||
return $this->groupManager->search($search);
|
||||
} else {
|
||||
$userObject = $this->userSession->getUser();
|
||||
if ($userObject !== null) {
|
||||
if ($userObject !== null && $this->groupManager instanceof GroupManager) {
|
||||
$groups = $this->groupManager->getSubAdmin()->getSubAdminsGroups($userObject);
|
||||
} else {
|
||||
$groups = [];
|
||||
|
|
|
|||
|
|
@ -233,6 +233,11 @@ class SubAdmin extends PublicEmitter implements ISubAdmin {
|
|||
return true;
|
||||
}
|
||||
|
||||
// Check if the user is already an admin
|
||||
if ($this->groupManager->isDelegatedAdmin($user->getUID())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$qb = $this->dbConn->getQueryBuilder();
|
||||
|
||||
$result = $qb->select('gid')
|
||||
|
|
|
|||
|
|
@ -114,6 +114,14 @@ interface IGroupManager {
|
|||
*/
|
||||
public function isAdmin($userId);
|
||||
|
||||
/**
|
||||
* Checks if a userId is eligible to users administration delegation
|
||||
* @param string $userId
|
||||
* @return bool if delegated admin
|
||||
* @since 30.0.0
|
||||
*/
|
||||
public function isDelegatedAdmin(string $userId): bool;
|
||||
|
||||
/**
|
||||
* Checks if a userId is in a group
|
||||
* @param string $userId
|
||||
|
|
|
|||
|
|
@ -10,14 +10,11 @@ namespace Test\Group;
|
|||
use OCP\IUserSession;
|
||||
|
||||
class MetaDataTest extends \Test\TestCase {
|
||||
/** @var \OC\Group\Manager */
|
||||
private $groupManager;
|
||||
/** @var \OCP\IUserSession */
|
||||
private $userSession;
|
||||
/** @var \OC\Group\MetaData */
|
||||
private $groupMetadata;
|
||||
/** @var bool */
|
||||
private $isAdmin = true;
|
||||
private \OC\Group\Manager $groupManager;
|
||||
private IUserSession $userSession;
|
||||
private \OC\Group\MetaData $groupMetadata;
|
||||
private bool $isAdmin = true;
|
||||
private bool $isDelegatedAdmin = true;
|
||||
|
||||
protected function setUp(): void {
|
||||
parent::setUp();
|
||||
|
|
@ -28,6 +25,7 @@ class MetaDataTest extends \Test\TestCase {
|
|||
$this->groupMetadata = new \OC\Group\MetaData(
|
||||
'foo',
|
||||
$this->isAdmin,
|
||||
$this->isDelegatedAdmin,
|
||||
$this->groupManager,
|
||||
$this->userSession
|
||||
);
|
||||
|
|
|
|||
Loading…
Reference in a new issue