From 0b6e27f129ee3f69a6fa3b6b3a1ef5a60b19dc96 Mon Sep 17 00:00:00 2001 From: Caj Larsson Date: Tue, 3 May 2022 20:26:58 +0800 Subject: [PATCH] fs swampfile repo flagfile to prevent deletion of non swamp files --- infrastructure/fs/swampfile/repository.go | 31 +++++++++ .../fs/swampfile/repository_test.go | 64 +++++++++++++++++-- server/bog.go | 8 ++- 3 files changed, 96 insertions(+), 7 deletions(-) diff --git a/infrastructure/fs/swampfile/repository.go b/infrastructure/fs/swampfile/repository.go index 4d0e3d9..b26bf93 100644 --- a/infrastructure/fs/swampfile/repository.go +++ b/infrastructure/fs/swampfile/repository.go @@ -5,8 +5,11 @@ import ( "os" "path" "time" + "errors" ) +var ErrDirtyRepo = errors.New("Dirty repository without flag") + type FileSystemSwampFileData struct { path string size int64 @@ -46,6 +49,34 @@ type Repository struct { Root string } +func NewRepository(root string) (*Repository, error) { + fi, err := os.ReadDir(root) + + if err != nil { + return nil, err + } + + flagpath := path.Join(root, ".bogrepo") + + if len(fi) == 0 { + // New Repository, write flagfile + f, err := os.OpenFile(flagpath, os.O_CREATE, 0644) + if err != nil { + return nil, err + } + f.Close() + } + + flagfile, err := os.OpenFile(flagpath, os.O_RDONLY, 0) + + if err != nil { + return nil, ErrDirtyRepo + } + flagfile.Close() + return &Repository { root }, nil +} + + func (f Repository) absPath(filename string, namespace_ns string) string { return path.Join(f.Root, namespace_ns, filename) } diff --git a/infrastructure/fs/swampfile/repository_test.go b/infrastructure/fs/swampfile/repository_test.go index e658f7f..6c1102c 100644 --- a/infrastructure/fs/swampfile/repository_test.go +++ b/infrastructure/fs/swampfile/repository_test.go @@ -3,17 +3,73 @@ package swampfile import ( "caj-larsson/bog/dataswamp/swampfile" "path" + "os" "testing" + "github.com/matryer/is" ) +func newRepoDir(t *testing.T) string { + r := t.TempDir() + d := path.Join(r, "fs") + + err := os.Mkdir(d, 0755) + if err != nil { + panic(err) + } + return d +} + + func TestFsFileRepo(t *testing.T) { var fac = func() swampfile.Repository { - r := t.TempDir() - d := path.Join(r, "fs") - repo := Repository{d} - return &repo + repo, err := NewRepository(newRepoDir(t)) + + if err != nil { + panic(err) + } + return repo } swampfile.RepositoryContract(fac, t) } + + +func TestEmptyDir(t *testing.T) { + is := is.New(t) + dir_path := newRepoDir(t) + _, err := NewRepository(dir_path) + + is.NoErr(err) + + _, err = os.OpenFile(path.Join(dir_path, ".bogrepo"), os.O_RDONLY, 0) + is.NoErr(err) +} + + +func TestDirtyDir(t *testing.T) { + is := is.New(t) + dir_path := newRepoDir(t) + + _, err := os.OpenFile(path.Join(dir_path, "randomfile"), os.O_CREATE, 0644) + is.NoErr(err) + + _, err = NewRepository(dir_path) + + is.Equal(err, ErrDirtyRepo) +} + + +func TestDirtyWithFlag(t *testing.T) { + is := is.New(t) + dir_path := newRepoDir(t) + + _, err := os.OpenFile(path.Join(dir_path, "randomfile"), os.O_CREATE, 0644) + is.NoErr(err) + + _, err = os.OpenFile(path.Join(dir_path, ".bogrepo"), os.O_CREATE, 0644) + is.NoErr(err) + + _, err = NewRepository(dir_path) + is.NoErr(err) +} diff --git a/server/bog.go b/server/bog.go index dfddca8..3f65a57 100644 --- a/server/bog.go +++ b/server/bog.go @@ -24,9 +24,11 @@ type Bog struct { } func buildFileDataRepository(config FileConfig) swampfile.Repository { - fsSwampfileRepo := new(fs_swampfile.Repository) - fsSwampfileRepo.Root = config.Path - return fsSwampfileRepo + r, err := fs_swampfile.NewRepository(config.Path) + if err != nil { + panic(err) + } + return r } func buildUserAgentRepository(config DatabaseConfig) namespace.Repository {