Currently trying out stalwart as mail and calendar server. It supports sharing calendars between users, but that is not configurable via the WebUI, only via a JMAP client or a WebDAV client that supports ACLs.
As DAVx5 does not seem to support the ACLs and I did not want to dig through the list of JMAP clients: here is how to do it with cURL.
The JMAP introductory guide was helpful, as it was easy to translate into cURL. The following steps could be automated further (e.g. storing cURL results into env vars or by using JMAPs result references), but this post should only show you an example of JMAP and allow you to adapt it for your own small, one-time tasks.
- Prepare your credentials: I'll assume that you stored your username and password in env vars
USERNAMEandPASSWORD. You'll also have to adapt the server URL. - Find out your account ID.
JMAP provides a well known endpoint with information about the server and about your account:
bash $ curl -sS -u "$USERNAME:$PASSWORD" 'https://example.com/.well-known/jmap' --follow | jq . { "capabilities": { "urn:ietf:params:jmap:core": { ... }, "urn:ietf:params:jmap:mail": {}, "urn:ietf:params:jmap:calendars": {}, "urn:ietf:params:jmap:calendars:parse": {}, }, "accounts": { "a": { "name": "simon@example.com", "isPersonal": true, ... }, "b": { "name": "some-group@example.com", "isPersonal": false, ... } }, "primaryAccounts": { "urn:ietf:params:jmap:calendars": "a", ... }, "username": "simon@example.com", "apiUrl": "https://example.com/jmap/", }Accounts withisPersonal: falseare groups (at least for stalwart). Most probably yourprimaryAccountis correct, so your account ID isa. -
Now list our calendars (insert your account ID into the query): ```bash $ curl -sS -u "$USERNAME:$PASSWORD" -X POST "https://example.com/jmap/" -H "Content-Type: application/json" -d '{ "using": [ "urn:ietf:params:jmap:core", "urn:ietf:params:jmap:calendars" ], "methodCalls": [ [ "Calendar/get", { "accountId": "a", "filter": {}, "sort": [{"property":"name","isAscending":true}], "limit": 100 }, "c1" ] ] }' | jq .
{ "methodResponses": [ [ "Calendar/get", { "accountId": "a", "state": "slq", "list": [ { "id": "x", "name": "calendar", "description": null, "color": "#84e543", "timeZone": null, "sortOrder": 0, "isDefault": true, "isSubscribed": true, "myRights": { "mayReadFreeBusy": true, "mayReadItems": true, "mayWriteAll": true, "mayWriteOwn": true, "mayUpdatePrivate": true, "mayRSVP": true, "mayShare": true, "mayDelete": true } } ], "notFound": [] }, "c1" ] ], "sessionState": "73fa67b4" }
Most resources have default `/get` and `/set` methods. 4. And finally: share the calendar with the other person. You need to insert: 1. your account ID (here `a`), 2. the ID of the calendar (here `x`), and 3. the account ID of the other person (here `c`).bash $ curl -sS -u "$USERNAME:$PASSWORD" -X POST "https://example.com/jmap/" -H "Content-Type: application/json" -d '{ "using": [ "urn:ietf:params:jmap:core", "urn:ietf:params:jmap:calendars" ], "methodCalls": [ [ "Calendar/set", { "accountId": "a", "update": { "x": {"shareWith":{"c": { "mayReadFreeBusy": true, "mayReadItems": true, "mayWriteAll": true, "mayWriteOwn": true, "mayUpdatePrivate": true, "mayRSVP": false, "mayShare": false, "mayDelete": true }}}} }, "c1" ] ] }' | jq . { "methodResponses": [ [ "Calendar/set", { "accountId": "b", "newState": "sr2aq", "updated": { "b": null } }, "c1" ] ], "sessionState": "4e26f850" }`` What confused me at first was, that the response didn't tell me explicitly that it was changed. You can only see that thenewStateis different from thestate` before.
And that's it for sharing your calendar. With similarly simple cURL requests you can also configure other settings, learn more about JMAP, or debug further details.