ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
class.ilAuthProviderLDAP.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
27{
29 private string $migration_account = '';
30 private bool $force_new_account = false;
31
32 public function __construct(ilAuthCredentials $credentials, int $a_server_id = 0)
33 {
35 $this->initServer($a_server_id);
36 }
37
38 public function getServer(): ilLDAPServer
39 {
40 return $this->server;
41 }
42
46 public function doAuthentication(ilAuthStatus $status): bool
47 {
48 try {
49 // bind
50 $query = new ilLDAPQuery($this->getServer());
51 $query->bind();
52 } catch (ilLDAPQueryException $e) {
53 $this->getLogger()->error('Cannot bind to LDAP server... ' . $e->getMessage());
54 $this->handleAuthenticationFail($status, 'auth_err_ldap_exception');
55 return false;
56 }
57 try {
58 // Read user data, which does ensure a sucessful authentication.
59 $users = $query->fetchUser(
60 $this->getCredentials()->getUsername()
61 );
62
63 if (!$users) {
64 $this->handleAuthenticationFail($status, 'err_wrong_login');
65 return false;
66 }
67 if (!trim($this->getCredentials()->getPassword())) {
68 $this->handleAuthenticationFail($status, 'err_wrong_login');
69 return false;
70 }
71 if (!array_key_exists($this->changeKeyCase($this->getCredentials()->getUsername()), $users)) {
72 $this->getLogger()->warning('Cannot find user: ' . $this->changeKeyCase($this->getCredentials()->getUsername()));
73 $this->handleAuthenticationFail($status, 'auth_err_ldap_exception');
74 return false;
75 }
76
77 // check group membership
78 if (!$query->checkGroupMembership(
79 $this->getCredentials()->getUsername(),
80 $users[$this->changeKeyCase($this->getCredentials()->getUsername())]
81 )) {
82 $this->handleAuthenticationFail($status, 'err_wrong_login');
83 return false;
84 }
85 } catch (ilLDAPQueryException $e) {
86 $this->getLogger()->error('Cannot fetch LDAP user data... ' . $e->getMessage());
87 $this->handleAuthenticationFail($status, 'auth_err_ldap_exception');
88 return false;
89 }
90 try {
91 // now bind with login credentials
92 $query->bind(
94 $users[$this->changeKeyCase($this->getCredentials()->getUsername())]['dn'],
95 $this->getCredentials()->getPassword()
96 );
97 } catch (ilLDAPQueryException $e) {
98 $this->handleAuthenticationFail($status, 'err_wrong_login');
99 return false;
100 }
101
102 // authentication success update profile
103 return $this->updateAccount($status, $users[$this->changeKeyCase($this->getCredentials()->getUsername())]);
104 }
105
109 protected function updateAccount(ilAuthStatus $status, array $user): bool
110 {
111 $user = array_change_key_case($user, CASE_LOWER);
112 $this->getLogger()->dump($user, ilLogLevel::DEBUG);
113
114 $sync = new ilLDAPUserSynchronisation(
115 'ldap_' . $this->getServer()->getServerId(),
116 $this->getServer()->getServerId()
117 );
118 $sync->setExternalAccount($this->getCredentials()->getUsername());
119 $sync->setUserData($user);
120 $sync->forceCreation($this->force_new_account);
121
122 try {
123 $internal_account = $sync->sync();
124 $this->getLogger()->debug('Internal account: ' . $internal_account);
125 } catch (UnexpectedValueException $e) {
126 $this->getLogger()->info('Login failed with message: ' . $e->getMessage());
127 $this->handleAuthenticationFail($status, 'err_wrong_login');
128 return false;
130 $this->handleAuthenticationFail($status, 'err_auth_ldap_failed');
131 return false;
133 // No syncronisation allowed => create Error
134 $this->getLogger()->info('Login failed with message: ' . $e->getMessage());
135 $this->handleAuthenticationFail($status, 'err_auth_ldap_no_ilias_user');
136 return false;
138 // Account migration required
139 $this->setExternalAccountName($this->getCredentials()->getUsername());
140 $this->getLogger()->info('Authentication failed: account migration required for external account: ' . $this->getCredentials()->getUsername());
142 return false;
143 }
145 $status->setAuthenticatedUserId(ilObjUser::_lookupId($internal_account));
146 return true;
147 }
148
149 protected function initServer(int $a_server_id): void
150 {
151 $this->server = new ilLDAPServer($a_server_id);
152 }
153
157 public function createNewAccount(ilAuthStatus $status): void
158 {
159 $this->force_new_account = true;
160
161 try {
162 $query = new ilLDAPQuery($this->getServer());
163 $query->bind();
164 } catch (ilLDAPQueryException $e) {
165 $this->getLogger()->error('Cannot bind to LDAP server... ' . $e->getMessage());
166 $this->handleAuthenticationFail($status, 'auth_err_ldap_exception');
167 return;
168 }
169 try {
170 // fetch user
171 $users = $query->fetchUser(
172 $this->getCredentials()->getUsername()
173 );
174 if (!$users) {
175 $this->handleAuthenticationFail($status, 'err_wrong_login');
176 return;
177 }
178 if (!array_key_exists($this->changeKeyCase($this->getCredentials()->getUsername()), $users)) {
179 $this->handleAuthenticationFail($status, 'err_wrong_login');
180 return;
181 }
182 } catch (ilLDAPQueryException $e) {
183 $this->getLogger()->error('Cannot fetch LDAP user data... ' . $e->getMessage());
184 $this->handleAuthenticationFail($status, 'auth_err_ldap_exception');
185 return;
186 }
187
188 // authentication success update profile
189 $this->updateAccount($status, $users[$this->changeKeyCase($this->getCredentials()->getUsername())]);
190 }
191
195 public function migrateAccount(ilAuthStatus $status): void
196 {
197 $this->force_new_account = true;
198
199 try {
200 $query = new ilLDAPQuery($this->getServer());
201 $query->bind();
202 } catch (ilLDAPQueryException $e) {
203 $this->getLogger()->error('Cannot bind to LDAP server... ' . $e->getMessage());
204 $this->handleAuthenticationFail($status, 'auth_err_ldap_exception');
205 return;
206 }
207
208 $users = $query->fetchUser($this->getCredentials()->getUsername());
209 $this->updateAccount($status, $users[$this->changeKeyCase($this->getCredentials()->getUsername())]);
210 }
211
215 public function getTriggerAuthMode(): string
216 {
217 return ilAuthUtils::AUTH_LDAP . '_' . $this->getServer()->getServerId();
218 }
219
223 public function getUserAuthModeName(): string
224 {
225 return 'ldap_' . $this->getServer()->getServerId();
226 }
227
231 public function getExternalAccountName(): string
232 {
234 }
235
236 public function setExternalAccountName(string $a_name): void
237 {
238 $this->migration_account = $a_name;
239 }
240
245 protected function changeKeyCase(string $a_string)
246 {
247 return array_key_first(array_change_key_case([$a_string => $a_string]));
248 }
249}
updateAccount(ilAuthStatus $status, array $user)
Update Account.
doAuthentication(ilAuthStatus $status)
@inheritDoc
changeKeyCase(string $a_string)
Change case similar to array_change_key_case, to avoid further encoding problems.
setExternalAccountName(string $a_name)
__construct(ilAuthCredentials $credentials, int $a_server_id=0)
migrateAccount(ilAuthStatus $status)
@inheritDoc
createNewAccount(ilAuthStatus $status)
@inheritDoc
handleAuthenticationFail(ilAuthStatus $status, string $a_reason)
ilAuthCredentials $credentials
const int STATUS_ACCOUNT_MIGRATION_REQUIRED
setAuthenticatedUserId(int $a_id)
setStatus(int $a_status)
Set auth status.
const int STATUS_AUTHENTICATED
const int AUTH_LDAP
Thrown in case of failed synchronisation settings.
Synchronization of user accounts used in auth container ldap, ,...
static _lookupId(string|array $a_user_str)
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc