ILIAS  trunk Revision v11.0_alpha-1862-g4e205cb56d4
All Data Structures Namespaces Files Functions Variables Enumerations Enumerator Modules Pages
ilOpenIdConnectUserSync Class Reference
+ Collaboration diagram for ilOpenIdConnectUserSync:

Public Member Functions

 __construct (private readonly ilOpenIdConnectSettings $settings, private readonly stdClass $user_info)
 
 setExternalAccount (string $ext_account)
 
 setInternalAccount (string $int_account)
 
 getUserId ()
 
 needsCreation ()
 
 updateUser ()
 

Data Fields

const AUTH_MODE = 'oidc'
 

Protected Member Functions

 parseRoleAssignments ()
 

Private Member Functions

 transformToXml ()
 
 valueFrom (string $connect_name)
 

Private Attributes

const UDF_STRING = 'udf_'
 
readonly ilLogger $logger
 
readonly ilXmlWriter $writer
 
string $ext_account = ''
 
string $int_account = ''
 
int $usr_id = 0
 
ilUserDefinedFields $udf
 

Detailed Description

Definition at line 21 of file class.ilOpenIdConnectUserSync.php.

Constructor & Destructor Documentation

◆ __construct()

ilOpenIdConnectUserSync::__construct ( private readonly ilOpenIdConnectSettings  $settings,
private readonly stdClass  $user_info 
)

Definition at line 33 of file class.ilOpenIdConnectUserSync.php.

References $DIC, ilUserDefinedFields\_getInstance(), and ILIAS\Repository\logger().

36  {
37  global $DIC;
38 
39  $this->logger = $DIC->logger()->auth();
40  $this->writer = new ilXmlWriter();
41  $this->udf = ilUserDefinedFields::_getInstance();
42  }
global $DIC
Definition: shib_login.php:22
+ Here is the call graph for this function:

Member Function Documentation

◆ getUserId()

ilOpenIdConnectUserSync::getUserId ( )

Definition at line 55 of file class.ilOpenIdConnectUserSync.php.

References $usr_id.

Referenced by transformToXml().

55  : int
56  {
57  return $this->usr_id;
58  }
+ Here is the caller graph for this function:

◆ needsCreation()

ilOpenIdConnectUserSync::needsCreation ( )

Definition at line 60 of file class.ilOpenIdConnectUserSync.php.

References ilLogLevel\DEBUG, and ILIAS\Repository\logger().

Referenced by parseRoleAssignments(), transformToXml(), and updateUser().

60  : bool
61  {
62  $this->logger->dump($this->int_account, ilLogLevel::DEBUG);
63 
64  return $this->int_account === '';
65  }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parseRoleAssignments()

ilOpenIdConnectUserSync::parseRoleAssignments ( )
protected
Returns
array<int, int> Map of role assignments, where the key equals the respetive value

Definition at line 281 of file class.ilOpenIdConnectUserSync.php.

References ilLogLevel\DEBUG, IL_INST_ID, ILIAS\Repository\int(), ILIAS\Repository\logger(), needsCreation(), null, and ILIAS\Repository\settings().

Referenced by transformToXml(), and updateUser().

