diff --git a/cassandane/Cassandane/Cyrus/Carddav.pm b/cassandane/Cassandane/Cyrus/Carddav.pm index 893a233dc7..4303992bea 100644 --- a/cassandane/Cassandane/Cyrus/Carddav.pm +++ b/cassandane/Cassandane/Cyrus/Carddav.pm @@ -1450,4 +1450,27 @@ EOF $self->assert_matches(qr/2500 members/, $value); } +sub test_delete_default_addressbook + :min_version_3_6 :needs_component_httpd +{ + my ($self) = @_; + + my $CardDAV = $self->{carddav}; + + my %Headers = ( + 'Authorization' => $CardDAV->auth_header() + ); + + my $Id = $CardDAV->NewAddressBook('foo'); + $self->assert_not_null($Id); + + my $href = $CardDAV->request_url($Id); + my $res = $CardDAV->ua->request('DELETE', $href, { headers => \%Headers }); + $self->assert_num_equals(204, $res->{status}); + + $href = $CardDAV->request_url('Default'); + $res = $CardDAV->ua->request('DELETE', $href, { headers => \%Headers }); + $self->assert_num_equals(405, $res->{status}); +} + 1; diff --git a/imap/http_carddav.c b/imap/http_carddav.c index 64c31ef981..065ce4d893 100644 --- a/imap/http_carddav.c +++ b/imap/http_carddav.c @@ -587,9 +587,19 @@ static void my_carddav_shutdown(void) static int carddav_parse_path(const char *path, struct request_target_t *tgt, const char **resultstr) { - return calcarddav_parse_path(path, tgt, - config_getstring(IMAPOPT_ADDRESSBOOKPREFIX), - resultstr); + int r = calcarddav_parse_path(path, tgt, + config_getstring(IMAPOPT_ADDRESSBOOKPREFIX), + resultstr); + if (r) return r; + + if (!tgt->resource && + !strncmpsafe(tgt->collection, + DEFAULT_ADDRBOOK "/", strlen(DEFAULT_ADDRBOOK)+1)) { + /* Can't delete default addressbook */ + tgt->allow &= ~ALLOW_DELETE; + } + + return 0; } #ifdef HAVE_LIBICALVCARD