From 01014afef5934375ae937d2da87981f6f2d090dc Mon Sep 17 00:00:00 2001 From: Ayman Bagabas Date: Mon, 3 Apr 2023 12:31:13 -0400 Subject: [PATCH] fix(backend): propagate errors --- server/backend/repo.go | 12 +++++------ server/backend/sqlite/sqlite.go | 38 ++++++++++++++++----------------- server/backend/sqlite/user.go | 3 ++- server/cmd/cmd.go | 6 +++--- server/cmd/description.go | 6 +++++- server/cmd/hidden.go | 6 +++++- server/cmd/private.go | 6 +++++- server/cmd/project_name.go | 6 +++++- 8 files changed, 50 insertions(+), 33 deletions(-) diff --git a/server/backend/repo.go b/server/backend/repo.go index ddc4c934b3aff06887f8fb2a1e1cbd2a3875fd95..88a25564bc24b8e9dd431d0dceabcf59163ed587 100644 --- a/server/backend/repo.go +++ b/server/backend/repo.go @@ -34,28 +34,28 @@ type RepositoryStore interface { // RepositoryMetadata is an interface for managing repository metadata. type RepositoryMetadata interface { // ProjectName returns the repository's project name. - ProjectName(repo string) string + ProjectName(repo string) (string, error) // SetProjectName sets the repository's project name. SetProjectName(repo, name string) error // Description returns the repository's description. - Description(repo string) string + Description(repo string) (string, error) // SetDescription sets the repository's description. SetDescription(repo, desc string) error // IsPrivate returns whether the repository is private. - IsPrivate(repo string) bool + IsPrivate(repo string) (bool, error) // SetPrivate sets whether the repository is private. SetPrivate(repo string, private bool) error // IsMirror returns whether the repository is a mirror. - IsMirror(repo string) bool + IsMirror(repo string) (bool, error) // IsHidden returns whether the repository is hidden. - IsHidden(repo string) bool + IsHidden(repo string) (bool, error) // SetHidden sets whether the repository is hidden. SetHidden(repo string, hidden bool) error } // RepositoryAccess is an interface for managing repository access. type RepositoryAccess interface { - IsCollaborator(repo string, username string) bool + IsCollaborator(repo string, username string) (bool, error) // AddCollaborator adds the authorized key as a collaborator on the repository. AddCollaborator(repo string, username string) error // RemoveCollaborator removes the authorized key as a collaborator on the repository. diff --git a/server/backend/sqlite/sqlite.go b/server/backend/sqlite/sqlite.go index 2dd6bd39d7d840c6849675daf3d49dceed8e3a05..2d10964f1baed8186c69c2150759b861001a5b30 100644 --- a/server/backend/sqlite/sqlite.go +++ b/server/backend/sqlite/sqlite.go @@ -134,7 +134,7 @@ func (d *SqliteBackend) CreateRepository(name string, opts backend.RepositoryOpt if err := wrapTx(d.db, context.Background(), func(tx *sqlx.Tx) error { _, err := tx.Exec(`INSERT INTO repo (name, project_name, description, private, mirror, hidden, updated_at) - VALUES (?, ?, ?, ?, ?, CURRENT_TIMESTAMP);`, + VALUES (?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP);`, name, opts.ProjectName, opts.Description, opts.Private, opts.Mirror, opts.Hidden) return err }); err != nil { @@ -282,61 +282,61 @@ func (d *SqliteBackend) Repository(repo string) (backend.Repository, error) { // Description returns the description of a repository. // // It implements backend.Backend. -func (d *SqliteBackend) Description(repo string) string { +func (d *SqliteBackend) Description(repo string) (string, error) { repo = utils.SanitizeRepo(repo) var desc string if err := wrapTx(d.db, context.Background(), func(tx *sqlx.Tx) error { return tx.Get(&desc, "SELECT description FROM repo WHERE name = ?", repo) }); err != nil { - return "" + return "", wrapDbErr(err) } - return desc + return desc, nil } // IsMirror returns true if the repository is a mirror. // // It implements backend.Backend. -func (d *SqliteBackend) IsMirror(repo string) bool { +func (d *SqliteBackend) IsMirror(repo string) (bool, error) { repo = utils.SanitizeRepo(repo) var mirror bool if err := wrapTx(d.db, context.Background(), func(tx *sqlx.Tx) error { return tx.Get(&mirror, "SELECT mirror FROM repo WHERE name = ?", repo) }); err != nil { - return false + return false, wrapDbErr(err) } - return mirror + return mirror, nil } // IsPrivate returns true if the repository is private. // // It implements backend.Backend. -func (d *SqliteBackend) IsPrivate(repo string) bool { +func (d *SqliteBackend) IsPrivate(repo string) (bool, error) { repo = utils.SanitizeRepo(repo) var private bool if err := wrapTx(d.db, context.Background(), func(tx *sqlx.Tx) error { return tx.Get(&private, "SELECT private FROM repo WHERE name = ?", repo) }); err != nil { - return false + return false, wrapDbErr(err) } - return private + return private, nil } // IsHidden returns true if the repository is hidden. // // It implements backend.Backend. -func (d *SqliteBackend) IsHidden(repo string) bool { +func (d *SqliteBackend) IsHidden(repo string) (bool, error) { repo = utils.SanitizeRepo(repo) var hidden bool if err := wrapTx(d.db, context.Background(), func(tx *sqlx.Tx) error { return tx.Get(&hidden, "SELECT hidden FROM repo WHERE name = ?", repo) }); err != nil { - return false + return false, wrapDbErr(err) } - return hidden + return hidden, nil } // SetHidden sets the hidden flag of a repository. @@ -353,16 +353,16 @@ func (d *SqliteBackend) SetHidden(repo string, hidden bool) error { // ProjectName returns the project name of a repository. // // It implements backend.Backend. -func (d *SqliteBackend) ProjectName(repo string) string { +func (d *SqliteBackend) ProjectName(repo string) (string, error) { repo = utils.SanitizeRepo(repo) var name string if err := wrapTx(d.db, context.Background(), func(tx *sqlx.Tx) error { return tx.Get(&name, "SELECT project_name FROM repo WHERE name = ?", repo) }); err != nil { - return "" + return "", wrapDbErr(err) } - return name + return name, nil } // SetDescription sets the description of a repository. @@ -440,7 +440,7 @@ func (d *SqliteBackend) Collaborators(repo string) ([]string, error) { // IsCollaborator returns true if the user is a collaborator of the repository. // // It implements backend.Backend. -func (d *SqliteBackend) IsCollaborator(repo string, username string) bool { +func (d *SqliteBackend) IsCollaborator(repo string, username string) (bool, error) { repo = utils.SanitizeRepo(repo) var count int if err := wrapTx(d.db, context.Background(), func(tx *sqlx.Tx) error { @@ -449,10 +449,10 @@ func (d *SqliteBackend) IsCollaborator(repo string, username string) bool { INNER JOIN repo ON repo.id = collab.repo_id WHERE repo.name = ? AND user.username = ?`, repo, username) }); err != nil { - return false + return false, wrapDbErr(err) } - return count > 0 + return count > 0, nil } // RemoveCollaborator removes a collaborator from a repository. diff --git a/server/backend/sqlite/user.go b/server/backend/sqlite/user.go index 764820d0c0a3172250b823b1d5999ed293b041a6..fa5cff166f27e8bea24772942594b9c8d2691f10 100644 --- a/server/backend/sqlite/user.go +++ b/server/backend/sqlite/user.go @@ -82,7 +82,8 @@ func (d *SqliteBackend) AccessLevel(repo string, username string) backend.Access r, _ := d.Repository(repo) if r != nil { // If the user is a collaborator, they have read/write access. - if d.IsCollaborator(repo, username) { + isCollab, _ := d.IsCollaborator(repo, username) + if isCollab { if anon > backend.ReadWriteAccess { return anon } diff --git a/server/cmd/cmd.go b/server/cmd/cmd.go index 6ba903f196db3ccacea4c6541599f8a0c0d30d86..671b6707ae339f0f70843e960c6413e1c4d23374 100644 --- a/server/cmd/cmd.go +++ b/server/cmd/cmd.go @@ -108,9 +108,9 @@ func checkIfAdmin(cmd *cobra.Command, _ []string) error { } } - user, err := cfg.Backend.UserByPublicKey(s.PublicKey()) - if err != nil { - return err + user, _ := cfg.Backend.UserByPublicKey(s.PublicKey()) + if user == nil { + return ErrUnauthorized } if !user.IsAdmin() { diff --git a/server/cmd/description.go b/server/cmd/description.go index bafabbfe8574904da2560442e541d80208550829..2708002725365adb75ea1e4c146460bc5c49642c 100644 --- a/server/cmd/description.go +++ b/server/cmd/description.go @@ -21,7 +21,11 @@ func descriptionCommand() *cobra.Command { return err } - desc := cfg.Backend.Description(rn) + desc, err := cfg.Backend.Description(rn) + if err != nil { + return err + } + cmd.Println(desc) default: if err := checkIfCollab(cmd, args); err != nil { diff --git a/server/cmd/hidden.go b/server/cmd/hidden.go index 7146579b36262771b56bf618857b8478932c48c9..ecd2a62d5852640b7c4f3c0e05e1dce51b0e1860 100644 --- a/server/cmd/hidden.go +++ b/server/cmd/hidden.go @@ -16,7 +16,11 @@ func hiddenCommand() *cobra.Command { return err } - hidden := cfg.Backend.IsHidden(repo) + hidden, err := cfg.Backend.IsHidden(repo) + if err != nil { + return err + } + cmd.Println(hidden) case 2: if err := checkIfCollab(cmd, args); err != nil { diff --git a/server/cmd/private.go b/server/cmd/private.go index 83e8e77ca72cfc022ad74c49d58b1268fc930e63..3b5181d48599aa38dbd7db64b2e32efc0cb58835 100644 --- a/server/cmd/private.go +++ b/server/cmd/private.go @@ -22,7 +22,11 @@ func privateCommand() *cobra.Command { return err } - isPrivate := cfg.Backend.IsPrivate(rn) + isPrivate, err := cfg.Backend.IsPrivate(rn) + if err != nil { + return err + } + cmd.Println(isPrivate) case 2: isPrivate, err := strconv.ParseBool(args[1]) diff --git a/server/cmd/project_name.go b/server/cmd/project_name.go index 68ca47c50bd0e06f61b67d4d2b64e330f7ce2e97..62e7f82b15c178b59738763c786986de560decfa 100644 --- a/server/cmd/project_name.go +++ b/server/cmd/project_name.go @@ -21,7 +21,11 @@ func projectName() *cobra.Command { return err } - pn := cfg.Backend.ProjectName(rn) + pn, err := cfg.Backend.ProjectName(rn) + if err != nil { + return err + } + cmd.Println(pn) default: if err := checkIfCollab(cmd, args); err != nil {