implemented a comprehensive Nextcloud file sharing system with support for user, group, and public link shares with gating based on server-side permissions; added sharing management interfaces including a share sheet; updated the file list with visual badges for incoming shares and improved OCS API response handling.
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
/// Nextcloud share permission bitmask helpers. These mirror the constants the
|
||||
/// OCS `files_sharing` API expects in the `permissions` field. Kept as pure
|
||||
/// functions (no Flutter/IO) so they are unit-testable.
|
||||
library;
|
||||
|
||||
/// Individual permission bits (Nextcloud `OCS\Constants`).
|
||||
const int kPermissionRead = 1;
|
||||
const int kPermissionUpdate = 2;
|
||||
const int kPermissionCreate = 4;
|
||||
const int kPermissionDelete = 8;
|
||||
const int kPermissionShare = 16;
|
||||
|
||||
/// User-facing presets that map onto a bitmask.
|
||||
enum SharePreset {
|
||||
/// Recipient can only view/download.
|
||||
readOnly,
|
||||
|
||||
/// Recipient can view, edit, add and remove (full editing).
|
||||
edit,
|
||||
|
||||
/// Upload-only "file request" — recipient can add files to a folder but not
|
||||
/// see existing contents. Only meaningful for folders.
|
||||
fileDrop,
|
||||
}
|
||||
|
||||
extension SharePresetLabel on SharePreset {
|
||||
String get label {
|
||||
switch (this) {
|
||||
case SharePreset.readOnly:
|
||||
return 'Nur Lesen';
|
||||
case SharePreset.edit:
|
||||
return 'Bearbeiten';
|
||||
case SharePreset.fileDrop:
|
||||
return 'Datei-Anfrage';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if [mask] contains the given [flag].
|
||||
bool hasPermission(int mask, int flag) => mask & flag == flag;
|
||||
|
||||
/// Builds the permission bitmask for a [preset].
|
||||
///
|
||||
/// [isFolder] matters for the `edit` preset: a file can only carry
|
||||
/// read+update, while a folder additionally supports create+delete. Nextcloud
|
||||
/// rejects create/delete on a file ("Failed to update share"), so they must be
|
||||
/// omitted there. When [allowReshare] is true the reshare bit is added to the
|
||||
/// editing presets — mirroring how the Nextcloud clients respect the
|
||||
/// `resharing` capability.
|
||||
int permissionsFor(
|
||||
SharePreset preset, {
|
||||
bool allowReshare = false,
|
||||
bool isFolder = false,
|
||||
}) {
|
||||
switch (preset) {
|
||||
case SharePreset.readOnly:
|
||||
return kPermissionRead;
|
||||
case SharePreset.edit:
|
||||
var base = kPermissionRead | kPermissionUpdate;
|
||||
if (isFolder) base |= kPermissionCreate | kPermissionDelete;
|
||||
return allowReshare ? base | kPermissionShare : base;
|
||||
case SharePreset.fileDrop:
|
||||
return kPermissionCreate;
|
||||
}
|
||||
}
|
||||
|
||||
/// Classifies an arbitrary permission bitmask into the closest preset, or null
|
||||
/// if it doesn't match any (e.g. a custom combination). The reshare bit is
|
||||
/// ignored for matching so an "edit" share stays "edit" regardless of reshare.
|
||||
SharePreset? presetFromBitmask(int mask) {
|
||||
final normalized = mask & ~kPermissionShare;
|
||||
if (normalized == kPermissionCreate) return SharePreset.fileDrop;
|
||||
if (normalized == kPermissionRead) return SharePreset.readOnly;
|
||||
// Any read share that also carries a write bit (update/create/delete) is
|
||||
// surfaced as "edit".
|
||||
const writeBits = kPermissionUpdate | kPermissionCreate | kPermissionDelete;
|
||||
if (hasPermission(normalized, kPermissionRead) &&
|
||||
normalized & writeBits != 0) {
|
||||
return SharePreset.edit;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
Reference in New Issue
Block a user