Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitaly.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavlo Strokov <pstrokov@gitlab.com>2022-10-20 15:16:59 +0300
committerPavlo Strokov <pstrokov@gitlab.com>2022-10-24 09:17:10 +0300
commita77085f46298d1dee2e39b15ec85bdad1bf93d0f (patch)
tree88816b0815de598ded380db34a262efedd44582e
parent9b455189ece1f9071febc9da4f65484eaeceb664 (diff)
service/operations: Improve validation of input
Gitaly should return the same error for all RPCs where the Repository input parameter is missing. Input validation code extracted into separate function where it makes sense. The test coverage extended to cover changed code. The error verification is done not only for the code, but for the message as well. It gives us confidence that a proper path is tested.
-rw-r--r--internal/gitaly/service/operations/apply_patch.go3
-rw-r--r--internal/gitaly/service/operations/apply_patch_test.go70
-rw-r--r--internal/gitaly/service/operations/branches.go64
-rw-r--r--internal/gitaly/service/operations/branches_test.go18
-rw-r--r--internal/gitaly/service/operations/cherry_pick_test.go22
-rw-r--r--internal/gitaly/service/operations/commit_files.go3
-rw-r--r--internal/gitaly/service/operations/commit_files_test.go57
-rw-r--r--internal/gitaly/service/operations/merge.go11
-rw-r--r--internal/gitaly/service/operations/merge_test.go12
-rw-r--r--internal/gitaly/service/operations/rebase.go3
-rw-r--r--internal/gitaly/service/operations/rebase_test.go56
-rw-r--r--internal/gitaly/service/operations/revert_test.go23
-rw-r--r--internal/gitaly/service/operations/squash.go3
-rw-r--r--internal/gitaly/service/operations/squash_test.go21
-rw-r--r--internal/gitaly/service/operations/submodules.go3
-rw-r--r--internal/gitaly/service/operations/submodules_test.go25
-rw-r--r--internal/gitaly/service/operations/tags.go25
-rw-r--r--internal/gitaly/service/operations/tags_test.go59
-rw-r--r--internal/gitaly/service/operations/utils.go6
19 files changed, 338 insertions, 146 deletions
diff --git a/internal/gitaly/service/operations/apply_patch.go b/internal/gitaly/service/operations/apply_patch.go
index 052001141..9cd025442 100644
--- a/internal/gitaly/service/operations/apply_patch.go
+++ b/internal/gitaly/service/operations/apply_patch.go
@@ -10,6 +10,7 @@ import (
"time"
"github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus"
+ gitalyerrors "gitlab.com/gitlab-org/gitaly/v15/internal/errors"
"gitlab.com/gitlab-org/gitaly/v15/internal/git"
"gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo"
"gitlab.com/gitlab-org/gitaly/v15/internal/helper"
@@ -197,7 +198,7 @@ func (s *Server) userApplyPatch(ctx context.Context, header *gitalypb.UserApplyP
func validateUserApplyPatchHeader(header *gitalypb.UserApplyPatchRequest_Header) error {
if header.GetRepository() == nil {
- return fmt.Errorf("missing Repository")
+ return gitalyerrors.ErrEmptyRepository
}
if header.GetUser() == nil {
diff --git a/internal/gitaly/service/operations/apply_patch_test.go b/internal/gitaly/service/operations/apply_patch_test.go
index 5a307e2a0..1fac3d309 100644
--- a/internal/gitaly/service/operations/apply_patch_test.go
+++ b/internal/gitaly/service/operations/apply_patch_test.go
@@ -21,7 +21,6 @@ import (
"gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction"
"gitlab.com/gitlab-org/gitaly/v15/internal/metadata"
"gitlab.com/gitlab-org/gitaly/v15/internal/testhelper"
- "gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg"
"gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testserver"
"gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo"
"gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb"
@@ -698,49 +697,62 @@ func TestFailedPatchApplyPatch(t *testing.T) {
func TestFailedValidationUserApplyPatch(t *testing.T) {
t.Parallel()
- _, repo, _ := testcfg.BuildWithRepo(t)
+ ctx := testhelper.Context(t)
+ ctx, _, repo, _, client := setupOperationsService(t, ctx)
testCases := []struct {
- desc string
- errorMessage string
- repo *gitalypb.Repository
- user *gitalypb.User
- branchName string
+ desc string
+ repo *gitalypb.Repository
+ user *gitalypb.User
+ branchName string
+ expErr error
}{
{
- desc: "missing Repository",
- errorMessage: "missing Repository",
- branchName: "new-branch",
- user: gittest.TestUser,
+ desc: "missing Repository",
+ branchName: "new-branch",
+ user: gittest.TestUser,
+ expErr: status.Error(codes.InvalidArgument, testhelper.GitalyOrPraefect(
+ "UserApplyPatch: empty Repository",
+ "repo scoped: empty Repository",
+ )),
},
-
{
- desc: "missing Branch",
- errorMessage: "missing Branch",
- repo: repo,
- user: gittest.TestUser,
+ desc: "missing Branch",
+ repo: repo,
+ user: gittest.TestUser,
+ expErr: status.Error(codes.InvalidArgument, "UserApplyPatch: missing Branch"),
},
{
- desc: "empty BranchName",
- errorMessage: "missing Branch",
- repo: repo,
- user: gittest.TestUser,
- branchName: "",
+ desc: "empty BranchName",
+ repo: repo,
+ user: gittest.TestUser,
+ branchName: "",
+ expErr: status.Error(codes.InvalidArgument, "UserApplyPatch: missing Branch"),
},
{
- desc: "missing User",
- errorMessage: "missing User",
- branchName: "new-branch",
- repo: repo,
+ desc: "missing User",
+ branchName: "new-branch",
+ repo: repo,
+ expErr: status.Error(codes.InvalidArgument, "UserApplyPatch: missing User"),
},
}
for _, testCase := range testCases {
t.Run(testCase.desc, func(t *testing.T) {
- request := applyPatchHeaderRequest(testCase.repo, testCase.user, testCase.branchName)
- err := validateUserApplyPatchHeader(request.GetHeader())
-
- require.Contains(t, err.Error(), testCase.errorMessage)
+ stream, err := client.UserApplyPatch(ctx)
+ require.NoError(t, err)
+ err = stream.Send(&gitalypb.UserApplyPatchRequest{
+ UserApplyPatchRequestPayload: &gitalypb.UserApplyPatchRequest_Header_{
+ Header: &gitalypb.UserApplyPatchRequest_Header{
+ Repository: testCase.repo,
+ User: testCase.user,
+ TargetBranch: []byte(testCase.branchName),
+ },
+ },
+ })
+ require.NoError(t, err)
+ _, err = stream.CloseAndRecv()
+ testhelper.RequireGrpcError(t, testCase.expErr, err)
})
}
}
diff --git a/internal/gitaly/service/operations/branches.go b/internal/gitaly/service/operations/branches.go
index 40cebfbc2..c8db57f87 100644
--- a/internal/gitaly/service/operations/branches.go
+++ b/internal/gitaly/service/operations/branches.go
@@ -4,6 +4,7 @@ import (
"context"
"errors"
+ gitalyerrors "gitlab.com/gitlab-org/gitaly/v15/internal/errors"
"gitlab.com/gitlab-org/gitaly/v15/internal/git"
"gitlab.com/gitlab-org/gitaly/v15/internal/git/updateref"
"gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/hook"
@@ -13,20 +14,27 @@ import (
"google.golang.org/grpc/status"
)
-//nolint:revive // This is unintentionally missing documentation.
-func (s *Server) UserCreateBranch(ctx context.Context, req *gitalypb.UserCreateBranchRequest) (*gitalypb.UserCreateBranchResponse, error) {
- if len(req.BranchName) == 0 {
- return nil, status.Errorf(codes.InvalidArgument, "Bad Request (empty branch name)")
+func validateUserCreateBranchRequest(in *gitalypb.UserCreateBranchRequest) error {
+ if in.GetRepository() == nil {
+ return gitalyerrors.ErrEmptyRepository
}
-
- if req.User == nil {
- return nil, status.Errorf(codes.InvalidArgument, "empty user")
+ if len(in.BranchName) == 0 {
+ return errors.New("Bad Request (empty branch name)") //nolint:stylecheck
}
-
- if len(req.StartPoint) == 0 {
- return nil, status.Errorf(codes.InvalidArgument, "empty start point")
+ if in.User == nil {
+ return errors.New("empty user")
+ }
+ if len(in.StartPoint) == 0 {
+ return errors.New("empty start point")
}
+ return nil
+}
+//nolint:revive // This is unintentionally missing documentation.
+func (s *Server) UserCreateBranch(ctx context.Context, req *gitalypb.UserCreateBranchRequest) (*gitalypb.UserCreateBranchResponse, error) {
+ if err := validateUserCreateBranchRequest(req); err != nil {
+ return nil, helper.ErrInvalidArgument(err)
+ }
quarantineDir, quarantineRepo, err := s.quarantinedRepo(ctx, req.GetRepository())
if err != nil {
return nil, err
@@ -98,20 +106,24 @@ func (s *Server) UserCreateBranch(ctx context.Context, req *gitalypb.UserCreateB
}
func validateUserUpdateBranchGo(req *gitalypb.UserUpdateBranchRequest) error {
+ if req.GetRepository() == nil {
+ return gitalyerrors.ErrEmptyRepository
+ }
+
if req.User == nil {
- return status.Errorf(codes.InvalidArgument, "empty user")
+ return errors.New("empty user")
}
if len(req.BranchName) == 0 {
- return status.Errorf(codes.InvalidArgument, "empty branch name")
+ return errors.New("empty branch name")
}
if len(req.Oldrev) == 0 {
- return status.Errorf(codes.InvalidArgument, "empty oldrev")
+ return errors.New("empty oldrev")
}
if len(req.Newrev) == 0 {
- return status.Errorf(codes.InvalidArgument, "empty newrev")
+ return errors.New("empty newrev")
}
return nil
@@ -121,7 +133,7 @@ func validateUserUpdateBranchGo(req *gitalypb.UserUpdateBranchRequest) error {
func (s *Server) UserUpdateBranch(ctx context.Context, req *gitalypb.UserUpdateBranchRequest) (*gitalypb.UserUpdateBranchResponse, error) {
// Validate the request
if err := validateUserUpdateBranchGo(req); err != nil {
- return nil, err
+ return nil, helper.ErrInvalidArgument(err)
}
newOID, err := git.ObjectHashSHA1.FromHex(string(req.Newrev))
@@ -161,17 +173,25 @@ func (s *Server) UserUpdateBranch(ctx context.Context, req *gitalypb.UserUpdateB
return &gitalypb.UserUpdateBranchResponse{}, nil
}
+func validateUserDeleteBranchRequest(in *gitalypb.UserDeleteBranchRequest) error {
+ if in.GetRepository() == nil {
+ return gitalyerrors.ErrEmptyRepository
+ }
+ if len(in.GetBranchName()) == 0 {
+ return errors.New("bad request: empty branch name")
+ }
+ if in.GetUser() == nil {
+ return errors.New("bad request: empty user")
+ }
+ return nil
+}
+
// UserDeleteBranch force-deletes a single branch in the context of a specific user. It executes
// hooks and contacts Rails to verify that the user is indeed allowed to delete that branch.
func (s *Server) UserDeleteBranch(ctx context.Context, req *gitalypb.UserDeleteBranchRequest) (*gitalypb.UserDeleteBranchResponse, error) {
- if len(req.BranchName) == 0 {
- return nil, helper.ErrInvalidArgumentf("bad request: empty branch name")
- }
-
- if req.User == nil {
- return nil, helper.ErrInvalidArgumentf("bad request: empty user")
+ if err := validateUserDeleteBranchRequest(req); err != nil {
+ return nil, helper.ErrInvalidArgument(err)
}
-
referenceName := git.NewReferenceNameFromBranchName(string(req.BranchName))
referenceValue, err := s.localrepo(req.GetRepository()).ResolveRevision(ctx, referenceName.Revision())
diff --git a/internal/gitaly/service/operations/branches_test.go b/internal/gitaly/service/operations/branches_test.go
index baa8920b9..c946d1def 100644
--- a/internal/gitaly/service/operations/branches_test.go
+++ b/internal/gitaly/service/operations/branches_test.go
@@ -342,13 +342,26 @@ func TestUserCreateBranch_Failure(t *testing.T) {
testCases := []struct {
desc string
+ repo *gitalypb.Repository
branchName string
startPoint string
user *gitalypb.User
err error
}{
{
+ desc: "repository not provided",
+ repo: nil,
+ branchName: "shiny-new-branch",
+ startPoint: "",
+ user: gittest.TestUser,
+ err: status.Error(codes.InvalidArgument, testhelper.GitalyOrPraefect(
+ "empty Repository",
+ "repo scoped: empty Repository",
+ )),
+ },
+ {
desc: "empty start_point",
+ repo: repo,
branchName: "shiny-new-branch",
startPoint: "",
user: gittest.TestUser,
@@ -356,6 +369,7 @@ func TestUserCreateBranch_Failure(t *testing.T) {
},
{
desc: "empty user",
+ repo: repo,
branchName: "shiny-new-branch",
startPoint: "master",
user: nil,
@@ -363,6 +377,7 @@ func TestUserCreateBranch_Failure(t *testing.T) {
},
{
desc: "non-existing starting point",
+ repo: repo,
branchName: "new-branch",
startPoint: "i-dont-exist",
user: gittest.TestUser,
@@ -371,6 +386,7 @@ func TestUserCreateBranch_Failure(t *testing.T) {
{
desc: "branch exists",
+ repo: repo,
branchName: "master",
startPoint: "master",
user: gittest.TestUser,
@@ -381,7 +397,7 @@ func TestUserCreateBranch_Failure(t *testing.T) {
for _, testCase := range testCases {
t.Run(testCase.desc, func(t *testing.T) {
request := &gitalypb.UserCreateBranchRequest{
- Repository: repo,
+ Repository: testCase.repo,
BranchName: []byte(testCase.branchName),
StartPoint: []byte(testCase.startPoint),
User: testCase.user,
diff --git a/internal/gitaly/service/operations/cherry_pick_test.go b/internal/gitaly/service/operations/cherry_pick_test.go
index 075b095bb..19a733e59 100644
--- a/internal/gitaly/service/operations/cherry_pick_test.go
+++ b/internal/gitaly/service/operations/cherry_pick_test.go
@@ -292,9 +292,19 @@ func TestServer_UserCherryPick_failedValidations(t *testing.T) {
testCases := []struct {
desc string
request *gitalypb.UserCherryPickRequest
- code codes.Code
+ expErr error
}{
{
+ desc: "no repository provided",
+ request: &gitalypb.UserCherryPickRequest{
+ Repository: nil,
+ },
+ expErr: status.Error(codes.InvalidArgument, testhelper.GitalyOrPraefect(
+ "UserCherryPick: empty Repository",
+ "repo scoped: empty Repository",
+ )),
+ },
+ {
desc: "empty user",
request: &gitalypb.UserCherryPickRequest{
Repository: repoProto,
@@ -303,7 +313,7 @@ func TestServer_UserCherryPick_failedValidations(t *testing.T) {
BranchName: []byte(destinationBranch),
Message: []byte("Cherry-picking " + cherryPickedCommit.Id),
},
- code: codes.InvalidArgument,
+ expErr: status.Error(codes.InvalidArgument, "UserCherryPick: empty User"),
},
{
desc: "empty commit",
@@ -314,7 +324,7 @@ func TestServer_UserCherryPick_failedValidations(t *testing.T) {
BranchName: []byte(destinationBranch),
Message: []byte("Cherry-picking " + cherryPickedCommit.Id),
},
- code: codes.InvalidArgument,
+ expErr: status.Error(codes.InvalidArgument, "UserCherryPick: empty Commit"),
},
{
desc: "empty branch name",
@@ -325,7 +335,7 @@ func TestServer_UserCherryPick_failedValidations(t *testing.T) {
BranchName: nil,
Message: []byte("Cherry-picking " + cherryPickedCommit.Id),
},
- code: codes.InvalidArgument,
+ expErr: status.Error(codes.InvalidArgument, "UserCherryPick: empty BranchName"),
},
{
desc: "empty message",
@@ -336,14 +346,14 @@ func TestServer_UserCherryPick_failedValidations(t *testing.T) {
BranchName: []byte(destinationBranch),
Message: nil,
},
- code: codes.InvalidArgument,
+ expErr: status.Error(codes.InvalidArgument, "UserCherryPick: empty Message"),
},
}
for _, testCase := range testCases {
t.Run(testCase.desc, func(t *testing.T) {
_, err := client.UserCherryPick(ctx, testCase.request)
- testhelper.RequireGrpcCode(t, err, testCase.code)
+ testhelper.RequireGrpcError(t, testCase.expErr, err)
})
}
}
diff --git a/internal/gitaly/service/operations/commit_files.go b/internal/gitaly/service/operations/commit_files.go
index 0637ee021..368100bbf 100644
--- a/internal/gitaly/service/operations/commit_files.go
+++ b/internal/gitaly/service/operations/commit_files.go
@@ -11,6 +11,7 @@ import (
"github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus"
"github.com/sirupsen/logrus"
+ gitalyerrors "gitlab.com/gitlab-org/gitaly/v15/internal/errors"
"gitlab.com/gitlab-org/gitaly/v15/internal/git"
"gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo"
"gitlab.com/gitlab-org/gitaly/v15/internal/git/remoterepo"
@@ -420,7 +421,7 @@ func (s *Server) fetchMissingCommit(
func validateUserCommitFilesHeader(header *gitalypb.UserCommitFilesRequestHeader) error {
if header.GetRepository() == nil {
- return fmt.Errorf("empty Repository")
+ return gitalyerrors.ErrEmptyRepository
}
if header.GetUser() == nil {
return fmt.Errorf("empty User")
diff --git a/internal/gitaly/service/operations/commit_files_test.go b/internal/gitaly/service/operations/commit_files_test.go
index e51d604fa..12102eb7e 100644
--- a/internal/gitaly/service/operations/commit_files_test.go
+++ b/internal/gitaly/service/operations/commit_files_test.go
@@ -1478,48 +1478,62 @@ func TestFailedUserCommitFilesRequest(t *testing.T) {
branchName := "feature"
testCases := []struct {
- desc string
- req *gitalypb.UserCommitFilesRequest
+ desc string
+ req *gitalypb.UserCommitFilesRequest
+ expErr error
}{
{
desc: "empty Repository",
req: headerRequest(nil, gittest.TestUser, branchName, commitFilesMessage, ""),
+ expErr: status.Error(codes.InvalidArgument, testhelper.GitalyOrPraefect(
+ "UserCommitFiles: empty Repository",
+ "repo scoped: empty Repository",
+ )),
},
{
- desc: "empty User",
- req: headerRequest(repo, nil, branchName, commitFilesMessage, ""),
+ desc: "empty User",
+ req: headerRequest(repo, nil, branchName, commitFilesMessage, ""),
+ expErr: status.Error(codes.InvalidArgument, "UserCommitFiles: empty User"),
},
{
- desc: "empty BranchName",
- req: headerRequest(repo, gittest.TestUser, "", commitFilesMessage, ""),
+ desc: "empty BranchName",
+ req: headerRequest(repo, gittest.TestUser, "", commitFilesMessage, ""),
+ expErr: status.Error(codes.InvalidArgument, "UserCommitFiles: empty BranchName"),
},
{
- desc: "empty CommitMessage",
- req: headerRequest(repo, gittest.TestUser, branchName, nil, ""),
+ desc: "empty CommitMessage",
+ req: headerRequest(repo, gittest.TestUser, branchName, nil, ""),
+ expErr: status.Error(codes.InvalidArgument, "UserCommitFiles: empty CommitMessage"),
},
{
- desc: "invalid object ID: \"foobar\"",
- req: setStartSha(headerRequest(repo, gittest.TestUser, branchName, commitFilesMessage, ""), "foobar"),
+ desc: "invalid object ID: \"foobar\"",
+ req: setStartSha(headerRequest(repo, gittest.TestUser, branchName, commitFilesMessage, ""), "foobar"),
+ expErr: status.Error(codes.InvalidArgument, `UserCommitFiles: invalid object ID: "foobar"`),
},
{
- desc: "failed to parse signature - Signature cannot have an empty name or email",
- req: headerRequest(repo, &gitalypb.User{}, branchName, commitFilesMessage, ""),
+ desc: "failed to parse signature - Signature cannot have an empty name or email",
+ req: headerRequest(repo, &gitalypb.User{}, branchName, commitFilesMessage, ""),
+ expErr: status.Error(codes.InvalidArgument, "commit: commit: failed to parse signature - Signature cannot have an empty name or email"),
},
{
- desc: "failed to parse signature - Signature cannot have an empty name or email",
- req: headerRequest(repo, &gitalypb.User{Name: []byte(""), Email: []byte("")}, branchName, commitFilesMessage, ""),
+ desc: "failed to parse signature - Signature cannot have an empty name or email",
+ req: headerRequest(repo, &gitalypb.User{Name: []byte(""), Email: []byte("")}, branchName, commitFilesMessage, ""),
+ expErr: status.Error(codes.InvalidArgument, "commit: commit: failed to parse signature - Signature cannot have an empty name or email"),
},
{
- desc: "failed to parse signature - Signature cannot have an empty name or email",
- req: headerRequest(repo, &gitalypb.User{Name: []byte(" "), Email: []byte(" ")}, branchName, commitFilesMessage, ""),
+ desc: "failed to parse signature - Signature cannot have an empty name or email",
+ req: headerRequest(repo, &gitalypb.User{Name: []byte(" "), Email: []byte(" ")}, branchName, commitFilesMessage, ""),
+ expErr: status.Error(codes.InvalidArgument, "commit: commit: failed to parse signature - Signature cannot have an empty name or email"),
},
{
- desc: "failed to parse signature - Signature cannot have an empty name or email",
- req: headerRequest(repo, &gitalypb.User{Name: []byte("Jane Doe"), Email: []byte("")}, branchName, commitFilesMessage, ""),
+ desc: "failed to parse signature - Signature cannot have an empty name or email",
+ req: headerRequest(repo, &gitalypb.User{Name: []byte("Jane Doe"), Email: []byte("")}, branchName, commitFilesMessage, ""),
+ expErr: status.Error(codes.InvalidArgument, "commit: commit: failed to parse signature - Signature cannot have an empty name or email"),
},
{
- desc: "failed to parse signature - Signature cannot have an empty name or email",
- req: headerRequest(repo, &gitalypb.User{Name: []byte(""), Email: []byte("janedoe@gitlab.com")}, branchName, commitFilesMessage, ""),
+ desc: "failed to parse signature - Signature cannot have an empty name or email",
+ req: headerRequest(repo, &gitalypb.User{Name: []byte(""), Email: []byte("janedoe@gitlab.com")}, branchName, commitFilesMessage, ""),
+ expErr: status.Error(codes.InvalidArgument, "commit: commit: failed to parse signature - Signature cannot have an empty name or email"),
},
}
@@ -1531,8 +1545,7 @@ func TestFailedUserCommitFilesRequest(t *testing.T) {
require.NoError(t, stream.Send(tc.req))
_, err = stream.CloseAndRecv()
- testhelper.RequireGrpcCode(t, err, codes.InvalidArgument)
- require.Contains(t, err.Error(), tc.desc)
+ testhelper.RequireGrpcError(t, tc.expErr, err)
})
}
}
diff --git a/internal/gitaly/service/operations/merge.go b/internal/gitaly/service/operations/merge.go
index 94192a7c4..315bc96ea 100644
--- a/internal/gitaly/service/operations/merge.go
+++ b/internal/gitaly/service/operations/merge.go
@@ -8,6 +8,7 @@ import (
"github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus"
"github.com/sirupsen/logrus"
+ gitalyerrors "gitlab.com/gitlab-org/gitaly/v15/internal/errors"
"gitlab.com/gitlab-org/gitaly/v15/internal/git"
"gitlab.com/gitlab-org/gitaly/v15/internal/git/updateref"
"gitlab.com/gitlab-org/gitaly/v15/internal/git2go"
@@ -17,6 +18,10 @@ import (
)
func validateMergeBranchRequest(request *gitalypb.UserMergeBranchRequest) error {
+ if request.GetRepository() == nil {
+ return gitalyerrors.ErrEmptyRepository
+ }
+
if request.User == nil {
return fmt.Errorf("empty user")
}
@@ -225,7 +230,7 @@ func (s *Server) UserMergeBranch(stream gitalypb.OperationService_UserMergeBranc
func validateFFRequest(in *gitalypb.UserFFBranchRequest) error {
if in.Repository == nil {
- return fmt.Errorf("empty repository")
+ return gitalyerrors.ErrEmptyRepository
}
if len(in.Branch) == 0 {
@@ -304,6 +309,10 @@ func (s *Server) UserFFBranch(ctx context.Context, in *gitalypb.UserFFBranchRequ
}
func validateUserMergeToRefRequest(in *gitalypb.UserMergeToRefRequest) error {
+ if in.GetRepository() == nil {
+ return gitalyerrors.ErrEmptyRepository
+ }
+
if len(in.FirstParentRef) == 0 && len(in.Branch) == 0 {
return fmt.Errorf("empty first parent ref and branch name")
}
diff --git a/internal/gitaly/service/operations/merge_test.go b/internal/gitaly/service/operations/merge_test.go
index 3965bb435..5fbd57363 100644
--- a/internal/gitaly/service/operations/merge_test.go
+++ b/internal/gitaly/service/operations/merge_test.go
@@ -140,6 +140,14 @@ func TestUserMergeBranch_failure(t *testing.T) {
expectedErr error
}{
{
+ desc: "no repository provided",
+ repo: nil,
+ expectedErr: status.Error(codes.InvalidArgument, testhelper.GitalyOrPraefect(
+ "empty Repository",
+ "repo scoped: empty Repository",
+ )),
+ },
+ {
desc: "empty user",
repo: repoProto,
branch: []byte(mergeBranchName),
@@ -372,8 +380,8 @@ func TestUserMergeBranch_abort(t *testing.T) {
closeSend bool
desc string
}{
- {req: &gitalypb.UserMergeBranchRequest{}, desc: "empty request, don't close"},
- {req: &gitalypb.UserMergeBranchRequest{}, closeSend: true, desc: "empty request and close"},
+ {req: &gitalypb.UserMergeBranchRequest{Repository: &gitalypb.Repository{}}, desc: "empty request, don't close"},
+ {req: &gitalypb.UserMergeBranchRequest{Repository: &gitalypb.Repository{}}, closeSend: true, desc: "empty request and close"},
{closeSend: true, desc: "no request just close"},
}
diff --git a/internal/gitaly/service/operations/rebase.go b/internal/gitaly/service/operations/rebase.go
index 1310055e5..c585df4a1 100644
--- a/internal/gitaly/service/operations/rebase.go
+++ b/internal/gitaly/service/operations/rebase.go
@@ -5,6 +5,7 @@ import (
"fmt"
"time"
+ gitalyerrors "gitlab.com/gitlab-org/gitaly/v15/internal/errors"
"gitlab.com/gitlab-org/gitaly/v15/internal/git"
"gitlab.com/gitlab-org/gitaly/v15/internal/git/updateref"
"gitlab.com/gitlab-org/gitaly/v15/internal/git2go"
@@ -161,7 +162,7 @@ var ErrInvalidBranch = errors.New("invalid branch name")
func validateUserRebaseConfirmableHeader(header *gitalypb.UserRebaseConfirmableRequest_Header) error {
if header.GetRepository() == nil {
- return errors.New("empty Repository")
+ return gitalyerrors.ErrEmptyRepository
}
if header.GetUser() == nil {
diff --git a/internal/gitaly/service/operations/rebase_test.go b/internal/gitaly/service/operations/rebase_test.go
index 3c3d3a3d1..6d06f5892 100644
--- a/internal/gitaly/service/operations/rebase_test.go
+++ b/internal/gitaly/service/operations/rebase_test.go
@@ -21,6 +21,7 @@ import (
"gitlab.com/gitlab-org/gitaly/v15/internal/transaction/txinfo"
"gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb"
"google.golang.org/grpc/codes"
+ "google.golang.org/grpc/status"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/timestamppb"
)
@@ -414,9 +415,34 @@ func TestUserRebaseConfirmable_abortViaClose(t *testing.T) {
desc string
code codes.Code
}{
- {req: &gitalypb.UserRebaseConfirmableRequest{}, desc: "empty request, don't close", code: codes.FailedPrecondition},
- {req: &gitalypb.UserRebaseConfirmableRequest{}, closeSend: true, desc: "empty request and close", code: codes.FailedPrecondition},
- {closeSend: true, desc: "no request just close", code: codes.Internal},
+ {
+ req: &gitalypb.UserRebaseConfirmableRequest{
+ UserRebaseConfirmableRequestPayload: &gitalypb.UserRebaseConfirmableRequest_Header_{
+ Header: &gitalypb.UserRebaseConfirmableRequest_Header{
+ Repository: &gitalypb.Repository{},
+ },
+ },
+ },
+ desc: "empty request, don't close",
+ code: codes.FailedPrecondition,
+ },
+ {
+ req: &gitalypb.UserRebaseConfirmableRequest{
+ UserRebaseConfirmableRequestPayload: &gitalypb.UserRebaseConfirmableRequest_Header_{
+ Header: &gitalypb.UserRebaseConfirmableRequest_Header{
+ Repository: &gitalypb.Repository{},
+ },
+ },
+ },
+ closeSend: true,
+ desc: "empty request and close",
+ code: codes.FailedPrecondition,
+ },
+ {
+ closeSend: true,
+ desc: "no request just close",
+ code: codes.Internal,
+ },
}
for i, tc := range testCases {
@@ -752,9 +778,19 @@ func TestUserRebaseConfirmable_failedWithCode(t *testing.T) {
testCases := []struct {
desc string
buildHeaderRequest func() *gitalypb.UserRebaseConfirmableRequest
- expectedCode codes.Code
+ expErr error
}{
{
+ desc: "no repository provided",
+ buildHeaderRequest: func() *gitalypb.UserRebaseConfirmableRequest {
+ return buildHeaderRequest(nil, gittest.TestUser, "1", rebaseBranchName, branchCommitID, nil, "master")
+ },
+ expErr: status.Error(codes.InvalidArgument, testhelper.GitalyOrPraefect(
+ "UserRebaseConfirmable: empty Repository",
+ "repo scoped: empty Repository",
+ )),
+ },
+ {
desc: "non-existing storage",
buildHeaderRequest: func() *gitalypb.UserRebaseConfirmableRequest {
repo := proto.Clone(repoProto).(*gitalypb.Repository)
@@ -762,7 +798,10 @@ func TestUserRebaseConfirmable_failedWithCode(t *testing.T) {
return buildHeaderRequest(repo, gittest.TestUser, "1", rebaseBranchName, branchCommitID, repo, "master")
},
- expectedCode: codes.InvalidArgument,
+ expErr: status.Error(codes.InvalidArgument, testhelper.GitalyOrPraefect(
+ `creating repo quarantine: creating object quarantine: getting repo path: GetStorageByName: no such storage: "@this-storage-does-not-exist"`,
+ "repo scoped: invalid Repository",
+ )),
},
{
desc: "missing repository path",
@@ -772,7 +811,10 @@ func TestUserRebaseConfirmable_failedWithCode(t *testing.T) {
return buildHeaderRequest(repo, gittest.TestUser, "1", rebaseBranchName, branchCommitID, repo, "master")
},
- expectedCode: codes.InvalidArgument,
+ expErr: status.Error(codes.InvalidArgument, testhelper.GitalyOrPraefect(
+ "creating repo quarantine: creating object quarantine: getting repo path: GetPath: relative path missing",
+ "repo scoped: invalid Repository",
+ )),
},
}
@@ -785,7 +827,7 @@ func TestUserRebaseConfirmable_failedWithCode(t *testing.T) {
require.NoError(t, rebaseStream.Send(headerRequest), "send header")
_, err = rebaseStream.Recv()
- testhelper.RequireGrpcCode(t, err, tc.expectedCode)
+ testhelper.RequireGrpcError(t, tc.expErr, err)
})
}
}
diff --git a/internal/gitaly/service/operations/revert_test.go b/internal/gitaly/service/operations/revert_test.go
index 4dcbe97e2..623769e11 100644
--- a/internal/gitaly/service/operations/revert_test.go
+++ b/internal/gitaly/service/operations/revert_test.go
@@ -15,6 +15,7 @@ import (
"gitlab.com/gitlab-org/gitaly/v15/internal/testhelper"
"gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb"
"google.golang.org/grpc/codes"
+ "google.golang.org/grpc/status"
"google.golang.org/protobuf/types/known/timestamppb"
)
@@ -372,9 +373,19 @@ func TestServer_UserRevert_failuedDueToValidations(t *testing.T) {
testCases := []struct {
desc string
request *gitalypb.UserRevertRequest
- code codes.Code
+ expErr error
}{
{
+ desc: "no repository provided",
+ request: &gitalypb.UserRevertRequest{
+ Repository: nil,
+ },
+ expErr: status.Error(codes.InvalidArgument, testhelper.GitalyOrPraefect(
+ "empty Repository",
+ "repo scoped: empty Repository",
+ )),
+ },
+ {
desc: "empty user",
request: &gitalypb.UserRevertRequest{
Repository: repoProto,
@@ -383,7 +394,7 @@ func TestServer_UserRevert_failuedDueToValidations(t *testing.T) {
BranchName: []byte(destinationBranch),
Message: []byte("Reverting " + revertedCommit.Id),
},
- code: codes.InvalidArgument,
+ expErr: status.Error(codes.InvalidArgument, "empty User"),
},
{
desc: "empty commit",
@@ -394,7 +405,7 @@ func TestServer_UserRevert_failuedDueToValidations(t *testing.T) {
BranchName: []byte(destinationBranch),
Message: []byte("Reverting " + revertedCommit.Id),
},
- code: codes.InvalidArgument,
+ expErr: status.Error(codes.InvalidArgument, "empty Commit"),
},
{
desc: "empty branch name",
@@ -405,7 +416,7 @@ func TestServer_UserRevert_failuedDueToValidations(t *testing.T) {
BranchName: nil,
Message: []byte("Reverting " + revertedCommit.Id),
},
- code: codes.InvalidArgument,
+ expErr: status.Error(codes.InvalidArgument, "empty BranchName"),
},
{
desc: "empty message",
@@ -416,14 +427,14 @@ func TestServer_UserRevert_failuedDueToValidations(t *testing.T) {
BranchName: []byte(destinationBranch),
Message: nil,
},
- code: codes.InvalidArgument,
+ expErr: status.Error(codes.InvalidArgument, "empty Message"),
},
}
for _, testCase := range testCases {
t.Run(testCase.desc, func(t *testing.T) {
_, err := client.UserRevert(ctx, testCase.request)
- testhelper.RequireGrpcCode(t, err, testCase.code)
+ testhelper.RequireGrpcError(t, testCase.expErr, err)
})
}
}
diff --git a/internal/gitaly/service/operations/squash.go b/internal/gitaly/service/operations/squash.go
index 7f2bc0881..5085bd540 100644
--- a/internal/gitaly/service/operations/squash.go
+++ b/internal/gitaly/service/operations/squash.go
@@ -5,6 +5,7 @@ import (
"errors"
"strings"
+ gitalyerrors "gitlab.com/gitlab-org/gitaly/v15/internal/errors"
"gitlab.com/gitlab-org/gitaly/v15/internal/git"
"gitlab.com/gitlab-org/gitaly/v15/internal/git2go"
"gitlab.com/gitlab-org/gitaly/v15/internal/gitaly/transaction"
@@ -34,7 +35,7 @@ func (s *Server) UserSquash(ctx context.Context, req *gitalypb.UserSquashRequest
func validateUserSquashRequest(req *gitalypb.UserSquashRequest) error {
if req.GetRepository() == nil {
- return errors.New("empty Repository")
+ return gitalyerrors.ErrEmptyRepository
}
if req.GetUser() == nil {
diff --git a/internal/gitaly/service/operations/squash_test.go b/internal/gitaly/service/operations/squash_test.go
index 0c482a330..6b5b86db4 100644
--- a/internal/gitaly/service/operations/squash_test.go
+++ b/internal/gitaly/service/operations/squash_test.go
@@ -24,6 +24,7 @@ import (
"gitlab.com/gitlab-org/gitaly/v15/internal/transaction/voting"
"gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb"
"google.golang.org/grpc/codes"
+ "google.golang.org/grpc/status"
"google.golang.org/protobuf/types/known/timestamppb"
)
@@ -525,7 +526,7 @@ func TestUserSquash_validation(t *testing.T) {
testCases := []struct {
desc string
request *gitalypb.UserSquashRequest
- code codes.Code
+ expErr error
}{
{
desc: "empty Repository",
@@ -537,7 +538,10 @@ func TestUserSquash_validation(t *testing.T) {
StartSha: startSha,
EndSha: endSha,
},
- code: codes.InvalidArgument,
+ expErr: status.Error(codes.InvalidArgument, testhelper.GitalyOrPraefect(
+ "UserSquash: empty Repository",
+ "repo scoped: empty Repository",
+ )),
},
{
desc: "empty User",
@@ -549,7 +553,7 @@ func TestUserSquash_validation(t *testing.T) {
StartSha: startSha,
EndSha: endSha,
},
- code: codes.InvalidArgument,
+ expErr: status.Error(codes.InvalidArgument, "UserSquash: empty User"),
},
{
desc: "empty StartSha",
@@ -561,7 +565,7 @@ func TestUserSquash_validation(t *testing.T) {
StartSha: "",
EndSha: endSha,
},
- code: codes.InvalidArgument,
+ expErr: status.Error(codes.InvalidArgument, "UserSquash: empty StartSha"),
},
{
desc: "empty EndSha",
@@ -573,7 +577,7 @@ func TestUserSquash_validation(t *testing.T) {
StartSha: startSha,
EndSha: "",
},
- code: codes.InvalidArgument,
+ expErr: status.Error(codes.InvalidArgument, "UserSquash: empty EndSha"),
},
{
desc: "empty Author",
@@ -585,7 +589,7 @@ func TestUserSquash_validation(t *testing.T) {
StartSha: startSha,
EndSha: endSha,
},
- code: codes.InvalidArgument,
+ expErr: status.Error(codes.InvalidArgument, "UserSquash: empty Author"),
},
{
desc: "empty CommitMessage",
@@ -597,15 +601,14 @@ func TestUserSquash_validation(t *testing.T) {
StartSha: startSha,
EndSha: endSha,
},
- code: codes.InvalidArgument,
+ expErr: status.Error(codes.InvalidArgument, "UserSquash: empty CommitMessage"),
},
}
for _, testCase := range testCases {
t.Run(testCase.desc, func(t *testing.T) {
_, err := client.UserSquash(ctx, testCase.request)
- testhelper.RequireGrpcCode(t, err, testCase.code)
- require.Contains(t, err.Error(), testCase.desc)
+ testhelper.RequireGrpcError(t, testCase.expErr, err)
})
}
}
diff --git a/internal/gitaly/service/operations/submodules.go b/internal/gitaly/service/operations/submodules.go
index 98cccb326..f49a895aa 100644
--- a/internal/gitaly/service/operations/submodules.go
+++ b/internal/gitaly/service/operations/submodules.go
@@ -8,6 +8,7 @@ import (
"strings"
"github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus"
+ gitalyerrors "gitlab.com/gitlab-org/gitaly/v15/internal/errors"
"gitlab.com/gitlab-org/gitaly/v15/internal/git"
"gitlab.com/gitlab-org/gitaly/v15/internal/git/updateref"
"gitlab.com/gitlab-org/gitaly/v15/internal/git2go"
@@ -30,7 +31,7 @@ func (s *Server) UserUpdateSubmodule(ctx context.Context, req *gitalypb.UserUpda
func validateUserUpdateSubmoduleRequest(req *gitalypb.UserUpdateSubmoduleRequest) error {
if req.GetRepository() == nil {
- return fmt.Errorf("empty Repository")
+ return gitalyerrors.ErrEmptyRepository
}
if req.GetUser() == nil {
diff --git a/internal/gitaly/service/operations/submodules_test.go b/internal/gitaly/service/operations/submodules_test.go
index e572224b5..655f1f5ee 100644
--- a/internal/gitaly/service/operations/submodules_test.go
+++ b/internal/gitaly/service/operations/submodules_test.go
@@ -17,6 +17,7 @@ import (
"gitlab.com/gitlab-org/gitaly/v15/internal/testhelper"
"gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb"
"google.golang.org/grpc/codes"
+ "google.golang.org/grpc/status"
"google.golang.org/protobuf/types/known/timestamppb"
)
@@ -196,7 +197,7 @@ func TestFailedUserUpdateSubmoduleRequestDueToValidations(t *testing.T) {
testCases := []struct {
desc string
request *gitalypb.UserUpdateSubmoduleRequest
- code codes.Code
+ expErr error
}{
{
desc: "empty Repository",
@@ -208,7 +209,10 @@ func TestFailedUserUpdateSubmoduleRequestDueToValidations(t *testing.T) {
Branch: []byte("some-branch"),
CommitMessage: []byte("Update Submodule message"),
},
- code: codes.InvalidArgument,
+ expErr: status.Error(codes.InvalidArgument, testhelper.GitalyOrPraefect(
+ "UserUpdateSubmodule: empty Repository",
+ "repo scoped: empty Repository",
+ )),
},
{
desc: "empty User",
@@ -220,7 +224,7 @@ func TestFailedUserUpdateSubmoduleRequestDueToValidations(t *testing.T) {
Branch: []byte("some-branch"),
CommitMessage: []byte("Update Submodule message"),
},
- code: codes.InvalidArgument,
+ expErr: status.Error(codes.InvalidArgument, "UserUpdateSubmodule: empty User"),
},
{
desc: "empty Submodule",
@@ -232,7 +236,7 @@ func TestFailedUserUpdateSubmoduleRequestDueToValidations(t *testing.T) {
Branch: []byte("some-branch"),
CommitMessage: []byte("Update Submodule message"),
},
- code: codes.InvalidArgument,
+ expErr: status.Error(codes.InvalidArgument, "UserUpdateSubmodule: empty Submodule"),
},
{
desc: "empty CommitSha",
@@ -244,7 +248,7 @@ func TestFailedUserUpdateSubmoduleRequestDueToValidations(t *testing.T) {
Branch: []byte("some-branch"),
CommitMessage: []byte("Update Submodule message"),
},
- code: codes.InvalidArgument,
+ expErr: status.Error(codes.InvalidArgument, "UserUpdateSubmodule: empty CommitSha"),
},
{
desc: "invalid CommitSha",
@@ -256,7 +260,7 @@ func TestFailedUserUpdateSubmoduleRequestDueToValidations(t *testing.T) {
Branch: []byte("some-branch"),
CommitMessage: []byte("Update Submodule message"),
},
- code: codes.InvalidArgument,
+ expErr: status.Error(codes.InvalidArgument, "UserUpdateSubmodule: invalid CommitSha"),
},
{
desc: "invalid CommitSha",
@@ -268,7 +272,7 @@ func TestFailedUserUpdateSubmoduleRequestDueToValidations(t *testing.T) {
Branch: []byte("some-branch"),
CommitMessage: []byte("Update Submodule message"),
},
- code: codes.InvalidArgument,
+ expErr: status.Error(codes.InvalidArgument, "UserUpdateSubmodule: invalid CommitSha"),
},
{
desc: "empty Branch",
@@ -280,7 +284,7 @@ func TestFailedUserUpdateSubmoduleRequestDueToValidations(t *testing.T) {
Branch: nil,
CommitMessage: []byte("Update Submodule message"),
},
- code: codes.InvalidArgument,
+ expErr: status.Error(codes.InvalidArgument, "UserUpdateSubmodule: empty Branch"),
},
{
desc: "empty CommitMessage",
@@ -292,15 +296,14 @@ func TestFailedUserUpdateSubmoduleRequestDueToValidations(t *testing.T) {
Branch: []byte("some-branch"),
CommitMessage: nil,
},
- code: codes.InvalidArgument,
+ expErr: status.Error(codes.InvalidArgument, "UserUpdateSubmodule: empty CommitMessage"),
},
}
for _, testCase := range testCases {
t.Run(testCase.desc, func(t *testing.T) {
_, err := client.UserUpdateSubmodule(ctx, testCase.request)
- testhelper.RequireGrpcCode(t, err, testCase.code)
- require.Contains(t, err.Error(), testCase.desc)
+ testhelper.RequireGrpcError(t, testCase.expErr, err)
})
}
}
diff --git a/internal/gitaly/service/operations/tags.go b/internal/gitaly/service/operations/tags.go
index 67fc7746c..893a2d330 100644
--- a/internal/gitaly/service/operations/tags.go
+++ b/internal/gitaly/service/operations/tags.go
@@ -8,6 +8,7 @@ import (
"regexp"
"time"
+ gitalyerrors "gitlab.com/gitlab-org/gitaly/v15/internal/errors"
"gitlab.com/gitlab-org/gitaly/v15/internal/git"
"gitlab.com/gitlab-org/gitaly/v15/internal/git/catfile"
"gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo"
@@ -19,16 +20,24 @@ import (
"google.golang.org/grpc/status"
)
-//nolint:revive // This is unintentionally missing documentation.
-func (s *Server) UserDeleteTag(ctx context.Context, req *gitalypb.UserDeleteTagRequest) (*gitalypb.UserDeleteTagResponse, error) {
- if len(req.TagName) == 0 {
- return nil, status.Errorf(codes.InvalidArgument, "empty tag name")
+func validateUserDeleteTagRequest(in *gitalypb.UserDeleteTagRequest) error {
+ if in.GetRepository() == nil {
+ return gitalyerrors.ErrEmptyRepository
}
-
- if req.User == nil {
- return nil, status.Errorf(codes.InvalidArgument, "empty user")
+ if len(in.GetTagName()) == 0 {
+ return errors.New("empty tag name")
+ }
+ if in.GetUser() == nil {
+ return errors.New("empty user")
}
+ return nil
+}
+//nolint:revive // This is unintentionally missing documentation.
+func (s *Server) UserDeleteTag(ctx context.Context, req *gitalypb.UserDeleteTagRequest) (*gitalypb.UserDeleteTagResponse, error) {
+ if err := validateUserDeleteTagRequest(req); err != nil {
+ return nil, helper.ErrInvalidArgument(err)
+ }
referenceName := git.ReferenceName(fmt.Sprintf("refs/tags/%s", req.TagName))
revision, err := s.localrepo(req.GetRepository()).ResolveRevision(ctx, referenceName.Revision())
if err != nil {
@@ -76,7 +85,7 @@ func validateUserCreateTag(req *gitalypb.UserCreateTagRequest) error {
}
if req.GetRepository() == nil {
- return fmt.Errorf("empty repository")
+ return gitalyerrors.ErrEmptyRepository
}
return nil
diff --git a/internal/gitaly/service/operations/tags_test.go b/internal/gitaly/service/operations/tags_test.go
index 64e59f2de..9ecf3c82b 100644
--- a/internal/gitaly/service/operations/tags_test.go
+++ b/internal/gitaly/service/operations/tags_test.go
@@ -949,19 +949,27 @@ func TestUserDeleteTag_invalidArgument(t *testing.T) {
ctx, _, repo, _, client := setupOperationsService(t, ctx)
testCases := []struct {
- desc string
- request *gitalypb.UserDeleteTagRequest
- response *gitalypb.UserDeleteTagResponse
- err error
+ desc string
+ request *gitalypb.UserDeleteTagRequest
+ err error
}{
{
+ desc: "no repository provided",
+ request: &gitalypb.UserDeleteTagRequest{
+ Repository: nil,
+ },
+ err: status.Error(codes.InvalidArgument, testhelper.GitalyOrPraefect(
+ "empty Repository",
+ "repo scoped: empty Repository",
+ )),
+ },
+ {
desc: "empty user",
request: &gitalypb.UserDeleteTagRequest{
Repository: repo,
TagName: []byte("does-matter-the-name-if-user-is-empty"),
},
- response: nil,
- err: status.Error(codes.InvalidArgument, "empty user"),
+ err: status.Error(codes.InvalidArgument, "empty user"),
},
{
desc: "empty tag name",
@@ -969,8 +977,7 @@ func TestUserDeleteTag_invalidArgument(t *testing.T) {
Repository: repo,
User: gittest.TestUser,
},
- response: nil,
- err: status.Error(codes.InvalidArgument, "empty tag name"),
+ err: status.Error(codes.InvalidArgument, "empty tag name"),
},
{
desc: "non-existent tag name",
@@ -979,8 +986,7 @@ func TestUserDeleteTag_invalidArgument(t *testing.T) {
User: gittest.TestUser,
TagName: []byte("i-do-not-exist"),
},
- response: nil,
- err: status.Errorf(codes.FailedPrecondition, "tag not found: %s", "i-do-not-exist"),
+ err: status.Errorf(codes.FailedPrecondition, "tag not found: %s", "i-do-not-exist"),
},
{
desc: "space in tag name",
@@ -989,8 +995,7 @@ func TestUserDeleteTag_invalidArgument(t *testing.T) {
User: gittest.TestUser,
TagName: []byte("a tag"),
},
- response: nil,
- err: status.Errorf(codes.FailedPrecondition, "tag not found: %s", "a tag"),
+ err: status.Errorf(codes.FailedPrecondition, "tag not found: %s", "a tag"),
},
{
desc: "newline in tag name",
@@ -999,16 +1004,14 @@ func TestUserDeleteTag_invalidArgument(t *testing.T) {
User: gittest.TestUser,
TagName: []byte("a\ntag"),
},
- response: nil,
- err: status.Errorf(codes.FailedPrecondition, "tag not found: %s", "a\ntag"),
+ err: status.Errorf(codes.FailedPrecondition, "tag not found: %s", "a\ntag"),
},
}
for _, testCase := range testCases {
t.Run(testCase.desc, func(t *testing.T) {
- response, err := client.UserDeleteTag(ctx, testCase.request)
+ _, err := client.UserDeleteTag(ctx, testCase.request)
testhelper.RequireGrpcError(t, testCase.err, err)
- testhelper.ProtoEqual(t, testCase.response, response)
})
}
}
@@ -1165,6 +1168,7 @@ func TestUserCreateTag_invalidArgument(t *testing.T) {
for _, tc := range []struct {
desc string
+ repo *gitalypb.Repository
tagName string
targetRevision string
message string
@@ -1172,7 +1176,19 @@ func TestUserCreateTag_invalidArgument(t *testing.T) {
expectedErr error
}{
{
+ desc: "no repository provided",
+ repo: nil,
+ tagName: "shiny-new-tag",
+ targetRevision: "main",
+ user: gittest.TestUser,
+ expectedErr: status.Error(codes.InvalidArgument, testhelper.GitalyOrPraefect(
+ "validating request: empty Repository",
+ "repo scoped: empty Repository",
+ )),
+ },
+ {
desc: "empty target revision",
+ repo: repo,
tagName: "shiny-new-tag",
targetRevision: "",
user: gittest.TestUser,
@@ -1180,6 +1196,7 @@ func TestUserCreateTag_invalidArgument(t *testing.T) {
},
{
desc: "empty user",
+ repo: repo,
tagName: "shiny-new-tag",
targetRevision: "main",
user: nil,
@@ -1187,6 +1204,7 @@ func TestUserCreateTag_invalidArgument(t *testing.T) {
},
{
desc: "empty starting point",
+ repo: repo,
tagName: "new-tag",
targetRevision: "",
user: gittest.TestUser,
@@ -1194,6 +1212,7 @@ func TestUserCreateTag_invalidArgument(t *testing.T) {
},
{
desc: "non-existing starting point",
+ repo: repo,
tagName: "new-tag",
targetRevision: "i-dont-exist",
user: gittest.TestUser,
@@ -1201,6 +1220,7 @@ func TestUserCreateTag_invalidArgument(t *testing.T) {
},
{
desc: "space in lightweight tag name",
+ repo: repo,
tagName: "a tag",
targetRevision: "main",
user: gittest.TestUser,
@@ -1208,6 +1228,7 @@ func TestUserCreateTag_invalidArgument(t *testing.T) {
},
{
desc: "space in annotated tag name",
+ repo: repo,
tagName: "a tag",
targetRevision: "main",
message: "a message",
@@ -1216,6 +1237,7 @@ func TestUserCreateTag_invalidArgument(t *testing.T) {
},
{
desc: "newline in lightweight tag name",
+ repo: repo,
tagName: "a\ntag",
targetRevision: "main",
user: gittest.TestUser,
@@ -1223,6 +1245,7 @@ func TestUserCreateTag_invalidArgument(t *testing.T) {
},
{
desc: "newline in annotated tag name",
+ repo: repo,
tagName: "a\ntag",
targetRevision: "main",
message: "a message",
@@ -1231,6 +1254,7 @@ func TestUserCreateTag_invalidArgument(t *testing.T) {
},
{
desc: "injection in lightweight tag name",
+ repo: repo,
tagName: injectedTag,
targetRevision: "main",
user: gittest.TestUser,
@@ -1238,6 +1262,7 @@ func TestUserCreateTag_invalidArgument(t *testing.T) {
},
{
desc: "injection in annotated tag name",
+ repo: repo,
tagName: injectedTag,
targetRevision: "main",
message: "a message",
@@ -1247,7 +1272,7 @@ func TestUserCreateTag_invalidArgument(t *testing.T) {
} {
t.Run(tc.desc, func(t *testing.T) {
request := &gitalypb.UserCreateTagRequest{
- Repository: repo,
+ Repository: tc.repo,
TagName: []byte(tc.tagName),
TargetRevision: []byte(tc.targetRevision),
User: tc.user,
diff --git a/internal/gitaly/service/operations/utils.go b/internal/gitaly/service/operations/utils.go
index 2052c9b3d..6d58e6f2d 100644
--- a/internal/gitaly/service/operations/utils.go
+++ b/internal/gitaly/service/operations/utils.go
@@ -4,11 +4,13 @@ import (
"fmt"
"time"
+ gitalyerrors "gitlab.com/gitlab-org/gitaly/v15/internal/errors"
"gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb"
"google.golang.org/protobuf/types/known/timestamppb"
)
type cherryPickOrRevertRequest interface {
+ GetRepository() *gitalypb.Repository
GetUser() *gitalypb.User
GetCommit() *gitalypb.GitCommit
GetBranchName() []byte
@@ -16,6 +18,10 @@ type cherryPickOrRevertRequest interface {
}
func validateCherryPickOrRevertRequest(req cherryPickOrRevertRequest) error {
+ if req.GetRepository() == nil {
+ return gitalyerrors.ErrEmptyRepository
+ }
+
if req.GetUser() == nil {
return fmt.Errorf("empty User")
}