diff --git a/github/enterprise_code_security_and_analysis.go b/github/enterprise_code_security_and_analysis.go new file mode 100644 index 00000000000..3980a86aa4b --- /dev/null +++ b/github/enterprise_code_security_and_analysis.go @@ -0,0 +1,78 @@ +// Copyright 2022 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" +) + +// EnterpriseSecurityAnalysisSettings represents security analysis settings for an enterprise. +type EnterpriseSecurityAnalysisSettings struct { + AdvancedSecurityEnabledForNewRepositories *bool `json:"advanced_security_enabled_for_new_repositories,omitempty"` + SecretScanningEnabledForNewRepositories *bool `json:"secret_scanning_enabled_for_new_repositories,omitempty"` + SecretScanningPushProtectionEnabledForNewRepositories *bool `json:"secret_scanning_push_protection_enabled_for_new_repositories,omitempty"` + SecretScanningPushProtectionCustomLink *string `json:"secret_scanning_push_protection_custom_link,omitempty"` +} + +// GetCodeSecurityAndAnalysis gets code security and analysis features for an enterprise. +// +// GitHub API docs: https://docs.github.com/en/rest/enterprise-admin/code-security-and-analysis?apiVersion=2022-11-28#get-code-security-and-analysis-features-for-an-enterprise +func (s *EnterpriseService) GetCodeSecurityAndAnalysis(ctx context.Context, enterprise string) (*EnterpriseSecurityAnalysisSettings, *Response, error) { + u := fmt.Sprintf("enterprises/%v/code_security_and_analysis", enterprise) + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + settings := new(EnterpriseSecurityAnalysisSettings) + resp, err := s.client.Do(ctx, req, settings) + if err != nil { + return nil, resp, err + } + + return settings, resp, nil +} + +// UpdateCodeSecurityAndAnalysis updates code security and analysis features for new repositories in an enterprise. +// +// GitHub API docs: https://docs.github.com/en/rest/enterprise-admin/code-security-and-analysis?apiVersion=2022-11-28#update-code-security-and-analysis-features-for-an-enterprise +func (s *EnterpriseService) UpdateCodeSecurityAndAnalysis(ctx context.Context, enterprise string, settings *EnterpriseSecurityAnalysisSettings) (*Response, error) { + u := fmt.Sprintf("enterprises/%v/code_security_and_analysis", enterprise) + req, err := s.client.NewRequest("PATCH", u, settings) + if err != nil { + return nil, err + } + + resp, err := s.client.Do(ctx, req, nil) + if err != nil { + return resp, err + } + + return resp, nil +} + +// EnableDisableSecurityFeature enables or disables a security feature for all repositories in an enterprise. +// +// Valid values for securityProduct: "advanced_security", "secret_scanning", "secret_scanning_push_protection". +// Valid values for enablement: "enable_all", "disable_all". +// +// GitHub API docs: https://docs.github.com/en/enterprise-cloud@latest/rest/enterprise-admin/code-security-and-analysis?apiVersion=2022-11-28#enable-or-disable-a-security-feature +func (s *EnterpriseService) EnableDisableSecurityFeature(ctx context.Context, enterprise, securityProduct, enablement string) (*Response, error) { + u := fmt.Sprintf("enterprises/%v/%v/%v", enterprise, securityProduct, enablement) + req, err := s.client.NewRequest("POST", u, nil) + if err != nil { + return nil, err + } + + resp, err := s.client.Do(ctx, req, nil) + if err != nil { + return resp, err + } + + return resp, nil +} diff --git a/github/enterprise_code_security_and_analysis_test.go b/github/enterprise_code_security_and_analysis_test.go new file mode 100644 index 00000000000..24bf89c51e3 --- /dev/null +++ b/github/enterprise_code_security_and_analysis_test.go @@ -0,0 +1,132 @@ +// Copyright 2022 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" + "encoding/json" + "fmt" + "net/http" + "testing" + + "github.com/google/go-cmp/cmp" +) + +func TestEnterpriseService_GetCodeSecurityAndAnalysis(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/enterprises/e/code_security_and_analysis", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + + fmt.Fprint(w, ` + { + "advanced_security_enabled_for_new_repositories": true, + "secret_scanning_enabled_for_new_repositories": true, + "secret_scanning_push_protection_enabled_for_new_repositories": true, + "secret_scanning_push_protection_custom_link": "https://github.com/test-org/test-repo/blob/main/README.md" + }`) + }) + + ctx := context.Background() + + const methodName = "GetCodeSecurityAndAnalysis" + + settings, _, err := client.Enterprise.GetCodeSecurityAndAnalysis(ctx, "e") + if err != nil { + t.Errorf("Enterprise.%v returned error: %v", methodName, err) + } + want := &EnterpriseSecurityAnalysisSettings{ + AdvancedSecurityEnabledForNewRepositories: Bool(true), + SecretScanningEnabledForNewRepositories: Bool(true), + SecretScanningPushProtectionEnabledForNewRepositories: Bool(true), + SecretScanningPushProtectionCustomLink: String("https://github.com/test-org/test-repo/blob/main/README.md"), + } + + if !cmp.Equal(settings, want) { + t.Errorf("Enterprise.%v return \ngot: %+v,\nwant:%+v", methodName, settings, want) + } + + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.Enterprise.GetCodeSecurityAndAnalysis(ctx, "o") + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Enterprise.GetCodeSecurityAndAnalysis(ctx, "e") + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestEnterpriseService_UpdateCodeSecurityAndAnalysis(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + input := &EnterpriseSecurityAnalysisSettings{ + AdvancedSecurityEnabledForNewRepositories: Bool(true), + SecretScanningEnabledForNewRepositories: Bool(true), + SecretScanningPushProtectionEnabledForNewRepositories: Bool(true), + SecretScanningPushProtectionCustomLink: String("https://github.com/test-org/test-repo/blob/main/README.md"), + } + + mux.HandleFunc("/enterprises/e/code_security_and_analysis", func(w http.ResponseWriter, r *http.Request) { + v := new(EnterpriseSecurityAnalysisSettings) + json.NewDecoder(r.Body).Decode(v) + + testMethod(t, r, "PATCH") + if !cmp.Equal(v, input) { + t.Errorf("Request body = %+v, want %+v", v, input) + } + }) + + ctx := context.Background() + + const methodName = "UpdateCodeSecurityAndAnalysis" + + _, err := client.Enterprise.UpdateCodeSecurityAndAnalysis(ctx, "e", input) + if err != nil { + t.Errorf("Enterprise.%v returned error: %v", methodName, err) + } + + testBadOptions(t, methodName, func() (err error) { + _, err = client.Enterprise.UpdateCodeSecurityAndAnalysis(ctx, "o", input) + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + return client.Enterprise.UpdateCodeSecurityAndAnalysis(ctx, "e", input) + }) +} + +func TestEnterpriseService_EnableAdvancedSecurity(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/enterprises/e/advanced_security/enable_all", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "POST") + }) + + ctx := context.Background() + + const methodName = "EnableDisableSecurityFeature" + + _, err := client.Enterprise.EnableDisableSecurityFeature(ctx, "e", "advanced_security", "enable_all") + if err != nil { + t.Errorf("Enterprise.%v returned error: %v", methodName, err) + } + + testBadOptions(t, methodName, func() (err error) { + _, err = client.Enterprise.EnableDisableSecurityFeature(ctx, "o", "advanced_security", "enable_all") + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + return client.Enterprise.EnableDisableSecurityFeature(ctx, "e", "advanced_security", "enable_all") + }) +} diff --git a/github/github-accessors.go b/github/github-accessors.go index e49872ead21..8a7a5996702 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -5118,6 +5118,38 @@ func (e *Enterprise) GetWebsiteURL() string { return *e.WebsiteURL } +// GetAdvancedSecurityEnabledForNewRepositories returns the AdvancedSecurityEnabledForNewRepositories field if it's non-nil, zero value otherwise. +func (e *EnterpriseSecurityAnalysisSettings) GetAdvancedSecurityEnabledForNewRepositories() bool { + if e == nil || e.AdvancedSecurityEnabledForNewRepositories == nil { + return false + } + return *e.AdvancedSecurityEnabledForNewRepositories +} + +// GetSecretScanningEnabledForNewRepositories returns the SecretScanningEnabledForNewRepositories field if it's non-nil, zero value otherwise. +func (e *EnterpriseSecurityAnalysisSettings) GetSecretScanningEnabledForNewRepositories() bool { + if e == nil || e.SecretScanningEnabledForNewRepositories == nil { + return false + } + return *e.SecretScanningEnabledForNewRepositories +} + +// GetSecretScanningPushProtectionCustomLink returns the SecretScanningPushProtectionCustomLink field if it's non-nil, zero value otherwise. +func (e *EnterpriseSecurityAnalysisSettings) GetSecretScanningPushProtectionCustomLink() string { + if e == nil || e.SecretScanningPushProtectionCustomLink == nil { + return "" + } + return *e.SecretScanningPushProtectionCustomLink +} + +// GetSecretScanningPushProtectionEnabledForNewRepositories returns the SecretScanningPushProtectionEnabledForNewRepositories field if it's non-nil, zero value otherwise. +func (e *EnterpriseSecurityAnalysisSettings) GetSecretScanningPushProtectionEnabledForNewRepositories() bool { + if e == nil || e.SecretScanningPushProtectionEnabledForNewRepositories == nil { + return false + } + return *e.SecretScanningPushProtectionEnabledForNewRepositories +} + // GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise. func (e *Environment) GetCreatedAt() Timestamp { if e == nil || e.CreatedAt == nil { diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index 1985dcd72f8..deb33dc9fee 100644 --- a/github/github-accessors_test.go +++ b/github/github-accessors_test.go @@ -5984,6 +5984,46 @@ func TestEnterprise_GetWebsiteURL(tt *testing.T) { e.GetWebsiteURL() } +func TestEnterpriseSecurityAnalysisSettings_GetAdvancedSecurityEnabledForNewRepositories(tt *testing.T) { + var zeroValue bool + e := &EnterpriseSecurityAnalysisSettings{AdvancedSecurityEnabledForNewRepositories: &zeroValue} + e.GetAdvancedSecurityEnabledForNewRepositories() + e = &EnterpriseSecurityAnalysisSettings{} + e.GetAdvancedSecurityEnabledForNewRepositories() + e = nil + e.GetAdvancedSecurityEnabledForNewRepositories() +} + +func TestEnterpriseSecurityAnalysisSettings_GetSecretScanningEnabledForNewRepositories(tt *testing.T) { + var zeroValue bool + e := &EnterpriseSecurityAnalysisSettings{SecretScanningEnabledForNewRepositories: &zeroValue} + e.GetSecretScanningEnabledForNewRepositories() + e = &EnterpriseSecurityAnalysisSettings{} + e.GetSecretScanningEnabledForNewRepositories() + e = nil + e.GetSecretScanningEnabledForNewRepositories() +} + +func TestEnterpriseSecurityAnalysisSettings_GetSecretScanningPushProtectionCustomLink(tt *testing.T) { + var zeroValue string + e := &EnterpriseSecurityAnalysisSettings{SecretScanningPushProtectionCustomLink: &zeroValue} + e.GetSecretScanningPushProtectionCustomLink() + e = &EnterpriseSecurityAnalysisSettings{} + e.GetSecretScanningPushProtectionCustomLink() + e = nil + e.GetSecretScanningPushProtectionCustomLink() +} + +func TestEnterpriseSecurityAnalysisSettings_GetSecretScanningPushProtectionEnabledForNewRepositories(tt *testing.T) { + var zeroValue bool + e := &EnterpriseSecurityAnalysisSettings{SecretScanningPushProtectionEnabledForNewRepositories: &zeroValue} + e.GetSecretScanningPushProtectionEnabledForNewRepositories() + e = &EnterpriseSecurityAnalysisSettings{} + e.GetSecretScanningPushProtectionEnabledForNewRepositories() + e = nil + e.GetSecretScanningPushProtectionEnabledForNewRepositories() +} + func TestEnvironment_GetCreatedAt(tt *testing.T) { var zeroValue Timestamp e := &Environment{CreatedAt: &zeroValue}