Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 23 additions & 10 deletions pkg/analyzer/analyzers/datadog/datadog.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,19 @@ func (a Analyzer) Analyze(ctx context.Context, credInfo map[string]string) (*ana
// Get appKey if provided
appKey := credInfo["appKey"]

info, err := AnalyzePermissions(a.Cfg, apiKey, appKey)
// Endpoint
endpoint := credInfo["endpoint"]

info, err := AnalyzePermissions(a.Cfg, apiKey, appKey, endpoint)
if err != nil {
return nil, err
}

fmt.Printf("SecretInfo: %+v\n", info)
return secretInfoToAnalyzerResult(info), nil
}

func AnalyzeAndPrintPermissions(cfg *config.Config, apiKey string, appKey string) {
info, err := AnalyzePermissions(cfg, apiKey, appKey)
func AnalyzeAndPrintPermissions(cfg *config.Config, apiKey, appKey, endpoint string) {
info, err := AnalyzePermissions(cfg, apiKey, appKey, endpoint)
if err != nil {
// just print the error in cli and continue as a partial success
color.Red("[x] Error : %s", err.Error())
Expand All @@ -57,16 +60,23 @@ func AnalyzeAndPrintPermissions(cfg *config.Config, apiKey string, appKey string
}

// AnalyzePermissions will collect all the scopes assigned to token along with resource it can access
func AnalyzePermissions(cfg *config.Config, apiKey string, appKey string) (*SecretInfo, error) {
func AnalyzePermissions(cfg *config.Config, apiKey, appKey, endpoint string) (*SecretInfo, error) {
// create the http client
client := analyzers.NewAnalyzeClient(cfg)

var secretInfo = &SecretInfo{}

// First detect which DataDog domain works with this API key
baseURL, err := DetectDomain(client, apiKey, appKey)
if err != nil {
return nil, fmt.Errorf("[x] %v", err)
var baseURL string
var err error

// If endpoint is provided, use it directly; otherwise detect domain
if endpoint != "" {
baseURL = endpoint + "/api"
} else {
baseURL, err = DetectDomain(client, apiKey, appKey)
if err != nil {
return nil, fmt.Errorf("[x] %v", err)
}
Comment on lines +81 to +87
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is right, keeping the domain detection helps OSS.
In Enterprise, the Analyzer would only run after successfully detecting so I think we're good.

}

// capture user information in secretInfo
Expand Down Expand Up @@ -114,7 +124,10 @@ func secretInfoToAnalyzerResult(info *SecretInfo) *analyzers.AnalyzerResult {
}

permissionBindings := secretInfoPermissionsToAnalyzerPermission(info.Permissions)
result.Bindings = analyzers.BindAllPermissions(*userResource, *permissionBindings...)

if userResource != nil && len(*permissionBindings) > 0 {
result.Bindings = analyzers.BindAllPermissions(*userResource, *permissionBindings...)
}

// Extract information from resources to create bindings
for _, resource := range info.Resources {
Expand Down
34 changes: 28 additions & 6 deletions pkg/analyzer/analyzers/datadog/datadog_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,12 @@ func TestAnalyzer_Analyze(t *testing.T) {
}

tests := []struct {
name string
apiKey string
appKey string
want []byte // JSON string
wantErr bool
name string
apiKey string
appKey string
endpoint string
want []byte // JSON string
wantErr bool
}{
{
name: "valid datadog credentials",
Expand All @@ -51,6 +52,27 @@ func TestAnalyzer_Analyze(t *testing.T) {
want: expectedOutput,
wantErr: false,
},
{
name: "valid datadog credentials with endpoint",
apiKey: apiKey,
appKey: appKey,
endpoint: "https://api.us5.datadoghq.com",
want: expectedOutput,
wantErr: false,
},
{
name: "valid datadog credentials with invalid endpoint",
apiKey: apiKey,
appKey: appKey,
endpoint: "https://api.eu.datadoghq.com",
want: []byte(fmt.Sprintf(`{
"AnalyzerType": %s,
"Bindings": [],
"UnboundedResources": null,
"Metadata": {}
}`, analyzers.AnalyzerTypeDatadog)),
wantErr: true,
},
{
name: "invalid credentials",
apiKey: "invalid_api_key",
Expand All @@ -63,7 +85,7 @@ func TestAnalyzer_Analyze(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
a := Analyzer{Cfg: &config.Config{}}
got, err := a.Analyze(ctx, map[string]string{"apiKey": tt.apiKey, "appKey": tt.appKey})
got, err := a.Analyze(ctx, map[string]string{"apiKey": tt.apiKey, "appKey": tt.appKey, "endpoint": tt.endpoint})

if (err != nil) != tt.wantErr {
t.Errorf("Analyzer.Analyze() error = %v, wantErr %v", err, tt.wantErr)
Expand Down
Loading
Loading