@@ -749,4 +749,168 @@ public function test_only_inactive_and_release_users_are_returned_blocked_filter
749749 wp_delete_user ( $ u3 );
750750 wp_delete_user ( $ u4 );
751751 }
752+
753+ /**
754+ * Test multisite security: admin can only unblock users who are members of current site
755+ */
756+ public function test_multisite_unblock_when_user_not_member_of_site () {
757+ if ( ! is_multisite () ) {
758+ $ this ->markTestSkipped ( 'This test requires multisite to be enabled ' );
759+ }
760+
761+ // Create a user who will be an admin on the current site
762+ $ network_user_id = $ this ->factory ->user ->create ([
763+ 'role ' => 'administrator ' ,
764+ 'user_registered ' => gmdate ( 'Y-m-d H:i:s ' , strtotime ( '-100 days ' ) ),
765+ ]);
766+
767+ // Make the user inactive
768+ update_user_meta ( $ network_user_id , Inactive_Users::LAST_SEEN_META_KEY , strtotime ( '-91 days ' ) );
769+ delete_user_meta ( $ network_user_id , Inactive_Users::LAST_SEEN_IGNORE_INACTIVITY_CHECK_UNTIL_META_KEY );
770+
771+ // Create a second site
772+ $ site_2_id = $ this ->factory ->blog ->create ();
773+
774+ // Remove the user from the current site and add them to site 2
775+ remove_user_from_blog ( $ network_user_id , get_current_blog_id () );
776+ // phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.switch_to_blog_switch_to_blog
777+ switch_to_blog ( $ site_2_id );
778+ add_user_to_blog ( $ site_2_id , $ network_user_id , 'administrator ' );
779+ restore_current_blog ();
780+
781+ // Create an admin user on the current site
782+ $ current_site_admin = $ this ->factory ->user ->create ([
783+ 'role ' => 'administrator ' ,
784+ ]);
785+
786+ // Set the current user to the admin of the current site
787+ wp_set_current_user ( $ current_site_admin );
788+
789+ // Verify the network user is not a member of the current site
790+ $ this ->assertFalse ( is_user_member_of_blog ( $ network_user_id , get_current_blog_id () ) );
791+
792+ // Simulate the unblock action request
793+ $ _GET ['action ' ] = 'reset_last_seen ' ;
794+ $ _GET ['user_id ' ] = $ network_user_id ;
795+ $ _GET ['reset_last_seen_nonce ' ] = wp_create_nonce ( 'reset_last_seen_action ' );
796+
797+ // Call the unblock action method
798+ Inactive_Users::last_seen_unblock_action ();
799+
800+ // Verify that the user is still considered inactive, since the user is not a member of the current site
801+ $ this ->assertTrue ( Inactive_Users::is_considered_inactive ( $ network_user_id ) );
802+
803+ // Clean up
804+ wp_delete_user ( $ network_user_id );
805+ wp_delete_user ( $ current_site_admin );
806+ unset( $ _GET ['action ' ], $ _GET ['user_id ' ], $ _GET ['reset_last_seen_nonce ' ] );
807+ }
808+
809+ /**
810+ * Test multisite security: admin can unblock users who ARE members of current site
811+ */
812+ public function test_multisite_unblock_when_user_is_member_of_site () {
813+ if ( ! is_multisite () ) {
814+ $ this ->markTestSkipped ( 'This test requires multisite to be enabled ' );
815+ }
816+
817+ // Create a user who IS a member of the current site
818+ $ site_user_id = $ this ->factory ->user ->create ([
819+ 'role ' => 'administrator ' ,
820+ 'user_registered ' => gmdate ( 'Y-m-d H:i:s ' , strtotime ( '-100 days ' ) ),
821+ ]);
822+
823+ // Make the user inactive
824+ update_user_meta ( $ site_user_id , Inactive_Users::LAST_SEEN_META_KEY , strtotime ( '-91 days ' ) );
825+ delete_user_meta ( $ site_user_id , Inactive_Users::LAST_SEEN_IGNORE_INACTIVITY_CHECK_UNTIL_META_KEY );
826+
827+ // Set the current user to be a super admin (who can edit any user)
828+ $ super_admin_id = $ this ->factory ->user ->create ([
829+ 'role ' => 'administrator ' ,
830+ ]);
831+ grant_super_admin ( $ super_admin_id );
832+ wp_set_current_user ( $ super_admin_id );
833+
834+ // Verify the user IS a member of the current site
835+ $ this ->assertTrue ( is_user_member_of_blog ( $ site_user_id , get_current_blog_id () ) );
836+
837+ // Verify the user is initially inactive
838+ $ this ->assertTrue ( Inactive_Users::is_considered_inactive ( $ site_user_id ) );
839+
840+ // Verify the current user has edit_user capability for this user
841+ $ this ->assertTrue ( current_user_can ( 'edit_user ' , $ site_user_id ), 'Super admin should have edit_user capability for any user ' );
842+
843+ // Simulate the unblock action request
844+ $ _GET ['action ' ] = 'reset_last_seen ' ;
845+ $ _GET ['user_id ' ] = $ site_user_id ;
846+ $ _GET ['reset_last_seen_nonce ' ] = wp_create_nonce ( 'reset_last_seen_action ' );
847+
848+ // Mock wp_safe_redirect to prevent actual redirect during test
849+ add_filter ( 'wp_redirect ' , function () {
850+ // Just return false to prevent actual redirect
851+ return false ;
852+ });
853+
854+ // Call the unblock action method
855+ Inactive_Users::last_seen_unblock_action ();
856+
857+ // Verify that the user was successfully unblocked (should no longer be considered inactive)
858+ $ this ->assertFalse ( Inactive_Users::is_considered_inactive ( $ site_user_id ) );
859+
860+ // Clean up
861+ wp_delete_user ( $ site_user_id );
862+ wp_delete_user ( $ super_admin_id );
863+ unset( $ _GET ['action ' ], $ _GET ['user_id ' ], $ _GET ['reset_last_seen_nonce ' ] );
864+ }
865+
866+ /**
867+ * Test that single-site unblock action
868+ */
869+ public function test_single_site_unblock_action () {
870+ if ( is_multisite () ) {
871+ $ this ->markTestSkipped ( 'This test is for single-site installations only ' );
872+ }
873+
874+ // Create a user
875+ $ user_id = $ this ->factory ->user ->create ([
876+ 'role ' => 'administrator ' ,
877+ 'user_registered ' => gmdate ( 'Y-m-d H:i:s ' , strtotime ( '-100 days ' ) ),
878+ ]);
879+
880+ // Make the user inactive
881+ update_user_meta ( $ user_id , Inactive_Users::LAST_SEEN_META_KEY , strtotime ( '-91 days ' ) );
882+ delete_user_meta ( $ user_id , Inactive_Users::LAST_SEEN_IGNORE_INACTIVITY_CHECK_UNTIL_META_KEY );
883+
884+ // Create an admin user
885+ $ admin_user_id = $ this ->factory ->user ->create ([
886+ 'role ' => 'administrator ' ,
887+ ]);
888+
889+ // Set the current user to the admin
890+ wp_set_current_user ( $ admin_user_id );
891+
892+ // Verify the user is initially inactive
893+ $ this ->assertTrue ( Inactive_Users::is_considered_inactive ( $ user_id ) );
894+
895+ // Simulate the unblock action request
896+ $ _GET ['action ' ] = 'reset_last_seen ' ;
897+ $ _GET ['user_id ' ] = $ user_id ;
898+ $ _GET ['reset_last_seen_nonce ' ] = wp_create_nonce ( 'reset_last_seen_action ' );
899+
900+ // Mock wp_safe_redirect to prevent actual redirect during test
901+ add_filter ( 'wp_redirect ' , function () {
902+ return false ;
903+ });
904+
905+ // Call the unblock action method
906+ Inactive_Users::last_seen_unblock_action ();
907+
908+ // Verify that the user was successfully unblocked (should no longer be considered inactive)
909+ $ this ->assertFalse ( Inactive_Users::is_considered_inactive ( $ user_id ) );
910+
911+ // Clean up
912+ wp_delete_user ( $ user_id );
913+ wp_delete_user ( $ admin_user_id );
914+ unset( $ _GET ['action ' ], $ _GET ['user_id ' ], $ _GET ['reset_last_seen_nonce ' ] );
915+ }
752916}
0 commit comments