From: Joas Schilling Date: Mon, 23 Oct 2023 10:28:48 +0000 (+0200) Subject: feat(profile): Add public interface for profile manager so apps can check config X-Git-Tag: v28.0.0beta1~82^2~1 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=2353d3cd5c1bc01c7ae4da9cd1c341f795982686;p=nextcloud-server.git feat(profile): Add public interface for profile manager so apps can check config Signed-off-by: Joas Schilling --- diff --git a/core/Controller/ProfilePageController.php b/core/Controller/ProfilePageController.php index 5034a665684..eacdd14c932 100644 --- a/core/Controller/ProfilePageController.php +++ b/core/Controller/ProfilePageController.php @@ -101,7 +101,7 @@ class ProfilePageController extends Controller { $this->initialStateService->provideInitialState( 'profileParameters', - $this->profileManager->getProfileParams($targetUser, $visitingUser), + $this->profileManager->getProfileFields($targetUser, $visitingUser), ); $this->eventDispatcher->dispatchTyped(new BeforeTemplateRenderedEvent($targetUserId)); diff --git a/core/Db/ProfileConfig.php b/core/Db/ProfileConfig.php index 3ebfe02ca79..ea0507df982 100644 --- a/core/Db/ProfileConfig.php +++ b/core/Db/ProfileConfig.php @@ -26,10 +26,10 @@ declare(strict_types=1); namespace OC\Core\Db; +use OCP\Profile\IProfileManager; use function Safe\json_decode; use function Safe\json_encode; use \JsonSerializable; -use OCP\Accounts\IAccountManager; use OCP\AppFramework\Db\Entity; use OCP\Profile\ParameterDoesNotExistException; @@ -44,48 +44,41 @@ class ProfileConfig extends Entity implements JsonSerializable { * Visible to users, guests, and public access * * @since 23.0.0 + * @deprecated 28.0.0 Use {@see IProfileManager::VISIBILITY_SHOW} instead */ - public const VISIBILITY_SHOW = 'show'; + public const VISIBILITY_SHOW = IProfileManager::VISIBILITY_SHOW; /** * Visible to users and guests * * @since 23.0.0 + * @deprecated 28.0.0 Use {@see IProfileManager::VISIBILITY_SHOW_USERS_ONLY} instead */ - public const VISIBILITY_SHOW_USERS_ONLY = 'show_users_only'; + public const VISIBILITY_SHOW_USERS_ONLY = IProfileManager::VISIBILITY_SHOW_USERS_ONLY; /** * Visible to nobody * * @since 23.0.0 + * @deprecated 28.0.0 Use {@see IProfileManager::VISIBILITY_HIDE} instead */ - public const VISIBILITY_HIDE = 'hide'; + public const VISIBILITY_HIDE = IProfileManager::VISIBILITY_HIDE; /** * Default account property visibility * * @since 23.0.0 + * @deprecated 28.0.0 Use {@see IProfileManager::DEFAULT_PROPERTY_VISIBILITY} instead */ - public const DEFAULT_PROPERTY_VISIBILITY = [ - IAccountManager::PROPERTY_ADDRESS => self::VISIBILITY_SHOW_USERS_ONLY, - IAccountManager::PROPERTY_AVATAR => self::VISIBILITY_SHOW, - IAccountManager::PROPERTY_BIOGRAPHY => self::VISIBILITY_SHOW, - IAccountManager::PROPERTY_DISPLAYNAME => self::VISIBILITY_SHOW, - IAccountManager::PROPERTY_HEADLINE => self::VISIBILITY_SHOW, - IAccountManager::PROPERTY_ORGANISATION => self::VISIBILITY_SHOW, - IAccountManager::PROPERTY_ROLE => self::VISIBILITY_SHOW, - IAccountManager::PROPERTY_EMAIL => self::VISIBILITY_SHOW_USERS_ONLY, - IAccountManager::PROPERTY_PHONE => self::VISIBILITY_SHOW_USERS_ONLY, - IAccountManager::PROPERTY_TWITTER => self::VISIBILITY_SHOW, - IAccountManager::PROPERTY_WEBSITE => self::VISIBILITY_SHOW, - ]; + public const DEFAULT_PROPERTY_VISIBILITY = IProfileManager::DEFAULT_PROPERTY_VISIBILITY; /** * Default visibility * * @since 23.0.0 + * @deprecated 28.0.0 Use {@see IProfileManager::DEFAULT_VISIBILITY} instead */ - public const DEFAULT_VISIBILITY = self::VISIBILITY_SHOW_USERS_ONLY; + public const DEFAULT_VISIBILITY = IProfileManager::DEFAULT_VISIBILITY; /** @var string */ protected $userId; diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php index 9d0570d349c..401d240da06 100644 --- a/lib/composer/composer/autoload_classmap.php +++ b/lib/composer/composer/autoload_classmap.php @@ -552,6 +552,7 @@ return array( 'OCP\\Preview\\IVersionedPreviewFile' => $baseDir . '/lib/public/Preview/IVersionedPreviewFile.php', 'OCP\\Profile\\BeforeTemplateRenderedEvent' => $baseDir . '/lib/public/Profile/BeforeTemplateRenderedEvent.php', 'OCP\\Profile\\ILinkAction' => $baseDir . '/lib/public/Profile/ILinkAction.php', + 'OCP\\Profile\\IProfileManager' => $baseDir . '/lib/public/Profile/IProfileManager.php', 'OCP\\Profile\\ParameterDoesNotExistException' => $baseDir . '/lib/public/Profile/ParameterDoesNotExistException.php', 'OCP\\Profiler\\IProfile' => $baseDir . '/lib/public/Profiler/IProfile.php', 'OCP\\Profiler\\IProfiler' => $baseDir . '/lib/public/Profiler/IProfiler.php', diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php index 63ad21216a4..7be62a3cf62 100644 --- a/lib/composer/composer/autoload_static.php +++ b/lib/composer/composer/autoload_static.php @@ -585,6 +585,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2 'OCP\\Preview\\IVersionedPreviewFile' => __DIR__ . '/../../..' . '/lib/public/Preview/IVersionedPreviewFile.php', 'OCP\\Profile\\BeforeTemplateRenderedEvent' => __DIR__ . '/../../..' . '/lib/public/Profile/BeforeTemplateRenderedEvent.php', 'OCP\\Profile\\ILinkAction' => __DIR__ . '/../../..' . '/lib/public/Profile/ILinkAction.php', + 'OCP\\Profile\\IProfileManager' => __DIR__ . '/../../..' . '/lib/public/Profile/IProfileManager.php', 'OCP\\Profile\\ParameterDoesNotExistException' => __DIR__ . '/../../..' . '/lib/public/Profile/ParameterDoesNotExistException.php', 'OCP\\Profiler\\IProfile' => __DIR__ . '/../../..' . '/lib/public/Profiler/IProfile.php', 'OCP\\Profiler\\IProfiler' => __DIR__ . '/../../..' . '/lib/public/Profiler/IProfiler.php', diff --git a/lib/private/Profile/ProfileManager.php b/lib/private/Profile/ProfileManager.php index 8fa65271205..ed79b622a7c 100644 --- a/lib/private/Profile/ProfileManager.php +++ b/lib/private/Profile/ProfileManager.php @@ -26,8 +26,9 @@ declare(strict_types=1); namespace OC\Profile; -use function Safe\array_flip; -use function Safe\usort; +use OCP\Profile\IProfileManager; +use function array_flip; +use function usort; use OC\AppFramework\Bootstrap\Coordinator; use OC\Core\Db\ProfileConfig; use OC\Core\Db\ProfileConfigMapper; @@ -49,7 +50,7 @@ use OCP\Cache\CappedMemoryCache; use Psr\Container\ContainerInterface; use Psr\Log\LoggerInterface; -class ProfileManager { +class ProfileManager implements IProfileManager { /** @var ILinkAction[] */ private array $actions = []; @@ -101,7 +102,7 @@ class ProfileManager { /** * If no user is passed as an argument return whether profile is enabled globally in `config.php` */ - public function isProfileEnabled(?IUser $user = null): ?bool { + public function isProfileEnabled(?IUser $user = null): bool { $profileEnabledGlobally = $this->config->getSystemValueBool('profile.enabled', true); if (empty($user) || !$profileEnabledGlobally) { @@ -109,7 +110,7 @@ class ProfileManager { } $account = $this->accountManager->getAccount($user); - return filter_var( + return (bool) filter_var( $account->getProperty(IAccountManager::PROPERTY_PROFILE_ENABLED)->getValue(), FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE, @@ -193,15 +194,15 @@ class ProfileManager { * Return whether the profile parameter of the target user * is visible to the visiting user */ - private function isParameterVisible(string $paramId, IUser $targetUser, ?IUser $visitingUser): bool { + public function isProfileFieldVisible(string $profileField, IUser $targetUser, ?IUser $visitingUser): bool { try { $account = $this->accountManager->getAccount($targetUser); - $scope = $account->getProperty($paramId)->getScope(); + $scope = $account->getProperty($profileField)->getScope(); } catch (PropertyDoesNotExistException $e) { // Allow the exception as not all profile parameters are account properties } - $visibility = $this->getProfileConfig($targetUser, $visitingUser)[$paramId]['visibility']; + $visibility = $this->getProfileConfig($targetUser, $visitingUser)[$profileField]['visibility']; // Handle profile visibility and account property scope if ($visibility === ProfileConfig::VISIBILITY_SHOW_USERS_ONLY) { @@ -221,7 +222,7 @@ class ProfileManager { if ($visibility === ProfileConfig::VISIBILITY_SHOW) { if (empty($scope)) { return true; - }; + } return match ($scope) { IAccountManager::SCOPE_PRIVATE => $visitingUser !== null && $this->knownUserService->isKnownToUser($targetUser->getUID(), $visitingUser->getUID()), @@ -238,8 +239,9 @@ class ProfileManager { /** * Return the profile parameters of the target user that are visible to the visiting user * in an associative array + * @return array{userId: string, address?: string|null, biography?: string|null, displayname?: string|null, headline?: string|null, isUserAvatarVisible?: bool, organisation?: string|null, role?: string|null, actions: list} */ - public function getProfileParams(IUser $targetUser, ?IUser $visitingUser): array { + public function getProfileFields(IUser $targetUser, ?IUser $visitingUser): array { $account = $this->accountManager->getAccount($targetUser); // Initialize associative array of profile parameters @@ -257,14 +259,14 @@ class ProfileManager { case IAccountManager::PROPERTY_ORGANISATION: case IAccountManager::PROPERTY_ROLE: $profileParameters[$property] = - $this->isParameterVisible($property, $targetUser, $visitingUser) + $this->isProfileFieldVisible($property, $targetUser, $visitingUser) // Explicitly set to null when value is empty string ? ($account->getProperty($property)->getValue() ?: null) : null; break; case IAccountManager::PROPERTY_AVATAR: // Add avatar visibility - $profileParameters['isUserAvatarVisible'] = $this->isParameterVisible($property, $targetUser, $visitingUser); + $profileParameters['isUserAvatarVisible'] = $this->isProfileFieldVisible($property, $targetUser, $visitingUser); break; } } @@ -284,7 +286,7 @@ class ProfileManager { array_filter( $this->getActions($targetUser, $visitingUser), function (ILinkAction $action) use ($targetUser, $visitingUser) { - return $this->isParameterVisible($action->getId(), $targetUser, $visitingUser); + return $this->isProfileFieldVisible($action->getId(), $targetUser, $visitingUser); } ), ) diff --git a/lib/private/Server.php b/lib/private/Server.php index b8004670634..37b7669f624 100644 --- a/lib/private/Server.php +++ b/lib/private/Server.php @@ -130,6 +130,7 @@ use OC\OCS\DiscoveryService; use OC\Preview\GeneratorHelper; use OC\Preview\IMagickSupport; use OC\Preview\MimeIconProvider; +use OC\Profile\ProfileManager; use OC\Remote\Api\ApiFactory; use OC\Remote\InstanceFactory; use OC\RichObjectStrings\Validator; @@ -235,6 +236,7 @@ use OCP\Log\ILogFactory; use OCP\Mail\IMailer; use OCP\OCM\IOCMDiscoveryService; use OCP\OCM\IOCMProvider; +use OCP\Profile\IProfileManager; use OCP\Remote\Api\IApiFactory; use OCP\Remote\IInstanceFactory; use OCP\RichObjectStrings\IValidator; @@ -1434,6 +1436,8 @@ class Server extends ServerContainer implements IServerContainer { $this->registerAlias(ISetupCheckManager::class, SetupCheckManager::class); + $this->registerAlias(IProfileManager::class, ProfileManager::class); + $this->connectDispatcher(); } diff --git a/lib/public/Profile/IProfileManager.php b/lib/public/Profile/IProfileManager.php new file mode 100644 index 00000000000..996e49d116e --- /dev/null +++ b/lib/public/Profile/IProfileManager.php @@ -0,0 +1,106 @@ + + * + * @author Joas Schilling + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +namespace OCP\Profile; + +use OCP\Accounts\IAccountManager; +use OCP\IUser; + +/** + * @since 28.0.0 + */ +interface IProfileManager { + /** + * Visible to users, guests, and public access + * + * @since 28.0.0 + */ + public const VISIBILITY_SHOW = 'show'; + + /** + * Visible to users and guests + * + * @since 28.0.0 + */ + public const VISIBILITY_SHOW_USERS_ONLY = 'show_users_only'; + + /** + * Visible to nobody + * + * @since 28.0.0 + */ + public const VISIBILITY_HIDE = 'hide'; + + /** + * Default account property visibility + * + * @since 28.0.0 + */ + public const DEFAULT_PROPERTY_VISIBILITY = [ + IAccountManager::PROPERTY_ADDRESS => self::VISIBILITY_SHOW_USERS_ONLY, + IAccountManager::PROPERTY_AVATAR => self::VISIBILITY_SHOW, + IAccountManager::PROPERTY_BIOGRAPHY => self::VISIBILITY_SHOW, + IAccountManager::PROPERTY_DISPLAYNAME => self::VISIBILITY_SHOW, + IAccountManager::PROPERTY_HEADLINE => self::VISIBILITY_SHOW, + IAccountManager::PROPERTY_ORGANISATION => self::VISIBILITY_SHOW, + IAccountManager::PROPERTY_ROLE => self::VISIBILITY_SHOW, + IAccountManager::PROPERTY_EMAIL => self::VISIBILITY_SHOW_USERS_ONLY, + IAccountManager::PROPERTY_PHONE => self::VISIBILITY_SHOW_USERS_ONLY, + IAccountManager::PROPERTY_TWITTER => self::VISIBILITY_SHOW, + IAccountManager::PROPERTY_WEBSITE => self::VISIBILITY_SHOW, + ]; + + /** + * Default visibility + * + * @since 28.0.0 + */ + public const DEFAULT_VISIBILITY = self::VISIBILITY_SHOW_USERS_ONLY; + + /** + * If no user is passed as an argument return whether profile is enabled globally in `config.php` + * + * @since 28.0.0 + */ + public function isProfileEnabled(?IUser $user = null): bool; + + /** + * Return whether the profile parameter of the target user + * is visible to the visiting user + * + * @since 28.0.0 + */ + public function isProfileFieldVisible(string $profileField, IUser $targetUser, ?IUser $visitingUser): bool; + + /** + * Return the profile parameters of the target user that are visible to the visiting user + * in an associative array + * + * @return array{userId: string, address?: ?string, biography?: ?string, displayname?: ?string, headline?: ?string, isUserAvatarVisible?: bool, organisation?: ?string, role?: ?string, actions: list} + * @since 28.0.0 + */ + public function getProfileFields(IUser $targetUser, ?IUser $visitingUser): array; +}