| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  | <?php | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-18 00:56:55 +08:00
										 |  |  | namespace BookStack\Api; | 
					
						
							| 
									
										
										
										
											2019-12-29 21:02:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-18 00:56:55 +08:00
										 |  |  | use BookStack\Activity\ActivityType; | 
					
						
							| 
									
										
										
										
											2023-05-19 03:53:39 +08:00
										 |  |  | use BookStack\Http\Controller; | 
					
						
							| 
									
										
										
										
											2023-05-18 00:56:55 +08:00
										 |  |  | use BookStack\Users\Models\User; | 
					
						
							| 
									
										
										
										
											2019-12-29 21:02:26 +08:00
										 |  |  | use Illuminate\Http\Request; | 
					
						
							| 
									
										
										
										
											2019-12-30 01:03:52 +08:00
										 |  |  | use Illuminate\Support\Facades\Hash; | 
					
						
							|  |  |  | use Illuminate\Support\Str; | 
					
						
							| 
									
										
										
										
											2019-12-29 21:02:26 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | class UserApiTokenController extends Controller | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Show the form to create a new API token. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2023-10-19 18:31:45 +08:00
										 |  |  |     public function create(Request $request, int $userId) | 
					
						
							| 
									
										
										
										
											2019-12-29 21:02:26 +08:00
										 |  |  |     { | 
					
						
							|  |  |  |         $this->checkPermission('access-api'); | 
					
						
							| 
									
										
										
										
											2019-12-30 03:46:46 +08:00
										 |  |  |         $this->checkPermissionOrCurrentUser('users-manage', $userId); | 
					
						
							| 
									
										
										
										
											2023-10-19 18:31:45 +08:00
										 |  |  |         $this->updateContext($request); | 
					
						
							| 
									
										
										
										
											2019-12-29 21:02:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-30 01:03:52 +08:00
										 |  |  |         $user = User::query()->findOrFail($userId); | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-19 22:24:48 +08:00
										 |  |  |         $this->setPageTitle(trans('settings.user_api_token_create')); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-30 01:03:52 +08:00
										 |  |  |         return view('users.api-tokens.create', [ | 
					
						
							|  |  |  |             'user' => $user, | 
					
						
							| 
									
										
										
										
											2023-10-19 18:31:45 +08:00
										 |  |  |             'back' => $this->getRedirectPath($user), | 
					
						
							| 
									
										
										
										
											2019-12-30 01:03:52 +08:00
										 |  |  |         ]); | 
					
						
							| 
									
										
										
										
											2019-12-29 21:02:26 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-30 01:03:52 +08:00
										 |  |  |     /** | 
					
						
							|  |  |  |      * Store a new API token in the system. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function store(Request $request, int $userId) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $this->checkPermission('access-api'); | 
					
						
							| 
									
										
										
										
											2019-12-30 03:46:46 +08:00
										 |  |  |         $this->checkPermissionOrCurrentUser('users-manage', $userId); | 
					
						
							| 
									
										
										
										
											2019-12-30 01:03:52 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         $this->validate($request, [ | 
					
						
							| 
									
										
										
										
											2021-11-05 08:26:55 +08:00
										 |  |  |             'name'       => ['required', 'max:250'], | 
					
						
							|  |  |  |             'expires_at' => ['date_format:Y-m-d'], | 
					
						
							| 
									
										
										
										
											2019-12-30 01:03:52 +08:00
										 |  |  |         ]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $user = User::query()->findOrFail($userId); | 
					
						
							|  |  |  |         $secret = Str::random(32); | 
					
						
							| 
									
										
										
										
											2019-12-30 04:18:37 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-30 01:03:52 +08:00
										 |  |  |         $token = (new ApiToken())->forceFill([ | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  |             'name'       => $request->get('name'), | 
					
						
							|  |  |  |             'token_id'   => Str::random(32), | 
					
						
							|  |  |  |             'secret'     => Hash::make($secret), | 
					
						
							|  |  |  |             'user_id'    => $user->id, | 
					
						
							| 
									
										
										
										
											2019-12-30 22:51:28 +08:00
										 |  |  |             'expires_at' => $request->get('expires_at') ?: ApiToken::defaultExpiry(), | 
					
						
							| 
									
										
										
										
											2019-12-30 01:03:52 +08:00
										 |  |  |         ]); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-30 04:07:28 +08:00
										 |  |  |         while (ApiToken::query()->where('token_id', '=', $token->token_id)->exists()) { | 
					
						
							|  |  |  |             $token->token_id = Str::random(32); | 
					
						
							| 
									
										
										
										
											2019-12-30 01:03:52 +08:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         $token->save(); | 
					
						
							| 
									
										
										
										
											2019-12-30 03:46:46 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-30 01:03:52 +08:00
										 |  |  |         session()->flash('api-token-secret:' . $token->id, $secret); | 
					
						
							| 
									
										
										
										
											2020-11-21 02:53:01 +08:00
										 |  |  |         $this->logActivity(ActivityType::API_TOKEN_CREATE, $token); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-19 18:31:45 +08:00
										 |  |  |         return redirect($token->getUrl()); | 
					
						
							| 
									
										
										
										
											2019-12-30 01:03:52 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Show the details for a user API token, with access to edit. | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2023-10-19 18:31:45 +08:00
										 |  |  |     public function edit(Request $request, int $userId, int $tokenId) | 
					
						
							| 
									
										
										
										
											2019-12-30 01:03:52 +08:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-10-19 18:31:45 +08:00
										 |  |  |         $this->updateContext($request); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-30 01:03:52 +08:00
										 |  |  |         [$user, $token] = $this->checkPermissionAndFetchUserToken($userId, $tokenId); | 
					
						
							|  |  |  |         $secret = session()->pull('api-token-secret:' . $token->id, null); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-19 22:24:48 +08:00
										 |  |  |         $this->setPageTitle(trans('settings.user_api_token')); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-30 01:03:52 +08:00
										 |  |  |         return view('users.api-tokens.edit', [ | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  |             'user'   => $user, | 
					
						
							|  |  |  |             'token'  => $token, | 
					
						
							|  |  |  |             'model'  => $token, | 
					
						
							| 
									
										
										
										
											2019-12-30 01:03:52 +08:00
										 |  |  |             'secret' => $secret, | 
					
						
							| 
									
										
										
										
											2023-10-19 18:31:45 +08:00
										 |  |  |             'back' => $this->getRedirectPath($user), | 
					
						
							| 
									
										
										
										
											2019-12-30 01:03:52 +08:00
										 |  |  |         ]); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Update the API token. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function update(Request $request, int $userId, int $tokenId) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2019-12-30 22:51:28 +08:00
										 |  |  |         $this->validate($request, [ | 
					
						
							| 
									
										
										
										
											2021-11-05 08:26:55 +08:00
										 |  |  |             'name'       => ['required', 'max:250'], | 
					
						
							|  |  |  |             'expires_at' => ['date_format:Y-m-d'], | 
					
						
							| 
									
										
										
										
											2019-12-30 01:03:52 +08:00
										 |  |  |         ]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         [$user, $token] = $this->checkPermissionAndFetchUserToken($userId, $tokenId); | 
					
						
							| 
									
										
										
										
											2019-12-30 22:51:28 +08:00
										 |  |  |         $token->fill([ | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  |             'name'       => $request->get('name'), | 
					
						
							| 
									
										
										
										
											2019-12-30 22:51:28 +08:00
										 |  |  |             'expires_at' => $request->get('expires_at') ?: ApiToken::defaultExpiry(), | 
					
						
							|  |  |  |         ])->save(); | 
					
						
							| 
									
										
										
										
											2019-12-30 01:03:52 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-21 02:53:01 +08:00
										 |  |  |         $this->logActivity(ActivityType::API_TOKEN_UPDATE, $token); | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-19 18:31:45 +08:00
										 |  |  |         return redirect($token->getUrl()); | 
					
						
							| 
									
										
										
										
											2019-12-30 01:03:52 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Show the delete view for this token. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function delete(int $userId, int $tokenId) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         [$user, $token] = $this->checkPermissionAndFetchUserToken($userId, $tokenId); | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-19 22:24:48 +08:00
										 |  |  |         $this->setPageTitle(trans('settings.user_api_token_delete')); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-30 01:03:52 +08:00
										 |  |  |         return view('users.api-tokens.delete', [ | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  |             'user'  => $user, | 
					
						
							| 
									
										
										
										
											2019-12-30 01:03:52 +08:00
										 |  |  |             'token' => $token, | 
					
						
							|  |  |  |         ]); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Destroy a token from the system. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function destroy(int $userId, int $tokenId) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         [$user, $token] = $this->checkPermissionAndFetchUserToken($userId, $tokenId); | 
					
						
							|  |  |  |         $token->delete(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-21 02:53:01 +08:00
										 |  |  |         $this->logActivity(ActivityType::API_TOKEN_DELETE, $token); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-19 18:31:45 +08:00
										 |  |  |         return redirect($this->getRedirectPath($user)); | 
					
						
							| 
									
										
										
										
											2019-12-30 01:03:52 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Check the permission for the current user and return an array | 
					
						
							|  |  |  |      * where the first item is the user in context and the second item is their | 
					
						
							|  |  |  |      * API token in context. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     protected function checkPermissionAndFetchUserToken(int $userId, int $tokenId): array | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2019-12-30 03:46:46 +08:00
										 |  |  |         $this->checkPermissionOr('users-manage', function () use ($userId) { | 
					
						
							|  |  |  |             return $userId === user()->id && userCan('access-api'); | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2019-12-30 01:03:52 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         $user = User::query()->findOrFail($userId); | 
					
						
							|  |  |  |         $token = ApiToken::query()->where('user_id', '=', $user->id)->where('id', '=', $tokenId)->firstOrFail(); | 
					
						
							| 
									
										
										
										
											2021-06-26 23:23:15 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-30 01:03:52 +08:00
										 |  |  |         return [$user, $token]; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-10-19 18:31:45 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Update the context for where the user is coming from to manage API tokens. | 
					
						
							|  |  |  |      * (Track of location for correct return redirects) | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     protected function updateContext(Request $request): void | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $context = $request->query('context'); | 
					
						
							|  |  |  |         if ($context) { | 
					
						
							|  |  |  |             session()->put('api-token-context', $context); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Get the redirect path for the current api token editing session. | 
					
						
							|  |  |  |      * Attempts to recall the context of where the user is editing from. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     protected function getRedirectPath(User $relatedUser): string | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         $context = session()->get('api-token-context'); | 
					
						
							| 
									
										
										
										
											2023-10-19 21:18:42 +08:00
										 |  |  |         if ($context === 'settings' || user()->id !== $relatedUser->id) { | 
					
						
							| 
									
										
										
										
											2023-10-19 18:31:45 +08:00
										 |  |  |             return $relatedUser->getEditUrl('#api_tokens'); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return url('/my-account/auth#api_tokens'); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-12-29 21:02:26 +08:00
										 |  |  | } |