Start simple filesystem storage backend
This commit is contained in:
parent
3281b1d32b
commit
d917938a29
@ -41,7 +41,11 @@ func main() {
|
|||||||
}
|
}
|
||||||
mux.Use(authProvider.Middleware())
|
mux.Use(authProvider.Middleware())
|
||||||
|
|
||||||
backend := storage.NewPostgreSQL()
|
//backend := storage.NewPostgreSQL()
|
||||||
|
backend, err := storage.NewFilesystem("./teststorage")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("failed to load storage backend: %s", err.Error())
|
||||||
|
}
|
||||||
mux.Mount("/", &carddav.Handler{Backend: backend})
|
mux.Mount("/", &carddav.Handler{Backend: backend})
|
||||||
|
|
||||||
server := http.Server{
|
server := http.Server{
|
||||||
|
@ -1,42 +1,134 @@
|
|||||||
package storage
|
package storage
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/emersion/go-vcard"
|
"github.com/emersion/go-vcard"
|
||||||
"github.com/emersion/go-webdav/carddav"
|
"github.com/emersion/go-webdav/carddav"
|
||||||
|
|
||||||
|
"git.sr.ht/~sircmpwn/tokidoki/auth"
|
||||||
)
|
)
|
||||||
|
|
||||||
type filesystemBackend struct {
|
type filesystemBackend struct {
|
||||||
path string
|
path string
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ carddav.Backend = (*filesystemBackend)(nil)
|
var nilBackend carddav.Backend = (*filesystemBackend)(nil)
|
||||||
|
|
||||||
func NewfilesystemBackend(path string) carddav.Backend {
|
func NewFilesystem(path string) (carddav.Backend, error) {
|
||||||
|
info, err := os.Stat(path)
|
||||||
|
if err != nil {
|
||||||
|
return nilBackend, fmt.Errorf("failed to create filesystem backend: %s", err.Error())
|
||||||
|
}
|
||||||
|
if !info.IsDir() {
|
||||||
|
return nilBackend, fmt.Errorf("base path for filesystem backend must be a directory")
|
||||||
|
}
|
||||||
return &filesystemBackend{
|
return &filesystemBackend{
|
||||||
path: path,
|
path: path,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *filesystemBackend) pathForContext(ctx context.Context) (string, error) {
|
||||||
|
raw := ctx.Value(auth.AuthCtxKey)
|
||||||
|
if raw == nil {
|
||||||
|
return b.path, nil
|
||||||
}
|
}
|
||||||
|
authCtx, ok := raw.(*auth.AuthContext)
|
||||||
|
if !ok {
|
||||||
|
panic("Invalid data in auth context!")
|
||||||
|
}
|
||||||
|
//TODO sanitize user name or at least check if valid dir name?
|
||||||
|
path := filepath.Join(b.path, authCtx.UserName)
|
||||||
|
|
||||||
|
_, err := os.Stat(path)
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
err = os.Mkdir(path, 0755)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("error creating '%s': %s", path, err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return path, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*filesystemBackend) AddressBook() (*carddav.AddressBook, error) {
|
func createDefaultAddressBook(path string) error {
|
||||||
panic("TODO")
|
// TODO what should the default address book look like?
|
||||||
|
defaultAB := carddav.AddressBook{
|
||||||
|
Path: "/default",
|
||||||
|
Name: "My contacts",
|
||||||
|
Description: "Default address book",
|
||||||
|
MaxResourceSize: 1024,
|
||||||
|
SupportedAddressData: []carddav.AddressDataType{},
|
||||||
|
}
|
||||||
|
blob, err := json.MarshalIndent(defaultAB, "", " ")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error creating default address book: %s", err.Error())
|
||||||
|
}
|
||||||
|
err = os.WriteFile(path, blob, 0644)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error writing default address book: %s", err.Error())
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*filesystemBackend) GetAddressObject(path string, req *carddav.AddressDataRequest) (*carddav.AddressObject, error) {
|
func (b *filesystemBackend) AddressBook(ctx context.Context) (*carddav.AddressBook, error) {
|
||||||
panic("TODO")
|
path, err := b.pathForContext(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
path = filepath.Join(path, "default.json")
|
||||||
|
_, err = os.Stat(path)
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
err = createDefaultAddressBook(path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
} else if err != nil {
|
||||||
|
return nil, fmt.Errorf("error opening address book: %s", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := ioutil.ReadFile(path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error opening address book: %s", err.Error())
|
||||||
|
}
|
||||||
|
var addressBook carddav.AddressBook
|
||||||
|
err = json.Unmarshal(data, &addressBook)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error reading address book: %s", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return &addressBook, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*filesystemBackend) ListAddressObjects(req *carddav.AddressDataRequest) ([]carddav.AddressObject, error) {
|
func (*filesystemBackend) GetAddressObject(ctx context.Context, path string, req *carddav.AddressDataRequest) (*carddav.AddressObject, error) {
|
||||||
panic("TODO")
|
//TODO
|
||||||
|
log.Fatalf("PutAddressObject(ctx, '%s', req): not implemented", path)
|
||||||
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*filesystemBackend) QueryAddressObjects(query *carddav.AddressBookQuery) ([]carddav.AddressObject, error) {
|
func (*filesystemBackend) ListAddressObjects(ctx context.Context, req *carddav.AddressDataRequest) ([]carddav.AddressObject, error) {
|
||||||
panic("TODO")
|
return []carddav.AddressObject{}, nil
|
||||||
|
//panic("TODO")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*filesystemBackend) PutAddressObject(path string, card vcard.Card) (loc string, err error) {
|
func (*filesystemBackend) QueryAddressObjects(ctx context.Context, query *carddav.AddressBookQuery) ([]carddav.AddressObject, error) {
|
||||||
panic("TODO")
|
return []carddav.AddressObject{}, nil
|
||||||
|
//panic("TODO")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*filesystemBackend) DeleteAddressObject(path string) error {
|
func (*filesystemBackend) PutAddressObject(ctx context.Context, path string, card vcard.Card) (loc string, err error) {
|
||||||
panic("TODO")
|
//TODO
|
||||||
|
log.Fatalf("PutAddressObject(ctx, '%s', card): not implemented", path)
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*filesystemBackend) DeleteAddressObject(ctx context.Context, path string) error {
|
||||||
|
//TODO
|
||||||
|
log.Fatalf("DeleteAddressObject(ctx, '%s'): not implemented", path)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user