Je travaille sur un plugin dérivé de ce tutorial . Jusqu'à présent, le plug-in ajoute une case à cocher sur la page d'édition du profil d'un utilisateur, où les administrateurs peuvent interdire l'utilisateur.
Si cette case est cochée, l'utilisateur recevra un message lors de sa connexion:
Ça fonctionne bien. Le problème est que si l'utilisateur est déjà connecté (a une session active) et est banni, l'utilisateur peut continuer à interagir avec le site jusqu'à ce que soit que la session se termine ou que l'utilisateur se déconnecte.
Comment puis-je terminer la session de l'utilisateur lors de l'interdiction afin que l'utilisateur soit expulsé?
Voici le code:
/**
* Admin init
*
* @access public
* @since 1.0
* @return void
*/
function rc_admin_init(){
// Edit user profile
add_action( 'edit_user_profile', 'rc_edit_user_profile' );
add_action( 'edit_user_profile_update', 'rc_edit_user_profile_update' );
}
add_action('admin_init', 'rc_admin_init' );
/**
* Adds custom checkbox to user edition page
*
* @access public
* @since 1.0
* @return void
*/
function rc_edit_user_profile() {
if ( !current_user_can( 'edit_users' ) ) {
return;
}
global $user_id;
// User cannot disable itself
$current_user = wp_get_current_user();
$current_user_id = $current_user->ID;
if ( $current_user_id == $user_id ) {
return;
}
?>
<h3>Ban user</h3>
<table class="form-table">
<tr>
<th scope="row"></th>
<td><label for="rc_ban"><input name="rc_ban" type="checkbox" id="rc_ban" /> Check to ban user.</label></td>
</tr>
</table>
<?php
}
/**
* Save custom checkbox
*
* @access public
* @since 1.0
* @return void
*/
function rc_edit_user_profile_update() {
if ( !current_user_can( 'edit_users' ) ) {
return;
}
global $user_id;
// User cannot disable itself
$current_user = wp_get_current_user();
$current_user_id = $current_user->ID;
if ( $current_user_id == $user_id ) {
return;
}
// Lock
if( isset( $_POST['rc_ban'] ) && $_POST['rc_ban'] = 'on' ) {
rc_ban_user( $user_id );
} else { // Unlock
rc_unban_user( $user_id );
}
}
/**
* Ban user
*
* @access public
* @since 1.0
* @return void
*/
function rc_ban_user( $user_id ) {
$old_status = rc_is_user_banned( $user_id );
// Update status
if ( !$old_status ) {
update_user_option( $user_id, 'rc_banned', true, false );
}
}
/**
* Un-ban user
*
* @access public
* @since 1.0
* @return void
*/
function rc_unban_user( $user_id ) {
$old_status = rc_is_user_banned( $user_id );
// Update status
if ( $old_status ) {
update_user_option( $user_id, 'rc_banned', false, false );
}
}
/**
* Checks if a user is already banned
*
* @access public
* @since 1.0
* @return void
*/
function rc_is_user_banned( $user_id ) {
return get_user_option( 'rc_banned', $user_id, false );
}
/**
* Check if user is locked while login process
*
* @access public
* @since 1.0
* @return void
*/
function rc_authenticate_user( $user ) {
if ( is_wp_error( $user ) ) {
return $user;
}
// Return error if user account is banned
$banned = get_user_option( 'rc_banned', $user->ID, false );
if ( $banned ) {
return new WP_Error( 'rc_banned', __('<strong>ERROR</strong>: This user account is disabled.', 'rc') );
}
return $user;
}
add_filter( 'wp_authenticate_user', 'rc_authenticate_user', 1 );
Donc, la fin de la session devrait aller dans la fonction rc_ban_user()
.
EDIT: Plugin complet posté en dessous .
Utilisez wp_logout()
. Il appelle wp_clear_auth_cookie()
et invalide immédiatement les informations de connexion actuelles.
Exemple de code, non testé:
add_action( 'init', 'log_out_banned_user' );
function log_out_banned_user() {
if ( ! is_user_logged_in() )
return;
$user = wp_get_current_user();
if ( ! get_user_option( 'rc_banned', $user->ID, false ) )
return;
wp_logout();
wp_redirect( home_url( '/' ) );
exit;
}
Bien que la méthode de toscho fonctionne, une approche plus simple pourrait consister à utiliser le crochet authenticate
pour les empêcher de s'authentifier via un cookie, ou tout autre moyen, de manière plus directe.
Code totalement non testé. Devrait travailler si.
// the priority of 999 is to ensure it's last in the auth chain
add_filter('authenticate', 'force_fail_banned_users', 999, 3);
function force_fail_banned_users($user, $username, $password) {
if ( ! is_a($user, 'WP_User') ) {
// we only care about actual users who already auth'd okay via some means
return $user;
}
if ( rc_is_user_banned( $user->ID ) ) {
// user is banned, so return a failure case
return new WP_Error('banned_user', 'Banned message goes here.');
}
// user not banned, so return the user normally
return $user;
}
La chaîne de filtres d'authentification vous permet de décider si un utilisateur est authentifié ou non à toutes les occasions possibles pour s'authentifier. Le renvoi d'une valeur WP_User les connecte. Le renvoi d'un WP_Error de n'importe quel type échoue, mais sa tentative d'authentification a échoué, quelle que soit la méthode employée, que ce soit via nom d'utilisateur/mot de passe ou via cookie.
J'écris aussi un plugin similaire et l'ai déjà publié sur WordPress.org. Je pense que la meilleure solution déposer la session utilisateur immédiatement puis administrateur cliquez sur le bouton "interdire" (bloquer) (lien). Ceci possible avec la classe WP_Session_Tokens
:
$manager = \WP_Session_Tokens::get_instance( $user_id );
$manager->destroy_all();
Et même si l'utilisateur est actuellement autorisé et que certaines pages de /wp-admin/
sont ouvertes, elles seront forcées de se déconnecter car nous abandonnons déjà des sessions (immédiatement).
Code source: https://wordpress.org/plugins/mark-user-as-spammer/
Le plugin est maintenant prêt à être utilisé et fonctionne avec élégance. Merci à Remi pour le didacticiel original et toscho (le bot) pour la solution opérationnelle à la session de l’utilisateur final après interdiction.
Je prévois ce qui suit pour les futures mises à jour:
Laissez un commentaire si vous avez des suggestions de mise à jour. Je vais éditer cette réponse chaque fois qu'il y a des mises à jour du plugin.
Créez un dossier nommé ban-users
dans votre dossier de plug-in et créez un fichier nommé ban-users.php
avec le code suivant:
<?php
/*
Plugin Name: Ban Users
Plugin URI: http://wordpress.stackexchange.com/questions/123902/ban-a-user-and-end-their-session
Description: Allows you to ban users
Author: Christine Cooper, Remi, toscho
Version: 1.1
Author URI: http://wordpress.stackexchange.com/questions/123902/ban-a-user-and-end-their-session
*/
/**
* Admin init
*
* @access public
* @since 1.0
* @return void
*/
function rc_admin_init(){
// Edit user profile
add_action( 'edit_user_profile', 'rc_edit_user_profile' );
add_action( 'edit_user_profile_update', 'rc_edit_user_profile_update' );
}
add_action('admin_init', 'rc_admin_init' );
/**
* Adds custom checkbox to user edition page
*
* @access public
* @since 1.0
* @return void
*/
function rc_edit_user_profile() {
if ( !current_user_can( 'edit_users' ) ) {
return;
}
global $user_id;
// User cannot disable itself
$current_user = wp_get_current_user();
$current_user_id = $current_user->ID;
if ( $current_user_id == $user_id ) {
return;
}
?>
<h3>Ban User</h3>
<table class="form-table">
<tr>
<th scope="row"></th>
<td><label for="rc_ban"><input name="rc_ban" type="checkbox" id="rc_ban" <?php if ( get_user_option( 'rc_banned', $user_id, false ) ) { echo 'checked'; } ?> /> Check to ban user </label></td>
</tr>
</table>
<?php
}
/**
* Save custom checkbox
*
* @access public
* @since 1.0
* @return void
*/
function rc_edit_user_profile_update() {
if ( !current_user_can( 'edit_users' ) ) {
return;
}
global $user_id;
// User cannot disable itself
$current_user = wp_get_current_user();
$current_user_id = $current_user->ID;
if ( $current_user_id == $user_id ) {
return;
}
// Lock
if( isset( $_POST['rc_ban'] ) && $_POST['rc_ban'] = 'on' ) {
rc_ban_user( $user_id );
} else { // Unlock
rc_unban_user( $user_id );
}
}
/**
* Ban user
*
* @access public
* @since 1.0
* @return void
*/
function rc_ban_user( $user_id ) {
$old_status = rc_is_user_banned( $user_id );
// Update status
if ( !$old_status ) {
update_user_option( $user_id, 'rc_banned', true, false );
}
}
/**
* Un-ban user
*
* @access public
* @since 1.0
* @return void
*/
function rc_unban_user( $user_id ) {
$old_status = rc_is_user_banned( $user_id );
// Update status
if ( $old_status ) {
update_user_option( $user_id, 'rc_banned', false, false );
}
}
/**
* Checks if a user is already banned
*
* @access public
* @since 1.0
* @return void
*/
function rc_is_user_banned( $user_id ) {
return get_user_option( 'rc_banned', $user_id, false );
}
/**
* End a users active session if they are banned
* By toscho http://wordpress.stackexchange.com/a/123903/24875
*
* @access public
* @since 1.1
* @return void
*/
add_action( 'init', 'log_out_banned_user' );
function log_out_banned_user() {
if ( ! is_user_logged_in() )
return;
$user = wp_get_current_user();
if ( ! get_user_option( 'rc_banned', $user->ID, false ) )
return;
wp_logout();
wp_redirect( home_url( '/' ) );
exit;
}
/**
* Check if user is locked while login process
*
* @access public
* @since 1.0
* @return void
*/
function rc_authenticate_user( $user ) {
if ( is_wp_error( $user ) ) {
return $user;
}
// Return error if user account is banned
$banned = get_user_option( 'rc_banned', $user->ID, false );
if ( $banned ) {
return new WP_Error( 'rc_banned', __('<strong>ERROR</strong>: Your user account has been disabled.', 'rc') );
}
return $user;
}
add_filter( 'wp_authenticate_user', 'rc_authenticate_user', 1 );