281  : array
282  {
283  $this->logger->debug('Parsing role assignments');
284 
285  $found_role = false;
286 
287  $roles_assignable[$this->settings->getRole()] = $this->settings->getRole();
288 
289  $this->logger->dump($this->settings->getRoleMappings(), ilLogLevel::DEBUG);
290 
291  foreach ($this->settings->getRoleMappings() as $role_id => $role_info) {
292  $this->logger->dump($role_id, ilLogLevel::DEBUG);
293  $this->logger->dump($role_info, ilLogLevel::DEBUG);
294 
295  if ($role_info['value'] === '') {
296  $this->logger->debug('No role mapping for role: ' . $role_id);
297  continue;
298  }
299 
300  [$role_attribute, $role_value] = array_map(trim(...), explode('::', $role_info['value']));
301 
302  if (!$role_attribute || !$role_value) {
303  $this->logger->debug('No valid role mapping configuration for: ' . $role_id);
304  continue;
305  }
306 
307  if (!isset($this->user_info->{$role_attribute})) {
308  $this->logger->debug('No user info passed');
309  continue;
310  }
311 
312  if (!$role_info['update'] && !$this->needsCreation()) {
313  $this->logger->debug('No user role update for role: ' . $role_id);
314  continue;
315  }
316 
317  if (is_array($this->user_info->{$role_attribute})) {
318  $roles_claim = array_map(trim(...), $this->user_info->{$role_attribute});
319  if (!in_array($role_value, $roles_claim, true)) {
320  $this->logger->debug('User account has no ' . $role_value);
321  continue;
322  }
323  } elseif (strcmp(trim((string) $this->user_info->{$role_attribute}), $role_value) !== 0) {
324  $this->logger->debug('User account has no ' . $role_value);
325  continue;
326  }
327 
328  $this->logger->debug('Matching role mapping for role_id: ' . $role_id);
329 
330  $found_role = true;
331  $roles_assignable[(int) $role_id] = (int) $role_id;
332  $long_role_id = ('il_' . IL_INST_ID . '_role_' . $role_id);
333 
334  $this->writer->xmlElement(
335  'Role',
336  [
337  'Id' => $long_role_id,
338  'Type' => 'Global',
339  'Action' => 'Assign'
340  ],
341  null
342  );
343  }
344 
345  if (!$found_role && $this->needsCreation()) {
346  $long_role_id = ('il_' . IL_INST_ID . '_role_' . $this->settings->getRole());
347 
348  $this->writer->xmlElement(
349  'Role',
350  [
351  'Id' => $long_role_id,
352  'Type' => 'Global',
353  'Action' => 'Assign'
354  ],
355  null
356  );
357  }
358 
359  return $roles_assignable;
360  }
const IL_INST_ID
Definition: constants.php:40
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ setExternalAccount()

ilOpenIdConnectUserSync::setExternalAccount ( string  $ext_account)

Definition at line 44 of file class.ilOpenIdConnectUserSync.php.

References $ext_account.

44  : void
45  {
46  $this->ext_account = $ext_account;
47  }

◆ setInternalAccount()

ilOpenIdConnectUserSync::setInternalAccount ( string  $int_account)

Definition at line 49 of file class.ilOpenIdConnectUserSync.php.

References $int_account, ilObjUser\_lookupId(), and ILIAS\Repository\int().

Referenced by updateUser().

49  : void
50  {
51  $this->int_account = $int_account;
52  $this->usr_id = (int) ilObjUser::_lookupId($this->int_account);
53  }
static _lookupId($a_user_str)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ transformToXml()

ilOpenIdConnectUserSync::transformToXml ( )
private

Definition at line 95 of file class.ilOpenIdConnectUserSync.php.

References ilAuthUtils\_generateLogin(), getUserId(), ILIAS\Repository\logger(), needsCreation(), null, parseRoleAssignments(), ILIAS\Repository\settings(), and valueFrom().

Referenced by updateUser().

