ILIAS  trunk Revision v11.0_alpha-2638-g80c1d007f79
class.ilSamlIdp.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
22 
23 final class ilSamlIdp
24 {
25  private const string PROP_IDP_ID = 'idp_id';
26  private const string PROP_IS_ACTIVE = 'is_active';
27  private const string PROP_DEFAULT_ROLE_ID = 'default_role_id';
28  private const string PROP_UID_CLAIM = 'uid_claim';
29  private const string PROP_LOGIN_CLAIM = 'login_claim';
30  private const string PROP_ENTITY_ID = 'entity_id';
31  private const string PROP_SYNC_STATUS = 'sync_status';
32  private const string PROP_ALLOW_LOCAL_AUTH = 'allow_local_auth';
33  private const string PROP_ACCOUNT_MIGR_STATUS = 'account_migr_status';
34 
35  private readonly ilDBInterface $db;
37  private static array $instances = [];
38  private bool $is_active = false;
39  private bool $allow_local_auth = false;
40  private int $default_role_id = 0;
41  private string $uid_claim = '';
42  private string $login_claim = '';
43  private bool $sync_status = false;
44  private string $entity_id = '';
45  private bool $account_migration_status = false;
46 
47  public function __construct(protected int $idp_id = 0)
48  {
49  $this->db = $GLOBALS['DIC']->database();
50 
51  if ($this->idp_id > 0) {
52  $this->read();
53  }
54  }
55 
56  public static function getFirstActiveIdp(): self
57  {
58  $idps = self::getActiveIdpList();
59  if ($idps !== []) {
60  return current($idps);
61  }
62 
63  throw new ilSamlException('No active SAML IDP found');
64  }
65 
66  public static function getInstanceByIdpId(int $a_idp_id): self
67  {
68  if (!isset(self::$instances[$a_idp_id]) || !(self::$instances[$a_idp_id] instanceof self)) {
69  self::$instances[$a_idp_id] = new self($a_idp_id);
70  }
71 
72  return self::$instances[$a_idp_id];
73  }
74 
75  private function read(): void
76  {
77  $query = 'SELECT * FROM saml_idp_settings WHERE idp_id = ' . $this->db->quote($this->idp_id, ilDBConstants::T_INTEGER);
78  $res = $this->db->query($query);
79  while ($record = $this->db->fetchAssoc($res)) {
80  $this->bindDbRecord($record);
81  return;
82  }
83 
84  throw new ilException('Could not find idp');
85  }
86 
87  public function persist(): void
88  {
89  if ($this->idp_id === 0) {
90  $this->setIdpId($this->db->nextId('saml_idp_settings'));
91  }
92 
93  $this->db->replace(
94  'saml_idp_settings',
95  [
96  self::PROP_IDP_ID => [ilDBConstants::T_INTEGER, $this->idp_id]
97  ],
98  [
99  self::PROP_IS_ACTIVE => [ilDBConstants::T_INTEGER, (int) $this->is_active],
100  self::PROP_DEFAULT_ROLE_ID => [ilDBConstants::T_INTEGER, $this->default_role_id],
101  self::PROP_UID_CLAIM => [ilDBConstants::T_TEXT, $this->uid_claim],
102  self::PROP_LOGIN_CLAIM => [ilDBConstants::T_TEXT, $this->login_claim],
103  self::PROP_ENTITY_ID => [ilDBConstants::T_TEXT, $this->entity_id],
104  self::PROP_SYNC_STATUS => [ilDBConstants::T_INTEGER, (int) $this->sync_status],
105  self::PROP_ALLOW_LOCAL_AUTH => [ilDBConstants::T_INTEGER, (int) $this->allow_local_auth],
106  self::PROP_ACCOUNT_MIGR_STATUS => [ilDBConstants::T_INTEGER, (int) $this->account_migration_status]
107  ]
108  );
109  }
110 
115  public function delete(): void
116  {
117  $mapping = new ilExternalAuthUserAttributeMapping('saml', $this->idp_id);
118  $mapping->delete();
119 
120  $this->db->manipulateF(
121  'UPDATE usr_data SET auth_mode = %s WHERE auth_mode = %s',
123  ['default', ilAuthUtils::AUTH_SAML . '_' . $this->idp_id]
124  );
125 
126  $this->db->manipulate('DELETE FROM saml_idp_settings WHERE idp_id = ' . $this->db->quote(
127  $this->idp_id,
129  ));
130  }
131 
135  public function toArray(): array
136  {
137  return [
138  self::PROP_IDP_ID => $this->idp_id,
139  self::PROP_IS_ACTIVE => $this->is_active,
140  self::PROP_DEFAULT_ROLE_ID => $this->default_role_id,
141  self::PROP_UID_CLAIM => $this->uid_claim,
142  self::PROP_LOGIN_CLAIM => $this->login_claim,
143  self::PROP_SYNC_STATUS => $this->sync_status,
144  self::PROP_ACCOUNT_MIGR_STATUS => $this->account_migration_status,
145  self::PROP_ALLOW_LOCAL_AUTH => $this->allow_local_auth,
146  self::PROP_ENTITY_ID => $this->entity_id
147  ];
148  }
149 
153  public function bindDbRecord(array $record): void
154  {
155  $this->setIdpId((int) $record[self::PROP_IDP_ID]);
156  $this->setActive((bool) $record[self::PROP_IS_ACTIVE]);
157  $this->setDefaultRoleId((int) $record[self::PROP_DEFAULT_ROLE_ID]);
158  $this->setUidClaim((string) $record[self::PROP_UID_CLAIM]);
159  $this->setLoginClaim((string) $record[self::PROP_LOGIN_CLAIM]);
160  $this->setSynchronizationStatus((bool) $record[self::PROP_SYNC_STATUS]);
161  $this->setAccountMigrationStatus((bool) $record[self::PROP_ACCOUNT_MIGR_STATUS]);
162  $this->setLocalLocalAuthenticationStatus((bool) $record[self::PROP_ALLOW_LOCAL_AUTH]);
163  $this->setEntityId((string) $record[self::PROP_ENTITY_ID]);
164  }
165 
166  public function bindForm(StandardForm $form): void
167  {
168  $data = $form->getData();
169  $this->setUidClaim((string) ($data[self::PROP_UID_CLAIM] ?? ""));
170  $this->setLocalLocalAuthenticationStatus((bool) ($data[self::PROP_ALLOW_LOCAL_AUTH] ?? false));
171  $this->setSynchronizationStatus(($data[self::PROP_SYNC_STATUS] ?? null) !== null);
172 
173  $this->setLoginClaim("");
174  $this->setDefaultRoleId(0);
175  $this->setAccountMigrationStatus(true);
176  if ($this->isSynchronizationEnabled()) {
177  $sync_status_data = $data[self::PROP_SYNC_STATUS];
178  $this->setLoginClaim($sync_status_data[self::PROP_LOGIN_CLAIM]);
179  $this->setDefaultRoleId((int) $sync_status_data[self::PROP_DEFAULT_ROLE_ID]);
180  $this->setAccountMigrationStatus((bool) $sync_status_data[self::PROP_ACCOUNT_MIGR_STATUS]);
181  }
182  }
183 
184  public static function isAuthModeSaml(string $a_auth_mode): bool
185  {
186  if ('' === $a_auth_mode) {
187  return false;
188  }
189 
190  $auth_arr = explode('_', $a_auth_mode);
191  return (
192  count($auth_arr) === 2 &&
193  (int) $auth_arr[0] === ilAuthUtils::AUTH_SAML &&
194  is_string($auth_arr[1]) && $auth_arr[1] !== ''
195  );
196  }
197 
198  public static function getIdpIdByAuthMode(string $a_auth_mode): ?int
199  {
200  if (self::isAuthModeSaml($a_auth_mode)) {
201  $auth_arr = explode('_', $a_auth_mode);
202  return (int) $auth_arr[1];
203  }
204 
205  return null;
206  }
207 
208  public static function geIdpIdByEntityId(string $entityId): int
209  {
210  foreach (self::getAllIdps() as $idp) {
211  if ($idp->isActive() && $idp->getEntityId() === $entityId) {
212  return $idp->getIdpId();
213  }
214  }
215 
216  return 0;
217  }
218 
222  public static function getActiveIdpList(): array
223  {
224  $idps = [];
225  foreach (self::getAllIdps() as $idp) {
226  if ($idp->isActive()) {
227  $idps[] = $idp;
228  }
229  }
230 
231  return $idps;
232  }
233 
237  public static function getAllIdps(): array
238  {
239  global $DIC;
240 
241  $res = $DIC->database()->query('SELECT * FROM saml_idp_settings');
242 
243  $idps = [];
244  while ($row = $DIC->database()->fetchAssoc($res)) {
245  $idp = new self();
246  $idp->bindDbRecord($row);
247 
248  $idps[] = $idp;
249  }
250 
251  return $idps;
252  }
253 
254  public static function getAuthModeByKey(string $a_auth_key): string
255  {
256  $auth_arr = explode('_', $a_auth_key);
257  if (count($auth_arr) > 1) {
258  return 'saml_' . $auth_arr[1];
259  }
260 
261  return 'saml';
262  }
263 
264  public static function getKeyByAuthMode(string $a_auth_mode): string
265  {
266  $auth_arr = explode('_', $a_auth_mode);
267  if (count($auth_arr) > 1) {
268  return ilAuthUtils::AUTH_SAML . '_' . $auth_arr[1];
269  }
270 
271  return (string) ilAuthUtils::AUTH_SAML;
272  }
273 
274  public function getEntityId(): string
275  {
276  return $this->entity_id;
277  }
278 
279  public function setEntityId(string $entity_id): void
280  {
281  $this->entity_id = $entity_id;
282  }
283 
284  public function isActive(): bool
285  {
286  return $this->is_active;
287  }
288 
289  public function setActive(bool $is_active): void
290  {
291  $this->is_active = $is_active;
292  }
293 
294  public function getIdpId(): int
295  {
296  return $this->idp_id;
297  }
298 
299  public function setIdpId(int $idp_id): void
300  {
301  $this->idp_id = $idp_id;
302  }
303 
304  public function allowLocalAuthentication(): bool
305  {
307  }
308 
309  public function setLocalLocalAuthenticationStatus(bool $status): void
310  {
311  $this->allow_local_auth = $status;
312  }
313 
314  public function getDefaultRoleId(): int
315  {
316  return $this->default_role_id;
317  }
318 
319  public function setDefaultRoleId(int $role_id): void
320  {
321  $this->default_role_id = $role_id;
322  }
323 
324  public function setUidClaim(string $claim): void
325  {
326  $this->uid_claim = $claim;
327  }
328 
329  public function getUidClaim(): string
330  {
331  return $this->uid_claim;
332  }
333 
334  public function setLoginClaim(string $claim): void
335  {
336  $this->login_claim = $claim;
337  }
338 
339  public function getLoginClaim(): string
340  {
341  return $this->login_claim;
342  }
343 
344  public function isSynchronizationEnabled(): bool
345  {
346  return $this->sync_status;
347  }
348 
349  public function setSynchronizationStatus(bool $sync): void
350  {
351  $this->sync_status = $sync;
352  }
353 
354  public function isAccountMigrationEnabled(): bool
355  {
357  }
358 
359  public function setAccountMigrationStatus(bool $status): void
360  {
361  $this->account_migration_status = $status;
362  }
363 }
bindDbRecord(array $record)
$res
Definition: ltiservices.php:66
static isAuthModeSaml(string $a_auth_mode)
const string PROP_UID_CLAIM
setActive(bool $is_active)
bindForm(StandardForm $form)
const string PROP_DEFAULT_ROLE_ID
setDefaultRoleId(int $role_id)
readonly ilDBInterface $db
static getInstanceByIdpId(int $a_idp_id)
static getIdpIdByAuthMode(string $a_auth_mode)
const string PROP_IS_ACTIVE
setEntityId(string $entity_id)
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
setLocalLocalAuthenticationStatus(bool $status)
setUidClaim(string $claim)
setLoginClaim(string $claim)
$GLOBALS["DIC"]
Definition: wac.php:53
static array $instances
global $DIC
Definition: shib_login.php:26
__construct(protected int $idp_id=0)
const string PROP_ENTITY_ID
int $default_role_id
static getAllIdps()
string $login_claim
static getKeyByAuthMode(string $a_auth_mode)
const string PROP_ACCOUNT_MIGR_STATUS
const string PROP_ALLOW_LOCAL_AUTH
string $uid_claim
setAccountMigrationStatus(bool $status)
static getAuthModeByKey(string $a_auth_key)
string $entity_id
isAccountMigrationEnabled()
const string PROP_IDP_ID
setIdpId(int $idp_id)
static geIdpIdByEntityId(string $entityId)
bool $allow_local_auth
const string PROP_LOGIN_CLAIM
allowLocalAuthentication()
static getActiveIdpList()
isSynchronizationEnabled()
setSynchronizationStatus(bool $sync)
const int AUTH_SAML
bool $account_migration_status
static getFirstActiveIdp()
const string PROP_SYNC_STATUS