handle user roles by organization
This commit is contained in:
@@ -0,0 +1,200 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Handles user authentication for wiaas
|
||||
*
|
||||
* User roles are inherited from organization
|
||||
*
|
||||
* Class Wiaas_Authentication
|
||||
*/
|
||||
class Wiaas_Authentication {
|
||||
|
||||
const SUPER_ADMIN_USER_ID = 1;
|
||||
|
||||
public static function init() {
|
||||
// authenticate current user
|
||||
add_action('determine_current_user', array(__CLASS__, 'authenticate_current_user'), 999);
|
||||
|
||||
// authenticates user on login
|
||||
add_filter( 'authenticate', array( __CLASS__, 'authenticate_user_on_login' ), 999, 3);
|
||||
|
||||
// retrieve preferred user role for user
|
||||
add_filter('get_user_metadata', array(__CLASS__, 'maybe_filter_user_roles'), 10, 3);
|
||||
|
||||
// redirect to dashboard after login
|
||||
add_filter( 'login_redirect', array( __CLASS__, 'login_redirect' ) );
|
||||
|
||||
// add role selector to login form
|
||||
add_action('login_form', array(__CLASS__, 'pick_role_on_login'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect admin user to dashboard
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function login_redirect() {
|
||||
return admin_url('index.php') ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add role selector to login form
|
||||
*/
|
||||
public static function pick_role_on_login() {
|
||||
?>
|
||||
<p>
|
||||
<label for="user_role"><?php esc_html_e( 'Role' , 'wiaas'); ?><br />
|
||||
<select id="user_role" class="input" name="role">
|
||||
<option value="administrator"><?php esc_html_e('Administrator', 'wiaas') ?></option>
|
||||
<option value="supplier"><?php esc_html_e('Supplier', 'wiaas') ?></option>
|
||||
<option value="commercial_lead"><?php esc_html_e('Commercial Lead', 'wiaas') ?></option>
|
||||
</select>
|
||||
</p>
|
||||
<?php
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Authenticate current user based on roles assigned to organization
|
||||
*
|
||||
* @param int|false $user_id
|
||||
* @return int|false|WP_Error
|
||||
*/
|
||||
public static function authenticate_current_user($user_id) {
|
||||
// do nothing if user not authenticated, user is super admin or this is REST API request
|
||||
if (! $user_id || $user_id === self::SUPER_ADMIN_USER_ID) {
|
||||
return $user_id;
|
||||
}
|
||||
|
||||
$is_rest_api = strpos($_SERVER['REQUEST_URI'], rest_get_url_prefix());
|
||||
|
||||
$role = $is_rest_api ?
|
||||
'customer' :
|
||||
get_user_meta($user_id, '_wiaas_current_user_admin_role', true);
|
||||
|
||||
$result = self::_can_user_have_role($user_id, $role, $is_rest_api);
|
||||
|
||||
if (is_wp_error($result)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $user_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Authenticate wiaas user on login based on roles assigned to organization
|
||||
*
|
||||
* @param WP_User $user
|
||||
* @return WP_User|WP_Error
|
||||
*/
|
||||
public static function authenticate_user_on_login($user) {
|
||||
// check if rest request
|
||||
$is_rest_api = strpos($_SERVER['REQUEST_URI'], rest_get_url_prefix());
|
||||
// do nothing if there is an error already,
|
||||
// user is super admin or
|
||||
// this is rest request
|
||||
if (is_wp_error($user) || $user->ID === 1 || $is_rest_api) {
|
||||
return $user;
|
||||
}
|
||||
|
||||
if (empty($_POST['role'])) {
|
||||
return new WP_Error('error', 'You must selected role to login!');
|
||||
}
|
||||
|
||||
// get selected role
|
||||
$requested_role = sanitize_key($_POST['role']);
|
||||
|
||||
// validate can user have requested role
|
||||
$result = self::_can_user_have_role($user->ID, $requested_role, false);
|
||||
|
||||
// if user organization has no requested role prevent access
|
||||
if (is_wp_error($result)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
// remember role for user and continue
|
||||
update_user_meta($user->ID, '_wiaas_current_user_admin_role', $requested_role);
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Filters user roles retrieval so that selected user role is retrieved for admin panel
|
||||
* and customer role is retrieved for JSON API request
|
||||
*
|
||||
* @param $null
|
||||
* @param int $user_id
|
||||
* @param string $meta_key
|
||||
* @return array|null
|
||||
*/
|
||||
public static function maybe_filter_user_roles($null, $user_id, $meta_key) {
|
||||
|
||||
global $wpdb;
|
||||
|
||||
if ($user_id !== 0 && $user_id !== self::SUPER_ADMIN_USER_ID && $meta_key === $wpdb->get_blog_prefix() . 'capabilities') {
|
||||
|
||||
$is_rest_api = strpos($_SERVER['REQUEST_URI'], rest_get_url_prefix());
|
||||
|
||||
$role = $is_rest_api ?
|
||||
'customer' :
|
||||
get_user_meta($user_id, '_wiaas_current_user_admin_role', true);
|
||||
|
||||
return array( array ( "$role" => true ));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// PRIVATE
|
||||
|
||||
/**
|
||||
* Determines if user can have requested role based on his organization roles
|
||||
*
|
||||
* @param int $user_id
|
||||
* @param string $user_role
|
||||
* @param bool $is_rest_api
|
||||
* @return bool|WP_Error
|
||||
*/
|
||||
private static function _can_user_have_role($user_id, $user_role, $is_rest_api) {
|
||||
// check if role valid for access
|
||||
if (! wp_roles()->is_role($user_role)) {
|
||||
return new WP_Error('error', 'Role is not valid!');
|
||||
}
|
||||
|
||||
// only customer role can access API
|
||||
if ($is_rest_api && $user_role !== 'customer') {
|
||||
return new WP_Error('error', 'No access!');
|
||||
}
|
||||
|
||||
// customer role cannot access admin backend
|
||||
if (! $is_rest_api && $user_role === 'customer') {
|
||||
return new WP_Error('error', 'No access!');
|
||||
}
|
||||
|
||||
// import organization functions (during user authentication it is not yet loaded)
|
||||
require_once dirname( __FILE__ ) . '/user/wiaas-organization-functions.php';
|
||||
|
||||
// get user organization
|
||||
$organization_id = wiaas_get_user_organization_id($user_id);
|
||||
|
||||
// validate if user has organization
|
||||
if (empty( $organization_id)) {
|
||||
return new WP_Error('error', 'Account not completed!');
|
||||
}
|
||||
// get organization roles
|
||||
$roles = wiaas_get_organization_roles($organization_id);
|
||||
|
||||
// validate if user has organization roles
|
||||
if (!in_array($user_role, $roles)) {
|
||||
return new WP_Error( 'error', 'Your account is not authorized for requested role. Please contact us for help.' );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Wiaas_Authentication::init();
|
||||
Reference in New Issue
Block a user