Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion appinfo/info.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<name>OpenID Connect user backend</name>
<summary>Use an OpenID Connect backend to login to your Nextcloud</summary>
<description>Allows flexible configuration of an OIDC server as Nextcloud login user backend.</description>
<version>8.1.0</version>
<version>8.1.1</version>
<licence>agpl</licence>
<author>Roeland Jago Douma</author>
<author>Julius Härtl</author>
Expand Down
2 changes: 1 addition & 1 deletion lib/Controller/LoginController.php
Original file line number Diff line number Diff line change
Expand Up @@ -601,7 +601,7 @@ public function code(string $state = '', string $code = '', string $scope = '',
$this->eventDispatcher->dispatchTyped(new UserLoggedInEvent($user, $user->getUID(), null, false));
}

$storeLoginTokenEnabled = $this->appConfig->getValueString(Application::APP_ID, 'store_login_token', '0') === '1';
$storeLoginTokenEnabled = $this->appConfig->getValueString(Application::APP_ID, 'store_login_token', '0', lazy: true) === '1';
if ($storeLoginTokenEnabled) {
// store all token information for potential token exchange requests
$tokenData = array_merge(
Expand Down
2 changes: 1 addition & 1 deletion lib/Controller/SettingsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ public function setID4ME(bool $enabled): JSONResponse {
public function setAdminConfig(array $values): JSONResponse {
foreach ($values as $key => $value) {
if ($key === 'store_login_token' && is_bool($value)) {
$this->appConfig->setValueString(Application::APP_ID, 'store_login_token', $value ? '1' : '0');
$this->appConfig->setValueString(Application::APP_ID, 'store_login_token', $value ? '1' : '0', lazy: true);
}
}
return new JSONResponse([]);
Expand Down
2 changes: 1 addition & 1 deletion lib/Listener/ExternalTokenRequestedListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public function handle(Event $event): void {

$this->logger->debug('[ExternalTokenRequestedListener] received request');

$storeLoginTokenEnabled = $this->appConfig->getValueString(Application::APP_ID, 'store_login_token', '0') === '1';
$storeLoginTokenEnabled = $this->appConfig->getValueString(Application::APP_ID, 'store_login_token', '0', lazy: true) === '1';
if (!$storeLoginTokenEnabled) {
throw new GetExternalTokenFailedException('Failed to get external token, login token is not stored', 0);
}
Expand Down
69 changes: 69 additions & 0 deletions lib/Migration/Version080101Date20251201121749.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php

declare(strict_types=1);

/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OCA\UserOIDC\Migration;

use Closure;
use OCA\UserOIDC\AppInfo\Application;
use OCA\UserOIDC\Db\ProviderMapper;
use OCA\UserOIDC\Service\ProviderService;
use OCP\IAppConfig;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;

class Version080101Date20251201121749 extends SimpleMigrationStep {

public function __construct(
private IAppConfig $appConfig,
private ProviderService $providerService,
private ProviderMapper $providerMapper,
) {
}

/**
* @param IOutput $output
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
* @param array $options
*/
public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options) {
// make admin settings lazy
$keys = [
'store_login_token',
'id4me_enabled',
'allow_multiple_user_backends',
];
foreach ($keys as $key) {
try {
if ($this->appConfig->hasKey(Application::APP_ID, $key)) {
$value = $this->appConfig->getValueString(Application::APP_ID, $key);
$this->appConfig->setValueString(Application::APP_ID, $key, $value, lazy: true);
}
} catch (\Exception) {
}
}

// make all provider settings lazy
$providers = $this->providerMapper->getProviders();
$supportedSettingKeys = $this->providerService->getSupportedSettings();
$supportedSettingKeys[] = ProviderService::SETTING_JWKS_CACHE;
$supportedSettingKeys[] = ProviderService::SETTING_JWKS_CACHE_TIMESTAMP;
foreach ($supportedSettingKeys as $key) {
foreach ($providers as $provider) {
$realKey = $this->providerService->getSettingsKey($provider->getId(), $key);
if ($this->appConfig->hasKey(Application::APP_ID, $realKey)) {
try {
$value = $this->appConfig->getValueString(Application::APP_ID, $realKey);
$this->appConfig->setValueString(Application::APP_ID, $realKey, $value, lazy: true);
} catch (\Exception) {
}
}
}
}
}
}
4 changes: 2 additions & 2 deletions lib/Service/ID4MeService.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ public function __construct(
}

public function setID4ME(bool $enabled): void {
$this->appConfig->setValueString(Application::APP_ID, 'id4me_enabled', $enabled ? '1' : '0');
$this->appConfig->setValueString(Application::APP_ID, 'id4me_enabled', $enabled ? '1' : '0', lazy: true);
}

public function getID4ME(): bool {
return $this->appConfig->getValueString(Application::APP_ID, 'id4me_enabled', '0') === '1';
return $this->appConfig->getValueString(Application::APP_ID, 'id4me_enabled', '0', lazy: true) === '1';
}
}
8 changes: 4 additions & 4 deletions lib/Service/ProviderService.php
Original file line number Diff line number Diff line change
Expand Up @@ -125,22 +125,22 @@ public function deleteSettings(int $providerId): void {
}

public function setSetting(int $providerId, string $key, string $value): void {
$this->appConfig->setValueString(Application::APP_ID, $this->getSettingsKey($providerId, $key), $value);
$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), '');
$value = $this->appConfig->getValueString(Application::APP_ID, $this->getSettingsKey($providerId, $key), '', lazy: true);
if ($value === '') {
return $default;
}
return $value;
}

private function getSettingsKey(int $providerId, string $key): string {
public function getSettingsKey(int $providerId, string $key): string {
return 'provider-' . strval($providerId) . '-' . $key;
}

private function getSupportedSettings(): array {
public function getSupportedSettings(): array {
return [
self::SETTING_MAPPING_DISPLAYNAME,
self::SETTING_MAPPING_EMAIL,
Expand Down
6 changes: 3 additions & 3 deletions lib/Service/SettingsService.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public function __construct(

public function getAllowMultipleUserBackEnds(): bool {
try {
return $this->appConfig->getValueString(Application::APP_ID, 'allow_multiple_user_backends', '1') === '1';
return $this->appConfig->getValueString(Application::APP_ID, 'allow_multiple_user_backends', '1', lazy: true) === '1';
} catch (AppConfigTypeConflictException $e) {
$this->logger->warning('Incorrect app config type when getting "allow_multiple_user_backends"', ['exception' => $e]);
return true;
Expand All @@ -34,11 +34,11 @@ public function getAllowMultipleUserBackEnds(): bool {

public function setAllowMultipleUserBackEnds(bool $value): void {
try {
$this->appConfig->setValueString(Application::APP_ID, 'allow_multiple_user_backends', $value ? '1' : '0');
$this->appConfig->setValueString(Application::APP_ID, 'allow_multiple_user_backends', $value ? '1' : '0', lazy: true);
} catch (AppConfigTypeConflictException $e) {
$this->logger->warning('Incorrect app config type when setting "allow_multiple_user_backends"', ['exception' => $e]);
$this->appConfig->deleteKey(Application::APP_ID, 'allow_multiple_user_backends');
$this->appConfig->setValueString(Application::APP_ID, 'allow_multiple_user_backends', $value ? '1' : '0');
$this->appConfig->setValueString(Application::APP_ID, 'allow_multiple_user_backends', $value ? '1' : '0', lazy: true);
}
}
}
4 changes: 2 additions & 2 deletions lib/Service/TokenService.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ public function getToken(bool $refreshIfExpired = true): ?Token {
* @throws PreConditionNotMetException
*/
public function checkLoginToken(): void {
$storeLoginTokenEnabled = $this->appConfig->getValueString(Application::APP_ID, 'store_login_token', '0') === '1';
$storeLoginTokenEnabled = $this->appConfig->getValueString(Application::APP_ID, 'store_login_token', '0', lazy: true) === '1';
if (!$storeLoginTokenEnabled) {
return;
}
Expand Down Expand Up @@ -255,7 +255,7 @@ public function decodeIdToken(Token $token): array {
* @throws \JsonException
*/
public function getExchangedToken(string $targetAudience, array $extraScopes = []): Token {
$storeLoginTokenEnabled = $this->appConfig->getValueString(Application::APP_ID, 'store_login_token', '0') === '1';
$storeLoginTokenEnabled = $this->appConfig->getValueString(Application::APP_ID, 'store_login_token', '0', lazy: true) === '1';
if (!$storeLoginTokenEnabled) {
throw new TokenExchangeFailedException(
'Failed to exchange token, storing the login token is disabled. It can be enabled in config.php',
Expand Down
2 changes: 1 addition & 1 deletion lib/Settings/AdminSettings.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public function getForm() {
);
$this->initialStateService->provideInitialState(
'storeLoginTokenState',
$this->appConfig->getValueString(Application::APP_ID, 'store_login_token', '0') === '1'
$this->appConfig->getValueString(Application::APP_ID, 'store_login_token', '0', lazy: true) === '1'
);
$this->initialStateService->provideInitialState(
'providers',
Expand Down
70 changes: 35 additions & 35 deletions tests/unit/Service/ProviderServiceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -189,41 +189,41 @@ public function testSetSettings() {
$this->appConfig->expects(self::any())
->method('getValueString')
->willReturnMap([
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_DISPLAYNAME, '', 'dn'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_EMAIL, '', 'mail'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_QUOTA, '', '1g'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_UID, '', 'uid'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_GROUPS, '', 'groups'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_LANGUAGE, '', 'language'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_LOCALE, '', 'locale'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_ADDRESS, '', 'address'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_STREETADDRESS, '', 'street_address'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_POSTALCODE, '', 'postal_code'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_LOCALITY, '', 'locality'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_REGION, '', 'region'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_COUNTRY, '', 'country'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_WEBSITE, '', 'website'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_AVATAR, '', 'avatar'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_TWITTER, '', 'twitter'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_FEDIVERSE, '', 'fediverse'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_ORGANISATION, '', 'organisation'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_ROLE, '', 'role'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_HEADLINE, '', 'headline'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_BIOGRAPHY, '', 'biography'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_PHONE, '', 'phone'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_GENDER, '', 'gender'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_PRONOUNS, '', 'pronouns'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_BIRTHDATE, '', 'birthdate'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_UNIQUE_UID, '', '1'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_CHECK_BEARER, '', '0'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_BEARER_PROVISIONING, '', '0'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_SEND_ID_TOKEN_HINT, '', '1'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_EXTRA_CLAIMS, '', 'claim1 claim2'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_PROVIDER_BASED_ID, '', '0'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_GROUP_PROVISIONING, '', '1'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_GROUP_WHITELIST_REGEX, '', ''],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_RESTRICT_LOGIN_TO_GROUPS, '', '0'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_RESOLVE_NESTED_AND_FALLBACK_CLAIMS_MAPPING, '', '0'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_DISPLAYNAME, '', true, 'dn'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_EMAIL, '', true, 'mail'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_QUOTA, '', true, '1g'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_UID, '', true, 'uid'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_GROUPS, '', true, 'groups'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_LANGUAGE, '', true, 'language'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_LOCALE, '', true, 'locale'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_ADDRESS, '', true, 'address'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_STREETADDRESS, '', true, 'street_address'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_POSTALCODE, '', true, 'postal_code'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_LOCALITY, '', true, 'locality'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_REGION, '', true, 'region'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_COUNTRY, '', true, 'country'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_WEBSITE, '', true, 'website'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_AVATAR, '', true, 'avatar'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_TWITTER, '', true, 'twitter'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_FEDIVERSE, '', true, 'fediverse'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_ORGANISATION, '', true, 'organisation'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_ROLE, '', true, 'role'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_HEADLINE, '', true, 'headline'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_BIOGRAPHY, '', true, 'biography'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_PHONE, '', true, 'phone'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_GENDER, '', true, 'gender'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_PRONOUNS, '', true, 'pronouns'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_MAPPING_BIRTHDATE, '', true, 'birthdate'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_UNIQUE_UID, '', true, '1'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_CHECK_BEARER, '', true, '0'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_BEARER_PROVISIONING, '', true, '0'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_SEND_ID_TOKEN_HINT, '', true, '1'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_EXTRA_CLAIMS, '', true, 'claim1 claim2'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_PROVIDER_BASED_ID, '', true, '0'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_GROUP_PROVISIONING, '', true, '1'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_GROUP_WHITELIST_REGEX, '', true, ''],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_RESTRICT_LOGIN_TO_GROUPS, '', true, '0'],
[Application::APP_ID, 'provider-1-' . ProviderService::SETTING_RESOLVE_NESTED_AND_FALLBACK_CLAIMS_MAPPING, '', true, '0'],
]);

Assert::assertEquals(
Expand Down
Loading