Commit Graph

263 Commits

Author SHA1 Message Date
Conrad Hoffmann
e971269ffb Add function to validate calendar for CalDAV
CalDAV imposes a set of constraints on iCal Calendar objects. They are
spelled out in RFC 4791, section 4.1 [1]. Add an exported function to
validate a calendar according to those constraints, and return data that
is necessary for further CalDAV processing and which can only be
extracted if the calendar meets these constraints.

[1]: https://datatracker.ietf.org/doc/html/rfc4791#section-4.1
2022-05-13 09:20:23 +02:00
Simon Ser
346cfadd34 webdav: rename ServeUserPrincipal to ServePrincipal
A principal may represent something else than a user, for instance
it may represent a group.

Also rename UserPrincipalPath to CurrentUserPrincipalPath, because
the principal being served may not represent the current user.
2022-05-12 18:44:43 +02:00
Conrad Hoffmann
303aef52f3 caldav: implement handleMultiget()
The implementation has feature parity with the CardDAV one.
2022-05-12 17:32:30 +02:00
Conrad Hoffmann
585b01a7a8 Implement GET/HEAD/PUT for calendar objects
Still missing a few features, but works to a certain extend. Requires
an update to the backend interface to support the operations
2022-05-12 14:50:26 +02:00
Conrad Hoffmann
cdb0de3b99 Return calendar description in PROPFIND 2022-05-12 14:50:26 +02:00
Conrad Hoffmann
6887b6b812 Support custom user principal and home set paths
Currently, the user principal path and the home set path are both
hardcoded to "/", for both CalDAV and CardDAV. This poses a challenge if
one wishes to run a CardDAV and CalDAV server in the same server.

This commit introduces the concept of a UserPrincipalBackend. This
backend must provide the path of the current user's principal URL from
the given request context.

The CalDAV and CardDAV backends are extended to also function as
UserPrincipalBackend. In addition, they are required to supply the path
of the respective home set (`calendar-home-set` and
`addressbook-home-set`). The CardDAV and CalDAV servers act accordingly.

The individual servers will continue to work as before (including the
option of keeping everything at "/"). If one wishes to run CardDAV and
CalDAV in parallel, the new `webdav.ServeUserPrincipal()` can be used as
a convenience function to serve a common user principal URL for both
servers. The input for this function can be easily computed by the
application by getting the home set paths from the backends and using
`caldav.NewCalendarHomeSet()` and `carddav.NewAddressbookHomeSet()` to
create the home sets.

Note that the storage backend will have to know about these paths as
well. For any non-trivial use case, a storage backend should probably
have access to the same UserPrincipalBackend. That is, however, an
implementation detail and doesn't have to be reflected in the
interfaces.
2022-05-11 11:12:04 +02:00
Conrad Hoffmann
b5c6f8927c Add exported function to create HTTPError
This can be used by backends to influence the status code returned to
clients for errors that occurred in the backend.
2022-05-03 16:56:13 +02:00
Conrad Hoffmann
95a4ae783b carddav: use AddressBook.Path in PROPFIND response 2022-05-02 20:58:00 +02:00
Conrad Hoffmann
8931e14cf6 caldav: use Calendar.Path in PROPFIND response 2022-05-02 20:56:38 +02:00
Simon Ser
d8a8af0448 internal: don't send an empty error element
According to RFC 4918 section 14.5, the error element can't be empty.
2022-05-02 20:41:33 +02:00
Simon Ser
3f8b212b0d internal: add Response.Err
Builds a detailed HTTPError + Error if the Response is a failure.
It contains more context than just the HTTPError.
2022-05-02 15:43:43 +02:00
Simon Ser
8cc6542f1c carddav: use partial error response on multiget failure
Instead of making the whole HTTP request fail when a single address
object cannot be fetched, return a partial error response.
2022-05-02 15:43:43 +02:00
Simon Ser
46ebe58ac2 internal: introduce NewErrorResponse
Same as NewOKResponse but for errors.
2022-05-02 15:43:43 +02:00
Simon Ser
4e8c5effe3 Replace DAVError with HTTPError + Error
That way we can avoid having different ways of representing the
same error value.
2022-05-02 15:43:43 +02:00
Simon Ser
8738a105fc internal: add HTTPError.Unwrap
This allows callers to access the underlying error via errors.Unwrap.
2022-05-02 15:43:43 +02:00
Konstantinos Koukas
25dfbaf95e caldav: add supported-calendar-component-set field 2022-04-12 09:38:26 +02:00
Conrad Hoffmann
6401d9ed45 caldav: extend query filter types
The basic types related to queries and filtering are missing some
features specified in the RFC (as also noted in the TODO comments). This
adds several of the missing elements, working towards being able to
handle all RFC-compliant queries.

