authorize('view', $user); return new UserManagerResource($user); } /** * Reset user's password * * @return \Illuminate\Http\JsonResponse */ public function resetPassword(Request $request, User $user) { Log::info(sprintf('Password reset for User ID #%s requested by User ID #%s', $user->id, $request->user()->id)); $this->authorize('update', $user); $credentials = [ 'token' => $this->broker()->createToken($user), 'email' => $user->email, 'password' => $user->password, ]; $response = $this->broker()->reset( $credentials, function ($user) { $user->resetPassword(); $user->save(); } ); if ($response == Password::PASSWORD_RESET) { Log::info(sprintf('Temporary password set for User ID #%s', $user->id)); $response = $this->broker()->sendResetLink( ['email' => $credentials['email']] ); } else { return response()->json([ 'message' => 'bad request', 'reason' => is_string($response) ? __($response) : __('errors.no_pwd_reset_for_this_user_type'), ], 400); } return $response == Password::RESET_LINK_SENT ? new UserManagerResource($user) : response()->json([ 'message' => 'bad request', 'reason' => __($response), ], 400); } /** * Store a newly created user in storage. * * @return \Illuminate\Http\JsonResponse */ public function store(UserManagerStoreRequest $request) { $this->authorize('create', User::class); $validated = $request->validated(); $user = User::create([ 'name' => $validated['name'], 'email' => $validated['email'], 'password' => Hash::make($validated['password']), ]); Log::info(sprintf('User ID #%s created by user ID #%s', $user->id, $request->user()->id)); if ($validated['is_admin']) { if ($user->promoteToAdministrator()) { $user->save(); Log::notice(sprintf('User ID #%s set as administrator at creation by user ID #%s', $user->id, $request->user()->id)); } } $user->refresh(); return (new UserManagerResource($user)) ->response() ->setStatusCode(201); } /** * Purge user's PATs. * * @return \Illuminate\Http\JsonResponse */ public function revokePATs(Request $request, User $user, TokenRepository $tokenRepository) { Log::info(sprintf('Deletion of all personal access tokens for User ID #%s requested by User ID #%s', $user->id, $request->user()->id)); $this->authorize('update', $user); $tokens = $tokenRepository->forUser($user->getAuthIdentifier()); $tokens->load('client')->filter(function ($token) { return $token->client->personal_access_client && ! $token->revoked; })->each(function ($token) { $token->revoke(); }); Log::info(sprintf('All personal access tokens for User ID #%s have been revoked', $user->id)); return response()->json(null, 204); } /** * Purge user's webauthn credentials. * * @return \Illuminate\Http\JsonResponse */ public function revokeWebauthnCredentials(Request $request, User $user) { Log::info(sprintf('Deletion of all security devices for User ID #%s requested by User ID #%s', $user->id, $request->user()->id)); $this->authorize('update', $user); $user->flushCredentials(); // WebauthnOnly user options need to be reset to prevent impossible login when // no more registered device exists. // See #110 if (blank($user->webAuthnCredentials()->WhereEnabled()->get())) { $user['preferences->useWebauthnOnly'] = false; $user->save(); Log::notice(sprintf('No more Webauthn credential for user ID #%s, useWebauthnOnly user preference reset to false', $user->id)); } Log::info(sprintf('All security devices for User ID #%s have been revoked', $user->id)); return response()->json(null, 204); } /** * Remove the specified user from storage. * * @return \Illuminate\Http\JsonResponse */ public function destroy(Request $request, User $user) { $this->authorize('delete', $user); // This will delete the user and all its 2FAs & Groups thanks to the onCascadeDelete constrains. // Deletion will not be done (and returns False) if the user is the only existing admin (see UserObserver clas) return $user->delete() === false ? response()->json([ 'message' => __('errors.cannot_delete_the_only_admin'), ], 403) : response()->json(null, 204); } /** * Promote (or demote) a user * * @return \App\Api\v1\Resources\UserManagerResource */ public function promote(UserManagerPromoteRequest $request, User $user) { $this->authorize('promote', $user); if ($user->promoteToAdministrator($request->validated('is_admin'))) { $user->save(); Log::info(sprintf('User ID #%s set is_admin=%s for User ID #%s', $request->user()->id, $user->isAdministrator(), $user->id)); return new UserManagerResource($user); } return response()->json([ 'message' => __('errors.cannot_demote_the_only_admin'), ], 403); } /** * Get the user's authentication logs * * @return \Illuminate\Http\JsonResponse */ public function authentications(Request $request, User $user) { $this->authorize('view', $user); $validated = $this->validate($request, [ 'limit' => 'sometimes|numeric', ]); $authentications = $request->has('limit') ? $user->authentications->take($validated['limit']) : $user->authentications; return UserAuthentication::collection($authentications); } /** * Get the broker to be used during password reset. * * @return \Illuminate\Contracts\Auth\PasswordBroker|\Illuminate\Auth\Passwords\PasswordBroker */ protected function broker() { return Password::broker(); } }