-
Notifications
You must be signed in to change notification settings - Fork 56
Expand file tree
/
Copy pathProviderService.php
More file actions
218 lines (198 loc) · 7.96 KB
/
ProviderService.php
File metadata and controls
218 lines (198 loc) · 7.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
<?php
/**
* SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
declare(strict_types=1);
namespace OCA\UserOIDC\Service;
use OCA\UserOIDC\AppInfo\Application;
use OCA\UserOIDC\Db\Provider;
use OCA\UserOIDC\Db\ProviderMapper;
use OCA\UserOIDC\ResponseDefinitions;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\IAppConfig;
/**
* @psalm-import-type UserOIDCProvider from ResponseDefinitions
* @psalm-import-type UserOIDCProviderSettings from ResponseDefinitions
*/
class ProviderService {
public const SETTING_CHECK_BEARER = 'checkBearer';
public const SETTING_SEND_ID_TOKEN_HINT = 'sendIdTokenHint';
public const SETTING_BEARER_PROVISIONING = 'bearerProvisioning';
public const SETTING_UNIQUE_UID = 'uniqueUid';
public const SETTING_MAPPING_UID = 'mappingUid';
public const SETTING_MAPPING_UID_DEFAULT = 'sub';
public const SETTING_MAPPING_DISPLAYNAME = 'mappingDisplayName';
public const SETTING_MAPPING_EMAIL = 'mappingEmail';
public const SETTING_MAPPING_QUOTA = 'mappingQuota';
public const SETTING_MAPPING_GROUPS = 'mappingGroups';
public const SETTING_MAPPING_LANGUAGE = 'mappingLanguage';
public const SETTING_MAPPING_LOCALE = 'mappingLocale';
public const SETTING_MAPPING_ADDRESS = 'mappingAddress';
public const SETTING_MAPPING_STREETADDRESS = 'mappingStreetaddress';
public const SETTING_MAPPING_POSTALCODE = 'mappingPostalcode';
public const SETTING_MAPPING_LOCALITY = 'mappingLocality';
public const SETTING_MAPPING_REGION = 'mappingRegion';
public const SETTING_MAPPING_COUNTRY = 'mappingCountry';
public const SETTING_MAPPING_WEBSITE = 'mappingWebsite';
public const SETTING_MAPPING_AVATAR = 'mappingAvatar';
public const SETTING_MAPPING_TWITTER = 'mappingTwitter';
public const SETTING_MAPPING_FEDIVERSE = 'mappingFediverse';
public const SETTING_MAPPING_ORGANISATION = 'mappingOrganisation';
public const SETTING_MAPPING_ROLE = 'mappingRole';
public const SETTING_MAPPING_HEADLINE = 'mappingHeadline';
public const SETTING_MAPPING_BIOGRAPHY = 'mappingBiography';
public const SETTING_MAPPING_PHONE = 'mappingPhonenumber';
public const SETTING_MAPPING_GENDER = 'mappingGender';
public const SETTING_MAPPING_PRONOUNS = 'mappingPronouns';
public const SETTING_MAPPING_BIRTHDATE = 'mappingBirthdate';
public const SETTING_EXTRA_CLAIMS = 'extraClaims';
public const SETTING_JWKS_CACHE = 'jwksCache';
public const SETTING_JWKS_CACHE_TIMESTAMP = 'jwksCacheTimestamp';
public const SETTING_PROVIDER_BASED_ID = 'providerBasedId';
public const SETTING_GROUP_PROVISIONING = 'groupProvisioning';
public const SETTING_GROUP_WHITELIST_REGEX = 'groupWhitelistRegex';
public const SETTING_RESTRICT_LOGIN_TO_GROUPS = 'restrictLoginToGroups';
public const SETTING_AZURE_GROUP_NAMES = 'azureGroupNames';
public const SETTING_RESOLVE_NESTED_AND_FALLBACK_CLAIMS_MAPPING = 'nestedAndFallbackClaims';
public const SETTING_LDAP_MAPPING_ATTRIBUTE = 'mappingAttribute';
public const BOOLEAN_SETTINGS_DEFAULT_VALUES = [
self::SETTING_GROUP_PROVISIONING => false,
self::SETTING_PROVIDER_BASED_ID => false,
self::SETTING_BEARER_PROVISIONING => false,
self::SETTING_UNIQUE_UID => true,
self::SETTING_CHECK_BEARER => false,
self::SETTING_SEND_ID_TOKEN_HINT => false,
self::SETTING_RESTRICT_LOGIN_TO_GROUPS => false,
self::SETTING_AZURE_GROUP_NAMES => false,
self::SETTING_RESOLVE_NESTED_AND_FALLBACK_CLAIMS_MAPPING => false,
];
public function __construct(
private IAppConfig $appConfig,
private ProviderMapper $providerMapper,
) {
}
/**
* @return list<UserOIDCProvider>
*/
public function getProvidersWithSettings(): array {
$providers = $this->providerMapper->getProviders();
return array_values(array_map(function ($provider) {
$providerSettings = $this->getSettings($provider->getId());
return array_merge($provider->jsonSerialize(), ['settings' => $providerSettings]);
}, $providers));
}
public function getProviderByIdentifier(string $identifier): ?Provider {
try {
return $this->providerMapper->findProviderByIdentifier($identifier);
} catch (DoesNotExistException $e) {
return null;
}
}
public function getProviderWithSettings(int $id): array {
$provider = $this->providerMapper->getProvider($id);
$providerSettings = $this->getSettings($provider->getId());
return array_merge($provider->jsonSerialize(), ['settings' => $providerSettings]);
}
/**
* @return UserOIDCProviderSettings
*/
public function getSettings(int $providerId): array {
$result = [];
foreach ($this->getSupportedSettings() as $setting) {
$value = $this->getSetting($providerId, $setting);
$result[$setting] = $this->convertToJSON($setting, $value);
}
/** @var UserOIDCProviderSettings $result */
return $result;
}
public function setSettings(int $providerId, array $settings): array {
$storedSettings = $this->getSettings($providerId);
foreach ($settings as $setting => $value) {
if (!in_array($setting, $this->getSupportedSettings(), true)) {
continue;
}
$this->setSetting($providerId, $setting, $this->convertFromJSON($setting, $value));
$storedSettings[$setting] = $value;
}
return $storedSettings;
}
public function deleteSettings(int $providerId): void {
foreach ($this->getSupportedSettings() as $setting) {
$this->appConfig->deleteKey(Application::APP_ID, $this->getSettingsKey($providerId, $setting));
}
$this->appConfig->deleteKey(Application::APP_ID, $this->getSettingsKey($providerId, self::SETTING_JWKS_CACHE));
$this->appConfig->deleteKey(Application::APP_ID, $this->getSettingsKey($providerId, self::SETTING_JWKS_CACHE_TIMESTAMP));
}
public function setSetting(int $providerId, string $key, string $value): void {
$this->appConfig->setValueString(Application::APP_ID, $this->getSettingsKey($providerId, $key), $value, lazy: true);
}
public function getSetting(int $providerId, string $key, string $default = ''): string {
$value = $this->appConfig->getValueString(Application::APP_ID, $this->getSettingsKey($providerId, $key), '', lazy: true);
if ($value === '') {
return $default;
}
return $value;
}
public function getSettingsKey(int $providerId, string $key): string {
return 'provider-' . strval($providerId) . '-' . $key;
}
/**
* @return list<string>
*/
public function getSupportedSettings(): array {
return [
self::SETTING_MAPPING_DISPLAYNAME,
self::SETTING_MAPPING_EMAIL,
self::SETTING_MAPPING_QUOTA,
self::SETTING_MAPPING_UID,
self::SETTING_MAPPING_GROUPS,
self::SETTING_MAPPING_LANGUAGE,
self::SETTING_MAPPING_LOCALE,
self::SETTING_MAPPING_ADDRESS,
self::SETTING_MAPPING_STREETADDRESS,
self::SETTING_MAPPING_POSTALCODE,
self::SETTING_MAPPING_LOCALITY,
self::SETTING_MAPPING_REGION,
self::SETTING_MAPPING_COUNTRY,
self::SETTING_MAPPING_WEBSITE,
self::SETTING_MAPPING_AVATAR,
self::SETTING_MAPPING_TWITTER,
self::SETTING_MAPPING_FEDIVERSE,
self::SETTING_MAPPING_ORGANISATION,
self::SETTING_MAPPING_ROLE,
self::SETTING_MAPPING_HEADLINE,
self::SETTING_MAPPING_BIOGRAPHY,
self::SETTING_MAPPING_PHONE,
self::SETTING_MAPPING_GENDER,
self::SETTING_MAPPING_PRONOUNS,
self::SETTING_MAPPING_BIRTHDATE,
self::SETTING_UNIQUE_UID,
self::SETTING_CHECK_BEARER,
self::SETTING_SEND_ID_TOKEN_HINT,
self::SETTING_BEARER_PROVISIONING,
self::SETTING_EXTRA_CLAIMS,
self::SETTING_PROVIDER_BASED_ID,
self::SETTING_GROUP_PROVISIONING,
self::SETTING_GROUP_WHITELIST_REGEX,
self::SETTING_RESTRICT_LOGIN_TO_GROUPS,
self::SETTING_AZURE_GROUP_NAMES,
self::SETTING_RESOLVE_NESTED_AND_FALLBACK_CLAIMS_MAPPING,
];
}
private function convertFromJSON(string $key, $value): string {
if (array_key_exists($key, self::BOOLEAN_SETTINGS_DEFAULT_VALUES)) {
return $value ? '1' : '0';
}
return (string)$value;
}
private function convertToJSON(string $key, $value) {
if (array_key_exists($key, self::BOOLEAN_SETTINGS_DEFAULT_VALUES)) {
if ($value === '') {
return self::BOOLEAN_SETTINGS_DEFAULT_VALUES[$key];
}
return $value === '1';
}
return (string)$value;
}
}