diff --git a/apps/dav/appinfo/v1/publicwebdav.php b/apps/dav/appinfo/v1/publicwebdav.php index 4dbf058bf239f..ab68a40d2ab63 100644 --- a/apps/dav/appinfo/v1/publicwebdav.php +++ b/apps/dav/appinfo/v1/publicwebdav.php @@ -33,7 +33,6 @@ use OCP\ITagManager; use OCP\IUserSession; use OCP\L10N\IFactory as IL10nFactory; -use OCP\Security\Bruteforce\IThrottler; use OCP\Server; use OCP\Share\IManager; use OCP\Share\IShare; @@ -50,12 +49,7 @@ Server::get(ISession::class)->close(); // Backends -$authBackend = new LegacyPublicAuth( - Server::get(IRequest::class), - Server::get(\OCP\Share\IManager::class), - Server::get(ISession::class), - Server::get(IThrottler::class) -); +$authBackend = Server::get(LegacyPublicAuth::class); $bearerAuthBackend = new BearerAuth( Server::get(IUserSession::class), Server::get(ISession::class), diff --git a/apps/dav/appinfo/v2/publicremote.php b/apps/dav/appinfo/v2/publicremote.php index 5e0d51825fc8c..64d4a6ff74715 100644 --- a/apps/dav/appinfo/v2/publicremote.php +++ b/apps/dav/appinfo/v2/publicremote.php @@ -35,10 +35,8 @@ use OCP\IRequest; use OCP\ISession; use OCP\ITagManager; -use OCP\IURLGenerator; use OCP\IUserSession; use OCP\L10N\IFactory; -use OCP\Security\Bruteforce\IThrottler; use OCP\Server; use OCP\Share\IManager; use Psr\Log\LoggerInterface; @@ -62,14 +60,7 @@ $requestUri = $request->getRequestUri(); // Backends -$authBackend = new PublicAuth( - $request, - Server::get(IManager::class), - $session, - Server::get(IThrottler::class), - Server::get(LoggerInterface::class), - Server::get(IURLGenerator::class), -); +$authBackend = Server::get(PublicAuth::class); $bearerAuthBackend = new BearerAuth( Server::get(IUserSession::class), $session, diff --git a/apps/dav/lib/Connector/LegacyPublicAuth.php b/apps/dav/lib/Connector/LegacyPublicAuth.php index b63261dacd950..b1cbbc5df35bd 100644 --- a/apps/dav/lib/Connector/LegacyPublicAuth.php +++ b/apps/dav/lib/Connector/LegacyPublicAuth.php @@ -12,6 +12,7 @@ use OCP\Defaults; use OCP\IRequest; use OCP\ISession; +use OCP\IUserSession; use OCP\Security\Bruteforce\IThrottler; use OCP\Share\Exceptions\ShareNotFound; use OCP\Share\IManager; @@ -33,6 +34,7 @@ public function __construct( private IManager $shareManager, private ISession $session, private IThrottler $throttler, + private IUserSession $userSession, ) { // setup realm $defaults = new Defaults(); @@ -64,7 +66,7 @@ protected function validateUserPass($username, $password) { $this->share = $share; - \OC_User::setIncognitoMode(true); + $this->userSession->setIncognitoMode(true); // check if the share is password protected if ($share->isPasswordProtected()) { diff --git a/apps/dav/lib/Connector/Sabre/Auth.php b/apps/dav/lib/Connector/Sabre/Auth.php index 71691990c0eaa..f26eddbd8dc50 100644 --- a/apps/dav/lib/Connector/Sabre/Auth.php +++ b/apps/dav/lib/Connector/Sabre/Auth.php @@ -185,6 +185,8 @@ private function auth(RequestInterface $request, ResponseInterface $response): a if ($this->twoFactorManager->needsSecondFactor($this->userSession->getUser())) { throw new \Sabre\DAV\Exception\NotAuthenticated('2FA challenge not passed.'); } + /** @psalm-suppress DeprecatedClass OC_User is deprecated*/ + /** @psalm-suppress DeprecatedMethod this call should be removed ideally */ if ( //Fix for broken webdav clients ($this->userSession->isLoggedIn() && is_null($this->session->get(self::DAV_AUTHENTICATED))) diff --git a/apps/dav/lib/Connector/Sabre/BearerAuth.php b/apps/dav/lib/Connector/Sabre/BearerAuth.php index 3cdd10cdfa5c4..a077f7b32ea71 100644 --- a/apps/dav/lib/Connector/Sabre/BearerAuth.php +++ b/apps/dav/lib/Connector/Sabre/BearerAuth.php @@ -58,7 +58,7 @@ public function validateBearerToken($bearerToken) { $sharedSecret = $this->resolveOcmSharedSecret($bearerToken); if ($sharedSecret !== null) { $this->token = $sharedSecret; - \OC_User::setIncognitoMode(true); + $this->userSession->setIncognitoMode(true); return $this->principalPrefix . $sharedSecret; } } @@ -69,7 +69,7 @@ public function validateBearerToken($bearerToken) { // the logged-in user is visible for the rest of the request. If the // bearer token is invalid and Sabre falls back to one of the public // auth backends, that backend will re-enable incognito mode itself. - \OC_User::setIncognitoMode(false); + $this->userSession->setIncognitoMode(false); if ($this->userSession->tryTokenLogin($this->request)) { return $this->setupUserFs($this->userSession->getUser()->getUID()); diff --git a/apps/dav/lib/Connector/Sabre/PublicAuth.php b/apps/dav/lib/Connector/Sabre/PublicAuth.php index b9ce2fb522b1a..4649a9a00f40c 100644 --- a/apps/dav/lib/Connector/Sabre/PublicAuth.php +++ b/apps/dav/lib/Connector/Sabre/PublicAuth.php @@ -14,6 +14,7 @@ use OCP\IRequest; use OCP\ISession; use OCP\IURLGenerator; +use OCP\IUserSession; use OCP\Security\Bruteforce\IThrottler; use OCP\Security\Bruteforce\MaxDelayReached; use OCP\Share\Exceptions\ShareNotFound; @@ -47,6 +48,7 @@ public function __construct( private IThrottler $throttler, private LoggerInterface $logger, private IURLGenerator $urlGenerator, + private IUserSession $userSession, ) { // setup realm $defaults = new Defaults(); @@ -134,7 +136,7 @@ private function checkToken(): array { } $this->share = $share; - \OC_User::setIncognitoMode(true); + $this->userSession->setIncognitoMode(true); // If already authenticated if ($this->isShareInSession($share)) { @@ -173,7 +175,7 @@ protected function validateUserPass($username, $password) { return false; } - \OC_User::setIncognitoMode(true); + $this->userSession->setIncognitoMode(true); // check if the share is password protected if ($share->isPasswordProtected()) { diff --git a/apps/dav/tests/unit/Connector/LegacyPublicAuthTest.php b/apps/dav/tests/unit/Connector/LegacyPublicAuthTest.php index 57cd8bc96a27e..cde2fa4cc6849 100644 --- a/apps/dav/tests/unit/Connector/LegacyPublicAuthTest.php +++ b/apps/dav/tests/unit/Connector/LegacyPublicAuthTest.php @@ -12,6 +12,7 @@ use OCA\DAV\Connector\LegacyPublicAuth; use OCP\IRequest; use OCP\ISession; +use OCP\IUserSession; use OCP\Security\Bruteforce\IThrottler; use OCP\Share\Exceptions\ShareNotFound; use OCP\Share\IManager; @@ -26,6 +27,7 @@ class LegacyPublicAuthTest extends TestCase { private IRequest&MockObject $request; private IManager&MockObject $shareManager; private IThrottler&MockObject $throttler; + private IUserSession&MockObject $userSession; private LegacyPublicAuth $auth; private string|false $oldUser; @@ -36,12 +38,14 @@ protected function setUp(): void { $this->request = $this->createMock(IRequest::class); $this->shareManager = $this->createMock(IManager::class); $this->throttler = $this->createMock(IThrottler::class); + $this->userSession = $this->createMock(IUserSession::class); $this->auth = new LegacyPublicAuth( $this->request, $this->shareManager, $this->session, - $this->throttler + $this->throttler, + $this->userSession, ); // Store current user diff --git a/apps/dav/tests/unit/Connector/Sabre/PublicAuthTest.php b/apps/dav/tests/unit/Connector/Sabre/PublicAuthTest.php index aa843fd0cfa35..e76fc347d9359 100644 --- a/apps/dav/tests/unit/Connector/Sabre/PublicAuthTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/PublicAuthTest.php @@ -13,6 +13,7 @@ use OCP\IRequest; use OCP\ISession; use OCP\IURLGenerator; +use OCP\IUserSession; use OCP\Security\Bruteforce\IThrottler; use OCP\Share\Exceptions\ShareNotFound; use OCP\Share\IManager; @@ -35,6 +36,7 @@ class PublicAuthTest extends \Test\TestCase { private IThrottler&MockObject $throttler; private LoggerInterface&MockObject $logger; private IURLGenerator&MockObject $urlGenerator; + private IUserSession&MockObject $userSession; private PublicAuth $auth; private bool|string $oldUser; @@ -48,6 +50,7 @@ protected function setUp(): void { $this->throttler = $this->createMock(IThrottler::class); $this->logger = $this->createMock(LoggerInterface::class); $this->urlGenerator = $this->createMock(IURLGenerator::class); + $this->userSession = $this->createMock(IUserSession::class); $this->auth = new PublicAuth( $this->request, @@ -56,6 +59,7 @@ protected function setUp(): void { $this->throttler, $this->logger, $this->urlGenerator, + $this->userSession, ); // Store current user diff --git a/apps/files_external/lib/Lib/Storage/SFTP.php b/apps/files_external/lib/Lib/Storage/SFTP.php index b1b5be38dbea3..02f3aa1998fe1 100644 --- a/apps/files_external/lib/Lib/Storage/SFTP.php +++ b/apps/files_external/lib/Lib/Storage/SFTP.php @@ -191,7 +191,8 @@ private function absPath(string $path): string { private function hostKeysPath(): string|false { try { - $userId = \OC_User::getUser(); + $userId = Server::get(\OCP\IUserSession::class)->getUser()?->getUID() ?? false; + ; if ($userId === false) { return false; } diff --git a/apps/files_external/lib/Migration/DummyUserSession.php b/apps/files_external/lib/Migration/DummyUserSession.php index cfb8bf6796ff2..77589e8248038 100644 --- a/apps/files_external/lib/Migration/DummyUserSession.php +++ b/apps/files_external/lib/Migration/DummyUserSession.php @@ -14,6 +14,7 @@ class DummyUserSession implements IUserSession { private ?IUser $user = null; + private bool $incognitoMode = false; #[\Override] public function login($uid, $password) { @@ -63,4 +64,14 @@ public function getImpersonatingUserID() : ?string { public function setImpersonatingUserID(bool $useCurrentUser = true): void { //no OP } + + #[\Override] + public function setIncognitoMode(bool $mode): void { + $this->incognitoMode = $mode; + } + + #[\Override] + public function isIncognitoMode(): bool { + return $this->incognitoMode; + } } diff --git a/apps/files_sharing/lib/Controller/ShareController.php b/apps/files_sharing/lib/Controller/ShareController.php index 18e8b32b7a014..38a355bda5d39 100644 --- a/apps/files_sharing/lib/Controller/ShareController.php +++ b/apps/files_sharing/lib/Controller/ShareController.php @@ -40,6 +40,7 @@ use OCP\ISession; use OCP\IURLGenerator; use OCP\IUserManager; +use OCP\IUserSession; use OCP\Security\Events\GenerateSecurePasswordEvent; use OCP\Security\ISecureRandom; use OCP\Security\PasswordContext; @@ -78,6 +79,7 @@ public function __construct( protected ISecureRandom $secureRandom, protected Defaults $defaults, private IPublicShareTemplateFactory $publicShareTemplateFactory, + private IUserSession $userSession, ) { parent::__construct($appName, $request, $session, $urlGenerator); } @@ -275,7 +277,7 @@ private function validateShare(IShare $share) { #[PublicPage] #[NoCSRFRequired] public function showShare($path = ''): TemplateResponse { - \OC_User::setIncognitoMode(true); + $this->userSession->setIncognitoMode(true); // Check whether share exists try { @@ -328,7 +330,7 @@ public function showShare($path = ''): TemplateResponse { #[NoCSRFRequired] #[NoSameSiteCookieRequired] public function downloadShare(string $token, ?string $files = null, string $path = ''): NotFoundResponse|RedirectResponse|DataResponse { - \OC_User::setIncognitoMode(true); + $this->userSession->setIncognitoMode(true); $share = $this->shareManager->getShareByToken($token); diff --git a/apps/files_sharing/lib/Updater.php b/apps/files_sharing/lib/Updater.php index 9ee8dfbaba0e6..7831d5892665f 100644 --- a/apps/files_sharing/lib/Updater.php +++ b/apps/files_sharing/lib/Updater.php @@ -142,11 +142,15 @@ private static function moveShareInOrOutOfShare($path): void { * @param string $newPath new path relative to data/user/files */ private static function renameChildren($oldPath, $newPath) { - $absNewPath = Filesystem::normalizePath('/' . \OC_User::getUser() . '/files/' . $newPath); - $absOldPath = Filesystem::normalizePath('/' . \OC_User::getUser() . '/files/' . $oldPath); + $userInSession = Server::get(IUserSession::class)->getUser()?->getUID(); + if ($userInSession === null) { + return; + } + $absNewPath = Filesystem::normalizePath('/' . $userInSession . '/files/' . $newPath); + $absOldPath = Filesystem::normalizePath('/' . $userInSession . '/files/' . $oldPath); $mountManager = Filesystem::getMountManager(); - $mountedShares = $mountManager->findIn('/' . \OC_User::getUser() . '/files/' . $oldPath); + $mountedShares = $mountManager->findIn('/' . $userInSession . '/files/' . $oldPath); foreach ($mountedShares as $mount) { /** @var MountPoint $mount */ if ($mount->getStorage()->instanceOfStorage(ISharedStorage::class)) { diff --git a/apps/files_sharing/tests/Controller/ShareControllerTest.php b/apps/files_sharing/tests/Controller/ShareControllerTest.php index 0cf3d0ca08747..f3e247cda2141 100644 --- a/apps/files_sharing/tests/Controller/ShareControllerTest.php +++ b/apps/files_sharing/tests/Controller/ShareControllerTest.php @@ -43,6 +43,7 @@ use OCP\IURLGenerator; use OCP\IUser; use OCP\IUserManager; +use OCP\IUserSession; use OCP\Security\ISecureRandom; use OCP\Server; use OCP\Share\Exceptions\ShareNotFound; @@ -80,6 +81,7 @@ class ShareControllerTest extends \Test\TestCase { private IEventDispatcher&MockObject $eventDispatcher; private FederatedShareProvider&MockObject $federatedShareProvider; private IPublicShareTemplateFactory&MockObject $publicShareTemplateFactory; + private IUserSession&MockObject $userSession; protected function setUp(): void { parent::setUp(); @@ -104,6 +106,7 @@ protected function setUp(): void { $this->l10n = $this->createMock(IL10N::class); $this->secureRandom = $this->createMock(ISecureRandom::class); $this->defaults = $this->createMock(Defaults::class); + $this->userSession = $this->createMock(IUserSession::class); $this->publicShareTemplateFactory = $this->createMock(IPublicShareTemplateFactory::class); $this->publicShareTemplateFactory ->expects($this->any()) @@ -144,6 +147,7 @@ protected function setUp(): void { $this->secureRandom, $this->defaults, $this->publicShareTemplateFactory, + $this->userSession, ); // Store current user diff --git a/apps/files_trashbin/lib/Trashbin.php b/apps/files_trashbin/lib/Trashbin.php index a7ffd8364c0cf..456fc1f804ecb 100644 --- a/apps/files_trashbin/lib/Trashbin.php +++ b/apps/files_trashbin/lib/Trashbin.php @@ -15,7 +15,6 @@ use OC\Files\Node\NonExistingFile; use OC\Files\Node\NonExistingFolder; use OC\Files\View; -use OC_User; use OCA\FederatedFileSharing\FederatedShareProvider; use OCA\Files_Trashbin\Command\Expire; use OCA\Files_Trashbin\Events\BeforeNodeRestoredEvent; @@ -50,6 +49,7 @@ use OCP\IURLGenerator; use OCP\IUser; use OCP\IUserManager; +use OCP\IUserSession; use OCP\Lock\ILockingProvider; use OCP\Lock\LockedException; use OCP\Server; @@ -65,6 +65,10 @@ class Trashbin implements IEventListener { // unit: percentage; 50% of available disk space/quota public const DEFAULTMAXSIZE = 50; + private static function getUser(): string|false { + return Server::get(IUserSession::class)->getUser()?->getUID() ?? false; + } + /** * Ensure we don't need to scan the file during the move to trash * by triggering the scan in the pre-hook @@ -92,14 +96,14 @@ public static function getUidAndFilename($filename) { // to a remote user with a federated cloud ID we use the current logged-in // user. We need a valid local user to move the file to the right trash bin if (!$userManager->userExists($uid)) { - $uid = OC_User::getUser(); + $uid = self::getUser(); } if (!$uid) { // no owner, usually because of share link from ext storage return [null, null]; } Filesystem::initMountPoints($uid); - if ($uid !== OC_User::getUser()) { + if ($uid !== self::getUser()) { $info = Filesystem::getFileInfo($filename); $ownerView = new View('/' . $uid . '/files'); try { @@ -453,7 +457,7 @@ private static function getConfiguredTrashbinSize(string $user): int|float { */ private static function retainVersions($filename, $owner, $ownerPath, $timestamp) { if (Server::get(IAppManager::class)->isEnabledForUser('files_versions') && !empty($ownerPath)) { - $user = OC_User::getUser(); + $user = self::getUser(); $rootView = new View('/'); if ($rootView->is_dir($owner . '/files_versions/' . $ownerPath)) { @@ -527,7 +531,7 @@ private static function copy(View $view, $source, $target) { * @return bool true on success, false otherwise */ public static function restore($file, $filename, $timestamp) { - $user = OC_User::getUser(); + $user = self::getUser(); if (!$user) { throw new \Exception('Tried to restore a file while not logged in'); } @@ -631,7 +635,7 @@ public static function restore($file, $filename, $timestamp) { */ private static function restoreVersions(View $view, $file, $filename, $uniqueFilename, $location, $timestamp) { if (Server::get(IAppManager::class)->isEnabledForUser('files_versions')) { - $user = OC_User::getUser(); + $user = self::getUser(); $rootView = new View('/'); $target = Filesystem::normalizePath('/' . $location . '/' . $uniqueFilename); @@ -667,7 +671,7 @@ private static function restoreVersions(View $view, $file, $filename, $uniqueFil * delete all files from the trash */ public static function deleteAll() { - $user = OC_User::getUser(); + $user = self::getUser(); $userRoot = Server::get(IRootFolder::class)->getUserFolder($user)->getParent(); $view = new View('/' . $user); $fileInfos = $view->getDirectoryContent('files_trashbin/files'); @@ -824,7 +828,7 @@ private static function deleteVersions(View $view, $file, $filename, $timestamp, * @return bool true if file exists, otherwise false */ public static function file_exists($filename, $timestamp = null) { - $user = OC_User::getUser(); + $user = self::getUser(); $view = new View('/' . $user); if ($timestamp) { diff --git a/apps/files_versions/lib/Storage.php b/apps/files_versions/lib/Storage.php index 0035750596f58..e944bc62ec5b2 100644 --- a/apps/files_versions/lib/Storage.php +++ b/apps/files_versions/lib/Storage.php @@ -15,7 +15,6 @@ use OC\Files\Search\SearchQuery; use OC\Files\View; use OC\User\NoUserException; -use OC_User; use OCA\Files_Sharing\SharedMount; use OCA\Files_Versions\AppInfo\Application; use OCA\Files_Versions\Command\Expire; @@ -41,6 +40,7 @@ use OCP\IURLGenerator; use OCP\IUser; use OCP\IUserManager; +use OCP\IUserSession; use OCP\Lock\ILockingProvider; use OCP\Server; use OCP\User\Exceptions\UserNotFoundException; @@ -96,14 +96,15 @@ class Storage { public static function getUidAndFilename($filename) { $uid = Filesystem::getOwner($filename); $userManager = Server::get(IUserManager::class); + $userInSession = Server::get(IUserSession::class)->getUser()?->getUID() ?? false; // if the user with the UID doesn't exists, e.g. because the UID points // to a remote user with a federated cloud ID we use the current logged-in // user. We need a valid local user to create the versions if (!$userManager->userExists($uid)) { - $uid = OC_User::getUser(); + $uid = $userInSession; } Filesystem::initMountPoints($uid); - if ($uid !== OC_User::getUser()) { + if ($uid !== $userInSession) { $info = Filesystem::getFileInfo($filename); $ownerView = new View('/' . $uid . '/files'); try { diff --git a/apps/settings/lib/Settings/Personal/APersonalInfoSettings.php b/apps/settings/lib/Settings/Personal/APersonalInfoSettings.php index 31cc0f6920ec0..b0468b8567e24 100644 --- a/apps/settings/lib/Settings/Personal/APersonalInfoSettings.php +++ b/apps/settings/lib/Settings/Personal/APersonalInfoSettings.php @@ -19,12 +19,14 @@ use OCP\AppFramework\Http\TemplateResponse; use OCP\AppFramework\Services\IInitialState; use OCP\Files\FileInfo; +use OCP\Files\IUserFolder; use OCP\IConfig; use OCP\IGroup; use OCP\IGroupManager; use OCP\IL10N; use OCP\IUser; use OCP\IUserManager; +use OCP\IUserSession; use OCP\L10N\IFactory; use OCP\Notification\IManager; use OCP\Server; @@ -54,6 +56,8 @@ public function __construct( private IInitialState $initialStateService, private IManager $manager, private IUserStatusManager $userStatusManager, + private IUserSession $userSession, + private IUserFolder $userFolder, ) { } @@ -73,14 +77,14 @@ public function getForm(): TemplateResponse { $lookupServerUploadEnabled = $shareProvider->isLookupServerUploadEnabled(); } - $uid = \OC_User::getUser(); - $user = $this->userManager->get($uid); + $user = $this->userSession->getUser(); + if (!$user) { + throw new \Exception('No user in session'); + } + $uid = $user->getUID(); $account = $this->accountManager->getAccount($user); - // make sure FS is setup before querying storage related stuff... - \OC_Util::setupFS($user->getUID()); - - $storageInfo = \OC_Helper::getStorageInfo('/'); + $storageInfo = $this->userFolder->getUserQuota(); if ($storageInfo['quota'] === FileInfo::SPACE_UNLIMITED) { $totalSpace = $this->l->t('Unlimited'); } else { diff --git a/apps/user_ldap/lib/Controller/RenewPasswordController.php b/apps/user_ldap/lib/Controller/RenewPasswordController.php index f441d5c2b5f50..60ccf6849b447 100644 --- a/apps/user_ldap/lib/Controller/RenewPasswordController.php +++ b/apps/user_ldap/lib/Controller/RenewPasswordController.php @@ -103,7 +103,8 @@ public function tryRenewPassword(string $user, string $oldPassword, ?string $new } try { - if (!is_null($newPassword) && \OC_User::setPassword($user, $newPassword)) { + $userObject = $this->userManager->get($user); + if (!is_null($newPassword) && !is_null($userObject) && $userObject->setPassword($user, $newPassword)) { $this->session->set('loginMessages', [ [], [$this->l10n->t('Please login with the new password')] ]); diff --git a/apps/user_ldap/lib/User/User.php b/apps/user_ldap/lib/User/User.php index c1f21a0eb13de..fcd3f878bc273 100644 --- a/apps/user_ldap/lib/User/User.php +++ b/apps/user_ldap/lib/User/User.php @@ -374,7 +374,7 @@ public function getHomePath(?string $valueFromLDAP = null): string|false { throw new \Exception('Home dir attribute can\'t be read from LDAP for uid: ' . $this->getUsername()); } - // false will apply default behaviour as defined and done by OC_User + // false will apply default behaviour $this->userConfig->setValueString($this->getUsername(), 'user_ldap', 'homePath', ''); return false; } diff --git a/build/psalm-baseline.xml b/build/psalm-baseline.xml index b6da12c8b93f5..b1b154ad0656a 100644 --- a/build/psalm-baseline.xml +++ b/build/psalm-baseline.xml @@ -2264,15 +2264,11 @@ - - getUID())]]> - - diff --git a/core/Controller/TwoFactorChallengeController.php b/core/Controller/TwoFactorChallengeController.php index cf7144bc76d45..eb81d587dee23 100644 --- a/core/Controller/TwoFactorChallengeController.php +++ b/core/Controller/TwoFactorChallengeController.php @@ -10,7 +10,6 @@ use OC\AppFramework\Http\Attributes\TwoFactorSetUpDoneRequired; use OC\Authentication\TwoFactorAuth\Manager; -use OC_User; use OCP\AppFramework\Controller; use OCP\AppFramework\Http\Attribute\BruteForceProtection; use OCP\AppFramework\Http\Attribute\FrontpageRoute; @@ -46,13 +45,6 @@ public function __construct( parent::__construct($appName, $request); } - /** - * @return string - */ - protected function getLogoutUrl() { - return OC_User::getLogoutUrl($this->urlGenerator); - } - /** * @param IProvider[] $providers */ @@ -86,7 +78,7 @@ public function selectChallenge(?string $redirect_url = null): StandaloneTemplat 'backupProvider' => $backupProvider, 'providerMissing' => $providerSet->isProviderMissing(), 'redirect_url' => $redirect_url, - 'logout_url' => $this->getLogoutUrl(), + 'logout_url' => $this->urlGenerator->getLogoutUrl(), 'hasSetupProviders' => !empty($setupProviders), ]; Util::addScript('core', 'twofactor-request-token'); @@ -128,7 +120,7 @@ public function showChallenge(string $challengeProviderId, ?string $redirect_url 'error_message' => $errorMessage, 'provider' => $provider, 'backupProvider' => $backupProvider, - 'logout_url' => $this->getLogoutUrl(), + 'logout_url' => $this->urlGenerator->getLogoutUrl(), 'redirect_url' => $redirect_url, 'template' => $tmpl->fetchPage(), ]; @@ -191,7 +183,7 @@ public function setupProviders(?string $redirect_url = null): StandaloneTemplate $data = [ 'providers' => $setupProviders, - 'logout_url' => $this->getLogoutUrl(), + 'logout_url' => $this->urlGenerator->getLogoutUrl(), 'redirect_url' => $redirect_url, ]; @@ -222,7 +214,7 @@ public function setupProvider(string $providerId, ?string $redirect_url = null) $tmpl = $provider->getLoginSetup($user)->getBody(); $data = [ 'provider' => $provider, - 'logout_url' => $this->getLogoutUrl(), + 'logout_url' => $this->urlGenerator->getLogoutUrl(), 'redirect_url' => $redirect_url, 'template' => $tmpl->fetchPage(), ]; diff --git a/core/Controller/UpdateController.php b/core/Controller/UpdateController.php index b073221f1c6a0..f7e0d96ba18d8 100644 --- a/core/Controller/UpdateController.php +++ b/core/Controller/UpdateController.php @@ -31,6 +31,7 @@ use OCP\IEventSourceFactory; use OCP\IL10N; use OCP\IRequest; +use OCP\IUserSession; use OCP\Util; use Psr\Log\LoggerInterface; @@ -45,6 +46,7 @@ public function __construct( private readonly Updater $updater, private readonly IEventDispatcher $dispatcher, private readonly LoggerInterface $logger, + private readonly IUserSession $userSession, ) { parent::__construct($appName, $request); } @@ -83,7 +85,7 @@ public function update(): DataResponse { // if a user is currently logged in, their session must be ignored to // avoid side effects - \OC_User::setIncognitoMode(true); + $this->userSession->setIncognitoMode(true); $incompatibleApps = []; diff --git a/lib/OC.php b/lib/OC.php index d68c206068eff..77910523945b4 100644 --- a/lib/OC.php +++ b/lib/OC.php @@ -896,13 +896,14 @@ public static function initForRequest(): void { $eventLogger->start('setup_backends', 'Setup group and user backends'); Server::get(\OCP\IUserManager::class)->registerBackend(new \OC\User\Database()); Server::get(\OCP\IGroupManager::class)->addBackend(new \OC\Group\Database()); + $userSession = Server::get(\OCP\IUserSession::class); //setup extra user backends if (!\OCP\Util::needUpgrade()) { OC_User::setupBackends(); } else { // Run upgrades in incognito mode - OC_User::setIncognitoMode(true); + $userSession->setIncognitoMode(true); } $eventLogger->end('setup_backends'); @@ -1354,7 +1355,6 @@ private static function resetStaticProperties(): void { \OC_Hook::clear(); \OC_Util::$styles = []; \OC_Util::$headers = []; - \OC_User::setIncognitoMode(false); \OC_User::$_setupedBackends = []; \OC_Helper::reset(); Filesystem::reset(); diff --git a/lib/private/DirectEditing/Manager.php b/lib/private/DirectEditing/Manager.php index e6b358d80cdd6..9a2ad8911056d 100644 --- a/lib/private/DirectEditing/Manager.php +++ b/lib/private/DirectEditing/Manager.php @@ -25,6 +25,8 @@ use OCP\Files\NotFoundException; use OCP\IDBConnection; use OCP\IL10N; +use OCP\ISession; +use OCP\IUserManager; use OCP\IUserSession; use OCP\L10N\IFactory; use OCP\Security\ISecureRandom; @@ -53,6 +55,8 @@ public function __construct( private IRootFolder $rootFolder, private IFactory $l10nFactory, private EncryptionManager $encryptionManager, + private IUserManager $userManager, + private ISession $session, ) { $this->userId = $userSession->getUser() ? $userSession->getUser()->getUID() : null; $this->l10n = $l10nFactory->get('lib'); @@ -252,8 +256,12 @@ public function accessToken(string $token): bool { return $result !== 0; } - public function invokeTokenScope($userId): void { - \OC_User::setUserId($userId); + public function invokeTokenScope(string $userId): void { + if ($user = $this->userManager->get($userId)) { + $this->userSession->setUser($user); + } else { + $this->session->set('user_id', $userId); + } } public function revertTokenScope(): void { diff --git a/lib/private/Files/Node/UserFolder.php b/lib/private/Files/Node/UserFolder.php index c9290cad3c376..2d552900c3854 100644 --- a/lib/private/Files/Node/UserFolder.php +++ b/lib/private/Files/Node/UserFolder.php @@ -86,6 +86,7 @@ public function getUserQuota(bool $useCache = true): array { 'used' => $used, 'quota' => $quota, 'total' => $total, + 'relative' => $relative, ]; $memcache->set($this->getPath(), $info, 5 * 60); diff --git a/lib/private/Files/Storage/Common.php b/lib/private/Files/Storage/Common.php index 2aa2bc6a3b57d..94d8f39334e4d 100644 --- a/lib/private/Files/Storage/Common.php +++ b/lib/private/Files/Storage/Common.php @@ -40,6 +40,7 @@ use OCP\Files\StorageNotAvailableException; use OCP\IConfig; use OCP\IDBConnection; +use OCP\IUserSession; use OCP\Lock\ILockingProvider; use OCP\Lock\LockedException; use OCP\Server; @@ -412,7 +413,7 @@ public function getStorageCache(?IStorage $storage = null): \OC\Files\Cache\Stor #[\Override] public function getOwner(string $path): string|false { if ($this->owner === null) { - $this->owner = \OC_User::getUser(); + $this->owner = Server::get(IUserSession::class)->getUser()?->getUID() ?? false; } return $this->owner; diff --git a/lib/private/Files/View.php b/lib/private/Files/View.php index 4c4e1c93c58e8..e3dca39675cd7 100644 --- a/lib/private/Files/View.php +++ b/lib/private/Files/View.php @@ -2285,7 +2285,8 @@ public function getUidAndFilename($filename) { throw new NotFoundException($this->getAbsolutePath($filename) . ' not found'); } $uid = $info->getOwner()->getUID(); - if ($uid !== \OC_User::getUser()) { + $userInSession = Server::get(IUserSession::class)->getUser()?->getUID(); + if ($uid !== $userInSession) { Filesystem::initMountPoints($uid); $ownerView = new View('/' . $uid . '/files'); try { diff --git a/lib/private/Log/LogDetails.php b/lib/private/Log/LogDetails.php index ce2942f47f8a9..5b37842babc57 100644 --- a/lib/private/Log/LogDetails.php +++ b/lib/private/Log/LogDetails.php @@ -11,6 +11,7 @@ use OC\SystemConfig; use OCP\IRequest; +use OCP\IUserSession; use OCP\Server; abstract class LogDetails { @@ -37,7 +38,7 @@ public function logDetails(string $app, string|array $message, int $level): arra $url = ($request->getRequestUri() !== '') ? $request->getRequestUri() : '--'; $method = $request->getMethod(); if ($this->config->getValue('installed', false)) { - $user = \OC_User::getUser() ?: '--'; + $user = Server::get(IUserSession::class)->getUser()?->getUID() ?? '--'; } else { $user = '--'; } diff --git a/lib/private/TemplateLayout.php b/lib/private/TemplateLayout.php index bddf34638d719..c17222dd13e7a 100644 --- a/lib/private/TemplateLayout.php +++ b/lib/private/TemplateLayout.php @@ -159,7 +159,7 @@ public function getPageTemplate(string $renderAs, string $appId): ITemplate { } $page->assign('user_displayname', $userDisplayName); - $page->assign('user_uid', \OC_User::getUser()); + $page->assign('user_uid', $user?->getUID() ?? false); break; case TemplateResponse::RENDER_AS_PUBLIC: $page = $this->templateManager->getTemplate('core', 'layout.public'); diff --git a/lib/private/User/Session.php b/lib/private/User/Session.php index 3bbefd7199fa1..4bb64f9b445d2 100644 --- a/lib/private/User/Session.php +++ b/lib/private/User/Session.php @@ -20,7 +20,6 @@ use OC\Hooks\PublicEmitter; use OC\Http\CookieHelper; use OC\Security\CSRF\CsrfTokenManager; -use OC_User; use OCA\DAV\Connector\Sabre\Auth; use OCP\AppFramework\Db\TTransactional; use OCP\AppFramework\Utility\ITimeFactory; @@ -69,6 +68,9 @@ class Session implements IUserSession, Emitter { protected ?IUser $activeUser = null; + // bool, stores if a user want to access a resource anonymously, e.g if they open a public link + private bool $incognitoMode = false; + public function __construct( private Manager $manager, private ISession $session, @@ -172,9 +174,7 @@ public function setVolatileActiveUser(?IUser $user): void { */ #[\Override] public function getUser() { - // FIXME: This is a quick'n dirty work-around for the incognito mode as - // described at https://github.com/owncloud/core/pull/12912#issuecomment-67391155 - if (OC_User::isIncognitoMode()) { + if ($this->isIncognitoMode()) { return null; } if (is_null($this->activeUser)) { @@ -191,6 +191,16 @@ public function getUser() { return $this->activeUser; } + #[\Override] + public function isIncognitoMode(): bool { + return $this->incognitoMode; + } + + #[\Override] + public function setIncognitoMode(bool $mode): void { + $this->incognitoMode = $mode; + } + /** * Validate whether the current session is valid * diff --git a/lib/private/legacy/OC_User.php b/lib/private/legacy/OC_User.php index 9bbdc305a0a3c..3b441d2b93dbd 100644 --- a/lib/private/legacy/OC_User.php +++ b/lib/private/legacy/OC_User.php @@ -40,13 +40,11 @@ * Hooks provided: * post_login(uid) * logout() + * @deprecated 36.0.0 No more non-deprecated methods in there */ class OC_User { public static $_setupedBackends = []; - // bool, stores if a user want to access a resource anonymously, e.g if they open a public link - private static $incognitoMode = false; - /** * Adds the backend to the list of used backends * @@ -97,6 +95,7 @@ public static function clearBackends() { /** * setup the configured backends in config.php * @suppress PhanDeprecatedFunction + * @internal Should not be used by applications */ public static function setupBackends() { Server::get(IAppManager::class)->loadApps(['prelogin']); @@ -135,6 +134,7 @@ public static function setupBackends() { * has already happened (e.g. via Single Sign On). * * Log in a user and regenerate a new session. + * @internal Should not be called by applications */ public static function loginWithApache(IApacheBackend $backend): bool { $uid = $backend->getCurrentUserId(); @@ -200,6 +200,7 @@ public static function loginWithApache(IApacheBackend $backend): bool { * true: authenticated * false: not authenticated * null: not handled / no backend available + * @deprecated 36.0.0 Should not be used by new apps, for user_saml we need to refactor to drop it */ public static function handleApacheAuth(): ?bool { $backend = self::findFirstActiveUsedBackend(); @@ -220,6 +221,7 @@ public static function handleApacheAuth(): ?bool { /** * Sets user id for session and triggers emit + * @deprecated 36.0.0 Use IUserSession */ public static function setUserId(?string $uid): void { $userSession = Server::get(IUserSession::class); @@ -233,21 +235,24 @@ public static function setUserId(?string $uid): void { /** * Set incognito mode, e.g. if a user wants to open a public link + * @deprecated 36.0.0 Use IUserSession::setIncognitoMode instead */ public static function setIncognitoMode(bool $status): void { - self::$incognitoMode = $status; + Server::get(IUserSession::class)->setIncognitoMode($status); } /** * Get incognito mode status + * @deprecated 36.0.0 Use IUserSession::isIncognitoMode instead */ public static function isIncognitoMode(): bool { - return self::$incognitoMode; + return Server::get(IUserSession::class)->isIncognitoMode(); } /** * Returns the current logout URL valid for the currently logged-in user * @return non-empty-string + * @deprecated 36.0.0 Use IURLGenerator */ public static function getLogoutUrl(IURLGenerator $urlGenerator): string { return $urlGenerator->getLogoutUrl(); @@ -257,21 +262,23 @@ public static function getLogoutUrl(IURLGenerator $urlGenerator): string { * Check if the user is an admin user * * @param string $uid uid of the admin + * @deprecated 36.0.0 Use IUserManager and IGroupManager */ public static function isAdminUser(string $uid): bool { $user = Server::get(IUserManager::class)->get($uid); $isAdmin = $user && Server::get(IGroupManager::class)->isAdmin($user->getUID()); - return $isAdmin && self::$incognitoMode === false; + return $isAdmin && !self::isIncognitoMode(); } /** * get the user id of the user currently logged in. * * @return string|false uid or false + * @deprecated 36.0.0 Use IUserSession or DI */ public static function getUser(): string|false { $uid = Server::get(ISession::class)?->get('user_id'); - if (!is_null($uid) && self::$incognitoMode === false) { + if (!is_null($uid) && !self::isIncognitoMode()) { return $uid; } else { return false; @@ -286,6 +293,7 @@ public static function getUser(): string|false { * @param string $recoveryPassword for the encryption app to reset encryption keys * * Change the password of a user + * @deprecated 36.0.0 Use OCP APIs */ public static function setPassword(string $uid, string $password, ?string $recoveryPassword = null): bool { $user = Server::get(IUserManager::class)->get($uid); diff --git a/lib/public/Files/IUserFolder.php b/lib/public/Files/IUserFolder.php index d49e87c0b7142..713fa8d8ba02d 100644 --- a/lib/public/Files/IUserFolder.php +++ b/lib/public/Files/IUserFolder.php @@ -19,7 +19,7 @@ interface IUserFolder extends Folder { /** * @param bool $useCache - Use the cached value if available instead of recalculate. - * @return array{used: int|float, free: int|float, total: int|float, quota: int|float} + * @return array{used: int|float, free: int|float, total: int|float, quota: int|float, relative: float} * @since 36.0.0 */ public function getUserQuota(bool $useCache = true): array; diff --git a/lib/public/IUserSession.php b/lib/public/IUserSession.php index daf25b5bdc43e..33d09f2d7bf27 100644 --- a/lib/public/IUserSession.php +++ b/lib/public/IUserSession.php @@ -96,4 +96,16 @@ public function getImpersonatingUserID(): ?string; * @since 18.0.0 */ public function setImpersonatingUserID(bool $useCurrentUser = true): void; + + /** + * Checks whether incognito mode is currently enabled + * @since 36.0.0 + */ + public function isIncognitoMode(): bool; + + /** + * Sets incognito mode + * @since 36.0.0 + */ + public function setIncognitoMode(bool $mode): void; } diff --git a/public.php b/public.php index fce195ba00ef2..a8f30f218256d 100644 --- a/public.php +++ b/public.php @@ -15,6 +15,7 @@ use OCP\App\IAppManager; use OCP\IConfig; use OCP\IRequest; +use OCP\IUserSession; use OCP\Server; use OCP\Template\ITemplateManager; use OCP\Util; @@ -84,7 +85,8 @@ function resolveService(string $service): string { // Load the app $appManager->loadApp($app); - OC_User::setIncognitoMode(true); + + Server::get(IUserSession::class)->setIncognitoMode(true); $baseuri = OC::$WEBROOT . '/public.php/' . $service . '/'; require_once $file; diff --git a/tests/Core/Controller/TwoFactorChallengeControllerTest.php b/tests/Core/Controller/TwoFactorChallengeControllerTest.php index dbd86ffd35ae7..4463adbf18d70 100644 --- a/tests/Core/Controller/TwoFactorChallengeControllerTest.php +++ b/tests/Core/Controller/TwoFactorChallengeControllerTest.php @@ -59,19 +59,16 @@ protected function setUp(): void { $this->urlGenerator = $this->createMock(IURLGenerator::class); $this->logger = $this->createMock(LoggerInterface::class); - $this->controller = $this->getMockBuilder(TwoFactorChallengeController::class) - ->setConstructorArgs([ - 'core', - $this->request, - $this->twoFactorManager, - $this->userSession, - $this->session, - $this->urlGenerator, - $this->logger, - ]) - ->onlyMethods(['getLogoutUrl']) - ->getMock(); - $this->controller->expects($this->any()) + $this->controller = new TwoFactorChallengeController( + 'core', + $this->request, + $this->twoFactorManager, + $this->userSession, + $this->session, + $this->urlGenerator, + $this->logger, + ); + $this->urlGenerator->expects($this->any()) ->method('getLogoutUrl') ->willReturn('logoutAttribute'); } diff --git a/tests/lib/DirectEditing/ManagerTest.php b/tests/lib/DirectEditing/ManagerTest.php index dcbf4273ad90a..ed14f388b51f9 100644 --- a/tests/lib/DirectEditing/ManagerTest.php +++ b/tests/lib/DirectEditing/ManagerTest.php @@ -21,7 +21,9 @@ use OCP\Files\IUserFolder; use OCP\IDBConnection; use OCP\IL10N; +use OCP\ISession; use OCP\IUser; +use OCP\IUserManager; use OCP\IUserSession; use OCP\L10N\IFactory; use OCP\Security\ISecureRandom; @@ -128,6 +130,9 @@ class ManagerTest extends TestCase { */ private $encryptionManager; + private IUserManager&MockObject $userManager; + private ISession&MockObject $session; + #[\Override] protected function setUp(): void { parent::setUp(); @@ -141,6 +146,8 @@ protected function setUp(): void { $this->userFolder = $this->createMock(IUserFolder::class); $this->l10n = $this->createMock(IL10N::class); $this->encryptionManager = $this->createMock(IManager::class); + $this->userManager = $this->createMock(IUserManager::class); + $this->session = $this->createMock(ISession::class); $l10nFactory = $this->createMock(IFactory::class); $l10nFactory->expects($this->once()) @@ -160,7 +167,14 @@ protected function setUp(): void { ->willReturn($user); $this->manager = new Manager( - $this->random, $this->connection, $this->userSession, $this->rootFolder, $l10nFactory, $this->encryptionManager + $this->random, + $this->connection, + $this->userSession, + $this->rootFolder, + $l10nFactory, + $this->encryptionManager, + $this->userManager, + $this->session, ); $this->manager->registerDirectEditor($this->editor); diff --git a/tests/lib/TestCase.php b/tests/lib/TestCase.php index ec5282867f1ec..5d88e214374f7 100644 --- a/tests/lib/TestCase.php +++ b/tests/lib/TestCase.php @@ -495,10 +495,11 @@ protected static function loginAsUser(string $user = ''): void { self::logout(); $setupManager = Server::get(SetupManager::class); $setupManager->tearDown(); - \OC_User::setUserId($user); $userManager = Server::get(IUserManager::class); + $userSession = Server::get(IUserSession::class); $userObject = $userManager->get($user); if (!is_null($userObject)) { + $userSession->setUser($userObject); $userObject->updateLastLoginTimestamp(); $setupManager->setupForUser($userObject); $rootFolder = Server::get(IRootFolder::class); diff --git a/tests/lib/User/SessionTest.php b/tests/lib/User/SessionTest.php index 20348f63cde34..6c7a9b37f9333 100644 --- a/tests/lib/User/SessionTest.php +++ b/tests/lib/User/SessionTest.php @@ -97,8 +97,6 @@ protected function setUp(): void { 'setMagicInCookie', ]) ->getMock(); - - \OC_User::setIncognitoMode(false); } public static function isLoggedInData(): array {