]> BookStack Code Mirror - bookstack/blob - app/Users/Controllers/RoleApiController.php
Merge branch 'v25-07' into development
[bookstack] / app / Users / Controllers / RoleApiController.php
1 <?php
2
3 namespace BookStack\Users\Controllers;
4
5 use BookStack\Http\ApiController;
6 use BookStack\Permissions\Permission;
7 use BookStack\Permissions\PermissionsRepo;
8 use BookStack\Users\Models\Role;
9 use Illuminate\Http\Request;
10 use Illuminate\Support\Facades\DB;
11
12 class RoleApiController extends ApiController
13 {
14     protected array $fieldsToExpose = [
15         'display_name', 'description', 'mfa_enforced', 'external_auth_id', 'created_at', 'updated_at',
16     ];
17
18     protected array $rules = [
19         'create' => [
20             'display_name'  => ['required', 'string', 'min:3', 'max:180'],
21             'description'   => ['string', 'max:180'],
22             'mfa_enforced'  => ['boolean'],
23             'external_auth_id' => ['string', 'max:180'],
24             'permissions'   => ['array'],
25             'permissions.*' => ['string'],
26         ],
27         'update' => [
28             'display_name'  => ['string', 'min:3', 'max:180'],
29             'description'   => ['string', 'max:180'],
30             'mfa_enforced'  => ['boolean'],
31             'external_auth_id' => ['string', 'max:180'],
32             'permissions'   => ['array'],
33             'permissions.*' => ['string'],
34         ]
35     ];
36
37     public function __construct(
38         protected PermissionsRepo $permissionsRepo
39     ) {
40         // Checks for all endpoints in this controller
41         $this->middleware(function ($request, $next) {
42             $this->checkPermission(Permission::UserRolesManage);
43
44             return $next($request);
45         });
46     }
47
48     /**
49      * Get a listing of roles in the system.
50      * Requires permission to manage roles.
51      */
52     public function list()
53     {
54         $roles = Role::query()->select(['*'])
55             ->withCount(['users', 'permissions']);
56
57         return $this->apiListingResponse($roles, [
58             ...$this->fieldsToExpose,
59             'permissions_count',
60             'users_count',
61         ]);
62     }
63
64     /**
65      * Create a new role in the system.
66      * Permissions should be provided as an array of permission name strings.
67      * Requires permission to manage roles.
68      */
69     public function create(Request $request)
70     {
71         $data = $this->validate($request, $this->rules()['create']);
72
73         $role = null;
74         DB::transaction(function () use ($data, &$role) {
75             $role = $this->permissionsRepo->saveNewRole($data);
76         });
77
78         $this->singleFormatter($role);
79
80         return response()->json($role);
81     }
82
83     /**
84      * View the details of a single role.
85      * Provides the permissions and a high-level list of the users assigned.
86      * Requires permission to manage roles.
87      */
88     public function read(string $id)
89     {
90         $role = $this->permissionsRepo->getRoleById($id);
91         $this->singleFormatter($role);
92
93         return response()->json($role);
94     }
95
96     /**
97      * Update an existing role in the system.
98      * Permissions should be provided as an array of permission name strings.
99      * An empty "permissions" array would clear granted permissions.
100      * In many cases, where permissions are changed, you'll want to fetch the existing
101      * permissions and then modify before providing in your update request.
102      * Requires permission to manage roles.
103      */
104     public function update(Request $request, string $id)
105     {
106         $data = $this->validate($request, $this->rules()['update']);
107         $role = $this->permissionsRepo->updateRole($id, $data);
108
109         $this->singleFormatter($role);
110
111         return response()->json($role);
112     }
113
114     /**
115      * Delete a role from the system.
116      * Requires permission to manage roles.
117      */
118     public function delete(string $id)
119     {
120         $this->permissionsRepo->deleteRole(intval($id));
121
122         return response('', 204);
123     }
124
125     /**
126      * Format the given role model for a single-result display.
127      */
128     protected function singleFormatter(Role $role): void
129     {
130         $role->load('users:id,name,slug');
131         $role->unsetRelation('permissions');
132         $role->setAttribute('permissions', $role->permissions()->orderBy('name', 'asc')->pluck('name'));
133         $role->makeVisible(['users', 'permissions']);
134     }
135 }