AvatarManager.php 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors
  5. * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
  6. * SPDX-License-Identifier: AGPL-3.0-only
  7. */
  8. namespace OC\Avatar;
  9. use OC\KnownUser\KnownUserService;
  10. use OC\User\Manager;
  11. use OC\User\NoUserException;
  12. use OCP\Accounts\IAccountManager;
  13. use OCP\Accounts\PropertyDoesNotExistException;
  14. use OCP\Files\IAppData;
  15. use OCP\Files\NotFoundException;
  16. use OCP\Files\NotPermittedException;
  17. use OCP\Files\StorageNotAvailableException;
  18. use OCP\IAvatar;
  19. use OCP\IAvatarManager;
  20. use OCP\IConfig;
  21. use OCP\IL10N;
  22. use OCP\IUserSession;
  23. use Psr\Log\LoggerInterface;
  24. /**
  25. * This class implements methods to access Avatar functionality
  26. */
  27. class AvatarManager implements IAvatarManager {
  28. public function __construct(
  29. private IUserSession $userSession,
  30. private Manager $userManager,
  31. private IAppData $appData,
  32. private IL10N $l,
  33. private LoggerInterface $logger,
  34. private IConfig $config,
  35. private IAccountManager $accountManager,
  36. private KnownUserService $knownUserService,
  37. ) {
  38. }
  39. /**
  40. * return a user specific instance of \OCP\IAvatar
  41. *
  42. * If the user is disabled a guest avatar will be returned
  43. *
  44. * @see \OCP\IAvatar
  45. * @param string $userId the ownCloud user id
  46. * @throws \Exception In case the username is potentially dangerous
  47. * @throws NotFoundException In case there is no user folder yet
  48. */
  49. public function getAvatar(string $userId): IAvatar {
  50. $user = $this->userManager->get($userId);
  51. if ($user === null) {
  52. throw new \Exception('user does not exist');
  53. }
  54. if (!$user->isEnabled()) {
  55. return $this->getGuestAvatar($userId);
  56. }
  57. // sanitize userID - fixes casing issue (needed for the filesystem stuff that is done below)
  58. $userId = $user->getUID();
  59. $requestingUser = $this->userSession->getUser();
  60. try {
  61. $folder = $this->appData->getFolder($userId);
  62. } catch (NotFoundException $e) {
  63. $folder = $this->appData->newFolder($userId);
  64. }
  65. try {
  66. $account = $this->accountManager->getAccount($user);
  67. $avatarProperties = $account->getProperty(IAccountManager::PROPERTY_AVATAR);
  68. $avatarScope = $avatarProperties->getScope();
  69. } catch (PropertyDoesNotExistException $e) {
  70. $avatarScope = '';
  71. }
  72. switch ($avatarScope) {
  73. // v2-private scope hides the avatar from public access and from unknown users
  74. case IAccountManager::SCOPE_PRIVATE:
  75. if ($requestingUser !== null && $this->knownUserService->isKnownToUser($requestingUser->getUID(), $userId)) {
  76. return new UserAvatar($folder, $this->l, $user, $this->logger, $this->config);
  77. }
  78. break;
  79. case IAccountManager::SCOPE_LOCAL:
  80. case IAccountManager::SCOPE_FEDERATED:
  81. case IAccountManager::SCOPE_PUBLISHED:
  82. return new UserAvatar($folder, $this->l, $user, $this->logger, $this->config);
  83. default:
  84. // use a placeholder avatar which caches the generated images
  85. return new PlaceholderAvatar($folder, $user, $this->logger);
  86. }
  87. return new PlaceholderAvatar($folder, $user, $this->logger);
  88. }
  89. /**
  90. * Clear generated avatars
  91. */
  92. public function clearCachedAvatars(): void {
  93. $users = $this->config->getUsersForUserValue('avatar', 'generated', 'true');
  94. foreach ($users as $userId) {
  95. // This also bumps the avatar version leading to cache invalidation in browsers
  96. $this->getAvatar($userId)->remove();
  97. }
  98. }
  99. public function deleteUserAvatar(string $userId): void {
  100. try {
  101. $folder = $this->appData->getFolder($userId);
  102. $folder->delete();
  103. } catch (NotFoundException $e) {
  104. $this->logger->debug("No cache for the user $userId. Ignoring avatar deletion");
  105. } catch (NotPermittedException | StorageNotAvailableException $e) {
  106. $this->logger->error("Unable to delete user avatars for $userId. gnoring avatar deletion");
  107. } catch (NoUserException $e) {
  108. $this->logger->debug("Account $userId not found. Ignoring avatar deletion");
  109. }
  110. $this->config->deleteUserValue($userId, 'avatar', 'generated');
  111. }
  112. /**
  113. * Returns a GuestAvatar.
  114. *
  115. * @param string $name The guest name, e.g. "Albert".
  116. */
  117. public function getGuestAvatar(string $name): IAvatar {
  118. return new GuestAvatar($name, $this->logger);
  119. }
  120. }