From 8131a2270432c6e28954a3572a73edd4b33aedd6 Mon Sep 17 00:00:00 2001 From: Ayman Bagabas Date: Mon, 27 Mar 2023 15:10:20 -0400 Subject: [PATCH] fix(backend): use subdir collabs path --- server/backend/file/file.go | 146 +++++++++--------------------------- server/backend/file/repo.go | 4 +- server/backend/noop/noop.go | 35 ++------- server/backend/server.go | 13 ---- 4 files changed, 41 insertions(+), 157 deletions(-) diff --git a/server/backend/file/file.go b/server/backend/file/file.go index 84d2f2db5e605ed873eeff54cddd7b9229284494..8ec6523a2f037deb0b9eb17d062724930c2eab38 100644 --- a/server/backend/file/file.go +++ b/server/backend/file/file.go @@ -26,7 +26,6 @@ import ( "io/fs" "os" "path/filepath" - "strconv" "strings" "github.com/charmbracelet/log" @@ -41,13 +40,11 @@ const ( anonAccess = "anon-access" allowKeyless = "allow-keyless" admins = "admins" - serverHost = "host" - serverName = "name" - serverPort = "port" repos = "repos" collabs = "collaborators" description = "description" exportOk = "git-daemon-export-ok" + private = "private" settings = "settings" ) @@ -55,9 +52,6 @@ var ( logger = log.WithPrefix("backend.file") defaults = map[string]string{ - serverName: "Soft Serve", - serverHost: "localhost", - serverPort: "23231", anonAccess: backend.ReadOnlyAccess.String(), allowKeyless: "true", } @@ -94,7 +88,7 @@ func (fb *FileBackend) adminsPath() string { } func (fb *FileBackend) collabsPath(repo string) string { - return filepath.Join(fb.path, collabs, repo) + return filepath.Join(fb.path, collabs, repo, collabs) } func sanatizeRepo(repo string) string { @@ -136,7 +130,8 @@ func NewFileBackend(path string) (*FileBackend, error) { return nil, err } } - for _, file := range []string{admins, anonAccess, allowKeyless, serverHost, serverName, serverPort} { + + for _, file := range []string{admins, anonAccess, allowKeyless} { fp := filepath.Join(fb.settingsPath(), file) _, err := os.Stat(fp) if errors.Is(err, fs.ErrNotExist) { @@ -216,28 +211,29 @@ func (fb *FileBackend) AddAdmin(pk gossh.PublicKey, memo string) error { // AddCollaborator adds a public key to the list of collaborators for the given repo. // // It implements backend.Backend. -func (fb *FileBackend) AddCollaborator(pk gossh.PublicKey, memo string, name string) error { +func (fb *FileBackend) AddCollaborator(pk gossh.PublicKey, memo string, repo string) error { + name := sanatizeRepo(repo) + repo = name + ".git" // Check if repo exists - if !exists(filepath.Join(fb.reposPath(), sanatizeRepo(name)+".git")) { - return fmt.Errorf("repository %s does not exist", name) + if !exists(filepath.Join(fb.reposPath(), repo)) { + return fmt.Errorf("repository %s does not exist", repo) } // Skip if the key already exists. - if fb.IsCollaborator(pk, name) { + if fb.IsCollaborator(pk, repo) { return fmt.Errorf("key already exists") } ak := backend.MarshalAuthorizedKey(pk) - name = sanatizeRepo(name) - if err := os.MkdirAll(filepath.Dir(fb.collabsPath(name)), 0755); err != nil { + if err := os.MkdirAll(filepath.Dir(fb.collabsPath(repo)), 0755); err != nil { logger.Debug("failed to create collaborators directory", - "err", err, "path", filepath.Dir(fb.collabsPath(name))) + "err", err, "path", filepath.Dir(fb.collabsPath(repo))) return err } - f, err := os.OpenFile(fb.collabsPath(name), os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0644) + f, err := os.OpenFile(fb.collabsPath(repo), os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0644) if err != nil { - logger.Debug("failed to open collaborators file", "err", err, "path", fb.collabsPath(name)) + logger.Debug("failed to open collaborators file", "err", err, "path", fb.collabsPath(repo)) return err } @@ -273,8 +269,10 @@ func (fb *FileBackend) Admins() ([]string, error) { // // It implements backend.Backend. func (fb *FileBackend) Collaborators(repo string) ([]string, error) { + name := sanatizeRepo(repo) + repo = name + ".git" // Check if repo exists - if !exists(filepath.Join(fb.reposPath(), sanatizeRepo(repo)+".git")) { + if !exists(filepath.Join(fb.reposPath(), repo)) { return nil, fmt.Errorf("repository %s does not exist", repo) } @@ -297,7 +295,9 @@ func (fb *FileBackend) Collaborators(repo string) ([]string, error) { return collabs, s.Err() } -// RemoveAdmin implements backend.Backend +// RemoveAdmin removes a public key from the list of server admins. +// +// It implements backend.Backend. func (fb *FileBackend) RemoveAdmin(pk gossh.PublicKey) error { f, err := os.OpenFile(fb.adminsPath(), os.O_RDWR, 0644) if err != nil { @@ -350,8 +350,10 @@ func (fb *FileBackend) RemoveAdmin(pk gossh.PublicKey) error { // // It implements backend.Backend. func (fb *FileBackend) RemoveCollaborator(pk gossh.PublicKey, repo string) error { + name := sanatizeRepo(repo) + repo = name + ".git" // Check if repo exists - if !exists(filepath.Join(fb.reposPath(), sanatizeRepo(repo)+".git")) { + if !exists(filepath.Join(fb.reposPath(), repo)) { return fmt.Errorf("repository %s does not exist", repo) } @@ -489,16 +491,16 @@ func (fb *FileBackend) IsAdmin(pk gossh.PublicKey) bool { // given repo. // // It implements backend.Backend. -func (fb *FileBackend) IsCollaborator(pk gossh.PublicKey, name string) bool { - name = sanatizeRepo(name) - _, err := os.Stat(fb.collabsPath(name)) +func (fb *FileBackend) IsCollaborator(pk gossh.PublicKey, repo string) bool { + repo = sanatizeRepo(repo) + ".git" + _, err := os.Stat(fb.collabsPath(repo)) if err != nil { return false } - f, err := os.Open(fb.collabsPath(name)) + f, err := os.Open(fb.collabsPath(repo)) if err != nil { - logger.Debug("failed to open collaborators file", "err", err, "path", fb.collabsPath(name)) + logger.Debug("failed to open collaborators file", "err", err, "path", fb.collabsPath(repo)) return false } @@ -526,50 +528,6 @@ func (fb *FileBackend) IsPrivate(repo string) bool { return r.IsPrivate() } -// ServerHost returns the server host. -// -// It implements backend.Backend. -func (fb *FileBackend) ServerHost() string { - line, err := readOneLine(filepath.Join(fb.settingsPath(), serverHost)) - if err != nil { - logger.Debug("failed to read server-host file", "err", err) - return "" - } - - return line -} - -// ServerName returns the server name. -// -// It implements backend.Backend. -func (fb *FileBackend) ServerName() string { - line, err := readOneLine(filepath.Join(fb.settingsPath(), serverName)) - if err != nil { - logger.Debug("failed to read server-name file", "err", err) - return "" - } - - return line -} - -// ServerPort returns the server port. -// -// It implements backend.Backend. -func (fb *FileBackend) ServerPort() string { - line, err := readOneLine(filepath.Join(fb.settingsPath(), serverPort)) - if err != nil { - logger.Debug("failed to read server-port file", "err", err) - return "" - } - - if _, err := strconv.Atoi(line); err != nil { - logger.Debug("failed to parse server-port file", "err", err) - return "" - } - - return line -} - // SetAllowKeyless sets whether or not to allow keyless access. // // It implements backend.Backend. @@ -621,6 +579,12 @@ func (fb *FileBackend) SetPrivate(repo string, priv bool) error { daemonExport := filepath.Join(fb.reposPath(), repo, exportOk) if priv { _ = os.Remove(daemonExport) + f, err := os.Create(filepath.Join(fb.reposPath(), repo, private)) + if err != nil { + return fmt.Errorf("failed to create private file: %w", err) + } + + _ = f.Close() //nolint:errcheck } else { // Create git-daemon-export-ok file if repo is public. f, err := os.Create(daemonExport) @@ -633,48 +597,6 @@ func (fb *FileBackend) SetPrivate(repo string, priv bool) error { return nil } -// SetServerHost sets the server host. -// -// It implements backend.Backend. -func (fb *FileBackend) SetServerHost(host string) error { - f, err := os.Create(filepath.Join(fb.settingsPath(), serverHost)) - if err != nil { - return fmt.Errorf("failed to create server-host file: %w", err) - } - - defer f.Close() //nolint:errcheck - _, err = fmt.Fprintln(f, host) - return err -} - -// SetServerName sets the server name. -// -// It implements backend.Backend. -func (fb *FileBackend) SetServerName(name string) error { - f, err := os.Create(filepath.Join(fb.settingsPath(), serverName)) - if err != nil { - return fmt.Errorf("failed to create server-name file: %w", err) - } - - defer f.Close() //nolint:errcheck - _, err = fmt.Fprintln(f, name) - return err -} - -// SetServerPort sets the server port. -// -// It implements backend.Backend. -func (fb *FileBackend) SetServerPort(port string) error { - f, err := os.Create(filepath.Join(fb.settingsPath(), serverPort)) - if err != nil { - return fmt.Errorf("failed to create server-port file: %w", err) - } - - defer f.Close() //nolint:errcheck - _, err = fmt.Fprintln(f, port) - return err -} - // CreateRepository creates a new repository. // // Created repositories are always bare. diff --git a/server/backend/file/repo.go b/server/backend/file/repo.go index 0697b51d0d420fd462ab781819b9f841033b404c..6e760d4295ea089d1951192ca369c1484e70038c 100644 --- a/server/backend/file/repo.go +++ b/server/backend/file/repo.go @@ -45,8 +45,8 @@ func (r *Repo) Description() string { // // It implements backend.Repository. func (r *Repo) IsPrivate() bool { - _, err := os.Stat(filepath.Join(r.path, exportOk)) - return err != nil + _, err := os.Stat(filepath.Join(r.path, private)) + return err == nil } // Open returns the underlying git.Repository. diff --git a/server/backend/noop/noop.go b/server/backend/noop/noop.go index 45cf143964aeb2e7f1ba098c0f061b064f06fde5..b91ffbee395e9daca5a465a61175d33a90c119e4 100644 --- a/server/backend/noop/noop.go +++ b/server/backend/noop/noop.go @@ -21,6 +21,11 @@ type Noop struct { Port string } +// RepositoryStorePath implements backend.Backend +func (*Noop) RepositoryStorePath() string { + return "" +} + // Admins implements backend.Backend func (*Noop) Admins() ([]string, error) { return nil, nil @@ -122,21 +127,6 @@ func (*Noop) Repository(repo string) (backend.Repository, error) { return nil, ErrNotImpl } -// ServerHost implements backend.Backend -func (*Noop) ServerHost() string { - return "localhost" -} - -// ServerName implements backend.Backend -func (*Noop) ServerName() string { - return "Soft Serve" -} - -// ServerPort implements backend.Backend -func (n *Noop) ServerPort() string { - return n.Port -} - // SetAllowKeyless implements backend.Backend func (*Noop) SetAllowKeyless(allow bool) error { return ErrNotImpl @@ -156,18 +146,3 @@ func (*Noop) SetDescription(repo string, desc string) error { func (*Noop) SetPrivate(repo string, priv bool) error { return ErrNotImpl } - -// SetServerHost implements backend.Backend -func (*Noop) SetServerHost(host string) error { - return ErrNotImpl -} - -// SetServerName implements backend.Backend -func (*Noop) SetServerName(name string) error { - return ErrNotImpl -} - -// SetServerPort implements backend.Backend -func (*Noop) SetServerPort(port string) error { - return ErrNotImpl -} diff --git a/server/backend/server.go b/server/backend/server.go index 97c02b0966e631ac09139960bd3f09d94e06a560..72198c018d445afabc5b2a5e049e742894c1fb5c 100644 --- a/server/backend/server.go +++ b/server/backend/server.go @@ -2,19 +2,6 @@ package backend // ServerBackend is an interface that handles server configuration. type ServerBackend interface { - // ServerName returns the server's name. - ServerName() string - // SetServerName sets the server's name. - SetServerName(name string) error - // ServerHost returns the server's host. - ServerHost() string - // SetServerHost sets the server's host. - SetServerHost(host string) error - // ServerPort returns the server's port. - ServerPort() string - // SetServerPort sets the server's port. - SetServerPort(port string) error - // AnonAccess returns the access level for anonymous users. AnonAccess() AccessLevel // SetAnonAccess sets the access level for anonymous users.