diff --git a/plugins/notifiers/client.go b/plugins/notifiers/client.go index b25301ed8..683c0b02c 100644 --- a/plugins/notifiers/client.go +++ b/plugins/notifiers/client.go @@ -21,7 +21,8 @@ type Config struct { Provider string `mapstructure:"provider" validate:"omitempty,oneof=slack"` // slack - Workspaces []slack.SlackWorkspace `mapstructure:"workspaces" validate:"required_if=Provider slack,dive"` + AccessToken string `mapstructure:"access_token" validate:"required_without=Workspaces"` + Workspaces []slack.SlackWorkspace `mapstructure:"workspaces" validate:"required_without=AccessToken,dive"` // custom messages Messages domain.NotificationMessages @@ -29,13 +30,49 @@ type Config struct { func NewClient(config *Config) (Client, error) { if config.Provider == ProviderTypeSlack { - slackConfig := &slack.Config{ - Workspaces: config.Workspaces, - Messages: config.Messages, + + slackConfig, err := NewSlackConfig(config) + if err != nil { + return nil, err } + httpClient := &http.Client{Timeout: 10 * time.Second} return slack.NewNotifier(slackConfig, httpClient), nil } return nil, errors.New("invalid notifier provider type") } + +func NewSlackConfig(config *Config) (*slack.Config, error) { + + // validation + if config.AccessToken == "" && len(config.Workspaces) == 0 { + return nil, errors.New("slack access token or workspaces must be provided") + } + if config.AccessToken != "" && len(config.Workspaces) != 0 { + return nil, errors.New("slack access token and workspaces cannot be provided at the same time") + } + + var slackConfig *slack.Config + if config.AccessToken != "" { + workspaces := []slack.SlackWorkspace{ + { + WorkspaceName: "default", + AccessToken: config.AccessToken, + Criteria: "1==1", + }, + } + slackConfig = &slack.Config{ + Workspaces: workspaces, + Messages: config.Messages, + } + return slackConfig, nil + } + + slackConfig = &slack.Config{ + Workspaces: config.Workspaces, + Messages: config.Messages, + } + + return slackConfig, nil +} diff --git a/plugins/notifiers/client_test.go b/plugins/notifiers/client_test.go new file mode 100644 index 000000000..c30cf12bd --- /dev/null +++ b/plugins/notifiers/client_test.go @@ -0,0 +1,111 @@ +package notifiers + +import ( + "github.com/goto/guardian/plugins/notifiers/slack" + "reflect" + "testing" +) + +func TestNewSlackConfig(t *testing.T) { + type args struct { + config *Config + } + tests := []struct { + name string + args args + want *slack.Config + wantErr bool + }{ + { + name: "should return error when no access token or workspaces are provided", + args: args{ + config: &Config{ + Provider: ProviderTypeSlack, + }, + }, + want: nil, + wantErr: true, + }, { + name: "should return error when both access token and workspaces are provided", + args: args{ + config: &Config{ + Provider: ProviderTypeSlack, + AccessToken: "foo", + Workspaces: []slack.SlackWorkspace{ + { + WorkspaceName: "default", + AccessToken: "bar", + Criteria: "1==1", + }, + }, + }, + }, + want: nil, + wantErr: true, + }, { + name: "should return slack config when access token is provided", + args: args{ + config: &Config{ + Provider: ProviderTypeSlack, + AccessToken: "foo", + }, + }, + want: &slack.Config{ + Workspaces: []slack.SlackWorkspace{ + { + WorkspaceName: "default", + AccessToken: "foo", + Criteria: "1==1", + }, + }, + }, + wantErr: false, + }, { + name: "should return slack config when workspaces are provided", + args: args{ + config: &Config{ + Provider: ProviderTypeSlack, + Workspaces: []slack.SlackWorkspace{ + { + WorkspaceName: "A", + AccessToken: "foo", + Criteria: "$email contains '@abc'", + }, + { + WorkspaceName: "B", + AccessToken: "bar", + Criteria: "$email contains '@xyz'", + }, + }, + }, + }, + want: &slack.Config{ + Workspaces: []slack.SlackWorkspace{ + { + WorkspaceName: "A", + AccessToken: "foo", + Criteria: "$email contains '@abc'", + }, + { + WorkspaceName: "B", + AccessToken: "bar", + Criteria: "$email contains '@xyz'", + }, + }, + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := NewSlackConfig(tt.args.config) + if (err != nil) != tt.wantErr { + t.Errorf("NewSlackConfig() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("NewSlackConfig() got = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/plugins/notifiers/slack/client_test.go b/plugins/notifiers/slack/client_test.go index 75b25fc87..77cfd181a 100644 --- a/plugins/notifiers/slack/client_test.go +++ b/plugins/notifiers/slack/client_test.go @@ -60,7 +60,6 @@ func (s *ClientTestSuite) TestNotify() { s.mockHttpClient.On("Do", mock.Anything).Return(resp, nil) expectedErrs := []error{ fmt.Errorf("[appeal_id=test-appeal-id] | %w", errors.New("error finding slack id for email test-user@abc.com in workspace: ws-1 - users_not_found")), - fmt.Errorf("[appeal_id=test-appeal-id] | error sending message to user:test-user@abc.com in workspace: | %w", errors.New("EOF")), } notifications := []domain.Notification{