1a25f0a04SGreg Roach<?php 23976b470SGreg Roach 3a25f0a04SGreg Roach/** 4a25f0a04SGreg Roach * webtrees: online genealogy 51fe542e9SGreg Roach * Copyright (C) 2021 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 28d8809d62SGreg Roachuse function is_int; 29d8809d62SGreg Roach 30a25f0a04SGreg Roach/** 3176692c8bSGreg Roach * Authentication. 32a25f0a04SGreg Roach */ 33c1010edaSGreg Roachclass Auth 34c1010edaSGreg Roach{ 354b9ff166SGreg Roach // Privacy constants 3616d6367aSGreg Roach public const PRIV_PRIVATE = 2; // Allows visitors to view the item 3716d6367aSGreg Roach public const PRIV_USER = 1; // Allows members to access the item 3816d6367aSGreg Roach public const PRIV_NONE = 0; // Allows managers to access the item 3916d6367aSGreg Roach public const PRIV_HIDE = -1; // Hide the item to all users 404b9ff166SGreg Roach 41a25f0a04SGreg Roach /** 42a25f0a04SGreg Roach * Are we currently logged in? 43a25f0a04SGreg Roach * 44cbc1590aSGreg Roach * @return bool 45a25f0a04SGreg Roach */ 468f53f488SRico Sonntag public static function check(): bool 47c1010edaSGreg Roach { 484b9ff166SGreg Roach return self::id() !== null; 49a25f0a04SGreg Roach } 50a25f0a04SGreg Roach 51a25f0a04SGreg Roach /** 52a25f0a04SGreg Roach * Is the specified/current user an administrator? 53a25f0a04SGreg Roach * 54e5a6b4d4SGreg Roach * @param UserInterface|null $user 55a25f0a04SGreg Roach * 56cbc1590aSGreg Roach * @return bool 57a25f0a04SGreg Roach */ 58e5a6b4d4SGreg Roach public static function isAdmin(UserInterface $user = null): bool 59c1010edaSGreg Roach { 60cb923727SGreg Roach $user = $user ?? self::user(); 61a25f0a04SGreg Roach 621fe542e9SGreg Roach return $user->getPreference(UserInterface::PREF_IS_ADMINISTRATOR) === '1'; 63a25f0a04SGreg Roach } 64a25f0a04SGreg Roach 65a25f0a04SGreg Roach /** 664b9ff166SGreg Roach * Is the specified/current user a manager of a tree? 67a25f0a04SGreg Roach * 6884caa210SGreg Roach * @param Tree $tree 69e5a6b4d4SGreg Roach * @param UserInterface|null $user 70a25f0a04SGreg Roach * 71cbc1590aSGreg Roach * @return bool 72a25f0a04SGreg Roach */ 73e5a6b4d4SGreg Roach public static function isManager(Tree $tree, UserInterface $user = null): bool 74c1010edaSGreg Roach { 75cb923727SGreg Roach $user = $user ?? self::user(); 76a25f0a04SGreg Roach 771fe542e9SGreg Roach return self::isAdmin($user) || $tree->getUserPreference($user, UserInterface::PREF_TREE_ROLE) === UserInterface::ROLE_MANAGER; 78a25f0a04SGreg Roach } 79a25f0a04SGreg Roach 80a25f0a04SGreg Roach /** 814b9ff166SGreg Roach * Is the specified/current user a moderator of a tree? 82a25f0a04SGreg Roach * 8384caa210SGreg Roach * @param Tree $tree 84e5a6b4d4SGreg Roach * @param UserInterface|null $user 85a25f0a04SGreg Roach * 86cbc1590aSGreg Roach * @return bool 87a25f0a04SGreg Roach */ 88e5a6b4d4SGreg Roach public static function isModerator(Tree $tree, UserInterface $user = null): bool 89c1010edaSGreg Roach { 90cb923727SGreg Roach $user = $user ?? self::user(); 91a25f0a04SGreg Roach 921fe542e9SGreg Roach return 931fe542e9SGreg Roach self::isManager($tree, $user) || 941fe542e9SGreg Roach $tree->getUserPreference($user, UserInterface::PREF_TREE_ROLE) === UserInterface::ROLE_MODERATOR; 95a25f0a04SGreg Roach } 96a25f0a04SGreg Roach 97a25f0a04SGreg Roach /** 984b9ff166SGreg Roach * Is the specified/current user an editor of a tree? 99a25f0a04SGreg Roach * 10084caa210SGreg Roach * @param Tree $tree 101e5a6b4d4SGreg Roach * @param UserInterface|null $user 102a25f0a04SGreg Roach * 103cbc1590aSGreg Roach * @return bool 104a25f0a04SGreg Roach */ 105e5a6b4d4SGreg Roach public static function isEditor(Tree $tree, UserInterface $user = null): bool 106c1010edaSGreg Roach { 107cb923727SGreg Roach $user = $user ?? self::user(); 108a25f0a04SGreg Roach 1091fe542e9SGreg Roach return 1101fe542e9SGreg Roach self::isModerator($tree, $user) || 1111fe542e9SGreg Roach $tree->getUserPreference($user, UserInterface::PREF_TREE_ROLE) === UserInterface::ROLE_EDITOR; 112a25f0a04SGreg Roach } 113a25f0a04SGreg Roach 114a25f0a04SGreg Roach /** 1154b9ff166SGreg Roach * Is the specified/current user a member of a tree? 116a25f0a04SGreg Roach * 11784caa210SGreg Roach * @param Tree $tree 118e5a6b4d4SGreg Roach * @param UserInterface|null $user 119a25f0a04SGreg Roach * 120cbc1590aSGreg Roach * @return bool 121a25f0a04SGreg Roach */ 122e5a6b4d4SGreg Roach public static function isMember(Tree $tree, UserInterface $user = null): bool 123c1010edaSGreg Roach { 124cb923727SGreg Roach $user = $user ?? self::user(); 125a25f0a04SGreg Roach 1261fe542e9SGreg Roach return 1271fe542e9SGreg Roach self::isEditor($tree, $user) || 1281fe542e9SGreg Roach $tree->getUserPreference($user, UserInterface::PREF_TREE_ROLE) === UserInterface::ROLE_MEMBER; 129a25f0a04SGreg Roach } 130a25f0a04SGreg Roach 131a25f0a04SGreg Roach /** 1324b9ff166SGreg Roach * What is the specified/current user's access level within a tree? 1334b9ff166SGreg Roach * 1344b9ff166SGreg Roach * @param Tree $tree 135e5a6b4d4SGreg Roach * @param UserInterface|null $user 1364b9ff166SGreg Roach * 137cbc1590aSGreg Roach * @return int 1384b9ff166SGreg Roach */ 139e364afe4SGreg Roach public static function accessLevel(Tree $tree, UserInterface $user = null): int 140c1010edaSGreg Roach { 141cb923727SGreg Roach $user = $user ?? self::user(); 1424b9ff166SGreg Roach 1434b9ff166SGreg Roach if (self::isManager($tree, $user)) { 1444b9ff166SGreg Roach return self::PRIV_NONE; 1454b9ff166SGreg Roach } 146b2ce94c6SRico Sonntag 147b2ce94c6SRico Sonntag if (self::isMember($tree, $user)) { 148b2ce94c6SRico Sonntag return self::PRIV_USER; 149b2ce94c6SRico Sonntag } 150b2ce94c6SRico Sonntag 151b2ce94c6SRico Sonntag return self::PRIV_PRIVATE; 1524b9ff166SGreg Roach } 1534b9ff166SGreg Roach 1544b9ff166SGreg Roach /** 155a25f0a04SGreg Roach * The ID of the authenticated user, from the current session. 156a25f0a04SGreg Roach * 157c3ffc4cbSGreg Roach * @return int|null 158a25f0a04SGreg Roach */ 159e364afe4SGreg Roach public static function id(): ?int 160c1010edaSGreg Roach { 161d8809d62SGreg Roach $wt_user = Session::get('wt_user'); 162d8809d62SGreg Roach 163d8809d62SGreg Roach return is_int($wt_user) ? $wt_user : null; 164a25f0a04SGreg Roach } 165a25f0a04SGreg Roach 166a25f0a04SGreg Roach /** 167a25f0a04SGreg Roach * The authenticated user, from the current session. 168a25f0a04SGreg Roach * 169e5a6b4d4SGreg Roach * @return UserInterface 170a25f0a04SGreg Roach */ 171e5a6b4d4SGreg Roach public static function user(): UserInterface 172c1010edaSGreg Roach { 17315674e31SGreg Roach return app(UserService::class)->find(self::id()) ?? new GuestUser(); 174a25f0a04SGreg Roach } 175a25f0a04SGreg Roach 176a25f0a04SGreg Roach /** 177a25f0a04SGreg Roach * Login directly as an explicit user - for masquerading. 178a25f0a04SGreg Roach * 179e5a6b4d4SGreg Roach * @param UserInterface $user 180cb923727SGreg Roach * 181cb923727SGreg Roach * @return void 182a25f0a04SGreg Roach */ 183e364afe4SGreg Roach public static function login(UserInterface $user): void 184c1010edaSGreg Roach { 18581b729d3SGreg Roach Session::regenerate(); 186895230eeSGreg Roach Session::put('wt_user', $user->id()); 187a25f0a04SGreg Roach } 188a25f0a04SGreg Roach 189a25f0a04SGreg Roach /** 190a25f0a04SGreg Roach * End the session for the current user. 191cb923727SGreg Roach * 192cb923727SGreg Roach * @return void 193a25f0a04SGreg Roach */ 194e364afe4SGreg Roach public static function logout(): void 195c1010edaSGreg Roach { 19631bc7874SGreg Roach Session::regenerate(true); 197a25f0a04SGreg Roach } 198e539f5c6SGreg Roach 199e539f5c6SGreg Roach /** 2009867b2f0SGreg Roach * @param ModuleInterface $module 201ef483801SGreg Roach * @param string $interface 2029867b2f0SGreg Roach * @param Tree $tree 203e5a6b4d4SGreg Roach * @param UserInterface $user 2049867b2f0SGreg Roach * 2059867b2f0SGreg Roach * @return void 2069867b2f0SGreg Roach */ 207ef483801SGreg Roach public static function checkComponentAccess(ModuleInterface $module, string $interface, Tree $tree, UserInterface $user): void 2089867b2f0SGreg Roach { 209ef483801SGreg Roach if ($module->accessLevel($tree, $interface) < self::accessLevel($tree, $user)) { 210d501c45dSGreg Roach throw new HttpAccessDeniedException(); 2119867b2f0SGreg Roach } 2129867b2f0SGreg Roach } 2139867b2f0SGreg Roach 2149867b2f0SGreg Roach /** 215e539f5c6SGreg Roach * @param Family|null $family 216ffc0a61fSGreg Roach * @param bool $edit 217e539f5c6SGreg Roach * 218ddeb3354SGreg Roach * @return Family 21981b729d3SGreg Roach * @throws HttpNotFoundException 22081b729d3SGreg Roach * @throws HttpAccessDeniedException 221e539f5c6SGreg Roach */ 2223c3fd0a5SGreg Roach public static function checkFamilyAccess(?Family $family, bool $edit = false): Family 223e539f5c6SGreg Roach { 22481b729d3SGreg Roach $message = I18N::translate('This family does not exist or you do not have permission to view it.'); 22581b729d3SGreg Roach 226e539f5c6SGreg Roach if ($family === null) { 22781b729d3SGreg Roach throw new HttpNotFoundException($message); 228e539f5c6SGreg Roach } 229e539f5c6SGreg Roach 2303c3fd0a5SGreg Roach if ($edit && $family->canEdit()) { 2318091bfd1SGreg Roach $family->lock(); 2328091bfd1SGreg Roach 233ddeb3354SGreg Roach return $family; 234e539f5c6SGreg Roach } 235e539f5c6SGreg Roach 2363c3fd0a5SGreg Roach if ($family->canShow()) { 2373c3fd0a5SGreg Roach return $family; 2383c3fd0a5SGreg Roach } 2393c3fd0a5SGreg Roach 24081b729d3SGreg Roach throw new HttpAccessDeniedException($message); 2413c3fd0a5SGreg Roach } 2423c3fd0a5SGreg Roach 243e539f5c6SGreg Roach /** 2441635452cSGreg Roach * @param Header|null $header 2451635452cSGreg Roach * @param bool $edit 2461635452cSGreg Roach * 2471635452cSGreg Roach * @return Header 24881b729d3SGreg Roach * @throws HttpNotFoundException 24981b729d3SGreg Roach * @throws HttpAccessDeniedException 2501635452cSGreg Roach */ 2511635452cSGreg Roach public static function checkHeaderAccess(?Header $header, bool $edit = false): Header 2521635452cSGreg Roach { 25381b729d3SGreg Roach $message = I18N::translate('This record does not exist or you do not have permission to view it.'); 25481b729d3SGreg Roach 2551635452cSGreg Roach if ($header === null) { 25681b729d3SGreg Roach throw new HttpNotFoundException($message); 2571635452cSGreg Roach } 2581635452cSGreg Roach 2591635452cSGreg Roach if ($edit && $header->canEdit()) { 2608091bfd1SGreg Roach $header->lock(); 2618091bfd1SGreg Roach 2621635452cSGreg Roach return $header; 2631635452cSGreg Roach } 2641635452cSGreg Roach 2651635452cSGreg Roach if ($header->canShow()) { 2661635452cSGreg Roach return $header; 2671635452cSGreg Roach } 2681635452cSGreg Roach 26981b729d3SGreg Roach throw new HttpAccessDeniedException($message); 2701635452cSGreg Roach } 2711635452cSGreg Roach 2721635452cSGreg Roach /** 273e539f5c6SGreg Roach * @param Individual|null $individual 274ffc0a61fSGreg Roach * @param bool $edit 2753c3fd0a5SGreg Roach * @param bool $chart For some charts, we can show private records 276e539f5c6SGreg Roach * 277ddeb3354SGreg Roach * @return Individual 27881b729d3SGreg Roach * @throws HttpNotFoundException 27981b729d3SGreg Roach * @throws HttpAccessDeniedException 280e539f5c6SGreg Roach */ 28181b729d3SGreg Roach public static function checkIndividualAccess(?Individual $individual, bool $edit = false, bool $chart = false): Individual 282e539f5c6SGreg Roach { 28381b729d3SGreg Roach $message = I18N::translate('This individual does not exist or you do not have permission to view it.'); 28481b729d3SGreg Roach 285e539f5c6SGreg Roach if ($individual === null) { 28681b729d3SGreg Roach throw new HttpNotFoundException($message); 287e539f5c6SGreg Roach } 288e539f5c6SGreg Roach 2893c3fd0a5SGreg Roach if ($edit && $individual->canEdit()) { 2908091bfd1SGreg Roach $individual->lock(); 2918091bfd1SGreg Roach 292ddeb3354SGreg Roach return $individual; 293e539f5c6SGreg Roach } 294e539f5c6SGreg Roach 2953c3fd0a5SGreg Roach if ($chart && $individual->tree()->getPreference('SHOW_PRIVATE_RELATIONSHIPS') === '1') { 2963c3fd0a5SGreg Roach return $individual; 2973c3fd0a5SGreg Roach } 2983c3fd0a5SGreg Roach 2993c3fd0a5SGreg Roach if ($individual->canShow()) { 3003c3fd0a5SGreg Roach return $individual; 3013c3fd0a5SGreg Roach } 3023c3fd0a5SGreg Roach 30381b729d3SGreg Roach throw new HttpAccessDeniedException($message); 3043c3fd0a5SGreg Roach } 3053c3fd0a5SGreg Roach 306e539f5c6SGreg Roach /** 307e8ded2caSGreg Roach * @param Location|null $location 308e8ded2caSGreg Roach * @param bool $edit 309e8ded2caSGreg Roach * 310e8ded2caSGreg Roach * @return Location 31181b729d3SGreg Roach * @throws HttpNotFoundException 31281b729d3SGreg Roach * @throws HttpAccessDeniedException 313e8ded2caSGreg Roach */ 314e8ded2caSGreg Roach public static function checkLocationAccess(?Location $location, bool $edit = false): Location 315e8ded2caSGreg Roach { 31681b729d3SGreg Roach $message = I18N::translate('This record does not exist or you do not have permission to view it.'); 31781b729d3SGreg Roach 318e8ded2caSGreg Roach if ($location === null) { 31981b729d3SGreg Roach throw new HttpNotFoundException($message); 320e8ded2caSGreg Roach } 321e8ded2caSGreg Roach 322e8ded2caSGreg Roach if ($edit && $location->canEdit()) { 323e8ded2caSGreg Roach $location->lock(); 324e8ded2caSGreg Roach 325e8ded2caSGreg Roach return $location; 326e8ded2caSGreg Roach } 327e8ded2caSGreg Roach 328e8ded2caSGreg Roach if ($location->canShow()) { 329e8ded2caSGreg Roach return $location; 330e8ded2caSGreg Roach } 331e8ded2caSGreg Roach 33281b729d3SGreg Roach throw new HttpAccessDeniedException($message); 333e8ded2caSGreg Roach } 334e8ded2caSGreg Roach 335e8ded2caSGreg Roach /** 336e539f5c6SGreg Roach * @param Media|null $media 337ffc0a61fSGreg Roach * @param bool $edit 338e539f5c6SGreg Roach * 339ddeb3354SGreg Roach * @return Media 34081b729d3SGreg Roach * @throws HttpNotFoundException 34181b729d3SGreg Roach * @throws HttpAccessDeniedException 342e539f5c6SGreg Roach */ 3433c3fd0a5SGreg Roach public static function checkMediaAccess(?Media $media, bool $edit = false): Media 344e539f5c6SGreg Roach { 34581b729d3SGreg Roach $message = I18N::translate('This media object does not exist or you do not have permission to view it.'); 34681b729d3SGreg Roach 347e539f5c6SGreg Roach if ($media === null) { 34881b729d3SGreg Roach throw new HttpNotFoundException($message); 349e539f5c6SGreg Roach } 350e539f5c6SGreg Roach 3513c3fd0a5SGreg Roach if ($edit && $media->canEdit()) { 3528091bfd1SGreg Roach $media->lock(); 3538091bfd1SGreg Roach 354ddeb3354SGreg Roach return $media; 355e539f5c6SGreg Roach } 356e539f5c6SGreg Roach 3573c3fd0a5SGreg Roach if ($media->canShow()) { 3583c3fd0a5SGreg Roach return $media; 3593c3fd0a5SGreg Roach } 3603c3fd0a5SGreg Roach 36181b729d3SGreg Roach throw new HttpAccessDeniedException($message); 3623c3fd0a5SGreg Roach } 3633c3fd0a5SGreg Roach 364e539f5c6SGreg Roach /** 365e539f5c6SGreg Roach * @param Note|null $note 366ffc0a61fSGreg Roach * @param bool $edit 367e539f5c6SGreg Roach * 368ddeb3354SGreg Roach * @return Note 36981b729d3SGreg Roach * @throws HttpNotFoundException 37081b729d3SGreg Roach * @throws HttpAccessDeniedException 371e539f5c6SGreg Roach */ 3723c3fd0a5SGreg Roach public static function checkNoteAccess(?Note $note, bool $edit = false): Note 373e539f5c6SGreg Roach { 37481b729d3SGreg Roach $message = I18N::translate('This note does not exist or you do not have permission to view it.'); 37581b729d3SGreg Roach 376e539f5c6SGreg Roach if ($note === null) { 37781b729d3SGreg Roach throw new HttpNotFoundException($message); 378e539f5c6SGreg Roach } 379e539f5c6SGreg Roach 3803c3fd0a5SGreg Roach if ($edit && $note->canEdit()) { 3818091bfd1SGreg Roach $note->lock(); 3828091bfd1SGreg Roach 383ddeb3354SGreg Roach return $note; 384e539f5c6SGreg Roach } 385e539f5c6SGreg Roach 3863c3fd0a5SGreg Roach if ($note->canShow()) { 3873c3fd0a5SGreg Roach return $note; 3883c3fd0a5SGreg Roach } 3893c3fd0a5SGreg Roach 39081b729d3SGreg Roach throw new HttpAccessDeniedException($message); 3913c3fd0a5SGreg Roach } 3923c3fd0a5SGreg Roach 393e539f5c6SGreg Roach /** 394e539f5c6SGreg Roach * @param GedcomRecord|null $record 395ffc0a61fSGreg Roach * @param bool $edit 396e539f5c6SGreg Roach * 397ddeb3354SGreg Roach * @return GedcomRecord 39881b729d3SGreg Roach * @throws HttpNotFoundException 39981b729d3SGreg Roach * @throws HttpAccessDeniedException 400e539f5c6SGreg Roach */ 4013c3fd0a5SGreg Roach public static function checkRecordAccess(?GedcomRecord $record, bool $edit = false): GedcomRecord 402e539f5c6SGreg Roach { 40381b729d3SGreg Roach $message = I18N::translate('This record does not exist or you do not have permission to view it.'); 40481b729d3SGreg Roach 405e539f5c6SGreg Roach if ($record === null) { 40681b729d3SGreg Roach throw new HttpNotFoundException($message); 407e539f5c6SGreg Roach } 408e539f5c6SGreg Roach 4093c3fd0a5SGreg Roach if ($edit && $record->canEdit()) { 4108091bfd1SGreg Roach $record->lock(); 4118091bfd1SGreg Roach 412ddeb3354SGreg Roach return $record; 413e539f5c6SGreg Roach } 414e539f5c6SGreg Roach 4153c3fd0a5SGreg Roach if ($record->canShow()) { 4163c3fd0a5SGreg Roach return $record; 4173c3fd0a5SGreg Roach } 4183c3fd0a5SGreg Roach 41981b729d3SGreg Roach throw new HttpAccessDeniedException($message); 4203c3fd0a5SGreg Roach } 4213c3fd0a5SGreg Roach 422e539f5c6SGreg Roach /** 423e539f5c6SGreg Roach * @param Repository|null $repository 424ffc0a61fSGreg Roach * @param bool $edit 425e539f5c6SGreg Roach * 426ddeb3354SGreg Roach * @return Repository 42781b729d3SGreg Roach * @throws HttpNotFoundException 42881b729d3SGreg Roach * @throws HttpAccessDeniedException 429e539f5c6SGreg Roach */ 4303c3fd0a5SGreg Roach public static function checkRepositoryAccess(?Repository $repository, bool $edit = false): Repository 431e539f5c6SGreg Roach { 43281b729d3SGreg Roach $message = I18N::translate('This repository does not exist or you do not have permission to view it.'); 43381b729d3SGreg Roach 434e539f5c6SGreg Roach if ($repository === null) { 43581b729d3SGreg Roach throw new HttpNotFoundException($message); 436e539f5c6SGreg Roach } 437e539f5c6SGreg Roach 4383c3fd0a5SGreg Roach if ($edit && $repository->canEdit()) { 4398091bfd1SGreg Roach $repository->lock(); 4408091bfd1SGreg Roach 441ddeb3354SGreg Roach return $repository; 442e539f5c6SGreg Roach } 443e539f5c6SGreg Roach 4443c3fd0a5SGreg Roach if ($repository->canShow()) { 4453c3fd0a5SGreg Roach return $repository; 4463c3fd0a5SGreg Roach } 4473c3fd0a5SGreg Roach 44881b729d3SGreg Roach throw new HttpAccessDeniedException($message); 4493c3fd0a5SGreg Roach } 4503c3fd0a5SGreg Roach 451e539f5c6SGreg Roach /** 452e539f5c6SGreg Roach * @param Source|null $source 453ffc0a61fSGreg Roach * @param bool $edit 454e539f5c6SGreg Roach * 455ddeb3354SGreg Roach * @return Source 45681b729d3SGreg Roach * @throws HttpNotFoundException 45781b729d3SGreg Roach * @throws HttpAccessDeniedException 458e539f5c6SGreg Roach */ 4593c3fd0a5SGreg Roach public static function checkSourceAccess(?Source $source, bool $edit = false): Source 460e539f5c6SGreg Roach { 46181b729d3SGreg Roach $message = I18N::translate('This source does not exist or you do not have permission to view it.'); 46281b729d3SGreg Roach 463e539f5c6SGreg Roach if ($source === null) { 46481b729d3SGreg Roach throw new HttpNotFoundException($message); 465e539f5c6SGreg Roach } 466e539f5c6SGreg Roach 4673c3fd0a5SGreg Roach if ($edit && $source->canEdit()) { 4688091bfd1SGreg Roach $source->lock(); 4698091bfd1SGreg Roach 470ddeb3354SGreg Roach return $source; 471e539f5c6SGreg Roach } 472ffc0a61fSGreg Roach 4733c3fd0a5SGreg Roach if ($source->canShow()) { 4743c3fd0a5SGreg Roach return $source; 4753c3fd0a5SGreg Roach } 4763c3fd0a5SGreg Roach 47781b729d3SGreg Roach throw new HttpAccessDeniedException($message); 4783c3fd0a5SGreg Roach } 4793c3fd0a5SGreg Roach 480ffc0a61fSGreg Roach /* 481ffc0a61fSGreg Roach * @param Submitter|null $submitter 482ffc0a61fSGreg Roach * @param bool $edit 483ffc0a61fSGreg Roach * 484ffc0a61fSGreg Roach * @return Submitter 48581b729d3SGreg Roach * @throws HttpFoundException 48681b729d3SGreg Roach * @throws HttpDeniedException 487ffc0a61fSGreg Roach */ 4883c3fd0a5SGreg Roach public static function checkSubmitterAccess(?Submitter $submitter, bool $edit = false): Submitter 489ffc0a61fSGreg Roach { 49081b729d3SGreg Roach $message = I18N::translate('This record does not exist or you do not have permission to view it.'); 49181b729d3SGreg Roach 492ffc0a61fSGreg Roach if ($submitter === null) { 49381b729d3SGreg Roach throw new HttpNotFoundException($message); 494ffc0a61fSGreg Roach } 495ffc0a61fSGreg Roach 4963c3fd0a5SGreg Roach if ($edit && $submitter->canEdit()) { 4978091bfd1SGreg Roach $submitter->lock(); 4988091bfd1SGreg Roach 499ffc0a61fSGreg Roach return $submitter; 500ffc0a61fSGreg Roach } 5013c3fd0a5SGreg Roach 5023c3fd0a5SGreg Roach if ($submitter->canShow()) { 5033c3fd0a5SGreg Roach return $submitter; 5043c3fd0a5SGreg Roach } 5053c3fd0a5SGreg Roach 50681b729d3SGreg Roach throw new HttpAccessDeniedException($message); 5073c3fd0a5SGreg Roach } 5081635452cSGreg Roach 5091635452cSGreg Roach /* 5101635452cSGreg Roach * @param Submission|null $submission 5111635452cSGreg Roach * @param bool $edit 5121635452cSGreg Roach * 5131635452cSGreg Roach * @return Submission 51481b729d3SGreg Roach * @throws HttpNotFoundException 51581b729d3SGreg Roach * @throws HttpAccessDeniedException 5161635452cSGreg Roach */ 5171635452cSGreg Roach public static function checkSubmissionAccess(?Submission $submission, bool $edit = false): Submission 5181635452cSGreg Roach { 51981b729d3SGreg Roach $message = I18N::translate('This record does not exist or you do not have permission to view it.'); 52081b729d3SGreg Roach 5211635452cSGreg Roach if ($submission === null) { 52281b729d3SGreg Roach throw new HttpNotFoundException($message); 5231635452cSGreg Roach } 5241635452cSGreg Roach 5251635452cSGreg Roach if ($edit && $submission->canEdit()) { 5268091bfd1SGreg Roach $submission->lock(); 5278091bfd1SGreg Roach 5281635452cSGreg Roach return $submission; 5291635452cSGreg Roach } 5301635452cSGreg Roach 5311635452cSGreg Roach if ($submission->canShow()) { 5321635452cSGreg Roach return $submission; 5331635452cSGreg Roach } 5341635452cSGreg Roach 53581b729d3SGreg Roach throw new HttpAccessDeniedException($message); 5361635452cSGreg Roach } 537870365fbSGreg Roach 538870365fbSGreg Roach /** 5395416d6ddSGreg Roach * @param Tree $tree 5405416d6ddSGreg Roach * @param UserInterface $user 5415416d6ddSGreg Roach * 5425416d6ddSGreg Roach * @return bool 5435416d6ddSGreg Roach */ 5445416d6ddSGreg Roach public static function canUploadMedia(Tree $tree, UserInterface $user): bool 5455416d6ddSGreg Roach { 5465416d6ddSGreg Roach return 547*be410956SGreg Roach self::isEditor($tree, $user) && 548*be410956SGreg Roach self::accessLevel($tree, $user) <= (int) $tree->getPreference('MEDIA_UPLOAD'); 5495416d6ddSGreg Roach } 5505416d6ddSGreg Roach 5515416d6ddSGreg Roach 5525416d6ddSGreg Roach /** 553870365fbSGreg Roach * @return array<int,string> 554870365fbSGreg Roach */ 555870365fbSGreg Roach public static function accessLevelNames(): array 556870365fbSGreg Roach { 557870365fbSGreg Roach return [ 558d823340dSGreg Roach self::PRIV_PRIVATE => I18N::translate('Show to visitors'), 559d823340dSGreg Roach self::PRIV_USER => I18N::translate('Show to members'), 560d823340dSGreg Roach self::PRIV_NONE => I18N::translate('Show to managers'), 561d823340dSGreg Roach self::PRIV_HIDE => I18N::translate('Hide from everyone'), 562870365fbSGreg Roach ]; 563870365fbSGreg Roach } 564138139c2SGreg Roach 565138139c2SGreg Roach /** 566138139c2SGreg Roach * @return array<string,string> 567138139c2SGreg Roach */ 568138139c2SGreg Roach public static function privacyRuleNames(): array 569138139c2SGreg Roach { 570138139c2SGreg Roach return [ 571138139c2SGreg Roach 'none' => I18N::translate('Show to visitors'), 572138139c2SGreg Roach 'privacy' => I18N::translate('Show to members'), 573138139c2SGreg Roach 'confidential' => I18N::translate('Show to managers'), 574138139c2SGreg Roach 'hidden' => I18N::translate('Hide from everyone'), 575138139c2SGreg Roach ]; 576138139c2SGreg Roach } 577a25f0a04SGreg Roach} 578