Commit Graph

60 Commits

Author SHA1 Message Date
Thomas Müller
3ed9a4f052 carddav, caldav: add missing headers on PUT
ETag and Last-Modified should be set to the new calendar object or
address object properties.
2024-03-28 11:22:46 +01:00
Conrad Hoffmann
ad1fe1c5a8
caldav, carddav: displayname and desription are optional
Both the displayname and the description can be absent for both
calendars and address books. If this is the case they should not show up
in PROPFIND responses as empty string.
2024-02-08 17:15:04 +01:00
Simon Ser
20fad80dff carddav: return HTTP 501 error instead of panicing 2024-02-07 17:26:50 +01:00
Simon Ser
fbcd08d64a carddav: pass pointer in CreateAddressBook
The struct is a bit too large to pass by value.
2024-02-07 17:24:04 +01:00
Simon Ser
f1d56f2437 internal: add IsRequestEmpty 2024-02-07 17:23:17 +01:00
Conrad Hoffmann
71bd967b43 carddav: support address book creation/deletion
Now that the handling for multiple address books is in place, this
commit adds initial support for creation and deletion of address books.

These operations obviously require support from the backend, so the
interface gains two new methods. All properties of the address book
passed to `CreateAddressBook()` may be unset (e.g. when a client sends a
MKCOL request without a body), except for the path, which is always set.
It is up to the backend to put any desired default values in place.
2024-02-07 17:20:48 +01:00
Conrad Hoffmann
eaac65215b carddav: support multiple address books
This is the equivalent of #127 (and #140) for CardDAV and finally allows
backends to serve different address books to different users.

While I'm breaking the interface, correct one last instance of
"Addressbook" to "AddressBook" (in `AddressBookHomeSetPath`).
2024-02-02 17:48:22 +01:00
Simon Ser
0fb0a675ab carddav: handle PROPFIND on root
Same as 7dd64908d2 ("caldav: handle PROPFIND on root") but for
CardDAV.
2023-07-06 12:14:17 +02:00
Conrad Hoffmann
ac9af45270 Dedicated type for conditional match header fields
The `If-Match` and `If-None-Match` conditional headers can have either a
wildcard or a (quoted) ETag as value. However, the ETag _could_ be a
literal `*`, so care must be taken to allow these cases to be
distinguished. The values of these headers have to be handled by the
backend, so export a type that facilitates working with these values.
2022-11-22 11:58:13 +01:00
Conrad Hoffmann
561012d30f carddav: switch to one static path layout
See #100 for details. Obsoletes #99.
2022-11-02 19:44:42 +01:00
Simon Ser
d7891ce50c internal: fix XML element struct naming
We were sometimes using TitleCase, sometimes Lowercase. Let's align
on the idiomatic Go naming and pick TitleCase everywhere.
2022-05-31 23:04:42 +02:00
Conrad Hoffmann
1e99b70a62 carddav: set content length header for HEAD/GET requests
Now that the backend can supply this value, use it for explicitly
setting the header in GET/HEAD responses if available.
2022-05-24 11:18:11 +02:00
Conrad Hoffmann
a3e56141d9 carddav: add support for getcontentlength property
Allow the backend to provide a value for the `getcontentlength` property
as described in [RFC 2518 section 13.4][1].

The implementation treats is as optional, allthough it is a required
property per RFC. Most clients do perfectly fine without it, though.

Properly setting this in the backend makes the CardDAV collection
listable with clients that do require it, e.g. cadaver.

[1]: https://datatracker.ietf.org/doc/html/rfc2518#section-13.4
2022-05-24 11:18:11 +02:00
Conrad Hoffmann
cabaf3268b carddav: return multistatus response on PROPPATCH
This does not implement any actual PROPPATCH logic, but makes the server
return a proper multistatus response with errors for each property
instead of a generic HTTP error.

It also adds the distinction between requests to the address book and
those to other resources. In CardDAV, only the address book itself has
properties that make sense to change via PROPPATCH. Those are responded
to with a 501, indicating that this needs further implementation.
Requests to other resources return 405 for each property, indicating
that the resources do not support PROPPATCH at all.
2022-05-23 11:30:03 +02:00
Conrad Hoffmann
b0c59cdea1 carddav/caldav: use 308 for .well-known redirects
This makes it a little less ambiguous (and, in case of Go clients, a lot
easier) that clients should follow the redirect by sending the same
PROPFIND request, including body, to the new location.

