PluginProbe
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin / 1.1.10
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin v1.1.10
1.1.10 1.1.9 1.1.8 1.1.7 1.1.6 1.1.5 1.1.4 1.1.3 1.1.2 1.1.1 1.1.0 1.0.1 1.0.0 0.9.8 0.9.7 0.9.6 0.9.4 0.9.5 0.9.3 0.9.2 0.9.1 0.9.0 0.8.9 0.8.8 0.8.7 All 34 releases
desktop-mode / apps / users / parts / permissions.php

permissions.php in OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin 1.1.10, at apps/users/parts/permissions.php

155 lines 5.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Users app — capability gates.
4 *
5 * Multi-tier gating, parallel to WordPress core's `users.php` flow:
6 *
7 * - `list_users` → REGISTER the window. Cap-only check; the
8 * opt-in toggle is JS-side.
9 * - `edit_users` → mutation quick-actions (Send password reset,
10 * Resend welcome).
11 * - `promote_users` → bulk role-change action; per-target gated
12 * through {@see openstation_users_window_assignable_roles()}.
13 * - `create_users` → "Add new user" tab.
14 * - `delete_users` → bulk-delete (single-site).
15 * - `remove_users` → bulk-remove (multisite — removes from current site,
16 * leaves the network user record alone).
17 *
18 * UI-side gating is purely UX polish — the actions and the REST
19 * routes in `rest.php` re-validate every cap and every per-target
20 * permission before mutating anything.
21 *
22 * @package OpenStation
23 */
24
25 defined( 'ABSPATH' ) || exit;
26
27 /**
28 * Whether the user is eligible to have the Users window registered.
29 *
30 * @param int|null $user_id Optional. Defaults to `get_current_user_id()`.
31 * @return bool
32 */
33 function openstation_users_window_user_can_register( $user_id = null ) {
34 $user_id = null === $user_id ? get_current_user_id() : (int) $user_id;
35 $can = $user_id > 0 && user_can( $user_id, 'list_users' );
36
37 /**
38 * Filter whether the current user can have the Users window
39 * registered. This is the boot-time check; runtime "should the
40 * dock click use the native window?" is the JS-side
41 * `nativeUsersEnabled` flag.
42 *
43 * @param bool $can Default: `list_users` capability.
44 * @param int $user_id User being checked.
45 */
46 return (bool) apply_filters(
47 'openstation_users_window_user_can_register',
48 $can,
49 $user_id
50 );
51 }
52
53 /**
54 * Combined cap-and-opt-in check. Used by callers that want the
55 * combined answer (e.g. analytics, an arrange-menu entry).
56 *
57 * @param int|null $user_id Optional.
58 * @return bool
59 */
60 function openstation_users_window_user_can_use( $user_id = null ) {
61 $user_id = null === $user_id ? get_current_user_id() : (int) $user_id;
62
63 $cap_ok = openstation_users_window_user_can_register( $user_id );
64
65 $opt_in = false;
66 if ( $cap_ok && function_exists( 'openstation_get_os_settings' ) ) {
67 $settings = openstation_get_os_settings( $user_id );
68 $opt_in = ! empty( $settings['nativeUsersEnabled'] );
69 }
70
71 $can = $cap_ok && $opt_in;
72
73 /**
74 * Filter whether the current user has opted into the native Users
75 * experience.
76 *
77 * @param bool $can Default gate result.
78 * @param int $user_id User being checked.
79 */
80 return (bool) apply_filters( 'openstation_users_window_user_can_use', $can, $user_id );
81 }
82
83 /**
84 * Resolve the role slugs the current viewer is allowed to assign to
85 * the given target user.
86 *
87 * Honors core's `editable_roles` filter. Note core's default returns
88 * EVERY registered role (administrator included) to any user with
89 * `promote_users` — there is no built-in capability-subset hierarchy
90 * in core. Sites wanting stricter rules must filter `editable_roles`
91 * or `openstation_users_window_assignable_roles` below. We compute
92 * the list server-side and surface it on the row so the UI can hide
93 * options the viewer can't apply; the mutation paths call this same
94 * filtered helper and reject anything outside it.
95 *
96 * @param int $viewer_id Requesting user.
97 * @param int $target_id Target user (optional — used by filters).
98 * @return string[] Role slugs the viewer can assign to the target.
99 */
100 function openstation_users_window_assignable_roles( $viewer_id, $target_id = 0 ) {
101 $viewer_id = (int) $viewer_id;
102 if ( $viewer_id <= 0 || ! user_can( $viewer_id, 'promote_users' ) ) {
103 return array();
104 }
105
106 // Switch to the viewer's perspective so `current_user_can` and
107 // `get_editable_roles` evaluate against their caps, not whoever
108 // happens to be acting at REST-init time.
109 $prev_user = get_current_user_id();
110 $switched = false;
111 if ( $prev_user !== $viewer_id ) {
112 wp_set_current_user( $viewer_id );
113 $switched = true;
114 }
115
116 // `get_editable_roles()` lives in wp-admin/includes/user.php
117 // which is NOT auto-loaded by the time `init` fires.
118 if ( ! function_exists( 'get_editable_roles' ) ) {
119 require_once ABSPATH . 'wp-admin/includes/user.php';
120 }
121 $editable = function_exists( 'get_editable_roles' )
122 ? (array) get_editable_roles()
123 : array();
124
125 if ( $switched ) {
126 wp_set_current_user( $prev_user );
127 }
128
129 $slugs = array_keys( $editable );
130
131 /**
132 * Filter the role slugs assignable by `$viewer_id` to `$target_id`.
133 *
134 * Use this to LOCK DOWN role assignment further (e.g. "site
135 * managers can't promote anyone to administrator even if core
136 * would let them"). Returning an empty array fully disables role
137 * mutation for the viewer.
138 *
139 * Returning a SUPERSET widens the mutation paths too — the
140 * bulk-role and the create-user paths validate the requested
141 * role against this same filtered list, so only add roles you
142 * genuinely intend to make assignable.
143 *
144 * @param string[] $slugs Default role slug list.
145 * @param int $viewer_id
146 * @param int $target_id
147 */
148 return (array) apply_filters(
149 'openstation_users_window_assignable_roles',
150 $slugs,
151 $viewer_id,
152 $target_id
153 );
154 }
155