PluginProbe
WCPOS – Point of Sale (POS) plugin for WooCommerce / 1.10.21
WCPOS – Point of Sale (POS) plugin for WooCommerce v1.10.21
1.10.22 1.10.21 1.10.20 1.10.19 1.10.18 1.10.17 1.10.16 1.10.15 1.10.13 1.10.14 1.10.12 1.10.11 1.10.10 1.10.9 1.10.8 untagged-3d9b7ccddc54df87c672 1.10.7 1.10.6 1.10.5 1.10.3 1.10.4 1.10.2 1.10.1 1.10.0 1.9.17 All 166 releases
← All changes | includes/Services/Permission_Rules.php +0 -97 1.10.22 → 1.10.21 View file →
@@ -440,105 +440,8 @@
440 440 return $caps;
441 441 }
442 442
443 443 /**
444 - * The only role a till user may assign.
445 - *
446 - * Customer creation from the till always produces this role; changing a
447 - * role is not a POS feature, so nothing legitimate needs more.
448 - */
449 - private const TILL_ASSIGNABLE_ROLES = array( 'customer' );
450 -
451 - /**
452 - * The roles a POS actor may hand out, or null when the actor is not fenced.
453 - *
454 - * Administrators (and so multisite super admins) are not fenced. A shop
455 - * manager — any actor with `manage_woocommerce` — follows WooCommerce's own
456 - * list for shop managers, `woocommerce_shop_manager_editable_roles`
457 - * (customer by default), which WooCommerce enforces only while it is active
458 - * and only for the literal `shop_manager` role name; applying it here keeps
459 - * that fence up when WooCommerce is deactivated (the roles and their
460 - * capabilities persist) and for a cashier who also holds shop manager.
461 - * Everyone else with till access gets TILL_ASSIGNABLE_ROLES.
462 - *
463 - * @param int $actor Acting user ID.
464 - *
465 - * @return array|null Role names, or null for an unfenced actor.
466 - */
467 - private static function assignable_roles( int $actor ): ?array {
468 - if ( $actor < 1 || ! user_can( $actor, 'access_woocommerce_pos' ) || user_can( $actor, 'manage_options' ) ) {
469 - return null;
470 - }
471 - $allowed = self::TILL_ASSIGNABLE_ROLES;
472 - if ( user_can( $actor, 'manage_woocommerce' ) ) {
473 - $allowed = (array) apply_filters( 'woocommerce_shop_manager_editable_roles', self::TILL_ASSIGNABLE_ROLES ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- WooCommerce's own fence list, applied as WooCommerce applies it.
474 - }
475 -
476 - return array_values( array_filter( array_map( 'strval', $allowed ) ) );
477 - }
478 -
479 - /**
480 - * Fence the roles a till user may assign (`editable_roles` filter).
481 - *
482 - * The Cashier role holds `edit_users` and, on WooCommerce below 9.9,
483 - * `promote_users` (customer creation needed it). WordPress's role-update
484 - * checks — `WP_REST_Users_Controller::check_role_update()`, `edit_user()`
485 - * and the users.php bulk actions — accept those two capabilities and then
486 - * ask `get_editable_roles()` which roles the actor may hand out; nothing
487 - * ranked them, so a cashier could set an ordinary customer's role to
488 - * Administrator. can_modify() does not catch that: it judges the target's
489 - * current capabilities, which a plain customer has none of until after the
490 - * update. It only ever removes roles; it never adds one.
491 - *
492 - * @param array $roles Editable roles keyed by role name.
493 - *
494 - * @return array
495 - */
496 - public static function filter_editable_roles( $roles ): array {
497 - $roles = (array) $roles;
498 - $allowed = self::assignable_roles( get_current_user_id() );
499 - if ( null === $allowed ) {
500 - return $roles;
501 - }
502 -
503 - return array_intersect_key( $roles, array_fill_keys( $allowed, true ) );
504 - }
505 -
506 - /**
507 - * Refuse a multisite "add existing user" invite outside the fence (`invite_user` action).
508 - *
509 - * WordPress's wp-admin/user-new.php stores the requested role in the `new_user_<key>`
510 - * option and only reads `get_editable_roles()` for the email's label, so an
511 - * invite to an existing network account can carry any role; accepting it
512 - * calls `add_user_to_blog()` with that role unchecked. Same fence as
513 - * filter_editable_roles(): a fenced actor's invite may name only an
514 - * assignable role, or the invite is deleted before its email goes out.
515 - *
516 - * @param int $user_id Invited user ID.
517 - * @param array|null $role Role label array, null when the role was not editable.
518 - * @param string $newuser_key Invitation key.
519 - *
520 - * @return void
521 - */
522 - public static function refuse_unfenced_invite( $user_id, $role, $newuser_key ): void {
523 - $allowed = self::assignable_roles( get_current_user_id() );
524 - if ( null === $allowed ) {
525 - return;
526 - }
527 - $invite = get_option( 'new_user_' . $newuser_key );
528 - $requested = \is_array( $invite ) && isset( $invite['role'] ) ? (string) $invite['role'] : '';
529 - if ( \in_array( $requested, $allowed, true ) ) {
530 - return;
531 - }
532 - delete_option( 'new_user_' . $newuser_key );
533 - wp_die(
534 - esc_html__( 'Sorry, you are not allowed to give users that role.', 'woocommerce-pos' ),
535 - '',
536 - array( 'response' => 403 )
537 - );
538 - }
539 -
540 - /**
541 444 * Build the staff account permission error.
542 445 *
543 446 * @return \WP_Error
544 447 */