diff --git a/modules/core/lib/Auth/UserPassOrgBase.php b/modules/core/lib/Auth/UserPassOrgBase.php index ea45fba5742e9b5fd27e90158b272df91424d075..9f1d47bff67ff3618f1e9b2bc0ac72ada00d2cdb 100644 --- a/modules/core/lib/Auth/UserPassOrgBase.php +++ b/modules/core/lib/Auth/UserPassOrgBase.php @@ -27,6 +27,16 @@ abstract class sspmod_core_Auth_UserPassOrgBase extends SimpleSAML_Auth_Source { const AUTHID = 'sspmod_core_Auth_UserPassOrgBase.AuthId'; + /** + * What way do we handle the organization as part of the username. + * Three values: + * 'none': Force the user to select the correct organization from the dropdown box. + * 'allow': Allow the user to enter the organization as part of the username. + * 'force': Remove the dropdown box. + */ + private $usernameOrgMethod; + + /** * Constructor for this authentication source. * @@ -42,6 +52,42 @@ abstract class sspmod_core_Auth_UserPassOrgBase extends SimpleSAML_Auth_Source { /* Call the parent constructor first, as required by the interface. */ parent::__construct($info, $config); + + $this->usernameOrgMethod = 'none'; + } + + + /** + * Configure the way organizations as part of the username is handled. + * + * There are three possible values: + * - 'none': Force the user to select the correct organization from the dropdown box. + * - 'allow': Allow the user to enter the organization as part of the username. + * - 'force': Remove the dropdown box. + * + * If unconfigured, the default is 'none'. + * + * @param string $usernameOrgMethod The method which should be used. + */ + protected function setUsernameOrgMethod($usernameOrgMethod) { + assert('in_array($usernameOrgMethod, array("none", "allow", "force"), TRUE)'); + + $this->usernameOrgMethod = $usernameOrgMethod; + } + + + /** + * Retrieve the way organizations as part of the username should be handled. + * + * There are three possible values: + * - 'none': Force the user to select the correct organization from the dropdown box. + * - 'allow': Allow the user to enter the organization as part of the username. + * - 'force': Remove the dropdown box. + * + * @return string The method which should be used. + */ + public function getUsernameOrgMethod() { + return $this->usernameOrgMethod; } @@ -127,6 +173,19 @@ abstract class sspmod_core_Auth_UserPassOrgBase extends SimpleSAML_Auth_Source { throw new Exception('Could not find authentication source with id ' . $state[self::AUTHID]); } + $orgMethod = $source->getUsernameOrgMethod(); + if ($orgMethod !== 'none') { + $tmp = explode('@', $username, 2); + if (count($tmp) === 2) { + $username = $tmp[0]; + $organization = $tmp[1]; + } else { + if ($orgMethod === 'force') { + /* The organization should be a part of the username, but isn't. */ + return 'WRONGUSERPASS'; + } + } + } try { /* Attempt to log in. */ @@ -157,7 +216,8 @@ abstract class sspmod_core_Auth_UserPassOrgBase extends SimpleSAML_Auth_Source { * This function is used by the login form to get the available organizations. * * @param string $authStateId The identifier of the authentication state. - * @return array Array of organizations. + * @return array|NULL Array of organizations. NULL if the user must enter the + * organization as part of the username. */ public static function listOrganizations($authStateId) { assert('is_string($authStateId)'); @@ -172,6 +232,11 @@ abstract class sspmod_core_Auth_UserPassOrgBase extends SimpleSAML_Auth_Source { throw new Exception('Could not find authentication source with id ' . $state[self::AUTHID]); } + $orgMethod = $source->getUsernameOrgMethod(); + if ($orgMethod === 'force') { + return NULL; + } + return $source->getOrganizations(); } } diff --git a/modules/core/www/loginuserpassorg.php b/modules/core/www/loginuserpassorg.php index 27cb9020667905ce5bb8e1c3932e651e20d56525..3a3e0e190b10c479cfce14a0a6bad583d8fc69b9 100644 --- a/modules/core/www/loginuserpassorg.php +++ b/modules/core/www/loginuserpassorg.php @@ -14,6 +14,7 @@ if (!array_key_exists('AuthState', $_REQUEST)) { throw new SimpleSAML_Error_BadRequest('Missing AuthState parameter.'); } $authStateId = $_REQUEST['AuthState']; +$organizations = sspmod_core_Auth_UserPassOrgBase::listOrganizations($authStateId); if (array_key_exists('username', $_REQUEST)) { $username = $_REQUEST['username']; @@ -30,25 +31,27 @@ if (array_key_exists('password', $_REQUEST)) { if (array_key_exists('organization', $_REQUEST)) { $organization = $_REQUEST['organization']; } else { - $organization = NULL; + $organization = ''; } -if (!empty($organization) && (!empty($username) || !empty($password))) { - /* Organization and either username or password set - attempt to log in. */ - $errorCode = sspmod_core_Auth_UserPassOrgBase::handleLogin($authStateId, $username, $password, $organization); -} else { - $errorCode = NULL; +$errorCode = NULL; +if ($organizations === NULL || !empty($organization)) { + if (!empty($username) && !empty($password)) { + $errorCode = sspmod_core_Auth_UserPassOrgBase::handleLogin($authStateId, $username, $password, $organization); + } } -$organizations = sspmod_core_Auth_UserPassOrgBase::listOrganizations($authStateId); - $globalConfig = SimpleSAML_Configuration::getInstance(); $t = new SimpleSAML_XHTML_Template($globalConfig, 'core:loginuserpass.php'); $t->data['stateparams'] = array('AuthState' => $authStateId); -$t->data['selectedOrg'] = $organization; -$t->data['organizations'] = $organizations; $t->data['username'] = $username; $t->data['errorcode'] = $errorCode; + +if ($organizations !== NULL) { + $t->data['selectedOrg'] = $organization; + $t->data['organizations'] = $organizations; +} + $t->show(); exit();