Skip to content

Commit

Permalink
cleanup di for share permissions wrapper
Browse files Browse the repository at this point in the history
Signed-off-by: Robin Appelman <[email protected]>
  • Loading branch information
icewind1991 committed Aug 15, 2023
1 parent a031bc4 commit 1701426
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 114 deletions.
75 changes: 28 additions & 47 deletions lib/private/Files/SetupManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
use OC\Files\Storage\Wrapper\Quota;
use OC\Lockdown\Filesystem\NullStorage;
use OC\Share\Share;
use OC\Share20\ShareDisableChecker;
use OC_App;
use OC_Hook;
use OC_Util;
Expand Down Expand Up @@ -67,52 +68,33 @@

class SetupManager {
private bool $rootSetup = false;
private IEventLogger $eventLogger;
private MountProviderCollection $mountProviderCollection;
private IMountManager $mountManager;
private IUserManager $userManager;
// List of users for which at least one mount is setup
private array $setupUsers = [];
// List of users for which all mounts are setup
private array $setupUsersComplete = [];
/** @var array<string, string[]> */
private array $setupUserMountProviders = [];
private IEventDispatcher $eventDispatcher;
private IUserMountCache $userMountCache;
private ILockdownManager $lockdownManager;
private IUserSession $userSession;
private ICache $cache;
private LoggerInterface $logger;
private IConfig $config;
private bool $listeningForProviders;
private array $fullSetupRequired = [];
private bool $setupBuiltinWrappersDone = false;

public function __construct(
IEventLogger $eventLogger,
MountProviderCollection $mountProviderCollection,
IMountManager $mountManager,
IUserManager $userManager,
IEventDispatcher $eventDispatcher,
IUserMountCache $userMountCache,
ILockdownManager $lockdownManager,
IUserSession $userSession,
private IEventLogger $eventLogger,
private MountProviderCollection $mountProviderCollection,
private IMountManager $mountManager,
private IUserManager $userManager,
private IEventDispatcher $eventDispatcher,
private IUserMountCache $userMountCache,
private ILockdownManager $lockdownManager,
private IUserSession $userSession,
ICacheFactory $cacheFactory,
LoggerInterface $logger,
IConfig $config
private LoggerInterface $logger,
private IConfig $config,
private ShareDisableChecker $shareDisableChecker,
) {
$this->eventLogger = $eventLogger;
$this->mountProviderCollection = $mountProviderCollection;
$this->mountManager = $mountManager;
$this->userManager = $userManager;
$this->eventDispatcher = $eventDispatcher;
$this->userMountCache = $userMountCache;
$this->lockdownManager = $lockdownManager;
$this->logger = $logger;
$this->userSession = $userSession;
$this->cache = $cacheFactory->createDistributed('setupmanager::');
$this->listeningForProviders = false;
$this->config = $config;

$this->setupListeners();
}
Expand Down Expand Up @@ -142,24 +124,23 @@ private function setupBuiltinWrappers() {
return $storage;
});

