Skip to content

Commit

Permalink
Change auth flags event to be in context of a user
Browse files Browse the repository at this point in the history
The core will trigger this event with a username (for users not in the system)
or username + user id for usernames already registered.

The plugin can return the flags for this specific user,
or core will use the defaults.
  • Loading branch information
vboctor committed Apr 16, 2017
1 parent 21af4d2 commit 6935b44
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 17 deletions.
58 changes: 50 additions & 8 deletions core/authentication_api.php
Expand Up @@ -75,17 +75,57 @@
$g_cache_current_user_id = null;

/**
* Gets set of flags for authentication that can be overridden by configuration or auth plugins.
* Gets set of flags for authentication for the specified user.
* @param int|null|bool The user id or null for logged in user or NO_USER/false for user that doesn't exist
* in the system, that may be auto-provisioned.
* @return AuthFlags The auth flags object to use.
*/
function auth_flags() {
static $s_flags = null;
if( is_null( $s_flags ) ) {
function auth_flags( $p_user_id = null, $p_username = '' ) {
if( is_null( $p_user_id ) ) {
$t_user_id = auth_get_current_user_id();
} else {
$t_user_id = (int)$p_user_id;
}

if( !$t_user_id && is_blank( $p_username ) ) {
# If user is not in db, must supply the name.
trigger_error( GENERIC_ERROR );
}

if( $t_user_id ) {
$t_username = user_get_name( $t_user_id );
$t_email = user_get_email( $t_user_id );
} else {
$t_username = $p_username;

# If the plugin cares about email, then it can check if user typed the email address
# as the username.
$t_email = '';
}

$t_event_arguments = array(
'user_id' => $t_user_id,
'username' => $t_username,
'email' => $t_email,
);

static $s_flags_cache = array();
if( !isset( $s_flags_cache[$t_user_id] ) ) {
$t_flags = event_signal( 'EVENT_AUTH_USER_FLAGS', array( $t_event_arguments ) );

# Don't cache in case of user not in db.
if( $t_user_id ) {
$s_flags_cache[$t_flags] = $t_flags;
}
} else {
$t_flags = $s_flags_cache[$t_user_id];
}

if( is_null( $t_flags ) ) {
$t_flags = new AuthFlags();
$s_flags = event_signal( 'EVENT_AUTH_FLAGS', $t_flags );
}

return $s_flags;
return $t_flags;
}

/**
Expand All @@ -108,10 +148,12 @@ function auth_password_change_not_allowed_message() {

/**
* Check if permanent login is enabled.
* @param int|bool $p_user_id The user id, or NO_USER/false for unknown user.
* @param string $p_username The username user typed in sign-in form.
* @return boolean true: yes, false: otherwise.
*/
function auth_allow_perm_login() {
$t_auth_flags = auth_flags();
function auth_allow_perm_login( $p_user_id, $p_username ) {
$t_auth_flags = auth_flags( $p_user_id, $p_username );
return $t_auth_flags->getPermSessionEnabled();
}

Expand Down
2 changes: 1 addition & 1 deletion core/events_inc.php
Expand Up @@ -148,5 +148,5 @@
'EVENT_LOG' => EVENT_TYPE_EXECUTE,

# Authentication Events
'EVENT_AUTH_FLAGS' => EVENT_TYPE_CHAIN,
'EVENT_AUTH_USER_FLAGS' => EVENT_TYPE_FIRST,
) );
14 changes: 10 additions & 4 deletions docbook/Developers_Guide/en-US/Events_Reference.xml
Expand Up @@ -157,14 +157,20 @@
</blockquote>

<blockquote id="dev.eventref.auth.flags">
<title>EVENT_AUTH_FLAGS (First)</title>
<title>EVENT_AUTH_USER_FLAGS (First)</title>

<blockquote>
<para>
An event that enables plugins to return a set of flags that control the authentication
behaviors and can provide their own login flow pages. For list of supported flags
check auth_flags() method in core/authentication_api. Only a single auth plugin can be
hooked to this. Flags that are not returned by the plugin will be set to defaults.
behaviors for the user who is logging in or logged in. In some cases, the user will be
in the system, but there will be cases where the username provided by the user doesn't
exist. In case the user doesn't exist, it is up to the authentication plugin whether
to fail the login, validate credentials then fail, or validate credentials then auto-provision
the user based on information the plugin is aware of (e.g. IDP or some db of accounts).
If no plugin is registered for events, then defaults are used. If plugin sets a subset
of the options, then the default will be used for the rest.
</para>
<para>
Checkout <ulink url="https://github.com/mantisbt-plugins/SampleAuth">SampleAuth plugin</ulink>
for more details.
</para>
Expand Down
7 changes: 4 additions & 3 deletions login.php
Expand Up @@ -41,11 +41,8 @@
require_api( 'session_api.php' );
require_api( 'string_api.php' );

$t_allow_perm_login = auth_allow_perm_login();

$f_username = gpc_get_string( 'username', '' );
$f_password = gpc_get_string( 'password', '' );
$f_perm_login = $t_allow_perm_login && gpc_get_bool( 'perm_login' );
$t_return = string_url( string_sanitize_url( gpc_get_string( 'return', config_get( 'default_home_page' ) ) ) );
$f_from = gpc_get_string( 'from', '' );
$f_secure_session = gpc_get_bool( 'secure_session', false );
Expand All @@ -60,6 +57,10 @@
$f_username = auth_prepare_username( $f_username );
$f_password = auth_prepare_password( $f_password );

$t_user_id = auth_get_user_id_from_login_name( $f_username );
$t_allow_perm_login = auth_allow_perm_login( $t_user_id, $f_username );
$f_perm_login = $t_allow_perm_login && gpc_get_bool( 'perm_login' );

gpc_set_cookie( config_get_global( 'cookie_prefix' ) . '_secure_session', $f_secure_session ? '1' : '0' );

if( auth_attempt_login( $f_username, $f_password, $f_perm_login ) ) {
Expand Down
2 changes: 1 addition & 1 deletion login_password_page.php
Expand Up @@ -115,7 +115,7 @@
( ON == config_get( 'send_reset_password' ) ) &&
( ON == config_get( 'enable_email_notification' ) );

$t_show_remember_me = !$f_reauthenticate && auth_allow_perm_login();
$t_show_remember_me = !$f_reauthenticate && auth_allow_perm_login( $t_user_id, $t_username );

$t_form_title = $f_reauthenticate ? lang_get( 'reauthenticate_title' ) : lang_get( 'login_title' );

Expand Down

0 comments on commit 6935b44

Please sign in to comment.