1a25f0a04SGreg Roach<?php 23976b470SGreg Roach 3a25f0a04SGreg Roach/** 4a25f0a04SGreg Roach * webtrees: online genealogy 5*8091bfd1SGreg Roach * Copyright (C) 2020 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 15a25f0a04SGreg Roach * along with this program. If not, see <http://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; 23e539f5c6SGreg Roachuse Fisharebest\Webtrees\Exceptions\FamilyAccessDeniedException; 24e539f5c6SGreg Roachuse Fisharebest\Webtrees\Exceptions\FamilyNotFoundException; 25d501c45dSGreg Roachuse Fisharebest\Webtrees\Exceptions\HttpAccessDeniedException; 26e539f5c6SGreg Roachuse Fisharebest\Webtrees\Exceptions\IndividualAccessDeniedException; 27e539f5c6SGreg Roachuse Fisharebest\Webtrees\Exceptions\IndividualNotFoundException; 28e539f5c6SGreg Roachuse Fisharebest\Webtrees\Exceptions\MediaAccessDeniedException; 29e539f5c6SGreg Roachuse Fisharebest\Webtrees\Exceptions\MediaNotFoundException; 30e539f5c6SGreg Roachuse Fisharebest\Webtrees\Exceptions\NoteAccessDeniedException; 31e539f5c6SGreg Roachuse Fisharebest\Webtrees\Exceptions\NoteNotFoundException; 32e539f5c6SGreg Roachuse Fisharebest\Webtrees\Exceptions\RecordAccessDeniedException; 33e539f5c6SGreg Roachuse Fisharebest\Webtrees\Exceptions\RecordNotFoundException; 34e539f5c6SGreg Roachuse Fisharebest\Webtrees\Exceptions\RepositoryAccessDeniedException; 35e539f5c6SGreg Roachuse Fisharebest\Webtrees\Exceptions\RepositoryNotFoundException; 36e539f5c6SGreg Roachuse Fisharebest\Webtrees\Exceptions\SourceAccessDeniedException; 37e539f5c6SGreg Roachuse Fisharebest\Webtrees\Exceptions\SourceNotFoundException; 389867b2f0SGreg Roachuse Fisharebest\Webtrees\Module\ModuleInterface; 39e5a6b4d4SGreg Roachuse Fisharebest\Webtrees\Services\UserService; 4079529c87SGreg Roach 41a25f0a04SGreg Roach/** 4276692c8bSGreg Roach * Authentication. 43a25f0a04SGreg Roach */ 44c1010edaSGreg Roachclass Auth 45c1010edaSGreg Roach{ 464b9ff166SGreg Roach // Privacy constants 4716d6367aSGreg Roach public const PRIV_PRIVATE = 2; // Allows visitors to view the item 4816d6367aSGreg Roach public const PRIV_USER = 1; // Allows members to access the item 4916d6367aSGreg Roach public const PRIV_NONE = 0; // Allows managers to access the item 5016d6367aSGreg Roach public const PRIV_HIDE = -1; // Hide the item to all users 514b9ff166SGreg Roach 52a25f0a04SGreg Roach /** 53a25f0a04SGreg Roach * Are we currently logged in? 54a25f0a04SGreg Roach * 55cbc1590aSGreg Roach * @return bool 56a25f0a04SGreg Roach */ 578f53f488SRico Sonntag public static function check(): bool 58c1010edaSGreg Roach { 594b9ff166SGreg Roach return self::id() !== null; 60a25f0a04SGreg Roach } 61a25f0a04SGreg Roach 62a25f0a04SGreg Roach /** 63a25f0a04SGreg Roach * Is the specified/current user an administrator? 64a25f0a04SGreg Roach * 65e5a6b4d4SGreg Roach * @param UserInterface|null $user 66a25f0a04SGreg Roach * 67cbc1590aSGreg Roach * @return bool 68a25f0a04SGreg Roach */ 69e5a6b4d4SGreg Roach public static function isAdmin(UserInterface $user = null): bool 70c1010edaSGreg Roach { 71cb923727SGreg Roach $user = $user ?? self::user(); 72a25f0a04SGreg Roach 737c4add84SGreg Roach return $user->getPreference(User::PREF_IS_ADMINISTRATOR) === '1'; 74a25f0a04SGreg Roach } 75a25f0a04SGreg Roach 76a25f0a04SGreg Roach /** 774b9ff166SGreg Roach * Is the specified/current user a manager of a tree? 78a25f0a04SGreg Roach * 7984caa210SGreg Roach * @param Tree $tree 80e5a6b4d4SGreg Roach * @param UserInterface|null $user 81a25f0a04SGreg Roach * 82cbc1590aSGreg Roach * @return bool 83a25f0a04SGreg Roach */ 84e5a6b4d4SGreg Roach public static function isManager(Tree $tree, UserInterface $user = null): bool 85c1010edaSGreg Roach { 86cb923727SGreg Roach $user = $user ?? self::user(); 87a25f0a04SGreg Roach 887c4add84SGreg Roach return self::isAdmin($user) || $tree->getUserPreference($user, User::PREF_TREE_ROLE) === User::ROLE_MANAGER; 89a25f0a04SGreg Roach } 90a25f0a04SGreg Roach 91a25f0a04SGreg Roach /** 924b9ff166SGreg Roach * Is the specified/current user a moderator of a tree? 93a25f0a04SGreg Roach * 9484caa210SGreg Roach * @param Tree $tree 95e5a6b4d4SGreg Roach * @param UserInterface|null $user 96a25f0a04SGreg Roach * 97cbc1590aSGreg Roach * @return bool 98a25f0a04SGreg Roach */ 99e5a6b4d4SGreg Roach public static function isModerator(Tree $tree, UserInterface $user = null): bool 100c1010edaSGreg Roach { 101cb923727SGreg Roach $user = $user ?? self::user(); 102a25f0a04SGreg Roach 1037c4add84SGreg Roach return self::isManager($tree, $user) || $tree->getUserPreference($user, User::PREF_TREE_ROLE) === User::ROLE_MODERATOR; 104a25f0a04SGreg Roach } 105a25f0a04SGreg Roach 106a25f0a04SGreg Roach /** 1074b9ff166SGreg Roach * Is the specified/current user an editor of a tree? 108a25f0a04SGreg Roach * 10984caa210SGreg Roach * @param Tree $tree 110e5a6b4d4SGreg Roach * @param UserInterface|null $user 111a25f0a04SGreg Roach * 112cbc1590aSGreg Roach * @return bool 113a25f0a04SGreg Roach */ 114e5a6b4d4SGreg Roach public static function isEditor(Tree $tree, UserInterface $user = null): bool 115c1010edaSGreg Roach { 116cb923727SGreg Roach $user = $user ?? self::user(); 117a25f0a04SGreg Roach 1187c4add84SGreg Roach return self::isModerator($tree, $user) || $tree->getUserPreference($user, User::PREF_TREE_ROLE) === 'edit'; 119a25f0a04SGreg Roach } 120a25f0a04SGreg Roach 121a25f0a04SGreg Roach /** 1224b9ff166SGreg Roach * Is the specified/current user a member of a tree? 123a25f0a04SGreg Roach * 12484caa210SGreg Roach * @param Tree $tree 125e5a6b4d4SGreg Roach * @param UserInterface|null $user 126a25f0a04SGreg Roach * 127cbc1590aSGreg Roach * @return bool 128a25f0a04SGreg Roach */ 129e5a6b4d4SGreg Roach public static function isMember(Tree $tree, UserInterface $user = null): bool 130c1010edaSGreg Roach { 131cb923727SGreg Roach $user = $user ?? self::user(); 132a25f0a04SGreg Roach 1337c4add84SGreg Roach return self::isEditor($tree, $user) || $tree->getUserPreference($user, User::PREF_TREE_ROLE) === 'access'; 134a25f0a04SGreg Roach } 135a25f0a04SGreg Roach 136a25f0a04SGreg Roach /** 1374b9ff166SGreg Roach * What is the specified/current user's access level within a tree? 1384b9ff166SGreg Roach * 1394b9ff166SGreg Roach * @param Tree $tree 140e5a6b4d4SGreg Roach * @param UserInterface|null $user 1414b9ff166SGreg Roach * 142cbc1590aSGreg Roach * @return int 1434b9ff166SGreg Roach */ 144e364afe4SGreg Roach public static function accessLevel(Tree $tree, UserInterface $user = null): int 145c1010edaSGreg Roach { 146cb923727SGreg Roach $user = $user ?? self::user(); 1474b9ff166SGreg Roach 1484b9ff166SGreg Roach if (self::isManager($tree, $user)) { 1494b9ff166SGreg Roach return self::PRIV_NONE; 1504b9ff166SGreg Roach } 151b2ce94c6SRico Sonntag 152b2ce94c6SRico Sonntag if (self::isMember($tree, $user)) { 153b2ce94c6SRico Sonntag return self::PRIV_USER; 154b2ce94c6SRico Sonntag } 155b2ce94c6SRico Sonntag 156b2ce94c6SRico Sonntag return self::PRIV_PRIVATE; 1574b9ff166SGreg Roach } 1584b9ff166SGreg Roach 1594b9ff166SGreg Roach /** 160a25f0a04SGreg Roach * The ID of the authenticated user, from the current session. 161a25f0a04SGreg Roach * 162c3ffc4cbSGreg Roach * @return int|null 163a25f0a04SGreg Roach */ 164e364afe4SGreg Roach public static function id(): ?int 165c1010edaSGreg Roach { 1669683b471SGreg Roach return Session::get('wt_user'); 167a25f0a04SGreg Roach } 168a25f0a04SGreg Roach 169a25f0a04SGreg Roach /** 170a25f0a04SGreg Roach * The authenticated user, from the current session. 171a25f0a04SGreg Roach * 172e5a6b4d4SGreg Roach * @return UserInterface 173a25f0a04SGreg Roach */ 174e5a6b4d4SGreg Roach public static function user(): UserInterface 175c1010edaSGreg Roach { 17615674e31SGreg Roach return app(UserService::class)->find(self::id()) ?? new GuestUser(); 177a25f0a04SGreg Roach } 178a25f0a04SGreg Roach 179a25f0a04SGreg Roach /** 180a25f0a04SGreg Roach * Login directly as an explicit user - for masquerading. 181a25f0a04SGreg Roach * 182e5a6b4d4SGreg Roach * @param UserInterface $user 183cb923727SGreg Roach * 184cb923727SGreg Roach * @return void 185a25f0a04SGreg Roach */ 186e364afe4SGreg Roach public static function login(UserInterface $user): void 187c1010edaSGreg Roach { 188e988f922SGreg Roach Session::regenerate(false); 189895230eeSGreg Roach Session::put('wt_user', $user->id()); 190a25f0a04SGreg Roach } 191a25f0a04SGreg Roach 192a25f0a04SGreg Roach /** 193a25f0a04SGreg Roach * End the session for the current user. 194cb923727SGreg Roach * 195cb923727SGreg Roach * @return void 196a25f0a04SGreg Roach */ 197e364afe4SGreg Roach public static function logout(): void 198c1010edaSGreg Roach { 19931bc7874SGreg Roach Session::regenerate(true); 200a25f0a04SGreg Roach } 201e539f5c6SGreg Roach 202e539f5c6SGreg Roach /** 2039867b2f0SGreg Roach * @param ModuleInterface $module 204ef483801SGreg Roach * @param string $interface 2059867b2f0SGreg Roach * @param Tree $tree 206e5a6b4d4SGreg Roach * @param UserInterface $user 2079867b2f0SGreg Roach * 2089867b2f0SGreg Roach * @return void 2099867b2f0SGreg Roach */ 210ef483801SGreg Roach public static function checkComponentAccess(ModuleInterface $module, string $interface, Tree $tree, UserInterface $user): void 2119867b2f0SGreg Roach { 212ef483801SGreg Roach if ($module->accessLevel($tree, $interface) < self::accessLevel($tree, $user)) { 213d501c45dSGreg Roach throw new HttpAccessDeniedException(); 2149867b2f0SGreg Roach } 2159867b2f0SGreg Roach } 2169867b2f0SGreg Roach 2179867b2f0SGreg Roach /** 218e539f5c6SGreg Roach * @param Family|null $family 219ffc0a61fSGreg Roach * @param bool $edit 220e539f5c6SGreg Roach * 221ddeb3354SGreg Roach * @return Family 222e539f5c6SGreg Roach * @throws FamilyNotFoundException 223e539f5c6SGreg Roach * @throws FamilyAccessDeniedException 224e539f5c6SGreg Roach */ 2253c3fd0a5SGreg Roach public static function checkFamilyAccess(?Family $family, bool $edit = false): Family 226e539f5c6SGreg Roach { 227e539f5c6SGreg Roach if ($family === null) { 228e539f5c6SGreg Roach throw new FamilyNotFoundException(); 229e539f5c6SGreg Roach } 230e539f5c6SGreg Roach 2313c3fd0a5SGreg Roach if ($edit && $family->canEdit()) { 232*8091bfd1SGreg Roach $family->lock(); 233*8091bfd1SGreg Roach 234ddeb3354SGreg Roach return $family; 235e539f5c6SGreg Roach } 236e539f5c6SGreg Roach 2373c3fd0a5SGreg Roach if ($family->canShow()) { 2383c3fd0a5SGreg Roach return $family; 2393c3fd0a5SGreg Roach } 2403c3fd0a5SGreg Roach 2413c3fd0a5SGreg Roach throw new FamilyAccessDeniedException(); 2423c3fd0a5SGreg Roach } 2433c3fd0a5SGreg Roach 244e539f5c6SGreg Roach /** 2451635452cSGreg Roach * @param Header|null $header 2461635452cSGreg Roach * @param bool $edit 2471635452cSGreg Roach * 2481635452cSGreg Roach * @return Header 2491635452cSGreg Roach * @throws RecordNotFoundException 2501635452cSGreg Roach * @throws RecordAccessDeniedException 2511635452cSGreg Roach */ 2521635452cSGreg Roach public static function checkHeaderAccess(?Header $header, bool $edit = false): Header 2531635452cSGreg Roach { 2541635452cSGreg Roach if ($header === null) { 2551635452cSGreg Roach throw new RecordNotFoundException(); 2561635452cSGreg Roach } 2571635452cSGreg Roach 2581635452cSGreg Roach if ($edit && $header->canEdit()) { 259*8091bfd1SGreg Roach $header->lock(); 260*8091bfd1SGreg Roach 2611635452cSGreg Roach return $header; 2621635452cSGreg Roach } 2631635452cSGreg Roach 2641635452cSGreg Roach if ($header->canShow()) { 2651635452cSGreg Roach return $header; 2661635452cSGreg Roach } 2671635452cSGreg Roach 2681635452cSGreg Roach throw new RecordAccessDeniedException(); 2691635452cSGreg Roach } 2701635452cSGreg Roach 2711635452cSGreg Roach /** 272e539f5c6SGreg Roach * @param Individual|null $individual 273ffc0a61fSGreg Roach * @param bool $edit 2743c3fd0a5SGreg Roach * @param bool $chart For some charts, we can show private records 275e539f5c6SGreg Roach * 276ddeb3354SGreg Roach * @return Individual 277e539f5c6SGreg Roach * @throws IndividualNotFoundException 278e539f5c6SGreg Roach * @throws IndividualAccessDeniedException 279e539f5c6SGreg Roach */ 2803c3fd0a5SGreg Roach public static function checkIndividualAccess(?Individual $individual, bool $edit = false, $chart = false): Individual 281e539f5c6SGreg Roach { 282e539f5c6SGreg Roach if ($individual === null) { 283e539f5c6SGreg Roach throw new IndividualNotFoundException(); 284e539f5c6SGreg Roach } 285e539f5c6SGreg Roach 2863c3fd0a5SGreg Roach if ($edit && $individual->canEdit()) { 287*8091bfd1SGreg Roach $individual->lock(); 288*8091bfd1SGreg Roach 289ddeb3354SGreg Roach return $individual; 290e539f5c6SGreg Roach } 291e539f5c6SGreg Roach 2923c3fd0a5SGreg Roach if ($chart && $individual->tree()->getPreference('SHOW_PRIVATE_RELATIONSHIPS') === '1') { 2933c3fd0a5SGreg Roach return $individual; 2943c3fd0a5SGreg Roach } 2953c3fd0a5SGreg Roach 2963c3fd0a5SGreg Roach if ($individual->canShow()) { 2973c3fd0a5SGreg Roach return $individual; 2983c3fd0a5SGreg Roach } 2993c3fd0a5SGreg Roach 3003c3fd0a5SGreg Roach throw new IndividualAccessDeniedException(); 3013c3fd0a5SGreg Roach } 3023c3fd0a5SGreg Roach 303e539f5c6SGreg Roach /** 304e539f5c6SGreg Roach * @param Media|null $media 305ffc0a61fSGreg Roach * @param bool $edit 306e539f5c6SGreg Roach * 307ddeb3354SGreg Roach * @return Media 308e539f5c6SGreg Roach * @throws MediaNotFoundException 309e539f5c6SGreg Roach * @throws MediaAccessDeniedException 310e539f5c6SGreg Roach */ 3113c3fd0a5SGreg Roach public static function checkMediaAccess(?Media $media, bool $edit = false): Media 312e539f5c6SGreg Roach { 313e539f5c6SGreg Roach if ($media === null) { 314e539f5c6SGreg Roach throw new MediaNotFoundException(); 315e539f5c6SGreg Roach } 316e539f5c6SGreg Roach 3173c3fd0a5SGreg Roach if ($edit && $media->canEdit()) { 318*8091bfd1SGreg Roach $media->lock(); 319*8091bfd1SGreg Roach 320ddeb3354SGreg Roach return $media; 321e539f5c6SGreg Roach } 322e539f5c6SGreg Roach 3233c3fd0a5SGreg Roach if ($media->canShow()) { 3243c3fd0a5SGreg Roach return $media; 3253c3fd0a5SGreg Roach } 3263c3fd0a5SGreg Roach 3273c3fd0a5SGreg Roach throw new MediaAccessDeniedException(); 3283c3fd0a5SGreg Roach } 3293c3fd0a5SGreg Roach 330e539f5c6SGreg Roach /** 331e539f5c6SGreg Roach * @param Note|null $note 332ffc0a61fSGreg Roach * @param bool $edit 333e539f5c6SGreg Roach * 334ddeb3354SGreg Roach * @return Note 335e539f5c6SGreg Roach * @throws NoteNotFoundException 336e539f5c6SGreg Roach * @throws NoteAccessDeniedException 337e539f5c6SGreg Roach */ 3383c3fd0a5SGreg Roach public static function checkNoteAccess(?Note $note, bool $edit = false): Note 339e539f5c6SGreg Roach { 340e539f5c6SGreg Roach if ($note === null) { 341e539f5c6SGreg Roach throw new NoteNotFoundException(); 342e539f5c6SGreg Roach } 343e539f5c6SGreg Roach 3443c3fd0a5SGreg Roach if ($edit && $note->canEdit()) { 345*8091bfd1SGreg Roach $note->lock(); 346*8091bfd1SGreg Roach 347ddeb3354SGreg Roach return $note; 348e539f5c6SGreg Roach } 349e539f5c6SGreg Roach 3503c3fd0a5SGreg Roach if ($note->canShow()) { 3513c3fd0a5SGreg Roach return $note; 3523c3fd0a5SGreg Roach } 3533c3fd0a5SGreg Roach 3543c3fd0a5SGreg Roach throw new NoteAccessDeniedException(); 3553c3fd0a5SGreg Roach } 3563c3fd0a5SGreg Roach 357e539f5c6SGreg Roach /** 358e539f5c6SGreg Roach * @param GedcomRecord|null $record 359ffc0a61fSGreg Roach * @param bool $edit 360e539f5c6SGreg Roach * 361ddeb3354SGreg Roach * @return GedcomRecord 362e539f5c6SGreg Roach * @throws RecordNotFoundException 363e539f5c6SGreg Roach * @throws RecordAccessDeniedException 364e539f5c6SGreg Roach */ 3653c3fd0a5SGreg Roach public static function checkRecordAccess(?GedcomRecord $record, bool $edit = false): GedcomRecord 366e539f5c6SGreg Roach { 367e539f5c6SGreg Roach if ($record === null) { 368e539f5c6SGreg Roach throw new RecordNotFoundException(); 369e539f5c6SGreg Roach } 370e539f5c6SGreg Roach 3713c3fd0a5SGreg Roach if ($edit && $record->canEdit()) { 372*8091bfd1SGreg Roach $record->lock(); 373*8091bfd1SGreg Roach 374ddeb3354SGreg Roach return $record; 375e539f5c6SGreg Roach } 376e539f5c6SGreg Roach 3773c3fd0a5SGreg Roach if ($record->canShow()) { 3783c3fd0a5SGreg Roach return $record; 3793c3fd0a5SGreg Roach } 3803c3fd0a5SGreg Roach 3813c3fd0a5SGreg Roach throw new RecordAccessDeniedException(); 3823c3fd0a5SGreg Roach } 3833c3fd0a5SGreg Roach 384e539f5c6SGreg Roach /** 385e539f5c6SGreg Roach * @param Repository|null $repository 386ffc0a61fSGreg Roach * @param bool $edit 387e539f5c6SGreg Roach * 388ddeb3354SGreg Roach * @return Repository 389e539f5c6SGreg Roach * @throws RepositoryNotFoundException 390e539f5c6SGreg Roach * @throws RepositoryAccessDeniedException 391e539f5c6SGreg Roach */ 3923c3fd0a5SGreg Roach public static function checkRepositoryAccess(?Repository $repository, bool $edit = false): Repository 393e539f5c6SGreg Roach { 394e539f5c6SGreg Roach if ($repository === null) { 395e539f5c6SGreg Roach throw new RepositoryNotFoundException(); 396e539f5c6SGreg Roach } 397e539f5c6SGreg Roach 3983c3fd0a5SGreg Roach if ($edit && $repository->canEdit()) { 399*8091bfd1SGreg Roach $repository->lock(); 400*8091bfd1SGreg Roach 401ddeb3354SGreg Roach return $repository; 402e539f5c6SGreg Roach } 403e539f5c6SGreg Roach 4043c3fd0a5SGreg Roach if ($repository->canShow()) { 4053c3fd0a5SGreg Roach return $repository; 4063c3fd0a5SGreg Roach } 4073c3fd0a5SGreg Roach 4083c3fd0a5SGreg Roach throw new RepositoryAccessDeniedException(); 4093c3fd0a5SGreg Roach } 4103c3fd0a5SGreg Roach 411e539f5c6SGreg Roach /** 412e539f5c6SGreg Roach * @param Source|null $source 413ffc0a61fSGreg Roach * @param bool $edit 414e539f5c6SGreg Roach * 415ddeb3354SGreg Roach * @return Source 416e539f5c6SGreg Roach * @throws SourceNotFoundException 417e539f5c6SGreg Roach * @throws SourceAccessDeniedException 418e539f5c6SGreg Roach */ 4193c3fd0a5SGreg Roach public static function checkSourceAccess(?Source $source, bool $edit = false): Source 420e539f5c6SGreg Roach { 421e539f5c6SGreg Roach if ($source === null) { 422e539f5c6SGreg Roach throw new SourceNotFoundException(); 423e539f5c6SGreg Roach } 424e539f5c6SGreg Roach 4253c3fd0a5SGreg Roach if ($edit && $source->canEdit()) { 426*8091bfd1SGreg Roach $source->lock(); 427*8091bfd1SGreg Roach 428ddeb3354SGreg Roach return $source; 429e539f5c6SGreg Roach } 430ffc0a61fSGreg Roach 4313c3fd0a5SGreg Roach if ($source->canShow()) { 4323c3fd0a5SGreg Roach return $source; 4333c3fd0a5SGreg Roach } 4343c3fd0a5SGreg Roach 4353c3fd0a5SGreg Roach throw new SourceAccessDeniedException(); 4363c3fd0a5SGreg Roach } 4373c3fd0a5SGreg Roach 438ffc0a61fSGreg Roach /* 439ffc0a61fSGreg Roach * @param Submitter|null $submitter 440ffc0a61fSGreg Roach * @param bool $edit 441ffc0a61fSGreg Roach * 442ffc0a61fSGreg Roach * @return Submitter 443ffc0a61fSGreg Roach * @throws RecordNotFoundException 444ffc0a61fSGreg Roach * @throws RecordAccessDeniedException 445ffc0a61fSGreg Roach */ 4463c3fd0a5SGreg Roach public static function checkSubmitterAccess(?Submitter $submitter, bool $edit = false): Submitter 447ffc0a61fSGreg Roach { 448ffc0a61fSGreg Roach if ($submitter === null) { 449ffc0a61fSGreg Roach throw new RecordNotFoundException(); 450ffc0a61fSGreg Roach } 451ffc0a61fSGreg Roach 4523c3fd0a5SGreg Roach if ($edit && $submitter->canEdit()) { 453*8091bfd1SGreg Roach $submitter->lock(); 454*8091bfd1SGreg Roach 455ffc0a61fSGreg Roach return $submitter; 456ffc0a61fSGreg Roach } 4573c3fd0a5SGreg Roach 4583c3fd0a5SGreg Roach if ($submitter->canShow()) { 4593c3fd0a5SGreg Roach return $submitter; 4603c3fd0a5SGreg Roach } 4613c3fd0a5SGreg Roach 4623c3fd0a5SGreg Roach throw new RecordAccessDeniedException(); 4633c3fd0a5SGreg Roach } 4641635452cSGreg Roach 4651635452cSGreg Roach /* 4661635452cSGreg Roach * @param Submission|null $submission 4671635452cSGreg Roach * @param bool $edit 4681635452cSGreg Roach * 4691635452cSGreg Roach * @return Submission 4701635452cSGreg Roach * @throws RecordNotFoundException 4711635452cSGreg Roach * @throws RecordAccessDeniedException 4721635452cSGreg Roach */ 4731635452cSGreg Roach public static function checkSubmissionAccess(?Submission $submission, bool $edit = false): Submission 4741635452cSGreg Roach { 4751635452cSGreg Roach if ($submission === null) { 4761635452cSGreg Roach throw new RecordNotFoundException(); 4771635452cSGreg Roach } 4781635452cSGreg Roach 4791635452cSGreg Roach if ($edit && $submission->canEdit()) { 480*8091bfd1SGreg Roach $submission->lock(); 481*8091bfd1SGreg Roach 4821635452cSGreg Roach return $submission; 4831635452cSGreg Roach } 4841635452cSGreg Roach 4851635452cSGreg Roach if ($submission->canShow()) { 4861635452cSGreg Roach return $submission; 4871635452cSGreg Roach } 4881635452cSGreg Roach 4891635452cSGreg Roach throw new RecordAccessDeniedException(); 4901635452cSGreg Roach } 491870365fbSGreg Roach 492870365fbSGreg Roach /** 493870365fbSGreg Roach * @return array<int,string> 494870365fbSGreg Roach */ 495870365fbSGreg Roach public static function accessLevelNames(): array 496870365fbSGreg Roach { 497870365fbSGreg Roach return [ 498d823340dSGreg Roach self::PRIV_PRIVATE => I18N::translate('Show to visitors'), 499d823340dSGreg Roach self::PRIV_USER => I18N::translate('Show to members'), 500d823340dSGreg Roach self::PRIV_NONE => I18N::translate('Show to managers'), 501d823340dSGreg Roach self::PRIV_HIDE => I18N::translate('Hide from everyone'), 502870365fbSGreg Roach ]; 503870365fbSGreg Roach } 504138139c2SGreg Roach 505138139c2SGreg Roach /** 506138139c2SGreg Roach * @return array<string,string> 507138139c2SGreg Roach */ 508138139c2SGreg Roach public static function privacyRuleNames(): array 509138139c2SGreg Roach { 510138139c2SGreg Roach return [ 511138139c2SGreg Roach 'none' => I18N::translate('Show to visitors'), 512138139c2SGreg Roach 'privacy' => I18N::translate('Show to members'), 513138139c2SGreg Roach 'confidential' => I18N::translate('Show to managers'), 514138139c2SGreg Roach 'hidden' => I18N::translate('Hide from everyone'), 515138139c2SGreg Roach ]; 516138139c2SGreg Roach } 517a25f0a04SGreg Roach} 518