95  : void
96  {
97  $this->writer->xmlStartTag('Users');
98 
99  if ($this->needsCreation()) {
100  $this->writer->xmlStartTag('User', ['Action' => 'Insert']);
101  $this->writer->xmlElement('Login', [], ilAuthUtils::_generateLogin($this->ext_account));
102  } else {
103  $this->writer->xmlStartTag(
104  'User',
105  [
106  'Id' => $this->getUserId(),
107  'Action' => 'Update'
108  ]
109  );
110  $this->writer->xmlElement('Login', [], $this->int_account);
111  }
112 
113  $this->writer->xmlElement('ExternalAccount', [], $this->ext_account);
114  $this->writer->xmlElement('AuthMode', ['type' => self::AUTH_MODE], null);
115 
116  $this->parseRoleAssignments();
117 
118  if ($this->needsCreation()) {
119  $this->writer->xmlElement('Active', [], 'true');
120  $this->writer->xmlElement('TimeLimitOwner', [], 7);
121  $this->writer->xmlElement('TimeLimitUnlimited', [], 1);
122  $this->writer->xmlElement('TimeLimitFrom', [], time());
123  $this->writer->xmlElement('TimeLimitUntil', [], time());
124  }
125 
126  $profile_fields = $this->settings->getProfileMappingFields();
127 
128  $udf_fields = [];
129  foreach ($this->udf->getDefinitions() as $definition) {
130  $field = self::UDF_STRING . $definition['field_id'];
131  $udf_fields[$field] = $field;
132  }
133 
134  $profile_and_udf_fields = $profile_fields + $udf_fields;
135  foreach ($profile_and_udf_fields as $field => $lng_key) {
136  $connect_name = $this->settings->getProfileMappingFieldValue($field);
137  if (!$connect_name) {
138  $this->logger->debug('Ignoring unconfigured field: ' . $field);
139  continue;
140  }
141  if (!$this->needsCreation() && !$this->settings->getProfileMappingFieldUpdate($field)) {
142  $this->logger->debug('Ignoring ' . $field . ' for update.');
143  continue;
144  }
145 
146  $value = $this->valueFrom($connect_name);
147  if ($value === '') {
148  $this->logger->debug('Cannot find user data in ' . $connect_name);
149  continue;
150  }
151 
152  switch ($field) {
153  case 'gender':
154  switch (strtolower($value)) {
155  case 'm':
156  case 'male':
157  $this->writer->xmlElement('Gender', [], 'm');
158  break;
159 
160  case 'f':
161  case 'female':
162  $this->writer->xmlElement('Gender', [], 'f');
163  break;
164 
165  default:
166  // use the default for anything that is not clearly m or f
167  $this->writer->xmlElement('Gender', [], 'n');
168  break;
169  }
170  break;
171 
172  case 'firstname':
173  $this->writer->xmlElement('Firstname', [], $value);
174  break;
175 
176  case 'lastname':
177  $this->writer->xmlElement('Lastname', [], $value);
178  break;
179 
180  case 'hobby':
181  $this->writer->xmlElement('Hobby', [], $value);
182  break;
183 
184  case 'title':
185  $this->writer->xmlElement('Title', [], $value);
186  break;
187 
188  case 'institution':
189  $this->writer->xmlElement('Institution', [], $value);
190  break;
191 
192  case 'department':
193  $this->writer->xmlElement('Department', [], $value);
194  break;
195 
196  case 'street':
197  $this->writer->xmlElement('Street', [], $value);
198  break;
199 
200  case 'city':
201  $this->writer->xmlElement('City', [], $value);
202  break;
203 
204  case 'zipcode':
205  $this->writer->xmlElement('PostalCode', [], $value);
206  break;
207 
208  case 'country':
209  $this->writer->xmlElement('Country', [], $value);
210  break;
211 
212  case 'phone_office':
213  $this->writer->xmlElement('PhoneOffice', [], $value);
214  break;
215 
216  case 'phone_home':
217  $this->writer->xmlElement('PhoneHome', [], $value);
218  break;
219 
220  case 'phone_mobile':
221  $this->writer->xmlElement('PhoneMobile', [], $value);
222  break;
223 
224  case 'fax':
225  $this->writer->xmlElement('Fax', [], $value);
226  break;
227 
228  case 'email':
229  $this->writer->xmlElement('Email', [], $value);
230  break;
231 
232  case 'second_email':
233  $this->writer->xmlElement('SecondEmail', [], $value);
234  break;
235 
236  case 'matriculation':
237  $this->writer->xmlElement('Matriculation', [], $value);
238  break;
239 
240  default:
241  if (!str_starts_with($field, 'udf_')) {
242  continue 2;
243  }
244 
245  $id_data = explode('_', $field);
246  if (!isset($id_data[1])) {
247  continue 2;
248  }
249 
250  $definition = $this->udf->getDefinition((int) $id_data[1]);
251  if (empty($definition)) {
252  $this->logger->warning(
253  sprintf(
254  'Invalid/Orphaned UD field mapping detected: %s',
255  $field
256  )
257  );
258  break;
259  }
260 
261  $this->writer->xmlElement(
262  'UserDefinedField',
263  [
264  'Id' => $definition['il_id'],
265  'Name' => $definition['field_name']
266  ],
267  $value
268  );
269  break;
270  }
271  }
272  $this->writer->xmlEndTag('User');
273  $this->writer->xmlEndTag('Users');
274 
275  $this->logger->debug($this->writer->xmlDumpMem());
276  }
static _generateLogin(string $a_login)
generate free login by starting with a default string and adding postfix numbers
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ updateUser()

