Skip to content

Commit

Permalink
Add headers dynamic to send on request (#182)
Browse files Browse the repository at this point in the history
* Add headers dynamic to send on request

* Adding unit test

* Fix fmt lint

* Update doc

* Update doc

* Fix test
  • Loading branch information
wiliansilvazup authored Dec 8, 2020
1 parent 8e3769e commit ecb4b12
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 4 deletions.
1 change: 1 addition & 0 deletions horusec-cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ All available flags are:
| HORUSEC_CLI_FALSE_POSITIVE_HASHES | horusecCliFalsePositiveHashes | false-positive | F | | Used to ignore vulnerability on analysis and setup with type `False positive`. ATTENTION when you add this configuration directly to the CLI, the configuration performed via the Horusec graphical interface will be overwritten. |
| HORUSEC_CLI_RISK_ACCEPT_HASHES | horusecCliRiskAcceptHashes | risk-accept | R | | Used to ignore vulnerability on analysis and setup with type `Risk accept`. ATTENTION when you add this configuration directly to the CLI, the configuration performed via the Horusec graphical interface will be overwritten. |
| HORUSEC_CLI_TOOLS_TO_IGNORE | horusecCliToolsToIgnore | tools-ignore | T | | Used to ignore tool on run horusec analysis. Available are: GoSec,SecurityCodeScan,Brakeman,Safety,Bandit,NpmAudit,YarnAudit,SpotBugs,HorusecKotlin,HorusecJava,HorusecLeaks,GitLeaks,TfSec,Semgrep,HorusecCsharp,HorusecNodeJS, HorusecKubernetes. Ex.: `T="GoSec, HorusecLeaks"` |
| HORUSEC_CLI_HEADERS | horusecCliHeaders | headers | | | Used to send dynamic headers on dispatch http request to horusec api service |
| | horusecCliWorkDir | | | | This setting tells to horusec the right directory to run a specific language. |
#### Authorization
Expand Down
3 changes: 3 additions & 0 deletions horusec-cli/cmd/horusec/start/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,9 @@ func (s *Start) loadFlags(cmd *cobra.Command) {
cmd.PersistentFlags().
StringVarP(&s.configs.RepositoryAuthorization, "authorization", "a", s.configs.GetRepositoryAuthorization(),
"The authorization token for the Horusec API")
cmd.PersistentFlags().
StringVar(&s.configs.Headers, "headers", s.configs.Headers,
"The headers dynamic to send on request in Horusec API. Example --headers=\"{\"X-Auth-Service\": \"my-value\"}\"")
cmd.PersistentFlags().
BoolVarP(&s.configs.ReturnErrorIfFoundVulnerability, "return-error", "e", s.configs.GetReturnErrorIfFoundVulnerability(),
"The return-error is the option to check if you can return \"exit(1)\" if found vulnerabilities. Example -e=\"true\"")
Expand Down
5 changes: 4 additions & 1 deletion horusec-cli/config/.example-horusec-cli.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,8 @@
"horusecCliRepositoryName": "horus",
"horusecCliFalsePositiveHashes": "hash1, hash2",
"horusecCliRiskAcceptHashes": "hash3, hash4",
"horusecCliToolsToIgnore": "GoSec"
"horusecCliToolsToIgnore": "GoSec",
"horusecCliHeaders": {
"X-Headers": "some-other-value"
}
}
25 changes: 25 additions & 0 deletions horusec-cli/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,9 @@ const (
// Used to ignore tools for run
// By default is empty
EnvToolsToIgnore = "HORUSEC_CLI_TOOLS_TO_IGNORE"
// Used send others headers on request to send in horusec-api
// By default is empty
EnvHeaders = "HORUSEC_CLI_HEADERS"
)

type Config struct {
Expand All @@ -162,6 +165,7 @@ type Config struct {
TimeoutInSecondsAnalysis int64
MonitorRetryInSeconds int64
RepositoryAuthorization string
Headers string
PrintOutputType string
JSONOutputFilePath string
TypesOfVulnerabilitiesToIgnore string
Expand Down Expand Up @@ -206,6 +210,7 @@ func (c *Config) SetConfigsFromViper() {
c.SetFalsePositiveHashes(viper.GetString(c.toLowerCamel(EnvFalsePositiveHashes)))
c.SetRiskAcceptHashes(viper.GetString(c.toLowerCamel(EnvRiskAcceptHashes)))
c.SetToolsToIgnore(viper.GetString(c.toLowerCamel(EnvToolsToIgnore)))
c.SetHeaders(viper.GetStringMapString(c.toLowerCamel(EnvHeaders)))
}

//nolint
Expand All @@ -232,6 +237,7 @@ func (c *Config) SetConfigsFromEnvironments() {
c.SetFalsePositiveHashes(env.GetEnvOrDefault(EnvFalsePositiveHashes, c.FalsePositiveHashes))
c.SetRiskAcceptHashes(env.GetEnvOrDefault(EnvRiskAcceptHashes, c.RiskAcceptHashes))
c.SetToolsToIgnore(env.GetEnvOrDefault(EnvToolsToIgnore, c.ToolsToIgnore))
c.SetHeaders(env.GetEnvOrDefault(EnvHeaders, c.Headers))
}

func (c *Config) GetHorusecAPIUri() string {
Expand Down Expand Up @@ -460,3 +466,22 @@ func (c *Config) GetToolsToIgnore() string {
func (c *Config) SetToolsToIgnore(toolsToIgnore string) {
c.ToolsToIgnore = toolsToIgnore
}

func (c *Config) GetHeaders() (headers map[string]string) {
err := json.Unmarshal([]byte(c.Headers), &headers)
logger.LogErrorWithLevel("Error on unmarshal headers to map", err, logger.ErrorLevel)
return headers
}

func (c *Config) SetHeaders(headers interface{}) {
if headers != nil && headers != "" {
headersString, ok := headers.(string)
if ok {
c.Headers = headersString
} else {
bytes, err := json.Marshal(headers)
logger.LogErrorWithLevel("Error on marshal headers to bytes", err, logger.ErrorLevel)
c.Headers = string(bytes)
}
}
}
11 changes: 11 additions & 0 deletions horusec-cli/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package config

import (
"encoding/json"
"os"
"testing"

Expand All @@ -41,6 +42,7 @@ func TestNewHorusecConfig(t *testing.T) {
assert.Equal(t, configs.CertPath, "")
assert.Equal(t, configs.CertInsecureSkipVerify, false)
assert.Equal(t, configs.ReturnErrorIfFoundVulnerability, false)
assert.Equal(t, configs.Headers, "")
path, _ := os.Getwd()
assert.Equal(t, configs.ProjectPath, path)
assert.Equal(t, configs.WorkDir, Config{}.WorkDir)
Expand All @@ -53,6 +55,7 @@ func TestNewHorusecConfig(t *testing.T) {
assert.Equal(t, configs.ToolsToIgnore, "")
assert.Equal(t, 0, len(configs.GetFalsePositiveHashesList()))
assert.Equal(t, 0, len(configs.GetRiskAcceptHashesList()))
assert.Equal(t, "", configs.Headers)
})
t.Run("Should change horusec config and return your new values", func(t *testing.T) {
configs := &Config{}
Expand All @@ -77,6 +80,7 @@ func TestNewHorusecConfig(t *testing.T) {
configs.SetFalsePositiveHashes("123456789")
configs.SetRiskAcceptHashes("987654321")
configs.SetToolsToIgnore("HorusecLeaks")
configs.SetHeaders(map[string]string{"header1": "value1"})
assert.NotEqual(t, configs.GetHorusecAPIUri(), "http://0.0.0.0:8000")
assert.NotEqual(t, configs.GetTimeoutInSecondsRequest(), int64(300))
assert.NotEqual(t, configs.GetTimeoutInSecondsAnalysis(), int64(600))
Expand All @@ -98,6 +102,7 @@ func TestNewHorusecConfig(t *testing.T) {
assert.NotEqual(t, configs.GetRiskAcceptHashes(), "")
assert.NotEqual(t, configs.GetToolsToIgnore(), "")
assert.NotNil(t, configs.GetWorkDir())
assert.NotEmpty(t, configs.GetHeaders())
})
t.Run("Should return horusec config using viper file", func(t *testing.T) {
path, err := os.Getwd()
Expand All @@ -120,6 +125,7 @@ func TestNewHorusecConfig(t *testing.T) {
assert.Equal(t, "./assets", configs.FilesOrPathsToIgnore)
assert.Equal(t, true, configs.ReturnErrorIfFoundVulnerability)
assert.Equal(t, "./", configs.ProjectPath)
assert.Equal(t, `{"x-headers":"some-other-value"}`, configs.Headers)
assert.Equal(t, wd, configs.WorkDir)
assert.Equal(t, configs.FilterPath, "./tmp")
assert.Equal(t, configs.EnableGitHistoryAnalysis, true)
Expand Down Expand Up @@ -158,6 +164,9 @@ func TestNewHorusecConfig(t *testing.T) {
assert.NoError(t, os.Setenv(EnvFalsePositiveHashes, "hash1, hash2"))
assert.NoError(t, os.Setenv(EnvRiskAcceptHashes, "hash3, hash4"))
assert.NoError(t, os.Setenv(EnvToolsToIgnore, "TfSec"))
headersBytes, err := json.Marshal(map[string]string{"X-other-header": "some-value"})
assert.NoError(t, err)
assert.NoError(t, os.Setenv(EnvHeaders, string(headersBytes)))
configs.SetConfigsFromEnvironments()
assert.Equal(t, "http://horusec.com", configs.HorusecAPIUri)
assert.Equal(t, int64(50), configs.TimeoutInSecondsRequest)
Expand All @@ -180,6 +189,7 @@ func TestNewHorusecConfig(t *testing.T) {
assert.Equal(t, "hash3, hash4", configs.RiskAcceptHashes)
assert.Equal(t, 2, len(configs.GetRiskAcceptHashesList()))
assert.Equal(t, "TfSec", configs.GetToolsToIgnore())
assert.Equal(t, map[string]string{"X-other-header": "some-value"}, configs.GetHeaders())
})
}

Expand All @@ -206,5 +216,6 @@ func TestToLowerCamel(t *testing.T) {
assert.Equal(t, "horusecCliFalsePositiveHashes", configs.toLowerCamel(EnvFalsePositiveHashes))
assert.Equal(t, "horusecCliRiskAcceptHashes", configs.toLowerCamel(EnvRiskAcceptHashes))
assert.Equal(t, "horusecCliToolsToIgnore", configs.toLowerCamel(EnvToolsToIgnore))
assert.Equal(t, "horusecCliHeaders", configs.toLowerCamel(EnvHeaders))
})
}
11 changes: 9 additions & 2 deletions horusec-cli/internal/services/horusapi/horus_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ func (s *Service) sendFindAnalysisRequest(analysisID uuid.UUID) (httpResponse.In
return nil, err
}

req.Header.Add("Authorization", s.config.GetRepositoryAuthorization())
s.addHeaders(req)
return s.httpUtil.DoRequest(req, tlsConfig)
}

Expand All @@ -105,7 +105,7 @@ func (s *Service) sendCreateAnalysisRequest(analysis *horusec.Analysis) (httpRes
return nil, err
}

req.Header.Add("Authorization", s.config.GetRepositoryAuthorization())
s.addHeaders(req)
return s.httpUtil.DoRequest(req, tlsConfig)
}

Expand Down Expand Up @@ -171,3 +171,10 @@ func (s *Service) newRequestData(analysis *horusec.Analysis) []byte {

return analysisData.ToBytes()
}

func (s *Service) addHeaders(req *http.Request) {
req.Header.Add("Authorization", s.config.GetRepositoryAuthorization())
for key, value := range s.config.GetHeaders() {
req.Header.Add(key, value)
}
}
2 changes: 1 addition & 1 deletion horusec-cli/internal/services/horusapi/horus_api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func TestSendAnalysis(t *testing.T) {

service := Service{
httpUtil: httpMock,
config: &cliConfig.Config{RepositoryAuthorization: "test"},
config: &cliConfig.Config{RepositoryAuthorization: "test", Headers: `{"some-header": "some-value"}`},
}

assert.NotPanics(t, func() {
Expand Down

0 comments on commit ecb4b12

Please sign in to comment.