]> BookStack Code Mirror - bookstack/blob - app/Auth/Access/Guards/Saml2SessionGuard.php
1bdb59d516f4c989194880f8ffe3a134f6b26d3b
[bookstack] / app / Auth / Access / Guards / Saml2SessionGuard.php
1 <?php
2
3 namespace BookStack\Auth\Access\Guards;
4
5 use BookStack\Auth\Access\LdapService;
6 use BookStack\Auth\User;
7 use BookStack\Auth\UserRepo;
8 use BookStack\Exceptions\LdapException;
9 use BookStack\Exceptions\LoginAttemptException;
10 use BookStack\Exceptions\LoginAttemptEmailNeededException;
11 use Illuminate\Contracts\Auth\UserProvider;
12 use Illuminate\Contracts\Session\Session;
13
14 class LdapSessionGuard extends ExternalBaseSessionGuard
15 {
16
17     protected $ldapService;
18
19     /**
20      * LdapSessionGuard constructor.
21      */
22     public function __construct($name,
23         UserProvider $provider,
24         Session $session,
25         LdapService $ldapService,
26         UserRepo $userRepo
27     )
28     {
29         $this->ldapService = $ldapService;
30         parent::__construct($name, $provider, $session, $userRepo);
31     }
32
33     /**
34      * Validate a user's credentials.
35      *
36      * @param array $credentials
37      * @return bool
38      * @throws LdapException
39      */
40     public function validate(array $credentials = [])
41     {
42         $userDetails = $this->ldapService->getUserDetails($credentials['username']);
43         $this->lastAttempted = $this->provider->retrieveByCredentials([
44             'external_auth_id' => $userDetails['uid']
45         ]);
46
47         return $this->ldapService->validateUserCredentials($userDetails, $credentials['username'], $credentials['password']);
48     }
49
50     /**
51      * Attempt to authenticate a user using the given credentials.
52      *
53      * @param array $credentials
54      * @param bool $remember
55      * @return bool
56      * @throws LoginAttemptEmailNeededException
57      * @throws LoginAttemptException
58      * @throws LdapException
59      */
60     public function attempt(array $credentials = [], $remember = false)
61     {
62         $username = $credentials['username'];
63         $userDetails = $this->ldapService->getUserDetails($username);
64         $this->lastAttempted = $user = $this->provider->retrieveByCredentials([
65             'external_auth_id' => $userDetails['uid']
66         ]);
67
68         if (!$this->ldapService->validateUserCredentials($userDetails, $username, $credentials['password'])) {
69             return false;
70         }
71
72         if (is_null($user)) {
73             $user = $this->freshUserInstanceFromLdapUserDetails($userDetails);
74         }
75
76         $this->checkForUserEmail($user, $credentials['email'] ?? '');
77         $this->saveIfNew($user);
78
79         // Sync LDAP groups if required
80         if ($this->ldapService->shouldSyncGroups()) {
81             $this->ldapService->syncGroups($user, $username);
82         }
83
84         $this->login($user, $remember);
85         return true;
86     }
87
88     /**
89      * Create a fresh user instance from details provided by a LDAP lookup.
90      */
91     protected function freshUserInstanceFromLdapUserDetails(array $ldapUserDetails): User
92     {
93         $user = new User();
94
95         $user->name = $ldapUserDetails['name'];
96         $user->external_auth_id = $ldapUserDetails['uid'];
97         $user->email = $ldapUserDetails['email'];
98         $user->email_confirmed = false;
99
100         return $user;
101     }
102
103 }