mirror of
https://github.com/Kozea/Radicale.git
synced 2025-06-26 16:45:52 +00:00
Page:
Sharing Collections
Pages
01 ‐ Reporting Issues
02 ‐ Contributions
C*DAV explanations
Client InfCloud
Client Status
Client Thunderbird
Client pimsync
Collection Storage
Collection type VSUBSCRIBED (Webcal)
Current Maintainers Contributors
Development Testing Release
Donations
Fail2Ban Setup
Home
Installing on Debian Linux
Installing on Docker
Installing on OpenBSD
LDAP authentication
Performance Tuning
Production ready installation
Radicale Custom DAV protocol extensions
Radicale Internals
Reverse Proxy Diagnostics Troubleshooting
Reverse Proxy Hints
Server Diagnostics Troubleshooting
Sharing Collections
Simple installation
No results
5
Sharing Collections
Peter Bieringer edited this page 2024-06-12 08:29:35 +02:00
Radicale v3
"radicale" is a lightwide CalDAV/CardDAV server and supporting sharing of collections only on server side with static configuration.
Sharing Collections with other configured users
Preparations
- create a directory aside
collection-root
(which is the base directory of "radicale" to lookup user folders) like e.g.collection-shared
- create a sub-directory structure with collections or group->collections
- softlink required collection directory into user's directory
- in case of read-only permissions are required for shared calendar, extend
rights
file matching particular collection and user
Example for a storage layout incl. shared calendar/addressbook
Note: */.Radicale*
files/directories are not shown here
[d]
: directory[f]
: file[l]
: softlink(ro)
: read-only(rw)
: read-write
[d] /var
└─[d] /lib
└─[d] /radicale
└─[d] /collections
├─[d] /collection-shared
│ ├─[d] /group1
│ │ ├─[d] /sharedcalendar1 (Collection)
│ │ │ ├─[f] sharedschedule1.ics
│ │ │ ├─[f] ...
│ │ │ └─[f] sharedscheduleX.ics
│ │ └─[d] /sharedaddressbook1 (Collection)
│ │ ├─[f] sharedcontact1.vcf
│ │ ├─[f] ...
│ │ └─[f] sharedcontactX.vcf
│ │
│ └─[d] /group2
│ ├─[d] /sharedcalendar2 (Collection)
│ │ ├─[f] sharedschedule1.ics
│ │ ├─[f] ...
│ │ └─[f] sharedscheduleX.ics
│ └─[d] /sharedaddressbook2 (Collection)
│ ├─[f] sharedcontact1.vcf
│ ├─[f] ...
│ └─[f] sharedcontactX.vcf
│
└─[d] /collection-root
├─[d] /USER1 (share some collections of "group1")
│ ├─[d] mycalendar1 (Collection)
│ ├─[d] myaddressbook1 (Collection)
│ ├─[l] sharedcalendar1 -> ../../collection-shared/group1/sharedcalendar1 (rw, default)
│ └─[l] sharedaddressbook1 -> ../../collection-shared/group1/sharedaddressbook1 (rw, default)
│
├─[d] /USER2 (share some collections of "group2" read-only)
│ ├─[d] mycalendar1 (Collection)
│ ├─[d] myaddressbook1 (Collection)
│ ├─[l] sharedcalendar2 -> ../../collection-shared/group2/sharedcalendar2 (ro)
│ └─[l] sharedaddressbook2 -> ../../collection-shared/group2/sharedaddressbook2 (ro)
Related rights
extension for read-only:
[group2-sharedcalendar2-ro]
user: USER2
collection: {user}/sharedcalendar2(/.+)?
permissions: r
[group2-sharedaddressbook2-ro]
user: USER2
collection: {user}/sharedaddressbook2(/.+)?
permissions: r
Sharing a collections read-only to public as WebCAL
ATTENTION: This is a simple and potentially insecure example
Requirements
- A reverse proxy in front of "radicale" is mandatory, because "radicale" itself is not supporting mix of authenticated and unauthenticated users.
Preparations
- create/assign a directory structure (see below)
- create users ADMIN1 and ANON1 with secret passwords
- extend the
rights
file to limit the user ANON1 only to GET requests ("i")
[anon]
user: ANON1
collection: {user}(/.*)?$
permissions: i
- extend the reverse proxy configuration by catching requests in a location, map and enrich the request with credentials of user ANON1 by conditionally adding the authorization header to the request.
<Location /public>
RewriteRule /public/(events[a-z0-9]+).ics$ /radicale/ANON1/public$1/ [PT]
</Location>
SetEnvIf Request_URI "^/public/(events[a-z0-9]+)\.ics$" ANON_PUBLICEVENTS
# "Basic <base64 encodede USER:PASS>" example generated with 'echo -n "ANON1:ANON1" | base64'
RequestHeader set Authorization "Basic QU5PTjE6QU5PTjE=" env=ANON_PUBLICEVENTS
Example for a storage layout
[d] /var
└─[d] /lib
└─[d] /radicale
└─[d] /collections
├─[d] /collection-shared
│ └─[d] /public
│ └─[d] /publicevents1 (Collection)
│ ├─[f] sharedschedule1.ics
│ ├─[f] ...
│ └─[f] sharedscheduleX.ics
│
└─[d] /collection-root
├─[d] /ADMIN1
│ └─[l] publicevents1 -> ../../collection-shared/public/publicevents1 (rw, default)
│
└─[d] /ANON1
└─[l] publicevents1 -> ../../collection-shared/public/publicevents1 (ro, only GET allowed)
Testing
GET request to a valid collection
(here it has 2 entries currently)
curl -s http://localhost/public/events1.ics | grep -E '(VEVENT|VCALENDAR)'
BEGIN:VCALENDAR
BEGIN:VEVENT
END:VEVENT
BEGIN:VEVENT
END:VEVENT
END:VCALENDAR
GET request to a non-existent collection
curl -s http://localhost/publicevents2.ics
The requested resource could not be found.
PROPFIND request to URL
(expected forbidden)
curl --request PROPFIND http://localhost/public/events1.ics
Access to the requested resource forbidden.
PUT request to URL
(expected forbidden)
curl --data-binary @test.ics --request PUT http://localhost/public/events1.ics
Access to the requested resource forbidden.
Publishing
URL for publishing e.g. via WebCAL: https://FQDN/public/events1.ics