aboutsummaryrefslogtreecommitdiffstats
path: root/lib/private/Settings/DeclarativeManager.php
diff options
context:
space:
mode:
Diffstat (limited to 'lib/private/Settings/DeclarativeManager.php')
-rw-r--r--lib/private/Settings/DeclarativeManager.php71
1 files changed, 67 insertions, 4 deletions
diff --git a/lib/private/Settings/DeclarativeManager.php b/lib/private/Settings/DeclarativeManager.php
index dea0c678f20..534b4b19984 100644
--- a/lib/private/Settings/DeclarativeManager.php
+++ b/lib/private/Settings/DeclarativeManager.php
@@ -15,6 +15,7 @@ use OCP\IAppConfig;
use OCP\IConfig;
use OCP\IGroupManager;
use OCP\IUser;
+use OCP\Security\ICrypto;
use OCP\Server;
use OCP\Settings\DeclarativeSettingsTypes;
use OCP\Settings\Events\DeclarativeSettingsGetValueEvent;
@@ -49,6 +50,7 @@ class DeclarativeManager implements IDeclarativeManager {
private IConfig $config,
private IAppConfig $appConfig,
private LoggerInterface $logger,
+ private ICrypto $crypto,
) {
}
@@ -266,7 +268,7 @@ class DeclarativeManager implements IDeclarativeManager {
$this->eventDispatcher->dispatchTyped(new DeclarativeSettingsSetValueEvent($user, $app, $formId, $fieldId, $value));
break;
case DeclarativeSettingsTypes::STORAGE_TYPE_INTERNAL:
- $this->saveInternalValue($user, $app, $fieldId, $value);
+ $this->saveInternalValue($user, $app, $formId, $fieldId, $value);
break;
default:
throw new Exception('Unknown storage type "' . $storageType . '"');
@@ -290,18 +292,52 @@ class DeclarativeManager implements IDeclarativeManager {
private function getInternalValue(IUser $user, string $app, string $formId, string $fieldId): mixed {
$sectionType = $this->getSectionType($app, $fieldId);
$defaultValue = $this->getDefaultValue($app, $formId, $fieldId);
+
+ $field = $this->getSchemaField($app, $formId, $fieldId);
+ $isSensitive = $field !== null && isset($field['sensitive']) && $field['sensitive'] === true;
+
switch ($sectionType) {
case DeclarativeSettingsTypes::SECTION_TYPE_ADMIN:
- return $this->config->getAppValue($app, $fieldId, $defaultValue);
+ $value = $this->config->getAppValue($app, $fieldId, $defaultValue);
+ break;
case DeclarativeSettingsTypes::SECTION_TYPE_PERSONAL:
- return $this->config->getUserValue($user->getUID(), $app, $fieldId, $defaultValue);
+ $value = $this->config->getUserValue($user->getUID(), $app, $fieldId, $defaultValue);
+ break;
default:
throw new Exception('Unknown section type "' . $sectionType . '"');
}
+ if ($isSensitive && $value !== '') {
+ try {
+ $value = $this->crypto->decrypt($value);
+ } catch (Exception $e) {
+ $this->logger->warning('Failed to decrypt sensitive value for field {field} in app {app}: {message}', [
+ 'field' => $fieldId,
+ 'app' => $app,
+ 'message' => $e->getMessage(),
+ ]);
+ $value = $defaultValue;
+ }
+ }
+ return $value;
}
- private function saveInternalValue(IUser $user, string $app, string $fieldId, mixed $value): void {
+ private function saveInternalValue(IUser $user, string $app, string $formId, string $fieldId, mixed $value): void {
$sectionType = $this->getSectionType($app, $fieldId);
+
+ $field = $this->getSchemaField($app, $formId, $fieldId);
+ if ($field !== null && isset($field['sensitive']) && $field['sensitive'] === true && $value !== '' && $value !== 'dummySecret') {
+ try {
+ $value = $this->crypto->encrypt($value);
+ } catch (Exception $e) {
+ $this->logger->warning('Failed to decrypt sensitive value for field {field} in app {app}: {message}', [
+ 'field' => $fieldId,
+ 'app' => $app,
+ 'message' => $e->getMessage()]
+ );
+ throw new Exception('Failed to encrypt sensitive value');
+ }
+ }
+
switch ($sectionType) {
case DeclarativeSettingsTypes::SECTION_TYPE_ADMIN:
$this->appConfig->setValueString($app, $fieldId, $value);
@@ -314,6 +350,27 @@ class DeclarativeManager implements IDeclarativeManager {
}
}
+ private function getSchemaField(string $app, string $formId, string $fieldId): ?array {
+ $form = $this->getForm($app, $formId);
+ if ($form !== null) {
+ foreach ($form->getSchema()['fields'] as $field) {
+ if ($field['id'] === $fieldId) {
+ return $field;
+ }
+ }
+ }
+ foreach ($this->appSchemas[$app] ?? [] as $schema) {
+ if ($schema['id'] === $formId) {
+ foreach ($schema['fields'] as $field) {
+ if ($field['id'] === $fieldId) {
+ return $field;
+ }
+ }
+ }
+ }
+ return null;
+ }
+
private function getDefaultValue(string $app, string $formId, string $fieldId): mixed {
foreach ($this->appSchemas[$app] as $schema) {
if ($schema['id'] === $formId) {
@@ -391,6 +448,12 @@ class DeclarativeManager implements IDeclarativeManager {
]);
return false;
}
+ if (isset($field['sensitive']) && $field['sensitive'] === true && !in_array($field['type'], [DeclarativeSettingsTypes::TEXT, DeclarativeSettingsTypes::PASSWORD])) {
+ $this->logger->warning('Declarative settings: sensitive field type is supported only for TEXT and PASSWORD types ({app}, {form_id}, {field_id})', [
+ 'app' => $appId, 'form_id' => $formId, 'field_id' => $fieldId,
+ ]);
+ return false;
+ }
if (!$this->validateField($appId, $formId, $field)) {
return false;
}