diff --git a/storage/filesystem.go b/storage/filesystem.go index 3ad71fd..f9bf934 100644 --- a/storage/filesystem.go +++ b/storage/filesystem.go @@ -178,7 +178,7 @@ func (b *filesystemBackend) GetAddressObject(ctx context.Context, path string, r return nil, err } - propFilter := []string{} + var propFilter []string if req != nil && !req.AllProp { propFilter = req.Props } @@ -194,10 +194,10 @@ func (b *filesystemBackend) GetAddressObject(ctx context.Context, path string, r } obj := carddav.AddressObject{ - Path: path, + Path: path, ModTime: info.ModTime(), - ETag: etag, - Card: *card, + ETag: etag, + Card: *card, } return &obj, nil } @@ -227,10 +227,10 @@ func (b *filesystemBackend) loadAll(ctx context.Context, propFilter []string) ([ } obj := carddav.AddressObject{ - Path: "/" + filepath.Base(filename), + Path: "/" + filepath.Base(filename), ModTime: info.ModTime(), - ETag: etag, - Card: *card, + ETag: etag, + Card: *card, } result = append(result, obj) return nil @@ -240,7 +240,7 @@ func (b *filesystemBackend) loadAll(ctx context.Context, propFilter []string) ([ } func (b *filesystemBackend) ListAddressObjects(ctx context.Context, req *carddav.AddressDataRequest) ([]carddav.AddressObject, error) { - propFilter := []string{} + var propFilter []string if req != nil && !req.AllProp { propFilter = req.Props } @@ -249,7 +249,7 @@ func (b *filesystemBackend) ListAddressObjects(ctx context.Context, req *carddav } func (b *filesystemBackend) QueryAddressObjects(ctx context.Context, query *carddav.AddressBookQuery) ([]carddav.AddressObject, error) { - propFilter := []string{} + var propFilter []string if query != nil && !query.DataRequest.AllProp { propFilter = query.DataRequest.Props } @@ -262,11 +262,34 @@ func (b *filesystemBackend) QueryAddressObjects(ctx context.Context, query *card return carddav.Filter(query, result) } +func (b *filesystemBackend) hasUIDConflict(ctx context.Context, uid, path string) (bool, error) { + all, err := b.loadAll(ctx, nil) + if err != nil { + return false, err + } + for _, contact := range all { + if contact.Path != path && contact.Card.Value(vcard.FieldUID) == uid { + return true, nil + } + } + + return false, nil +} + func (b *filesystemBackend) PutAddressObject(ctx context.Context, path string, card vcard.Card) (loc string, err error) { localPath, err := b.safePath(ctx, path) if err != nil { return "", err } + + conflict, err := b.hasUIDConflict(ctx, card.Value(vcard.FieldUID), path) + if err != nil { + return "", err + } + if conflict { + return "", carddav.NewPreconditionError(carddav.PreconditionNoUIDConflict) + } + f, err := os.OpenFile(localPath, os.O_RDWR|os.O_CREATE, 0644) if err != nil { return "", err