1a25f0a04SGreg Roach<?php 23976b470SGreg Roach 3a25f0a04SGreg Roach/** 4a25f0a04SGreg Roach * webtrees: online genealogy 5d11be702SGreg Roach * Copyright (C) 2023 webtrees development team 6a25f0a04SGreg Roach * This program is free software: you can redistribute it and/or modify 7a25f0a04SGreg Roach * it under the terms of the GNU General Public License as published by 8a25f0a04SGreg Roach * the Free Software Foundation, either version 3 of the License, or 9a25f0a04SGreg Roach * (at your option) any later version. 10a25f0a04SGreg Roach * This program is distributed in the hope that it will be useful, 11a25f0a04SGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of 12a25f0a04SGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13a25f0a04SGreg Roach * GNU General Public License for more details. 14a25f0a04SGreg Roach * You should have received a copy of the GNU General Public License 1589f7189bSGreg Roach * along with this program. If not, see <https://www.gnu.org/licenses/>. 16a25f0a04SGreg Roach */ 17fcfa147eSGreg Roach 18e7f56f2aSGreg Roachdeclare(strict_types=1); 19e7f56f2aSGreg Roach 2076692c8bSGreg Roachnamespace Fisharebest\Webtrees; 21a25f0a04SGreg Roach 22e5a6b4d4SGreg Roachuse Fisharebest\Webtrees\Contracts\UserInterface; 2381b729d3SGreg Roachuse Fisharebest\Webtrees\Http\Exceptions\HttpAccessDeniedException; 2481b729d3SGreg Roachuse Fisharebest\Webtrees\Http\Exceptions\HttpNotFoundException; 259867b2f0SGreg Roachuse Fisharebest\Webtrees\Module\ModuleInterface; 26e5a6b4d4SGreg Roachuse Fisharebest\Webtrees\Services\UserService; 2779529c87SGreg Roach 2810e06497SGreg Roachuse function assert; 29d8809d62SGreg Roachuse function is_int; 30d8809d62SGreg Roach 31a25f0a04SGreg Roach/** 3276692c8bSGreg Roach * Authentication. 33a25f0a04SGreg Roach */ 34c1010edaSGreg Roachclass Auth 35c1010edaSGreg Roach{ 364b9ff166SGreg Roach // Privacy constants 3716d6367aSGreg Roach public const PRIV_PRIVATE = 2; // Allows visitors to view the item 3816d6367aSGreg Roach public const PRIV_USER = 1; // Allows members to access the item 3916d6367aSGreg Roach public const PRIV_NONE = 0; // Allows managers to access the item 4016d6367aSGreg Roach public const PRIV_HIDE = -1; // Hide the item to all users 414b9ff166SGreg Roach 42a25f0a04SGreg Roach /** 43a25f0a04SGreg Roach * Are we currently logged in? 44a25f0a04SGreg Roach * 45cbc1590aSGreg Roach * @return bool 46a25f0a04SGreg Roach */ 478f53f488SRico Sonntag public static function check(): bool 48c1010edaSGreg Roach { 494b9ff166SGreg Roach return self::id() !== null; 50a25f0a04SGreg Roach } 51a25f0a04SGreg Roach 52a25f0a04SGreg Roach /** 53a25f0a04SGreg Roach * Is the specified/current user an administrator? 54a25f0a04SGreg Roach * 55e5a6b4d4SGreg Roach * @param UserInterface|null $user 56a25f0a04SGreg Roach * 57cbc1590aSGreg Roach * @return bool 58a25f0a04SGreg Roach */ 59e5a6b4d4SGreg Roach public static function isAdmin(UserInterface $user = null): bool 60c1010edaSGreg Roach { 613529c469SGreg Roach $user ??= self::user(); 62a25f0a04SGreg Roach 631fe542e9SGreg Roach return $user->getPreference(UserInterface::PREF_IS_ADMINISTRATOR) === '1'; 64a25f0a04SGreg Roach } 65a25f0a04SGreg Roach 66a25f0a04SGreg Roach /** 674b9ff166SGreg Roach * Is the specified/current user a manager of a tree? 68a25f0a04SGreg Roach * 6984caa210SGreg Roach * @param Tree $tree 70e5a6b4d4SGreg Roach * @param UserInterface|null $user 71a25f0a04SGreg Roach * 72cbc1590aSGreg Roach * @return bool 73a25f0a04SGreg Roach */ 74e5a6b4d4SGreg Roach public static function isManager(Tree $tree, UserInterface $user = null): bool 75c1010edaSGreg Roach { 763529c469SGreg Roach $user ??= self::user(); 77a25f0a04SGreg Roach 781fe542e9SGreg Roach return self::isAdmin($user) || $tree->getUserPreference($user, UserInterface::PREF_TREE_ROLE) === UserInterface::ROLE_MANAGER; 79a25f0a04SGreg Roach } 80a25f0a04SGreg Roach 81a25f0a04SGreg Roach /** 824b9ff166SGreg Roach * Is the specified/current user a moderator of a tree? 83a25f0a04SGreg Roach * 8484caa210SGreg Roach * @param Tree $tree 85e5a6b4d4SGreg Roach * @param UserInterface|null $user 86a25f0a04SGreg Roach * 87cbc1590aSGreg Roach * @return bool 88a25f0a04SGreg Roach */ 89e5a6b4d4SGreg Roach public static function isModerator(Tree $tree, UserInterface $user = null): bool 90c1010edaSGreg Roach { 913529c469SGreg Roach $user ??= self::user(); 92a25f0a04SGreg Roach 931fe542e9SGreg Roach return 941fe542e9SGreg Roach self::isManager($tree, $user) || 951fe542e9SGreg Roach $tree->getUserPreference($user, UserInterface::PREF_TREE_ROLE) === UserInterface::ROLE_MODERATOR; 96a25f0a04SGreg Roach } 97a25f0a04SGreg Roach 98a25f0a04SGreg Roach /** 994b9ff166SGreg Roach * Is the specified/current user an editor of a tree? 100a25f0a04SGreg Roach * 10184caa210SGreg Roach * @param Tree $tree 102e5a6b4d4SGreg Roach * @param UserInterface|null $user 103a25f0a04SGreg Roach * 104cbc1590aSGreg Roach * @return bool 105a25f0a04SGreg Roach */ 106e5a6b4d4SGreg Roach public static function isEditor(Tree $tree, UserInterface $user = null): bool 107c1010edaSGreg Roach { 1083529c469SGreg Roach $user ??= self::user(); 109a25f0a04SGreg Roach 1101fe542e9SGreg Roach return 1111fe542e9SGreg Roach self::isModerator($tree, $user) || 1121fe542e9SGreg Roach $tree->getUserPreference($user, UserInterface::PREF_TREE_ROLE) === UserInterface::ROLE_EDITOR; 113a25f0a04SGreg Roach } 114a25f0a04SGreg Roach 115a25f0a04SGreg Roach /** 1164b9ff166SGreg Roach * Is the specified/current user a member of a tree? 117a25f0a04SGreg Roach * 11884caa210SGreg Roach * @param Tree $tree 119e5a6b4d4SGreg Roach * @param UserInterface|null $user 120a25f0a04SGreg Roach * 121cbc1590aSGreg Roach * @return bool 122a25f0a04SGreg Roach */ 123e5a6b4d4SGreg Roach public static function isMember(Tree $tree, UserInterface $user = null): bool 124c1010edaSGreg Roach { 1253529c469SGreg Roach $user ??= self::user(); 126a25f0a04SGreg Roach 1271fe542e9SGreg Roach return 1281fe542e9SGreg Roach self::isEditor($tree, $user) || 1291fe542e9SGreg Roach $tree->getUserPreference($user, UserInterface::PREF_TREE_ROLE) === UserInterface::ROLE_MEMBER; 130a25f0a04SGreg Roach } 131a25f0a04SGreg Roach 132a25f0a04SGreg Roach /** 1334b9ff166SGreg Roach * What is the specified/current user's access level within a tree? 1344b9ff166SGreg Roach * 1354b9ff166SGreg Roach * @param Tree $tree 136e5a6b4d4SGreg Roach * @param UserInterface|null $user 1374b9ff166SGreg Roach * 138cbc1590aSGreg Roach * @return int 1394b9ff166SGreg Roach */ 140e364afe4SGreg Roach public static function accessLevel(Tree $tree, UserInterface $user = null): int 141c1010edaSGreg Roach { 1423529c469SGreg Roach $user ??= self::user(); 1434b9ff166SGreg Roach 1444b9ff166SGreg Roach if (self::isManager($tree, $user)) { 1454b9ff166SGreg Roach return self::PRIV_NONE; 1464b9ff166SGreg Roach } 147b2ce94c6SRico Sonntag 148b2ce94c6SRico Sonntag if (self::isMember($tree, $user)) { 149b2ce94c6SRico Sonntag return self::PRIV_USER; 150b2ce94c6SRico Sonntag } 151b2ce94c6SRico Sonntag 152b2ce94c6SRico Sonntag return self::PRIV_PRIVATE; 1534b9ff166SGreg Roach } 1544b9ff166SGreg Roach 1554b9ff166SGreg Roach /** 156a25f0a04SGreg Roach * The ID of the authenticated user, from the current session. 157a25f0a04SGreg Roach * 158c3ffc4cbSGreg Roach * @return int|null 159a25f0a04SGreg Roach */ 160e364afe4SGreg Roach public static function id(): ?int 161c1010edaSGreg Roach { 162d8809d62SGreg Roach $wt_user = Session::get('wt_user'); 163d8809d62SGreg Roach 164d8809d62SGreg Roach return is_int($wt_user) ? $wt_user : null; 165a25f0a04SGreg Roach } 166a25f0a04SGreg Roach 167a25f0a04SGreg Roach /** 168a25f0a04SGreg Roach * The authenticated user, from the current session. 169a25f0a04SGreg Roach * 170e5a6b4d4SGreg Roach * @return UserInterface 171a25f0a04SGreg Roach */ 172e5a6b4d4SGreg Roach public static function user(): UserInterface 173c1010edaSGreg Roach { 174b55cbc6bSGreg Roach $user_service = app(UserService::class); 175b55cbc6bSGreg Roach assert($user_service instanceof UserService); 176b55cbc6bSGreg Roach 177b55cbc6bSGreg Roach return $user_service->find(self::id()) ?? new GuestUser(); 178a25f0a04SGreg Roach } 179a25f0a04SGreg Roach 180a25f0a04SGreg Roach /** 181a25f0a04SGreg Roach * Login directly as an explicit user - for masquerading. 182a25f0a04SGreg Roach * 183e5a6b4d4SGreg Roach * @param UserInterface $user 184cb923727SGreg Roach * 185cb923727SGreg Roach * @return void 186a25f0a04SGreg Roach */ 187e364afe4SGreg Roach public static function login(UserInterface $user): void 188c1010edaSGreg Roach { 18981b729d3SGreg Roach Session::regenerate(); 190895230eeSGreg Roach Session::put('wt_user', $user->id()); 191a25f0a04SGreg Roach } 192a25f0a04SGreg Roach 193a25f0a04SGreg Roach /** 194a25f0a04SGreg Roach * End the session for the current user. 195cb923727SGreg Roach * 196cb923727SGreg Roach * @return void 197a25f0a04SGreg Roach */ 198e364afe4SGreg Roach public static function logout(): void 199c1010edaSGreg Roach { 20031bc7874SGreg Roach Session::regenerate(true); 201a25f0a04SGreg Roach } 202e539f5c6SGreg Roach 203e539f5c6SGreg Roach /** 204*ac19d600SGreg Roach * @template T of ModuleInterface 205*ac19d600SGreg Roach * 2069867b2f0SGreg Roach * @param ModuleInterface $module 207*ac19d600SGreg Roach * @param class-string<T> $interface 2089867b2f0SGreg Roach * @param Tree $tree 209e5a6b4d4SGreg Roach * @param UserInterface $user 2109867b2f0SGreg Roach * 2119867b2f0SGreg Roach * @return void 2129867b2f0SGreg Roach */ 213ef483801SGreg Roach public static function checkComponentAccess(ModuleInterface $module, string $interface, Tree $tree, UserInterface $user): void 2149867b2f0SGreg Roach { 215ef483801SGreg Roach if ($module->accessLevel($tree, $interface) < self::accessLevel($tree, $user)) { 216d501c45dSGreg Roach throw new HttpAccessDeniedException(); 2179867b2f0SGreg Roach } 2189867b2f0SGreg Roach } 2199867b2f0SGreg Roach 2209867b2f0SGreg Roach /** 221e539f5c6SGreg Roach * @param Family|null $family 222ffc0a61fSGreg Roach * @param bool $edit 223e539f5c6SGreg Roach * 224ddeb3354SGreg Roach * @return Family 22581b729d3SGreg Roach * @throws HttpNotFoundException 22681b729d3SGreg Roach * @throws HttpAccessDeniedException 227e539f5c6SGreg Roach */ 2283c3fd0a5SGreg Roach public static function checkFamilyAccess(?Family $family, bool $edit = false): Family 229e539f5c6SGreg Roach { 23081b729d3SGreg Roach $message = I18N::translate('This family does not exist or you do not have permission to view it.'); 23181b729d3SGreg Roach 232e539f5c6SGreg Roach if ($family === null) { 23381b729d3SGreg Roach throw new HttpNotFoundException($message); 234e539f5c6SGreg Roach } 235e539f5c6SGreg Roach 2363c3fd0a5SGreg Roach if ($edit && $family->canEdit()) { 2378091bfd1SGreg Roach $family->lock(); 2388091bfd1SGreg Roach 239ddeb3354SGreg Roach return $family; 240e539f5c6SGreg Roach } 241e539f5c6SGreg Roach 2423c3fd0a5SGreg Roach if ($family->canShow()) { 2433c3fd0a5SGreg Roach return $family; 2443c3fd0a5SGreg Roach } 2453c3fd0a5SGreg Roach 24681b729d3SGreg Roach throw new HttpAccessDeniedException($message); 2473c3fd0a5SGreg Roach } 2483c3fd0a5SGreg Roach 249e539f5c6SGreg Roach /** 2501635452cSGreg Roach * @param Header|null $header 2511635452cSGreg Roach * @param bool $edit 2521635452cSGreg Roach * 2531635452cSGreg Roach * @return Header 25481b729d3SGreg Roach * @throws HttpNotFoundException 25581b729d3SGreg Roach * @throws HttpAccessDeniedException 2561635452cSGreg Roach */ 2571635452cSGreg Roach public static function checkHeaderAccess(?Header $header, bool $edit = false): Header 2581635452cSGreg Roach { 25981b729d3SGreg Roach $message = I18N::translate('This record does not exist or you do not have permission to view it.'); 26081b729d3SGreg Roach 2611635452cSGreg Roach if ($header === null) { 26281b729d3SGreg Roach throw new HttpNotFoundException($message); 2631635452cSGreg Roach } 2641635452cSGreg Roach 2651635452cSGreg Roach if ($edit && $header->canEdit()) { 2668091bfd1SGreg Roach $header->lock(); 2678091bfd1SGreg Roach 2681635452cSGreg Roach return $header; 2691635452cSGreg Roach } 2701635452cSGreg Roach 2711635452cSGreg Roach if ($header->canShow()) { 2721635452cSGreg Roach return $header; 2731635452cSGreg Roach } 2741635452cSGreg Roach 27581b729d3SGreg Roach throw new HttpAccessDeniedException($message); 2761635452cSGreg Roach } 2771635452cSGreg Roach 2781635452cSGreg Roach /** 279e539f5c6SGreg Roach * @param Individual|null $individual 280ffc0a61fSGreg Roach * @param bool $edit 2813c3fd0a5SGreg Roach * @param bool $chart For some charts, we can show private records 282e539f5c6SGreg Roach * 283ddeb3354SGreg Roach * @return Individual 28481b729d3SGreg Roach * @throws HttpNotFoundException 28581b729d3SGreg Roach * @throws HttpAccessDeniedException 286e539f5c6SGreg Roach */ 28781b729d3SGreg Roach public static function checkIndividualAccess(?Individual $individual, bool $edit = false, bool $chart = false): Individual 288e539f5c6SGreg Roach { 28981b729d3SGreg Roach $message = I18N::translate('This individual does not exist or you do not have permission to view it.'); 29081b729d3SGreg Roach 291e539f5c6SGreg Roach if ($individual === null) { 29281b729d3SGreg Roach throw new HttpNotFoundException($message); 293e539f5c6SGreg Roach } 294e539f5c6SGreg Roach 2953c3fd0a5SGreg Roach if ($edit && $individual->canEdit()) { 2968091bfd1SGreg Roach $individual->lock(); 2978091bfd1SGreg Roach 298ddeb3354SGreg Roach return $individual; 299e539f5c6SGreg Roach } 300e539f5c6SGreg Roach 3013c3fd0a5SGreg Roach if ($chart && $individual->tree()->getPreference('SHOW_PRIVATE_RELATIONSHIPS') === '1') { 3023c3fd0a5SGreg Roach return $individual; 3033c3fd0a5SGreg Roach } 3043c3fd0a5SGreg Roach 3053c3fd0a5SGreg Roach if ($individual->canShow()) { 3063c3fd0a5SGreg Roach return $individual; 3073c3fd0a5SGreg Roach } 3083c3fd0a5SGreg Roach 30981b729d3SGreg Roach throw new HttpAccessDeniedException($message); 3103c3fd0a5SGreg Roach } 3113c3fd0a5SGreg Roach 312e539f5c6SGreg Roach /** 313e8ded2caSGreg Roach * @param Location|null $location 314e8ded2caSGreg Roach * @param bool $edit 315e8ded2caSGreg Roach * 316e8ded2caSGreg Roach * @return Location 31781b729d3SGreg Roach * @throws HttpNotFoundException 31881b729d3SGreg Roach * @throws HttpAccessDeniedException 319e8ded2caSGreg Roach */ 320e8ded2caSGreg Roach public static function checkLocationAccess(?Location $location, bool $edit = false): Location 321e8ded2caSGreg Roach { 32281b729d3SGreg Roach $message = I18N::translate('This record does not exist or you do not have permission to view it.'); 32381b729d3SGreg Roach 324e8ded2caSGreg Roach if ($location === null) { 32581b729d3SGreg Roach throw new HttpNotFoundException($message); 326e8ded2caSGreg Roach } 327e8ded2caSGreg Roach 328e8ded2caSGreg Roach if ($edit && $location->canEdit()) { 329e8ded2caSGreg Roach $location->lock(); 330e8ded2caSGreg Roach 331e8ded2caSGreg Roach return $location; 332e8ded2caSGreg Roach } 333e8ded2caSGreg Roach 334e8ded2caSGreg Roach if ($location->canShow()) { 335e8ded2caSGreg Roach return $location; 336e8ded2caSGreg Roach } 337e8ded2caSGreg Roach 33881b729d3SGreg Roach throw new HttpAccessDeniedException($message); 339e8ded2caSGreg Roach } 340e8ded2caSGreg Roach 341e8ded2caSGreg Roach /** 342e539f5c6SGreg Roach * @param Media|null $media 343ffc0a61fSGreg Roach * @param bool $edit 344e539f5c6SGreg Roach * 345ddeb3354SGreg Roach * @return Media 34681b729d3SGreg Roach * @throws HttpNotFoundException 34781b729d3SGreg Roach * @throws HttpAccessDeniedException 348e539f5c6SGreg Roach */ 3493c3fd0a5SGreg Roach public static function checkMediaAccess(?Media $media, bool $edit = false): Media 350e539f5c6SGreg Roach { 35181b729d3SGreg Roach $message = I18N::translate('This media object does not exist or you do not have permission to view it.'); 35281b729d3SGreg Roach 353e539f5c6SGreg Roach if ($media === null) { 35481b729d3SGreg Roach throw new HttpNotFoundException($message); 355e539f5c6SGreg Roach } 356e539f5c6SGreg Roach 3573c3fd0a5SGreg Roach if ($edit && $media->canEdit()) { 3588091bfd1SGreg Roach $media->lock(); 3598091bfd1SGreg Roach 360ddeb3354SGreg Roach return $media; 361e539f5c6SGreg Roach } 362e539f5c6SGreg Roach 3633c3fd0a5SGreg Roach if ($media->canShow()) { 3643c3fd0a5SGreg Roach return $media; 3653c3fd0a5SGreg Roach } 3663c3fd0a5SGreg Roach 36781b729d3SGreg Roach throw new HttpAccessDeniedException($message); 3683c3fd0a5SGreg Roach } 3693c3fd0a5SGreg Roach 370e539f5c6SGreg Roach /** 371e539f5c6SGreg Roach * @param Note|null $note 372ffc0a61fSGreg Roach * @param bool $edit 373e539f5c6SGreg Roach * 374ddeb3354SGreg Roach * @return Note 37581b729d3SGreg Roach * @throws HttpNotFoundException 37681b729d3SGreg Roach * @throws HttpAccessDeniedException 377e539f5c6SGreg Roach */ 3783c3fd0a5SGreg Roach public static function checkNoteAccess(?Note $note, bool $edit = false): Note 379e539f5c6SGreg Roach { 38081b729d3SGreg Roach $message = I18N::translate('This note does not exist or you do not have permission to view it.'); 38181b729d3SGreg Roach 382e539f5c6SGreg Roach if ($note === null) { 38381b729d3SGreg Roach throw new HttpNotFoundException($message); 384e539f5c6SGreg Roach } 385e539f5c6SGreg Roach 3863c3fd0a5SGreg Roach if ($edit && $note->canEdit()) { 3878091bfd1SGreg Roach $note->lock(); 3888091bfd1SGreg Roach 389ddeb3354SGreg Roach return $note; 390e539f5c6SGreg Roach } 391e539f5c6SGreg Roach 3923c3fd0a5SGreg Roach if ($note->canShow()) { 3933c3fd0a5SGreg Roach return $note; 3943c3fd0a5SGreg Roach } 3953c3fd0a5SGreg Roach 39681b729d3SGreg Roach throw new HttpAccessDeniedException($message); 3973c3fd0a5SGreg Roach } 3983c3fd0a5SGreg Roach 399e539f5c6SGreg Roach /** 400701f5d18SGreg Roach * @param SharedNote|null $shared_note 401701f5d18SGreg Roach * @param bool $edit 402701f5d18SGreg Roach * 403701f5d18SGreg Roach * @return SharedNote 404701f5d18SGreg Roach * @throws HttpNotFoundException 405701f5d18SGreg Roach * @throws HttpAccessDeniedException 406701f5d18SGreg Roach */ 407701f5d18SGreg Roach public static function checkSharedNoteAccess(?SharedNote $shared_note, bool $edit = false): SharedNote 408701f5d18SGreg Roach { 409701f5d18SGreg Roach $message = I18N::translate('This note does not exist or you do not have permission to view it.'); 410701f5d18SGreg Roach 411701f5d18SGreg Roach if ($shared_note === null) { 412701f5d18SGreg Roach throw new HttpNotFoundException($message); 413701f5d18SGreg Roach } 414701f5d18SGreg Roach 415701f5d18SGreg Roach if ($edit && $shared_note->canEdit()) { 416701f5d18SGreg Roach $shared_note->lock(); 417701f5d18SGreg Roach 418701f5d18SGreg Roach return $shared_note; 419701f5d18SGreg Roach } 420701f5d18SGreg Roach 421701f5d18SGreg Roach if ($shared_note->canShow()) { 422701f5d18SGreg Roach return $shared_note; 423701f5d18SGreg Roach } 424701f5d18SGreg Roach 425701f5d18SGreg Roach throw new HttpAccessDeniedException($message); 426701f5d18SGreg Roach } 427701f5d18SGreg Roach 428701f5d18SGreg Roach /** 429e539f5c6SGreg Roach * @param GedcomRecord|null $record 430ffc0a61fSGreg Roach * @param bool $edit 431e539f5c6SGreg Roach * 432ddeb3354SGreg Roach * @return GedcomRecord 43381b729d3SGreg Roach * @throws HttpNotFoundException 43481b729d3SGreg Roach * @throws HttpAccessDeniedException 435e539f5c6SGreg Roach */ 4363c3fd0a5SGreg Roach public static function checkRecordAccess(?GedcomRecord $record, bool $edit = false): GedcomRecord 437e539f5c6SGreg Roach { 43881b729d3SGreg Roach $message = I18N::translate('This record does not exist or you do not have permission to view it.'); 43981b729d3SGreg Roach 440e539f5c6SGreg Roach if ($record === null) { 44181b729d3SGreg Roach throw new HttpNotFoundException($message); 442e539f5c6SGreg Roach } 443e539f5c6SGreg Roach 4443c3fd0a5SGreg Roach if ($edit && $record->canEdit()) { 4458091bfd1SGreg Roach $record->lock(); 4468091bfd1SGreg Roach 447ddeb3354SGreg Roach return $record; 448e539f5c6SGreg Roach } 449e539f5c6SGreg Roach 4503c3fd0a5SGreg Roach if ($record->canShow()) { 4513c3fd0a5SGreg Roach return $record; 4523c3fd0a5SGreg Roach } 4533c3fd0a5SGreg Roach 45481b729d3SGreg Roach throw new HttpAccessDeniedException($message); 4553c3fd0a5SGreg Roach } 4563c3fd0a5SGreg Roach 457e539f5c6SGreg Roach /** 458e539f5c6SGreg Roach * @param Repository|null $repository 459ffc0a61fSGreg Roach * @param bool $edit 460e539f5c6SGreg Roach * 461ddeb3354SGreg Roach * @return Repository 46281b729d3SGreg Roach * @throws HttpNotFoundException 46381b729d3SGreg Roach * @throws HttpAccessDeniedException 464e539f5c6SGreg Roach */ 4653c3fd0a5SGreg Roach public static function checkRepositoryAccess(?Repository $repository, bool $edit = false): Repository 466e539f5c6SGreg Roach { 46781b729d3SGreg Roach $message = I18N::translate('This repository does not exist or you do not have permission to view it.'); 46881b729d3SGreg Roach 469e539f5c6SGreg Roach if ($repository === null) { 47081b729d3SGreg Roach throw new HttpNotFoundException($message); 471e539f5c6SGreg Roach } 472e539f5c6SGreg Roach 4733c3fd0a5SGreg Roach if ($edit && $repository->canEdit()) { 4748091bfd1SGreg Roach $repository->lock(); 4758091bfd1SGreg Roach 476ddeb3354SGreg Roach return $repository; 477e539f5c6SGreg Roach } 478e539f5c6SGreg Roach 4793c3fd0a5SGreg Roach if ($repository->canShow()) { 4803c3fd0a5SGreg Roach return $repository; 4813c3fd0a5SGreg Roach } 4823c3fd0a5SGreg Roach 48381b729d3SGreg Roach throw new HttpAccessDeniedException($message); 4843c3fd0a5SGreg Roach } 4853c3fd0a5SGreg Roach 486e539f5c6SGreg Roach /** 487e539f5c6SGreg Roach * @param Source|null $source 488ffc0a61fSGreg Roach * @param bool $edit 489e539f5c6SGreg Roach * 490ddeb3354SGreg Roach * @return Source 49181b729d3SGreg Roach * @throws HttpNotFoundException 49281b729d3SGreg Roach * @throws HttpAccessDeniedException 493e539f5c6SGreg Roach */ 4943c3fd0a5SGreg Roach public static function checkSourceAccess(?Source $source, bool $edit = false): Source 495e539f5c6SGreg Roach { 49681b729d3SGreg Roach $message = I18N::translate('This source does not exist or you do not have permission to view it.'); 49781b729d3SGreg Roach 498e539f5c6SGreg Roach if ($source === null) { 49981b729d3SGreg Roach throw new HttpNotFoundException($message); 500e539f5c6SGreg Roach } 501e539f5c6SGreg Roach 5023c3fd0a5SGreg Roach if ($edit && $source->canEdit()) { 5038091bfd1SGreg Roach $source->lock(); 5048091bfd1SGreg Roach 505ddeb3354SGreg Roach return $source; 506e539f5c6SGreg Roach } 507ffc0a61fSGreg Roach 5083c3fd0a5SGreg Roach if ($source->canShow()) { 5093c3fd0a5SGreg Roach return $source; 5103c3fd0a5SGreg Roach } 5113c3fd0a5SGreg Roach 51281b729d3SGreg Roach throw new HttpAccessDeniedException($message); 5133c3fd0a5SGreg Roach } 5143c3fd0a5SGreg Roach 515b1089081SGreg Roach /** 516ffc0a61fSGreg Roach * @param Submitter|null $submitter 517ffc0a61fSGreg Roach * @param bool $edit 518ffc0a61fSGreg Roach * 519ffc0a61fSGreg Roach * @return Submitter 520b1089081SGreg Roach * @throws HttpNotFoundException 521b1089081SGreg Roach * @throws HttpAccessDeniedException 522ffc0a61fSGreg Roach */ 5233c3fd0a5SGreg Roach public static function checkSubmitterAccess(?Submitter $submitter, bool $edit = false): Submitter 524ffc0a61fSGreg Roach { 52581b729d3SGreg Roach $message = I18N::translate('This record does not exist or you do not have permission to view it.'); 52681b729d3SGreg Roach 527ffc0a61fSGreg Roach if ($submitter === null) { 52881b729d3SGreg Roach throw new HttpNotFoundException($message); 529ffc0a61fSGreg Roach } 530ffc0a61fSGreg Roach 5313c3fd0a5SGreg Roach if ($edit && $submitter->canEdit()) { 5328091bfd1SGreg Roach $submitter->lock(); 5338091bfd1SGreg Roach 534ffc0a61fSGreg Roach return $submitter; 535ffc0a61fSGreg Roach } 5363c3fd0a5SGreg Roach 5373c3fd0a5SGreg Roach if ($submitter->canShow()) { 5383c3fd0a5SGreg Roach return $submitter; 5393c3fd0a5SGreg Roach } 5403c3fd0a5SGreg Roach 54181b729d3SGreg Roach throw new HttpAccessDeniedException($message); 5423c3fd0a5SGreg Roach } 5431635452cSGreg Roach 544b1089081SGreg Roach /** 5451635452cSGreg Roach * @param Submission|null $submission 5461635452cSGreg Roach * @param bool $edit 5471635452cSGreg Roach * 5481635452cSGreg Roach * @return Submission 54981b729d3SGreg Roach * @throws HttpNotFoundException 55081b729d3SGreg Roach * @throws HttpAccessDeniedException 5511635452cSGreg Roach */ 5521635452cSGreg Roach public static function checkSubmissionAccess(?Submission $submission, bool $edit = false): Submission 5531635452cSGreg Roach { 55481b729d3SGreg Roach $message = I18N::translate('This record does not exist or you do not have permission to view it.'); 55581b729d3SGreg Roach 5561635452cSGreg Roach if ($submission === null) { 55781b729d3SGreg Roach throw new HttpNotFoundException($message); 5581635452cSGreg Roach } 5591635452cSGreg Roach 5601635452cSGreg Roach if ($edit && $submission->canEdit()) { 5618091bfd1SGreg Roach $submission->lock(); 5628091bfd1SGreg Roach 5631635452cSGreg Roach return $submission; 5641635452cSGreg Roach } 5651635452cSGreg Roach 5661635452cSGreg Roach if ($submission->canShow()) { 5671635452cSGreg Roach return $submission; 5681635452cSGreg Roach } 5691635452cSGreg Roach 57081b729d3SGreg Roach throw new HttpAccessDeniedException($message); 5711635452cSGreg Roach } 572870365fbSGreg Roach 573870365fbSGreg Roach /** 5745416d6ddSGreg Roach * @param Tree $tree 5755416d6ddSGreg Roach * @param UserInterface $user 5765416d6ddSGreg Roach * 5775416d6ddSGreg Roach * @return bool 5785416d6ddSGreg Roach */ 5795416d6ddSGreg Roach public static function canUploadMedia(Tree $tree, UserInterface $user): bool 5805416d6ddSGreg Roach { 5815416d6ddSGreg Roach return 582be410956SGreg Roach self::isEditor($tree, $user) && 583be410956SGreg Roach self::accessLevel($tree, $user) <= (int) $tree->getPreference('MEDIA_UPLOAD'); 5845416d6ddSGreg Roach } 5855416d6ddSGreg Roach 5865416d6ddSGreg Roach 5875416d6ddSGreg Roach /** 588870365fbSGreg Roach * @return array<int,string> 589870365fbSGreg Roach */ 590870365fbSGreg Roach public static function accessLevelNames(): array 591870365fbSGreg Roach { 592870365fbSGreg Roach return [ 593d823340dSGreg Roach self::PRIV_PRIVATE => I18N::translate('Show to visitors'), 594d823340dSGreg Roach self::PRIV_USER => I18N::translate('Show to members'), 595d823340dSGreg Roach self::PRIV_NONE => I18N::translate('Show to managers'), 596d823340dSGreg Roach self::PRIV_HIDE => I18N::translate('Hide from everyone'), 597870365fbSGreg Roach ]; 598870365fbSGreg Roach } 599138139c2SGreg Roach 600138139c2SGreg Roach /** 601138139c2SGreg Roach * @return array<string,string> 602138139c2SGreg Roach */ 603138139c2SGreg Roach public static function privacyRuleNames(): array 604138139c2SGreg Roach { 605138139c2SGreg Roach return [ 606138139c2SGreg Roach 'none' => I18N::translate('Show to visitors'), 607138139c2SGreg Roach 'privacy' => I18N::translate('Show to members'), 608138139c2SGreg Roach 'confidential' => I18N::translate('Show to managers'), 609138139c2SGreg Roach 'hidden' => I18N::translate('Hide from everyone'), 610138139c2SGreg Roach ]; 611138139c2SGreg Roach } 612a25f0a04SGreg Roach} 613