X-Git-Url: http://source.bookstackapp.com/bookstack/blobdiff_plain/d089623aac6b39641a0ff610c124cb3a01609efd..refs/pull/3770/head:/app/Http/Controllers/Api/UserApiController.php diff --git a/app/Http/Controllers/Api/UserApiController.php b/app/Http/Controllers/Api/UserApiController.php index ed1a4b13d..64e9d732d 100644 --- a/app/Http/Controllers/Api/UserApiController.php +++ b/app/Http/Controllers/Api/UserApiController.php @@ -4,26 +4,66 @@ namespace BookStack\Http\Controllers\Api; use BookStack\Auth\User; use BookStack\Auth\UserRepo; +use BookStack\Exceptions\UserUpdateException; use Closure; +use Illuminate\Http\Request; +use Illuminate\Support\Facades\DB; +use Illuminate\Validation\Rules\Password; +use Illuminate\Validation\Rules\Unique; class UserApiController extends ApiController { protected $userRepo; protected $fieldsToExpose = [ - 'email', 'created_at', 'updated_at', 'last_activity_at', 'external_auth_id' - ]; - - protected $rules = [ - 'create' => [ - ], - 'update' => [ - ], + 'email', 'created_at', 'updated_at', 'last_activity_at', 'external_auth_id', ]; public function __construct(UserRepo $userRepo) { $this->userRepo = $userRepo; + + // Checks for all endpoints in this controller + $this->middleware(function ($request, $next) { + $this->checkPermission('users-manage'); + $this->preventAccessInDemoMode(); + + return $next($request); + }); + } + + protected function rules(int $userId = null): array + { + return [ + 'create' => [ + 'name' => ['required', 'min:2', 'max:100'], + 'email' => [ + 'required', 'min:2', 'email', new Unique('users', 'email'), + ], + 'external_auth_id' => ['string'], + 'language' => ['string', 'max:15', 'alpha_dash'], + 'password' => [Password::default()], + 'roles' => ['array'], + 'roles.*' => ['integer'], + 'send_invite' => ['boolean'], + ], + 'update' => [ + 'name' => ['min:2', 'max:100'], + 'email' => [ + 'min:2', + 'email', + (new Unique('users', 'email'))->ignore($userId ?? null), + ], + 'external_auth_id' => ['string'], + 'language' => ['string', 'max:15', 'alpha_dash'], + 'password' => [Password::default()], + 'roles' => ['array'], + 'roles.*' => ['integer'], + ], + 'delete' => [ + 'migrate_ownership_id' => ['integer', 'exists:users,id'], + ], + ]; } /** @@ -32,9 +72,9 @@ class UserApiController extends ApiController */ public function list() { - $this->checkPermission('users-manage'); - - $users = $this->userRepo->getApiUsersBuilder(); + $users = User::query()->select(['*']) + ->scopes('withLastActivityAt') + ->with(['avatar']); return $this->apiListingResponse($users, [ 'id', 'name', 'slug', 'email', 'external_auth_id', @@ -42,18 +82,67 @@ class UserApiController extends ApiController ], [Closure::fromCallable([$this, 'listFormatter'])]); } + /** + * Create a new user in the system. + * Requires permission to manage users. + */ + public function create(Request $request) + { + $data = $this->validate($request, $this->rules()['create']); + $sendInvite = ($data['send_invite'] ?? false) === true; + + $user = null; + DB::transaction(function () use ($data, $sendInvite, &$user) { + $user = $this->userRepo->create($data, $sendInvite); + }); + + $this->singleFormatter($user); + + return response()->json($user); + } + /** * View the details of a single user. * Requires permission to manage users. */ public function read(string $id) { - $this->checkPermission('users-manage'); + $user = $this->userRepo->getById($id); + $this->singleFormatter($user); + + return response()->json($user); + } + + /** + * Update an existing user in the system. + * Requires permission to manage users. + * + * @throws UserUpdateException + */ + public function update(Request $request, string $id) + { + $data = $this->validate($request, $this->rules($id)['update']); + $user = $this->userRepo->getById($id); + $this->userRepo->update($user, $data, userCan('users-manage')); + $this->singleFormatter($user); + + return response()->json($user); + } + + /** + * Delete a user from the system. + * Can optionally accept a user id via `migrate_ownership_id` to indicate + * who should be the new owner of their related content. + * Requires permission to manage users. + */ + public function delete(Request $request, string $id) + { + $user = $this->userRepo->getById($id); + $newOwnerId = $request->get('migrate_ownership_id', null); - $singleUser = $this->userRepo->getById($id); - $this->singleFormatter($singleUser); + $this->userRepo->destroy($user, $newOwnerId); - return response()->json($singleUser); + return response('', 204); } /**