storage: adapt to go-webdav interface changes
This commit is contained in:
parent
39f90686f9
commit
adb2a8bdfb
@ -225,6 +225,10 @@ func (b *filesystemBackend) GetCalendar(ctx context.Context, urlPath string) (*c
|
|||||||
return &calendar, nil
|
return &calendar, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *filesystemBackend) CreateCalendar(ctx context.Context, calendar *caldav.Calendar) error {
|
||||||
|
panic("TODO")
|
||||||
|
}
|
||||||
|
|
||||||
func (b *filesystemBackend) GetCalendarObject(ctx context.Context, objPath string, req *caldav.CalendarCompRequest) (*caldav.CalendarObject, error) {
|
func (b *filesystemBackend) GetCalendarObject(ctx context.Context, objPath string, req *caldav.CalendarCompRequest) (*caldav.CalendarObject, error) {
|
||||||
log.Debug().Str("path", objPath).Msg("filesystem.GetCalendarObject()")
|
log.Debug().Str("path", objPath).Msg("filesystem.GetCalendarObject()")
|
||||||
|
|
||||||
@ -299,12 +303,12 @@ func (b *filesystemBackend) QueryCalendarObjects(ctx context.Context, urlPath st
|
|||||||
return filtered, err
|
return filtered, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *filesystemBackend) PutCalendarObject(ctx context.Context, objPath string, calendar *ical.Calendar, opts *caldav.PutCalendarObjectOptions) (loc string, err error) {
|
func (b *filesystemBackend) PutCalendarObject(ctx context.Context, objPath string, calendar *ical.Calendar, opts *caldav.PutCalendarObjectOptions) (*caldav.CalendarObject, error) {
|
||||||
log.Debug().Str("path", objPath).Msg("filesystem.PutCalendarObject()")
|
log.Debug().Str("path", objPath).Msg("filesystem.PutCalendarObject()")
|
||||||
|
|
||||||
_, uid, err := caldav.ValidateCalendarObject(calendar)
|
_, uid, err := caldav.ValidateCalendarObject(calendar)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", caldav.NewPreconditionError(caldav.PreconditionValidCalendarObjectResource)
|
return nil, caldav.NewPreconditionError(caldav.PreconditionValidCalendarObjectResource)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Object always get saved as <UID>.ics
|
// Object always get saved as <UID>.ics
|
||||||
@ -313,7 +317,7 @@ func (b *filesystemBackend) PutCalendarObject(ctx context.Context, objPath strin
|
|||||||
|
|
||||||
localPath, err := b.safeLocalCalDAVPath(ctx, objPath)
|
localPath, err := b.safeLocalCalDAVPath(ctx, objPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
flags := os.O_RDWR | os.O_CREATE | os.O_TRUNC
|
flags := os.O_RDWR | os.O_CREATE | os.O_TRUNC
|
||||||
@ -328,33 +332,49 @@ func (b *filesystemBackend) PutCalendarObject(ctx context.Context, objPath strin
|
|||||||
// Make sure we overwrite the _right_ file
|
// Make sure we overwrite the _right_ file
|
||||||
etag, err := etagForFile(localPath)
|
etag, err := etagForFile(localPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", webdav.NewHTTPError(http.StatusPreconditionFailed, err)
|
return nil, webdav.NewHTTPError(http.StatusPreconditionFailed, err)
|
||||||
}
|
}
|
||||||
want, err := opts.IfMatch.ETag()
|
want, err := opts.IfMatch.ETag()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", webdav.NewHTTPError(http.StatusBadRequest, err)
|
return nil, webdav.NewHTTPError(http.StatusBadRequest, err)
|
||||||
}
|
}
|
||||||
if want != etag {
|
if want != etag {
|
||||||
err = fmt.Errorf("If-Match does not match current ETag (%s/%s)", want, etag)
|
err = fmt.Errorf("If-Match does not match current ETag (%s/%s)", want, etag)
|
||||||
return "", webdav.NewHTTPError(http.StatusPreconditionFailed, err)
|
return nil, webdav.NewHTTPError(http.StatusPreconditionFailed, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
f, err := os.OpenFile(localPath, flags, 0666)
|
f, err := os.OpenFile(localPath, flags, 0666)
|
||||||
if os.IsExist(err) {
|
if os.IsExist(err) {
|
||||||
return "", caldav.NewPreconditionError(caldav.PreconditionNoUIDConflict)
|
return nil, caldav.NewPreconditionError(caldav.PreconditionNoUIDConflict)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return "", err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
|
|
||||||
enc := ical.NewEncoder(f)
|
enc := ical.NewEncoder(f)
|
||||||
err = enc.Encode(calendar)
|
err = enc.Encode(calendar)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return objPath, nil
|
etag, err := etagForFile(localPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
info, err := f.Stat()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
r := caldav.CalendarObject{
|
||||||
|
Path: objPath,
|
||||||
|
ModTime: info.ModTime(),
|
||||||
|
ContentLength: info.Size(),
|
||||||
|
ETag: etag,
|
||||||
|
Data: calendar,
|
||||||
|
}
|
||||||
|
return &r, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *filesystemBackend) DeleteCalendarObject(ctx context.Context, path string) error {
|
func (b *filesystemBackend) DeleteCalendarObject(ctx context.Context, path string) error {
|
||||||
|
@ -129,22 +129,51 @@ func (b *filesystemBackend) loadAllAddressObjects(ctx context.Context, urlPath s
|
|||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *filesystemBackend) createDefaultAddressBook(ctx context.Context) (*carddav.AddressBook, error) {
|
func (b *filesystemBackend) writeAddressBook(ctx context.Context, ab *carddav.AddressBook) error {
|
||||||
// TODO what should the default address book look like?
|
localPath, err := b.safeLocalCardDAVPath(ctx, ab.Path)
|
||||||
localPath, err_ := b.localCardDAVDir(ctx, defaultResourceName)
|
if err != nil {
|
||||||
if err_ != nil {
|
return err
|
||||||
return nil, fmt.Errorf("error creating default address book: %s", err_.Error())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
homeSetPath, err_ := b.AddressBookHomeSetPath(ctx)
|
log.Debug().Str("local", localPath).Str("url", ab.Path).Msg("filesystem.writeAddressBook()")
|
||||||
if err_ != nil {
|
|
||||||
return nil, fmt.Errorf("error creating default address book: %s", err_.Error())
|
blob, err := json.MarshalIndent(ab, "", " ")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return os.WriteFile(path.Join(localPath, addressBookFileName), blob, 0644)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error writing address book: %s", err.Error())
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *filesystemBackend) createAddressBook(ctx context.Context, ab *carddav.AddressBook) error {
|
||||||
|
localPath, err := b.safeLocalCardDAVPath(ctx, ab.Path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debug().Str("local", localPath).Str("url", ab.Path).Msg("filesystem.createAddressBook()")
|
||||||
|
|
||||||
|
err = os.Mkdir(localPath, 0755)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error creating address book: %s", err.Error())
|
||||||
|
}
|
||||||
|
return b.writeAddressBook(ctx, ab)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *filesystemBackend) createDefaultAddressBook(ctx context.Context) (*carddav.AddressBook, error) {
|
||||||
|
log.Debug().Msg("filesystem.createDefaultAddressBook()")
|
||||||
|
|
||||||
|
homeSetPath, err := b.AddressBookHomeSetPath(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error creating default address book: %s", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
urlPath := path.Join(homeSetPath, defaultResourceName) + "/"
|
urlPath := path.Join(homeSetPath, defaultResourceName) + "/"
|
||||||
|
|
||||||
log.Debug().Str("local", localPath).Str("url", urlPath).Msg("filesystem.createDefaultAddressBook()")
|
// TODO what should the default address book look like?
|
||||||
|
|
||||||
defaultAB := carddav.AddressBook{
|
defaultAB := carddav.AddressBook{
|
||||||
Path: urlPath,
|
Path: urlPath,
|
||||||
Name: "My contacts",
|
Name: "My contacts",
|
||||||
@ -152,14 +181,8 @@ func (b *filesystemBackend) createDefaultAddressBook(ctx context.Context) (*card
|
|||||||
MaxResourceSize: 1024,
|
MaxResourceSize: 1024,
|
||||||
SupportedAddressData: nil,
|
SupportedAddressData: nil,
|
||||||
}
|
}
|
||||||
blob, err := json.MarshalIndent(defaultAB, "", " ")
|
err = b.createAddressBook(ctx, &defaultAB)
|
||||||
if err != nil {
|
log.Debug().Err(err).Msg("filesystem.createDefaultAddressBook() done")
|
||||||
return nil, fmt.Errorf("error creating default address book: %s", err.Error())
|
|
||||||
}
|
|
||||||
err = os.WriteFile(path.Join(localPath, addressBookFileName), blob, 0644)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("error writing default address book: %s", err.Error())
|
|
||||||
}
|
|
||||||
return &defaultAB, nil
|
return &defaultAB, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,6 +266,35 @@ func (b *filesystemBackend) GetAddressBook(ctx context.Context, urlPath string)
|
|||||||
return &addressBook, nil
|
return &addressBook, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *filesystemBackend) CreateAddressBook(ctx context.Context, ab *carddav.AddressBook) error {
|
||||||
|
log.Debug().Str("path", ab.Path).Msg("filesystem.CreateAddressBook()")
|
||||||
|
ab.MaxResourceSize = 4096
|
||||||
|
err := b.createAddressBook(ctx, ab)
|
||||||
|
log.Debug().Err(err).Msg("filesystem.CreateAddressBook() done")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *filesystemBackend) UpdateAddressBook(ctx context.Context, ab *carddav.AddressBook) error {
|
||||||
|
log.Debug().Str("path", ab.Path).Msg("filesystem.UpdateAddressBook()")
|
||||||
|
ab.MaxResourceSize = 4096
|
||||||
|
err := b.writeAddressBook(ctx, ab)
|
||||||
|
log.Debug().Err(err).Msg("filesystem.UpdateAddressBook() done")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *filesystemBackend) DeleteAddressBook(ctx context.Context, urlPath string) error {
|
||||||
|
log.Debug().Str("path", urlPath).Msg("filesystem.DeleteAddressBook()")
|
||||||
|
|
||||||
|
localPath, err := b.safeLocalCardDAVPath(ctx, urlPath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
log.Debug().Str("path", localPath).Msg("deleting addressbook")
|
||||||
|
err = os.RemoveAll(localPath)
|
||||||
|
log.Debug().Err(err).Msg("filesystem.DeleteAddressBook() done")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
func (b *filesystemBackend) GetAddressObject(ctx context.Context, objPath string, req *carddav.AddressDataRequest) (*carddav.AddressObject, error) {
|
func (b *filesystemBackend) GetAddressObject(ctx context.Context, objPath string, req *carddav.AddressDataRequest) (*carddav.AddressObject, error) {
|
||||||
log.Debug().Str("path", objPath).Msg("filesystem.GetAddressObject()")
|
log.Debug().Str("path", objPath).Msg("filesystem.GetAddressObject()")
|
||||||
|
|
||||||
@ -317,7 +369,7 @@ func (b *filesystemBackend) QueryAddressObjects(ctx context.Context, urlPath str
|
|||||||
return filtered, err
|
return filtered, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *filesystemBackend) PutAddressObject(ctx context.Context, objPath string, card vcard.Card, opts *carddav.PutAddressObjectOptions) (loc string, err error) {
|
func (b *filesystemBackend) PutAddressObject(ctx context.Context, objPath string, card vcard.Card, opts *carddav.PutAddressObjectOptions) (*carddav.AddressObject, error) {
|
||||||
log.Debug().Str("path", objPath).Msg("filesystem.PutAddressObject()")
|
log.Debug().Str("path", objPath).Msg("filesystem.PutAddressObject()")
|
||||||
|
|
||||||
// Object always get saved as <UID>.vcf
|
// Object always get saved as <UID>.vcf
|
||||||
@ -326,7 +378,7 @@ func (b *filesystemBackend) PutAddressObject(ctx context.Context, objPath string
|
|||||||
|
|
||||||
localPath, err := b.safeLocalCardDAVPath(ctx, objPath)
|
localPath, err := b.safeLocalCardDAVPath(ctx, objPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
flags := os.O_RDWR | os.O_CREATE | os.O_TRUNC
|
flags := os.O_RDWR | os.O_CREATE | os.O_TRUNC
|
||||||
@ -341,33 +393,48 @@ func (b *filesystemBackend) PutAddressObject(ctx context.Context, objPath string
|
|||||||
// Make sure we overwrite the _right_ file
|
// Make sure we overwrite the _right_ file
|
||||||
etag, err := etagForFile(localPath)
|
etag, err := etagForFile(localPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", webdav.NewHTTPError(http.StatusPreconditionFailed, err)
|
return nil, webdav.NewHTTPError(http.StatusPreconditionFailed, err)
|
||||||
}
|
}
|
||||||
want, err := opts.IfMatch.ETag()
|
want, err := opts.IfMatch.ETag()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", webdav.NewHTTPError(http.StatusBadRequest, err)
|
return nil, webdav.NewHTTPError(http.StatusBadRequest, err)
|
||||||
}
|
}
|
||||||
if want != etag {
|
if want != etag {
|
||||||
err = fmt.Errorf("If-Match does not match current ETag (%s/%s)", want, etag)
|
err = fmt.Errorf("If-Match does not match current ETag (%s/%s)", want, etag)
|
||||||
return "", webdav.NewHTTPError(http.StatusPreconditionFailed, err)
|
return nil, webdav.NewHTTPError(http.StatusPreconditionFailed, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
f, err := os.OpenFile(localPath, flags, 0666)
|
f, err := os.OpenFile(localPath, flags, 0666)
|
||||||
if os.IsExist(err) {
|
if os.IsExist(err) {
|
||||||
return "", carddav.NewPreconditionError(carddav.PreconditionNoUIDConflict)
|
return nil, carddav.NewPreconditionError(carddav.PreconditionNoUIDConflict)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return "", err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
|
|
||||||
enc := vcard.NewEncoder(f)
|
enc := vcard.NewEncoder(f)
|
||||||
err = enc.Encode(card)
|
if err := enc.Encode(card); err != nil {
|
||||||
if err != nil {
|
return nil, err
|
||||||
return "", err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return objPath, nil
|
etag, err := etagForFile(localPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
info, err := f.Stat()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
r := carddav.AddressObject{
|
||||||
|
Path: objPath,
|
||||||
|
ModTime: info.ModTime(),
|
||||||
|
ContentLength: info.Size(),
|
||||||
|
ETag: etag,
|
||||||
|
Card: card,
|
||||||
|
}
|
||||||
|
return &r, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *filesystemBackend) DeleteAddressObject(ctx context.Context, path string) error {
|
func (b *filesystemBackend) DeleteAddressObject(ctx context.Context, path string) error {
|
||||||
|
@ -32,6 +32,18 @@ func (*psqlBackend) GetAddressBook(ctx context.Context, path string) (*carddav.A
|
|||||||
panic("TODO")
|
panic("TODO")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*psqlBackend) CreateAddressBook(ctx context.Context, ab *carddav.AddressBook) error {
|
||||||
|
panic("TODO")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*psqlBackend) UpdateAddressBook(ctx context.Context, ab *carddav.AddressBook) error {
|
||||||
|
panic("TODO")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*psqlBackend) DeleteAddressBook(ctx context.Context, path string) error {
|
||||||
|
panic("TODO")
|
||||||
|
}
|
||||||
|
|
||||||
func (*psqlBackend) GetAddressObject(ctx context.Context, path string, req *carddav.AddressDataRequest) (*carddav.AddressObject, error) {
|
func (*psqlBackend) GetAddressObject(ctx context.Context, path string, req *carddav.AddressDataRequest) (*carddav.AddressObject, error) {
|
||||||
panic("TODO")
|
panic("TODO")
|
||||||
}
|
}
|
||||||
@ -44,7 +56,7 @@ func (*psqlBackend) QueryAddressObjects(ctx context.Context, path string, query
|
|||||||
panic("TODO")
|
panic("TODO")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*psqlBackend) PutAddressObject(ctx context.Context, path string, card vcard.Card, opts *carddav.PutAddressObjectOptions) (loc string, err error) {
|
func (*psqlBackend) PutAddressObject(ctx context.Context, path string, card vcard.Card, opts *carddav.PutAddressObjectOptions) (*carddav.AddressObject, error) {
|
||||||
panic("TODO")
|
panic("TODO")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user