-
Notifications
You must be signed in to change notification settings - Fork 8
Autoprovision and Authenticator support with detailed examples #5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
7811aa4
2a18ba2
d252c56
d109439
9feb9b4
5c96390
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,9 +15,9 @@ function register() { | |
| $this->description = plugin_lang_get( 'description' ); | ||
| $this->page = ''; | ||
|
|
||
| $this->version = '0.1'; | ||
| $this->version = '0.2'; | ||
| $this->requires = array( | ||
| 'MantisCore' => '2.3.0-dev', | ||
| 'MantisCore' => '2.14.0-dev', | ||
| ); | ||
|
|
||
| $this->author = 'MantisBT Team'; | ||
|
|
@@ -37,16 +37,23 @@ function hooks() { | |
| return $t_hooks; | ||
| } | ||
|
|
||
| function config() { | ||
| return array( | ||
| # set to 'true', if the plugin can do autoprovisioning - otherwise only "known" users will be able to log in | ||
| 'autoprovision' => true, | ||
| # sets the access level configured by autoprov; defaults to system configures default access level | ||
| 'default_access_level' => config_get( 'default_new_account_access_level' ) | ||
| ); | ||
| } | ||
|
|
||
| function auth_user_flags( $p_event_name, $p_args ) { | ||
| # Don't access DB if db_is_connected() is false. | ||
|
|
||
| $t_username = $p_args['username']; | ||
|
|
||
| $t_user_id = $p_args['user_id']; | ||
|
|
||
| # If user is unknown, don't handle authentication for it, since this plugin doesn't do | ||
| # auto-provisioning | ||
| if( !$t_user_id ) { | ||
| # If user is unknown and autoprovision is not set, than don't handle authentication for it | ||
| if( !$t_user_id && ! plugin_config_get( 'autoprovision' ) ) { | ||
| return null; | ||
| } | ||
|
|
||
|
|
@@ -55,14 +62,29 @@ function auth_user_flags( $p_event_name, $p_args ) { | |
| return null; | ||
| } | ||
|
|
||
| $t_access_level = user_get_access_level( $t_user_id, ALL_PROJECTS ); | ||
| if( $t_user_id ) { | ||
| $t_access_level = user_get_access_level( $t_user_id, ALL_PROJECTS ); | ||
|
|
||
| # Have administrators use default login flow | ||
| if( $t_access_level >= ADMINISTRATOR ) { | ||
| # Have administrators use default login flow | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use tabs instead of spaces across the PR.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm having tabs here in midnight commander, however, they are 4 spaces wide tabs. |
||
| if( $t_access_level >= ADMINISTRATOR ) { | ||
| return null; | ||
| } | ||
| } | ||
|
|
||
| # for everybody else use the custom authentication | ||
| /* | ||
| * | ||
| * add any filter parameters here | ||
| * | ||
| * e.g. if you want the plugin to handle usernames only which contain '@': | ||
| * | ||
| * if ( ! preg_match('/^.*@.*$/',$t_username) ) { | ||
| * return null; | ||
| * } | ||
| * | ||
| * or to use this custom authenticateion for everybody else: | ||
| * | ||
| */ | ||
|
|
||
| $t_flags = new AuthFlags(); | ||
|
|
||
| # Passwords managed externally for all users | ||
|
|
@@ -71,9 +93,28 @@ function auth_user_flags( $p_event_name, $p_args ) { | |
|
|
||
| # No one can use standard auth mechanism | ||
|
|
||
| # Override Login page and Logout Redirect | ||
| $t_flags->setCredentialsPage( helper_url_combine( plugin_page( 'login', /* redirect */ true ), 'username=' . $t_username ) ); | ||
| $t_flags->setLogoutRedirectPage( plugin_page( 'logout', /* redirect */ true ) ); | ||
| # Override Credentials, Authenticator page and Logout Redirect - see 'pages' subdirectory | ||
| /* | ||
| * | ||
| * custom Credentials Page for user. This is displayed after the user did input his username (and the username is known to Mantis or plugin is autoprov capable) | ||
| * | ||
| */ | ||
| //$t_flags->setCredentialsPage( helper_url_combine( plugin_page( 'credentials', /* redirect */ true ), 'username=' . $t_username ) ); | ||
| /* | ||
| * | ||
| * custom Authenticator Page for user. This is called, when the user entered both username and password in the standard MantisBT login flow | ||
| * username and password in $_POST | ||
| * | ||
| * Please NOTE: if you don't do any filtering - e.g. e-mail - than this will be the only Auth Plugin besides the built-in! Stacking is not (yet) supported | ||
| * | ||
| */ | ||
| $t_flags->setAuthenticatorPage( helper_url_combine( plugin_page( 'login', /* redirect */ true ), ( !empty($t_username) ? 'username=' . urlencode($t_username) : '' ) ) ); | ||
| /* | ||
| * | ||
| * custom Logout Page for user. | ||
| * | ||
| */ | ||
| //$t_flags->setLogoutRedirectPage( plugin_page( 'logout', /* redirect */ true ) ); | ||
|
|
||
| # No long term session for identity provider to be able to kick users out. | ||
| $t_flags->setPermSessionEnabled( false ); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,183 @@ | ||
| <?php | ||
| /** | ||
| * MantisBT - A PHP based bugtracking system | ||
| * | ||
| * MantisBT is free software: you can redistribute it and/or modify | ||
| * it under the terms of the GNU General Public License as published by | ||
| * the Free Software Foundation, either version 2 of the License, or | ||
| * (at your option) any later version. | ||
| * | ||
| * MantisBT is distributed in the hope that it will be useful, | ||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| * GNU General Public License for more details. | ||
| * | ||
| * You should have received a copy of the GNU General Public License | ||
| * along with MantisBT. If not, see <http://www.gnu.org/licenses/>. | ||
| * | ||
| * @copyright Copyright 2002 MantisBT Team - mantisbt-dev@lists.sourceforge.net | ||
| */ | ||
|
|
||
| /** | ||
| * Class for dealing with custom authentication requests | ||
| * | ||
| * | ||
| * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
| * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
| * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
| * | ||
| * Class is written for demonstration purposes ONLY!!! | ||
| * | ||
| * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
| * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
| * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
| * | ||
| * @copyright Tamas Dajka 2018 | ||
| * @author Tamas Dajka <viper@vipernet.hu> | ||
| * @link http://www.mantisbt.org | ||
| * @package MantisBT | ||
| * @subpackage classes | ||
| * @plugin SampleAuth | ||
| */ | ||
|
|
||
| /* | ||
| * | ||
| * User API is needed for user auto provision | ||
| * | ||
| */ | ||
| require_api( 'user_api.php' ); | ||
| require_api( 'email_api.php' ); | ||
|
|
||
| class CustomAuthPlugin { | ||
|
|
||
| /** | ||
| * Constructor | ||
| */ | ||
| function __construct() { | ||
| # spaceholder | ||
| } | ||
|
|
||
| /** | ||
| * login | ||
| * | ||
| * @params: username, password | ||
| * @return: | ||
| * - false on login failure | ||
| * - username on login success | ||
| */ | ||
| function login( $username, $password ) { | ||
| /* | ||
| * | ||
| * Check access/auth in remote system | ||
| * | ||
| */ | ||
| if ( !$this->auth($username,$password) ) { | ||
| return false; | ||
| } | ||
|
|
||
| /* | ||
| * | ||
| * Should we autoprovision the user? | ||
| * | ||
| */ | ||
| if( plugin_config_get( 'autoprovision' ) ) { | ||
| /* | ||
| * Check if user exists, probably needs customization | ||
| */ | ||
| if( ! user_get_id_by_name($username) ) { | ||
| /* | ||
| * data needed for autorpovision: | ||
| * - username | ||
| * - password | ||
| * | ||
| * Optional params: | ||
| * | ||
| * - access_level (null) | ||
| * - protected (false) | ||
| * - enabled (true) | ||
| * - realname | ||
| * - admin_name | ||
| * | ||
| */ | ||
|
|
||
| $t_user_data = $this->get_user_data( $username ); | ||
|
|
||
| /* | ||
| * create user, but with empty e-mail => prevent mantis from sending signup e-mail | ||
| * we set a strong random password | ||
| * | ||
| * To get this work, you either have to set $g_allow_blank_email = ON, or change the value here on-the-fly (don't forget to set it back) | ||
| * | ||
| */ | ||
| $original_g_allow_blank_email = config_get( 'allow_blank_email' ); | ||
| config_set_global( 'allow_blank_email', ON ); | ||
| user_create( $username, auth_generate_random_password(24), '', $t_user_data['access_level'], false, true, $t_user_data['realname'] ); | ||
| config_set_global( 'allow_blank_email', $original_g_allow_blank_email ); | ||
|
|
||
| /* | ||
| * Set user e-mail | ||
| */ | ||
| if( !is_blank( $t_user_data['email'] ) && email_is_valid( $t_user_data['email'] ) && ( $t_user_id = user_get_id_by_name( $username ) ) ) { | ||
| user_set_field( $t_user_id,'email', $t_user_data['email'] ); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| return $username; | ||
| } | ||
|
|
||
| /** | ||
| * logout | ||
| * | ||
| * @return: bool | ||
| */ | ||
| function logout() { | ||
| # spaceholder | ||
| return true; | ||
| } | ||
|
|
||
| /** | ||
| * collects user data from auth system | ||
| * | ||
| * @return: array() | ||
| */ | ||
| function get_user_data( $username = '' ) { | ||
| if ( empty($username) ) { | ||
| return array(); | ||
| } | ||
|
|
||
| /* | ||
| * dummy data for now, access_level 25 is REPORTER -> see <ROOT>/core/constant_inc.php | ||
| */ | ||
| return array( 'username' => $username, 'email' => 'john.doe@gmail.com', 'access_level' => config_get( 'default_new_account_access_level' ), 'realname' => 'John Doe' ); | ||
| } | ||
|
|
||
| /** | ||
| * Auth validity check | ||
| * | ||
| * @params: username, password | ||
| * @return: bool | ||
| */ | ||
| function auth( $username, $password ) { | ||
| if ( empty( $username ) || empty( $password ) ) { | ||
| return false; | ||
| } | ||
|
|
||
| /* | ||
| * We should check for external auth here | ||
| * | ||
| * dummy return for now | ||
| */ | ||
|
|
||
| # comment this out for testing or write your own | ||
| return false; | ||
|
|
||
| /* example authentication */ | ||
| if( $username == 'john.doe' && $password == 'Abc.123' ) { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. just return the expression instead if/else blocks.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry, I don't get what you mean here. The 'auth' function should do the authentication, the john.doe is just an example for a simple behaviour. |
||
| return true; | ||
| } else { | ||
| return false; | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| <?php | ||
| # Copyright (c) MantisBT Team - mantisbt-dev@lists.sourceforge.net | ||
| # Licensed under the MIT license | ||
|
|
||
| require_once( 'core.php' ); | ||
| require_api( 'authentication_api.php' ); | ||
| require_api( 'user_api.php' ); | ||
|
|
||
| $f_username = gpc_get( 'username' ); | ||
| $f_reauthenticate = gpc_get_bool( 'reauthenticate', false ); | ||
| $f_return = gpc_get_string( 'return', config_get( 'default_home_page' ) ); | ||
|
|
||
| $t_return = string_url( string_sanitize_url( $f_return ) ); | ||
|
|
||
| /* | ||
| * | ||
| * Set up and call the external authenticator with the username provided | ||
| * (password is not known this time - makeing use of SSO possible | ||
| * | ||
| */ | ||
|
|
||
| $t_user_id = is_blank( $f_username ) ? false : user_get_id_by_name( $f_username ); | ||
|
|
||
| if( $t_user_id == false ) { | ||
| $t_query_args = array( | ||
| 'error' => 1, | ||
| 'username' => $f_username, | ||
| ); | ||
|
|
||
| if( !is_blank( 'return' ) ) { | ||
| $t_query_args['return'] = $t_return; | ||
| } | ||
|
|
||
| if( $f_reauthenticate ) { | ||
| $t_query_args['reauthenticate'] = 1; | ||
| } | ||
|
|
||
| $t_query_text = http_build_query( $t_query_args, '', '&' ); | ||
| // we will create a loop this way - this will redirect us again to this login page... | ||
| //$t_uri = auth_login_page( $t_query_text ); | ||
| // no "stack like" auth mechs, forcing default page on error | ||
| $t_uri = helper_url_combine( AUTH_PAGE_USERNAME, $t_query_args); | ||
|
|
||
| print_header_redirect( $t_uri ); | ||
| } | ||
|
|
||
| # Let user into MantisBT | ||
| auth_login_user( $t_user_id ); | ||
|
|
||
| # Redirect to original page user wanted to access before authentication | ||
| if( !is_blank( $t_return ) ) { | ||
| print_header_redirect( 'login_cookie_test.php?return=' . $t_return ); | ||
| } | ||
|
|
||
| # If no return page, redirect to default page | ||
| print_header_redirect( config_get( 'default_home_page' ) ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should the above
user_is_anonymous()be inside this if statement?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think so, and I really don't see any point getting the user_access_level if it's not really needed.