xref: /webtrees/app/Auth.php (revision 5416d6dd3f87a3c649f9964bd6153fafcb9ea0e7)
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    /**
539*5416d6ddSGreg Roach     * @param Tree          $tree
540*5416d6ddSGreg Roach     * @param UserInterface $user
541*5416d6ddSGreg Roach     *
542*5416d6ddSGreg Roach     * @return bool
543*5416d6ddSGreg Roach     */
544*5416d6ddSGreg Roach    public static function canUploadMedia(Tree $tree, UserInterface $user): bool
545*5416d6ddSGreg Roach    {
546*5416d6ddSGreg Roach        return
547*5416d6ddSGreg Roach            Auth::isEditor($tree, $user) &&
548*5416d6ddSGreg Roach            Auth::accessLevel($tree, $user) <= (int) $tree->getPreference('MEDIA_UPLOAD');
549*5416d6ddSGreg Roach    }
550*5416d6ddSGreg Roach
551*5416d6ddSGreg Roach
552*5416d6ddSGreg 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