From f8ec4594bf9e337f56dd1aa94b73a5ec5fe9be55 Mon Sep 17 00:00:00 2001 From: Danil Tarasov <87192879+almostinf@users.noreply.github.com> Date: Thu, 23 May 2024 18:09:07 +0300 Subject: [PATCH] feat(api): forbidden create unresolved contact type (#1030) --- api/config.go | 5 +- api/controller/contact.go | 34 ++++- api/controller/contact_test.go | 228 +++++++++++++++++++++++++-------- api/handler/contact.go | 7 +- api/handler/contact_test.go | 23 +++- api/handler/team_contact.go | 1 + cmd/api/config.go | 19 ++- cmd/api/config_test.go | 13 +- cmd/api/main.go | 1 + 9 files changed, 268 insertions(+), 63 deletions(-) diff --git a/api/config.go b/api/config.go index 22aceee39..09d444c55 100644 --- a/api/config.go +++ b/api/config.go @@ -42,8 +42,9 @@ type Config struct { // Authorization contains authorization configuration. type Authorization struct { - AdminList map[string]struct{} - Enabled bool + AdminList map[string]struct{} + Enabled bool + AllowedContactTypes map[string]struct{} } // IsEnabled returns true if auth is enabled and false otherwise. diff --git a/api/controller/contact.go b/api/controller/contact.go index 41482cf94..cbae223a9 100644 --- a/api/controller/contact.go +++ b/api/controller/contact.go @@ -15,6 +15,9 @@ import ( "github.com/moira-alert/moira/database" ) +// ErrNotAllowedContactType means that this type of contact is not allowed to be created. +var ErrNotAllowedContactType = errors.New("cannot create contact with not allowed contact type") + // GetAllContacts gets all moira contacts. func GetAllContacts(database moira.Database) (*dto.ContactList, *api.ErrorResponse) { contacts, err := database.GetAllContacts() @@ -47,11 +50,21 @@ func GetContactById(database moira.Database, contactID string) (*dto.Contact, *a } // CreateContact creates new notification contact for current user. -func CreateContact(dataBase moira.Database, auth *api.Authorization, contact *dto.Contact, userLogin, teamID string) *api.ErrorResponse { +func CreateContact( + dataBase moira.Database, + auth *api.Authorization, + contact *dto.Contact, + userLogin, + teamID string, +) *api.ErrorResponse { if userLogin != "" && teamID != "" { return api.ErrorInternalServer(fmt.Errorf("CreateContact: cannot create contact when both userLogin and teamID specified")) } + if !isAllowedContactType(auth, userLogin, contact.Type) { + return api.ErrorInvalidRequest(ErrNotAllowedContactType) + } + // Only admins are allowed to create contacts for other users if !auth.IsAdmin(userLogin) || contact.User == "" { contact.User = userLogin @@ -91,7 +104,16 @@ func CreateContact(dataBase moira.Database, auth *api.Authorization, contact *dt } // UpdateContact updates notification contact for current user. -func UpdateContact(dataBase moira.Database, contactDTO dto.Contact, contactData moira.ContactData) (dto.Contact, *api.ErrorResponse) { +func UpdateContact( + dataBase moira.Database, + auth *api.Authorization, + contactDTO dto.Contact, + contactData moira.ContactData, +) (dto.Contact, *api.ErrorResponse) { + if !isAllowedContactType(auth, contactDTO.User, contactDTO.Type) { + return contactDTO, api.ErrorInvalidRequest(ErrNotAllowedContactType) + } + contactData.Type = contactDTO.Type contactData.Value = contactDTO.Value contactData.Name = contactDTO.Name @@ -227,3 +249,11 @@ func isContactExists(dataBase moira.Database, contactID string) (bool, error) { } return true, nil } + +func isAllowedContactType(auth *api.Authorization, userLogin string, contactType string) bool { + isAdmin := auth.IsAdmin(userLogin) + + _, isAllowedContact := auth.AllowedContactTypes[contactType] + + return isAllowedContact || isAdmin +} diff --git a/api/controller/contact_test.go b/api/controller/contact_test.go index 06c0087da..f4b7e575b 100644 --- a/api/controller/contact_test.go +++ b/api/controller/contact_test.go @@ -111,15 +111,27 @@ func TestCreateContact(t *testing.T) { mockCtrl := gomock.NewController(t) dataBase := mock_moira_alert.NewMockDatabase(mockCtrl) defer mockCtrl.Finish() - const userLogin = "user" - const teamID = "team" - auth := &api.Authorization{Enabled: false} + + const ( + userLogin = "user" + teamID = "team" + contactType = "mail" + notAllowedContactType = "mattermost" + contactValue = "some@mail.com" + ) + + auth := &api.Authorization{ + Enabled: false, + AllowedContactTypes: map[string]struct{}{ + contactType: {}, + }, + } Convey("Create for user", t, func() { Convey("Success", func() { contact := &dto.Contact{ - Value: "some@mail.com", - Type: "mail", + Value: contactValue, + Type: contactType, } dataBase.EXPECT().SaveContact(gomock.Any()).Return(nil) err := CreateContact(dataBase, auth, contact, userLogin, "") @@ -130,8 +142,8 @@ func TestCreateContact(t *testing.T) { Convey("Success with id", func() { contact := dto.Contact{ ID: uuid.Must(uuid.NewV4()).String(), - Value: "some@mail.com", - Type: "mail", + Value: contactValue, + Type: contactType, } expectedContact := moira.ContactData{ ID: contact.ID, @@ -150,8 +162,8 @@ func TestCreateContact(t *testing.T) { Convey("Contact exists by id", func() { contact := &dto.Contact{ ID: uuid.Must(uuid.NewV4()).String(), - Value: "some@mail.com", - Type: "mail", + Value: contactValue, + Type: contactType, } dataBase.EXPECT().GetContact(contact.ID).Return(moira.ContactData{}, nil) err := CreateContact(dataBase, auth, contact, userLogin, "") @@ -161,8 +173,8 @@ func TestCreateContact(t *testing.T) { Convey("Error get contact", func() { contact := &dto.Contact{ ID: uuid.Must(uuid.NewV4()).String(), - Value: "some@mail.com", - Type: "mail", + Value: contactValue, + Type: contactType, } err := fmt.Errorf("oooops! Can not write contact") dataBase.EXPECT().GetContact(contact.ID).Return(moira.ContactData{}, err) @@ -170,10 +182,21 @@ func TestCreateContact(t *testing.T) { So(expected, ShouldResemble, api.ErrorInternalServer(err)) }) + Convey("Error create now allowed contact", func() { + contact := &dto.Contact{ + ID: uuid.Must(uuid.NewV4()).String(), + Value: contactValue, + Type: notAllowedContactType, + } + expectedErr := api.ErrorInvalidRequest(ErrNotAllowedContactType) + err := CreateContact(dataBase, auth, contact, userLogin, "") + So(err, ShouldResemble, expectedErr) + }) + Convey("Error save contact", func() { contact := &dto.Contact{ - Value: "some@mail.com", - Type: "mail", + Value: contactValue, + Type: contactType, } err := fmt.Errorf("oooops! Can not write contact") dataBase.EXPECT().SaveContact(gomock.Any()).Return(err) @@ -190,8 +213,8 @@ func TestCreateContact(t *testing.T) { Convey("Create for team", t, func() { Convey("Success", func() { contact := &dto.Contact{ - Value: "some@mail.com", - Type: "mail", + Value: contactValue, + Type: contactType, } dataBase.EXPECT().SaveContact(gomock.Any()).Return(nil) err := CreateContact(dataBase, auth, contact, "", teamID) @@ -202,8 +225,8 @@ func TestCreateContact(t *testing.T) { Convey("Success with id", func() { contact := dto.Contact{ ID: uuid.Must(uuid.NewV4()).String(), - Value: "some@mail.com", - Type: "mail", + Value: contactValue, + Type: contactType, } expectedContact := moira.ContactData{ ID: contact.ID, @@ -222,8 +245,8 @@ func TestCreateContact(t *testing.T) { Convey("Success with custom name", func() { contact := dto.Contact{ ID: uuid.Must(uuid.NewV4()).String(), - Value: "some@mail.com", - Type: "mail", + Value: contactValue, + Type: contactType, Name: "some-name", } expectedContact := moira.ContactData{ @@ -244,8 +267,8 @@ func TestCreateContact(t *testing.T) { Convey("Contact exists by id", func() { contact := &dto.Contact{ ID: uuid.Must(uuid.NewV4()).String(), - Value: "some@mail.com", - Type: "mail", + Value: contactValue, + Type: contactType, } dataBase.EXPECT().GetContact(contact.ID).Return(moira.ContactData{}, nil) err := CreateContact(dataBase, auth, contact, "", teamID) @@ -255,8 +278,8 @@ func TestCreateContact(t *testing.T) { Convey("Error get contact", func() { contact := &dto.Contact{ ID: uuid.Must(uuid.NewV4()).String(), - Value: "some@mail.com", - Type: "mail", + Value: contactValue, + Type: contactType, } err := fmt.Errorf("oooops! Can not write contact") dataBase.EXPECT().GetContact(contact.ID).Return(moira.ContactData{}, err) @@ -264,10 +287,21 @@ func TestCreateContact(t *testing.T) { So(expected, ShouldResemble, api.ErrorInternalServer(err)) }) + Convey("Error create not allowed contact", func() { + contact := &dto.Contact{ + ID: uuid.Must(uuid.NewV4()).String(), + Value: contactValue, + Type: notAllowedContactType, + } + expectedErr := api.ErrorInvalidRequest(ErrNotAllowedContactType) + err := CreateContact(dataBase, auth, contact, "", teamID) + So(err, ShouldResemble, expectedErr) + }) + Convey("Error save contact", func() { contact := &dto.Contact{ - Value: "some@mail.com", - Type: "mail", + Value: contactValue, + Type: contactType, } err := fmt.Errorf("oooops! Can not write contact") dataBase.EXPECT().SaveContact(gomock.Any()).Return(err) @@ -280,10 +314,11 @@ func TestCreateContact(t *testing.T) { }) }) }) + Convey("Error on create with both: userLogin and teamID specified", t, func() { contact := &dto.Contact{ - Value: "some@mail.com", - Type: "mail", + Value: contactValue, + Type: contactType, } err := CreateContact(dataBase, auth, contact, userLogin, teamID) So(err, ShouldResemble, api.ErrorInternalServer(fmt.Errorf("CreateContact: cannot create contact when both userLogin and teamID specified"))) @@ -294,18 +329,28 @@ func TestAdminsCreatesContact(t *testing.T) { mockCtrl := gomock.NewController(t) dataBase := mock_moira_alert.NewMockDatabase(mockCtrl) defer mockCtrl.Finish() - const userLogin = "user" - const adminLogin = "admin" + + const ( + userLogin = "user" + adminLogin = "admin" + contactType = "mail" + notAllowedContactType = "mattermost" + contactValue = "some@mail.com" + ) + auth := &api.Authorization{ Enabled: true, AdminList: map[string]struct{}{adminLogin: {}}, + AllowedContactTypes: map[string]struct{}{ + contactType: {}, + }, } Convey("Create for user", t, func() { Convey("The same user", func() { contact := &dto.Contact{ - Value: "some@mail.com", - Type: "mail", + Value: contactValue, + Type: contactType, User: userLogin, } dataBase.EXPECT().SaveContact(gomock.Any()).Return(nil) @@ -316,8 +361,8 @@ func TestAdminsCreatesContact(t *testing.T) { Convey("The same user by admin", func() { contact := &dto.Contact{ - Value: "some@mail.com", - Type: "mail", + Value: contactValue, + Type: contactType, User: adminLogin, } dataBase.EXPECT().SaveContact(gomock.Any()).Return(nil) @@ -328,8 +373,8 @@ func TestAdminsCreatesContact(t *testing.T) { Convey("Non admin can not create contact for other user", func() { contact := &dto.Contact{ - Value: "some@mail.com", - Type: "mail", + Value: contactValue, + Type: contactType, User: adminLogin, } dataBase.EXPECT().SaveContact(gomock.Any()).Return(nil) @@ -340,8 +385,20 @@ func TestAdminsCreatesContact(t *testing.T) { Convey("Admin can create contact for other user", func() { contact := &dto.Contact{ - Value: "some@mail.com", - Type: "mail", + Value: contactValue, + Type: contactType, + User: userLogin, + } + dataBase.EXPECT().SaveContact(gomock.Any()).Return(nil) + err := CreateContact(dataBase, auth, contact, adminLogin, "") + So(err, ShouldBeNil) + So(contact.User, ShouldResemble, userLogin) + }) + + Convey("Admin can create not allowed contact", func() { + contact := &dto.Contact{ + Value: contactValue, + Type: notAllowedContactType, User: userLogin, } dataBase.EXPECT().SaveContact(gomock.Any()).Return(nil) @@ -356,15 +413,28 @@ func TestUpdateContact(t *testing.T) { mockCtrl := gomock.NewController(t) dataBase := mock_moira_alert.NewMockDatabase(mockCtrl) defer mockCtrl.Finish() - const userLogin = "user" - const teamID = "team" + + const ( + userLogin = "user" + teamID = "team" + contactType = "mail" + contactValue = "some@mail.com" + notAllowedContactType = "mattermost" + ) + + auth := &api.Authorization{ + Enabled: false, + AllowedContactTypes: map[string]struct{}{ + contactType: {}, + }, + } Convey("User update", t, func() { Convey("Success", func() { contactDTO := dto.Contact{ - Value: "some@mail.com", + Value: contactValue, Name: "some-name", - Type: "mail", + Type: contactType, } contactID := uuid.Must(uuid.NewV4()).String() contact := moira.ContactData{ @@ -375,17 +445,31 @@ func TestUpdateContact(t *testing.T) { User: userLogin, } dataBase.EXPECT().SaveContact(&contact).Return(nil) - expectedContact, err := UpdateContact(dataBase, contactDTO, moira.ContactData{ID: contactID, User: userLogin}) + expectedContact, err := UpdateContact(dataBase, auth, contactDTO, moira.ContactData{ID: contactID, User: userLogin}) So(err, ShouldBeNil) So(expectedContact.User, ShouldResemble, userLogin) So(expectedContact.ID, ShouldResemble, contactID) So(expectedContact.Name, ShouldResemble, contactDTO.Name) }) + Convey("Error update not allowed contact", func() { + contactDTO := dto.Contact{ + Value: contactValue, + Type: notAllowedContactType, + } + expectedErr := api.ErrorInvalidRequest(ErrNotAllowedContactType) + contactID := uuid.Must(uuid.NewV4()).String() + expectedContact, err := UpdateContact(dataBase, auth, contactDTO, moira.ContactData{ID: contactID, User: userLogin}) + So(err, ShouldResemble, expectedErr) + So(expectedContact.User, ShouldResemble, contactDTO.User) + So(expectedContact.ID, ShouldResemble, contactDTO.ID) + So(expectedContact.Name, ShouldResemble, contactDTO.Name) + }) + Convey("Error save", func() { contactDTO := dto.Contact{ - Value: "some@mail.com", - Type: "mail", + Value: contactValue, + Type: contactType, } contactID := uuid.Must(uuid.NewV4()).String() contact := moira.ContactData{ @@ -396,17 +480,18 @@ func TestUpdateContact(t *testing.T) { } err := fmt.Errorf("oooops") dataBase.EXPECT().SaveContact(&contact).Return(err) - expectedContact, actual := UpdateContact(dataBase, contactDTO, contact) + expectedContact, actual := UpdateContact(dataBase, auth, contactDTO, contact) So(actual, ShouldResemble, api.ErrorInternalServer(err)) So(expectedContact.User, ShouldResemble, contactDTO.User) So(expectedContact.ID, ShouldResemble, contactDTO.ID) }) }) + Convey("Team update", t, func() { Convey("Success", func() { contactDTO := dto.Contact{ - Value: "some@mail.com", - Type: "mail", + Value: contactValue, + Type: contactType, } contactID := uuid.Must(uuid.NewV4()).String() contact := moira.ContactData{ @@ -416,7 +501,7 @@ func TestUpdateContact(t *testing.T) { Team: teamID, } dataBase.EXPECT().SaveContact(&contact).Return(nil) - expectedContact, err := UpdateContact(dataBase, contactDTO, moira.ContactData{ID: contactID, Team: teamID}) + expectedContact, err := UpdateContact(dataBase, auth, contactDTO, moira.ContactData{ID: contactID, Team: teamID}) So(err, ShouldBeNil) So(expectedContact.TeamID, ShouldResemble, teamID) So(expectedContact.ID, ShouldResemble, contactID) @@ -424,8 +509,8 @@ func TestUpdateContact(t *testing.T) { Convey("Error save", func() { contactDTO := dto.Contact{ - Value: "some@mail.com", - Type: "mail", + Value: contactValue, + Type: contactType, } contactID := uuid.Must(uuid.NewV4()).String() contact := moira.ContactData{ @@ -436,7 +521,7 @@ func TestUpdateContact(t *testing.T) { } err := fmt.Errorf("oooops") dataBase.EXPECT().SaveContact(&contact).Return(err) - expectedContact, actual := UpdateContact(dataBase, contactDTO, contact) + expectedContact, actual := UpdateContact(dataBase, auth, contactDTO, contact) So(actual, ShouldResemble, api.ErrorInternalServer(err)) So(expectedContact.TeamID, ShouldResemble, contactDTO.TeamID) So(expectedContact.ID, ShouldResemble, contactDTO.ID) @@ -444,6 +529,47 @@ func TestUpdateContact(t *testing.T) { }) } +func TestIsAllowedContactType(t *testing.T) { + const ( + admin = "admin" + user = "user" + allowedContactType = "slack" + notAllowedContactType = "mattermost" + ) + + auth := &api.Authorization{ + Enabled: true, + AdminList: map[string]struct{}{ + admin: {}, + }, + AllowedContactTypes: map[string]struct{}{ + allowedContactType: {}, + }, + } + + Convey("Test isAllowedContactType", t, func() { + Convey("Test with user and allowed contact type", func() { + isAllowed := isAllowedContactType(auth, user, allowedContactType) + So(isAllowed, ShouldBeTrue) + }) + + Convey("Test with user and not allowed contact type", func() { + isAllowed := isAllowedContactType(auth, user, notAllowedContactType) + So(isAllowed, ShouldBeFalse) + }) + + Convey("Test with admin and allowed contact type", func() { + isAllowed := isAllowedContactType(auth, admin, allowedContactType) + So(isAllowed, ShouldBeTrue) + }) + + Convey("Test with admin and not allowed contact type", func() { + isAllowed := isAllowedContactType(auth, admin, notAllowedContactType) + So(isAllowed, ShouldBeTrue) + }) + }) +} + func TestRemoveContact(t *testing.T) { const userLogin = "user" const teamID = "team" diff --git a/api/handler/contact.go b/api/handler/contact.go index 2b41d7ac6..ba31d1f2d 100644 --- a/api/handler/contact.go +++ b/api/handler/contact.go @@ -98,6 +98,7 @@ func createNewContact(writer http.ResponseWriter, request *http.Request) { render.Render(writer, request, api.ErrorInvalidRequest(err)) //nolint return } + userLogin := middleware.GetLogin(request) auth := middleware.GetAuth(request) @@ -150,13 +151,17 @@ func updateContact(writer http.ResponseWriter, request *http.Request) { render.Render(writer, request, api.ErrorInvalidRequest(err)) //nolint return } + contactData := request.Context().Value(contactKey).(moira.ContactData) - contactDTO, err := controller.UpdateContact(database, contactDTO, contactData) + auth := middleware.GetAuth(request) + + contactDTO, err := controller.UpdateContact(database, auth, contactDTO, contactData) if err != nil { render.Render(writer, request, err) //nolint return } + if err := render.Render(writer, request, &contactDTO); err != nil { render.Render(writer, request, api.ErrorRender(err)) //nolint } diff --git a/api/handler/contact_test.go b/api/handler/contact_test.go index 2801f9cef..6deb8b71d 100644 --- a/api/handler/contact_test.go +++ b/api/handler/contact_test.go @@ -22,6 +22,7 @@ import ( const ( ContactIDKey = "contactID" ContactKey = "contact" + AuthKey = "auth" LoginKey = "login" defaultContact = "testContact" defaultLogin = "testLogin" @@ -195,7 +196,12 @@ func TestCreateNewContact(t *testing.T) { login := defaultLogin testErr := errors.New("test error") - auth := &api.Authorization{Enabled: false} + auth := &api.Authorization{ + Enabled: false, + AllowedContactTypes: map[string]struct{}{ + "mail": {}, + }, + } newContactDto := &dto.Contact{ ID: defaultContact, @@ -223,7 +229,7 @@ func TestCreateNewContact(t *testing.T) { testRequest := httptest.NewRequest(http.MethodPut, "/contact", bytes.NewBuffer(jsonContact)) testRequest = testRequest.WithContext(middleware.SetContextValueForTest(testRequest.Context(), LoginKey, login)) - testRequest = testRequest.WithContext(middleware.SetContextValueForTest(testRequest.Context(), "auth", auth)) + testRequest = testRequest.WithContext(middleware.SetContextValueForTest(testRequest.Context(), AuthKey, auth)) testRequest.Header.Add("content-type", "application/json") createNewContact(responseWriter, testRequest) @@ -413,6 +419,7 @@ func TestUpdateContact(t *testing.T) { database = mockDb testRequest := httptest.NewRequest(http.MethodPut, "/contact/"+contactID, bytes.NewBuffer(jsonContact)) + testRequest = testRequest.WithContext(middleware.SetContextValueForTest(testRequest.Context(), ContactKey, moira.ContactData{ ID: contactID, Name: updatedContactDto.Name, @@ -420,6 +427,12 @@ func TestUpdateContact(t *testing.T) { Value: updatedContactDto.Value, User: updatedContactDto.User, })) + testRequest = testRequest.WithContext(middleware.SetContextValueForTest(testRequest.Context(), AuthKey, &api.Authorization{ + AllowedContactTypes: map[string]struct{}{ + updatedContactDto.Type: {}, + }, + })) + testRequest.Header.Add("content-type", "application/json") updateContact(responseWriter, testRequest) @@ -461,6 +474,12 @@ func TestUpdateContact(t *testing.T) { Value: updatedContactDto.Value, User: updatedContactDto.User, })) + testRequest = testRequest.WithContext(middleware.SetContextValueForTest(testRequest.Context(), AuthKey, &api.Authorization{ + AllowedContactTypes: map[string]struct{}{ + updatedContactDto.Type: {}, + }, + })) + testRequest.Header.Add("content-type", "application/json") updateContact(responseWriter, testRequest) diff --git a/api/handler/team_contact.go b/api/handler/team_contact.go index e7dd5bcd7..8d515afba 100644 --- a/api/handler/team_contact.go +++ b/api/handler/team_contact.go @@ -37,6 +37,7 @@ func createNewTeamContact(writer http.ResponseWriter, request *http.Request) { render.Render(writer, request, api.ErrorInvalidRequest(err)) //nolint:errcheck return } + teamID := middleware.GetTeamID(request) auth := middleware.GetAuth(request) diff --git a/cmd/api/config.go b/cmd/api/config.go index 3dbf05bec..bfd5ca3eb 100644 --- a/cmd/api/config.go +++ b/cmd/api/config.go @@ -108,29 +108,39 @@ type featureFlags struct { func (config *apiConfig) getSettings( metricsTTL map[moira.ClusterKey]time.Duration, flags api.FeatureFlags, + webConfig *webConfig, ) *api.Config { return &api.Config{ EnableCORS: config.EnableCORS, Listen: config.Listen, MetricsTTL: metricsTTL, Flags: flags, - Authorization: config.Authorization.toApiConfig(), + Authorization: config.Authorization.toApiConfig(webConfig), } } -func (auth *authorization) toApiConfig() api.Authorization { +func (auth *authorization) toApiConfig(webConfig *webConfig) api.Authorization { adminList := make(map[string]struct{}, len(auth.AdminList)) for _, admin := range auth.AdminList { adminList[admin] = struct{}{} } + + allowedContactTypes := make(map[string]struct{}, len(webConfig.ContactsTemplate)) + + for _, contactTemplate := range webConfig.ContactsTemplate { + allowedContactTypes[contactTemplate.ContactType] = struct{}{} + } + return api.Authorization{ - Enabled: auth.Enabled, - AdminList: adminList, + Enabled: auth.Enabled, + AdminList: adminList, + AllowedContactTypes: allowedContactTypes, } } func (config *webConfig) getSettings(isRemoteEnabled bool, remotes cmd.RemotesConfig) *api.WebConfig { webContacts := make([]api.WebContact, 0, len(config.ContactsTemplate)) + for _, contactTemplate := range config.ContactsTemplate { contact := api.WebContact{ ContactType: contactTemplate.ContactType, @@ -140,6 +150,7 @@ func (config *webConfig) getSettings(isRemoteEnabled bool, remotes cmd.RemotesCo Placeholder: contactTemplate.Placeholder, Help: contactTemplate.Help, } + webContacts = append(webContacts, contact) } diff --git a/cmd/api/config_test.go b/cmd/api/config_test.go index d72c42525..782fcf301 100644 --- a/cmd/api/config_test.go +++ b/cmd/api/config_test.go @@ -19,6 +19,14 @@ func Test_apiConfig_getSettings(t *testing.T) { moira.DefaultGraphiteRemoteCluster: 24 * time.Hour, } + webConfig := &webConfig{ + ContactsTemplate: []webContact{ + { + ContactType: "test", + }, + }, + } + apiConf := apiConfig{ Listen: "0000", EnableCORS: true, @@ -31,10 +39,13 @@ func Test_apiConfig_getSettings(t *testing.T) { Flags: api.FeatureFlags{IsReadonlyEnabled: true}, Authorization: api.Authorization{ AdminList: make(map[string]struct{}), + AllowedContactTypes: map[string]struct{}{ + "test": {}, + }, }, } - result := apiConf.getSettings(metricTTLs, api.FeatureFlags{IsReadonlyEnabled: true}) + result := apiConf.getSettings(metricTTLs, api.FeatureFlags{IsReadonlyEnabled: true}, webConfig) So(result, ShouldResemble, expectedResult) }) } diff --git a/cmd/api/main.go b/cmd/api/main.go index 65face808..9f87d2fd9 100644 --- a/cmd/api/main.go +++ b/cmd/api/main.go @@ -61,6 +61,7 @@ func main() { apiConfig := applicationConfig.API.getSettings( applicationConfig.ClustersMetricTTL(), applicationConfig.Web.getFeatureFlags(), + &applicationConfig.Web, ) logger, err := logging.ConfigureLog(applicationConfig.Logger.LogFile, applicationConfig.Logger.LogLevel, serviceName, applicationConfig.Logger.LogPrettyFormat)