User Switching - Version 1.5.7

Version Description

Download this release

Release Info

Developer johnbillion
Plugin Icon 128x128 User Switching
Version 1.5.7
Comparing to
See all releases

Code changes from version 1.5.6 to 1.5.7

Files changed (3) hide show
  1. phpstan.neon.dist +17 -0
  2. readme.md +24 -10
  3. user-switching.php +45 -11
phpstan.neon.dist ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ includes:
2
+ - vendor/szepeviktor/phpstan-wordpress/extension.neon
3
+ parameters:
4
+ level: max
5
+ implicitThrows: false
6
+ paths:
7
+ - user-switching.php
8
+ bootstrapFiles:
9
+ - tests/stubs.php
10
+ ignoreErrors:
11
+ # Uses func_get_args()
12
+ - '#^Function apply_filters invoked with [34567] parameters, 2 required\.$#'
13
+ # Covers the breaks after exits in user_switching::action_init()
14
+ -
15
+ message: '#^Unreachable statement#'
16
+ path: user-switching.php
17
+ count: 3
readme.md CHANGED
@@ -1,8 +1,8 @@
1
  # User Switching
2
 
3
- Stable tag: 1.5.6
4
  Requires at least: 3.7
5
- Tested up to: 5.7
6
  Requires PHP: 5.3
7
  License: GPL v2 or later
8
  Tags: users, profiles, user switching, fast user switching, multisite, buddypress, bbpress, become, user management, developer
@@ -105,7 +105,7 @@ Yes, and you'll also be able to switch users from member profile screens.
105
 
106
  ### Does this plugin work with WooCommerce?
107
 
108
- Yes, but for maximum compatibility you should use WooCommerce version 3.6 or later.
109
 
110
  ### Does this plugin work if my site is using a two-factor authentication plugin?
111
 
@@ -145,8 +145,21 @@ Yes. Use the `user_switching::maybe_switch_url()` method for this. It takes care
145
  if ( $url ) {
146
  printf(
147
  '<a href="%1$s">Switch to %2$s</a>',
148
- $url,
149
- $target_user->display_name
 
 
 
 
 
 
 
 
 
 
 
 
 
150
  );
151
  }
152
  }
@@ -243,6 +256,12 @@ In addition, User Switching respects the following filters from WordPress core w
243
 
244
  ## Changelog ##
245
 
 
 
 
 
 
 
246
  ### 1.5.6 ###
247
 
248
  * Add a class to the table row on the user edit screen.
@@ -321,11 +340,6 @@ In addition, User Switching respects the following filters from WordPress core w
321
  * Docblock improvements.
322
  * Coding standards improvements.
323
 
324
- ### 0.6.1 ###
325
-
326
- - Slovak translation by Max Samael.
327
-
328
-
329
  ### 0.6 ###
330
 
331
  - More intuitive redirecting after switching.
1
  # User Switching
2
 
3
+ Stable tag: 1.5.7
4
  Requires at least: 3.7
5
+ Tested up to: 5.8
6
  Requires PHP: 5.3
7
  License: GPL v2 or later
8
  Tags: users, profiles, user switching, fast user switching, multisite, buddypress, bbpress, become, user management, developer
105
 
106
  ### Does this plugin work with WooCommerce?
107
 
108
+ Yes. For maximum compatibility you should use WooCommerce version 3.6 or later.
109
 
110
  ### Does this plugin work if my site is using a two-factor authentication plugin?
111
 
145
  if ( $url ) {
146
  printf(
147
  '<a href="%1$s">Switch to %2$s</a>',
148
+ esc_url( $url ),
149
+ esc_html( $target_user->display_name )
150
+ );
151
+ }
152
+ }
153
+
154
+ This link also works for switching back to the original user, but if you want an explicit link for this you can use the following code:
155
+
156
+ if ( method_exists( 'user_switching', 'get_old_user' ) ) {
157
+ $old_user = user_switching::get_old_user();
158
+ if ( $old_user ) {
159
+ printf(
160
+ '<a href="%1$s">Switch back to %2$s</a>',
161
+ esc_url( user_switching::switch_back_url( $old_user ) ),
162
+ esc_html( $old_user->display_name )
163
  );
164
  }
165
  }
256
 
257
  ## Changelog ##
258
 
