Skip to content

Commit

Permalink
Merge pull request #48538 from nextcloud/fix/get-managers-as-subadmin
Browse files Browse the repository at this point in the history
fix: Return correct list of managers for a user
  • Loading branch information
Pytal authored Oct 9, 2024
2 parents 85e3c9a + 96035d2 commit d66e469
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 49 deletions.
74 changes: 43 additions & 31 deletions apps/provisioning_api/lib/Controller/AUserData.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
*/
namespace OCA\Provisioning_API\Controller;

use OC\Group\Manager;
use OC\Group\Manager as GroupManager;
use OC\User\Backend;
use OC\User\NoUserException;
use OC_Helper;
Expand All @@ -20,9 +20,10 @@
use OCP\AppFramework\OCS\OCSNotFoundException;
use OCP\AppFramework\OCSController;
use OCP\Files\NotFoundException;
use OCP\Group\ISubAdmin;
use OCP\IConfig;
use OCP\IGroupManager;
use OCP\IRequest;
use OCP\IUser;
use OCP\IUserManager;
use OCP\IUserSession;
use OCP\L10N\IFactory;
Expand All @@ -45,35 +46,18 @@ abstract class AUserData extends OCSController {
public const USER_FIELD_MANAGER = 'manager';
public const USER_FIELD_NOTIFICATION_EMAIL = 'notify_email';

/** @var IUserManager */
protected $userManager;
/** @var IConfig */
protected $config;
/** @var Manager */
protected $groupManager;
/** @var IUserSession */
protected $userSession;
/** @var IAccountManager */
protected $accountManager;
/** @var IFactory */
protected $l10nFactory;

public function __construct(string $appName,
public function __construct(
string $appName,
IRequest $request,
IUserManager $userManager,
IConfig $config,
IGroupManager $groupManager,
IUserSession $userSession,
IAccountManager $accountManager,
IFactory $l10nFactory) {
protected IUserManager $userManager,
protected IConfig $config,
protected GroupManager $groupManager,
protected IUserSession $userSession,
protected IAccountManager $accountManager,
protected ISubAdmin $subAdminManager,
protected IFactory $l10nFactory,
) {
parent::__construct($appName, $request);

$this->userManager = $userManager;
$this->config = $config;
$this->groupManager = $groupManager;
$this->userSession = $userSession;
$this->accountManager = $accountManager;
$this->l10nFactory = $l10nFactory;
}

/**
Expand Down Expand Up @@ -136,8 +120,8 @@ protected function getUserData(string $userId, bool $includeScopes = false): ?ar
$data['backend'] = $targetUserObject->getBackendClassName();
$data['subadmin'] = $this->getUserSubAdminGroupsData($targetUserObject->getUID());
$data[self::USER_FIELD_QUOTA] = $this->fillStorageInfo($targetUserObject->getUID());
$managerUids = $targetUserObject->getManagerUids();
$data[self::USER_FIELD_MANAGER] = empty($managerUids) ? '' : $managerUids[0];
$managers = $this->getManagers($targetUserObject);
$data[self::USER_FIELD_MANAGER] = empty($managers) ? '' : $managers[0];

try {
if ($includeScopes) {
Expand Down Expand Up @@ -206,6 +190,34 @@ protected function getUserData(string $userId, bool $includeScopes = false): ?ar
return $data;
}

/**
* @return string[]
*/
protected function getManagers(IUser $user): array {
$currentLoggedInUser = $this->userSession->getUser();

$managerUids = $user->getManagerUids();
if ($this->groupManager->isAdmin($currentLoggedInUser->getUID()) || $this->groupManager->isDelegatedAdmin($currentLoggedInUser->getUID())) {
return $managerUids;
}

if ($this->subAdminManager->isSubAdmin($currentLoggedInUser)) {
$accessibleManagerUids = array_values(array_filter(
$managerUids,
function (string $managerUid) use ($currentLoggedInUser) {
$manager = $this->userManager->get($managerUid);
if (!($manager instanceof IUser)) {
return false;
}
return $this->subAdminManager->isUserAccessible($currentLoggedInUser, $manager);
},
));
return $accessibleManagerUids;
}

return [];
}

/**
* Get the groups a user is a subadmin of
*
Expand Down
3 changes: 3 additions & 0 deletions apps/provisioning_api/lib/Controller/GroupsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use OCP\AppFramework\OCS\OCSForbiddenException;
use OCP\AppFramework\OCS\OCSNotFoundException;
use OCP\AppFramework\OCSController;
use OCP\Group\ISubAdmin;
use OCP\IConfig;
use OCP\IGroup;
use OCP\IGroupManager;
Expand All @@ -47,6 +48,7 @@ public function __construct(string $appName,
IGroupManager $groupManager,
IUserSession $userSession,
IAccountManager $accountManager,
ISubAdmin $subAdminManager,
IFactory $l10nFactory,
LoggerInterface $logger) {
parent::__construct($appName,
Expand All @@ -56,6 +58,7 @@ public function __construct(string $appName,
$groupManager,
$userSession,
$accountManager,
$subAdminManager,
$l10nFactory
);

Expand Down
5 changes: 4 additions & 1 deletion apps/provisioning_api/lib/Controller/UsersController.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
use OCP\AppFramework\OCS\OCSNotFoundException;
use OCP\AppFramework\OCSController;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Group\ISubAdmin;
use OCP\HintException;
use OCP\IConfig;
use OCP\IGroup;
Expand Down Expand Up @@ -63,6 +64,7 @@ public function __construct(
IGroupManager $groupManager,
IUserSession $userSession,
IAccountManager $accountManager,
ISubAdmin $subAdminManager,
IFactory $l10nFactory,
private IURLGenerator $urlGenerator,
private LoggerInterface $logger,
Expand All @@ -81,6 +83,7 @@ public function __construct(
$groupManager,
$userSession,
$accountManager,
$subAdminManager,
$l10nFactory
);

Expand Down Expand Up @@ -946,7 +949,7 @@ public function editUser(string $userId, string $key, string $value): DataRespon
$permittedFields[] = IAccountManager::PROPERTY_PROFILE_ENABLED;
$permittedFields[] = IAccountManager::PROPERTY_BIRTHDATE;
$permittedFields[] = IAccountManager::PROPERTY_PRONOUNS;

$permittedFields[] = IAccountManager::PROPERTY_PHONE . self::SCOPE_SUFFIX;
$permittedFields[] = IAccountManager::PROPERTY_ADDRESS . self::SCOPE_SUFFIX;
$permittedFields[] = IAccountManager::PROPERTY_WEBSITE . self::SCOPE_SUFFIX;
Expand Down
10 changes: 5 additions & 5 deletions apps/provisioning_api/tests/Controller/GroupsControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
namespace OCA\Provisioning_API\Tests\Controller;

use OC\Group\Manager;
use OC\SubAdmin;
use OC\User\NoUserException;
use OCA\Provisioning_API\Controller\GroupsController;
use OCP\Accounts\IAccountManager;
use OCP\Group\ISubAdmin;
use OCP\IConfig;
use OCP\IRequest;
use OCP\IUser;
Expand All @@ -34,12 +34,12 @@ class GroupsControllerTest extends \Test\TestCase {
protected $userSession;
/** @var IAccountManager|\PHPUnit\Framework\MockObject\MockObject */
protected $accountManager;
/** @var ISubAdmin|\PHPUnit\Framework\MockObject\MockObject */
protected $subAdminManager;
/** @var IFactory|\PHPUnit\Framework\MockObject\MockObject */
protected $l10nFactory;
/** @var LoggerInterface|\PHPUnit\Framework\MockObject\MockObject */
protected $logger;
/** @var SubAdmin|\PHPUnit\Framework\MockObject\MockObject */
protected $subAdminManager;

/** @var GroupsController|\PHPUnit\Framework\MockObject\MockObject */
protected $api;
Expand All @@ -54,11 +54,10 @@ protected function setUp(): void {
$this->groupManager = $this->createMock(Manager::class);
$this->userSession = $this->createMock(IUserSession::class);
$this->accountManager = $this->createMock(IAccountManager::class);
$this->subAdminManager = $this->createMock(ISubAdmin::class);
$this->l10nFactory = $this->createMock(IFactory::class);
$this->logger = $this->createMock(LoggerInterface::class);

$this->subAdminManager = $this->createMock(SubAdmin::class);

$this->groupManager
->method('getSubAdmin')
->willReturn($this->subAdminManager);
Expand All @@ -72,6 +71,7 @@ protected function setUp(): void {
$this->groupManager,
$this->userSession,
$this->accountManager,
$this->subAdminManager,
$this->l10nFactory,
$this->logger
])
Expand Down
20 changes: 8 additions & 12 deletions apps/provisioning_api/tests/Controller/UsersControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\OCS\OCSException;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Group\ISubAdmin;
use OCP\IConfig;
use OCP\IGroup;
use OCP\IL10N;
Expand Down Expand Up @@ -57,6 +58,8 @@ class UsersControllerTest extends TestCase {
protected $api;
/** @var IAccountManager|MockObject */
protected $accountManager;
/** @var ISubAdmin|MockObject */
protected $subAdminManager;
/** @var IURLGenerator|MockObject */
protected $urlGenerator;
/** @var IRequest|MockObject */
Expand Down Expand Up @@ -86,6 +89,7 @@ protected function setUp(): void {
$this->logger = $this->createMock(LoggerInterface::class);
$this->request = $this->createMock(IRequest::class);
$this->accountManager = $this->createMock(IAccountManager::class);
$this->subAdminManager = $this->createMock(ISubAdmin::class);
$this->urlGenerator = $this->createMock(IURLGenerator::class);
$this->l10nFactory = $this->createMock(IFactory::class);
$this->newUserMailHelper = $this->createMock(NewUserMailHelper::class);
Expand All @@ -108,6 +112,7 @@ protected function setUp(): void {
$this->groupManager,
$this->userSession,
$this->accountManager,
$this->subAdminManager,
$this->l10nFactory,
$this->urlGenerator,
$this->logger,
Expand Down Expand Up @@ -376,6 +381,7 @@ public function testAddUserSuccessfulWithDisplayName(): void {
$this->groupManager,
$this->userSession,
$this->accountManager,
$this->subAdminManager,
$this->l10nFactory,
$this->urlGenerator,
$this->logger,
Expand Down Expand Up @@ -931,7 +937,6 @@ public function testGetUserDataAsAdmin(): void {
->disableOriginalConstructor()
->getMock();
$loggedInUser
->expects($this->exactly(2))
->method('getUID')
->willReturn('admin');
$targetUser = $this->getMockBuilder(IUser::class)
Expand All @@ -941,16 +946,13 @@ public function testGetUserDataAsAdmin(): void {
->method('getSystemEMailAddress')
->willReturn('demo@nextcloud.com');
$this->userSession
->expects($this->once())
->method('getUser')
->willReturn($loggedInUser);
$this->userManager
->expects($this->exactly(2))
->method('get')
->with('UID')
->willReturn($targetUser);
$this->groupManager
->expects($this->once())
->method('isAdmin')
->with('admin')
->willReturn(true);
Expand Down Expand Up @@ -1079,7 +1081,6 @@ public function testGetUserDataAsSubAdminAndUserIsAccessible(): void {
->disableOriginalConstructor()
->getMock();
$loggedInUser
->expects($this->exactly(2))
->method('getUID')
->willReturn('subadmin');
$targetUser = $this->getMockBuilder(IUser::class)
Expand All @@ -1090,16 +1091,13 @@ public function testGetUserDataAsSubAdminAndUserIsAccessible(): void {
->method('getSystemEMailAddress')
->willReturn('demo@nextcloud.com');
$this->userSession
->expects($this->once())
->method('getUser')
->willReturn($loggedInUser);
$this->userManager
->expects($this->exactly(2))
->method('get')
->with('UID')
->willReturn($targetUser);
$this->groupManager
->expects($this->once())
->method('isAdmin')
->with('subadmin')
->willReturn(false);
Expand Down Expand Up @@ -1267,23 +1265,19 @@ public function testGetUserDataAsSubAdminSelfLookup(): void {
->disableOriginalConstructor()
->getMock();
$loggedInUser
->expects($this->exactly(3))
->method('getUID')
->willReturn('UID');
$targetUser = $this->getMockBuilder(IUser::class)
->disableOriginalConstructor()
->getMock();
$this->userSession
->expects($this->once())
->method('getUser')
->willReturn($loggedInUser);
$this->userManager
->expects($this->exactly(2))
->method('get')
->with('UID')
->willReturn($targetUser);
$this->groupManager
->expects($this->once())
->method('isAdmin')
->with('UID')
->willReturn(false);
Expand Down Expand Up @@ -3667,6 +3661,7 @@ public function testGetCurrentUserLoggedIn(): void {
$this->groupManager,
$this->userSession,
$this->accountManager,
$this->subAdminManager,
$this->l10nFactory,
$this->urlGenerator,
$this->logger,
Expand Down Expand Up @@ -3756,6 +3751,7 @@ public function testGetUser(): void {
$this->groupManager,
$this->userSession,
$this->accountManager,
$this->subAdminManager,
$this->l10nFactory,
$this->urlGenerator,
$this->logger,
Expand Down
3 changes: 3 additions & 0 deletions lib/private/SubAdmin.php
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,9 @@ public function isSubAdmin(IUser $user): bool {
* @return bool
*/
public function isUserAccessible(IUser $subadmin, IUser $user): bool {
if ($subadmin->getUID() === $user->getUID()) {
return true;
}
if (!$this->isSubAdmin($subadmin)) {
return false;
}
Expand Down

0 comments on commit d66e469

Please sign in to comment.