PluginProbe
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin / 1.1.4
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin v1.1.4
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 / includes / users-window / permissions.php

permissions.php in OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin 1.1.4, at includes/users-window/permissions.php

160 lines 5.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * OpenStation — Native Users Window: 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" toolbar button.
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 REST routes in `rest.php`
19 * re-validate every cap and every per-target permission before
20 * 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 REST mutation routes call this
94 * same 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 (the hook
118 // our window registers on). Without this require_once the
119 // function doesn't exist, the array comes back empty, and the
120 // admin sees only the site's default_role ("subscriber") in
121 // the role dropdown — exactly the symptom that surfaced once
122 // real-world testing started.
123 if ( ! function_exists( 'get_editable_roles' ) ) {
124 require_once ABSPATH . 'wp-admin/includes/user.php';
125 }
126 $editable = function_exists( 'get_editable_roles' )
127 ? (array) get_editable_roles()
128 : array();
129
130 if ( $switched ) {
131 wp_set_current_user( $prev_user );
132 }
133
134 $slugs = array_keys( $editable );
135
136 /**
137 * Filter the role slugs assignable by `$viewer_id` to `$target_id`.
138 *
139 * Use this to LOCK DOWN role assignment further (e.g. "site
140 * managers can't promote anyone to administrator even if core
141 * would let them"). Returning an empty array fully disables role
142 * mutation for the viewer.
143 *
144 * Returning a SUPERSET widens the REST endpoints too — both the
145 * bulk-role route and the create-user route validate the requested
146 * role against this same filtered list (see `rest.php`), so only
147 * add roles you genuinely intend to make assignable.
148 *
149 * @param string[] $slugs Default role slug list.
150 * @param int $viewer_id
151 * @param int $target_id
152 */
153 return (array) apply_filters(
154 'openstation_users_window_assignable_roles',
155 $slugs,
156 $viewer_id,
157 $target_id
158 );
159 }
160