Skip to content

Commit

Permalink
CR-15777 (#409)
Browse files Browse the repository at this point in the history
* from repo CR-15777

Signed-off-by: kim-codefresh <[email protected]>

* bump

Signed-off-by: kim-codefresh <[email protected]>

* resolve comments

Signed-off-by: kim-codefresh <[email protected]>

* fix test

Signed-off-by: kim-codefresh <[email protected]>

Signed-off-by: kim-codefresh <[email protected]>
  • Loading branch information
kim-codefresh authored Jan 11, 2023
1 parent bbc5094 commit 8efa73d
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 7 deletions.
17 changes: 17 additions & 0 deletions pkg/git/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,11 @@ func (o *CloneOptions) GetRepo(ctx context.Context) (Repository, fs.FS, error) {
default:
return nil, nil, err
}
} else if o.CloneForWrite {
err = validateRepoWritePermission(ctx, r)
if err != nil {
return nil, nil, fmt.Errorf("failed to validate repository write permission: %w", err)
}
}

bootstrapFS, err := o.FS.Chroot(o.path)
Expand All @@ -252,6 +257,18 @@ func (o *CloneOptions) GetRepo(ctx context.Context) (Repository, fs.FS, error) {
return r, fs.Create(bootstrapFS), nil
}

var validateRepoWritePermission = func(ctx context.Context, r *repo) error {
_, err := r.Persist(ctx, &PushOptions{
CommitMsg: "Validating repository write permission",
})

if err != nil {
return fmt.Errorf("failed pushing commit to repository: %w", err)
}

return nil
}

func (o *CloneOptions) URL() string {
return o.url
}
Expand Down
116 changes: 109 additions & 7 deletions pkg/git/repository_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -596,12 +596,13 @@ func Test_clone(t *testing.T) {

func TestGetRepo(t *testing.T) {
tests := map[string]struct {
opts *CloneOptions
wantErr string
cloneFn func(context.Context, *CloneOptions) (*repo, error)
createRepoFn func(context.Context, *CloneOptions) (defaultBranch string, err error)
initRepoFn func(context.Context, *CloneOptions, string) (*repo, error)
assertFn func(*testing.T, Repository, fs.FS, error)
opts *CloneOptions
wantErr string
cloneFn func(context.Context, *CloneOptions) (*repo, error)
validateRepoWritePermissionFn func(ctx context.Context, r *repo) error
createRepoFn func(context.Context, *CloneOptions) (defaultBranch string, err error)
initRepoFn func(context.Context, *CloneOptions, string) (*repo, error)
assertFn func(*testing.T, Repository, fs.FS, error)
}{
"Should get a repo": {
opts: &CloneOptions{
Expand All @@ -611,6 +612,9 @@ func TestGetRepo(t *testing.T) {
cloneFn: func(_ context.Context, opts *CloneOptions) (*repo, error) {
return &repo{}, nil
},
validateRepoWritePermissionFn: func(ctx context.Context, r *repo) error {
return nil
},
assertFn: func(t *testing.T, r Repository, f fs.FS, e error) {
assert.NotNil(t, r)
assert.NotNil(t, f)
Expand Down Expand Up @@ -708,20 +712,25 @@ func TestGetRepo(t *testing.T) {
assert.NotNil(t, f)
assert.Nil(t, e)
},
validateRepoWritePermissionFn: func(ctx context.Context, r *repo) error {
return nil
},
},
}

origClone, origCreateRepo, origInitRepo := clone, createRepo, initRepo
origClone, origCreateRepo, origInitRepo, origValidateRepoWritePermission := clone, createRepo, initRepo, validateRepoWritePermission
defer func() {
clone = origClone
createRepo = origCreateRepo
initRepo = origInitRepo
validateRepoWritePermission = origValidateRepoWritePermission
}()
for tname, tt := range tests {
t.Run(tname, func(t *testing.T) {
clone = tt.cloneFn
createRepo = tt.createRepoFn
initRepo = tt.initRepoFn
validateRepoWritePermission = tt.validateRepoWritePermissionFn
if tt.opts != nil {
tt.opts.Parse()
}
Expand Down Expand Up @@ -1550,3 +1559,96 @@ func Test_repo_commit(t *testing.T) {
})
}
}
func Test_validateRepoWritePermission(t *testing.T) {
tests := map[string]struct {
opts *PushOptions
wantErr bool
beforeFn func(r *mocks.MockRepository, w *mocks.MockWorktree)
}{
"Should fail if push context failed": {
opts: nil,
wantErr: true,
beforeFn: func(r *mocks.MockRepository, w *mocks.MockWorktree) {
r.EXPECT().PushContext(gomock.Any(), &gg.PushOptions{
Auth: nil,
Progress: os.Stderr,
}).
Times(1).
Return(fmt.Errorf("some error"))
w.EXPECT().AddGlob(gomock.Any()).
Times(1).
Return(nil)
w.EXPECT().Commit("Validating repository write permission", gomock.Any()).
Times(1).
Return(plumbing.Hash{}, nil)
},
},
"Should fail if commit failed": {
opts: nil,
wantErr: true,
beforeFn: func(r *mocks.MockRepository, w *mocks.MockWorktree) {
w.EXPECT().AddGlob(gomock.Any()).
Times(1).
Return(nil)
w.EXPECT().Commit("Validating repository write permission", gomock.Any()).
Times(1).
Return(plumbing.Hash{}, fmt.Errorf("some error"))
},
},
"Should succeed if push context succeed": {
opts: nil,
wantErr: false,
beforeFn: func(r *mocks.MockRepository, w *mocks.MockWorktree) {
r.EXPECT().PushContext(gomock.Any(), &gg.PushOptions{
Auth: nil,
Progress: os.Stderr,
}).
Times(1).
Return(nil)
w.EXPECT().AddGlob(gomock.Any()).
Times(1).
Return(nil)
w.EXPECT().Commit("Validating repository write permission", gomock.Any()).
Times(1).
Return(plumbing.Hash{}, nil)
},
},
}

gitConfig := &config.Config{
User: struct {
Name string
Email string
}{
Name: "name",
Email: "email",
},
}

for tname, tt := range tests {
t.Run(tname, func(t *testing.T) {
ctrl := gomock.NewController(t)
mockRepo := mocks.NewMockRepository(ctrl)
mockWt := mocks.NewMockWorktree(ctrl)
mockProvider := &mockProvider{}

mockRepo.EXPECT().ConfigScoped(gomock.Any()).Return(gitConfig, nil).AnyTimes()
getProvider = func(providerType, repoURL string, auth *Auth) (Provider, error) { return mockProvider, nil }
worktree = func(r gogit.Repository) (gogit.Worktree, error) { return mockWt, nil }

r := &repo{
Repository: mockRepo,
progress: os.Stderr,
}

tt.beforeFn(mockRepo, mockWt)

err := validateRepoWritePermission(context.Background(), r)
if (err != nil) != tt.wantErr {
t.Errorf("error = %v, wantErr %v", err, tt.wantErr)
return
}

})
}
}

0 comments on commit 8efa73d

Please sign in to comment.