]> BookStack Code Mirror - bookstack/blob - app/Http/Controller.php
8facf5dab3c3331d1538b373b68b269d6c6f53b4
[bookstack] / app / Http / Controller.php
1 <?php
2
3 namespace BookStack\Http;
4
5 use BookStack\Activity\Models\Loggable;
6 use BookStack\App\Model;
7 use BookStack\Exceptions\NotifyException;
8 use BookStack\Facades\Activity;
9 use Illuminate\Foundation\Bus\DispatchesJobs;
10 use Illuminate\Foundation\Validation\ValidatesRequests;
11 use Illuminate\Http\JsonResponse;
12 use Illuminate\Http\RedirectResponse;
13 use Illuminate\Http\Request;
14 use Illuminate\Routing\Controller as BaseController;
15
16 abstract class Controller extends BaseController
17 {
18     use DispatchesJobs;
19     use ValidatesRequests;
20
21     /**
22      * Check if the current user is signed in.
23      */
24     protected function isSignedIn(): bool
25     {
26         return auth()->check();
27     }
28
29     /**
30      * Stops the application and shows a permission error if
31      * the application is in demo mode.
32      */
33     protected function preventAccessInDemoMode()
34     {
35         if (config('app.env') === 'demo') {
36             $this->showPermissionError();
37         }
38     }
39
40     /**
41      * Adds the page title into the view.
42      */
43     public function setPageTitle(string $title)
44     {
45         view()->share('pageTitle', $title);
46     }
47
48     /**
49      * On a permission error redirect to home and display.
50      * the error as a notification.
51      *
52      * @return never
53      */
54     protected function showPermissionError()
55     {
56         $message = request()->wantsJson() ? trans('errors.permissionJson') : trans('errors.permission');
57
58         throw new NotifyException($message, '/', 403);
59     }
60
61     /**
62      * Checks that the current user has the given permission otherwise throw an exception.
63      */
64     protected function checkPermission(string $permission): void
65     {
66         if (!user() || !user()->can($permission)) {
67             $this->showPermissionError();
68         }
69     }
70
71     /**
72      * Prevent access for guest users beyond this point.
73      */
74     protected function preventGuestAccess(): void
75     {
76         if (user()->isGuest()) {
77             $this->showPermissionError();
78         }
79     }
80
81     /**
82      * Check the current user's permissions against an ownable item otherwise throw an exception.
83      */
84     protected function checkOwnablePermission(string $permission, Model $ownable): void
85     {
86         if (!userCan($permission, $ownable)) {
87             $this->showPermissionError();
88         }
89     }
90
91     /**
92      * Check if a user has a permission or bypass the permission
93      * check if the given callback resolves true.
94      */
95     protected function checkPermissionOr(string $permission, callable $callback): void
96     {
97         if ($callback() !== true) {
98             $this->checkPermission($permission);
99         }
100     }
101
102     /**
103      * Check if the current user has a permission or bypass if the provided user
104      * id matches the current user.
105      */
106     protected function checkPermissionOrCurrentUser(string $permission, int $userId): void
107     {
108         $this->checkPermissionOr($permission, function () use ($userId) {
109             return $userId === user()->id;
110         });
111     }
112
113     /**
114      * Send back a json error message.
115      */
116     protected function jsonError(string $messageText = '', int $statusCode = 500): JsonResponse
117     {
118         return response()->json(['message' => $messageText, 'status' => 'error'], $statusCode);
119     }
120
121     /**
122      * Create and return a new download response factory using the current request.
123      */
124     protected function download(): DownloadResponseFactory
125     {
126         return new DownloadResponseFactory(request());
127     }
128
129     /**
130      * Show a positive, successful notification to the user on next view load.
131      */
132     protected function showSuccessNotification(string $message): void
133     {
134         session()->flash('success', $message);
135     }
136
137     /**
138      * Show a warning notification to the user on next view load.
139      */
140     protected function showWarningNotification(string $message): void
141     {
142         session()->flash('warning', $message);
143     }
144
145     /**
146      * Show an error notification to the user on next view load.
147      */
148     protected function showErrorNotification(string $message): void
149     {
150         session()->flash('error', $message);
151     }
152
153     /**
154      * Log an activity in the system.
155      *
156      * @param string|Loggable $detail
157      */
158     protected function logActivity(string $type, $detail = ''): void
159     {
160         Activity::add($type, $detail);
161     }
162
163     /**
164      * Get the validation rules for image files.
165      */
166     protected function getImageValidationRules(): array
167     {
168         return ['image_extension', 'mimes:jpeg,png,gif,webp', 'max:' . (config('app.upload_limit') * 1000)];
169     }
170
171     /**
172      * Redirect to the URL provided in the request as a '_return' parameter.
173      * Will check that the parameter leads to a URL under the root path of the system.
174      */
175     protected function redirectToRequest(Request $request): RedirectResponse
176     {
177         $basePath = url('/');
178         $returnUrl = $request->input('_return') ?? $basePath;
179
180         if (!str_starts_with($returnUrl, $basePath)) {
181             return redirect($basePath);
182         }
183
184         return redirect($returnUrl);
185     }
186 }