See also the documentation of [http.Client.Do()][1] and the comments in
[http.redirectBehavior()][2].

Confirmed to not make a difference for Evolution and Thunderbird
clients.

[1]: https://pkg.go.dev/net/http#Client.Do
[2]: https://cs.opensource.google/go/go/+/refs/tags/go1.18.2:src/net/http/client.go;drc=d8762b2f4532cc2e5ec539670b88bbc469a13938;l=502
2022-05-23 09:54:10 +02:00
Simon Ser
bc3faca3a0 carddav: only call CurrentUserPrincipal when necessary 2022-05-13 15:29:55 +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
95a4ae783b carddav: use AddressBook.Path in PROPFIND response 2022-05-02 20:58:00 +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
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
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
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
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
Heiko Carrasco
4316bbcd93
caldav: add server handling for well-known URLs 2020-10-09 15:10:33 +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
842acb3647
carddav: add Client.PutAddressObject 2020-02-12 19:47:16 +01:00
Simon Ser
25678476db
internal: add ETag 2020-02-03 21:48:31 +01:00
Simon Ser
dd1527b97e
carddav: allow created address book objects to have a different path
Closes: https://github.com/emersion/go-webdav/issues/32
2020-01-30 15:20:10 +01:00
Simon Ser
feea39c898
carddav: fix server appearing as read-only in Evolution 2020-01-30 00:43:23 +01:00
Simon Ser
8937358ac1
Allow servers to return DAV capabilities in OPTIONS 2020-01-29 18:03:47 +01:00
Simon Ser
1f509de404
carddav: honor address-data in addressbook-query 2020-01-27 10:30:19 +01:00
Simon Ser
29cccc7ef9
carddav: add query filter support in server
Closes: https://github.com/emersion/go-webdav/issues/18
2020-01-24 16:34:57 +01:00
Simon Ser
94f47fa001
carddav: add limit support to addressbook-query
References: https://github.com/emersion/go-webdav/issues/18
2020-01-23 10:35:14 +01:00
Simon Ser
cd5945aace
carddav: add AddressBook{Query,MultiGet}.AllProp 2020-01-22 19:18:58 +01:00
Simon Ser
7e29f37bd8
carddav: add allprop and propname support to query and multiget in server 2020-01-22 18:59:01 +01:00
Simon Ser
0a251a8dfb
carddav: add AddressObject.{ModTime,ETag} 2020-01-22 15:35:36 +01:00
Simon Ser
2eb6e89979
carddav: add DELETE support to server 2020-01-22 15:16:41 +01:00
Simon Ser
aa750836d4
carddav: add PUT support to server 2020-01-22 15:14:49 +01:00
Simon Ser
bf97060e19
carddav: don't support PROPPATCH
PROPPATCH can't be used to change an address object's data. For now,
let's not support it.
2020-01-22 14:52:14 +01:00
Simon Ser
6d229f4e8a
webdav: add COPY support to server 2020-01-22 13:00:42 +01:00
Simon Ser
3268102d5a
webdav: add MOVE support to server 2020-01-22 11:43:36 +01:00
Simon Ser
6eeeccb96e
all: encode hrefs, replace hrefs with path in public API
Closes: https://github.com/emersion/go-webdav/issues/14
Closes: https://github.com/emersion/go-webdav/issues/16
2020-01-22 11:07:30 +01:00
Simon Ser
90fe8dedf7
internal: add PROPPATCH support to server 2020-01-21 23:18:27 +01:00
Simon Ser
e9e1f102de
webdav: add MKCOL support to server 2020-01-21 22:05:59 +01:00
Simon Ser
41b68829e8
webdav: add DELETE support to server 2020-01-21 21:46:01 +01:00
Simon Ser
7d6de88179
webdav: add support for PUT to server 2020-01-21 21:19:44 +01:00
Simon Ser
0469c3d389
all: add basic docs 2020-01-21 21:01:18 +01:00
Simon Ser
3a61646ab4
carddav: add current-user-principal to server 2020-01-20 10:56:25 +01:00