From aa8fb74e5cda1e740646406ec07b671c5b5648ec Mon Sep 17 00:00:00 2001 From: Ayman Bagabas Date: Thu, 23 Mar 2023 13:27:45 -0400 Subject: [PATCH] fix(backend): private repos, description, and nested repos names --- server/backend/file/file.go | 29 ++++++++++++++++------------- server/backend/file/repo.go | 8 +++++--- server/config/config.go | 2 ++ 3 files changed, 23 insertions(+), 16 deletions(-) diff --git a/server/backend/file/file.go b/server/backend/file/file.go index cc0281f5e7699686d02ebab61f90e5b8d5d0b6e7..2bc66b3ac458c94724e5c46ef49f0868ea7e89b2 100644 --- a/server/backend/file/file.go +++ b/server/backend/file/file.go @@ -48,7 +48,7 @@ const ( repos = "repos" collabs = "collaborators" description = "description" - private = "private" + exportOk = "git-daemon-export-ok" settings = "settings" ) @@ -264,7 +264,7 @@ func (fb *FileBackend) AnonAccess() backend.AccessLevel { // It implements backend.Backend. func (fb *FileBackend) Description(repo string) string { repo = sanatizeRepo(repo) + ".git" - r := &Repo{path: filepath.Join(fb.reposPath(), repo)} + r := &Repo{path: filepath.Join(fb.reposPath(), repo), root: fb.reposPath()} return r.Description() } @@ -307,7 +307,15 @@ func (fb *FileBackend) IsAdmin(pk gossh.PublicKey) bool { // It implements backend.Backend. func (fb *FileBackend) IsCollaborator(pk gossh.PublicKey, repo string) bool { repo = sanatizeRepo(repo) + ".git" + _, err := os.Stat(filepath.Join(fb.reposPath(), repo)) + if errors.Is(err, os.ErrNotExist) { + return false + } + f, err := os.Open(fb.collabsPath(repo)) + if err != nil && errors.Is(err, os.ErrNotExist) { + return false + } if err != nil { logger.Debug("failed to open collaborators file", "err", err, "path", fb.collabsPath(repo)) return false @@ -333,7 +341,7 @@ func (fb *FileBackend) IsCollaborator(pk gossh.PublicKey, repo string) bool { // It implements backend.Backend. func (fb *FileBackend) IsPrivate(repo string) bool { repo = sanatizeRepo(repo) + ".git" - r := &Repo{path: filepath.Join(fb.reposPath(), repo)} + r := &Repo{path: filepath.Join(fb.reposPath(), repo), root: fb.reposPath()} return r.IsPrivate() } @@ -428,15 +436,9 @@ func (fb *FileBackend) SetDescription(repo string, desc string) error { // It implements backend.Backend. func (fb *FileBackend) SetPrivate(repo string, priv bool) error { repo = sanatizeRepo(repo) + ".git" - daemonExport := filepath.Join(fb.reposPath(), repo, "git-daemon-export-ok") + 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) @@ -505,8 +507,9 @@ func (fb *FileBackend) CreateRepository(name string, private bool) (backend.Repo } fb.SetPrivate(name, private) + fb.SetDescription(name, "") - return &Repo{path: rp}, nil + return &Repo{path: rp, root: fb.reposPath()}, nil } // DeleteRepository deletes the given repository. @@ -537,7 +540,7 @@ func (fb *FileBackend) Repository(repo string) (backend.Repository, error) { return nil, err } - return &Repo{path: rp}, nil + return &Repo{path: rp, root: fb.reposPath()}, nil } // Repositories returns a list of all repositories. @@ -556,7 +559,7 @@ func (fb *FileBackend) Repositories() ([]backend.Repository, error) { return nil } - repos = append(repos, &Repo{path: path}) + repos = append(repos, &Repo{path: path, root: fb.reposPath()}) return nil }) diff --git a/server/backend/file/repo.go b/server/backend/file/repo.go index 6764f5fe3164fa5518712159b5f140d895c6bfa3..2a8c3c9d2367b8cb36630567ef31f5dd8cc955d5 100644 --- a/server/backend/file/repo.go +++ b/server/backend/file/repo.go @@ -16,6 +16,7 @@ var _ backend.Repository = (*Repo)(nil) // // It implemenets backend.Repository. type Repo struct { + root string path string } @@ -23,14 +24,15 @@ type Repo struct { // // It implements backend.Repository. func (r *Repo) Name() string { - return strings.TrimSuffix(filepath.Base(r.path), ".git") + name := strings.TrimSuffix(strings.TrimPrefix(r.path, r.root), ".git") + return strings.TrimPrefix(name, "/") } // Description returns the repository's description. // // It implements backend.Repository. func (r *Repo) Description() string { - desc, err := readAll(r.path) + desc, err := readAll(filepath.Join(r.path, description)) if err != nil { logger.Debug("failed to read description file", "err", err, "path", filepath.Join(r.path, description)) @@ -44,7 +46,7 @@ func (r *Repo) Description() string { // // It implements backend.Repository. func (r *Repo) IsPrivate() bool { - _, err := os.Stat(filepath.Join(r.path, private)) + _, err := os.Stat(filepath.Join(r.path, exportOk)) return errors.Is(err, os.ErrExist) } diff --git a/server/config/config.go b/server/config/config.go index 05f008e57ff29a4ecadf20fb5ad411703d040fd7..8a3de7e1c5313333245a07b0fde349a1281d1e66 100644 --- a/server/config/config.go +++ b/server/config/config.go @@ -76,6 +76,8 @@ func DefaultConfig() *Config { if err != nil { log.Fatal(err) } + // Add the initial admin keys to the list of admins. + fb.AdditionalAdmins = cfg.InitialAdminKeys return cfg.WithBackend(fb).WithAccessMethod(fb) }