]> BookStack Code Mirror - bookstack/blob - app/Auth/Access/Guards/LdapSessionGuard.php
Import thumbnail photos when LDAP users are created.
[bookstack] / app / Auth / Access / Guards / LdapSessionGuard.php
1 <?php
2
3 namespace BookStack\Auth\Access\Guards;
4
5 use BookStack\Auth\Access\LdapService;
6 use BookStack\Auth\Access\RegistrationService;
7 use BookStack\Auth\User;
8 use BookStack\Auth\UserRepo;
9 use BookStack\Exceptions\LdapException;
10 use BookStack\Exceptions\LoginAttemptException;
11 use BookStack\Exceptions\LoginAttemptEmailNeededException;
12 use BookStack\Exceptions\UserRegistrationException;
13 use Illuminate\Contracts\Auth\UserProvider;
14 use Illuminate\Contracts\Session\Session;
15 use Illuminate\Support\Facades\Hash;
16 use Illuminate\Support\Str;
17
18 class LdapSessionGuard extends ExternalBaseSessionGuard
19 {
20
21     protected $ldapService;
22
23     /**
24      * LdapSessionGuard constructor.
25      */
26     public function __construct($name,
27         UserProvider $provider,
28         Session $session,
29         LdapService $ldapService,
30         RegistrationService $registrationService
31     )
32     {
33         $this->ldapService = $ldapService;
34         parent::__construct($name, $provider, $session, $registrationService);
35     }
36
37     /**
38      * Validate a user's credentials.
39      *
40      * @param array $credentials
41      * @return bool
42      * @throws LdapException
43      */
44     public function validate(array $credentials = [])
45     {
46         $userDetails = $this->ldapService->getUserDetails($credentials['username']);
47
48         if (isset($userDetails['uid'])) {
49             $this->lastAttempted = $this->provider->retrieveByCredentials([
50                 'external_auth_id' => $userDetails['uid']
51             ]);
52         }
53
54         return $this->ldapService->validateUserCredentials($userDetails, $credentials['password']);
55     }
56
57     /**
58      * Attempt to authenticate a user using the given credentials.
59      *
60      * @param array $credentials
61      * @param bool $remember
62      * @return bool
63      * @throws LoginAttemptException
64      * @throws LdapException
65      */
66     public function attempt(array $credentials = [], $remember = false)
67     {
68         $username = $credentials['username'];
69         $userDetails = $this->ldapService->getUserDetails($username);
70
71         $user = null;
72         if (isset($userDetails['uid'])) {
73             $this->lastAttempted = $user = $this->provider->retrieveByCredentials([
74                 'external_auth_id' => $userDetails['uid']
75             ]);
76         }
77
78         if (!$this->ldapService->validateUserCredentials($userDetails, $credentials['password'])) {
79             return false;
80         }
81
82         if (is_null($user)) {
83             try {
84                 $user = $this->createNewFromLdapAndCreds($userDetails, $credentials);
85             } catch (UserRegistrationException $exception) {
86                 throw new LoginAttemptException($exception->message);
87             }
88         }
89
90         // Sync LDAP groups if required
91         if ($this->ldapService->shouldSyncGroups()) {
92             $this->ldapService->syncGroups($user, $username);
93         }
94
95         $this->login($user, $remember);
96         return true;
97     }
98
99     /**
100      * Create a new user from the given ldap credentials and login credentials
101      * @throws LoginAttemptEmailNeededException
102      * @throws LoginAttemptException
103      * @throws UserRegistrationException
104      */
105     protected function createNewFromLdapAndCreds(array $ldapUserDetails, array $credentials): User
106     {
107         $email = trim($ldapUserDetails['email'] ?: ($credentials['email'] ?? ''));
108
109         if (empty($email)) {
110             throw new LoginAttemptEmailNeededException();
111         }
112
113         $details = [
114             'name' => $ldapUserDetails['name'],
115             'email' => $ldapUserDetails['email'] ?: $credentials['email'],
116             'external_auth_id' => $ldapUserDetails['uid'],
117             'password' => Str::random(32),
118         ];
119
120         $user = $this->registrationService->registerUser($details, null, false);
121
122         if (config('services.ldap.import_thumbnail_photos')) {
123             $imageService = app()->make(ImageService::class);
124             $image = $imageService->saveNewFromBase64Uri('data:image/jpg;base64,'.base64_encode($ldapUserDetails['avatar']), $ldapUserDetails['uid'].'.jpg', 'user');
125
126             $user['image_id'] = $image->id;
127             $user->save();
128         }
129
130         return $user;
131     }
132
133 }