9.1 KiB
Collection Sharing
Static collection sharing without permissions filter using soft-links (Unix-only) is supported since storage type multifilesystem was implemented, see (Wiki: Sharing Collections)[https://github.com/Kozea/Radicale/wiki/Sharing-Collections]
With 3.7.0 a major extension was implemented using internal mapping configuration stored in a database and a management API.
Sharing Configuration Store
Types of supported sharing configuration:
- csv (>= 3.7.0)
- files (>= 3.7.0)
Sharing Configuration Entry Data
ShareType: type of sharetoken: token-based share (do not require user authentication)map: map-based share (requires user authentication)
PathOrToken: token or "virtual" collection, has to be unique (PRIMARY KEY)PathMapped: target collectionOwner: owner of the shareUser: user of the sharePermissions: effective permission of the shareEnabledByOwner: control by ownerEnabledByUser: control by userHiddenByOwner: control by ownerHiddenByUser: control by userTimestampCreated: unixtime of creationTimestampUpdated: unixtime of last updateProperties: overlay properties (limited set whitelisted)
Enabled*: owner AND user have to enable a share to become usable
Hidden*: owner AND user have to disable a share to become visible in PROPFIND
Sharing Configuration Entry Storage
CSV
(>= 3.7.0)
One CSV file containing one row per sharing config, separated by ; and containing header with columns from above.
If given, properties are stored in JSON format in CSV.
Files
(>= 3.7.0)
File-based configuration store is using encoded PathOrToken as filename for each config. File contains the data stored as "dict" in binary Python "pickle" format (same is also used for item cache files).
Sharing Access
Sharing Access via Maps
(>= 3.7.0)
Map-based sharing can be accessed as usual after authentication and authorization.
Permission Control
permit_create_map- supported rights permissions:
Mm
- supported rights permissions:
Workflow
- create map as owner
- enable map as owner (can be combined with "create")
- enable map as user (explicit required to avoid sudden available share)
In case share should be visible using PROPFIND
- unhide map as owner (can be combined with "create")
- unhide map as user (explicit required to avoid sudden visible share)
Sharing Access via Tokens
(>= 3.7.0)
Token-based sharing can be accessed after retrieving the token via
Token-URI: /.token/<Token>
Permission Control
permit_create_token- supported rights permissions:
Tt
- supported rights permissions:
Workflow
- create token as owner
- enable token as owner (can be combined with "create")
- handover URI with token to client
Sharing Configuration Management API
Sharing Configuration Management API version 1
(>= 3.7.0)
Type: POST API
Base-URI: /.sharing/v1/<ShareType>/<Hook>
See also test cases in radicale/tests/test_sharing.py
Data Format
Input Data Format
Parsing be controlled by CONTENT_TYPE
- application/x-www-form-urlencoded (>= 3.7.0)
- application/json (>= 3.7.0)
Output Data Format
Can be selected by HTTP_ACCEPT
- text/plain (>= 3.7.0)
- text/csv (>= 3.7.0) - only for "list"
- application/json (>= 3.7.0)
Accepted Input Data Fields
PathOrToken: token or "virtual" collectionPathMapped: target collectionOwner: owner of the shareUser: user of the sharePermissions: effective permission of the shareEnabled: owner/user selected by authenticationHidden: owner/user selected by authenticationProperties: properties to overlay
API Hooks
API Hook "info"
Shows what kind of ShareTypes are supported
- Example: TEXT
curl -u user:pass -H "accept: text/plain" -d "" http://localhost:5232/.sharing/v1/all/info
ApiVersion=1
Status='success'
FeatureEnabledCollectionByMap=True
PermittedCreateCollectionByMap=True
FeatureEnabledCollectionByToken=True
PermittedCreateCollectionByToken=True
- Example: JSON
curl -u user:pass --silent -H "accept: application/json" -d "" http://localhost:5232/.sharing/v1/all/info | jq
{
"ApiVersion": 1,
"Status": "success",
"FeatureEnabledCollectionByMap": true,
"PermittedCreateCollectionByMap": true,
"FeatureEnabledCollectionByToken": true,
"PermittedCreateCollectionByToken": true
}
API Hook "(token|map)/create"
- Authorization
Authenticated user is Owner
API Hook "token/create"
Create a share by mapping a collection of an Owner to a token.
- Authorization
Authenticated user as Owner has at least read access to PathMapped
- Input
| Parameter | Type | Requirement |
|---|---|---|
| PathMapped | str | mandatory |
| User | str | optional(default:owner) |
| Permissions | str | optional(default:r) |
| Enabled | bool | optional(owner/default:False) |
| Hidden | bool | optional(owner/default:True) |
| Properties | str | optional |
- Output
| Parameter | Type | Value | | - | - | | PathOrToken | str | (autogenerated token) |
- Example: TEXT
curl -u user:pass -d "PathMapped=/user/testcalendar1/" http://localhost:5232/.sharing/v1/token/create
ApiVersion=1
Status='success'
PathOrToken='v1/VQR7AmsVRi2ZlFj_JwGpFx-ES5Goyku-gP_YkLh1zUw='
API Hook "map/create"
Create a share by mapping a collection of an Owner to an User.
- Authorization
Authenticated user as Owner has at least read access to PathMapped
Provided User has at least read access to PathOrToken
- Input
| Parameter | Type | Requirement | | - | - | | PathOrToken | str | mandatory | | PathMapped | str | mandatory | | User | str | mandatory | | Permissions | str | optional(default:r) | | Enabled | bool | optional(owner/default:False) | | Hidden | bool | optional(owner/default:True) | | Properties | optional |
-
Output: result status
-
Example: TEXT
curl -u owner:pass -d "PathOrToken=/user/cal1-from-owner/" -d "PathMapped=/owner/cal1/" -d "User=user" http://localhost:5232/.sharing/v1/map/create
ApiVersion=1
Status=success
API Hook "(map|token|all)/list"
List shares (optional with filter) either owned or assigned as user.
- Authorization
Authenticated user as Owner or User
- Input
| Parameter | Type | Used for |
|---|---|---|
| PathOrToken | str | optional |
| PathMapped | str | optional |
-
Output: plain/csv/json
-
Example: CSV
curl -H "accept: text/csv" -u owner:pass -d "" http://localhost:5232/.sharing/v1/map/list
ShareType,PathOrToken,PathMapped,Owner,User,Permissions,EnabledByOwner,EnabledByUser,HiddenByOwner,HiddenByUser,TimestampCreated,TimestampUpdated,Properties
map,/user/cal1-from-owner/,/owner/cal1/,owner,user,r,False,False,True,True,1771962120,1771962120,{}
API Hook "(map|token)/delete"
Delete a share selected by PathOrToken.
- Authorization
Authenticated user is Owner
- Input
| Parameter | Type | Used for | as Owner | as User |
|---|---|---|---|---|
| PathOrToken | str | selection | mandatory | not-permitted |
- Output: result status
API Hook "(token|map)/update"
Update a share selected by PathOrToken.
Execute delete+create in case PathOrToken needs to be changed.
- Authorization
Authenticated user is Owner or User
- Input
| Parameter | Type | Used for | Owner | User |
|---|---|---|---|---|
| PathOrToken | str | selection | mandatory | mandatory |
| PathMapped | str | adjust | optional | not-permitted |
| User | str | adjust | optional | not-permitted |
| Permissions | str | adjust | optional | not-permitted |
| Enabled | bool | adjust | optional(owner) | optional(user) |
| Hidden | bool | adjust | optional(owner) | optional(user) |
| Properties | str | adjust | optional | optional |
- Output: result status
API Hooks "(map|token)/(enable|disable|hide|unhide)"
Toggle enable|disable|hide|unhide of Owner or User of a share selected by PathOrToken
- Authorization
Authenticated user is Owner or User
- Input
| Parameter | Type | Used for | Owner | User |
|---|---|---|---|---|
| PathOrToken | selection | mandatory | mandatory |
-
Output: result status
-
Example: TEXT (enable)
curl -u owner:pass -d "PathOrToken=/user/cal1-from-owner/" -d "PathMapped=/owner/cal1/" -d "User=user" http://localhost:5232/.sharing/v1/map/enable
ApiVersion=1
Status=success
- Example: JSON (unhide)
curl -u owner:pass -d '{"PathOrToken": "/user/cal1-from-owner/", "PathMapped": "/owner/cal1/", "User": "user"} http://localhost:5232/.sharing/v1/map/unhide
ApiVersion=1
Status='success'
Properties Overlay
Owner or user can define per share a set of properties to overlay on PROPFIND response during create or update via API.
Whitelisted ones are defined in OVERLAY_PROPERTIES_WHITELIST in radicale/sharing/__init__.py:
C:calendar-description(>= 3.7.0)ICAL:calendar-color(>= 3.7.0)CR:addressbook-description(>= 3.7.0)INF:addressbook-color(>= 3.7.0)
Properties Overlay Control Options
permit_properties_overlay- supported share permissions:
Pp
- supported share permissions:
enforce_properties_overlay- supported share permissions:
Ee
- supported share permissions: