Skip to content

Commit e9600c9

Browse files
committed
Override UserPassBaseOrg::handleLogin to be able to store the selected ldap-source
1 parent 6b0db5c commit e9600c9

1 file changed

Lines changed: 92 additions & 0 deletions

File tree

src/Auth/Source/LdapMulti.php

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use SimpleSAML\Auth;
2020
use SimpleSAML\Configuration;
2121
use SimpleSAML\Error;
22+
use SimpleSAML\Logger;
2223
use SimpleSAML\Module\core\Auth\UserPassOrgBase;
2324

2425
use function array_change_key_case;
@@ -28,6 +29,12 @@
2829

2930
class LdapMulti extends UserPassOrgBase
3031
{
32+
/**
33+
* The key of the OrgId field in the state, identifies which org was selected.
34+
*/
35+
public const string SOURCEID = '\SimpleSAML\Module\ldap\Auth\LdapMulti.SelectedSource';
36+
37+
3138
/**
3239
* An LDAP configuration object.
3340
*/
@@ -160,6 +167,80 @@ public function loginOverload(
160167
}
161168

162169

170+
/**
171+
* Handle login request.
172+
*
173+
* This function is used by the login form (core/loginuserpassorg) when the user
174+
* enters a username and password. On success, it will not return. On wrong
175+
* username/password failure, and other errors, it will throw an exception.
176+
*
177+
* @param string $authStateId The identifier of the authentication state.
178+
* @param string $username The username the user wrote.
179+
* @param string $password The password the user wrote.
180+
* @param string $organization The id of the organization the user chose.
181+
*/
182+
public static function handleLogin(
183+
string $authStateId,
184+
string $username,
185+
string $password,
186+
string $organization,
187+
): void {
188+
/* Retrieve the authentication state. */
189+
$state = Auth\State::loadState($authStateId, self::STAGEID);
190+
191+
/* Find authentication source. */
192+
Assert::keyExists($state, self::AUTHID);
193+
194+
/** @var \SimpleSAML\Module\core\Auth\UserPassOrgBase|null $source */
195+
$source = Auth\Source::getById($state[self::AUTHID]);
196+
if ($source === null) {
197+
throw new \Exception('Could not find authentication source with id ' . $state[self::AUTHID]);
198+
}
199+
200+
$orgMethod = $source->getUsernameOrgMethod();
201+
if ($orgMethod !== 'none') {
202+
$tmp = explode('@', $username, 2);
203+
if (count($tmp) === 2) {
204+
$username = $tmp[0];
205+
$organization = $tmp[1];
206+
} else {
207+
if ($orgMethod === 'force') {
208+
/* The organization should be a part of the username, but isn't. */
209+
throw new Error\Error(Error\ErrorCodes::WRONGUSERPASS);
210+
}
211+
}
212+
}
213+
214+
/* Attempt to log in. */
215+
try {
216+
$attributes = $source->login($username, $password, $organization);
217+
} catch (\Exception $e) {
218+
Logger::stats('Unsuccessful login attempt from ' . $_SERVER['REMOTE_ADDR'] . '.');
219+
throw $e;
220+
}
221+
222+
Logger::stats(
223+
'User \'' . $username . '\' at \'' . $organization
224+
. '\' successfully authenticated from ' . $_SERVER['REMOTE_ADDR'],
225+
);
226+
227+
// Add the selected Org to the state
228+
$mapping = $source->getMapping();
229+
$state[self::SOURCEID] = $mapping[$organization]['authsource'];
230+
$state[self::ORGID] = $organization;
231+
$state['PersistentAuthData'][] = self::ORGID;
232+
233+
$state['Attributes'] = $attributes;
234+
Auth\Source::completeAuth($state);
235+
236+
237+
// Save the $state-array, so that we can restore it after a redirect
238+
$authStateId = Auth\State::saveState($state, self::STAGEID);
239+
240+
parent::handleLogin($authStateId, $username, $password, $organization);
241+
}
242+
243+
163244
/**
164245
* Attempt to log in using the given username and password.
165246
*
@@ -183,4 +264,15 @@ protected function getOrganizations(): array
183264
{
184265
return $this->orgs;
185266
}
267+
268+
269+
/**
270+
* Retrieve the mapping
271+
*
272+
* @return array<mixed> Associative array with the organization/authsource mapping.
273+
*/
274+
protected function getMapping(): array
275+
{
276+
return $this->mapping;
277+
}
186278
}

0 commit comments

Comments
 (0)