ILIAS  release_8 Revision v8.19
All Data Structures Namespaces Files Functions Variables Modules Pages
class.ilOpenIdConnectSettings.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
26 
28 {
29  private const STORAGE_ID = 'oidc';
30 
31  public const FILE_STORAGE = 'openidconnect/login_form_image';
32  public const DEFAULT_SCOPE = 'openid';
33  public const LOGIN_ELEMENT_TYPE_TXT = 0;
34  public const LOGIN_ELEMENT_TYPE_IMG = 1;
35  public const LOGIN_ENFORCE = 0;
36  public const LOGIN_STANDARD = 1;
37  public const LOGOUT_SCOPE_GLOBAL = 0;
38  public const LOGOUT_SCOPE_LOCAL = 1;
39 
40  public const URL_VALIDATION_PROVIDER = 0;
41  public const URL_VALIDATION_CUSTOM = 1;
42  public const URL_VALIDATION_NONE = 2;
43 
46 
47  private static ?self $instance = null;
48 
51  private bool $active = false;
52  private string $provider = '';
53  private string $client_id = '';
54  private string $secret = '';
55  private int $login_element_type = self::LOGIN_ELEMENT_TYPE_TXT;
56  private ?string $login_element_img_name = null;
57  private ?string $login_element_text = null;
58  private int $login_prompt_type = self::LOGIN_ENFORCE;
59  private ?int $logout_scope = null;
60  private bool $custom_session = false;
61  private int $session_duration = 60;
62  private ?bool $allow_sync;
63  private ?int $role;
64  private string $uid = '';
66  private array $profile_map = [];
68  private array $profile_update_map = [];
70  private array $role_mappings = [];
72  private array $additional_scopes = [];
73  private int $validate_scopes = self::URL_VALIDATION_PROVIDER;
74  private ?string $custom_discovery_url = null;
75 
76  private function __construct()
77  {
78  global $DIC;
79 
80  $this->storage = new ilSetting(self::STORAGE_ID);
81  $this->filesystem = $DIC->filesystem()->web();
82  $this->load();
83  }
84 
85  public static function getInstance(): self
86  {
87  if (self::$instance === null) {
88  self::$instance = new self();
89  }
90 
91  return self::$instance;
92  }
93 
94  public function setActive(bool $active): void
95  {
96  $this->active = $active;
97  }
98 
99  public function getActive(): bool
100  {
101  return $this->active;
102  }
103 
104  public function setProvider(string $url): void
105  {
106  $this->provider = $url;
107  }
108 
109  public function getProvider(): string
110  {
111  return $this->provider;
112  }
113 
114  public function setClientId(string $client_id): void
115  {
116  $this->client_id = $client_id;
117  }
118 
119  public function getClientId(): string
120  {
121  return $this->client_id;
122  }
123 
124  public function setSecret(string $secret): void
125  {
126  $this->secret = $secret;
127  }
128 
129  public function getSecret(): string
130  {
131  return $this->secret;
132  }
133 
134  public function setLoginElementType(int $type): void
135  {
136  $this->login_element_type = $type;
137  }
138 
139  public function getLoginElementType(): int
140  {
142  }
143 
144  public function setLoginElementImage(string $a_img_name): void
145  {
146  $this->login_element_img_name = $a_img_name;
147  }
148 
149  public function getLoginElementImage(): string
150  {
152  }
153 
154  public function setLoginElementText(string $text): void
155  {
156  $this->login_element_text = $text;
157  }
158 
159 
160  public function getLoginElemenText(): string
161  {
163  }
164 
165  public function setLoginPromptType(int $a_type): void
166  {
167  $this->login_prompt_type = $a_type;
168  }
169 
170  public function getLoginPromptType(): int
171  {
173  }
174 
175  public function setLogoutScope(int $a_scope): void
176  {
177  $this->logout_scope = $a_scope;
178  }
179 
180  public function getLogoutScope(): int
181  {
182  return $this->logout_scope;
183  }
184 
185  public function useCustomSession(bool $a_stat): void
186  {
187  $this->custom_session = $a_stat;
188  }
189 
190  public function isCustomSession(): bool
191  {
192  return $this->custom_session;
193  }
194 
195  public function setSessionDuration(int $a_duration): void
196  {
197  $this->session_duration = $a_duration;
198  }
199 
200  public function getSessionDuration(): int
201  {
203  }
204 
205  public function isSyncAllowed(): bool
206  {
207  return $this->allow_sync;
208  }
209 
210  public function allowSync(bool $a_stat): void
211  {
212  $this->allow_sync = $a_stat;
213  }
214 
215  public function setRole(int $role): void
216  {
217  $this->role = $role;
218  }
219 
220  public function getRole(): int
221  {
222  return $this->role;
223  }
224 
225  public function setUidField(string $field): void
226  {
227  $this->uid = $field;
228  }
229 
230  public function getUidField(): string
231  {
232  return $this->uid;
233  }
234 
238  public function getAdditionalScopes(): array
239  {
241  }
242 
247  public function setAdditionalScopes(array $additional_scopes): void
248  {
249  $this->additional_scopes = $additional_scopes;
250  }
251 
255  public function getAllScopes(): array
256  {
258  array_unshift($scopes, self::DEFAULT_SCOPE);
259 
260  return $scopes;
261  }
262 
267  public function deleteImageFile(): void
268  {
269  if ($this->filesystem->has(self::FILE_STORAGE . '/' . $this->getLoginElementImage())) {
270  $this->filesystem->delete(self::FILE_STORAGE . '/' . $this->getLoginElementImage());
271  }
272  }
273 
274  public function hasImageFile(): bool
275  {
276  return
277  $this->getLoginElementImage() !== '' &&
278  $this->filesystem->has(self::FILE_STORAGE . '/' . $this->getLoginElementImage());
279  }
280 
281  public function getImageFilePath(): string
282  {
283  return implode(
284  '/',
285  [
287  self::FILE_STORAGE . '/' . $this->getLoginElementImage()
288  ]
289  );
290  }
291 
295  public function setRoleMappings(array $a_role_mappings): void
296  {
297  $this->role_mappings = $a_role_mappings;
298  }
299 
303  public function getRoleMappings(): array
304  {
305  return $this->role_mappings;
306  }
307 
308  public function getRoleMappingValueForId(int $a_role_id): string
309  {
310  if (isset($this->role_mappings[$a_role_id]['value'])) {
311  return (string) $this->role_mappings[$a_role_id]['value'];
312  }
313 
314  return '';
315  }
316 
317  public function getRoleMappingUpdateForId(int $a_role_id): bool
318  {
319  if (isset($this->role_mappings[$a_role_id]['update'])) {
320  return (bool) $this->role_mappings[$a_role_id]['update'];
321  }
322 
323  return false;
324  }
325 
326  public function validateScopes(string $discoveryURL, array $custom_scopes): array
327  {
328  $result = [];
329  try {
330  $curl = new ilCurlConnection($discoveryURL);
331  $curl->init();
332 
333  $curl->setOpt(CURLOPT_HEADER, 0);
334  $curl->setOpt(CURLOPT_RETURNTRANSFER, true);
335  $curl->setOpt(CURLOPT_TIMEOUT, 4);
336 
337  $response = $curl->exec();
338 
339  if ($curl->getInfo(CURLINFO_RESPONSE_CODE) === 200) {
340  $decoded_response = json_decode($response, false, 512, JSON_THROW_ON_ERROR);
341  $available_scopes = $decoded_response->scopes_supported;
342  array_unshift($custom_scopes, self::DEFAULT_SCOPE);
343  if (!empty(array_diff($custom_scopes, $available_scopes))) {
344  $result = [self::VALIDATION_ISSUE_INVALID_SCOPE, array_diff($custom_scopes, $available_scopes)];
345  }
346  } else {
347  $result = [self::VALIDATION_ISSUE_DISCOVERY_ERROR, $response];
348  }
349  } finally {
350  if (isset($curl)) {
351  $curl->close();
352  }
353  }
354  return $result;
355  }
356 
357  public function save(): void
358  {
359  $this->storage->set('active', (string) ((int) $this->getActive()));
360  $this->storage->set('provider', $this->getProvider());
361  $this->storage->set('client_id', $this->getClientId());
362  $this->storage->set('secret', $this->getSecret());
363  $this->storage->set('scopes', serialize($this->getAdditionalScopes()));
364  $this->storage->set('le_img', $this->getLoginElementImage());
365  $this->storage->set('le_text', $this->getLoginElemenText());
366  $this->storage->set('le_type', (string) $this->getLoginElementType());
367  $this->storage->set('prompt_type', (string) $this->getLoginPromptType());
368  $this->storage->set('logout_scope', (string) $this->getLogoutScope());
369  $this->storage->set('custom_session', (string) ((int) $this->isCustomSession()));
370  $this->storage->set('session_duration', (string) $this->getSessionDuration());
371  $this->storage->set('allow_sync', (string) ((int) $this->isSyncAllowed()));
372  $this->storage->set('role', (string) $this->getRole());
373  $this->storage->set('uid', $this->getUidField());
374 
375  foreach ($this->getProfileMappingFields() as $field => $lang_key) {
376  $this->storage->set('pmap_' . $field, $this->getProfileMappingFieldValue($field));
377  $this->storage->set('pumap_' . $field, (string) ((int) $this->getProfileMappingFieldUpdate($field)));
378  }
379  $this->storage->set('role_mappings', serialize($this->getRoleMappings()));
380  $this->storage->set('validate_scopes', (string) $this->getValidateScopes());
381  if (self::URL_VALIDATION_CUSTOM === $this->getValidateScopes()) {
382  $this->storage->set('custom_discovery_url', $this->getCustomDiscoveryUrl());
383  } else {
384  $this->storage->delete('custom_discovery_url');
385  }
386  }
387 
388  protected function load(): void
389  {
390  foreach ($this->getProfileMappingFields() as $field => $lang_key) {
391  $this->profile_map[$field] = (string) $this->storage->get('pmap_' . $field, '');
392  $this->profile_update_map[$field] = (bool) $this->storage->get('pumap_' . $field, '0');
393  }
394 
395  $this->setActive((bool) $this->storage->get('active', '0'));
396  $this->setProvider($this->storage->get('provider', ''));
397  $this->setClientId($this->storage->get('client_id', ''));
398  $this->setSecret($this->storage->get('secret', ''));
399  $this->setAdditionalScopes((array) unserialize(
400  $this->storage->get('scopes', serialize([])),
401  ['allowed_classes' => false]
402  ));
403  $this->setLoginElementImage($this->storage->get('le_img', ''));
404  $this->setLoginElementText((string) $this->storage->get('le_text'));
405  $this->setLoginElementType((int) $this->storage->get('le_type'));
406  $this->setLoginPromptType((int) $this->storage->get('prompt_type', (string) self::LOGIN_ENFORCE));
407  $this->setLogoutScope((int) $this->storage->get('logout_scope', (string) self::LOGOUT_SCOPE_GLOBAL));
408  $this->useCustomSession((bool) $this->storage->get('custom_session', '0'));
409  $this->setSessionDuration((int) $this->storage->get('session_duration', '60'));
410  $this->allowSync((bool) $this->storage->get('allow_sync', '0'));
411  $this->setRole((int) $this->storage->get('role', '0'));
412  $this->setUidField((string) $this->storage->get('uid', ''));
413  $this->setRoleMappings((array) unserialize(
414  $this->storage->get('role_mappings', serialize([])),
415  ['allowed_classes' => false]
416  ));
417  $this->setValidateScopes((int) $this->storage->get('validate_scopes', (string) self::URL_VALIDATION_PROVIDER));
418  if (self::URL_VALIDATION_CUSTOM === $this->getValidateScopes()) {
419  $this->setCustomDiscoveryUrl($this->storage->get('custom_discovery_url'));
420  }
421  }
422 
423  public function getProfileMappingFieldValue(string $field): string
424  {
425  return (string) ($this->profile_map[$field] ?? '');
426  }
427 
428  public function setProfileMappingFieldValue(string $field, string $value): void
429  {
430  $this->profile_map[$field] = $value;
431  }
432 
433  public function getProfileMappingFieldUpdate(string $field): bool
434  {
435  return (bool) ($this->profile_update_map[$field] ?? false);
436  }
437 
438  public function setProfileMappingFieldUpdate(string $field, bool $value): void
439  {
440  $this->profile_update_map[$field] = $value;
441  }
442 
443  public function setValidateScopes(int $validation_mode): void
444  {
445  $this->validate_scopes = $validation_mode;
446  }
447 
448  public function getValidateScopes(): int
449  {
450  return $this->validate_scopes;
451  }
452 
453  public function setCustomDiscoveryUrl(?string $discoveryUrl): void
454  {
455  $this->custom_discovery_url = $discoveryUrl;
456  }
457 
458  public function getCustomDiscoveryUrl(): ?string
459  {
461  }
465  public function getProfileMappingFields(): array
466  {
467  return [
468  'firstname' => 'firstname',
469  'lastname' => 'lastname',
470  'email' => 'email',
471  'birthday' => 'birthday'
472  ];
473  }
474 }
static getWebspaceDir(string $mode="filesystem")
get webspace directory
$type
$scopes
Definition: ltitoken.php:99
setProfileMappingFieldValue(string $field, string $value)
setCustomDiscoveryUrl(?string $discoveryUrl)
setRoleMappings(array $a_role_mappings)
global $DIC
Definition: feed.php:28
setProfileMappingFieldUpdate(string $field, bool $value)
validateScopes(string $discoveryURL, array $custom_scopes)
$url
$response
setAdditionalScopes(array $additional_scopes)
Class FlySystemFileAccessTest disabled disabled disabled.