diff --git a/github/github-accessors.go b/github/github-accessors.go index 679f7eb7123..5b5215f99e9 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -25598,6 +25598,134 @@ func (s *SecretScanningAlertUpdateOptions) GetResolutionComment() string { return *s.ResolutionComment } +// GetCustomPatternVersion returns the CustomPatternVersion field if it's non-nil, zero value otherwise. +func (s *SecretScanningCustomPatternSetting) GetCustomPatternVersion() string { + if s == nil || s.CustomPatternVersion == nil { + return "" + } + return *s.CustomPatternVersion +} + +// GetPatternConfigVersion returns the PatternConfigVersion field if it's non-nil, zero value otherwise. +func (s *SecretScanningPatternConfigs) GetPatternConfigVersion() string { + if s == nil || s.PatternConfigVersion == nil { + return "" + } + return *s.PatternConfigVersion +} + +// GetPatternConfigVersion returns the PatternConfigVersion field if it's non-nil, zero value otherwise. +func (s *SecretScanningPatternConfigsUpdate) GetPatternConfigVersion() string { + if s == nil || s.PatternConfigVersion == nil { + return "" + } + return *s.PatternConfigVersion +} + +// GetPatternConfigVersion returns the PatternConfigVersion field if it's non-nil, zero value otherwise. +func (s *SecretScanningPatternConfigsUpdateOptions) GetPatternConfigVersion() string { + if s == nil || s.PatternConfigVersion == nil { + return "" + } + return *s.PatternConfigVersion +} + +// GetAlertTotal returns the AlertTotal field if it's non-nil, zero value otherwise. +func (s *SecretScanningPatternOverride) GetAlertTotal() int { + if s == nil || s.AlertTotal == nil { + return 0 + } + return *s.AlertTotal +} + +// GetAlertTotalPercentage returns the AlertTotalPercentage field if it's non-nil, zero value otherwise. +func (s *SecretScanningPatternOverride) GetAlertTotalPercentage() int { + if s == nil || s.AlertTotalPercentage == nil { + return 0 + } + return *s.AlertTotalPercentage +} + +// GetBypassrate returns the Bypassrate field if it's non-nil, zero value otherwise. +func (s *SecretScanningPatternOverride) GetBypassrate() int { + if s == nil || s.Bypassrate == nil { + return 0 + } + return *s.Bypassrate +} + +// GetCustomPatternVersion returns the CustomPatternVersion field if it's non-nil, zero value otherwise. +func (s *SecretScanningPatternOverride) GetCustomPatternVersion() string { + if s == nil || s.CustomPatternVersion == nil { + return "" + } + return *s.CustomPatternVersion +} + +// GetDefaultSetting returns the DefaultSetting field if it's non-nil, zero value otherwise. +func (s *SecretScanningPatternOverride) GetDefaultSetting() string { + if s == nil || s.DefaultSetting == nil { + return "" + } + return *s.DefaultSetting +} + +// GetDisplayName returns the DisplayName field if it's non-nil, zero value otherwise. +func (s *SecretScanningPatternOverride) GetDisplayName() string { + if s == nil || s.DisplayName == nil { + return "" + } + return *s.DisplayName +} + +// GetEnterpriseSetting returns the EnterpriseSetting field if it's non-nil, zero value otherwise. +func (s *SecretScanningPatternOverride) GetEnterpriseSetting() string { + if s == nil || s.EnterpriseSetting == nil { + return "" + } + return *s.EnterpriseSetting +} + +// GetFalsePositiveRate returns the FalsePositiveRate field if it's non-nil, zero value otherwise. +func (s *SecretScanningPatternOverride) GetFalsePositiveRate() int { + if s == nil || s.FalsePositiveRate == nil { + return 0 + } + return *s.FalsePositiveRate +} + +// GetFalsePositives returns the FalsePositives field if it's non-nil, zero value otherwise. +func (s *SecretScanningPatternOverride) GetFalsePositives() int { + if s == nil || s.FalsePositives == nil { + return 0 + } + return *s.FalsePositives +} + +// GetSetting returns the Setting field if it's non-nil, zero value otherwise. +func (s *SecretScanningPatternOverride) GetSetting() string { + if s == nil || s.Setting == nil { + return "" + } + return *s.Setting +} + +// GetSlug returns the Slug field if it's non-nil, zero value otherwise. +func (s *SecretScanningPatternOverride) GetSlug() string { + if s == nil || s.Slug == nil { + return "" + } + return *s.Slug +} + +// GetTokenType returns the TokenType field if it's non-nil, zero value otherwise. +func (s *SecretScanningPatternOverride) GetTokenType() string { + if s == nil || s.TokenType == nil { + return "" + } + return *s.TokenType +} + // GetStatus returns the Status field if it's non-nil, zero value otherwise. func (s *SecretScanningPushProtection) GetStatus() string { if s == nil || s.Status == nil { diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index 4a1b298c2af..29138a2dc69 100644 --- a/github/github-accessors_test.go +++ b/github/github-accessors_test.go @@ -32973,6 +32973,182 @@ func TestSecretScanningAlertUpdateOptions_GetResolutionComment(tt *testing.T) { s.GetResolutionComment() } +func TestSecretScanningCustomPatternSetting_GetCustomPatternVersion(tt *testing.T) { + tt.Parallel() + var zeroValue string + s := &SecretScanningCustomPatternSetting{CustomPatternVersion: &zeroValue} + s.GetCustomPatternVersion() + s = &SecretScanningCustomPatternSetting{} + s.GetCustomPatternVersion() + s = nil + s.GetCustomPatternVersion() +} + +func TestSecretScanningPatternConfigs_GetPatternConfigVersion(tt *testing.T) { + tt.Parallel() + var zeroValue string + s := &SecretScanningPatternConfigs{PatternConfigVersion: &zeroValue} + s.GetPatternConfigVersion() + s = &SecretScanningPatternConfigs{} + s.GetPatternConfigVersion() + s = nil + s.GetPatternConfigVersion() +} + +func TestSecretScanningPatternConfigsUpdate_GetPatternConfigVersion(tt *testing.T) { + tt.Parallel() + var zeroValue string + s := &SecretScanningPatternConfigsUpdate{PatternConfigVersion: &zeroValue} + s.GetPatternConfigVersion() + s = &SecretScanningPatternConfigsUpdate{} + s.GetPatternConfigVersion() + s = nil + s.GetPatternConfigVersion() +} + +func TestSecretScanningPatternConfigsUpdateOptions_GetPatternConfigVersion(tt *testing.T) { + tt.Parallel() + var zeroValue string + s := &SecretScanningPatternConfigsUpdateOptions{PatternConfigVersion: &zeroValue} + s.GetPatternConfigVersion() + s = &SecretScanningPatternConfigsUpdateOptions{} + s.GetPatternConfigVersion() + s = nil + s.GetPatternConfigVersion() +} + +func TestSecretScanningPatternOverride_GetAlertTotal(tt *testing.T) { + tt.Parallel() + var zeroValue int + s := &SecretScanningPatternOverride{AlertTotal: &zeroValue} + s.GetAlertTotal() + s = &SecretScanningPatternOverride{} + s.GetAlertTotal() + s = nil + s.GetAlertTotal() +} + +func TestSecretScanningPatternOverride_GetAlertTotalPercentage(tt *testing.T) { + tt.Parallel() + var zeroValue int + s := &SecretScanningPatternOverride{AlertTotalPercentage: &zeroValue} + s.GetAlertTotalPercentage() + s = &SecretScanningPatternOverride{} + s.GetAlertTotalPercentage() + s = nil + s.GetAlertTotalPercentage() +} + +func TestSecretScanningPatternOverride_GetBypassrate(tt *testing.T) { + tt.Parallel() + var zeroValue int + s := &SecretScanningPatternOverride{Bypassrate: &zeroValue} + s.GetBypassrate() + s = &SecretScanningPatternOverride{} + s.GetBypassrate() + s = nil + s.GetBypassrate() +} + +func TestSecretScanningPatternOverride_GetCustomPatternVersion(tt *testing.T) { + tt.Parallel() + var zeroValue string + s := &SecretScanningPatternOverride{CustomPatternVersion: &zeroValue} + s.GetCustomPatternVersion() + s = &SecretScanningPatternOverride{} + s.GetCustomPatternVersion() + s = nil + s.GetCustomPatternVersion() +} + +func TestSecretScanningPatternOverride_GetDefaultSetting(tt *testing.T) { + tt.Parallel() + var zeroValue string + s := &SecretScanningPatternOverride{DefaultSetting: &zeroValue} + s.GetDefaultSetting() + s = &SecretScanningPatternOverride{} + s.GetDefaultSetting() + s = nil + s.GetDefaultSetting() +} + +func TestSecretScanningPatternOverride_GetDisplayName(tt *testing.T) { + tt.Parallel() + var zeroValue string + s := &SecretScanningPatternOverride{DisplayName: &zeroValue} + s.GetDisplayName() + s = &SecretScanningPatternOverride{} + s.GetDisplayName() + s = nil + s.GetDisplayName() +} + +func TestSecretScanningPatternOverride_GetEnterpriseSetting(tt *testing.T) { + tt.Parallel() + var zeroValue string + s := &SecretScanningPatternOverride{EnterpriseSetting: &zeroValue} + s.GetEnterpriseSetting() + s = &SecretScanningPatternOverride{} + s.GetEnterpriseSetting() + s = nil + s.GetEnterpriseSetting() +} + +func TestSecretScanningPatternOverride_GetFalsePositiveRate(tt *testing.T) { + tt.Parallel() + var zeroValue int + s := &SecretScanningPatternOverride{FalsePositiveRate: &zeroValue} + s.GetFalsePositiveRate() + s = &SecretScanningPatternOverride{} + s.GetFalsePositiveRate() + s = nil + s.GetFalsePositiveRate() +} + +func TestSecretScanningPatternOverride_GetFalsePositives(tt *testing.T) { + tt.Parallel() + var zeroValue int + s := &SecretScanningPatternOverride{FalsePositives: &zeroValue} + s.GetFalsePositives() + s = &SecretScanningPatternOverride{} + s.GetFalsePositives() + s = nil + s.GetFalsePositives() +} + +func TestSecretScanningPatternOverride_GetSetting(tt *testing.T) { + tt.Parallel() + var zeroValue string + s := &SecretScanningPatternOverride{Setting: &zeroValue} + s.GetSetting() + s = &SecretScanningPatternOverride{} + s.GetSetting() + s = nil + s.GetSetting() +} + +func TestSecretScanningPatternOverride_GetSlug(tt *testing.T) { + tt.Parallel() + var zeroValue string + s := &SecretScanningPatternOverride{Slug: &zeroValue} + s.GetSlug() + s = &SecretScanningPatternOverride{} + s.GetSlug() + s = nil + s.GetSlug() +} + +func TestSecretScanningPatternOverride_GetTokenType(tt *testing.T) { + tt.Parallel() + var zeroValue string + s := &SecretScanningPatternOverride{TokenType: &zeroValue} + s.GetTokenType() + s = &SecretScanningPatternOverride{} + s.GetTokenType() + s = nil + s.GetTokenType() +} + func TestSecretScanningPushProtection_GetStatus(tt *testing.T) { tt.Parallel() var zeroValue string diff --git a/github/secret_scanning_pattern_configs.go b/github/secret_scanning_pattern_configs.go new file mode 100644 index 00000000000..c2d51f7d803 --- /dev/null +++ b/github/secret_scanning_pattern_configs.go @@ -0,0 +1,165 @@ +// Copyright 2025 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package github + +import ( + "context" + "fmt" +) + +// SecretScanningPatternConfigs represents a collection of GitHub secret scanning patterns +// and their settings related to push protection. +type SecretScanningPatternConfigs struct { + PatternConfigVersion *string `json:"pattern_config_version,omitempty"` + ProviderPatternOverrides []*SecretScanningPatternOverride `json:"provider_pattern_overrides,omitempty"` + CustomPatternOverrides []*SecretScanningPatternOverride `json:"custom_pattern_overrides,omitempty"` +} + +// SecretScanningPatternOverride respresents an override for provider partner or custom organization patterns. +type SecretScanningPatternOverride struct { + TokenType *string `json:"token_type,omitempty"` + CustomPatternVersion *string `json:"custom_pattern_version,omitempty"` + Slug *string `json:"slug,omitempty"` + DisplayName *string `json:"display_name,omitempty"` + AlertTotal *int `json:"alert_total,omitempty"` + AlertTotalPercentage *int `json:"alert_total_percentage,omitempty"` + FalsePositives *int `json:"false_positives,omitempty"` + FalsePositiveRate *int `json:"false_positive_rate,omitempty"` + Bypassrate *int `json:"bypass_rate,omitempty"` + DefaultSetting *string `json:"default_setting,omitempty"` + EnterpriseSetting *string `json:"enterprise_setting,omitempty"` + Setting *string `json:"setting,omitempty"` +} + +// SecretScanningPatternConfigsUpdate represents a secret scanning pattern configurations update. +type SecretScanningPatternConfigsUpdate struct { + PatternConfigVersion *string `json:"pattern_config_version,omitempty"` +} + +// SecretScanningPatternConfigsUpdateOptions specifies optional parameters to +// the SecretScanningService.UpdatePatternConfigsForEnterprise method and +// the SecretScanningService.UpdatePatternConfigsForOrg method. +type SecretScanningPatternConfigsUpdateOptions struct { + // The version of the entity. + PatternConfigVersion *string `json:"pattern_config_version,omitempty"` + + // Pattern settings for provider patterns. + ProviderPatternSettings []*SecretScanningProviderPatternSetting `json:"provider_pattern_settings,omitempty"` + + // Pattern settings for custom patterns. + CustomPatternSettings []*SecretScanningCustomPatternSetting `json:"custom_pattern_settings,omitempty"` +} + +// SecretScanningProviderPatternSetting defines an optional pattern setting for provider patterns. +type SecretScanningProviderPatternSetting struct { + // The ID of the pattern to configure. + TokenType string `json:"token_type"` + + // Push protection setting to set for the pattern. + // Can be one of: "not-set", "disabled", "enabled" + PushProtectionSetting string `json:"push_protection_setting"` +} + +// SecretScanningCustomPatternSetting defines an optional pattern setting for custom patterns. +type SecretScanningCustomPatternSetting struct { + // The ID of the pattern to configure. + TokenType string `json:"token_type"` + + // The version of the entity + CustomPatternVersion *string `json:"custom_pattern_version,omitempty"` + + // Push protection setting to set for the pattern. + // Can be one of: "not-set", "disabled", "enabled" + PushProtectionSetting string `json:"push_protection_setting"` +} + +// ListPatternConfigsForEnterprise lists the secret scanning pattern configurations for an enterprise. +// +// GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/secret-scanning/push-protection#list-enterprise-pattern-configurations +// +//meta:operation GET /enterprises/{enterprise}/secret-scanning/pattern-configurations +func (s *SecretScanningService) ListPatternConfigsForEnterprise(ctx context.Context, enterprise string) (*SecretScanningPatternConfigs, *Response, error) { + u := fmt.Sprintf("enterprises/%v/secret-scanning/pattern-configurations", enterprise) + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + var patternConfigs *SecretScanningPatternConfigs + resp, err := s.client.Do(ctx, req, &patternConfigs) + if err != nil { + return nil, resp, err + } + + return patternConfigs, resp, nil +} + +// ListPatternConfigsForOrg lists the secret scanning pattern configurations for an organization. +// +// GitHub API docs: https://docs.github.com/rest/secret-scanning/push-protection#list-organization-pattern-configurations +// +//meta:operation GET /orgs/{org}/secret-scanning/pattern-configurations +func (s *SecretScanningService) ListPatternConfigsForOrg(ctx context.Context, org string) (*SecretScanningPatternConfigs, *Response, error) { + u := fmt.Sprintf("orgs/%v/secret-scanning/pattern-configurations", org) + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + var patternConfigs *SecretScanningPatternConfigs + resp, err := s.client.Do(ctx, req, &patternConfigs) + if err != nil { + return nil, resp, err + } + + return patternConfigs, resp, nil +} + +// UpdatePatternConfigsForEnterprise updates the secret scanning pattern configurations for an enterprise. +// +// GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/secret-scanning/push-protection#update-enterprise-pattern-configurations +// +//meta:operation PATCH /enterprises/{enterprise}/secret-scanning/pattern-configurations +func (s *SecretScanningService) UpdatePatternConfigsForEnterprise(ctx context.Context, enterprise string, opts *SecretScanningPatternConfigsUpdateOptions) (*SecretScanningPatternConfigsUpdate, *Response, error) { + u := fmt.Sprintf("enterprises/%v/secret-scanning/pattern-configurations", enterprise) + + req, err := s.client.NewRequest("PATCH", u, opts) + if err != nil { + return nil, nil, err + } + + var patternConfigsUpdate *SecretScanningPatternConfigsUpdate + resp, err := s.client.Do(ctx, req, &patternConfigsUpdate) + if err != nil { + return nil, resp, err + } + + return patternConfigsUpdate, resp, nil +} + +// UpdatePatternConfigsForOrg updates the secret scanning pattern configurations for an organization. +// +// GitHub API docs: https://docs.github.com/rest/secret-scanning/push-protection#update-organization-pattern-configurations +// +//meta:operation PATCH /orgs/{org}/secret-scanning/pattern-configurations +func (s *SecretScanningService) UpdatePatternConfigsForOrg(ctx context.Context, org string, opts *SecretScanningPatternConfigsUpdateOptions) (*SecretScanningPatternConfigsUpdate, *Response, error) { + u := fmt.Sprintf("orgs/%v/secret-scanning/pattern-configurations", org) + + req, err := s.client.NewRequest("PATCH", u, opts) + if err != nil { + return nil, nil, err + } + + var patternConfigsUpdate *SecretScanningPatternConfigsUpdate + resp, err := s.client.Do(ctx, req, &patternConfigsUpdate) + if err != nil { + return nil, resp, err + } + + return patternConfigsUpdate, resp, nil +} diff --git a/github/secret_scanning_pattern_configs_test.go b/github/secret_scanning_pattern_configs_test.go new file mode 100644 index 00000000000..2db1c6d7648 --- /dev/null +++ b/github/secret_scanning_pattern_configs_test.go @@ -0,0 +1,569 @@ +// Copyright 2025 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package github + +import ( + "context" + "fmt" + "net/http" + "testing" + + "github.com/google/go-cmp/cmp" +) + +func TestSecretScanningService_ListPatternConfigsForEnterprise(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/enterprises/e/secret-scanning/pattern-configurations", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + + fmt.Fprint(w, `{ + "pattern_config_version": "0ujsswThIGTUYm2K8FjOOfXtY1K", + "provider_pattern_overrides": [ + { + "token_type": "GITHUB_PERSONAL_ACCESS_TOKEN", + "slug": "github_personal_access_token_legacy_v2", + "display_name": "GitHub Personal Access Token (Legacy v2)", + "alert_total": 15, + "alert_total_percentage": 36, + "false_positives": 2, + "false_positive_rate": 13, + "bypass_rate": 13, + "default_setting": "enabled", + "setting": "enabled", + "enterprise_setting": "enabled" + } + ], + "custom_pattern_overrides": [ + { + "token_type": "cp_2", + "custom_pattern_version": "0ujsswThIGTUYm2K8FjOOfXtY1K", + "slug": "custom-api-key", + "display_name": "Custom API Key", + "alert_total": 15, + "alert_total_percentage": 36, + "false_positives": 3, + "false_positive_rate": 20, + "bypass_rate": 20, + "default_setting": "disabled", + "setting": "enabled" + } + ] + }`) + }) + + ctx := context.Background() + + patternConfigs, _, err := client.SecretScanning.ListPatternConfigsForEnterprise(ctx, "e") + if err != nil { + t.Errorf("SecretScanning.ListPatternConfigsForEnterprise returned error: %v", err) + } + + want := &SecretScanningPatternConfigs{ + PatternConfigVersion: Ptr("0ujsswThIGTUYm2K8FjOOfXtY1K"), + ProviderPatternOverrides: []*SecretScanningPatternOverride{ + { + TokenType: Ptr("GITHUB_PERSONAL_ACCESS_TOKEN"), + CustomPatternVersion: nil, + Slug: Ptr("github_personal_access_token_legacy_v2"), + DisplayName: Ptr("GitHub Personal Access Token (Legacy v2)"), + AlertTotal: Ptr(15), + AlertTotalPercentage: Ptr(36), + FalsePositives: Ptr(2), + FalsePositiveRate: Ptr(13), + Bypassrate: Ptr(13), + DefaultSetting: Ptr("enabled"), + EnterpriseSetting: Ptr("enabled"), + Setting: Ptr("enabled"), + }, + }, + CustomPatternOverrides: []*SecretScanningPatternOverride{ + { + TokenType: Ptr("cp_2"), + CustomPatternVersion: Ptr("0ujsswThIGTUYm2K8FjOOfXtY1K"), + Slug: Ptr("custom-api-key"), + DisplayName: Ptr("Custom API Key"), + AlertTotal: Ptr(15), + AlertTotalPercentage: Ptr(36), + FalsePositives: Ptr(3), + FalsePositiveRate: Ptr(20), + Bypassrate: Ptr(20), + DefaultSetting: Ptr("disabled"), + EnterpriseSetting: nil, + Setting: Ptr("enabled"), + }, + }, + } + + if !cmp.Equal(patternConfigs, want) { + t.Errorf("SecretScanning.ListPatternConfigsForEnterprise returned %+v, want %+v", patternConfigs, want) + } + + const methodName = "ListPatternConfigsForEnterprise" + + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.SecretScanning.ListPatternConfigsForEnterprise(ctx, "\n") + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + _, resp, err := client.SecretScanning.ListPatternConfigsForEnterprise(ctx, "e") + return resp, err + }) +} + +func TestSecretScanningService_ListPatternConfigsForOrg(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/orgs/o/secret-scanning/pattern-configurations", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + + fmt.Fprint(w, `{ + "pattern_config_version": "0ujsswThIGTUYm2K8FjOOfXtY1K", + "provider_pattern_overrides": [ + { + "token_type": "GITHUB_PERSONAL_ACCESS_TOKEN", + "slug": "github_personal_access_token_legacy_v2", + "display_name": "GitHub Personal Access Token (Legacy v2)", + "alert_total": 15, + "alert_total_percentage": 36, + "false_positives": 2, + "false_positive_rate": 13, + "bypass_rate": 13, + "default_setting": "enabled", + "setting": "enabled", + "enterprise_setting": "enabled" + } + ], + "custom_pattern_overrides": [ + { + "token_type": "cp_2", + "custom_pattern_version": "0ujsswThIGTUYm2K8FjOOfXtY1K", + "slug": "custom-api-key", + "display_name": "Custom API Key", + "alert_total": 15, + "alert_total_percentage": 36, + "false_positives": 3, + "false_positive_rate": 20, + "bypass_rate": 20, + "default_setting": "disabled", + "setting": "enabled" + } + ] + }`) + + ctx := context.Background() + + patternConfigs, _, err := client.SecretScanning.ListPatternConfigsForOrg(ctx, "o") + if err != nil { + t.Errorf("SecretScanning.ListPatternConfigsForOrg returned error: %v", err) + } + + want := &SecretScanningPatternConfigs{ + PatternConfigVersion: Ptr("0ujsswThIGTUYm2K8FjOOfXtY1K"), + ProviderPatternOverrides: []*SecretScanningPatternOverride{ + { + TokenType: Ptr("GITHUB_PERSONAL_ACCESS_TOKEN"), + CustomPatternVersion: nil, + Slug: Ptr("github_personal_access_token_legacy_v2"), + DisplayName: Ptr("GitHub Personal Access Token (Legacy v2)"), + AlertTotal: Ptr(15), + AlertTotalPercentage: Ptr(36), + FalsePositives: Ptr(2), + FalsePositiveRate: Ptr(13), + Bypassrate: Ptr(13), + DefaultSetting: Ptr("enabled"), + EnterpriseSetting: Ptr("enabled"), + Setting: Ptr("enabled"), + }, + }, + CustomPatternOverrides: []*SecretScanningPatternOverride{ + { + TokenType: Ptr("cp_2"), + CustomPatternVersion: Ptr("0ujsswThIGTUYm2K8FjOOfXtY1K"), + Slug: Ptr("custom-api-key"), + DisplayName: Ptr("Custom API Key"), + AlertTotal: Ptr(15), + AlertTotalPercentage: Ptr(36), + FalsePositives: Ptr(3), + FalsePositiveRate: Ptr(20), + Bypassrate: Ptr(20), + DefaultSetting: Ptr("disabled"), + EnterpriseSetting: nil, + Setting: Ptr("enabled"), + }, + }, + } + + if !cmp.Equal(patternConfigs, want) { + t.Errorf("SecretScanning.ListPatternConfigsForOrg returned %+v, want %+v", patternConfigs, want) + } + + const methodName = "ListPatternConfigsForOrg" + + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.SecretScanning.ListPatternConfigsForOrg(ctx, "\n") + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + _, resp, err := client.SecretScanning.ListPatternConfigsForOrg(ctx, "o") + return resp, err + }) + }) +} + +func TestSecretScanningService_UpdatePatternConfigsForEnterprise(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/enterprises/e/secret-scanning/pattern-configurations", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "PATCH") + + fmt.Fprint(w, `{ + "pattern_config_version": "0ujsswThIGTUYm2K8FjOOfXtY1K" + }`) + + ctx := context.Background() + + opts := &SecretScanningPatternConfigsUpdateOptions{ + PatternConfigVersion: Ptr("0ujsswThIGTUYm2K8FjOOfXtY1K"), + ProviderPatternSettings: []*SecretScanningProviderPatternSetting{ + { + TokenType: "GITHUB_PERSONAL_ACCESS_TOKEN", + PushProtectionSetting: "enabled", + }, + }, + CustomPatternSettings: []*SecretScanningCustomPatternSetting{ + { + TokenType: "cp_2", + CustomPatternVersion: Ptr("0ujsswThIGTUYm2K8FjOOfXtY1K"), + PushProtectionSetting: "enabled", + }, + }, + } + + configsUpdate, _, err := client.SecretScanning.UpdatePatternConfigsForEnterprise(ctx, "e", opts) + if err != nil { + t.Errorf("SecretScanning.UpdatePatternConfigsForEnterprise returned error: %v", err) + } + + want := &SecretScanningPatternConfigsUpdate{ + PatternConfigVersion: Ptr("0ujsswThIGTUYm2K8FjOOfXtY1K"), + } + + if !cmp.Equal(configsUpdate, want) { + t.Errorf("SecretScanning.UpdatePatternConfigsForEnterprise returned %+v, want %+v", configsUpdate, want) + } + + const methodName = "UpdatePatternConfigsForEnterprise" + + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.SecretScanning.UpdatePatternConfigsForEnterprise(ctx, "\n", opts) + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + _, resp, err := client.SecretScanning.UpdatePatternConfigsForEnterprise(ctx, "o", opts) + return resp, err + }) + }) +} + +func TestSecretScanningService_UpdatePatternConfigsForOrg(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + mux.HandleFunc("/orgs/o/secret-scanning/pattern-configurations", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "PATCH") + + fmt.Fprint(w, `{ + "pattern_config_version": "0ujsswThIGTUYm2K8FjOOfXtY1K" + }`) + + ctx := context.Background() + + opts := &SecretScanningPatternConfigsUpdateOptions{ + PatternConfigVersion: Ptr("0ujsswThIGTUYm2K8FjOOfXtY1K"), + ProviderPatternSettings: []*SecretScanningProviderPatternSetting{ + { + TokenType: "GITHUB_PERSONAL_ACCESS_TOKEN", + PushProtectionSetting: "enabled", + }, + }, + CustomPatternSettings: []*SecretScanningCustomPatternSetting{ + { + TokenType: "cp_2", + CustomPatternVersion: Ptr("0ujsswThIGTUYm2K8FjOOfXtY1K"), + PushProtectionSetting: "enabled", + }, + }, + } + + configsUpdate, _, err := client.SecretScanning.UpdatePatternConfigsForOrg(ctx, "o", opts) + if err != nil { + t.Errorf("SecretScanning.UpdatePatternConfigsForOrg returned err: %v", err) + } + + want := &SecretScanningPatternConfigsUpdate{ + PatternConfigVersion: Ptr("0ujsswThIGTUYm2K8FjOOfXtY1K"), + } + + if !cmp.Equal(configsUpdate, want) { + t.Errorf("SecretScanning.UpdatePatternConfigsForOrg returned %+v, want %+v", configsUpdate, want) + } + + const methodName = "UpdatePatternConfigsForOrg" + + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.SecretScanning.UpdatePatternConfigsForOrg(ctx, "\n", opts) + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + _, resp, err := client.SecretScanning.UpdatePatternConfigsForOrg(ctx, "o", opts) + return resp, err + }) + }) +} + +func TestSecretScanningPatternConfigs_Marshal(t *testing.T) { + t.Parallel() + testJSONMarshal(t, &SecretScanningPatternConfigs{}, `{}`) + + v := &SecretScanningPatternConfigs{ + PatternConfigVersion: Ptr("0ujsswThIGTUYm2K8FjOOfXtY1K"), + ProviderPatternOverrides: []*SecretScanningPatternOverride{ + { + TokenType: Ptr("GITHUB_PERSONAL_ACCESS_TOKEN"), + CustomPatternVersion: nil, + Slug: Ptr("github_personal_access_token_legacy_v2"), + DisplayName: Ptr("GitHub Personal Access Token (Legacy v2)"), + AlertTotal: Ptr(15), + AlertTotalPercentage: Ptr(36), + FalsePositives: Ptr(2), + FalsePositiveRate: Ptr(13), + Bypassrate: Ptr(13), + DefaultSetting: Ptr("enabled"), + EnterpriseSetting: Ptr("enabled"), + Setting: Ptr("enabled"), + }, + }, + CustomPatternOverrides: []*SecretScanningPatternOverride{ + { + TokenType: Ptr("cp_2"), + CustomPatternVersion: Ptr("0ujsswThIGTUYm2K8FjOOfXtY1K"), + Slug: Ptr("custom-api-key"), + DisplayName: Ptr("Custom API Key"), + AlertTotal: Ptr(15), + AlertTotalPercentage: Ptr(36), + FalsePositives: Ptr(3), + FalsePositiveRate: Ptr(20), + Bypassrate: Ptr(20), + DefaultSetting: Ptr("disabled"), + EnterpriseSetting: nil, + Setting: Ptr("enabled"), + }, + }, + } + + want := `{ + "pattern_config_version": "0ujsswThIGTUYm2K8FjOOfXtY1K", + "provider_pattern_overrides": [ + { + "token_type": "GITHUB_PERSONAL_ACCESS_TOKEN", + "slug": "github_personal_access_token_legacy_v2", + "display_name": "GitHub Personal Access Token (Legacy v2)", + "alert_total": 15, + "alert_total_percentage": 36, + "false_positives": 2, + "false_positive_rate": 13, + "bypass_rate": 13, + "default_setting": "enabled", + "setting": "enabled", + "enterprise_setting": "enabled" + } + ], + "custom_pattern_overrides": [ + { + "token_type": "cp_2", + "custom_pattern_version": "0ujsswThIGTUYm2K8FjOOfXtY1K", + "slug": "custom-api-key", + "display_name": "Custom API Key", + "alert_total": 15, + "alert_total_percentage": 36, + "false_positives": 3, + "false_positive_rate": 20, + "bypass_rate": 20, + "default_setting": "disabled", + "setting": "enabled" + } + ] + }` + + testJSONMarshal(t, v, want) +} + +func TestSecretScanningPatternOverride_Marshal(t *testing.T) { + t.Parallel() + testJSONMarshal(t, &SecretScanningPatternOverride{}, `{}`) + + v := &SecretScanningPatternOverride{ + TokenType: Ptr("GITHUB_PERSONAL_ACCESS_TOKEN"), + CustomPatternVersion: nil, + Slug: Ptr("github_personal_access_token_legacy_v2"), + DisplayName: Ptr("GitHub Personal Access Token (Legacy v2)"), + AlertTotal: Ptr(15), + AlertTotalPercentage: Ptr(36), + FalsePositives: Ptr(2), + FalsePositiveRate: Ptr(13), + Bypassrate: Ptr(13), + DefaultSetting: Ptr("enabled"), + EnterpriseSetting: Ptr("enabled"), + Setting: Ptr("enabled"), + } + + want := `{ + "token_type": "GITHUB_PERSONAL_ACCESS_TOKEN", + "slug": "github_personal_access_token_legacy_v2", + "display_name": "GitHub Personal Access Token (Legacy v2)", + "alert_total": 15, + "alert_total_percentage": 36, + "false_positives": 2, + "false_positive_rate": 13, + "bypass_rate": 13, + "default_setting": "enabled", + "setting": "enabled", + "enterprise_setting": "enabled" + }` + + testJSONMarshal(t, v, want) + + v = &SecretScanningPatternOverride{ + TokenType: Ptr("cp_2"), + CustomPatternVersion: Ptr("0ujsswThIGTUYm2K8FjOOfXtY1K"), + Slug: Ptr("custom-api-key"), + DisplayName: Ptr("Custom API Key"), + AlertTotal: Ptr(15), + AlertTotalPercentage: Ptr(36), + FalsePositives: Ptr(3), + FalsePositiveRate: Ptr(20), + Bypassrate: Ptr(20), + DefaultSetting: Ptr("disabled"), + EnterpriseSetting: nil, + Setting: Ptr("enabled"), + } + + want = `{ + "token_type": "cp_2", + "custom_pattern_version": "0ujsswThIGTUYm2K8FjOOfXtY1K", + "slug": "custom-api-key", + "display_name": "Custom API Key", + "alert_total": 15, + "alert_total_percentage": 36, + "false_positives": 3, + "false_positive_rate": 20, + "bypass_rate": 20, + "default_setting": "disabled", + "setting": "enabled" + }` + + testJSONMarshal(t, v, want) +} + +func TestSecretScanningPatternConfigsUpdate_Marshal(t *testing.T) { + t.Parallel() + testJSONMarshal(t, &SecretScanningPatternConfigsUpdate{}, `{}`) + + v := &SecretScanningPatternConfigsUpdate{ + PatternConfigVersion: Ptr("0ujsswThIGTUYm2K8FjOOfXtY1K"), + } + + want := `{ + "pattern_config_version": "0ujsswThIGTUYm2K8FjOOfXtY1K" + }` + + testJSONMarshal(t, v, want) +} + +func TestSecretScanningPatternConfigsUpdateOptions_Marshal(t *testing.T) { + t.Parallel() + testJSONMarshal(t, &SecretScanningPatternConfigsUpdateOptions{}, `{}`) + + v := &SecretScanningPatternConfigsUpdateOptions{ + PatternConfigVersion: Ptr("0ujsswThIGTUYm2K8FjOOfXtY1K"), + ProviderPatternSettings: []*SecretScanningProviderPatternSetting{ + { + TokenType: "GITHUB_PERSONAL_ACCESS_TOKEN", + PushProtectionSetting: "enabled", + }, + }, + CustomPatternSettings: []*SecretScanningCustomPatternSetting{ + { + TokenType: "cp_2", + CustomPatternVersion: Ptr("0ujsswThIGTUYm2K8FjOOfXtY1K"), + PushProtectionSetting: "enabled", + }, + }, + } + + want := `{ + "pattern_config_version": "0ujsswThIGTUYm2K8FjOOfXtY1K", + "provider_pattern_settings": [ + { + "token_type": "GITHUB_PERSONAL_ACCESS_TOKEN", + "push_protection_setting": "enabled" + } + ], + "custom_pattern_settings": [ + { + "token_type": "cp_2", + "custom_pattern_version": "0ujsswThIGTUYm2K8FjOOfXtY1K", + "push_protection_setting": "enabled" + } + ] + }` + + testJSONMarshal(t, v, want) +} + +func TestSecretScanningProviderPatternSetting_Marshal(t *testing.T) { + t.Parallel() + testJSONMarshal(t, &SecretScanningProviderPatternSetting{}, `{}`) + + v := SecretScanningProviderPatternSetting{ + TokenType: "GITHUB_PERSONAL_ACCESS_TOKEN", + PushProtectionSetting: "enabled", + } + + want := `{ + "token_type": "GITHUB_PERSONAL_ACCESS_TOKEN", + "push_protection_setting": "enabled" + }` + + testJSONMarshal(t, v, want) +} + +func TestSecretScanninCustomPatternSetting_Marshal(t *testing.T) { + t.Parallel() + testJSONMarshal(t, &SecretScanningCustomPatternSetting{}, `{}`) + + v := SecretScanningCustomPatternSetting{ + TokenType: "cp_2", + CustomPatternVersion: Ptr("0ujsswThIGTUYm2K8FjOOfXtY1K"), + PushProtectionSetting: "enabled", + } + + want := `{ + "token_type": "cp_2", + "custom_pattern_version": "0ujsswThIGTUYm2K8FjOOfXtY1K", + "push_protection_setting": "enabled" + }` + + testJSONMarshal(t, v, want) +}