Filesystem::addStorageWrapper('sharing_mask', function ($mountPoint, IStorage $storage, IMountPoint $mount) {
$reSharingEnabled = Share::isResharingAllowed();
$sharingEnabledForMount = $mount->getOption('enable_sharing', true);
/** @var IUserSession $userSession */
$userSession = \OC::$server->get(IUserSession::class);
$user = $userSession->getUser();
/** @var IManager $shareManager */
$shareManager = \OC::$server->get(IManager::class);
$sharingEnabledForUser = $user ? !$shareManager->sharingDisabledForUser($user->getUID()) : true;
$isShared = $storage->instanceOfStorage(ISharedStorage::class);
if (!$sharingEnabledForMount || !$sharingEnabledForUser || (!$reSharingEnabled && $isShared)) {
return new PermissionsMask([
'storage' => $storage,
'mask' => Constants::PERMISSION_ALL - Constants::PERMISSION_SHARE,
]);
$reSharingEnabled = Share::isResharingAllowed();
$user = $this->userSession->getUser();
$sharingEnabledForUser = $user ? !$this->shareDisableChecker->sharingDisabledForUser($user->getUID()) : true;
Filesystem::addStorageWrapper(
'sharing_mask',
function ($mountPoint, IStorage $storage, IMountPoint $mount) use ($reSharingEnabled, $sharingEnabledForUser) {
$sharingEnabledForMount = $mount->getOption('enable_sharing', true);
$isShared = $storage->instanceOfStorage(ISharedStorage::class);
if (!$sharingEnabledForMount || !$sharingEnabledForUser || (!$reSharingEnabled && $isShared)) {
return new PermissionsMask([
'storage' => $storage,
'mask' => Constants::PERMISSION_ALL - Constants::PERMISSION_SHARE,
]);
}
return $storage;
}
return $storage;
});
);

// install storage availability wrapper, before most other wrappers
Filesystem::addStorageWrapper('oc_availability', function ($mountPoint, IStorage $storage) {
Expand Down
45 changes: 14 additions & 31 deletions lib/private/Files/SetupManagerFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

namespace OC\Files;

use OC\Share20\ShareDisableChecker;
use OCP\Diagnostics\IEventLogger;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Files\Config\IMountProviderCollection;
Expand All @@ -36,40 +37,21 @@
use Psr\Log\LoggerInterface;

class SetupManagerFactory {
private IEventLogger $eventLogger;
private IMountProviderCollection $mountProviderCollection;
private IUserManager $userManager;
private IEventDispatcher $eventDispatcher;
private IUserMountCache $userMountCache;
private ILockdownManager $lockdownManager;
private IUserSession $userSession;
private ?SetupManager $setupManager;
private ICacheFactory $cacheFactory;
private LoggerInterface $logger;
private IConfig $config;

public function __construct(
IEventLogger $eventLogger,
IMountProviderCollection $mountProviderCollection,
IUserManager $userManager,
IEventDispatcher $eventDispatcher,
IUserMountCache $userMountCache,
ILockdownManager $lockdownManager,
IUserSession $userSession,
ICacheFactory $cacheFactory,
LoggerInterface $logger,
IConfig $config
private IEventLogger $eventLogger,
private IMountProviderCollection $mountProviderCollection,
private IUserManager $userManager,
private IEventDispatcher $eventDispatcher,
private IUserMountCache $userMountCache,
private ILockdownManager $lockdownManager,
private IUserSession $userSession,
private ICacheFactory $cacheFactory,
private LoggerInterface $logger,
private IConfig $config,
private ShareDisableChecker $shareDisableChecker,
) {
$this->eventLogger = $eventLogger;
$this->mountProviderCollection = $mountProviderCollection;
$this->userManager = $userManager;
$this->eventDispatcher = $eventDispatcher;
$this->userMountCache = $userMountCache;
$this->lockdownManager = $lockdownManager;
$this->userSession = $userSession;
$this->cacheFactory = $cacheFactory;
$this->logger = $logger;
$this->config = $config;
$this->setupManager = null;
}

Expand All @@ -86,7 +68,8 @@ public function create(IMountManager $mountManager): SetupManager {
$this->userSession,
$this->cacheFactory,
$this->logger,
$this->config
$this->config,
$this->shareDisableChecker,
);
}
return $this->setupManager;
Expand Down
4 changes: 3 additions & 1 deletion lib/private/Server.php
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@
use OC\Security\VerificationToken\VerificationToken;
use OC\Session\CryptoWrapper;
use OC\Share20\ProviderFactory;
use OC\Share20\ShareDisableChecker;
use OC\Share20\ShareHelper;
use OC\SpeechToText\SpeechToTextManager;
use OC\SystemTag\ManagerFactory as SystemTagManagerFactory;
Expand Down Expand Up @@ -1237,7 +1238,8 @@ public function __construct($webRoot, \OC\Config $config) {
$c->get('ThemingDefaults'),
$c->get(IEventDispatcher::class),
$c->get(IUserSession::class),
$c->get(KnownUserService::class)
$c->get(KnownUserService::class),
$c->get(ShareDisableChecker::class)
);

return $manager;
Expand Down
40 changes: 5 additions & 35 deletions lib/private/Share20/Manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,6 @@ class Manager implements IManager {
private $userManager;
/** @var IRootFolder */
private $rootFolder;
/** @var CappedMemoryCache */
private $sharingDisabledForUsersCache;
/** @var LegacyHooks */
private $legacyHooks;
/** @var IMailer */
Expand All @@ -122,6 +120,7 @@ class Manager implements IManager {
private $userSession;
/** @var KnownUserService */
private $knownUserService;
private ShareDisableChecker $shareDisableChecker;

public function __construct(
LoggerInterface $logger,
Expand All @@ -140,7 +139,8 @@ public function __construct(
\OC_Defaults $defaults,
IEventDispatcher $dispatcher,
IUserSession $userSession,
KnownUserService $knownUserService
KnownUserService $knownUserService,
ShareDisableChecker $shareDisableChecker
) {
$this->logger = $logger;
$this->config = $config;
Expand All @@ -153,7 +153,6 @@ public function __construct(
$this->factory = $factory;
$this->userManager = $userManager;
$this->rootFolder = $rootFolder;
$this->sharingDisabledForUsersCache = new CappedMemoryCache();
// The constructor of LegacyHooks registers the listeners of share events
// do not remove if those are not properly migrated
$this->legacyHooks = new LegacyHooks($dispatcher);
Expand All @@ -163,6 +162,7 @@ public function __construct(
$this->dispatcher = $dispatcher;
$this->userSession = $userSession;
$this->knownUserService = $knownUserService;
$this->shareDisableChecker = $shareDisableChecker;
}

/**
Expand Down Expand Up @@ -2011,37 +2011,7 @@ public function currentUserCanEnumerateTargetUser(?IUser $currentUser, IUser $ta
* @return bool
*/
public function sharingDisabledForUser($userId) {
if ($userId === null) {
return false;
}

if (isset($this->sharingDisabledForUsersCache[$userId])) {
return $this->sharingDisabledForUsersCache[$userId];
}

if ($this->config->getAppValue('core', 'shareapi_exclude_groups', 'no') === 'yes') {
$groupsList = $this->config->getAppValue('core', 'shareapi_exclude_groups_list', '');
$excludedGroups = json_decode($groupsList);
if (is_null($excludedGroups)) {
$excludedGroups = explode(',', $groupsList);
$newValue = json_encode($excludedGroups);
$this->config->setAppValue('core', 'shareapi_exclude_groups_list', $newValue);
}
$user = $this->userManager->get($userId);
$usersGroups = $this->groupManager->getUserGroupIds($user);
if (!empty($usersGroups)) {
$remainingGroups = array_diff($usersGroups, $excludedGroups);
// if the user is only in groups which are disabled for sharing then
// sharing is also disabled for the user
if (empty($remainingGroups)) {
$this->sharingDisabledForUsersCache[$userId] = true;
return true;
}
}
}

$this->sharingDisabledForUsersCache[$userId] = false;
return false;
return $this->shareDisableChecker->sharingDisabledForUser($userId);
}

/**
Expand Down
66 changes: 66 additions & 0 deletions lib/private/Share20/ShareDisableChecker.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php

namespace OC\Share20;

use OCP\Cache\CappedMemoryCache;
use OCP\IConfig;
use OCP\IGroupManager;
use OCP\IUserManager;

/**
* split of from the share manager to allow using it with minimal DI
*/
class ShareDisableChecker {
private CappedMemoryCache $sharingDisabledForUsersCache;

public function __construct(
private IConfig $config,
private IUserManager $userManager,
private IGroupManager $groupManager,
) {
$this->sharingDisabledForUsersCache = new CappedMemoryCache();
}


/**
* Copied from \OC_Util::isSharingDisabledForUser
*
* TODO: Deprecate function from OC_Util
*
* @param string $userId
* @return bool
*/
public function sharingDisabledForUser($userId) {
if ($userId === null) {
return false;
}

if (isset($this->sharingDisabledForUsersCache[$userId])) {
return $this->sharingDisabledForUsersCache[$userId];
}

if ($this->config->getAppValue('core', 'shareapi_exclude_groups', 'no') === 'yes') {
$groupsList = $this->config->getAppValue('core', 'shareapi_exclude_groups_list', '');
$excludedGroups = json_decode($groupsList);
if (is_null($excludedGroups)) {
$excludedGroups = explode(',', $groupsList);
$newValue = json_encode($excludedGroups);
$this->config->setAppValue('core', 'shareapi_exclude_groups_list', $newValue);
}
$user = $this->userManager->get($userId);
$usersGroups = $this->groupManager->getUserGroupIds($user);
if (!empty($usersGroups)) {
$remainingGroups = array_diff($usersGroups, $excludedGroups);
// if the user is only in groups which are disabled for sharing then
// sharing is also disabled for the user
if (empty($remainingGroups)) {
$this->sharingDisabledForUsersCache[$userId] = true;
return true;
}
}
}

$this->sharingDisabledForUsersCache[$userId] = false;
return false;
}
}

0 comments on commit 1701426

Please sign in to comment.