259
+ ### 1.5.7 ###
260
+
261
+ * Fix some issues that could lead to PHP errors given a malformed cookie.
262
+ * Fix documentation.
263
+
264
+
265
  ### 1.5.6 ###
266
 
267
  * Add a class to the table row on the user edit screen.
340
  * Docblock improvements.
341
  * Coding standards improvements.
342
 
 
 
 
 
 
343
  ### 0.6 ###
344
 
345
  - More intuitive redirecting after switching.
user-switching.php CHANGED
@@ -5,12 +5,12 @@
5
  * @package user-switching
6
  * @link https://github.com/johnbillion/user-switching
7
  * @author John Blackbourn <john@johnblackbourn.com>
8
- * @copyright 2009-2020 John Blackbourn
9
  * @license GPL v2 or later
10
  *
11
  * Plugin Name: User Switching
12
  * Description: Instant switching between user accounts in WordPress
13
- * Version: 1.5.6
14
  * Plugin URI: https://johnblackbourn.com/wordpress-plugin-user-switching/
15
  * Author: John Blackbourn & contributors
16
  * Author URI: https://github.com/johnbillion/user-switching/graphs/contributors
@@ -31,7 +31,7 @@
31
  */
32
 
33
  /**
34
- * Main container class for the User Switching plugin.
35
  */
