diff --git a/internal/api/api.go b/internal/api/api.go index b6d526e07..4a56a364e 100644 --- a/internal/api/api.go +++ b/internal/api/api.go @@ -5,6 +5,7 @@ package api import ( "encoding/json" "fmt" + "github.com/snyk/go-application-framework/pkg/common" "io" "net/http" "net/url" @@ -21,7 +22,7 @@ type ApiClient interface { GetFeatureFlag(flagname string, origId string) (bool, error) GetUserMe() (string, error) GetSelf() (contract.SelfResponse, error) - GetSastSettings(orgId string) (contract.SastResponse, error) + GetSastSettings(orgId string) (common.SastResponse, error) } var _ ApiClient = (*snykApiClient)(nil) @@ -196,9 +197,9 @@ func (a *snykApiClient) GetSelf() (contract.SelfResponse, error) { return selfData, nil } -func (a *snykApiClient) GetSastSettings(orgId string) (contract.SastResponse, error) { - var response contract.SastResponse - var defaultResult contract.SastResponse +func (a *snykApiClient) GetSastSettings(orgId string) (common.SastResponse, error) { + var response common.SastResponse + var defaultResult common.SastResponse endpoint := a.url + "/v1/cli-config/settings/sast?org=" + url.QueryEscape(orgId) res, err := a.client.Get(endpoint) diff --git a/internal/mocks/api.go b/internal/mocks/api.go index fca44db62..65ee56996 100644 --- a/internal/mocks/api.go +++ b/internal/mocks/api.go @@ -10,6 +10,8 @@ import ( gomock "github.com/golang/mock/gomock" contract "github.com/snyk/go-application-framework/internal/api/contract" + + "github.com/snyk/go-application-framework/pkg/common" ) // MockApiClient is a mock of ApiClient interface. @@ -81,10 +83,10 @@ func (mr *MockApiClientMockRecorder) GetOrgIdFromSlug(slugName interface{}) *gom } // GetSastSettings mocks base method. -func (m *MockApiClient) GetSastSettings(orgId string) (contract.SastResponse, error) { +func (m *MockApiClient) GetSastSettings(orgId string) (common.SastResponse, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetSastSettings", orgId) - ret0, _ := ret[0].(contract.SastResponse) + ret0, _ := ret[0].(common.SastResponse) ret1, _ := ret[1].(error) return ret0, ret1 } diff --git a/pkg/app/app.go b/pkg/app/app.go index 12f0974d4..d570f18c3 100644 --- a/pkg/app/app.go +++ b/pkg/app/app.go @@ -44,6 +44,28 @@ func defaultFuncOrganizationSlug(engine workflow.Engine, config configuration.Co return callback } +func defaultFuncGetSastSettings(engine workflow.Engine, config configuration.Configuration, logger *zerolog.Logger, apiClientFactory func(url string, client *http.Client) api.ApiClient) configuration.DefaultValueFunction { + callback := func(existingValue interface{}) (interface{}, error) { + if existingValue != nil { + return existingValue, nil + } + client := engine.GetNetworkAccess().GetHttpClient() + url := config.GetString(configuration.API_URL) + apiClient := apiClientFactory(url, client) + orgId := config.GetString(configuration.ORGANIZATION) + if len(orgId) == 0 { + return existingValue, nil + } + response, err := apiClient.GetSastSettings(orgId) + if err != nil { + logger.Err(err).Msg("Failed to access settings.") + return false, err + } + return response, nil + } + return callback +} + func defaultFuncOrganization(engine workflow.Engine, config configuration.Configuration, logger *zerolog.Logger, apiClientFactory func(url string, client *http.Client) api.ApiClient) configuration.DefaultValueFunction { callback := func(existingValue interface{}) (interface{}, error) { client := engine.GetNetworkAccess().GetHttpClient() @@ -213,6 +235,7 @@ func initConfiguration(engine workflow.Engine, config configuration.Configuratio config.AddDefaultValue(configuration.ORGANIZATION, defaultFuncOrganization(engine, config, logger, apiClientFactory)) config.AddDefaultValue(configuration.ORGANIZATION_SLUG, defaultFuncOrganizationSlug(engine, config, logger, apiClientFactory)) + config.AddDefaultValue(configuration.SAST_SETTINGS, defaultFuncGetSastSettings(engine, config, logger, apiClientFactory)) config.AddDefaultValue(configuration.FF_OAUTH_AUTH_FLOW_ENABLED, func(existingValue any) (any, error) { if existingValue == nil { diff --git a/internal/api/contract/SastSettings.go b/pkg/common/sast_settings.go similarity index 97% rename from internal/api/contract/SastSettings.go rename to pkg/common/sast_settings.go index 520e793dc..b498768cd 100644 --- a/internal/api/contract/SastSettings.go +++ b/pkg/common/sast_settings.go @@ -1,4 +1,4 @@ -package contract +package common type LocalCodeEngine struct { AllowCloudUpload bool `json:"allowCloudUpload"` diff --git a/pkg/configuration/constants.go b/pkg/configuration/constants.go index 33eac8729..20dde7d51 100644 --- a/pkg/configuration/constants.go +++ b/pkg/configuration/constants.go @@ -38,6 +38,7 @@ const ( WORKING_DIRECTORY string = "internal_working_dir" IS_FEDRAMP string = "internal_is_fedramp" ORGANIZATION_SLUG string = "internal_org_slug" + SAST_SETTINGS string = "internal_sast_settings" AUTHENTICATION_SUBDOMAINS string = "internal_auth_subdomain" // array of additional subdomains to add authentication for AUTHENTICATION_ADDITIONAL_URLS string = "internal_additional_auth_urls" // array of additional urls to add authentication for ADD_TRUSTED_CA_FILE string = "internal_additional_trusted_ca_file" // pem file location containing additional CAs to trust diff --git a/pkg/configuration/storage.go b/pkg/configuration/storage.go index fe2b0a324..68212b840 100644 --- a/pkg/configuration/storage.go +++ b/pkg/configuration/storage.go @@ -3,6 +3,7 @@ package configuration import ( "context" "encoding/json" + "os" "path/filepath" "sync" diff --git a/pkg/local_workflows/code_workflow.go b/pkg/local_workflows/code_workflow.go index 34beab727..43f105757 100644 --- a/pkg/local_workflows/code_workflow.go +++ b/pkg/local_workflows/code_workflow.go @@ -8,8 +8,8 @@ import ( "github.com/spf13/pflag" "github.com/snyk/go-application-framework/internal/api" - "github.com/snyk/go-application-framework/internal/api/contract" "github.com/snyk/go-application-framework/internal/utils" + "github.com/snyk/go-application-framework/pkg/common" "github.com/snyk/go-application-framework/pkg/configuration" "github.com/snyk/go-application-framework/pkg/local_workflows/code_workflow" "github.com/snyk/go-application-framework/pkg/local_workflows/config_utils" @@ -45,18 +45,9 @@ func GetCodeFlagSet() *pflag.FlagSet { // WORKFLOWID_CODE defines a new workflow identifier var WORKFLOWID_CODE workflow.Identifier = workflow.NewWorkflowIdentifier(codeWorkflowName) -func getSastSettings(engine workflow.Engine) (*contract.SastResponse, error) { +func getSastSettings(engine workflow.Engine) (*common.SastResponse, error) { config := engine.GetConfiguration() org := config.GetString(configuration.ORGANIZATION) - key := fmt.Sprintf("CACHE_SAST_RESPONSE_%s", org) - - cachedContent := config.Get(key) - if cachedContent != nil { - cachedResponse, ok := cachedContent.(*contract.SastResponse) - if ok { - return cachedResponse, nil - } - } client := engine.GetNetworkAccess().GetHttpClient() url := config.GetString(configuration.API_URL) @@ -67,7 +58,7 @@ func getSastSettings(engine workflow.Engine) (*contract.SastResponse, error) { return &tmp, err } - engine.GetConfiguration().Set(key, &tmp) + engine.GetConfiguration().Set(org, &tmp) return &tmp, nil } @@ -151,6 +142,7 @@ func codeWorkflowEntryPoint(invocationCtx workflow.InvocationContext, _ []workfl logger := invocationCtx.GetEnhancedLogger() sastEnabledI, err := config.GetWithError(code_workflow.ConfigurationSastEnabled) + if err != nil { return result, err } diff --git a/pkg/local_workflows/code_workflow_test.go b/pkg/local_workflows/code_workflow_test.go index a71939672..52b549931 100644 --- a/pkg/local_workflows/code_workflow_test.go +++ b/pkg/local_workflows/code_workflow_test.go @@ -3,6 +3,7 @@ package localworkflows import ( "encoding/json" "fmt" + "github.com/snyk/go-application-framework/pkg/common" "math/rand" "net/http" "net/http/httptest" @@ -37,9 +38,9 @@ func Test_Code_entrypoint(t *testing.T) { fmt.Println(r.URL) if strings.HasSuffix(r.URL.String(), "/v1/cli-config/settings/sast?org="+org) { sastSettingsCalled++ - sastSettings := &contract.SastResponse{ + sastSettings := &common.SastResponse{ SastEnabled: true, - LocalCodeEngine: contract.LocalCodeEngine{ + LocalCodeEngine: common.LocalCodeEngine{ Enabled: true, /* ensures that legacycli will be called */ }, } @@ -98,7 +99,7 @@ func Test_Code_entrypoint(t *testing.T) { assert.NoError(t, err) assert.NotNil(t, rs) assert.Equal(t, expectedData, rs[0].GetPayload().(string)) - assert.Equal(t, 1, sastSettingsCalled) + assert.Equal(t, 2, sastSettingsCalled) } func Test_Code_legacyImplementation_happyPath(t *testing.T) {