diff --git a/cmd/drone-server/config/config.go b/cmd/drone-server/config/config.go index fc4f06f75..68970f1f9 100644 --- a/cmd/drone-server/config/config.go +++ b/cmd/drone-server/config/config.go @@ -80,13 +80,14 @@ type ( Yaml Yaml // Remote configurations - Bitbucket Bitbucket - Gitea Gitea - Github Github - GitLab GitLab - Gogs Gogs - Stash Stash - Gitee Gitee + Bitbucket Bitbucket + Gitea Gitea + Github Github + GitLab GitLab + Gogs Gogs + Stash Stash + Gitee Gitee + IncomingWebhook IncomingWebhook } // Cloning provides the cloning configuration. @@ -443,6 +444,10 @@ type ( ContentSecurityPolicy string `envconfig:"DRONE_HTTP_CONTENT_SECURITY_POLICY"` ReferrerPolicy string `envconfig:"DRONE_HTTP_REFERRER_POLICY"` } + + IncomingWebhook struct { + Events []string `envconfig:"DRONE_INCOMING_WEBHOOK_EVENTS" default:"branch,deployment,push,tag,pull_request"` + } ) // Environ returns the settings from the environment. diff --git a/cmd/drone-server/inject_service.go b/cmd/drone-server/inject_service.go index 25c9b8eb8..82a1313fe 100644 --- a/cmd/drone-server/inject_service.go +++ b/cmd/drone-server/inject_service.go @@ -85,7 +85,7 @@ func provideContentService(client *scm.Client, renewer core.Renewer) core.FileSe // provideHookService is a Wire provider function that returns a // hook service based on the environment configuration. func provideHookService(client *scm.Client, renewer core.Renewer, config config.Config) core.HookService { - return hook.New(client, config.Proxy.Addr, renewer) + return hook.New(client, config.Proxy.Addr, renewer, config.IncomingWebhook.Events) } // provideNetrcService is a Wire provider function that returns diff --git a/service/hook/hook.go b/service/hook/hook.go index eb4641916..fe23258be 100644 --- a/service/hook/hook.go +++ b/service/hook/hook.go @@ -23,14 +23,15 @@ import ( ) // New returns a new HookService. -func New(client *scm.Client, addr string, renew core.Renewer) core.HookService { - return &service{client: client, addr: addr, renew: renew} +func New(client *scm.Client, addr string, renew core.Renewer, events []string) core.HookService { + return &service{client: client, addr: addr, renew: renew, events: events} } type service struct { renew core.Renewer client *scm.Client addr string + events []string } func (s *service) Create(ctx context.Context, user *core.User, repo *core.Repository) error { @@ -38,6 +39,12 @@ func (s *service) Create(ctx context.Context, user *core.User, repo *core.Reposi if err != nil { return err } + + eventsMap := make(map[string]bool) + for _, event := range s.events { + eventsMap[event] = true + } + ctx = context.WithValue(ctx, scm.TokenKey{}, &scm.Token{ Token: user.Token, Refresh: user.Refresh, @@ -48,11 +55,11 @@ func (s *service) Create(ctx context.Context, user *core.User, repo *core.Reposi Target: s.addr + "/hook", Secret: repo.Signer, Events: scm.HookEvents{ - Branch: true, - Deployment: true, - PullRequest: true, - Push: true, - Tag: true, + Branch: eventsMap["branch"], + Deployment: eventsMap["deployment"], + PullRequest: eventsMap["pull_request"], + Push: eventsMap["push"], + Tag: eventsMap["tag"], }, } return replaceHook(ctx, s.client, repo.Slug, hook) diff --git a/service/hook/hook_test.go b/service/hook/hook_test.go index 10bf069be..14dfdab5b 100644 --- a/service/hook/hook_test.go +++ b/service/hook/hook_test.go @@ -50,11 +50,52 @@ func TestCreate(t *testing.T) { mockRepos := mockscm.NewMockRepositoryService(controller) mockRepos.EXPECT().ListHooks(gomock.Any(), "octocat/hello-world", gomock.Any()).Return(mockHooks, nil, nil) mockRepos.EXPECT().CreateHook(gomock.Any(), "octocat/hello-world", hook).Return(nil, nil, nil) - client := new(scm.Client) client.Repositories = mockRepos - service := New(client, "https://drone.company.com", mockRenewer) + service := New(client, "https://drone.company.com", mockRenewer, []string{"branch", "deployment", "push", "tag", "pull_request"}) + err := service.Create(noContext, mockUser, mockRepo) + if err != nil { + t.Error(err) + } +} + +func TestCreateWithLimitedEvents(t *testing.T) { + controller := gomock.NewController(t) + defer controller.Finish() + + mockUser := &core.User{} + mockHooks := []*scm.Hook{} + mockRepo := &core.Repository{ + Namespace: "octocat", + Name: "hello-world", + Slug: "octocat/hello-world", + Signer: "abc123", + } + + hook := &scm.HookInput{ + Name: "drone", + Target: "https://drone.company.com/hook", + Secret: "abc123", + Events: scm.HookEvents{ + Branch: false, + Deployment: true, + PullRequest: true, + Push: false, + Tag: true, + }, + } + + mockRenewer := mock.NewMockRenewer(controller) + mockRenewer.EXPECT().Renew(gomock.Any(), mockUser, false).Return(nil) + + mockRepos := mockscm.NewMockRepositoryService(controller) + mockRepos.EXPECT().ListHooks(gomock.Any(), "octocat/hello-world", gomock.Any()).Return(mockHooks, nil, nil) + mockRepos.EXPECT().CreateHook(gomock.Any(), "octocat/hello-world", hook).Return(nil, nil, nil) + client := new(scm.Client) + client.Repositories = mockRepos + + service := New(client, "https://drone.company.com", mockRenewer, []string{"deployment", "tag", "pull_request"}) err := service.Create(noContext, mockUser, mockRepo) if err != nil { t.Error(err) @@ -70,7 +111,7 @@ func TestCreate_RenewErr(t *testing.T) { mockRenewer := mock.NewMockRenewer(controller) mockRenewer.EXPECT().Renew(gomock.Any(), mockUser, false).Return(scm.ErrNotAuthorized) - service := New(nil, "https://drone.company.com", mockRenewer) + service := New(nil, "https://drone.company.com", mockRenewer, []string{}) err := service.Create(noContext, mockUser, nil) if err != scm.ErrNotAuthorized { t.Errorf("Want not authorized error, got %v", err) @@ -106,7 +147,7 @@ func TestDelete(t *testing.T) { client := new(scm.Client) client.Repositories = mockRepos - service := New(client, "https://drone.company.com", mockRenewer) + service := New(client, "https://drone.company.com", mockRenewer, []string{}) err := service.Delete(noContext, mockUser, mockRepo) if err != nil { t.Error(err) @@ -122,7 +163,7 @@ func TestDelete_RenewErr(t *testing.T) { mockRenewer := mock.NewMockRenewer(controller) mockRenewer.EXPECT().Renew(gomock.Any(), mockUser, false).Return(scm.ErrNotAuthorized) - service := New(nil, "https://drone.company.com", mockRenewer) + service := New(nil, "https://drone.company.com", mockRenewer, []string{}) err := service.Delete(noContext, mockUser, nil) if err != scm.ErrNotAuthorized { t.Errorf("Want not authorized error, got %v", err)