v1.0.0
This commit is contained in:
parent
3291a5f7d2
commit
212d64abfa
27 changed files with 8654 additions and 2 deletions
268
includes/class-bulk-actions.php
Normal file
268
includes/class-bulk-actions.php
Normal file
|
|
@ -0,0 +1,268 @@
|
|||
<?php
|
||||
/**
|
||||
* Bulk actions handler
|
||||
*
|
||||
* @package TwoFactorExtended
|
||||
* @since 0.1.0
|
||||
*/
|
||||
|
||||
// Prevent direct access.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class Two_Factor_Extended_Bulk_Actions
|
||||
*
|
||||
* Handles bulk actions for users.
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
class Two_Factor_Extended_Bulk_Actions {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->init_hooks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize WordPress hooks.
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
private function init_hooks(): void {
|
||||
// Add bulk actions to users list.
|
||||
add_filter( 'bulk_actions-users', array( $this, 'register_bulk_actions' ) );
|
||||
|
||||
// Handle bulk actions.
|
||||
add_filter( 'handle_bulk_actions-users', array( $this, 'handle_bulk_actions' ), 10, 3 );
|
||||
|
||||
// Display admin notices after bulk actions.
|
||||
add_action( 'admin_notices', array( $this, 'display_bulk_action_notices' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register bulk actions.
|
||||
*
|
||||
* @since 0.1.0
|
||||
*
|
||||
* @param array $actions Existing bulk actions.
|
||||
*
|
||||
* @return array Modified bulk actions.
|
||||
*/
|
||||
public function register_bulk_actions( array $actions ): array {
|
||||
if ( ! current_user_can( 'manage_options' ) ) {
|
||||
return $actions;
|
||||
}
|
||||
|
||||
$actions['two_factor_extended_require'] = __( 'Require 2FA Setup', 'two-factor-extended' );
|
||||
$actions['two_factor_extended_reset'] = __( 'Reset 2FA Grace Period', 'two-factor-extended' );
|
||||
|
||||
return $actions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle bulk actions.
|
||||
*
|
||||
* @since 0.1.0
|
||||
*
|
||||
* @param string $redirect_to Redirect URL.
|
||||
* @param string $action Action name.
|
||||
* @param array $user_ids User IDs.
|
||||
*
|
||||
* @return string Modified redirect URL.
|
||||
*/
|
||||
public function handle_bulk_actions( string $redirect_to, string $action, array $user_ids ): string {
|
||||
// Check capability.
|
||||
if ( ! current_user_can( 'manage_options' ) ) {
|
||||
return $redirect_to;
|
||||
}
|
||||
|
||||
// Handle our bulk actions.
|
||||
if ( 'two_factor_extended_require' === $action ) {
|
||||
$processed = $this->bulk_require_2fa( $user_ids );
|
||||
|
||||
$redirect_to = add_query_arg(
|
||||
array(
|
||||
'two_factor_extended_bulk_require' => $processed,
|
||||
),
|
||||
$redirect_to
|
||||
);
|
||||
} elseif ( 'two_factor_extended_reset' === $action ) {
|
||||
$processed = $this->bulk_reset_grace_period( $user_ids );
|
||||
|
||||
$redirect_to = add_query_arg(
|
||||
array(
|
||||
'two_factor_extended_bulk_reset' => $processed,
|
||||
),
|
||||
$redirect_to
|
||||
);
|
||||
}
|
||||
|
||||
return $redirect_to;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bulk require 2FA for users.
|
||||
*
|
||||
* @since 0.1.0
|
||||
*
|
||||
* @param array $user_ids User IDs.
|
||||
*
|
||||
* @return int Number of users processed.
|
||||
*/
|
||||
private function bulk_require_2fa( array $user_ids ): int {
|
||||
$processed = 0;
|
||||
$enforcement = two_factor_extended()->get_enforcement();
|
||||
|
||||
foreach ( $user_ids as $user_id ) {
|
||||
// Skip if user doesn't exist.
|
||||
$user = get_userdata( $user_id );
|
||||
if ( ! $user ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get required providers for user.
|
||||
$required = $enforcement->get_required_providers_for_user( $user_id );
|
||||
|
||||
// Skip if no requirements.
|
||||
if ( empty( $required ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Set enforcement start date to now (starts grace period).
|
||||
update_user_meta( $user_id, Two_Factor_Extended_Enforcement::META_ENFORCEMENT_START, time() );
|
||||
|
||||
// Log the action.
|
||||
two_factor_extended()->get_audit_log()->log_event(
|
||||
'bulk_require_2fa',
|
||||
sprintf(
|
||||
'Bulk action: Require 2FA for user %s',
|
||||
$user->user_login
|
||||
),
|
||||
$user_id,
|
||||
array(
|
||||
'required_providers' => $required,
|
||||
)
|
||||
);
|
||||
|
||||
$processed++;
|
||||
}
|
||||
|
||||
return $processed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bulk reset grace period for users.
|
||||
*
|
||||
* @since 0.1.0
|
||||
*
|
||||
* @param array $user_ids User IDs.
|
||||
*
|
||||
* @return int Number of users processed.
|
||||
*/
|
||||
private function bulk_reset_grace_period( array $user_ids ): int {
|
||||
$processed = 0;
|
||||
|
||||
foreach ( $user_ids as $user_id ) {
|
||||
// Skip if user doesn't exist.
|
||||
$user = get_userdata( $user_id );
|
||||
if ( ! $user ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Reset enforcement start date (restarts grace period).
|
||||
update_user_meta( $user_id, Two_Factor_Extended_Enforcement::META_ENFORCEMENT_START, time() );
|
||||
|
||||
// Clear grace period notified flag.
|
||||
delete_user_meta( $user_id, Two_Factor_Extended_Enforcement::META_GRACE_NOTIFIED );
|
||||
|
||||
// Log the action.
|
||||
two_factor_extended()->get_audit_log()->log_event(
|
||||
'bulk_reset_grace',
|
||||
sprintf(
|
||||
'Bulk action: Reset grace period for user %s',
|
||||
$user->user_login
|
||||
),
|
||||
$user_id
|
||||
);
|
||||
|
||||
$processed++;
|
||||
}
|
||||
|
||||
return $processed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display admin notices after bulk actions.
|
||||
*
|
||||
* This method displays success messages after bulk actions are completed.
|
||||
* No nonce verification is needed here because:
|
||||
* 1. This is a read-only operation (displaying a message)
|
||||
* 2. The actual bulk action was already verified in handle_bulk_actions()
|
||||
* 3. The GET parameters are the result of a POST-redirect-GET pattern
|
||||
* 4. Only the count is used, which is safely cast to int
|
||||
* 5. User capability is verified before displaying
|
||||
*
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public function display_bulk_action_notices(): void {
|
||||
// Check if on users page.
|
||||
$screen = get_current_screen();
|
||||
if ( ! $screen || 'users' !== $screen->id ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Verify user has capability to see these notices.
|
||||
if ( ! current_user_can( 'manage_options' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Bulk require 2FA notice.
|
||||
// Use filter_input() for safe GET parameter access.
|
||||
$bulk_require_count = filter_input( INPUT_GET, 'two_factor_extended_bulk_require', FILTER_VALIDATE_INT );
|
||||
|
||||
if ( $bulk_require_count && $bulk_require_count > 0 ) {
|
||||
printf(
|
||||
'<div class="notice notice-success is-dismissible"><p>%s</p></div>',
|
||||
esc_html(
|
||||
sprintf(
|
||||
/* translators: %d: Number of users */
|
||||
_n(
|
||||
'2FA requirement set for %d user.',
|
||||
'2FA requirement set for %d users.',
|
||||
$bulk_require_count,
|
||||
'two-factor-extended'
|
||||
),
|
||||
$bulk_require_count
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Bulk reset grace period notice.
|
||||
$bulk_reset_count = filter_input( INPUT_GET, 'two_factor_extended_bulk_reset', FILTER_VALIDATE_INT );
|
||||
|
||||
if ( $bulk_reset_count && $bulk_reset_count > 0 ) {
|
||||
printf(
|
||||
'<div class="notice notice-success is-dismissible"><p>%s</p></div>',
|
||||
esc_html(
|
||||
sprintf(
|
||||
/* translators: %d: Number of users */
|
||||
_n(
|
||||
'Grace period reset for %d user.',
|
||||
'Grace period reset for %d users.',
|
||||
$bulk_reset_count,
|
||||
'two-factor-extended'
|
||||
),
|
||||
$bulk_reset_count
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue