diff options
author | Jonas Meurer <jonas@freesources.org> | 2021-07-08 18:26:27 +0200 |
---|---|---|
committer | Jonas Meurer <jonas@freesources.org> | 2021-10-20 11:33:23 +0200 |
commit | 3fe267b77279a44dcd9f4ccf75cd2f7ac8321c7b (patch) | |
tree | 84568b792a7112523427c7726d1ed0e92d60fc99 /apps/user_status/lib | |
parent | 2083e1ede253a6ea76f67d37c382cd851620ad99 (diff) | |
download | nextcloud-server-3fe267b77279a44dcd9f4ccf75cd2f7ac8321c7b.tar.gz nextcloud-server-3fe267b77279a44dcd9f4ccf75cd2f7ac8321c7b.zip |
Respect user enumeration settings in user status lists
So far, the functions to find user statuses listed didn't respect user
enumeration settings (`shareapi_allow_share_dialog_user_enumeration`
and `shareapi_restrict_user_enumeration_to_group` core app settings).
Fix this privacy issue by returning an empty list in case
`shareapi_allow_share_dialog_user_enumeration` is unset or
`shareapi_restrict_user_enumeration_to_group` is set.
In the long run, we might want to return users from common groups if
`shareapi_restrict_user_enumeration_to_group` is set. It's complicated
to implement this in a way that scales, though. See the discussion at
https://github.com/nextcloud/server/pull/27879#pullrequestreview-753655308
for details.
Also, don't register the user_status dashboard widget at all if
`shareapi_allow_share_dialog_user_enumeration` is unset or
`shareapi_restrict_user_enumeration_to_group` is set.
Fixes: #27122
Signed-off-by: Jonas Meurer <jonas@freesources.org>
Diffstat (limited to 'apps/user_status/lib')
-rw-r--r-- | apps/user_status/lib/AppInfo/Application.php | 12 | ||||
-rw-r--r-- | apps/user_status/lib/Service/StatusService.php | 37 |
2 files changed, 43 insertions, 6 deletions
diff --git a/apps/user_status/lib/AppInfo/Application.php b/apps/user_status/lib/AppInfo/Application.php index 8ccf0f497c3..7a47fc45c95 100644 --- a/apps/user_status/lib/AppInfo/Application.php +++ b/apps/user_status/lib/AppInfo/Application.php @@ -36,6 +36,7 @@ use OCP\AppFramework\Bootstrap\IBootContext; use OCP\AppFramework\Bootstrap\IBootstrap; use OCP\AppFramework\Bootstrap\IRegistrationContext; use OCP\AppFramework\Http\Events\BeforeTemplateRenderedEvent; +use OCP\IConfig; use OCP\User\Events\UserDeletedEvent; use OCP\User\Events\UserLiveStatusEvent; use OCP\UserStatus\IManager; @@ -71,8 +72,15 @@ class Application extends App implements IBootstrap { $context->registerEventListener(UserLiveStatusEvent::class, UserLiveStatusListener::class); $context->registerEventListener(BeforeTemplateRenderedEvent::class, BeforeTemplateRenderedListener::class); - // Register the Dashboard panel - $context->registerDashboardWidget(UserStatusWidget::class); + $config = $this->getContainer()->query(IConfig::class); + $shareeEnumeration = $config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') === 'yes'; + $shareeEnumerationInGroupOnly = $shareeEnumeration && $config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_group', 'no') === 'yes'; + $shareeEnumerationPhone = $shareeEnumeration && $config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_phone', 'no') === 'yes'; + + // Register the Dashboard panel if user enumeration is enabled and not limited + if ($shareeEnumeration && !$shareeEnumerationInGroupOnly && !$shareeEnumerationPhone) { + $context->registerDashboardWidget(UserStatusWidget::class); + } } public function boot(IBootContext $context): void { diff --git a/apps/user_status/lib/Service/StatusService.php b/apps/user_status/lib/Service/StatusService.php index 9d1cf8764ba..655c37da9cc 100644 --- a/apps/user_status/lib/Service/StatusService.php +++ b/apps/user_status/lib/Service/StatusService.php @@ -35,6 +35,7 @@ use OCA\UserStatus\Exception\InvalidStatusTypeException; use OCA\UserStatus\Exception\StatusMessageTooLongException; use OCP\AppFramework\Db\DoesNotExistException; use OCP\AppFramework\Utility\ITimeFactory; +use OCP\IConfig; use OCP\UserStatus\IUserStatus; /** @@ -56,6 +57,15 @@ class StatusService { /** @var EmojiService */ private $emojiService; + /** @var bool */ + private $shareeEnumeration; + + /** @var bool */ + private $shareeEnumerationInGroupOnly; + + /** @var bool */ + private $shareeEnumerationPhone; + /** * List of priorities ordered by their priority */ @@ -88,17 +98,22 @@ class StatusService { * * @param UserStatusMapper $mapper * @param ITimeFactory $timeFactory - * @param PredefinedStatusService $defaultStatusService, + * @param PredefinedStatusService $defaultStatusService * @param EmojiService $emojiService + * @param IConfig $config */ public function __construct(UserStatusMapper $mapper, ITimeFactory $timeFactory, PredefinedStatusService $defaultStatusService, - EmojiService $emojiService) { + EmojiService $emojiService, + IConfig $config) { $this->mapper = $mapper; $this->timeFactory = $timeFactory; $this->predefinedStatusService = $defaultStatusService; $this->emojiService = $emojiService; + $this->shareeEnumeration = $config->getAppValue('core', 'shareapi_allow_share_dialog_user_enumeration', 'yes') === 'yes'; + $this->shareeEnumerationInGroupOnly = $this->shareeEnumeration && $config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_group', 'no') === 'yes'; + $this->shareeEnumerationPhone = $this->shareeEnumeration && $config->getAppValue('core', 'shareapi_restrict_user_enumeration_to_phone', 'no') === 'yes'; } /** @@ -107,6 +122,13 @@ class StatusService { * @return UserStatus[] */ public function findAll(?int $limit = null, ?int $offset = null): array { + // Return empty array if user enumeration is disabled or limited to groups + // TODO: find a solution that scales to get only users from common groups if user enumeration is limited to + // groups. See discussion at https://github.com/nextcloud/server/pull/27879#discussion_r729715936 + if (!$this->shareeEnumeration || $this->shareeEnumerationInGroupOnly || $this->shareeEnumerationPhone) { + return []; + } + return array_map(function ($status) { return $this->processStatus($status); }, $this->mapper->findAll($limit, $offset)); @@ -118,6 +140,13 @@ class StatusService { * @return array */ public function findAllRecentStatusChanges(?int $limit = null, ?int $offset = null): array { + // Return empty array if user enumeration is disabled or limited to groups + // TODO: find a solution that scales to get only users from common groups if user enumeration is limited to + // groups. See discussion at https://github.com/nextcloud/server/pull/27879#discussion_r729715936 + if (!$this->shareeEnumeration || $this->shareeEnumerationInGroupOnly || $this->shareeEnumerationPhone) { + return []; + } + return array_map(function ($status) { return $this->processStatus($status); }, $this->mapper->findAllRecent($limit, $offset)); @@ -226,7 +255,7 @@ class StatusService { /** * @param string $userId * @param string|null $statusIcon - * @param string|null $message + * @param string $message * @param int|null $clearAt * @return UserStatus * @throws InvalidClearAtException @@ -334,7 +363,7 @@ class StatusService { * up to date and provides translated default status if needed * * @param UserStatus $status - * @returns UserStatus + * @return UserStatus */ private function processStatus(UserStatus $status): UserStatus { $clearAt = $status->getClearAt(); |