PluginProbe
UpStream: a Project Management Plugin for WordPress / trunk
UpStream: a Project Management Plugin for WordPress vtrunk
trunk 1.39.0 1.39.1 1.39.2 1.39.3 2.0.7 2.1.0
upstream / includes / up-permissions-functions.php

up-permissions-functions.php in UpStream: a Project Management Plugin for WordPress trunk, at includes/up-permissions-functions.php

453 lines 13.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Upstream permission functions
4 *
5 * @package UpStream
6 */
7
8 // Exit if accessed directly.
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit;
11 }
12
13 /************************* BEGIN UPSTREAM V2 FUNCTIONALITY */
14
15
16 if ( ! defined( 'UPSTREAM_ITEM_TYPE_PROJECT' ) ) {
17
18 define( 'UPSTREAM_ITEM_TYPE_PROJECT', 'project' );
19 define( 'UPSTREAM_ITEM_TYPE_MILESTONE', 'milestone' );
20 define( 'UPSTREAM_ITEM_TYPE_CLIENT', 'client' );
21 define( 'UPSTREAM_ITEM_TYPE_TASK', 'task' );
22 define( 'UPSTREAM_ITEM_TYPE_BUG', 'bug' );
23 define( 'UPSTREAM_ITEM_TYPE_FILE', 'file' );
24 define( 'UPSTREAM_ITEM_TYPE_DISCUSSION', 'discussion' );
25
26 }
27
28 define( 'UPSTREAM_PERMISSIONS_UNCHANGED', 0 );
29 define( 'UPSTREAM_PERMISSIONS_OVERRIDE_ALLOW', 1 );
30 define( 'UPSTREAM_PERMISSIONS_OVERRIDE_BLOCK', 2 );
31
32 define( 'UPSTREAM_PERMISSIONS_ACTION_VIEW', 'view' );
33 define( 'UPSTREAM_PERMISSIONS_ACTION_EDIT', 'edit' );
34 define( 'UPSTREAM_PERMISSIONS_ACTION_CREATE', 'create' );
35 define( 'UPSTREAM_PERMISSIONS_ACTION_DELETE', 'delete' );
36 define( 'UPSTREAM_PERMISSIONS_ACTION_COPY', 'copy' );
37
38 define( 'UPSTREAM_PERMISSIONS_FILTER_OBJECT', 'upstream_permissions_filter_object' );
39 define( 'UPSTREAM_PERMISSIONS_FILTER_FIELD', 'upstream_permissions_filter_field' );
40 define( 'UPSTREAM_PERMISSIONS_FILTER_BYPASS', 'upstream_permissions_filter_bypass' );
41 define( 'UPSTREAM_PERMISSIONS_FILTER_PAGE_ACCESS', 'upstream_permissions_filter_page_access' );
42
43 /**
44 * Upstream_can_access_object
45 *
46 * @param string $capability Capability name.
47 * @param string $object_type Object type.
48 * @param int $object_id Object id.
49 * @param string $parent_type Parent type.
50 * @param int $parent_id Parent ID.
51 * @param string $action Action name.
52 * @param bool $is_admin_page Is admin page.
53 */
54 function upstream_can_access_object( $capability, $object_type, $object_id, $parent_type, $parent_id, $action, $is_admin_page = false ) {
55 if ( 'milestones' === $object_type ) {
56 $object_type = 'milestone';
57 } elseif ( 'tasks' === $object_type ) {
58 $object_type = 'task';
59 } elseif ( 'bugs' === $object_type ) {
60 $object_type = 'bug';
61 } elseif ( 'files' === $object_type ) {
62 $object_type = 'file';
63 }
64
65 $user_id = get_current_user_id();
66 $override = apply_filters(
67 UPSTREAM_PERMISSIONS_FILTER_OBJECT,
68 UPSTREAM_PERMISSIONS_UNCHANGED,
69 $object_type,
70 $object_id,
71 $parent_type,
72 $parent_id,
73 $user_id,
74 $action
75 );
76
77 if ( UPSTREAM_PERMISSIONS_OVERRIDE_BLOCK === $override ) {
78 return false;
79 } elseif ( UPSTREAM_PERMISSIONS_OVERRIDE_ALLOW === $override ) {
80 return true;
81 } else {
82 if ( $is_admin_page ) {
83 return upstream_admin_permissions( $capability );
84 } else {
85 return upstream_permissions( $capability, $object_id );
86 }
87 }
88 }
89
90 /**
91 * Upstream_can_access_field
92 *
93 * @param string $capability Capability name.
94 * @param string $object_type Object type.
95 * @param int $object_id Object id.
96 * @param string $parent_type Parent type.
97 * @param int $parent_id Parent ID.
98 * @param string $field Field name.
99 * @param string $action Action name.
100 * @param bool $is_admin_page Is admin page.
101 */
102 function upstream_can_access_field( $capability, $object_type, $object_id, $parent_type, $parent_id, $field, $action, $is_admin_page = false ) {
103 if ( 'milestones' === $object_type ) {
104 $object_type = 'milestone';
105 } elseif ( 'tasks' === $object_type ) {
106 $object_type = 'task';
107 } elseif ( 'bugs' === $object_type ) {
108 $object_type = 'bug';
109 } elseif ( 'files' === $object_type ) {
110 $object_type = 'file';
111 }
112
113 $user_id = get_current_user_id();
114 $override = apply_filters(
115 UPSTREAM_PERMISSIONS_FILTER_FIELD,
116 UPSTREAM_PERMISSIONS_UNCHANGED,
117 $object_type,
118 $object_id,
119 $parent_type,
120 $parent_id,
121 $field,
122 $user_id,
123 $action
124 );
125
126 if ( UPSTREAM_PERMISSIONS_OVERRIDE_BLOCK === $override ) {
127 return false;
128 } elseif ( UPSTREAM_PERMISSIONS_OVERRIDE_ALLOW === $override ) {
129 return true;
130 } else {
131 if ( $is_admin_page ) {
132 return upstream_admin_permissions( $capability );
133 } else {
134 return upstream_permissions( $capability, $object_id );
135 }
136 }
137 }
138
139
140 /************************* END UPSTREAM V2 FUNCTIONALITY ******************************/
141
142 /**
143 * Upstream_override_access_object
144 *
145 * @param bool $orig_value Default value.
146 * @param string $object_type Object type.
147 * @param int $object_id Object id.
148 * @param string $parent_type Parent type.
149 * @param int $parent_id Parent ID.
150 * @param string $action Action name.
151 */
152 function upstream_override_access_object( $orig_value, $object_type, $object_id, $parent_type, $parent_id, $action ) {
153 if ( 'milestones' === $object_type ) {
154 $object_type = 'milestone';
155 } elseif ( 'tasks' === $object_type ) {
156 $object_type = 'task';
157 } elseif ( 'bugs' === $object_type ) {
158 $object_type = 'bug';
159 } elseif ( 'files' === $object_type ) {
160 $object_type = 'file';
161 }
162
163 $user_id = get_current_user_id();
164 $override = apply_filters(
165 UPSTREAM_PERMISSIONS_FILTER_OBJECT,
166 UPSTREAM_PERMISSIONS_UNCHANGED,
167 $object_type,
168 $object_id,
169 $parent_type,
170 $parent_id,
171 $user_id,
172 $action
173 );
174
175 if ( UPSTREAM_PERMISSIONS_OVERRIDE_BLOCK === $override ) {
176 return false;
177 } elseif ( UPSTREAM_PERMISSIONS_OVERRIDE_ALLOW === $override ) {
178 return true;
179 } else {
180 return $orig_value;
181 }
182 }
183
184 /**
185 * Upstream_can_access_field
186 *
187 * @param bool $orig_value Default value.
188 * @param string $object_type Object type.
189 * @param int $object_id Object id.
190 * @param string $parent_type Parent type.
191 * @param int $parent_id Parent ID.
192 * @param string $field Field name.
193 * @param string $action Action name.
194 */
195 function upstream_override_access_field( $orig_value, $object_type, $object_id, $parent_type, $parent_id, $field, $action ) {
196 if ( 'milestones' === $object_type ) {
197 $object_type = 'milestone';
198 } elseif ( 'tasks' === $object_type ) {
199 $object_type = 'task';
200 } elseif ( 'bugs' === $object_type ) {
201 $object_type = 'bug';
202 } elseif ( 'files' === $object_type ) {
203 $object_type = 'file';
204 }
205
206 $user_id = get_current_user_id();
207 $override = apply_filters(
208 UPSTREAM_PERMISSIONS_FILTER_FIELD,
209 UPSTREAM_PERMISSIONS_UNCHANGED,
210 $object_type,
211 $object_id,
212 $parent_type,
213 $parent_id,
214 $field,
215 $user_id,
216 $action
217 );
218
219 if ( UPSTREAM_PERMISSIONS_OVERRIDE_BLOCK === $override ) {
220 return false;
221 } elseif ( UPSTREAM_PERMISSIONS_OVERRIDE_ALLOW === $override ) {
222 return true;
223 } else {
224 return $orig_value;
225 }
226 }
227
228 /**
229 * Permission checks for the frontend are always run through here.
230 * Return true if they are allowed.
231 *
232 * @param string|null $capability Capability name.
233 * @param int|null $item_id Item id.
234 * @deprecated Use current_user_can
235 */
236 function upstream_permissions( $capability = null, $item_id = null ) {
237 // allow bypass of standard permissions by capability.
238 if ( apply_filters( UPSTREAM_PERMISSIONS_FILTER_BYPASS, false, $capability ) ) {
239 return true;
240 }
241
242 // set the return variable that can be overwritten after all checks.
243 $return = false;
244 $current_user = upstream_current_user_id();
245
246 // these guys can do whatever they want.
247 if ( upstream_project_owner_id() === upstream_current_user_id() ||
248 current_user_can( 'upstream_manager' ) ||
249 current_user_can( 'administrator' ) ) {
250 $return = true;
251 }
252
253 // if they are simply a project member or a client user, this will give them at least READ access to the project.
254 // and stops them being redirected to the projects archive page.
255 if ( 'view_project' === $capability ) {
256 $members = upstream_project_members_ids();
257 if ( is_array( $members ) && in_array( $current_user, $members ) ) {
258 $return = true;
259 }
260
261 // client users.
262 $client_users = upstream_project_client_users();
263 if ( is_array( $client_users ) && in_array( $current_user, $client_users ) ) {
264 $return = true;
265 }
266 }
267
268 // if capability is set and they have the capability.
269 if ( isset( $capability ) && ! empty( $capability ) ) {
270
271 // for WP user - get standard capabilities.
272 if ( is_int( $current_user ) && current_user_can( $capability ) ) {
273 $return = true;
274 }
275
276 // for client users.
277 // get their capabilities, stored within the meta of the Client post type.
278 if ( ! is_int( $current_user ) ) {
279 $client_users = get_post_meta(
280 upstream_project_client_id( upstream_post_id() ),
281 '_upstream_client_users',
282 true
283 );
284 if ( is_array( $client_users ) && ! empty( $client_users ) ) {
285 foreach ( $client_users as $index => $user ) {
286 if ( $user['id'] === $current_user ) {
287 if ( isset( $user['capability'] ) && in_array( $capability, $user['capability'], true ) ) {
288 $return = true;
289 }
290 }
291 }
292 }
293 }
294 }
295
296 // if we have an individual item and they are the creator or have been assigned this item.
297 // used for the 'Actions' column to allow editing/deleting buttons.
298 if ( isset( $item_id ) ) {
299 $item = upstream_project_item_by_id( upstream_post_id(), $item_id );
300 $assigned_to = isset( $item['assigned_to'] ) ? (array) $item['assigned_to'] : array();
301 $created_by = isset( $item['created_by'] ) ? $item['created_by'] : null;
302 if ( in_array( $current_user, $assigned_to ) || $created_by == $current_user ) {
303 $return = true;
304 }
305 }
306
307 // blocks all fields (except for status) from being edited/deleted.
308 // used if the project status is closed.
309 if ( 'project_status_field' !== $capability && upstream_project_status_type() === 'closed' ) {
310 $return = false;
311 }
312
313 return apply_filters( 'upstream_permissions', $return );
314 }
315
316
317 /*
318 ======================================================================================
319 ADMIN
320 ======================================================================================
321 */
322
323
324 /**
325 * Permission checks are always run through here.
326 * Return true if they are allowed.
327 *
328 * @param string $capability Permission capability.
329 *
330 * @return bool
331 */
332 function upstream_admin_permissions( $capability = null ) {
333 /*
334 * Set the return variable that can be overwritten after all checks
335 */
336 $return = false;
337
338 /*
339 * These guys can do whatever they want
340 */
341 if ( upstream_project_owner_id() === upstream_current_user_id() ||
342 current_user_can( 'upstream_manager' ) ||
343 current_user_can( 'administrator' ) ) {
344 $return = true;
345 }
346
347 /*
348 * If the user has the capability
349 */
350 if ( isset( $capability ) && ! empty( $capability ) ) {
351 if ( current_user_can( $capability ) ) {
352 $return = true;
353 }
354 }
355
356 /*
357 * If project status is closed, block all fields (except for status) from being edited/deleted
358 */
359 if ( ( isset( $capability ) && 'project_status_field' !== $capability ) &&
360 upstream_project_status_type() == 'closed' ) {
361 $return = false;
362 }
363
364 return apply_filters( 'upstream_admin_permissions', $return );
365 }
366
367 /**
368 * Retrieve all Client Users permissions available.
369 *
370 * @since 1.11.0
371 *
372 * @return array
373 */
374 function upstream_get_client_users_permissions() {
375 $permissions = array();
376 $permissions_list = (array) apply_filters( 'upstream:users.permissions', array() );
377
378 foreach ( $permissions_list as $permission ) {
379 $permissions[ $permission['key'] ] = $permission;
380 }
381
382 return $permissions;
383 }
384
385 /**
386 * Check if a given user can access a given project.
387 *
388 * @since 1.12.2
389 *
390 * @param numeric/WP_User $user_id The user to be checked against the project.
391 * @param numeric $project_id The project to be checked.
392 *
393 * @return bool
394 */
395 function upstream_user_can_access_project( $user_id, $project_id ) {
396 $project_id = is_numeric( $project_id ) ? (int) $project_id : 0;
397 if ( $project_id <= 0 ) {
398 return false;
399 }
400
401 $user = $user_id instanceof \WP_User ? $user_id : new \WP_User( $user_id );
402 if ( 0 === $user->ID && ! apply_filters( 'upstream_permissions_filter_page_access', false ) ) {
403 return false;
404 }
405
406 $override = apply_filters(
407 UPSTREAM_PERMISSIONS_FILTER_OBJECT,
408 UPSTREAM_PERMISSIONS_UNCHANGED,
409 'project',
410 $project_id,
411 null,
412 0,
413 $user->ID,
414 UPSTREAM_PERMISSIONS_ACTION_VIEW
415 );
416
417 if ( UPSTREAM_PERMISSIONS_OVERRIDE_BLOCK === $override ) {
418 return false;
419 } elseif ( UPSTREAM_PERMISSIONS_OVERRIDE_ALLOW === $override ) {
420 return true;
421 }
422
423 $user_is_admin = count( array_intersect( (array) $user->roles, array( 'administrator', 'upstream_manager' ) ) ) > 0;
424 if ( $user_is_admin ) {
425 return true;
426 }
427
428 $user_can_access_project = false;
429
430 if ( in_array( 'upstream_client_user', $user->roles, true ) ) {
431 // Check if client user is allowed on this project.
432 $meta = (array) get_post_meta( $project_id, '_upstream_project_client_users' );
433 $meta = ! empty( $meta ) ? (array) $meta[0] : array();
434 $meta = empty( $meta ) ? array() : $meta;
435
436 if ( in_array( $user->ID, $meta ) ) {
437 $user_can_access_project = true;
438 }
439 }
440
441 if ( ! $user_can_access_project && user_can( $user, 'edit_published_projects' ) ) {
442 // Check if user is a member of the project.
443 $project_members = upstream_project_members_ids( $project_id );
444 if ( is_array( $project_members ) && in_array( $user->ID, $project_members ) ) {
445 $user_can_access_project = true;
446 } elseif ( $user->ID === (int) $project_members ) {
447 $user_can_access_project = true;
448 }
449 }
450
451 return $user_can_access_project;
452 }
453