]> BookStack Code Mirror - bookstack/blob - app/Http/Controllers/UserController.php
Merge branch 'master' into 2019-design
[bookstack] / app / Http / Controllers / UserController.php
1 <?php namespace BookStack\Http\Controllers;
2
3 use BookStack\Auth\Access\SocialAuthService;
4 use BookStack\Auth\User;
5 use BookStack\Auth\UserRepo;
6 use BookStack\Exceptions\UserUpdateException;
7 use Illuminate\Http\Request;
8 use Illuminate\Http\Response;
9
10 class UserController extends Controller
11 {
12
13     protected $user;
14     protected $userRepo;
15
16     /**
17      * UserController constructor.
18      * @param User     $user
19      * @param UserRepo $userRepo
20      */
21     public function __construct(User $user, UserRepo $userRepo)
22     {
23         $this->user = $user;
24         $this->userRepo = $userRepo;
25         parent::__construct();
26     }
27
28     /**
29      * Display a listing of the users.
30      * @param Request $request
31      * @return Response
32      */
33     public function index(Request $request)
34     {
35         $this->checkPermission('users-manage');
36         $listDetails = [
37             'order' => $request->get('order', 'asc'),
38             'search' => $request->get('search', ''),
39             'sort' => $request->get('sort', 'name'),
40         ];
41         $users = $this->userRepo->getAllUsersPaginatedAndSorted(20, $listDetails);
42         $this->setPageTitle(trans('settings.users'));
43         $users->appends($listDetails);
44         return view('users/index', ['users' => $users, 'listDetails' => $listDetails]);
45     }
46
47     /**
48      * Show the form for creating a new user.
49      * @return Response
50      */
51     public function create()
52     {
53         $this->checkPermission('users-manage');
54         $authMethod = config('auth.method');
55         $roles = $this->userRepo->getAllRoles();
56         return view('users/create', ['authMethod' => $authMethod, 'roles' => $roles]);
57     }
58
59     /**
60      * Store a newly created user in storage.
61      * @param  Request $request
62      * @return Response
63      * @throws UserUpdateException
64      */
65     public function store(Request $request)
66     {
67         $this->checkPermission('users-manage');
68         $validationRules = [
69             'name'             => 'required',
70             'email'            => 'required|email|unique:users,email'
71         ];
72
73         $authMethod = config('auth.method');
74         if ($authMethod === 'standard') {
75             $validationRules['password'] = 'required|min:5';
76             $validationRules['password-confirm'] = 'required|same:password';
77         } elseif ($authMethod === 'ldap') {
78             $validationRules['external_auth_id'] = 'required';
79         }
80         $this->validate($request, $validationRules);
81
82         $user = $this->user->fill($request->all());
83
84         if ($authMethod === 'standard') {
85             $user->password = bcrypt($request->get('password'));
86         } elseif ($authMethod === 'ldap') {
87             $user->external_auth_id = $request->get('external_auth_id');
88         }
89
90         $user->save();
91
92         if ($request->filled('roles')) {
93             $roles = $request->get('roles');
94             $this->userRepo->setUserRoles($user, $roles);
95         }
96
97         $this->userRepo->downloadAndAssignUserAvatar($user);
98
99         return redirect('/settings/users');
100     }
101
102     /**
103      * Show the form for editing the specified user.
104      * @param  int              $id
105      * @param \BookStack\Auth\Access\SocialAuthService $socialAuthService
106      * @return Response
107      */
108     public function edit($id, SocialAuthService $socialAuthService)
109     {
110         $this->checkPermissionOr('users-manage', function () use ($id) {
111             return $this->currentUser->id == $id;
112         });
113
114         $user = $this->user->findOrFail($id);
115
116         $authMethod = ($user->system_name) ? 'system' : config('auth.method');
117
118         $activeSocialDrivers = $socialAuthService->getActiveDrivers();
119         $this->setPageTitle(trans('settings.user_profile'));
120         $roles = $this->userRepo->getAllRoles();
121         return view('users/edit', ['user' => $user, 'activeSocialDrivers' => $activeSocialDrivers, 'authMethod' => $authMethod, 'roles' => $roles]);
122     }
123
124     /**
125      * Update the specified user in storage.
126      * @param  Request $request
127      * @param  int $id
128      * @return Response
129      * @throws UserUpdateException
130      */
131     public function update(Request $request, $id)
132     {
133         $this->preventAccessForDemoUsers();
134         $this->checkPermissionOr('users-manage', function () use ($id) {
135             return $this->currentUser->id == $id;
136         });
137
138         $this->validate($request, [
139             'name'             => 'min:2',
140             'email'            => 'min:2|email|unique:users,email,' . $id,
141             'password'         => 'min:5|required_with:password_confirm',
142             'password-confirm' => 'same:password|required_with:password',
143             'setting'          => 'array'
144         ]);
145
146         $user = $this->userRepo->getById($id);
147         $user->fill($request->all());
148
149         // Role updates
150         if (userCan('users-manage') && $request->filled('roles')) {
151             $roles = $request->get('roles');
152             $this->userRepo->setUserRoles($user, $roles);
153         }
154
155         // Password updates
156         if ($request->filled('password')) {
157             $password = $request->get('password');
158             $user->password = bcrypt($password);
159         }
160
161         // External auth id updates
162         if ($this->currentUser->can('users-manage') && $request->filled('external_auth_id')) {
163             $user->external_auth_id = $request->get('external_auth_id');
164         }
165
166         // Save an user-specific settings
167         if ($request->filled('setting')) {
168             foreach ($request->get('setting') as $key => $value) {
169                 setting()->putUser($user, $key, $value);
170             }
171         }
172
173         $user->save();
174         session()->flash('success', trans('settings.users_edit_success'));
175
176         $redirectUrl = userCan('users-manage') ? '/settings/users' : '/settings/users/' . $user->id;
177         return redirect($redirectUrl);
178     }
179
180     /**
181      * Show the user delete page.
182      * @param int $id
183      * @return \Illuminate\View\View
184      */
185     public function delete($id)
186     {
187         $this->checkPermissionOr('users-manage', function () use ($id) {
188             return $this->currentUser->id == $id;
189         });
190
191         $user = $this->userRepo->getById($id);
192         $this->setPageTitle(trans('settings.users_delete_named', ['userName' => $user->name]));
193         return view('users/delete', ['user' => $user]);
194     }
195
196     /**
197      * Remove the specified user from storage.
198      * @param  int $id
199      * @return Response
200      * @throws \Exception
201      */
202     public function destroy($id)
203     {
204         $this->preventAccessForDemoUsers();
205         $this->checkPermissionOr('users-manage', function () use ($id) {
206             return $this->currentUser->id == $id;
207         });
208
209         $user = $this->userRepo->getById($id);
210
211         if ($this->userRepo->isOnlyAdmin($user)) {
212             session()->flash('error', trans('errors.users_cannot_delete_only_admin'));
213             return redirect($user->getEditUrl());
214         }
215
216         if ($user->system_name === 'public') {
217             session()->flash('error', trans('errors.users_cannot_delete_guest'));
218             return redirect($user->getEditUrl());
219         }
220
221         $this->userRepo->destroy($user);
222         session()->flash('success', trans('settings.users_delete_success'));
223
224         return redirect('/settings/users');
225     }
226
227     /**
228      * Show the user profile page
229      * @param $id
230      * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
231      */
232     public function showProfilePage($id)
233     {
234         $user = $this->userRepo->getById($id);
235         $userActivity = $this->userRepo->getActivity($user);
236         $recentlyCreated = $this->userRepo->getRecentlyCreated($user, 5, 0);
237         $assetCounts = $this->userRepo->getAssetCounts($user);
238         return view('users/profile', [
239             'user' => $user,
240             'activity' => $userActivity,
241             'recentlyCreated' => $recentlyCreated,
242             'assetCounts' => $assetCounts
243         ]);
244     }
245
246     /**
247      * Update the user's preferred book-list display setting.
248      * @param $id
249      * @param Request $request
250      * @return \Illuminate\Http\RedirectResponse
251      */
252     public function switchBookView($id, Request $request)
253     {
254         return $this->switchViewType($id, $request, 'books');
255     }
256
257     /**
258      * Update the user's preferred shelf-list display setting.
259      * @param $id
260      * @param Request $request
261      * @return \Illuminate\Http\RedirectResponse
262      */
263     public function switchShelfView($id, Request $request)
264     {
265         return $this->switchViewType($id, $request, 'bookshelves');
266     }
267
268     /**
269      * For a type of list, switch with stored view type for a user.
270      * @param integer $userId
271      * @param Request $request
272      * @param string $listName
273      * @return \Illuminate\Http\RedirectResponse
274      */
275     protected function switchViewType($userId, Request $request, string $listName)
276     {
277         $this->checkPermissionOrCurrentUser('users-manage', $userId);
278
279         $viewType = $request->get('view_type');
280         if (!in_array($viewType, ['grid', 'list'])) {
281             $viewType = 'list';
282         }
283
284         $user = $this->userRepo->getById($id);
285         $key = $listName . '_view_type';
286         setting()->putUser($user, $key, $viewType);
287
288         return redirect()->back(302, [], "/settings/users/$userId");
289     }
290
291     /**
292      * Change the stored sort type for the books view.
293      * @param $id
294      * @param Request $request
295      * @return \Illuminate\Http\RedirectResponse
296      */
297     public function changeBooksSort($id, Request $request)
298     {
299         // TODO - Test this endpoint
300         return $this->changeListSort($id, $request, 'books');
301     }
302
303     /**
304      * Changed the stored preference for a list sort order.
305      * @param int $userId
306      * @param Request $request
307      * @param string $listName
308      * @return \Illuminate\Http\RedirectResponse
309      */
310     protected function changeListSort(int $userId, Request $request, string $listName)
311     {
312         $this->checkPermissionOrCurrentUser('users-manage', $userId);
313
314         $sort = $request->get('sort');
315         if (!in_array($sort, ['name', 'created_at', 'updated_at'])) {
316             $sort = 'name';
317         }
318
319         $order = $request->get('order');
320         if (!in_array($order, ['asc', 'desc'])) {
321             $order = 'asc';
322         }
323
324         $user = $this->user->findOrFail($userId);
325         $sortKey = $listName . '_sort';
326         $orderKey = $listName . '_sort_order';
327         setting()->putUser($user, $sortKey, $sort);
328         setting()->putUser($user, $orderKey, $order);
329
330         return redirect()->back(302, [], "/settings/users/$userId");
331     }
332
333 }