The work is not fully done, e.g. the collation for text-match is still
not handled, but it's getting pretty close.
2022-04-01 18:29:58 +02:00
Conrad Hoffmann
7dafedd290 Add type-safe precondition errors for CalDAV 2022-04-01 16:22:04 +02:00
Conrad Hoffmann
c4206ba616 carddav: pass If-(None-)Match to backend
This simply extends the interfaces to pass on the values if they were
used, relying on the backend to handle things accordingly.
2022-03-22 09:28:24 +01:00
Conrad Hoffmann
52215c1690 Pass request context to backend interface
This aligns the caldav interface with the carddav one (see #53).
2022-03-16 20:11:00 +01:00
Simon Ser
106d4e1c88 caldav: add basic server
A lot of features a still missing, but basic discovery works.

Co-authored-by: Conrad Hoffmann <ch@bitfehler.net>
2022-03-16 16:47:29 +01:00
Simon Ser
9caa4ff356 caldav: add support for reports
Co-authored-by: Conrad Hoffmann <ch@bitfehler.net>
2022-03-16 16:47:29 +01:00
Conrad Hoffmann
85d2b222bb Add error type representing DAV/XML errors
Backends will need some way to signal that a precondition error occurred
(and specifying which one) without causing the server to return a 500.
This commit adds an exported function to create a specific error for
this. The existing error handling routine is slightly adapted to handle
this error in such a way that it returns the desired result.

Usage would be something like:

```
return "", carddav.NewPreconditionError(carddav.PreconditionNoUIDConflict)
```

which triggers the following HTTP response:

```
HTTP/1.1 409 Conflict.
Content-Type: text/xml; charset=utf-8.
Date: Thu, 10 Mar 2022 10:28:56 GMT.
Content-Length: 141.
Connection: close.

<?xml version="1.0" encoding="UTF-8"?>
<error xmlns="DAV:"><no-uid-conflict
xmlns="urn:ietf:params:xml:ns:carddav"></no-uid-conflict></error>
```

This response gets correctly recognized by e.g. Evolution (though it's
handling is not great).

The added error type is generic enough to be used for other stuff also.
As it is not exported (internal package), new functions for creating
such errors would have to be added.
2022-03-10 16:48:11 +01:00
Sebastien Binet
6d59672ed4 carddav: add filtering and matching helper functions
Updates emersion/hydroxide#159.

Signed-off-by: Sebastien Binet <binet@cern.ch>
Co-authored-by: Conrad Hoffmann <ch@bitfehler.net>
2022-03-01 10:06:11 +01:00
Conrad Hoffmann
dc57b81662
carddav/server: set ETag and Last-Modified if available
Some clients (e.g. Evolution) will not work properly without this. It is
up to the underlying backend to actually provide this data, the headers
will only be set if it is available.
2022-02-24 12:41:56 +01:00
Conrad Hoffmann
0f6744ede8 Pass request context to storage interface
This way the storage implementation can communicate with any potentially
used middleware (e.g. authentication) or for example abort requests.
2022-02-23 12:01:13 +01:00
Simon Ser
2162596af8 readme: update badges 2022-02-02 13:54:40 +01:00
jumo98
6238e10e65
Include ModTime for directories if available 2021-08-11 11:08:03 +02:00
Sebastien Binet
8efde26ef9
internal: use http.TimeFormat to marshal Time values 2021-03-16 18:42:55 +01:00
Apehaenger
ed52608852
Make Response.Path return the path on error 2021-01-12 12:57:28 +01:00
Simon Ser
373663f9ee
readme: add CI badge 2020-10-12 17:35:10 +02:00
Heiko Carrasco
4316bbcd93
caldav: add server handling for well-known URLs 2020-10-09 15:10:33 +02:00
proletarius101
9cd3bb51b9 fix: deprecrated conversion from int64 to string 2020-09-09 16:00:38 +02:00
AlmogBaku
9e23289610 sync-collection for client 2020-05-25 18:28:24 +02:00
Simon Ser
25df841e2b
internal: move HTTPError to common file
This is used by both clients and servers now.
2020-05-13 18:24:29 +02:00
Simon Ser
a4e0e81003
caldav: add Client.MultiGetCalendar 2020-05-13 16:45:25 +02:00
Simon Ser
5328b4c493
caldav: set Depth to 1 for calendar-query REPORT requests
SabreDAV chokes on an unset Depth header field.
2020-05-13 15:06:16 +02:00
Simon Ser
4c0dc5d900
internal: parse WebDAV toplevel <error> elements 2020-05-13 15:02:52 +02:00
Simon Ser
f4e3fe8c0a
internal: add Multistatus.Get test with HTTP error
References: https://github.com/emersion/go-webdav/issues/39
2020-04-05 14:37:17 +02:00
Simon Ser
66d5686c9e
ci: add .build.yml 2020-04-02 16:50:41 +02:00
AlmogBaku
1b725cb0b9 fixes #33, remove missingPropError error 2020-04-02 16:48:13 +02:00
Simon Ser
abadf534f4
carddav: expose supported address data in client 2020-02-27 12:36:14 +01:00
Simon Ser
514296664c
caldav: upgrade to latest go-ical API 2020-02-24 21:16:45 +01:00
Simon Ser
4c419a961d
caldav: add Client.GetCalendarObject 2020-02-24 18:19:39 +01:00
Simon Ser
7bb9b3aa0b
caldav: add Client.PutCalendarObject 2020-02-24 18:13:24 +01:00
Simon Ser
07d4dfae5e
Use new ical library 2020-02-24 17:52:25 +01:00
Simon Ser
7d2b6a3902
carddav: make Discover fail when target is empty 2020-02-19 16:32:35 +01:00
Simon Ser
4b24edf624
carddav: fix Discover with default HTTPS port 2020-02-19 16:31:03 +01:00
Simon Ser
ddf2a85958
Introduce HTTPClient, remove Client.SetBasicAuth 2020-02-19 16:02:49 +01:00
Simon Ser
c52097fefb
carddav: add Client.GetAddressObject 2020-02-12 21:38:55 +01:00