2020-02-01 19:42:22 +08:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace BookStack\Auth\Access\Guards;
|
|
|
|
|
|
|
|
use BookStack\Auth\Access\LdapService;
|
2020-02-03 01:31:00 +08:00
|
|
|
use BookStack\Auth\Access\RegistrationService;
|
2020-02-01 19:42:22 +08:00
|
|
|
use BookStack\Auth\User;
|
2022-03-24 00:34:23 +08:00
|
|
|
use BookStack\Exceptions\JsonDebugException;
|
2020-02-01 19:42:22 +08:00
|
|
|
use BookStack\Exceptions\LdapException;
|
|
|
|
use BookStack\Exceptions\LoginAttemptEmailNeededException;
|
2021-06-26 23:23:15 +08:00
|
|
|
use BookStack\Exceptions\LoginAttemptException;
|
2020-02-03 01:31:00 +08:00
|
|
|
use BookStack\Exceptions\UserRegistrationException;
|
2020-02-01 19:42:22 +08:00
|
|
|
use Illuminate\Contracts\Auth\UserProvider;
|
|
|
|
use Illuminate\Contracts\Session\Session;
|
2020-02-03 01:31:00 +08:00
|
|
|
use Illuminate\Support\Str;
|
2020-02-01 19:42:22 +08:00
|
|
|
|
|
|
|
class LdapSessionGuard extends ExternalBaseSessionGuard
|
|
|
|
{
|
2022-03-24 00:34:23 +08:00
|
|
|
protected LdapService $ldapService;
|
2020-02-01 19:42:22 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* LdapSessionGuard constructor.
|
|
|
|
*/
|
2021-03-08 06:24:05 +08:00
|
|
|
public function __construct(
|
|
|
|
$name,
|
2020-02-01 19:42:22 +08:00
|
|
|
UserProvider $provider,
|
|
|
|
Session $session,
|
|
|
|
LdapService $ldapService,
|
2020-02-03 01:31:00 +08:00
|
|
|
RegistrationService $registrationService
|
2021-03-08 06:24:05 +08:00
|
|
|
) {
|
2020-02-01 19:42:22 +08:00
|
|
|
$this->ldapService = $ldapService;
|
2020-02-03 01:31:00 +08:00
|
|
|
parent::__construct($name, $provider, $session, $registrationService);
|
2020-02-01 19:42:22 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Validate a user's credentials.
|
|
|
|
*
|
|
|
|
* @param array $credentials
|
2021-06-26 23:23:15 +08:00
|
|
|
*
|
2020-02-01 19:42:22 +08:00
|
|
|
* @throws LdapException
|
2021-06-26 23:23:15 +08:00
|
|
|
*
|
|
|
|
* @return bool
|
2020-02-01 19:42:22 +08:00
|
|
|
*/
|
|
|
|
public function validate(array $credentials = [])
|
|
|
|
{
|
|
|
|
$userDetails = $this->ldapService->getUserDetails($credentials['username']);
|
|
|
|
|
2020-02-15 22:44:36 +08:00
|
|
|
if (isset($userDetails['uid'])) {
|
|
|
|
$this->lastAttempted = $this->provider->retrieveByCredentials([
|
2021-06-26 23:23:15 +08:00
|
|
|
'external_auth_id' => $userDetails['uid'],
|
2020-02-15 22:44:36 +08:00
|
|
|
]);
|
|
|
|
}
|
|
|
|
|
|
|
|
return $this->ldapService->validateUserCredentials($userDetails, $credentials['password']);
|
2020-02-01 19:42:22 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Attempt to authenticate a user using the given credentials.
|
|
|
|
*
|
|
|
|
* @param array $credentials
|
2022-03-25 19:14:27 +08:00
|
|
|
* @param bool $remember
|
2021-06-26 23:23:15 +08:00
|
|
|
*
|
2022-03-24 00:34:23 +08:00
|
|
|
* @throws LdapException*@throws \BookStack\Exceptions\JsonDebugException
|
|
|
|
* @throws LoginAttemptException
|
|
|
|
* @throws JsonDebugException
|
2022-03-25 19:14:27 +08:00
|
|
|
*
|
|
|
|
* @return bool
|
2020-02-01 19:42:22 +08:00
|
|
|
*/
|
|
|
|
public function attempt(array $credentials = [], $remember = false)
|
|
|
|
{
|
|
|
|
$username = $credentials['username'];
|
|
|
|
$userDetails = $this->ldapService->getUserDetails($username);
|
|
|
|
|
2020-02-15 22:44:36 +08:00
|
|
|
$user = null;
|
|
|
|
if (isset($userDetails['uid'])) {
|
|
|
|
$this->lastAttempted = $user = $this->provider->retrieveByCredentials([
|
2021-06-26 23:23:15 +08:00
|
|
|
'external_auth_id' => $userDetails['uid'],
|
2020-02-15 22:44:36 +08:00
|
|
|
]);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!$this->ldapService->validateUserCredentials($userDetails, $credentials['password'])) {
|
2020-02-01 19:42:22 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (is_null($user)) {
|
2020-04-26 19:13:00 +08:00
|
|
|
try {
|
|
|
|
$user = $this->createNewFromLdapAndCreds($userDetails, $credentials);
|
|
|
|
} catch (UserRegistrationException $exception) {
|
2022-02-04 08:26:19 +08:00
|
|
|
throw new LoginAttemptException($exception->getMessage());
|
2020-04-26 19:13:00 +08:00
|
|
|
}
|
2020-02-01 19:42:22 +08:00
|
|
|
}
|
|
|
|
|
2020-02-01 22:30:23 +08:00
|
|
|
// Sync LDAP groups if required
|
|
|
|
if ($this->ldapService->shouldSyncGroups()) {
|
|
|
|
$this->ldapService->syncGroups($user, $username);
|
2020-02-01 19:42:22 +08:00
|
|
|
}
|
|
|
|
|
2021-05-25 01:45:08 +08:00
|
|
|
// Attach avatar if non-existent
|
2021-11-06 08:32:01 +08:00
|
|
|
if (!$user->avatar()->exists()) {
|
2021-05-25 01:45:08 +08:00
|
|
|
$this->ldapService->saveAndAttachAvatar($user, $userDetails);
|
|
|
|
}
|
|
|
|
|
2020-02-01 22:30:23 +08:00
|
|
|
$this->login($user, $remember);
|
2021-06-26 23:23:15 +08:00
|
|
|
|
2020-02-01 22:30:23 +08:00
|
|
|
return true;
|
|
|
|
}
|
2020-02-01 19:42:22 +08:00
|
|
|
|
2020-02-01 22:30:23 +08:00
|
|
|
/**
|
2021-06-26 23:23:15 +08:00
|
|
|
* Create a new user from the given ldap credentials and login credentials.
|
|
|
|
*
|
2020-02-03 01:31:00 +08:00
|
|
|
* @throws LoginAttemptEmailNeededException
|
2020-02-01 22:30:23 +08:00
|
|
|
* @throws LoginAttemptException
|
2020-02-03 01:31:00 +08:00
|
|
|
* @throws UserRegistrationException
|
2020-02-01 22:30:23 +08:00
|
|
|
*/
|
2020-02-03 01:31:00 +08:00
|
|
|
protected function createNewFromLdapAndCreds(array $ldapUserDetails, array $credentials): User
|
2020-02-01 22:30:23 +08:00
|
|
|
{
|
2020-02-03 01:31:00 +08:00
|
|
|
$email = trim($ldapUserDetails['email'] ?: ($credentials['email'] ?? ''));
|
2020-02-01 19:42:22 +08:00
|
|
|
|
2020-02-03 01:31:00 +08:00
|
|
|
if (empty($email)) {
|
2020-02-01 22:30:23 +08:00
|
|
|
throw new LoginAttemptEmailNeededException();
|
2020-02-01 19:42:22 +08:00
|
|
|
}
|
|
|
|
|
2020-02-03 01:31:00 +08:00
|
|
|
$details = [
|
2021-06-26 23:23:15 +08:00
|
|
|
'name' => $ldapUserDetails['name'],
|
|
|
|
'email' => $ldapUserDetails['email'] ?: $credentials['email'],
|
2020-02-03 01:31:00 +08:00
|
|
|
'external_auth_id' => $ldapUserDetails['uid'],
|
2021-06-26 23:23:15 +08:00
|
|
|
'password' => Str::random(32),
|
2020-02-03 01:31:00 +08:00
|
|
|
];
|
2020-02-01 19:42:22 +08:00
|
|
|
|
2020-10-13 00:33:55 +08:00
|
|
|
$user = $this->registrationService->registerUser($details, null, false);
|
2021-05-25 01:45:08 +08:00
|
|
|
$this->ldapService->saveAndAttachAvatar($user, $ldapUserDetails);
|
2021-06-26 23:23:15 +08:00
|
|
|
|
2020-10-13 00:33:55 +08:00
|
|
|
return $user;
|
2020-02-01 19:42:22 +08:00
|
|
|
}
|
|
|
|
}
|