From 4694d34ab993965df81433c95a7d1234361d2d41 Mon Sep 17 00:00:00 2001 From: Felix Schwarz Date: Mon, 25 Aug 2025 18:36:10 +0200 Subject: [PATCH 1/3] - ConfidentialManager: - add new class method to return the array of actions automatically disallowed when confidential protection is turned on - add new exempted actions setting (OCClassSettingsKeyConfidentialExemptedActions) - adapt disallowedActions to remove exempt actions, thereby allowing them - .h: fix ObjC property definitions - replace calls to ConfidentialManager with self where favorable - classSettingsMetadata: replace strings with symbols - .. and other code and style improvements - doc/CONFIGURATION.json: run automatic MDM documentation re-creation after addition of new options --- doc/CONFIGURATION.json | 249 +++++++++++++++++- .../Confidential/ConfidentialManager.h | 32 ++- .../Confidential/ConfidentialManager.m | 181 +++++++------ 3 files changed, 365 insertions(+), 97 deletions(-) diff --git a/doc/CONFIGURATION.json b/doc/CONFIGURATION.json index 1ee0c8b8a..8c3ee3851 100644 --- a/doc/CONFIGURATION.json +++ b/doc/CONFIGURATION.json @@ -49,10 +49,26 @@ "description" : "Delete", "value" : "com.owncloud.action.delete" }, + { + "description" : "Details", + "value" : "com.owncloud.action.detailspace" + }, + { + "description" : "Disable space", + "value" : "com.owncloud.action.disablespace" + }, { "description" : "Duplicate", "value" : "com.owncloud.action.duplicate" }, + { + "description" : "Edit description", + "value" : "com.owncloud.action.editspacedescription" + }, + { + "description" : "Edit image", + "value" : "com.owncloud.action.editspaceimage" + }, { "description" : "Favorite item", "value" : "com.owncloud.action.favorite" @@ -61,6 +77,10 @@ "description" : "Paste", "value" : "com.owncloud.action.importpasteboard" }, + { + "description" : "Edit space", + "value" : "com.owncloud.action.managespace" + }, { "description" : "Markup", "value" : "com.owncloud.action.markup" @@ -101,6 +121,10 @@ "description" : "Image metadata", "value" : "com.owncloud.action.show-exif" }, + { + "description" : "Members", + "value" : "com.owncloud.action.spacemembers" + }, { "description" : "Unfavorite item", "value" : "com.owncloud.action.unfavorite" @@ -199,10 +223,26 @@ "description" : "Delete", "value" : "com.owncloud.action.delete" }, + { + "description" : "Details", + "value" : "com.owncloud.action.detailspace" + }, + { + "description" : "Disable space", + "value" : "com.owncloud.action.disablespace" + }, { "description" : "Duplicate", "value" : "com.owncloud.action.duplicate" }, + { + "description" : "Edit description", + "value" : "com.owncloud.action.editspacedescription" + }, + { + "description" : "Edit image", + "value" : "com.owncloud.action.editspaceimage" + }, { "description" : "Favorite item", "value" : "com.owncloud.action.favorite" @@ -211,6 +251,10 @@ "description" : "Paste", "value" : "com.owncloud.action.importpasteboard" }, + { + "description" : "Edit space", + "value" : "com.owncloud.action.managespace" + }, { "description" : "Markup", "value" : "com.owncloud.action.markup" @@ -251,6 +295,10 @@ "description" : "Image metadata", "value" : "com.owncloud.action.show-exif" }, + { + "description" : "Members", + "value" : "com.owncloud.action.spacemembers" + }, { "description" : "Unfavorite item", "value" : "com.owncloud.action.unfavorite" @@ -398,6 +446,20 @@ "status" : "advanced", "type" : "string" }, + { + "autoExpansion" : "none", + "category" : "App", + "categoryTag" : "app", + "classIdentifier" : "app", + "className" : "ownCloudAppShared.VendorServices", + "defaultValue" : true, + "description" : "Enable/disable AI features.", + "flatIdentifier" : "app.allow-ai-features", + "key" : "allow-ai-features", + "label" : "app.allow-ai-features", + "status" : "advanced", + "type" : "bool" + }, { "autoExpansion" : "none", "category" : "App", @@ -1260,7 +1322,6 @@ "categoryTag" : "confidential", "classIdentifier" : "confidential", "className" : "ConfidentialManager", - "defaultValue" : false, "description" : "Controls if confidential related MDM settings can be overwritten.", "flatIdentifier" : "confidential.allow-overwrite-confidential-mdm-settings", "key" : "allow-overwrite-confidential-mdm-settings", @@ -1274,7 +1335,6 @@ "categoryTag" : "confidential", "classIdentifier" : "confidential", "className" : "ConfidentialManager", - "defaultValue" : true, "description" : "Controls whether screenshots are allowed or not. If not allowed confidential views will be marked as sensitive and are not visible in screenshots.", "flatIdentifier" : "confidential.allow-screenshots", "key" : "allow-screenshots", @@ -1288,14 +1348,144 @@ "categoryTag" : "confidential", "classIdentifier" : "confidential", "className" : "ConfidentialManager", - "defaultValue" : false, - "description" : "Controls if views which contains sensitive content contains a watermark or not.", - "flatIdentifier" : "confidential.mark-confidential-views", - "key" : "mark-confidential-views", - "label" : "confidential.mark-confidential-views", + "description" : "List of actions exempt from auto-disallow of particular actions when enabling confidential protections.", + "flatIdentifier" : "confidential.exempted-actions", + "key" : "exempted-actions", + "label" : "confidential.exempted-actions", + "possibleValues" : [ + { + "description" : "Exempt com.owncloud.action.copy from list of auto-disallowed actions.", + "value" : "com.owncloud.action.copy" + }, + { + "description" : "Exempt com.owncloud.action.markup from list of auto-disallowed actions.", + "value" : "com.owncloud.action.markup" + }, + { + "description" : "Exempt com.owncloud.action.openin from list of auto-disallowed actions.", + "value" : "com.owncloud.action.openin" + } + ], + "status" : "advanced", + "type" : "stringArray" + }, + { + "autoExpansion" : "none", + "category" : "Confidential", + "categoryTag" : "confidential", + "classIdentifier" : "confidential", + "className" : "ConfidentialManager", + "description" : "Controls the color as hex value of the watermark text.", + "flatIdentifier" : "confidential.text-color", + "key" : "text-color", + "label" : "confidential.text-color", + "status" : "advanced", + "type" : "string" + }, + { + "autoExpansion" : "none", + "category" : "Confidential", + "categoryTag" : "confidential", + "classIdentifier" : "confidential", + "className" : "ConfidentialManager", + "description" : "Controls the column spacing of the watermark text in pixel.", + "flatIdentifier" : "confidential.text-column-spacing", + "key" : "text-column-spacing", + "label" : "confidential.text-column-spacing", + "status" : "advanced", + "type" : "int" + }, + { + "autoExpansion" : "none", + "category" : "Confidential", + "categoryTag" : "confidential", + "classIdentifier" : "confidential", + "className" : "ConfidentialManager", + "description" : "Controls if the given custom text should be shown as watermark text.", + "flatIdentifier" : "confidential.text-custom-text", + "key" : "text-custom-text", + "label" : "confidential.text-custom-text", + "status" : "advanced", + "type" : "string" + }, + { + "autoExpansion" : "none", + "category" : "Confidential", + "categoryTag" : "confidential", + "classIdentifier" : "confidential", + "className" : "ConfidentialManager", + "description" : "Controls the line spacing of the watermark text in pixel.", + "flatIdentifier" : "confidential.text-line-spacing", + "key" : "text-line-spacing", + "label" : "confidential.text-line-spacing", + "status" : "advanced", + "type" : "int" + }, + { + "autoExpansion" : "none", + "category" : "Confidential", + "categoryTag" : "confidential", + "classIdentifier" : "confidential", + "className" : "ConfidentialManager", + "description" : "Controls the opacity of the watermark text. Possible values: 0 - 100", + "flatIdentifier" : "confidential.text-opacity", + "key" : "text-opacity", + "label" : "confidential.text-opacity", + "status" : "advanced", + "type" : "int" + }, + { + "autoExpansion" : "none", + "category" : "Confidential", + "categoryTag" : "confidential", + "classIdentifier" : "confidential", + "className" : "ConfidentialManager", + "description" : "Controls if the current timestamp should be shown as watermark text.", + "flatIdentifier" : "confidential.text-show-timestamp", + "key" : "text-show-timestamp", + "label" : "confidential.text-show-timestamp", + "status" : "advanced", + "type" : "bool" + }, + { + "autoExpansion" : "none", + "category" : "Confidential", + "categoryTag" : "confidential", + "classIdentifier" : "confidential", + "className" : "ConfidentialManager", + "description" : "Controls if the user email should be shown as watermark text.", + "flatIdentifier" : "confidential.text-show-user-email", + "key" : "text-show-user-email", + "label" : "confidential.text-show-user-email", + "status" : "advanced", + "type" : "bool" + }, + { + "autoExpansion" : "none", + "category" : "Confidential", + "categoryTag" : "confidential", + "classIdentifier" : "confidential", + "className" : "ConfidentialManager", + "description" : "Controls if the user ID should be shown as watermark text.", + "flatIdentifier" : "confidential.text-show-user-id", + "key" : "text-show-user-id", + "label" : "confidential.text-show-user-id", "status" : "advanced", "type" : "bool" }, + { + "autoExpansion" : "none", + "category" : "Confidential", + "categoryTag" : "confidential", + "classIdentifier" : "confidential", + "className" : "ConfidentialManager", + "description" : "Controls the number or visible characters in redacted text. Choose value -1 to do not redact text.", + "flatIdentifier" : "confidential.visible-redacted-characters", + "key" : "visible-redacted-characters", + "label" : "confidential.visible-redacted-characters", + "status" : "advanced", + "type" : "int" + }, { "autoExpansion" : "none", "category" : "Connection", @@ -1428,6 +1618,21 @@ "status" : "advanced", "type" : "string" }, + { + "autoExpansion" : "none", + "category" : "Endpoints", + "categoryTag" : "endpoints", + "classIdentifier" : "connection", + "className" : "OCConnection", + "defaultValue" : "kwdav/status.php", + "description" : "Endpoint to retrieve basic status information and detect a Kiteworks installation.", + "flags" : 4, + "flatIdentifier" : "connection.endpoint-kiteworks-status", + "key" : "endpoint-kiteworks-status", + "label" : "connection.endpoint-kiteworks-status", + "status" : "advanced", + "type" : "string" + }, { "autoExpansion" : "none", "category" : "Endpoints", @@ -1920,10 +2125,26 @@ "description" : "Extension with the identifier com.owncloud.action.delete.", "value" : "com.owncloud.action.delete" }, + { + "description" : "Extension with the identifier com.owncloud.action.detailspace.", + "value" : "com.owncloud.action.detailspace" + }, + { + "description" : "Extension with the identifier com.owncloud.action.disablespace.", + "value" : "com.owncloud.action.disablespace" + }, { "description" : "Extension with the identifier com.owncloud.action.duplicate.", "value" : "com.owncloud.action.duplicate" }, + { + "description" : "Extension with the identifier com.owncloud.action.editspacedescription.", + "value" : "com.owncloud.action.editspacedescription" + }, + { + "description" : "Extension with the identifier com.owncloud.action.editspaceimage.", + "value" : "com.owncloud.action.editspaceimage" + }, { "description" : "Extension with the identifier com.owncloud.action.favorite.", "value" : "com.owncloud.action.favorite" @@ -1936,6 +2157,10 @@ "description" : "Extension with the identifier com.owncloud.action.instant_media_upload.", "value" : "com.owncloud.action.instant_media_upload" }, + { + "description" : "Extension with the identifier com.owncloud.action.managespace.", + "value" : "com.owncloud.action.managespace" + }, { "description" : "Extension with the identifier com.owncloud.action.markup.", "value" : "com.owncloud.action.markup" @@ -1980,6 +2205,10 @@ "description" : "Extension with the identifier com.owncloud.action.show-exif.", "value" : "com.owncloud.action.show-exif" }, + { + "description" : "Extension with the identifier com.owncloud.action.spacemembers.", + "value" : "com.owncloud.action.spacemembers" + }, { "description" : "Extension with the identifier com.owncloud.action.unfavorite.", "value" : "com.owncloud.action.unfavorite" @@ -2024,6 +2253,10 @@ "description" : "Extension with the identifier license.PocketSVG.", "value" : "license.PocketSVG" }, + { + "description" : "Extension with the identifier license.SHA3-256.", + "value" : "license.SHA3-256" + }, { "description" : "Extension with the identifier license.openssl.", "value" : "license.openssl" @@ -2798,4 +3031,4 @@ "status" : "advanced", "type" : "stringArray" } -] \ No newline at end of file +] diff --git a/ownCloudAppFramework/Confidential/ConfidentialManager.h b/ownCloudAppFramework/Confidential/ConfidentialManager.h index 7e3a3f243..4bcc813a0 100644 --- a/ownCloudAppFramework/Confidential/ConfidentialManager.h +++ b/ownCloudAppFramework/Confidential/ConfidentialManager.h @@ -25,20 +25,23 @@ NS_ASSUME_NONNULL_BEGIN @property(class,strong,nonatomic,readonly) ConfidentialManager *sharedConfidentialManager; -@property (assign, readonly) BOOL allowScreenshots; -@property (assign, readonly) BOOL markConfidentialViews; -@property (assign, readonly) BOOL allowOverwriteConfidentialMDMSettings; -@property (assign, readonly) BOOL confidentialSettingsEnabled; - -@property (assign, readonly) CGFloat textOpacity; -@property (assign, readonly, nullable) NSString *textColor; -@property (assign, readonly) CGFloat columnSpacing; -@property (assign, readonly) CGFloat lineSpacing; -@property (assign, readonly) BOOL showUserEmail; -@property (assign, readonly) BOOL showUserID; -@property (assign, readonly) BOOL showTimestamp; -@property (assign, readonly, nullable) NSString *customText; -@property (assign, readonly) NSInteger visibleRedactedCharacters; +@property(class,strong,nonatomic,readonly) NSArray *autoDisallowedActions; //!< List of identifiers of action extensions that would be automatically disallowed when enabling confidential protections and not making use of any exemptions. + +@property (nonatomic, readonly) BOOL allowScreenshots; +@property (nonatomic, readonly) BOOL markConfidentialViews; +@property (nonatomic, readonly) BOOL allowOverwriteConfidentialMDMSettings; +@property (nonatomic, readonly) BOOL confidentialSettingsEnabled; + +@property (nonatomic, readonly) CGFloat textOpacity; +@property (nonatomic, readonly, nullable) NSString *textColor; +@property (nonatomic, readonly) CGFloat columnSpacing; +@property (nonatomic, readonly) CGFloat lineSpacing; +@property (nonatomic, readonly) BOOL showUserEmail; +@property (nonatomic, readonly) BOOL showUserID; +@property (nonatomic, readonly) BOOL showTimestamp; +@property (nonatomic, readonly, nullable) NSString *customText; +@property (nonatomic, readonly) NSInteger visibleRedactedCharacters; +@property (nonatomic, readonly, nullable) NSArray *exemptActions; //!< Identifiers of action extensions exempt from automatically being disallowed when enabling confidential protections. @property (nonatomic, readonly, nullable) NSArray *disallowedActions; @end @@ -49,6 +52,7 @@ extern OCClassSettingsIdentifier OCClassSettingsIdentifierConfidential; extern OCClassSettingsKey OCClassSettingsKeyAllowScreenshots; extern OCClassSettingsKey OCClassSettingsKeyAllowOverwriteConfidentialMDMSettings; +extern OCClassSettingsKey OCClassSettingsKeyConfidentialExemptedActions; extern OCClassSettingsKey OCClassSettingsKeyConfidentialTextOpacity; extern OCClassSettingsKey OCClassSettingsKeyConfidentialTextColor; extern OCClassSettingsKey OCClassSettingsKeyConfidentialTextColumnSpacing; diff --git a/ownCloudAppFramework/Confidential/ConfidentialManager.m b/ownCloudAppFramework/Confidential/ConfidentialManager.m index 4d49e1213..f5aff01df 100644 --- a/ownCloudAppFramework/Confidential/ConfidentialManager.m +++ b/ownCloudAppFramework/Confidential/ConfidentialManager.m @@ -55,152 +55,182 @@ - (BOOL)markConfidentialViews { } - (BOOL)allowOverwriteConfidentialMDMSettings { - NSNumber *value = [ConfidentialManager classSettingForOCClassSettingsKey:OCClassSettingsKeyAllowOverwriteConfidentialMDMSettings]; + NSNumber *value = [self classSettingForOCClassSettingsKey:OCClassSettingsKeyAllowOverwriteConfidentialMDMSettings]; return self.confidentialSettingsEnabled && ((value != nil) ? value.boolValue : NO); } +- (BOOL)confidentialSettingsEnabled { + return (!self.allowScreenshots || self.markConfidentialViews); +} + - (CGFloat)textOpacity { - NSNumber *value = [ConfidentialManager classSettingForOCClassSettingsKey:OCClassSettingsKeyConfidentialTextOpacity]; + NSNumber *value = [self classSettingForOCClassSettingsKey:OCClassSettingsKeyConfidentialTextOpacity]; return (value != nil) ? (value.intValue / 100.0) : 0.6; } - (NSString *)textColor { - NSString *value = [ConfidentialManager classSettingForOCClassSettingsKey:OCClassSettingsKeyConfidentialTextColor]; - return value; + return ([self classSettingForOCClassSettingsKey:OCClassSettingsKeyConfidentialTextColor]); } - (CGFloat)columnSpacing { - NSNumber *value = [ConfidentialManager classSettingForOCClassSettingsKey:OCClassSettingsKeyConfidentialTextColumnSpacing]; + NSNumber *value = [self classSettingForOCClassSettingsKey:OCClassSettingsKeyConfidentialTextColumnSpacing]; return (value != nil) ? value.floatValue : 40.0; } - (CGFloat)lineSpacing { - NSNumber *value = [ConfidentialManager classSettingForOCClassSettingsKey:OCClassSettingsKeyConfidentialTextLineSpacing]; + NSNumber *value = [self classSettingForOCClassSettingsKey:OCClassSettingsKeyConfidentialTextLineSpacing]; return (value != nil) ? value.floatValue : 40.0; } - (BOOL)showUserEmail { - NSNumber *value = [ConfidentialManager classSettingForOCClassSettingsKey:OCClassSettingsKeyConfidentialTextShowUserEmail]; + NSNumber *value = [self classSettingForOCClassSettingsKey:OCClassSettingsKeyConfidentialTextShowUserEmail]; return (value != nil) ? value.boolValue : NO; } - (BOOL)showUserID { - NSNumber *value = [ConfidentialManager classSettingForOCClassSettingsKey:OCClassSettingsKeyConfidentialTextShowUserID]; + NSNumber *value = [self classSettingForOCClassSettingsKey:OCClassSettingsKeyConfidentialTextShowUserID]; return (value != nil) ? value.boolValue : NO; } - (BOOL)showTimestamp { - NSNumber *value = [ConfidentialManager classSettingForOCClassSettingsKey:OCClassSettingsKeyConfidentialTextShowTimestamp]; + NSNumber *value = [self classSettingForOCClassSettingsKey:OCClassSettingsKeyConfidentialTextShowTimestamp]; return (value != nil) ? value.boolValue : NO; } - (NSString *)customText { - NSString *value = [ConfidentialManager classSettingForOCClassSettingsKey:OCClassSettingsKeyConfidentialTextCustomText]; - return value; + return ([self classSettingForOCClassSettingsKey:OCClassSettingsKeyConfidentialTextCustomText]); } - (NSInteger)visibleRedactedCharacters { - NSNumber *value = [ConfidentialManager classSettingForOCClassSettingsKey:OCClassSettingsKeyConfidentialVisibleRedactedCharacters]; + NSNumber *value = [self classSettingForOCClassSettingsKey:OCClassSettingsKeyConfidentialVisibleRedactedCharacters]; return (value != nil) ? value.integerValue : -1; } -- (BOOL)confidentialSettingsEnabled { - return !self.allowScreenshots || self.markConfidentialViews; +- (NSArray *)exemptActions { + return ([self classSettingForOCClassSettingsKey:OCClassSettingsKeyConfidentialExemptedActions]); } -- (NSArray *)disallowedActions { ++ (NSArray *)autoDisallowedActions { + return (@[ + @"com.owncloud.action.openin", + @"com.owncloud.action.copy", + /* + As of iOS 18.2.1: + The markup action could not be modified to implement protection mechanisms - + not even on the CALayer level - without interaction with the system-provided + view breaking and becoming unusable in different ways. A possible reason for + this is that the markup feature is delivered by the OS as Remote UI (visible + as QLRemoteUIHostViewController in the view hierarchy) and that otherwise working + approaches to "passing through" events are not usable with these. + */ + @"com.owncloud.action.markup" + ]); +} + +- (NSArray *)disallowedActions { if (self.confidentialSettingsEnabled && !self.allowOverwriteConfidentialMDMSettings) { - return @[ - @"com.owncloud.action.openin", - @"com.owncloud.action.copy", - /* - As of iOS 18.2.1: - The markup action could not be modified to implement protection mechanisms - - not even on the CALayer level - without interaction with the system-provided - view breaking and becoming unusable in different ways. A possible reason for - this is that the markup feature is delivered by the OS as Remote UI (visible - as QLRemoteUIHostViewController in the view hierarchy) and that otherwise working - approaches to "passing through" events are not usable with these. - */ - @"com.owncloud.action.markup" - ]; + NSMutableArray *disallowedActions = [ConfidentialManager.autoDisallowedActions mutableCopy]; + NSArray *exemptActions; + + if (((exemptActions = self.exemptActions) != nil) && (exemptActions.count > 0)) { + [disallowedActions removeObjectsInArray:exemptActions]; + } + + return (disallowedActions); } - return nil; + return (nil); } + (NSDictionary *)defaultSettingsForIdentifier:(OCClassSettingsIdentifier)identifier { - return nil; + return (nil); } + (OCClassSettingsMetadataCollection)classSettingsMetadata { + NSArray *possibleExemptActionIDs = ConfidentialManager.autoDisallowedActions; + NSMutableArray *> *possibleExemptionValues = [NSMutableArray new]; + + for (OCExtensionIdentifier actionID in possibleExemptActionIDs) { + [possibleExemptionValues addObject:@{ + OCClassSettingsMetadataKeyValue : actionID, + OCClassSettingsMetadataKeyDescription : [NSString stringWithFormat:@"Exempt %@ from list of auto-disallowed actions.", actionID] + }]; + } + return (@{ OCClassSettingsKeyAllowScreenshots : @{ - @"type" : OCClassSettingsMetadataTypeBoolean, - @"description" : @"Controls whether screenshots are allowed or not. If not allowed confidential views will be marked as sensitive and are not visible in screenshots.", - @"status" : OCClassSettingsKeyStatusAdvanced, - @"category" : @"Confidential" + OCClassSettingsMetadataKeyType : OCClassSettingsMetadataTypeBoolean, + OCClassSettingsMetadataKeyDescription : @"Controls whether screenshots are allowed or not. If not allowed confidential views will be marked as sensitive and are not visible in screenshots.", + OCClassSettingsMetadataKeyStatus : OCClassSettingsKeyStatusAdvanced, + OCClassSettingsMetadataKeyCategory : @"Confidential" }, OCClassSettingsKeyAllowOverwriteConfidentialMDMSettings : @{ - @"type" : OCClassSettingsMetadataTypeBoolean, - @"description" : @"Controls if confidential related MDM settings can be overwritten.", - @"status" : OCClassSettingsKeyStatusAdvanced, - @"category" : @"Confidential" + OCClassSettingsMetadataKeyType : OCClassSettingsMetadataTypeBoolean, + OCClassSettingsMetadataKeyDescription : @"Controls if confidential related MDM settings can be overwritten.", + OCClassSettingsMetadataKeyStatus : OCClassSettingsKeyStatusAdvanced, + OCClassSettingsMetadataKeyCategory : @"Confidential" + }, + OCClassSettingsKeyConfidentialExemptedActions : @{ + OCClassSettingsMetadataKeyType : OCClassSettingsMetadataTypeStringArray, + OCClassSettingsMetadataKeyDescription : @"List of actions exempt from auto-disallow of particular actions when enabling confidential protections.", + OCClassSettingsMetadataKeyStatus : OCClassSettingsKeyStatusAdvanced, + OCClassSettingsMetadataKeyCategory : @"Confidential", + OCClassSettingsMetadataKeyPossibleValues: possibleExemptionValues }, OCClassSettingsKeyConfidentialTextOpacity : @{ - @"type" : OCClassSettingsMetadataTypeInteger, - @"description" : @"Controls the opacity of the watermark text. Possible values: 0 - 100", - @"status" : OCClassSettingsKeyStatusAdvanced, - @"category" : @"Confidential" + OCClassSettingsMetadataKeyType : OCClassSettingsMetadataTypeInteger, + OCClassSettingsMetadataKeyDescription : @"Controls the opacity of the watermark text. Possible values: 0 - 100", + OCClassSettingsMetadataKeyStatus : OCClassSettingsKeyStatusAdvanced, + OCClassSettingsMetadataKeyCategory : @"Confidential" }, OCClassSettingsKeyConfidentialTextColumnSpacing : @{ - @"type" : OCClassSettingsMetadataTypeInteger, - @"description" : @"Controls the column spacing of the watermark text in pixel.", - @"status" : OCClassSettingsKeyStatusAdvanced, - @"category" : @"Confidential" + OCClassSettingsMetadataKeyType : OCClassSettingsMetadataTypeInteger, + OCClassSettingsMetadataKeyDescription : @"Controls the column spacing of the watermark text in pixel.", + OCClassSettingsMetadataKeyStatus : OCClassSettingsKeyStatusAdvanced, + OCClassSettingsMetadataKeyCategory : @"Confidential" }, OCClassSettingsKeyConfidentialTextLineSpacing : @{ - @"type" : OCClassSettingsMetadataTypeInteger, - @"description" : @"Controls the line spacing of the watermark text in pixel.", - @"status" : OCClassSettingsKeyStatusAdvanced, - @"category" : @"Confidential" + OCClassSettingsMetadataKeyType : OCClassSettingsMetadataTypeInteger, + OCClassSettingsMetadataKeyDescription : @"Controls the line spacing of the watermark text in pixel.", + OCClassSettingsMetadataKeyStatus : OCClassSettingsKeyStatusAdvanced, + OCClassSettingsMetadataKeyCategory : @"Confidential" }, OCClassSettingsKeyConfidentialTextColor : @{ - @"type" : OCClassSettingsMetadataTypeString, - @"description" : @"Controls the color as hex value of the watermark text.", - @"status" : OCClassSettingsKeyStatusAdvanced, - @"category" : @"Confidential" + OCClassSettingsMetadataKeyType : OCClassSettingsMetadataTypeString, + OCClassSettingsMetadataKeyDescription : @"Controls the color as hex value of the watermark text.", + OCClassSettingsMetadataKeyStatus : OCClassSettingsKeyStatusAdvanced, + OCClassSettingsMetadataKeyCategory : @"Confidential" }, OCClassSettingsKeyConfidentialVisibleRedactedCharacters : @{ - @"type" : OCClassSettingsMetadataTypeInteger, - @"description" : @"Controls the number or visible characters in redacted text. Choose value -1 to do not redact text.", - @"status" : OCClassSettingsKeyStatusAdvanced, - @"category" : @"Confidential" + OCClassSettingsMetadataKeyType : OCClassSettingsMetadataTypeInteger, + OCClassSettingsMetadataKeyDescription : @"Controls the number or visible characters in redacted text. Choose value -1 to do not redact text.", + OCClassSettingsMetadataKeyStatus : OCClassSettingsKeyStatusAdvanced, + OCClassSettingsMetadataKeyCategory : @"Confidential" }, OCClassSettingsKeyConfidentialTextShowUserEmail : @{ - @"type" : OCClassSettingsMetadataTypeBoolean, - @"description" : @"Controls if the user email should be shown as watermark text.", - @"status" : OCClassSettingsKeyStatusAdvanced, - @"category" : @"Confidential" + OCClassSettingsMetadataKeyType : OCClassSettingsMetadataTypeBoolean, + OCClassSettingsMetadataKeyDescription : @"Controls if the user email should be shown as watermark text.", + OCClassSettingsMetadataKeyStatus : OCClassSettingsKeyStatusAdvanced, + OCClassSettingsMetadataKeyCategory : @"Confidential" }, OCClassSettingsKeyConfidentialTextShowUserID : @{ - @"type" : OCClassSettingsMetadataTypeBoolean, - @"description" : @"Controls if the user ID should be shown as watermark text.", - @"status" : OCClassSettingsKeyStatusAdvanced, - @"category" : @"Confidential" + OCClassSettingsMetadataKeyType : OCClassSettingsMetadataTypeBoolean, + OCClassSettingsMetadataKeyDescription : @"Controls if the user ID should be shown as watermark text.", + OCClassSettingsMetadataKeyStatus : OCClassSettingsKeyStatusAdvanced, + OCClassSettingsMetadataKeyCategory : @"Confidential" }, OCClassSettingsKeyConfidentialTextShowTimestamp : @{ - @"type" : OCClassSettingsMetadataTypeBoolean, - @"description" : @"Controls if the current timestamp should be shown as watermark text.", - @"status" : OCClassSettingsKeyStatusAdvanced, - @"category" : @"Confidential" + OCClassSettingsMetadataKeyType : OCClassSettingsMetadataTypeBoolean, + OCClassSettingsMetadataKeyDescription : @"Controls if the current timestamp should be shown as watermark text.", + OCClassSettingsMetadataKeyStatus : OCClassSettingsKeyStatusAdvanced, + OCClassSettingsMetadataKeyCategory : @"Confidential" }, OCClassSettingsKeyConfidentialTextCustomText : @{ - @"type" : OCClassSettingsMetadataTypeString, - @"description" : @"Controls if the given custom text should be shown as watermark text.", - @"status" : OCClassSettingsKeyStatusAdvanced, - @"category" : @"Confidential" + OCClassSettingsMetadataKeyType : OCClassSettingsMetadataTypeString, + OCClassSettingsMetadataKeyDescription : @"Controls if the given custom text should be shown as watermark text.", + OCClassSettingsMetadataKeyStatus : OCClassSettingsKeyStatusAdvanced, + OCClassSettingsMetadataKeyCategory : @"Confidential" } }); } @@ -250,6 +280,7 @@ - (OCClassSettingsSourceIdentifier)settingsSourceIdentifier OCClassSettingsKey OCClassSettingsKeyAllowScreenshots = @"allow-screenshots"; OCClassSettingsKey OCClassSettingsKeyAllowOverwriteConfidentialMDMSettings = @"allow-overwrite-confidential-mdm-settings"; +OCClassSettingsKey OCClassSettingsKeyConfidentialExemptedActions = @"exempted-actions"; OCClassSettingsKey OCClassSettingsKeyConfidentialTextOpacity = @"text-opacity"; OCClassSettingsKey OCClassSettingsKeyConfidentialTextColor = @"text-color"; OCClassSettingsKey OCClassSettingsKeyConfidentialTextColumnSpacing = @"text-column-spacing"; From 00dd35b1ef7644da6af8ea9828e5b9c7c9202df3 Mon Sep 17 00:00:00 2001 From: felix-schwarz Date: Mon, 25 Aug 2025 16:38:36 +0000 Subject: [PATCH 2/3] Configuration documentation updated --- doc/configuration.adoc | 148 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 143 insertions(+), 5 deletions(-) diff --git a/doc/configuration.adoc b/doc/configuration.adoc index 5ec075368..83fe816fb 100644 --- a/doc/configuration.adoc +++ b/doc/configuration.adoc @@ -44,15 +44,30 @@ tag::actions[] ! `com.owncloud.action.delete` ! Delete +! `com.owncloud.action.detailspace` +! Details + +! `com.owncloud.action.disablespace` +! Disable space + ! `com.owncloud.action.duplicate` ! Duplicate +! `com.owncloud.action.editspacedescription` +! Edit description + +! `com.owncloud.action.editspaceimage` +! Edit image + ! `com.owncloud.action.favorite` ! Favorite item ! `com.owncloud.action.importpasteboard` ! Paste +! `com.owncloud.action.managespace` +! Edit space + ! `com.owncloud.action.markup` ! Markup @@ -83,6 +98,9 @@ tag::actions[] ! `com.owncloud.action.show-exif` ! Image metadata +! `com.owncloud.action.spacemembers` +! Members + ! `com.owncloud.action.unfavorite` ! Unfavorite item @@ -157,15 +175,30 @@ action.create-document-mode ! `com.owncloud.action.delete` ! Delete +! `com.owncloud.action.detailspace` +! Details + +! `com.owncloud.action.disablespace` +! Disable space + ! `com.owncloud.action.duplicate` ! Duplicate +! `com.owncloud.action.editspacedescription` +! Edit description + +! `com.owncloud.action.editspaceimage` +! Edit image + ! `com.owncloud.action.favorite` ! Favorite item ! `com.owncloud.action.importpasteboard` ! Paste +! `com.owncloud.action.managespace` +! Edit space + ! `com.owncloud.action.markup` ! Markup @@ -196,6 +229,9 @@ action.create-document-mode ! `com.owncloud.action.show-exif` ! Image metadata +! `com.owncloud.action.spacemembers` +! Members + ! `com.owncloud.action.unfavorite` ! Unfavorite item @@ -353,6 +389,12 @@ tag::app[] |supported `candidate` +|app.allow-ai-features +|bool +|`true` +|Enable/disable AI features. +|advanced `candidate` + |app.app-store-link |string |`https://itunes.apple.com/app/id1359583808?mt=8` @@ -815,20 +857,89 @@ tag::confidential[] |confidential.allow-overwrite-confidential-mdm-settings |bool -|`false` +| |Controls if confidential related MDM settings can be overwritten. |advanced `candidate` |confidential.allow-screenshots |bool -|`true` +| |Controls whether screenshots are allowed or not. If not allowed confidential views will be marked as sensitive and are not visible in screenshots. |advanced `candidate` -|confidential.mark-confidential-views +|confidential.exempted-actions +|stringArray +| +|List of actions exempt from auto-disallow of particular actions when enabling confidential protections. +[cols="1,1"] +!=== +! Value +! Description +! `com.owncloud.action.copy` +! Exempt com.owncloud.action.copy from list of auto-disallowed actions. + +! `com.owncloud.action.markup` +! Exempt com.owncloud.action.markup from list of auto-disallowed actions. + +! `com.owncloud.action.openin` +! Exempt com.owncloud.action.openin from list of auto-disallowed actions. + +!=== + +|advanced `candidate` + +|confidential.text-color +|string +| +|Controls the color as hex value of the watermark text. +|advanced `candidate` + +|confidential.text-column-spacing +|int +| +|Controls the column spacing of the watermark text in pixel. +|advanced `candidate` + +|confidential.text-custom-text +|string +| +|Controls if the given custom text should be shown as watermark text. +|advanced `candidate` + +|confidential.text-line-spacing +|int +| +|Controls the line spacing of the watermark text in pixel. +|advanced `candidate` + +|confidential.text-opacity +|int +| +|Controls the opacity of the watermark text. Possible values: 0 - 100 +|advanced `candidate` + +|confidential.text-show-timestamp |bool -|`false` -|Controls if views which contains sensitive content contains a watermark or not. +| +|Controls if the current timestamp should be shown as watermark text. +|advanced `candidate` + +|confidential.text-show-user-email +|bool +| +|Controls if the user email should be shown as watermark text. +|advanced `candidate` + +|confidential.text-show-user-id +|bool +| +|Controls if the user ID should be shown as watermark text. +|advanced `candidate` + +|confidential.visible-redacted-characters +|int +| +|Controls the number or visible characters in redacted text. Choose value -1 to do not redact text. |advanced `candidate` |=== @@ -1107,6 +1218,12 @@ tag::endpoints[] |Endpoint to use for retrieving server capabilities. |advanced `candidate` +|connection.endpoint-kiteworks-status +|string +|`kwdav/status.php` +|Endpoint to retrieve basic status information and detect a Kiteworks installation. +|advanced `candidate` + |connection.endpoint-recipients |string |`ocs/v2.php/apps/files_sharing/api/v1/sharees` @@ -1219,9 +1336,21 @@ tag::extensions[] ! `com.owncloud.action.delete` ! Extension with the identifier com.owncloud.action.delete. +! `com.owncloud.action.detailspace` +! Extension with the identifier com.owncloud.action.detailspace. + +! `com.owncloud.action.disablespace` +! Extension with the identifier com.owncloud.action.disablespace. + ! `com.owncloud.action.duplicate` ! Extension with the identifier com.owncloud.action.duplicate. +! `com.owncloud.action.editspacedescription` +! Extension with the identifier com.owncloud.action.editspacedescription. + +! `com.owncloud.action.editspaceimage` +! Extension with the identifier com.owncloud.action.editspaceimage. + ! `com.owncloud.action.favorite` ! Extension with the identifier com.owncloud.action.favorite. @@ -1231,6 +1360,9 @@ tag::extensions[] ! `com.owncloud.action.instant_media_upload` ! Extension with the identifier com.owncloud.action.instant_media_upload. +! `com.owncloud.action.managespace` +! Extension with the identifier com.owncloud.action.managespace. + ! `com.owncloud.action.markup` ! Extension with the identifier com.owncloud.action.markup. @@ -1264,6 +1396,9 @@ tag::extensions[] ! `com.owncloud.action.show-exif` ! Extension with the identifier com.owncloud.action.show-exif. +! `com.owncloud.action.spacemembers` +! Extension with the identifier com.owncloud.action.spacemembers. + ! `com.owncloud.action.unfavorite` ! Extension with the identifier com.owncloud.action.unfavorite. @@ -1297,6 +1432,9 @@ tag::extensions[] ! `license.PocketSVG` ! Extension with the identifier license.PocketSVG. +! `license.SHA3-256` +! Extension with the identifier license.SHA3-256. + ! `license.openssl` ! Extension with the identifier license.openssl. From 9b053d9c7d80877d27f0dfc73e4aa602124422a7 Mon Sep 17 00:00:00 2001 From: Felix Schwarz Date: Mon, 25 Aug 2025 18:41:36 +0200 Subject: [PATCH 3/3] - add changelog --- changelog/12.6.1_2025_xx_xx/1489 | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 changelog/12.6.1_2025_xx_xx/1489 diff --git a/changelog/12.6.1_2025_xx_xx/1489 b/changelog/12.6.1_2025_xx_xx/1489 new file mode 100644 index 000000000..cb7b513e3 --- /dev/null +++ b/changelog/12.6.1_2025_xx_xx/1489 @@ -0,0 +1,13 @@ +Change: Option to exempt actions from auto-disallow + +Adds a new MDM option `confidential.exempted-actions` to exempt one or more actions from being automatically disallowed when enabling Confidential Protection. + +Example to allow the open in action: +```xml +confidential.exempted-actions + + com.owncloud.action.openin + +``` + +https://github.com/owncloud/ios-app/pull/1489