|
22 | 22 | use OCA\Libresign\Service\IdentifyMethod\Xmpp; |
23 | 23 | use OCP\IConfig; |
24 | 24 | use OCP\IL10N; |
| 25 | +use OCP\IUserManager; |
25 | 26 |
|
26 | 27 | class IdentifyMethodService { |
27 | 28 | public const IDENTIFY_ACCOUNT = 'account'; |
@@ -56,6 +57,7 @@ public function __construct( |
56 | 57 | private IConfig $config, |
57 | 58 | private IdentifyMethodMapper $identifyMethodMapper, |
58 | 59 | private IL10N $l10n, |
| 60 | + private IUserManager $userManager, |
59 | 61 | private Account $account, |
60 | 62 | private Email $email, |
61 | 63 | private Signal $signal, |
@@ -283,4 +285,68 @@ public function getIdentifyMethodsSettings(): array { |
283 | 285 | } |
284 | 286 | return $this->identifyMethodsSettings; |
285 | 287 | } |
| 288 | + |
| 289 | + /** |
| 290 | + * Resolve UID from certificate chain data |
| 291 | + * |
| 292 | + * Extracts and resolves the identifier from certificate subject or extensions. |
| 293 | + * Supports fallbacks for older LibreSign versions and converts to standard |
| 294 | + * identifier format (account:uid or email:value). |
| 295 | + * |
| 296 | + * @param array $chainArr Certificate chain array with subject and extensions |
| 297 | + * @param string $host Host domain for email matching |
| 298 | + * @return string|null Resolved identifier in format "type:value" or null |
| 299 | + */ |
| 300 | + public function resolveUid(array $chainArr, string $host): ?string { |
| 301 | + if (!empty($chainArr['subject']['UID'])) { |
| 302 | + return $chainArr['subject']['UID']; |
| 303 | + } |
| 304 | + if (!empty($chainArr['subject']['CN'])) { |
| 305 | + $cn = $chainArr['subject']['CN']; |
| 306 | + if (is_array($cn)) { |
| 307 | + $cn = $cn[0]; |
| 308 | + } |
| 309 | + if (preg_match('/^(?<key>.*):(?<value>.*), /', (string)$cn, $matches)) { |
| 310 | + return $matches['key'] . ':' . $matches['value']; |
| 311 | + } |
| 312 | + } |
| 313 | + if (!empty($chainArr['extensions']['subjectAltName'])) { |
| 314 | + $subjectAltName = $chainArr['extensions']['subjectAltName']; |
| 315 | + if (is_array($subjectAltName)) { |
| 316 | + $subjectAltName = $subjectAltName[0]; |
| 317 | + } |
| 318 | + preg_match('/^(?<key>(email|account)):(?<value>.*)$/', (string)$subjectAltName, $matches); |
| 319 | + if ($matches) { |
| 320 | + if (str_ends_with($matches['value'], $host)) { |
| 321 | + $uid = str_replace('@' . $host, '', $matches['value']); |
| 322 | + $userFound = $this->userManager->get($uid); |
| 323 | + if ($userFound) { |
| 324 | + return 'account:' . $uid; |
| 325 | + } else { |
| 326 | + $userFound = $this->userManager->getByEmail($matches['value']); |
| 327 | + if ($userFound) { |
| 328 | + $userFound = current($userFound); |
| 329 | + return 'account:' . $userFound->getUID(); |
| 330 | + } else { |
| 331 | + return 'email:' . $matches['value']; |
| 332 | + } |
| 333 | + } |
| 334 | + } else { |
| 335 | + $userFound = $this->userManager->getByEmail($matches['value']); |
| 336 | + if ($userFound) { |
| 337 | + $userFound = current($userFound); |
| 338 | + return 'account:' . $userFound->getUID(); |
| 339 | + } else { |
| 340 | + $userFound = $this->userManager->get($matches['value']); |
| 341 | + if ($userFound) { |
| 342 | + return 'account:' . $userFound->getUID(); |
| 343 | + } else { |
| 344 | + return $matches['key'] . ':' . $matches['value']; |
| 345 | + } |
| 346 | + } |
| 347 | + } |
| 348 | + } |
| 349 | + } |
| 350 | + return null; |
| 351 | + } |
286 | 352 | } |
0 commit comments