1515use OCP \IConfig ;
1616use OCP \IGroupManager ;
1717use OCP \IUser ;
18+ use OCP \Security \ICrypto ;
1819use OCP \Server ;
1920use OCP \Settings \DeclarativeSettingsTypes ;
2021use OCP \Settings \Events \DeclarativeSettingsGetValueEvent ;
@@ -49,6 +50,7 @@ public function __construct(
4950 private IConfig $ config ,
5051 private IAppConfig $ appConfig ,
5152 private LoggerInterface $ logger ,
53+ private ICrypto $ crypto ,
5254 ) {
5355 }
5456
@@ -266,7 +268,7 @@ public function setValue(IUser $user, string $app, string $formId, string $field
266268 $ this ->eventDispatcher ->dispatchTyped (new DeclarativeSettingsSetValueEvent ($ user , $ app , $ formId , $ fieldId , $ value ));
267269 break ;
268270 case DeclarativeSettingsTypes::STORAGE_TYPE_INTERNAL :
269- $ this ->saveInternalValue ($ user , $ app , $ fieldId , $ value );
271+ $ this ->saveInternalValue ($ user , $ app , $ formId , $ fieldId , $ value );
270272 break ;
271273 default :
272274 throw new Exception ('Unknown storage type " ' . $ storageType . '" ' );
@@ -290,18 +292,54 @@ private function getForm(string $app, string $formId): ?IDeclarativeSettingsForm
290292 private function getInternalValue (IUser $ user , string $ app , string $ formId , string $ fieldId ): mixed {
291293 $ sectionType = $ this ->getSectionType ($ app , $ fieldId );
292294 $ defaultValue = $ this ->getDefaultValue ($ app , $ formId , $ fieldId );
295+
296+ $ form = $ this ->getForm ($ app , $ fieldId );
297+ if ($ form === null ) {
298+ $ field = $ this ->getSchemaField ($ app , $ formId , $ fieldId );
299+ } else {
300+ $ field = $ this ->getSchemaField ($ app , $ formId , $ fieldId , $ form );
301+ }
302+ $ isSensitive = $ field !== null && isset ($ field ['sensitive ' ]) && $ field ['sensitive ' ];
303+
293304 switch ($ sectionType ) {
294305 case DeclarativeSettingsTypes::SECTION_TYPE_ADMIN :
295- return $ this ->config ->getAppValue ($ app , $ fieldId , $ defaultValue );
306+ $ value = $ this ->config ->getAppValue ($ app , $ fieldId , $ defaultValue );
307+ break ;
296308 case DeclarativeSettingsTypes::SECTION_TYPE_PERSONAL :
297- return $ this ->config ->getUserValue ($ user ->getUID (), $ app , $ fieldId , $ defaultValue );
309+ $ value = $ this ->config ->getUserValue ($ user ->getUID (), $ app , $ fieldId , $ defaultValue );
310+ break ;
298311 default :
299312 throw new Exception ('Unknown section type " ' . $ sectionType . '" ' );
300313 }
314+ if ($ isSensitive && !empty ($ value )) {
315+ try {
316+ $ value = $ this ->crypto ->decrypt ($ value );
317+ } catch (Exception $ e ) {
318+ $ this ->logger ->warning (sprintf ('Failed to decrypt sensitive value for field "%s" in app "%s": %s ' , $ fieldId , $ app , $ e ->getMessage ()));
319+ $ value = $ defaultValue ;
320+ }
321+ }
322+ return $ value ;
301323 }
302324
303- private function saveInternalValue (IUser $ user , string $ app , string $ fieldId , mixed $ value ): void {
325+ private function saveInternalValue (IUser $ user , string $ app , string $ formId , string $ fieldId , mixed $ value ): void {
304326 $ sectionType = $ this ->getSectionType ($ app , $ fieldId );
327+
328+ $ form = $ this ->getForm ($ app , $ formId );
329+ if ($ form === null ) {
330+ $ field = $ this ->getSchemaField ($ app , $ formId , $ fieldId );
331+ } else {
332+ $ field = $ this ->getSchemaField ($ app , $ formId , $ fieldId , $ form );
333+ }
334+ if ($ field !== null && isset ($ field ['sensitive ' ]) && $ field ['sensitive ' ] && !empty ($ value ) && $ value !== 'dummySecret ' ) {
335+ try {
336+ $ value = $ this ->crypto ->encrypt ($ value );
337+ } catch (Exception $ e ) {
338+ $ this ->logger ->warning (sprintf ('Failed to encrypt sensitive value for field "%s" in app "%s": %s ' , $ fieldId , $ app , $ e ->getMessage ()));
339+ throw new Exception ('Failed to encrypt sensitive value ' );
340+ }
341+ }
342+
305343 switch ($ sectionType ) {
306344 case DeclarativeSettingsTypes::SECTION_TYPE_ADMIN :
307345 $ this ->appConfig ->setValueString ($ app , $ fieldId , $ value );
@@ -314,6 +352,26 @@ private function saveInternalValue(IUser $user, string $app, string $fieldId, mi
314352 }
315353 }
316354
355+ private function getSchemaField (string $ app , string $ formId , string $ fieldId , ?IDeclarativeSettingsForm $ form = null ): ?array {
356+ if ($ form !== null ) {
357+ foreach ($ form ->getSchema ()['fields ' ] as $ field ) {
358+ if ($ field ['id ' ] === $ fieldId ) {
359+ return $ field ;
360+ }
361+ }
362+ }
363+ foreach ($ this ->appSchemas [$ app ] ?? [] as $ schema ) {
364+ if ($ schema ['id ' ] === $ formId ) {
365+ foreach ($ schema ['fields ' ] as $ field ) {
366+ if ($ field ['id ' ] === $ fieldId ) {
367+ return $ field ;
368+ }
369+ }
370+ }
371+ }
372+ return null ;
373+ }
374+
317375 private function getDefaultValue (string $ app , string $ formId , string $ fieldId ): mixed {
318376 foreach ($ this ->appSchemas [$ app ] as $ schema ) {
319377 if ($ schema ['id ' ] === $ formId ) {
@@ -391,6 +449,12 @@ private function validateSchema(string $appId, array $schema): bool {
391449 ]);
392450 return false ;
393451 }
452+ if (!in_array ($ field ['type ' ], [DeclarativeSettingsTypes::TEXT , DeclarativeSettingsTypes::PASSWORD ]) && isset ($ field ['sensitive ' ]) && $ field ['sensitive ' ]) {
453+ $ this ->logger ->warning ('Declarative settings: sensitive field type is supported only for TEXT and PASSWORD types ' , [
454+ 'app ' => $ appId , 'form_id ' => $ formId , 'field_id ' => $ fieldId ,
455+ ]);
456+ return false ;
457+ }
394458 if (!$ this ->validateField ($ appId , $ formId , $ field )) {
395459 return false ;
396460 }
0 commit comments