diff --git a/core/util/utils.go b/core/util/utils.go index f26f5a6..bee836d 100644 --- a/core/util/utils.go +++ b/core/util/utils.go @@ -31,10 +31,16 @@ var ( slashRegex = regexp.MustCompile(`/+$`) ) -var DefaultScopes = []string{ - "integration_read", - "integration_write", -} +var ( + DefaultScopes = []string{ + "integration_read", + "integration_write", + } + DefaultCredentials = []string{ + "/api/integration-modules/{code}", + "/api/integration-modules/{code}/edit", + } +) var defaultCurrencies = map[string]string{ "rub": "₽", @@ -123,7 +129,9 @@ func (u *Utils) GenerateToken() string { } // GetAPIClient will initialize RetailCRM api client from url and key. -func (u *Utils) GetAPIClient(url, key string, scopes []string) (*retailcrm.Client, int, error) { +// Scopes will be used to determine if client is valid. If there are no scopes - credentials will be used instead. +func (u *Utils) GetAPIClient( + url, key string, scopes []string, credentials ...[]string) (*retailcrm.Client, int, error) { client := retailcrm.New(url, key). WithLogger(retailcrm.DebugLoggerAdapter(u.Logger)) client.Debug = u.IsDebug @@ -134,8 +142,15 @@ func (u *Utils) GetAPIClient(url, key string, scopes []string) (*retailcrm.Clien } if res := u.checkScopes(cr.Scopes, scopes); len(res) != 0 { - u.Logger.Error(url, status, res) - return nil, http.StatusBadRequest, errorutil.NewInsufficientScopesErr(res) + if len(credentials) == 0 || len(cr.Scopes) > 0 { + u.Logger.Error(url, status, res) + return nil, http.StatusBadRequest, errorutil.NewInsufficientScopesErr(res) + } + + if res := u.checkScopes(cr.Credentials, credentials[0]); len(res) != 0 { + u.Logger.Error(url, status, res) + return nil, http.StatusBadRequest, errorutil.NewInsufficientScopesErr(res) + } } return client, 0, nil diff --git a/core/util/utils_test.go b/core/util/utils_test.go index c3868eb..5843e12 100644 --- a/core/util/utils_test.go +++ b/core/util/utils_test.go @@ -97,7 +97,7 @@ func (u *UtilsTest) Test_GetAPIClient_FailAPI() { } } -func (u *UtilsTest) Test_GetAPIClient_FailAPICredentials() { +func (u *UtilsTest) Test_GetAPIClient_FailAPIScopes() { resp := retailcrm.CredentialResponse{ Success: true, Scopes: []string{}, @@ -120,6 +120,50 @@ func (u *UtilsTest) Test_GetAPIClient_FailAPICredentials() { } } +func (u *UtilsTest) Test_GetAPIClient_FailAPICredentials() { + resp := retailcrm.CredentialResponse{ + Success: true, + Credentials: []string{DefaultCredentials[0]}, + SiteAccess: "all", + SitesAvailable: []string{}, + } + + data, _ := json.Marshal(resp) + + defer gock.Off() + gock.New(testCRMURL). + Get("/credentials"). + Reply(http.StatusOK). + BodyString(string(data)) + + _, status, err := u.utils.GetAPIClient(testCRMURL, "key", DefaultScopes, DefaultCredentials) + assert.Equal(u.T(), http.StatusBadRequest, status) + if assert.NotNil(u.T(), err) { + assert.True(u.T(), errors.Is(err, errorutil.ErrInsufficientScopes)) + } +} + +func (u *UtilsTest) Test_GetAPIClient_SuccessCredentials() { + resp := retailcrm.CredentialResponse{ + Success: true, + Credentials: DefaultCredentials, + SiteAccess: "all", + SitesAvailable: []string{"site"}, + } + + data, _ := json.Marshal(resp) + + defer gock.Off() + gock.New(testCRMURL). + Get("/credentials"). + Reply(http.StatusOK). + BodyString(string(data)) + + _, status, err := u.utils.GetAPIClient(testCRMURL, "key", DefaultScopes, DefaultCredentials) + require.NoError(u.T(), err) + assert.Equal(u.T(), 0, status) +} + func (u *UtilsTest) Test_GetAPIClient_Success() { resp := retailcrm.CredentialResponse{ Success: true,