36
  class user_switching {
37
 
@@ -44,6 +44,8 @@ class user_switching {
44
 
45
  /**
46
  * Sets up all the filters and actions.
 
 
47
  */
48
  public function init_hooks() {
49
  // Required functionality:
@@ -73,6 +75,8 @@ class user_switching {
73
 
74
  /**
75
  * Defines the names of the cookies used by User Switching.
 
 
76
  */
77
  public function action_plugins_loaded() {
78
  // User Switching's auth_cookie
@@ -95,6 +99,7 @@ class user_switching {
95
  * Outputs the 'Switch To' link on the user editing screen if the current user has permission to switch to them.
96
  *
97
  * @param WP_User $user User object for this screen.
 
98
  */
99
  public function action_personal_options( WP_User $user ) {
100
  $link = self::maybe_switch_url( $user );
@@ -123,13 +128,19 @@ class user_switching {
123
  $cookie_life = apply_filters( 'auth_cookie_expiration', 172800, get_current_user_id(), false );
124
  $current = wp_parse_auth_cookie( '', 'logged_in' );
125
 
 
 
 
 
126
  // Here we calculate the expiration length of the current auth cookie and compare it to the default expiration.
127
  // If it's greater than this, then we know the user checked 'Remember Me' when they logged in.
128
- return ( ( $current['expiration'] - time() ) > $cookie_life );
129
  }
130
 
131
  /**
132
  * Loads localisation files and routes actions depending on the 'action' query var.
 
 
133
  */
134
  public function action_init() {
135
  load_plugin_textdomain( 'user-switching', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' );
@@ -226,7 +237,7 @@ class user_switching {
226
  // We're attempting to switch off the current user:
227
  case 'switch_off':
228
  // Check authentication:
229
- if ( ! current_user_can( 'switch_off' ) ) {
230
  /* Translators: "switch off" means to temporarily log out */
231
  wp_die( esc_html__( 'Could not switch off.', 'user-switching' ) );
232
  }
@@ -285,6 +296,8 @@ class user_switching {
285
 
286
  /**
287
  * Displays the 'Switched to {user}' and 'Switch back to {user}' messages in the admin area.
 
 
288
  */
289
  public function action_admin_notices() {
290
  $user = wp_get_current_user();
@@ -436,6 +449,7 @@ class user_switching {
436
  * Adds a 'Switch back to {user}' link to the account menu, and a `Switch To` link to the user edit menu.
437
  *
438
  * @param WP_Admin_Bar $wp_admin_bar The admin bar object.
 
439
  */
440
  public function action_admin_bar_menu( WP_Admin_Bar $wp_admin_bar ) {
441
  if ( ! is_admin_bar_showing() ) {
@@ -519,6 +533,8 @@ class user_switching {
519
 
520
  /**
521
  * Adds a 'Switch back to {user}' link to the Meta sidebar widget.
 
 
522
  */
523
  public function action_wp_meta() {
524
  $old_user = self::get_old_user();
@@ -543,6 +559,8 @@ class user_switching {
543
 
544
  /**
545
  * Adds a 'Switch back to {user}' link to the WordPress footer if the admin toolbar isn't showing.
 
 
546
  */
547
  public function action_wp_footer() {
548
  if ( is_admin_bar_showing() || did_action( 'wp_meta' ) ) {
@@ -646,6 +664,8 @@ class user_switching {
646
 
647
  /**
648
  * Adds a 'Switch To' link to each member's profile page and profile listings in BuddyPress.
 
 
649
  */
650
  public function action_bp_button() {
651
  $user = null;
@@ -683,6 +703,8 @@ class user_switching {
683
 
684
  /**
685
  * Adds a 'Switch To' link to each member's profile page in bbPress.
 
 
686
  */
687
  public function action_bbpress_button() {
688
  $user = get_userdata( bbp_get_user_id() );
@@ -833,6 +855,8 @@ class user_switching {
833
 
834
  /**
835
  * Instructs WooCommerce to forget the session for the current user, without deleting it.
 
 
836
  */
837
  public function forget_woocommerce_session() {
838
  if ( ! function_exists( 'WC' ) ) {
@@ -865,7 +889,7 @@ class user_switching {
865
  * @param bool[] $user_caps Array of key/value pairs where keys represent a capability name and boolean values
866
  * represent whether the user has that capability.
867
  * @param string[] $required_caps Array of required primitive capabilities for the requested capability.
868
- * @param array $args {
869
  * Arguments that accompany the requested capability check.
870
  *
871
  * @type string $0 Requested capability.
@@ -911,7 +935,7 @@ class user_switching {
911
  * @param string[] $required_caps Array of required primitive capabilities for the requested capability.
912
  * @param string $cap Capability or meta capability being checked.
913
  * @param int $user_id Concerned user ID.
914
- * @param array $args {
915
  * Arguments that accompany the requested capability check.
916
  *
917
  * @type mixed ...$0 Optional second and further parameters.
@@ -958,6 +982,7 @@ if ( ! function_exists( 'user_switching_set_olduser_cookie' ) ) {
958
  * @param int $old_user_id The ID of the originating user, usually the current logged in user.
959
  * @param bool $pop Optional. Pop the latest user off the auth cookie, instead of appending the new one. Default false.
960
  * @param string $token Optional. The old user's session token to store for later reuse. Default empty string.
 
961
  */
962
  function user_switching_set_olduser_cookie( $old_user_id, $pop = false, $token = '' ) {
963
  $secure_auth_cookie = user_switching::secure_auth_cookie();
@@ -982,6 +1007,10 @@ if ( ! function_exists( 'user_switching_set_olduser_cookie' ) ) {
982
 
983
  $auth_cookie = json_encode( $auth_cookie );
984
 
 
 
 
 
985
  /**
986
  * Fires immediately before the User Switching authentication cookie is set.
987
  *
@@ -1031,6 +1060,7 @@ if ( ! function_exists( 'user_switching_clear_olduser_cookie' ) ) {
1031
  * Clears the cookies containing the originating user, or pops the latest item off the end if there's more than one.
1032
  *
1033
  * @param bool $clear_all Optional. Whether to clear the cookies (as opposed to just popping the last user off the end). Default true.
 
1034
  */
1035
  function user_switching_clear_olduser_cookie( $clear_all = true ) {
1036
  $auth_cookie = user_switching_get_auth_cookie();
@@ -1066,7 +1096,10 @@ if ( ! function_exists( 'user_switching_clear_olduser_cookie' ) ) {
1066
  $old_user_id = wp_validate_auth_cookie( $old_cookie, $scheme );
1067
  if ( $old_user_id ) {
1068
  $parts = wp_parse_auth_cookie( $old_cookie, $scheme );
1069
- user_switching_set_olduser_cookie( $old_user_id, true, $parts['token'] );
 
 
 
1070
  }
1071
  }
1072
  }
@@ -1128,8 +1161,9 @@ if ( ! function_exists( 'switch_to_user' ) ) {
1128
 
1129
  $old_user_id = ( is_user_logged_in() ) ? get_current_user_id() : false;
1130
  $old_token = function_exists( 'wp_get_session_token' ) ? wp_get_session_token() : '';
1131
- $auth_cookie = user_switching_get_auth_cookie();
1132
- $cookie_parts = wp_parse_auth_cookie( end( $auth_cookie ) );
 
1133
 
1134
  if ( $set_old_user && $old_user_id ) {
1135
  // Switching to another user
@@ -1137,7 +1171,7 @@ if ( ! function_exists( 'switch_to_user' ) ) {
1137
  user_switching_set_olduser_cookie( $old_user_id, false, $old_token );
1138
  } else {
1139
  // Switching back, either after being switched off or after being switched to another user
1140
- $new_token = isset( $cookie_parts['token'] ) ? $cookie_parts['token'] : '';
1141
  user_switching_clear_olduser_cookie( false );
1142
  }
1143
 
5
  * @package user-switching
6
  * @link https://github.com/johnbillion/user-switching
7
  * @author John Blackbourn <john@johnblackbourn.com>
8
+ * @copyright 2009-2021 John Blackbourn
9
  * @license GPL v2 or later
10
  *
11
  * Plugin Name: User Switching
12
  * Description: Instant switching between user accounts in WordPress
13
+ * Version: 1.5.7
14
  * Plugin URI: https://johnblackbourn.com/wordpress-plugin-user-switching/
15
  * Author: John Blackbourn & contributors
16
  * Author URI: https://github.com/johnbillion/user-switching/graphs/contributors
31
  */
32
 
33
  /**
34
+ * Main singleton class for the User Switching plugin.
35
  */
36
  class user_switching {
37
 
44
 
45
  /**
46
  * Sets up all the filters and actions.
47
+ *
48
+ * @return void
49
  */
50
  public function init_hooks() {
51
  // Required functionality:
75
 
76
  /**
77
  * Defines the names of the cookies used by User Switching.
78
+ *
79
+ * @return void
80
  */
81
  public function action_plugins_loaded() {
82
  // User Switching's auth_cookie
99
  * Outputs the 'Switch To' link on the user editing screen if the current user has permission to switch to them.
100
  *
101
  * @param WP_User $user User object for this screen.
102
+ * @return void
103
  */
104
  public function action_personal_options( WP_User $user ) {
105
  $link = self::maybe_switch_url( $user );
128
  $cookie_life = apply_filters( 'auth_cookie_expiration', 172800, get_current_user_id(), false );
129
  $current = wp_parse_auth_cookie( '', 'logged_in' );
130
 
131
+ if ( ! $current ) {
132
+ return false;
133
+ }
134
+
135
  // Here we calculate the expiration length of the current auth cookie and compare it to the default expiration.
136
  // If it's greater than this, then we know the user checked 'Remember Me' when they logged in.
137
+ return ( intval( $current['expiration'] ) - time() > $cookie_life );
138
  }
139
 
140
  /**
141
  * Loads localisation files and routes actions depending on the 'action' query var.
142
+ *
143
+ * @return void
144
  */
145
  public function action_init() {
146
  load_plugin_textdomain( 'user-switching', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' );
237
  // We're attempting to switch off the current user:
238
  case 'switch_off':
239
  // Check authentication:
240
+ if ( ! $current_user || ! current_user_can( 'switch_off' ) ) {
241
  /* Translators: "switch off" means to temporarily log out */
242
  wp_die( esc_html__( 'Could not switch off.', 'user-switching' ) );
243
  }
296
 
297
  /**
298
  * Displays the 'Switched to {user}' and 'Switch back to {user}' messages in the admin area.
299
+ *
300
+ * @return void
301
  */
302
  public function action_admin_notices() {
303
  $user = wp_get_current_user();
449
  * Adds a 'Switch back to {user}' link to the account menu, and a `Switch To` link to the user edit menu.
450
  *
451
  * @param WP_Admin_Bar $wp_admin_bar The admin bar object.
452
+ * @return void
453
  */
454
  public function action_admin_bar_menu( WP_Admin_Bar $wp_admin_bar ) {
455
  if ( ! is_admin_bar_showing() ) {
533
 
534
  /**
535
  * Adds a 'Switch back to {user}' link to the Meta sidebar widget.
536
+ *
537
+ * @return void
538
  */
539
  public function action_wp_meta() {
540
  $old_user = self::get_old_user();
559
 
560
  /**
561
  * Adds a 'Switch back to {user}' link to the WordPress footer if the admin toolbar isn't showing.
562
+ *
563
+ * @return void
564
  */
565
  public function action_wp_footer() {
566
  if ( is_admin_bar_showing() || did_action( 'wp_meta' ) ) {
664
 
665
  /**
666
  * Adds a 'Switch To' link to each member's profile page and profile listings in BuddyPress.
667
+ *
668
+ * @return void
669
  */
670
  public function action_bp_button() {
671
  $user = null;
703
 
704
  /**
705
  * Adds a 'Switch To' link to each member's profile page in bbPress.
706
+ *
707
+ * @return void
708
  */
709
  public function action_bbpress_button() {
710
  $user = get_userdata( bbp_get_user_id() );
855
 
856
  /**
857
  * Instructs WooCommerce to forget the session for the current user, without deleting it.
858
+ *
859
+ * @return void
860
  */
861
  public function forget_woocommerce_session() {
862
  if ( ! function_exists( 'WC' ) ) {
889
  * @param bool[] $user_caps Array of key/value pairs where keys represent a capability name and boolean values
890
  * represent whether the user has that capability.
891
  * @param string[] $required_caps Array of required primitive capabilities for the requested capability.
892
+ * @param mixed[] $args {
893
  * Arguments that accompany the requested capability check.
894
  *
895
  * @type string $0 Requested capability.
935
  * @param string[] $required_caps Array of required primitive capabilities for the requested capability.
936
  * @param string $cap Capability or meta capability being checked.
937
  * @param int $user_id Concerned user ID.
938
+ * @param mixed[] $args {
939
  * Arguments that accompany the requested capability check.
940
  *
941
  * @type mixed ...$0 Optional second and further parameters.
982
  * @param int $old_user_id The ID of the originating user, usually the current logged in user.
983
  * @param bool $pop Optional. Pop the latest user off the auth cookie, instead of appending the new one. Default false.
984
  * @param string $token Optional. The old user's session token to store for later reuse. Default empty string.
985
+ * @return void
986
  */
987
  function user_switching_set_olduser_cookie( $old_user_id, $pop = false, $token = '' ) {
988
  $secure_auth_cookie = user_switching::secure_auth_cookie();
1007
 
1008
  $auth_cookie = json_encode( $auth_cookie );
1009
 
1010
+ if ( false === $auth_cookie ) {
1011
+ return;
1012
+ }
1013
+
1014
  /**
1015
  * Fires immediately before the User Switching authentication cookie is set.
1016
  *
1060
  * Clears the cookies containing the originating user, or pops the latest item off the end if there's more than one.
1061
  *
1062
  * @param bool $clear_all Optional. Whether to clear the cookies (as opposed to just popping the last user off the end). Default true.
1063
+ * @return void
1064
  */
1065
  function user_switching_clear_olduser_cookie( $clear_all = true ) {
1066
  $auth_cookie = user_switching_get_auth_cookie();
1096
  $old_user_id = wp_validate_auth_cookie( $old_cookie, $scheme );
1097
  if ( $old_user_id ) {
1098
  $parts = wp_parse_auth_cookie( $old_cookie, $scheme );
1099
+
1100
+ if ( false !== $parts ) {
1101
+ user_switching_set_olduser_cookie( $old_user_id, true, $parts['token'] );
1102
+ }
1103
  }
1104
  }
1105
  }
1161
 
1162
  $old_user_id = ( is_user_logged_in() ) ? get_current_user_id() : false;
1163
  $old_token = function_exists( 'wp_get_session_token' ) ? wp_get_session_token() : '';
1164
+ $auth_cookies = user_switching_get_auth_cookie();
1165
+ $auth_cookie = end( $auth_cookies );
1166
+ $cookie_parts = $auth_cookie ? wp_parse_auth_cookie( $auth_cookie ) : false;
1167
 
1168
  if ( $set_old_user && $old_user_id ) {
1169
  // Switching to another user
1171
  user_switching_set_olduser_cookie( $old_user_id, false, $old_token );
1172
  } else {
1173
  // Switching back, either after being switched off or after being switched to another user
1174
+ $new_token = ( $cookie_parts && isset( $cookie_parts['token'] ) ) ? $cookie_parts['token'] : '';
1175
  user_switching_clear_olduser_cookie( false );
1176
  }
1177