LLMS_Prevent_Concurrent_Logins
Contents
Source Source
File: includes/class-llms-prevent-concurrent-logins.php
class LLMS_Prevent_Concurrent_Logins {
use LLMS_Trait_Singleton;
/**
* Array of sessions for the current user.
*
* @var array
*/
private $user_sessions;
/**
* Current user ID.
*
* @var int
*/
private $user_id;
/**
* Private Constructor.
*
* @since 5.6.0
*
* @return void
*/
private function __construct() {
if ( llms_parse_bool( get_option( 'lifterlms_prevent_concurrent_logins', 'no' ) ) &&
! empty( get_option( 'lifterlms_prevent_concurrent_logins_roles', array( 'student' ) ) ) ) {
add_action( 'init', array( $this, 'init' ) );
add_action( 'init', array( $this, 'maybe_prevent_concurrent_logins' ) );
}
}
/**
* Initialize.
*
* @since 5.6.0
*
* @return void
*/
public function init() {
$this->user_id = get_current_user_id();
if ( empty( $this->user_id ) ) {
return;
}
$this->user_sessions = wp_get_all_sessions();
}
/**
* Maybe prevent current logins.
*
* @since 5.6.0
*
* @return bool `true` if concurrent login prevented, `false` otherwise.
*/
public function maybe_prevent_concurrent_logins() {
// No logged in user or current user has only one active session: nothing to do.
if ( empty( $this->user_sessions ) || count( $this->user_sessions ) < 2 ) {
return false;
}
/**
* Filters whether or not allowing a specific user to have concurrent sessions.
*
* @since 5.6.0
*
* @param bool $allow Whether or not the user should be allowed to have concurrent sessions.
* @param int $user_id WP_User ID of the current use.
*/
if ( (bool) apply_filters( 'llms_allow_user_concurrent_logins', false, $this->user_id ) ) {
return false;
}
// Current user doesn't have any restricted role: nothing to do.
if ( empty( array_intersect( get_userdata( $this->user_id )->roles, (array) get_option( 'lifterlms_prevent_concurrent_logins_roles', array( 'student' ) ) ) ) ) {
return false;
}
$this->destroy_all_sessions_but_newest();
return true;
}
/**
* Prevent login by destroying all the user's sessions but the newest.
*
* @since 5.6.0
*
* @return int 1 if the kept session is the current one, 0 otherwise.
*/
private function destroy_all_sessions_but_newest() {
$is_current_session_newest_session = $this->current_user_newest_session_login_time() === $this->current_user_current_session_login_time();
$is_current_session_newest_session
?
wp_destroy_other_sessions()
:
wp_destroy_current_session();
return (int) $is_current_session_newest_session;
}
/**
* Retrieve current session for the current user.
*
* @since 5.6.0
*
* @return int
*/
private function current_user_current_session_login_time() {
$sessions = WP_Session_Tokens::get_instance( $this->user_id );
return $sessions->get( wp_get_session_token() )['login'];
}
/**
* Retrieve newest session login time for the current user.
*
* The bigger the login time is the newest the session is.
*
* @since 5.6.0
*
* @return int
*/
private function current_user_newest_session_login_time() {
return max( array_column( $this->user_sessions, 'login' ) );
}
}
Expand full source code Collapse full source code View on GitHub
Methods Methods
- __construct — Private Constructor.
- current_user_current_session_login_time — Retrieve current session for the current user.
- current_user_newest_session_login_time — Retrieve newest session login time for the current user.
- destroy_all_sessions_but_newest — Prevent login by destroying all the user's sessions but the newest.
- init — Initialize.
- maybe_prevent_concurrent_logins — Maybe prevent current logins.
Changelog Changelog
| Version | Description |
|---|---|
| 5.6.0 | Introduced. |