PluginProbe ʕ •ᴥ•ʔ
Advanced Access Manager – Access Governance for WordPress / trunk
Advanced Access Manager – Access Governance for WordPress vtrunk
6.8.4 6.8.5 6.9.0 6.9.1 6.9.10 6.9.11 6.9.12 6.9.13 6.9.14 6.9.15 6.9.16 6.9.17 6.9.18 6.9.19 6.9.2 6.9.20 6.9.21 6.9.22 6.9.23 6.9.24 6.9.25 6.9.26 6.9.27 6.9.28 6.9.29 6.9.3 6.9.30 6.9.31 6.9.32 6.9.33 6.9.34 6.9.35 6.9.36 6.9.37 6.9.38 6.9.39 6.9.4 6.9.41 6.9.42 6.9.43 6.9.44 6.9.45 6.9.46 6.9.47 6.9.48 6.9.49 6.9.5 6.9.51 6.9.6 6.9.7 6.9.8 6.9.9 7.0.0 7.0.0-alpha.6 7.0.0-alpha.7 7.0.0-beta.1 7.0.0-rc1 7.0.0-rc2 7.0.0-rc3 7.0.1 7.0.10 7.0.11 7.0.2 7.0.3 7.0.4 7.0.5 7.0.6 7.0.7 7.0.8 7.0.9 7.1.0 7.1.1 trunk 3.0 4.0 4.0.1 4.1 4.2 4.3 4.4 4.4.1 4.5 4.6 4.6.1 4.6.2 4.7 4.7.1 4.7.2 4.7.5 4.7.6 4.8 4.8.1 4.9 4.9.1 4.9.2 4.9.3 4.9.4 4.9.5 4.9.5.1 4.9.5.2 5.0 5.0.1 5.0.2 5.0.3 5.0.4 5.0.5 5.0.6 5.0.7 5.0.8 5.1 5.1.1 5.10 5.11 5.2 5.2.1 5.2.5 5.2.6 5.2.7 5.3 5.3.1 5.3.2 5.3.3 5.3.4 5.3.5 5.4 5.4.1 5.4.2 5.4.3 5.4.3.1 5.4.3.2 5.5 5.5.1 5.5.2 5.6 5.6.1 5.6.1.1 5.7 5.7.1 5.7.2 5.7.3 5.8 5.8.1 5.8.2 5.8.3 5.9 5.9.1 5.9.1.1 5.9.2 5.9.2.1 5.9.3 5.9.4 5.9.5 5.9.6 5.9.6.1 5.9.6.2 5.9.6.3 5.9.7 5.9.7.1 5.9.7.2 5.9.7.3 5.9.8 5.9.8.1 5.9.9 5.9.9.1 6.0.0 6.0.1 6.0.2 6.0.3 6.0.4 6.0.5 6.1.0 6.1.1 6.2.0 6.2.1 6.2.2 6.3.0 6.3.1 6.3.2 6.3.3 6.4.0 6.4.1 6.4.2 6.4.3 6.5.0 6.5.1 6.5.2 6.5.3 6.5.4 6.6.0 6.6.1 6.6.2 6.6.3 6.6.4 6.7.0 6.7.1 6.7.2 6.7.3 6.7.4 6.7.5 6.7.6 6.7.7 6.7.8 6.7.9 6.8.0 6.8.1 6.8.2 6.8.3
advanced-access-manager / application / Restful / Users.php
advanced-access-manager / application / Restful Last commit date
AccessDeniedRedirect.php 1 year ago AdminToolbar.php 1 year ago ApiRoute.php 1 year ago BackendMenu.php 1 year ago BackwardCompatibility.php 1 year ago Capability.php 1 year ago Configs.php 5 months ago Content.php 1 year ago Identity.php 1 year ago Jwt.php 5 months ago LoginRedirect.php 1 year ago LogoutRedirect.php 1 year ago Metabox.php 1 year ago Mu.php 1 year ago NotFoundRedirect.php 1 year ago Policies.php 1 year ago Roles.php 1 year ago SecureLogin.php 1 year ago SecurityAudit.php 1 year ago ServiceTrait.php 1 year ago Settings.php 1 year ago Urls.php 1 year ago Users.php 1 year ago Widgets.php 1 year ago
Users.php
524 lines
1 <?php
2
3 /**
4 * ======================================================================
5 * LICENSE: This file is subject to the terms and conditions defined in *
6 * file 'license.txt', which is part of this source code package. *
7 * ======================================================================
8 */
9
10 /**
11 * RESTful API for user management
12 *
13 * @package AAM
14 * @version 7.0.0
15 */
16 class AAM_Restful_Users
17 {
18
19 use AAM_Restful_ServiceTrait;
20
21 /**
22 * Necessary permissions to access endpoint
23 *
24 * @version 7.0.0
25 */
26 const PERMISSIONS = [
27 'aam_manager',
28 'aam_manage_users'
29 ];
30
31 /**
32 * Constructor
33 *
34 * @return void
35 * @access protected
36 *
37 * @version 7.0.0
38 */
39 protected function __construct()
40 {
41 // Register API endpoint
42 add_action('rest_api_init', function() {
43 // Get the list of users
44 $this->_register_route('/users', [
45 'methods' => WP_REST_Server::READABLE,
46 'callback' => array($this, 'get_users'),
47 'args' => array(
48 'fields' => array(
49 'description' => 'List of additional fields to return',
50 'type' => 'string',
51 'validate_callback' => function ($value) {
52 return $this->_validate_fields_input($value);
53 }
54 ),
55 'search' => array(
56 'description' => 'Search string',
57 'type' => 'string'
58 ),
59 'offset' => array(
60 'description' => 'Pagination offset',
61 'type' => 'number',
62 'default' => 0
63 ),
64 'per_page' => array(
65 'description' => 'Pagination limit per page',
66 'type' => 'number',
67 'default' => 10
68 ),
69 'role' => array(
70 'description' => 'Return users only for given role',
71 'type' => 'string'
72 )
73 )
74 ], self::PERMISSIONS, false);
75
76 // Get a specific user
77 $this->_register_route('/user/(?P<id>[\d]+)', [
78 'methods' => WP_REST_Server::READABLE,
79 'callback' => array($this, 'get_user'),
80 'args' => array(
81 'id' => array(
82 'description' => 'Unique user id',
83 'type' => 'number',
84 'validate_callback' => function ($value, $request) {
85 return $this->_validate_user_accessibility(
86 $value, $request->get_method()
87 );
88 }
89 ),
90 'fields' => array(
91 'description' => 'List of additional fields to return',
92 'type' => 'string',
93 'validate_callback' => function ($value) {
94 return $this->_validate_fields_input($value);
95 }
96 )
97 )
98 ], self::PERMISSIONS, false);
99
100 // Update existing user
101 $this->_register_route('/user/(?P<id>[\d]+)', [
102 'methods' => WP_REST_Server::EDITABLE,
103 'callback' => array($this, 'update_user'),
104 'args' => array(
105 'id' => array(
106 'description' => 'Unique user id',
107 'type' => 'number',
108 'validate_callback' => function ($value, $request) {
109 return $this->_validate_user_accessibility(
110 $value, $request->get_method()
111 );
112 }
113 ),
114 'status' => array(
115 'description' => 'User status',
116 'type' => 'string',
117 'enum' => [
118 'active',
119 'inactive'
120 ]
121 ),
122 'expiration' => array(
123 'description' => 'User access expiration date-time & trigger',
124 'type' => 'object',
125 'properties' => [
126 'expires_at' => [
127 'type' => 'string',
128 'format' => 'date-time',
129 'required' => true
130 ],
131 'trigger' => [
132 'type' => ['string', 'object'],
133 'required' => true,
134 'default' => 'logout',
135 'properties' => [
136 'type' => [
137 'type' => 'string',
138 'required' => true,
139 'enum' => AAM_Framework_Proxy_User::ALLOWED_EXPIRATION_TRIGGERS
140 ],
141 'role' => [
142 'type' => 'string',
143 'validate_callback' => function ($value) {
144 return $this->_validate_role_accessibility(
145 $value
146 );
147 }
148 ]
149 ]
150 ]
151 ]
152 ),
153 'add_capabilities' => array(
154 'description' => 'List of capabilities to assign',
155 'type' => 'array',
156 'items' => array(
157 'type' => 'string'
158 )
159 ),
160 'deprive_capabilities' => array(
161 'description' => 'List of capabilities to deprive',
162 'type' => 'array',
163 'items' => [
164 'type' => 'string'
165 ]
166 ),
167 'remove_capabilities' => array(
168 'description' => 'List of capabilities to remove',
169 'type' => 'array',
170 'items' => array(
171 'type' => 'string'
172 )
173 ),
174 'fields' => array(
175 'description' => 'List of additional fields to return',
176 'type' => 'string',
177 'validate_callback' => function ($value) {
178 return $this->_validate_fields_input($value);
179 }
180 )
181 )
182 ], self::PERMISSIONS, false);
183
184 // Reset existing user settings
185 $this->_register_route('/user/(?P<id>[\d]+)', [
186 'methods' => WP_REST_Server::DELETABLE,
187 'callback' => array($this, 'reset_user'),
188 'args' => array(
189 'id' => array(
190 'description' => 'Unique user id',
191 'type' => 'number',
192 'validate_callback' => function ($value, $request) {
193 return $this->_validate_user_accessibility(
194 $value, $request->get_method()
195 );
196 }
197 ),
198 'fields' => array(
199 'description' => 'List of additional fields to return',
200 'type' => 'string',
201 'validate_callback' => function ($value) {
202 return $this->_validate_fields_input($value);
203 }
204 )
205 )
206 ], self::PERMISSIONS, false);
207 });
208 }
209
210 /**
211 * Get a paginated list of users
212 *
213 * @param WP_REST_Request $request
214 *
215 * @return WP_REST_Response
216 * @access public
217 *
218 * @version 7.0.0
219 */
220 public function get_users(WP_REST_Request $request)
221 {
222 try {
223 // Prepare the list of filters
224 $filters = [
225 'number' => $request->get_param('per_page'),
226 'search' => $request->get_param('search'),
227 'offset' => $request->get_param('offset')
228 ];
229
230 $role_filter = $request->get_param('role');
231
232 if (!empty($role_filter)) {
233 $filters['role__in'] = $role_filter;
234 }
235
236 // Modify the search, if not empty
237 if (!empty($filters['search'])) {
238 $filters['search'] .= '*';
239 }
240
241 // Iterate over the list of all users and enrich it with additional
242 // attributes
243 $fields = $this->_determine_additional_fields($request);
244 $result = [
245 'list' => [],
246 'summary' => [
247 'total_count' => AAM::api()->users->get_user_count(),
248 'filtered_count' => AAM::api()->users->get_user_count($filters)
249 ]
250 ];
251
252 foreach(AAM::api()->users->get_users($filters) as $user) {
253 array_push($result['list'], $this->_prepare_output($user, $fields));
254 }
255 } catch (Exception $e) {
256 $result = $this->_prepare_error_response($e);
257 }
258
259 return rest_ensure_response($result);
260 }
261
262 /**
263 * Get a user
264 *
265 * @param WP_REST_Request $request
266 *
267 * @return WP_REST_Response
268 * @access public
269 *
270 * @version 7.0.0
271 */
272 public function get_user(WP_REST_Request $request)
273 {
274 try {
275 $result = $this->_prepare_output(
276 AAM::api()->users->get_user($request->get_param('id')),
277 $this->_determine_additional_fields($request)
278 );
279 } catch (Exception $e) {
280 $result = $this->_prepare_error_response($e);
281 }
282
283 return rest_ensure_response($result);
284 }
285
286 /**
287 * Update user
288 *
289 * @param WP_REST_Request $request
290 *
291 * @return WP_REST_Response
292 * @access public
293 *
294 * @version 7.0.0
295 */
296 public function update_user(WP_REST_Request $request)
297 {
298 try {
299 $expiration = $request->get_param('expiration');
300 $status = $request->get_param('status');
301 $add_caps = $request->get_param('add_capabilities');
302 $remove_caps = $request->get_param('remove_capabilities');
303 $deprive_caps = $request->get_param('deprive_capabilities');
304 $data = [];
305
306 if (!empty($expiration)) {
307 $data['expiration'] = $expiration;
308 }
309
310 if (!empty($status)) {
311 $data['status'] = $status;
312 }
313
314 if (!empty($add_caps)) {
315 $data['add_caps'] = $add_caps;
316 }
317
318 if (!empty($remove_caps)) {
319 $data['remove_caps'] = $remove_caps;
320 }
321
322 if (!empty($deprive_caps)) {
323 $data['deprive_caps'] = $deprive_caps;
324 }
325
326 $user = AAM::api()->users->get_user($request->get_param('id'));
327
328 // Update user data
329 $user->update($data);
330
331 $result = $this->_prepare_output(
332 $user, $this->_determine_additional_fields($request)
333 );
334 } catch (Exception $e) {
335 $result = $this->_prepare_error_response($e);
336 }
337
338 return rest_ensure_response($result);
339 }
340
341 /**
342 * Reset user
343 *
344 * @param WP_REST_Request $request
345 *
346 * @return WP_REST_Response
347 * @access public
348 *
349 * @version 7.0.0
350 */
351 public function reset_user(WP_REST_Request $request)
352 {
353 try {
354 $user = AAM::api()->users->get_user($request->get_param('id'));
355
356 // Reset user
357 $user->reset();
358
359 $result = $this->_prepare_output(
360 $user, $this->_determine_additional_fields($request)
361 );
362 } catch (Exception $e) {
363 $result = $this->_prepare_error_response($e);
364 }
365
366 return rest_ensure_response($result);
367 }
368
369 /**
370 * Validate the input field "fields"
371 *
372 * @param string|null $value Input value
373 *
374 * @return bool|WP_Error
375 * @access private
376 *
377 * @version 7.0.0
378 */
379 private function _validate_fields_input($value)
380 {
381 $response = true;
382
383 if (is_string($value) && strlen($value) > 0) {
384 $invalid_fields = [];
385
386 foreach(explode(',', $value) as $field) {
387 if (strlen(sanitize_key($field)) !== strlen($field)) {
388 $invalid_fields[] = $field;
389 }
390 }
391
392 if (count($invalid_fields) > 0) {
393 $response = new WP_Error(
394 'rest_invalid_param',
395 sprintf(
396 'Invalid fields: %s',
397 implode(', ', $invalid_fields)
398 ),
399 array('status' => 400)
400 );
401 }
402 }
403
404 return $response;
405 }
406
407 /**
408 * Prepare user data
409 *
410 * @param AAM_Framework_AccessLevel_User $user
411 * @param array $fields
412 *
413 * @return array
414 * @access private
415 *
416 * @version 7.0.0
417 */
418 private function _prepare_output($user, $fields = [])
419 {
420 // Prepare user's display name
421 if ($user->first_name && $user->last_name) {
422 $display_name = sprintf('%s %s', $user->first_name, $user->last_name);
423 } elseif ( $user->first_name ) {
424 $display_name = $user->first_name;
425 } elseif ( $user->last_name ) {
426 $display_name = $user->last_name;
427 } else {
428 $display_name = $user->user_email;
429 }
430
431 $item = [
432 'id' => $user->ID,
433 'user_login' => $user->user_login,
434 'display_name' => $display_name,
435 'user_level' => intval($user->user_level),
436 'roles' => $this->_prepare_user_roles($user->roles),
437 'assigned_capabilities' => $user->caps,
438 'all_capabilities' => $user->allcaps,
439 'status' => $user->status
440 ];
441
442 $expires_at = $user->expires_at;
443
444 if (!empty($expires_at)) {
445 $item['expiration'] = [
446 'expires_at' => $expires_at->format(DateTime::RFC3339),
447 'expires_at_timestamp' => $expires_at->getTimestamp(),
448 'trigger' => $user->expiration_trigger
449 ];
450 }
451
452 // Addition list of actions that current user can perform upon given user
453 $item['permissions'] = [];
454
455 if (current_user_can('edit_user', $item['id'])) {
456 array_push($item['permissions'], 'allow_manage', 'allow_edit');
457
458 if(current_user_can('aam_toggle_users')) {
459 array_push(
460 $item['permissions'],
461 $item['status'] === 'inactive' ? 'allow_unlock' : 'allow_lock'
462 );
463 }
464 }
465
466 $result = [];
467
468 foreach($fields as $field) {
469 if (!isset($result[$field]) && isset($item[$field])) {
470 $result[$field] = $item[$field];
471 }
472 }
473
474 return apply_filters(
475 'aam_rest_user_output_filter', $result, $user, $fields
476 );
477 }
478
479 /**
480 * Prepare list of roles
481 *
482 * @param array $roles
483 *
484 * @return array
485 * @access private
486 *
487 * @version 7.0.0
488 */
489 private function _prepare_user_roles($roles)
490 {
491 $response = [];
492
493 $names = wp_roles()->get_names();
494
495 if (is_array($roles)) {
496 foreach ($roles as $role) {
497 if (array_key_exists($role, $names)) {
498 $response[] = translate_user_role($names[$role]);
499 }
500 }
501 }
502
503 return $response;
504 }
505
506 /**
507 * Determine list of additional fields to return
508 *
509 * @param WP_REST_Request $request
510 *
511 * @return array
512 * @access private
513 *
514 * @version 7.0.0
515 */
516 private function _determine_additional_fields(WP_REST_Request $request)
517 {
518 $fields = $request->get_param('fields');
519 $fields = !empty($fields) ? wp_parse_list($fields) : [];
520
521 return array_unique(array_merge([ 'id' ], $fields));
522 }
523
524 }