19declare(strict_types=1);
42 private readonly stdClass $user_info
46 $this->
logger = $DIC->logger()->auth();
47 $this->
lng = $DIC->language();
49 $this->user_defined_fields =
$DIC[
'user']->getProfile()->getAllUserDefinedFields();
72 return $this->int_account ===
'';
84 $importParser->setXMLContent($this->writer->xmlDumpMem(
false));
87 $importParser->setRoleAssignment($roles);
90 $importParser->startParsing();
91 $debug = $importParser->getProtocol();
92 $this->
logger->debug(json_encode($debug, JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT));
105 $this->writer->xmlStartTag(
'Users');
108 $this->writer->xmlStartTag(
'User', [
'Action' =>
'Insert']);
111 $this->writer->xmlStartTag(
118 $this->writer->xmlElement(
'Login', [], $this->int_account);
121 $this->writer->xmlElement(
'ExternalAccount', [], $this->ext_account);
122 $this->writer->xmlElement(
'AuthMode', [
'type' => self::AUTH_MODE],
null);
127 $this->writer->xmlElement(
'Active', [],
'true');
128 $this->writer->xmlElement(
'TimeLimitOwner', [], 7);
129 $this->writer->xmlElement(
'TimeLimitUnlimited', [], 1);
130 $this->writer->xmlElement(
'TimeLimitFrom', [], time());
131 $this->writer->xmlElement(
'TimeLimitUntil', [], time());
134 $profile_fields = $this->
settings->getProfileMappingFields();
137 foreach ($this->user_defined_fields as $field) {
138 $field = self::UDF_STRING . $field->getIdentifier();
139 $udf_fields[$field] = $field;
142 $profile_and_udf_fields = $profile_fields + $udf_fields;
143 foreach ($profile_and_udf_fields as $field => $lng_key) {
144 $connect_name = $this->
settings->getProfileMappingFieldValue($field);
145 if (!$connect_name) {
146 $this->
logger->debug(
'Ignoring unconfigured field: ' . $field);
150 $this->
logger->debug(
'Ignoring ' . $field .
' for update.');
154 $value = $this->
valueFrom($connect_name);
156 $this->
logger->debug(
'Cannot find user data in ' . $connect_name);
162 switch (strtolower($value)) {
165 $this->writer->xmlElement(
'Gender', [],
'm');
170 $this->writer->xmlElement(
'Gender', [],
'f');
175 $this->writer->xmlElement(
'Gender', [],
'n');
181 $this->writer->xmlElement(
'Firstname', [], $value);
185 $this->writer->xmlElement(
'Lastname', [], $value);
189 $this->writer->xmlElement(
'Hobby', [], $value);
193 $this->writer->xmlElement(
'Title', [], $value);
197 $this->writer->xmlElement(
'Institution', [], $value);
201 $this->writer->xmlElement(
'Department', [], $value);
205 $this->writer->xmlElement(
'Street', [], $value);
209 $this->writer->xmlElement(
'City', [], $value);
213 $this->writer->xmlElement(
'PostalCode', [], $value);
217 $this->writer->xmlElement(
'Country', [], $value);
221 $this->writer->xmlElement(
'PhoneOffice', [], $value);
225 $this->writer->xmlElement(
'PhoneHome', [], $value);
229 $this->writer->xmlElement(
'PhoneMobile', [], $value);
233 $this->writer->xmlElement(
'Fax', [], $value);
237 $this->writer->xmlElement(
'Email', [], $value);
241 $this->writer->xmlElement(
'SecondEmail', [], $value);
244 case 'matriculation':
245 $this->writer->xmlElement(
'Matriculation', [], $value);
249 if (!str_starts_with($field,
'udf_')) {
253 $id_data = explode(
'_', $field);
254 if (!isset($id_data[1])) {
258 $field = $this->user_defined_fields[$id_data[1]] ??
null;
259 if ($definition ===
null) {
262 'Invalid/Orphaned UD field mapping detected: %s',
269 $this->writer->xmlElement(
272 'Id' => $field->getIdentifier(),
273 'Name' => $field->getLabel($this->lng)
280 $this->writer->xmlEndTag(
'User');
281 $this->writer->xmlEndTag(
'Users');
283 $this->
logger->debug($this->writer->xmlDumpMem());
291 $this->
logger->debug(
'Parsing role assignments');
299 foreach ($this->
settings->getRoleMappings() as $role_id => $role_info) {
303 if ($role_info[
'value'] ===
'') {
304 $this->
logger->debug(
'No role mapping for role: ' . $role_id);
308 [$role_attribute, $role_value] = array_map(trim(...), explode(
'::', $role_info[
'value']));
310 if (!$role_attribute || !$role_value) {
311 $this->
logger->debug(
'No valid role mapping configuration for: ' . $role_id);
315 if (!isset($this->user_info->{$role_attribute})) {
316 $this->
logger->debug(
'No user info passed');
321 $this->
logger->debug(
'No user role update for role: ' . $role_id);
325 if (is_array($this->user_info->{$role_attribute})) {
326 $roles_claim = array_map(
327 static function (mixed $value):
string {
328 return match (
true) {
329 is_string($value) => trim($value),
330 $value instanceof stdClass && property_exists($value,
'id') => trim((
string) $value->id),
331 $value instanceof stdClass && property_exists($value,
'value') => trim((
string) $value->value),
332 default =>
throw new DomainException(sprintf(
333 'Unexpected role value type, please check your provider configuration: %s',
334 print_r($value,
true)
338 $this->user_info->{$role_attribute}
340 if (!in_array($role_value, $roles_claim,
true)) {
341 $this->
logger->debug(
'User account has no ' . $role_value);
344 } elseif (strcmp(trim((
string) $this->user_info->{$role_attribute}), $role_value) !== 0) {
345 $this->
logger->debug(
'User account has no ' . $role_value);
349 $this->
logger->debug(
'Matching role mapping for role_id: ' . $role_id);
352 $roles_assignable[(
int) $role_id] = (
int) $role_id;
353 $long_role_id = (
'il_' .
IL_INST_ID .
'_role_' . $role_id);
355 $this->writer->xmlElement(
358 'Id' => $long_role_id,
366 if (!$found_role && $this->needsCreation()) {
369 $this->writer->xmlElement(
372 'Id' => $long_role_id,
380 return $roles_assignable;
383 private function valueFrom(
string $connect_name): string
385 if (!$connect_name) {
389 if (!property_exists($this->user_info, $connect_name)) {
390 $this->
logger->debug(
'Cannot find property ' . $connect_name .
' in user info ');
394 return (
string) $this->user_info->{$connect_name};
static _generateLogin(string $a_login)
generate free login by starting with a default string and adding postfix numbers
Component logger with individual log levels by component id.
static _lookupId(string|array $a_user_str)
static _checkExternalAuthAccount(string $a_auth, string $a_account, bool $tryFallback=true)
check whether external account and authentication method matches with a user
__construct(private readonly ilOpenIdConnectSettings $settings, private readonly stdClass $user_info)
readonly ilLogger $logger
setExternalAccount(string $ext_account)
valueFrom(string $connect_name)
array $user_defined_fields
setInternalAccount(string $int_account)
readonly ilXmlWriter $writer
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...