ilOpenIdConnectUserSync::updateUser ( )

Definition at line 67 of file class.ilOpenIdConnectUserSync.php.

References ilObjUser\_checkExternalAuthAccount(), ILIAS\Repository\logger(), needsCreation(), parseRoleAssignments(), setInternalAccount(), ILIAS\Repository\settings(), transformToXml(), and USER_FOLDER_ID.

67  : bool
68  {
69  if ($this->needsCreation() && !$this->settings->isSyncAllowed()) {
70  throw new ilOpenIdConnectSyncForbiddenException('No internal account given.');
71  }
72 
73  $this->transformToXml();
74 
75  $importParser = new ilUserImportParser();
76  $importParser->setXMLContent($this->writer->xmlDumpMem(false));
77 
78  $roles = $this->parseRoleAssignments();
79  $importParser->setRoleAssignment($roles);
80 
81  $importParser->setFolderId(USER_FOLDER_ID);
82  $importParser->startParsing();
83  $debug = $importParser->getProtocol();
84  $this->logger->debug(json_encode($debug, JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT));
85 
87  self::AUTH_MODE,
88  $this->ext_account
89  );
91 
92  return true;
93  }
const USER_FOLDER_ID
Definition: constants.php:33
static _checkExternalAuthAccount(string $a_auth, string $a_account, bool $tryFallback=true)
check whether external account and authentication method matches with a user
+ Here is the call graph for this function:

◆ valueFrom()

ilOpenIdConnectUserSync::valueFrom ( string  $connect_name)
private

Definition at line 362 of file class.ilOpenIdConnectUserSync.php.

References ILIAS\Repository\logger().

Referenced by transformToXml().

362  : string
363  {
364  if (!$connect_name) {
365  return '';
366  }
367 
368  if (!property_exists($this->user_info, $connect_name)) {
369  $this->logger->debug('Cannot find property ' . $connect_name . ' in user info ');
370  return '';
371  }
372 
373  return (string) $this->user_info->{$connect_name};
374  }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Field Documentation

◆ $ext_account

string ilOpenIdConnectUserSync::$ext_account = ''
private

Definition at line 28 of file class.ilOpenIdConnectUserSync.php.

Referenced by setExternalAccount().

◆ $int_account

string ilOpenIdConnectUserSync::$int_account = ''
private

Definition at line 29 of file class.ilOpenIdConnectUserSync.php.

Referenced by setInternalAccount().

◆ $logger

readonly ilLogger ilOpenIdConnectUserSync::$logger
private

Definition at line 26 of file class.ilOpenIdConnectUserSync.php.

◆ $udf

ilUserDefinedFields ilOpenIdConnectUserSync::$udf
private

Definition at line 31 of file class.ilOpenIdConnectUserSync.php.

◆ $usr_id

int ilOpenIdConnectUserSync::$usr_id = 0
private

Definition at line 30 of file class.ilOpenIdConnectUserSync.php.

Referenced by getUserId().

◆ $writer

readonly ilXmlWriter ilOpenIdConnectUserSync::$writer
private

Definition at line 27 of file class.ilOpenIdConnectUserSync.php.

◆ AUTH_MODE

const ilOpenIdConnectUserSync::AUTH_MODE = 'oidc'

◆ UDF_STRING

const ilOpenIdConnectUserSync::UDF_STRING = 'udf_'
private

Definition at line 24 of file class.ilOpenIdConnectUserSync.php.


The documentation for this class was generated from the following file: