132 lines
4.9 KiB
Dart
132 lines
4.9 KiB
Dart
/// Subset of Nextcloud's `files_sharing` capabilities block that the mobile
|
|
/// sharing UI gates on. Nextcloud reports these per authenticated user, so a
|
|
/// group that an admin excluded from creating public links sees
|
|
/// `public.enabled == false` here — exactly how the web UI hides those buttons.
|
|
///
|
|
/// The block is deeply nested and varies between server versions, so this is
|
|
/// parsed by hand from the raw OCS map with safe fallbacks rather than via
|
|
/// code generation. Missing fields default to the most restrictive value so a
|
|
/// newer/older server never accidentally unlocks a capability.
|
|
class NextcloudSharingCapabilities {
|
|
/// `files_sharing.api_enabled` — master switch. When false the user may not
|
|
/// create any share (user, group or link).
|
|
final bool apiEnabled;
|
|
|
|
/// `files_sharing.public.enabled` — public link shares allowed.
|
|
final bool publicEnabled;
|
|
|
|
/// `files_sharing.public.multiple_links` — more than one link per file.
|
|
final bool publicMultipleLinks;
|
|
|
|
/// `files_sharing.public.upload` — public upload / file-drop folders.
|
|
final bool publicUploadEnabled;
|
|
|
|
/// `files_sharing.public.password.enforced` — a password is mandatory on
|
|
/// public links, so the create flow must collect one upfront.
|
|
final bool publicPasswordEnforced;
|
|
|
|
/// `files_sharing.public.expire_date.enabled`.
|
|
final bool publicExpireEnabled;
|
|
|
|
/// `files_sharing.public.expire_date.days` — default/maximum lifetime.
|
|
final int? publicExpireDays;
|
|
|
|
/// `files_sharing.public.expire_date.enforced` — expiry cannot be removed.
|
|
final bool publicExpireEnforced;
|
|
|
|
/// `files_sharing.group.enabled` (falls back to the older `group_sharing`).
|
|
final bool groupEnabled;
|
|
|
|
/// `files_sharing.resharing` — recipients may reshare.
|
|
final bool resharing;
|
|
|
|
// --- password_policy (a sibling capability of files_sharing) ---
|
|
// These let the link-password UI state the rules up front instead of only
|
|
// surfacing them after the server rejects a weak password. The
|
|
// "non-common password" (breach) check can only be enforced server-side.
|
|
|
|
/// `password_policy.minLength`.
|
|
final int? passwordMinLength;
|
|
|
|
/// `password_policy.enforceUpperLowerCase`.
|
|
final bool passwordEnforceUpperLower;
|
|
|
|
/// `password_policy.enforceNumericCharacters`.
|
|
final bool passwordEnforceNumeric;
|
|
|
|
/// `password_policy.enforceSpecialCharacters`.
|
|
final bool passwordEnforceSpecial;
|
|
|
|
const NextcloudSharingCapabilities({
|
|
this.apiEnabled = false,
|
|
this.publicEnabled = false,
|
|
this.publicMultipleLinks = false,
|
|
this.publicUploadEnabled = false,
|
|
this.publicPasswordEnforced = false,
|
|
this.publicExpireEnabled = false,
|
|
this.publicExpireDays,
|
|
this.publicExpireEnforced = false,
|
|
this.groupEnabled = false,
|
|
this.resharing = false,
|
|
this.passwordMinLength,
|
|
this.passwordEnforceUpperLower = false,
|
|
this.passwordEnforceNumeric = false,
|
|
this.passwordEnforceSpecial = false,
|
|
});
|
|
|
|
/// Parses the `files_sharing` sub-map of an OCS `cloud/capabilities`
|
|
/// response, plus the optional sibling `password_policy` map. Tolerates
|
|
/// missing intermediate maps and type drift.
|
|
factory NextcloudSharingCapabilities.fromFilesSharing(
|
|
Map<String, dynamic> filesSharing, {
|
|
Map<String, dynamic>? passwordPolicy,
|
|
}) {
|
|
Map<String, dynamic>? sub(Map<String, dynamic>? m, String key) {
|
|
final value = m?[key];
|
|
return value is Map<String, dynamic> ? value : null;
|
|
}
|
|
|
|
bool boolAt(Map<String, dynamic>? m, String key) => m?[key] == true;
|
|
int? intAt(Map<String, dynamic>? m, String key) {
|
|
final v = m?[key];
|
|
if (v is int) return v;
|
|
if (v is String) return int.tryParse(v);
|
|
return null;
|
|
}
|
|
|
|
final public = sub(filesSharing, 'public');
|
|
final password = sub(public, 'password');
|
|
final expire = sub(public, 'expire_date');
|
|
final group = sub(filesSharing, 'group');
|
|
|
|
return NextcloudSharingCapabilities(
|
|
apiEnabled: boolAt(filesSharing, 'api_enabled'),
|
|
publicEnabled: boolAt(public, 'enabled'),
|
|
publicMultipleLinks: boolAt(public, 'multiple_links'),
|
|
publicUploadEnabled: boolAt(public, 'upload'),
|
|
publicPasswordEnforced: boolAt(password, 'enforced'),
|
|
publicExpireEnabled: boolAt(expire, 'enabled'),
|
|
publicExpireDays: intAt(expire, 'days'),
|
|
publicExpireEnforced: boolAt(expire, 'enforced'),
|
|
// Newer servers nest it under `group.enabled`; older ones expose a flat
|
|
// `group_sharing` boolean.
|
|
groupEnabled:
|
|
boolAt(group, 'enabled') || boolAt(filesSharing, 'group_sharing'),
|
|
resharing: boolAt(filesSharing, 'resharing'),
|
|
passwordMinLength: intAt(passwordPolicy, 'minLength'),
|
|
passwordEnforceUpperLower: boolAt(
|
|
passwordPolicy,
|
|
'enforceUpperLowerCase',
|
|
),
|
|
passwordEnforceNumeric: boolAt(
|
|
passwordPolicy,
|
|
'enforceNumericCharacters',
|
|
),
|
|
passwordEnforceSpecial: boolAt(
|
|
passwordPolicy,
|
|
'enforceSpecialCharacters',
|
|
),
|
|
);
|
|
}
|
|
}
|