From 37375e60a6b98764dc745017aa76c362963aee48 Mon Sep 17 00:00:00 2001 From: Will Roden Date: Tue, 5 Dec 2023 15:17:55 -0600 Subject: [PATCH 01/13] Remove ambiguous fields from AuditEntry --- github/enterprise_audit_log_test.go | 43 +- github/github-accessors.go | 516 +--------------------- github/github-accessors_test.go | 635 +--------------------------- github/github_test.go | 9 + github/orgs_audit_log.go | 182 ++++---- github/orgs_audit_log_test.go | 240 ++++++----- test/integration/audit_log_test.go | 2 +- 7 files changed, 269 insertions(+), 1358 deletions(-) diff --git a/github/enterprise_audit_log_test.go b/github/enterprise_audit_log_test.go index 2e91346ebf3..0d9e44a3eb6 100644 --- a/github/enterprise_audit_log_test.go +++ b/github/enterprise_audit_log_test.go @@ -11,8 +11,6 @@ import ( "net/http" "testing" "time" - - "github.com/google/go-cmp/cmp" ) func TestEnterpriseService_GetAuditLog(t *testing.T) { @@ -54,34 +52,31 @@ func TestEnterpriseService_GetAuditLog(t *testing.T) { if err != nil { t.Errorf("Enterprise.GetAuditLog returned error: %v", err) } - startedAt, _ := time.Parse(time.RFC3339, "2021-03-07T00:33:04.000Z") - completedAt, _ := time.Parse(time.RFC3339, "2021-03-07T00:35:08.000Z") timestamp := time.Unix(0, 1615077308538*1e6) - want := []*AuditEntry{ { - Timestamp: &Timestamp{timestamp}, - DocumentID: String("beeZYapIUe-wKg5-beadb33"), - Action: String("workflows.completed_workflow_run"), - Actor: String("testactor"), - CompletedAt: &Timestamp{completedAt}, - Conclusion: String("success"), - CreatedAt: &Timestamp{timestamp}, - Event: String("schedule"), - HeadBranch: String("master"), - HeadSHA: String("5acdeadbeef64d1a62388e901e5cdc9358644b37"), - Name: String("Code scanning - action"), - Org: String("o"), - Repo: String("o/blue-crayon-1"), - StartedAt: &Timestamp{startedAt}, - WorkflowID: Int64(123456), - WorkflowRunID: Int64(628312345), + Timestamp: &Timestamp{timestamp}, + DocumentID: String("beeZYapIUe-wKg5-beadb33"), + Action: String("workflows.completed_workflow_run"), + Actor: String("testactor"), + CreatedAt: &Timestamp{timestamp}, + Org: String("o"), + AdditionalFields: map[string]interface{}{ + "completed_at": "2021-03-07T00:35:08.000Z", + "conclusion": "success", + "event": "schedule", + "head_branch": "master", + "head_sha": "5acdeadbeef64d1a62388e901e5cdc9358644b37", + "name": "Code scanning - action", + "repo": "o/blue-crayon-1", + "started_at": "2021-03-07T00:33:04.000Z", + "workflow_id": float64(123456), + "workflow_run_id": float64(628312345), + }, }, } - if !cmp.Equal(auditEntries, want) { - t.Errorf("Enterprise.GetAuditLog return \ngot: %+v,\nwant:%+v", auditEntries, want) - } + assertNoDiff(t, want, auditEntries) const methodName = "GetAuditLog" testBadOptions(t, methodName, func() (err error) { diff --git a/github/github-accessors.go b/github/github-accessors.go index e15eb10204b..f32865c14ab 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -1070,22 +1070,6 @@ func (a *AuditEntry) GetAction() string { return *a.Action } -// GetActive returns the Active field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetActive() bool { - if a == nil || a.Active == nil { - return false - } - return *a.Active -} - -// GetActiveWas returns the ActiveWas field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetActiveWas() bool { - if a == nil || a.ActiveWas == nil { - return false - } - return *a.ActiveWas -} - // GetActor returns the Actor field if it's non-nil, zero value otherwise. func (a *AuditEntry) GetActor() string { if a == nil || a.Actor == nil { @@ -1094,12 +1078,12 @@ func (a *AuditEntry) GetActor() string { return *a.Actor } -// GetActorIP returns the ActorIP field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetActorIP() string { - if a == nil || a.ActorIP == nil { - return "" +// GetActorID returns the ActorID field if it's non-nil, zero value otherwise. +func (a *AuditEntry) GetActorID() int64 { + if a == nil || a.ActorID == nil { + return 0 } - return *a.ActorIP + return *a.ActorID } // GetActorLocation returns the ActorLocation field. @@ -1110,14 +1094,6 @@ func (a *AuditEntry) GetActorLocation() *ActorLocation { return a.ActorLocation } -// GetBlockedUser returns the BlockedUser field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetBlockedUser() string { - if a == nil || a.BlockedUser == nil { - return "" - } - return *a.BlockedUser -} - // GetBusiness returns the Business field if it's non-nil, zero value otherwise. func (a *AuditEntry) GetBusiness() string { if a == nil || a.Business == nil { @@ -1126,52 +1102,12 @@ func (a *AuditEntry) GetBusiness() string { return *a.Business } -// GetCancelledAt returns the CancelledAt field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetCancelledAt() Timestamp { - if a == nil || a.CancelledAt == nil { - return Timestamp{} - } - return *a.CancelledAt -} - -// GetCompletedAt returns the CompletedAt field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetCompletedAt() Timestamp { - if a == nil || a.CompletedAt == nil { - return Timestamp{} - } - return *a.CompletedAt -} - -// GetConclusion returns the Conclusion field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetConclusion() string { - if a == nil || a.Conclusion == nil { - return "" - } - return *a.Conclusion -} - -// GetConfig returns the Config field. -func (a *AuditEntry) GetConfig() *HookConfig { - if a == nil { - return nil - } - return a.Config -} - -// GetConfigWas returns the ConfigWas field. -func (a *AuditEntry) GetConfigWas() *HookConfig { - if a == nil { - return nil - } - return a.ConfigWas -} - -// GetContentType returns the ContentType field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetContentType() string { - if a == nil || a.ContentType == nil { - return "" +// GetBusinessID returns the BusinessID field if it's non-nil, zero value otherwise. +func (a *AuditEntry) GetBusinessID() int64 { + if a == nil || a.BusinessID == nil { + return 0 } - return *a.ContentType + return *a.BusinessID } // GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise. @@ -1182,22 +1118,6 @@ func (a *AuditEntry) GetCreatedAt() Timestamp { return *a.CreatedAt } -// GetData returns the Data field. -func (a *AuditEntry) GetData() *AuditEntryData { - if a == nil { - return nil - } - return a.Data -} - -// GetDeployKeyFingerprint returns the DeployKeyFingerprint field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetDeployKeyFingerprint() string { - if a == nil || a.DeployKeyFingerprint == nil { - return "" - } - return *a.DeployKeyFingerprint -} - // GetDocumentID returns the DocumentID field if it's non-nil, zero value otherwise. func (a *AuditEntry) GetDocumentID() string { if a == nil || a.DocumentID == nil { @@ -1206,38 +1126,6 @@ func (a *AuditEntry) GetDocumentID() string { return *a.DocumentID } -// GetEmoji returns the Emoji field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetEmoji() string { - if a == nil || a.Emoji == nil { - return "" - } - return *a.Emoji -} - -// GetEnvironmentName returns the EnvironmentName field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetEnvironmentName() string { - if a == nil || a.EnvironmentName == nil { - return "" - } - return *a.EnvironmentName -} - -// GetEvent returns the Event field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetEvent() string { - if a == nil || a.Event == nil { - return "" - } - return *a.Event -} - -// GetExplanation returns the Explanation field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetExplanation() string { - if a == nil || a.Explanation == nil { - return "" - } - return *a.Explanation -} - // GetExternalIdentityNameID returns the ExternalIdentityNameID field if it's non-nil, zero value otherwise. func (a *AuditEntry) GetExternalIdentityNameID() string { if a == nil || a.ExternalIdentityNameID == nil { @@ -1254,14 +1142,6 @@ func (a *AuditEntry) GetExternalIdentityUsername() string { return *a.ExternalIdentityUsername } -// GetFingerprint returns the Fingerprint field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetFingerprint() string { - if a == nil || a.Fingerprint == nil { - return "" - } - return *a.Fingerprint -} - // GetHashedToken returns the HashedToken field if it's non-nil, zero value otherwise. func (a *AuditEntry) GetHashedToken() string { if a == nil || a.HashedToken == nil { @@ -1270,118 +1150,6 @@ func (a *AuditEntry) GetHashedToken() string { return *a.HashedToken } -// GetHeadBranch returns the HeadBranch field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetHeadBranch() string { - if a == nil || a.HeadBranch == nil { - return "" - } - return *a.HeadBranch -} - -// GetHeadSHA returns the HeadSHA field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetHeadSHA() string { - if a == nil || a.HeadSHA == nil { - return "" - } - return *a.HeadSHA -} - -// GetHookID returns the HookID field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetHookID() int64 { - if a == nil || a.HookID == nil { - return 0 - } - return *a.HookID -} - -// GetIsHostedRunner returns the IsHostedRunner field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetIsHostedRunner() bool { - if a == nil || a.IsHostedRunner == nil { - return false - } - return *a.IsHostedRunner -} - -// GetJobName returns the JobName field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetJobName() string { - if a == nil || a.JobName == nil { - return "" - } - return *a.JobName -} - -// GetJobWorkflowRef returns the JobWorkflowRef field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetJobWorkflowRef() string { - if a == nil || a.JobWorkflowRef == nil { - return "" - } - return *a.JobWorkflowRef -} - -// GetLimitedAvailability returns the LimitedAvailability field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetLimitedAvailability() bool { - if a == nil || a.LimitedAvailability == nil { - return false - } - return *a.LimitedAvailability -} - -// GetMessage returns the Message field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetMessage() string { - if a == nil || a.Message == nil { - return "" - } - return *a.Message -} - -// GetName returns the Name field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetName() string { - if a == nil || a.Name == nil { - return "" - } - return *a.Name -} - -// GetOAuthApplicationID returns the OAuthApplicationID field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetOAuthApplicationID() int64 { - if a == nil || a.OAuthApplicationID == nil { - return 0 - } - return *a.OAuthApplicationID -} - -// GetOldPermission returns the OldPermission field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetOldPermission() string { - if a == nil || a.OldPermission == nil { - return "" - } - return *a.OldPermission -} - -// GetOldUser returns the OldUser field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetOldUser() string { - if a == nil || a.OldUser == nil { - return "" - } - return *a.OldUser -} - -// GetOpenSSHPublicKey returns the OpenSSHPublicKey field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetOpenSSHPublicKey() string { - if a == nil || a.OpenSSHPublicKey == nil { - return "" - } - return *a.OpenSSHPublicKey -} - -// GetOperationType returns the OperationType field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetOperationType() string { - if a == nil || a.OperationType == nil { - return "" - } - return *a.OperationType -} - // GetOrg returns the Org field if it's non-nil, zero value otherwise. func (a *AuditEntry) GetOrg() string { if a == nil || a.Org == nil { @@ -1398,174 +1166,6 @@ func (a *AuditEntry) GetOrgID() int64 { return *a.OrgID } -// GetPermission returns the Permission field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetPermission() string { - if a == nil || a.Permission == nil { - return "" - } - return *a.Permission -} - -// GetPreviousVisibility returns the PreviousVisibility field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetPreviousVisibility() string { - if a == nil || a.PreviousVisibility == nil { - return "" - } - return *a.PreviousVisibility -} - -// GetProgrammaticAccessType returns the ProgrammaticAccessType field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetProgrammaticAccessType() string { - if a == nil || a.ProgrammaticAccessType == nil { - return "" - } - return *a.ProgrammaticAccessType -} - -// GetPullRequestID returns the PullRequestID field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetPullRequestID() int64 { - if a == nil || a.PullRequestID == nil { - return 0 - } - return *a.PullRequestID -} - -// GetPullRequestTitle returns the PullRequestTitle field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetPullRequestTitle() string { - if a == nil || a.PullRequestTitle == nil { - return "" - } - return *a.PullRequestTitle -} - -// GetPullRequestURL returns the PullRequestURL field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetPullRequestURL() string { - if a == nil || a.PullRequestURL == nil { - return "" - } - return *a.PullRequestURL -} - -// GetReadOnly returns the ReadOnly field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetReadOnly() string { - if a == nil || a.ReadOnly == nil { - return "" - } - return *a.ReadOnly -} - -// GetRepo returns the Repo field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetRepo() string { - if a == nil || a.Repo == nil { - return "" - } - return *a.Repo -} - -// GetRepository returns the Repository field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetRepository() string { - if a == nil || a.Repository == nil { - return "" - } - return *a.Repository -} - -// GetRepositoryPublic returns the RepositoryPublic field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetRepositoryPublic() bool { - if a == nil || a.RepositoryPublic == nil { - return false - } - return *a.RepositoryPublic -} - -// GetRunAttempt returns the RunAttempt field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetRunAttempt() int64 { - if a == nil || a.RunAttempt == nil { - return 0 - } - return *a.RunAttempt -} - -// GetRunnerGroupID returns the RunnerGroupID field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetRunnerGroupID() int64 { - if a == nil || a.RunnerGroupID == nil { - return 0 - } - return *a.RunnerGroupID -} - -// GetRunnerGroupName returns the RunnerGroupName field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetRunnerGroupName() string { - if a == nil || a.RunnerGroupName == nil { - return "" - } - return *a.RunnerGroupName -} - -// GetRunnerID returns the RunnerID field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetRunnerID() int64 { - if a == nil || a.RunnerID == nil { - return 0 - } - return *a.RunnerID -} - -// GetRunnerName returns the RunnerName field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetRunnerName() string { - if a == nil || a.RunnerName == nil { - return "" - } - return *a.RunnerName -} - -// GetRunNumber returns the RunNumber field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetRunNumber() int64 { - if a == nil || a.RunNumber == nil { - return 0 - } - return *a.RunNumber -} - -// GetSourceVersion returns the SourceVersion field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetSourceVersion() string { - if a == nil || a.SourceVersion == nil { - return "" - } - return *a.SourceVersion -} - -// GetStartedAt returns the StartedAt field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetStartedAt() Timestamp { - if a == nil || a.StartedAt == nil { - return Timestamp{} - } - return *a.StartedAt -} - -// GetTargetLogin returns the TargetLogin field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetTargetLogin() string { - if a == nil || a.TargetLogin == nil { - return "" - } - return *a.TargetLogin -} - -// GetTargetVersion returns the TargetVersion field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetTargetVersion() string { - if a == nil || a.TargetVersion == nil { - return "" - } - return *a.TargetVersion -} - -// GetTeam returns the Team field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetTeam() string { - if a == nil || a.Team == nil { - return "" - } - return *a.Team -} - // GetTimestamp returns the Timestamp field if it's non-nil, zero value otherwise. func (a *AuditEntry) GetTimestamp() Timestamp { if a == nil || a.Timestamp == nil { @@ -1590,38 +1190,6 @@ func (a *AuditEntry) GetTokenScopes() string { return *a.TokenScopes } -// GetTopic returns the Topic field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetTopic() string { - if a == nil || a.Topic == nil { - return "" - } - return *a.Topic -} - -// GetTransportProtocol returns the TransportProtocol field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetTransportProtocol() int { - if a == nil || a.TransportProtocol == nil { - return 0 - } - return *a.TransportProtocol -} - -// GetTransportProtocolName returns the TransportProtocolName field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetTransportProtocolName() string { - if a == nil || a.TransportProtocolName == nil { - return "" - } - return *a.TransportProtocolName -} - -// GetTriggerID returns the TriggerID field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetTriggerID() int64 { - if a == nil || a.TriggerID == nil { - return 0 - } - return *a.TriggerID -} - // GetUser returns the User field if it's non-nil, zero value otherwise. func (a *AuditEntry) GetUser() string { if a == nil || a.User == nil { @@ -1630,52 +1198,12 @@ func (a *AuditEntry) GetUser() string { return *a.User } -// GetUserAgent returns the UserAgent field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetUserAgent() string { - if a == nil || a.UserAgent == nil { - return "" - } - return *a.UserAgent -} - -// GetVisibility returns the Visibility field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetVisibility() string { - if a == nil || a.Visibility == nil { - return "" - } - return *a.Visibility -} - -// GetWorkflowID returns the WorkflowID field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetWorkflowID() int64 { - if a == nil || a.WorkflowID == nil { +// GetUserID returns the UserID field if it's non-nil, zero value otherwise. +func (a *AuditEntry) GetUserID() int64 { + if a == nil || a.UserID == nil { return 0 } - return *a.WorkflowID -} - -// GetWorkflowRunID returns the WorkflowRunID field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetWorkflowRunID() int64 { - if a == nil || a.WorkflowRunID == nil { - return 0 - } - return *a.WorkflowRunID -} - -// GetOldLogin returns the OldLogin field if it's non-nil, zero value otherwise. -func (a *AuditEntryData) GetOldLogin() string { - if a == nil || a.OldLogin == nil { - return "" - } - return *a.OldLogin -} - -// GetOldName returns the OldName field if it's non-nil, zero value otherwise. -func (a *AuditEntryData) GetOldName() string { - if a == nil || a.OldName == nil { - return "" - } - return *a.OldName + return *a.UserID } // GetApp returns the App field. @@ -14454,22 +13982,6 @@ func (p *Plan) GetSpace() int { return *p.Space } -// GetCode returns the Code field if it's non-nil, zero value otherwise. -func (p *PolicyOverrideReason) GetCode() string { - if p == nil || p.Code == nil { - return "" - } - return *p.Code -} - -// GetMessage returns the Message field if it's non-nil, zero value otherwise. -func (p *PolicyOverrideReason) GetMessage() string { - if p == nil || p.Message == nil { - return "" - } - return *p.Message -} - // GetConfigURL returns the ConfigURL field if it's non-nil, zero value otherwise. func (p *PreReceiveHook) GetConfigURL() string { if p == nil || p.ConfigURL == nil { diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index 84d104f18cb..2e8f9bacb43 100644 --- a/github/github-accessors_test.go +++ b/github/github-accessors_test.go @@ -1263,26 +1263,6 @@ func TestAuditEntry_GetAction(tt *testing.T) { a.GetAction() } -func TestAuditEntry_GetActive(tt *testing.T) { - var zeroValue bool - a := &AuditEntry{Active: &zeroValue} - a.GetActive() - a = &AuditEntry{} - a.GetActive() - a = nil - a.GetActive() -} - -func TestAuditEntry_GetActiveWas(tt *testing.T) { - var zeroValue bool - a := &AuditEntry{ActiveWas: &zeroValue} - a.GetActiveWas() - a = &AuditEntry{} - a.GetActiveWas() - a = nil - a.GetActiveWas() -} - func TestAuditEntry_GetActor(tt *testing.T) { var zeroValue string a := &AuditEntry{Actor: &zeroValue} @@ -1293,14 +1273,14 @@ func TestAuditEntry_GetActor(tt *testing.T) { a.GetActor() } -func TestAuditEntry_GetActorIP(tt *testing.T) { - var zeroValue string - a := &AuditEntry{ActorIP: &zeroValue} - a.GetActorIP() +func TestAuditEntry_GetActorID(tt *testing.T) { + var zeroValue int64 + a := &AuditEntry{ActorID: &zeroValue} + a.GetActorID() a = &AuditEntry{} - a.GetActorIP() + a.GetActorID() a = nil - a.GetActorIP() + a.GetActorID() } func TestAuditEntry_GetActorLocation(tt *testing.T) { @@ -1310,16 +1290,6 @@ func TestAuditEntry_GetActorLocation(tt *testing.T) { a.GetActorLocation() } -func TestAuditEntry_GetBlockedUser(tt *testing.T) { - var zeroValue string - a := &AuditEntry{BlockedUser: &zeroValue} - a.GetBlockedUser() - a = &AuditEntry{} - a.GetBlockedUser() - a = nil - a.GetBlockedUser() -} - func TestAuditEntry_GetBusiness(tt *testing.T) { var zeroValue string a := &AuditEntry{Business: &zeroValue} @@ -1330,58 +1300,14 @@ func TestAuditEntry_GetBusiness(tt *testing.T) { a.GetBusiness() } -func TestAuditEntry_GetCancelledAt(tt *testing.T) { - var zeroValue Timestamp - a := &AuditEntry{CancelledAt: &zeroValue} - a.GetCancelledAt() - a = &AuditEntry{} - a.GetCancelledAt() - a = nil - a.GetCancelledAt() -} - -func TestAuditEntry_GetCompletedAt(tt *testing.T) { - var zeroValue Timestamp - a := &AuditEntry{CompletedAt: &zeroValue} - a.GetCompletedAt() - a = &AuditEntry{} - a.GetCompletedAt() - a = nil - a.GetCompletedAt() -} - -func TestAuditEntry_GetConclusion(tt *testing.T) { - var zeroValue string - a := &AuditEntry{Conclusion: &zeroValue} - a.GetConclusion() - a = &AuditEntry{} - a.GetConclusion() - a = nil - a.GetConclusion() -} - -func TestAuditEntry_GetConfig(tt *testing.T) { - a := &AuditEntry{} - a.GetConfig() - a = nil - a.GetConfig() -} - -func TestAuditEntry_GetConfigWas(tt *testing.T) { - a := &AuditEntry{} - a.GetConfigWas() - a = nil - a.GetConfigWas() -} - -func TestAuditEntry_GetContentType(tt *testing.T) { - var zeroValue string - a := &AuditEntry{ContentType: &zeroValue} - a.GetContentType() +func TestAuditEntry_GetBusinessID(tt *testing.T) { + var zeroValue int64 + a := &AuditEntry{BusinessID: &zeroValue} + a.GetBusinessID() a = &AuditEntry{} - a.GetContentType() + a.GetBusinessID() a = nil - a.GetContentType() + a.GetBusinessID() } func TestAuditEntry_GetCreatedAt(tt *testing.T) { @@ -1394,23 +1320,6 @@ func TestAuditEntry_GetCreatedAt(tt *testing.T) { a.GetCreatedAt() } -func TestAuditEntry_GetData(tt *testing.T) { - a := &AuditEntry{} - a.GetData() - a = nil - a.GetData() -} - -func TestAuditEntry_GetDeployKeyFingerprint(tt *testing.T) { - var zeroValue string - a := &AuditEntry{DeployKeyFingerprint: &zeroValue} - a.GetDeployKeyFingerprint() - a = &AuditEntry{} - a.GetDeployKeyFingerprint() - a = nil - a.GetDeployKeyFingerprint() -} - func TestAuditEntry_GetDocumentID(tt *testing.T) { var zeroValue string a := &AuditEntry{DocumentID: &zeroValue} @@ -1421,46 +1330,6 @@ func TestAuditEntry_GetDocumentID(tt *testing.T) { a.GetDocumentID() } -func TestAuditEntry_GetEmoji(tt *testing.T) { - var zeroValue string - a := &AuditEntry{Emoji: &zeroValue} - a.GetEmoji() - a = &AuditEntry{} - a.GetEmoji() - a = nil - a.GetEmoji() -} - -func TestAuditEntry_GetEnvironmentName(tt *testing.T) { - var zeroValue string - a := &AuditEntry{EnvironmentName: &zeroValue} - a.GetEnvironmentName() - a = &AuditEntry{} - a.GetEnvironmentName() - a = nil - a.GetEnvironmentName() -} - -func TestAuditEntry_GetEvent(tt *testing.T) { - var zeroValue string - a := &AuditEntry{Event: &zeroValue} - a.GetEvent() - a = &AuditEntry{} - a.GetEvent() - a = nil - a.GetEvent() -} - -func TestAuditEntry_GetExplanation(tt *testing.T) { - var zeroValue string - a := &AuditEntry{Explanation: &zeroValue} - a.GetExplanation() - a = &AuditEntry{} - a.GetExplanation() - a = nil - a.GetExplanation() -} - func TestAuditEntry_GetExternalIdentityNameID(tt *testing.T) { var zeroValue string a := &AuditEntry{ExternalIdentityNameID: &zeroValue} @@ -1481,16 +1350,6 @@ func TestAuditEntry_GetExternalIdentityUsername(tt *testing.T) { a.GetExternalIdentityUsername() } -func TestAuditEntry_GetFingerprint(tt *testing.T) { - var zeroValue string - a := &AuditEntry{Fingerprint: &zeroValue} - a.GetFingerprint() - a = &AuditEntry{} - a.GetFingerprint() - a = nil - a.GetFingerprint() -} - func TestAuditEntry_GetHashedToken(tt *testing.T) { var zeroValue string a := &AuditEntry{HashedToken: &zeroValue} @@ -1501,146 +1360,6 @@ func TestAuditEntry_GetHashedToken(tt *testing.T) { a.GetHashedToken() } -func TestAuditEntry_GetHeadBranch(tt *testing.T) { - var zeroValue string - a := &AuditEntry{HeadBranch: &zeroValue} - a.GetHeadBranch() - a = &AuditEntry{} - a.GetHeadBranch() - a = nil - a.GetHeadBranch() -} - -func TestAuditEntry_GetHeadSHA(tt *testing.T) { - var zeroValue string - a := &AuditEntry{HeadSHA: &zeroValue} - a.GetHeadSHA() - a = &AuditEntry{} - a.GetHeadSHA() - a = nil - a.GetHeadSHA() -} - -func TestAuditEntry_GetHookID(tt *testing.T) { - var zeroValue int64 - a := &AuditEntry{HookID: &zeroValue} - a.GetHookID() - a = &AuditEntry{} - a.GetHookID() - a = nil - a.GetHookID() -} - -func TestAuditEntry_GetIsHostedRunner(tt *testing.T) { - var zeroValue bool - a := &AuditEntry{IsHostedRunner: &zeroValue} - a.GetIsHostedRunner() - a = &AuditEntry{} - a.GetIsHostedRunner() - a = nil - a.GetIsHostedRunner() -} - -func TestAuditEntry_GetJobName(tt *testing.T) { - var zeroValue string - a := &AuditEntry{JobName: &zeroValue} - a.GetJobName() - a = &AuditEntry{} - a.GetJobName() - a = nil - a.GetJobName() -} - -func TestAuditEntry_GetJobWorkflowRef(tt *testing.T) { - var zeroValue string - a := &AuditEntry{JobWorkflowRef: &zeroValue} - a.GetJobWorkflowRef() - a = &AuditEntry{} - a.GetJobWorkflowRef() - a = nil - a.GetJobWorkflowRef() -} - -func TestAuditEntry_GetLimitedAvailability(tt *testing.T) { - var zeroValue bool - a := &AuditEntry{LimitedAvailability: &zeroValue} - a.GetLimitedAvailability() - a = &AuditEntry{} - a.GetLimitedAvailability() - a = nil - a.GetLimitedAvailability() -} - -func TestAuditEntry_GetMessage(tt *testing.T) { - var zeroValue string - a := &AuditEntry{Message: &zeroValue} - a.GetMessage() - a = &AuditEntry{} - a.GetMessage() - a = nil - a.GetMessage() -} - -func TestAuditEntry_GetName(tt *testing.T) { - var zeroValue string - a := &AuditEntry{Name: &zeroValue} - a.GetName() - a = &AuditEntry{} - a.GetName() - a = nil - a.GetName() -} - -func TestAuditEntry_GetOAuthApplicationID(tt *testing.T) { - var zeroValue int64 - a := &AuditEntry{OAuthApplicationID: &zeroValue} - a.GetOAuthApplicationID() - a = &AuditEntry{} - a.GetOAuthApplicationID() - a = nil - a.GetOAuthApplicationID() -} - -func TestAuditEntry_GetOldPermission(tt *testing.T) { - var zeroValue string - a := &AuditEntry{OldPermission: &zeroValue} - a.GetOldPermission() - a = &AuditEntry{} - a.GetOldPermission() - a = nil - a.GetOldPermission() -} - -func TestAuditEntry_GetOldUser(tt *testing.T) { - var zeroValue string - a := &AuditEntry{OldUser: &zeroValue} - a.GetOldUser() - a = &AuditEntry{} - a.GetOldUser() - a = nil - a.GetOldUser() -} - -func TestAuditEntry_GetOpenSSHPublicKey(tt *testing.T) { - var zeroValue string - a := &AuditEntry{OpenSSHPublicKey: &zeroValue} - a.GetOpenSSHPublicKey() - a = &AuditEntry{} - a.GetOpenSSHPublicKey() - a = nil - a.GetOpenSSHPublicKey() -} - -func TestAuditEntry_GetOperationType(tt *testing.T) { - var zeroValue string - a := &AuditEntry{OperationType: &zeroValue} - a.GetOperationType() - a = &AuditEntry{} - a.GetOperationType() - a = nil - a.GetOperationType() -} - func TestAuditEntry_GetOrg(tt *testing.T) { var zeroValue string a := &AuditEntry{Org: &zeroValue} @@ -1661,216 +1380,6 @@ func TestAuditEntry_GetOrgID(tt *testing.T) { a.GetOrgID() } -func TestAuditEntry_GetPermission(tt *testing.T) { - var zeroValue string - a := &AuditEntry{Permission: &zeroValue} - a.GetPermission() - a = &AuditEntry{} - a.GetPermission() - a = nil - a.GetPermission() -} - -func TestAuditEntry_GetPreviousVisibility(tt *testing.T) { - var zeroValue string - a := &AuditEntry{PreviousVisibility: &zeroValue} - a.GetPreviousVisibility() - a = &AuditEntry{} - a.GetPreviousVisibility() - a = nil - a.GetPreviousVisibility() -} - -func TestAuditEntry_GetProgrammaticAccessType(tt *testing.T) { - var zeroValue string - a := &AuditEntry{ProgrammaticAccessType: &zeroValue} - a.GetProgrammaticAccessType() - a = &AuditEntry{} - a.GetProgrammaticAccessType() - a = nil - a.GetProgrammaticAccessType() -} - -func TestAuditEntry_GetPullRequestID(tt *testing.T) { - var zeroValue int64 - a := &AuditEntry{PullRequestID: &zeroValue} - a.GetPullRequestID() - a = &AuditEntry{} - a.GetPullRequestID() - a = nil - a.GetPullRequestID() -} - -func TestAuditEntry_GetPullRequestTitle(tt *testing.T) { - var zeroValue string - a := &AuditEntry{PullRequestTitle: &zeroValue} - a.GetPullRequestTitle() - a = &AuditEntry{} - a.GetPullRequestTitle() - a = nil - a.GetPullRequestTitle() -} - -func TestAuditEntry_GetPullRequestURL(tt *testing.T) { - var zeroValue string - a := &AuditEntry{PullRequestURL: &zeroValue} - a.GetPullRequestURL() - a = &AuditEntry{} - a.GetPullRequestURL() - a = nil - a.GetPullRequestURL() -} - -func TestAuditEntry_GetReadOnly(tt *testing.T) { - var zeroValue string - a := &AuditEntry{ReadOnly: &zeroValue} - a.GetReadOnly() - a = &AuditEntry{} - a.GetReadOnly() - a = nil - a.GetReadOnly() -} - -func TestAuditEntry_GetRepo(tt *testing.T) { - var zeroValue string - a := &AuditEntry{Repo: &zeroValue} - a.GetRepo() - a = &AuditEntry{} - a.GetRepo() - a = nil - a.GetRepo() -} - -func TestAuditEntry_GetRepository(tt *testing.T) { - var zeroValue string - a := &AuditEntry{Repository: &zeroValue} - a.GetRepository() - a = &AuditEntry{} - a.GetRepository() - a = nil - a.GetRepository() -} - -func TestAuditEntry_GetRepositoryPublic(tt *testing.T) { - var zeroValue bool - a := &AuditEntry{RepositoryPublic: &zeroValue} - a.GetRepositoryPublic() - a = &AuditEntry{} - a.GetRepositoryPublic() - a = nil - a.GetRepositoryPublic() -} - -func TestAuditEntry_GetRunAttempt(tt *testing.T) { - var zeroValue int64 - a := &AuditEntry{RunAttempt: &zeroValue} - a.GetRunAttempt() - a = &AuditEntry{} - a.GetRunAttempt() - a = nil - a.GetRunAttempt() -} - -func TestAuditEntry_GetRunnerGroupID(tt *testing.T) { - var zeroValue int64 - a := &AuditEntry{RunnerGroupID: &zeroValue} - a.GetRunnerGroupID() - a = &AuditEntry{} - a.GetRunnerGroupID() - a = nil - a.GetRunnerGroupID() -} - -func TestAuditEntry_GetRunnerGroupName(tt *testing.T) { - var zeroValue string - a := &AuditEntry{RunnerGroupName: &zeroValue} - a.GetRunnerGroupName() - a = &AuditEntry{} - a.GetRunnerGroupName() - a = nil - a.GetRunnerGroupName() -} - -func TestAuditEntry_GetRunnerID(tt *testing.T) { - var zeroValue int64 - a := &AuditEntry{RunnerID: &zeroValue} - a.GetRunnerID() - a = &AuditEntry{} - a.GetRunnerID() - a = nil - a.GetRunnerID() -} - -func TestAuditEntry_GetRunnerName(tt *testing.T) { - var zeroValue string - a := &AuditEntry{RunnerName: &zeroValue} - a.GetRunnerName() - a = &AuditEntry{} - a.GetRunnerName() - a = nil - a.GetRunnerName() -} - -func TestAuditEntry_GetRunNumber(tt *testing.T) { - var zeroValue int64 - a := &AuditEntry{RunNumber: &zeroValue} - a.GetRunNumber() - a = &AuditEntry{} - a.GetRunNumber() - a = nil - a.GetRunNumber() -} - -func TestAuditEntry_GetSourceVersion(tt *testing.T) { - var zeroValue string - a := &AuditEntry{SourceVersion: &zeroValue} - a.GetSourceVersion() - a = &AuditEntry{} - a.GetSourceVersion() - a = nil - a.GetSourceVersion() -} - -func TestAuditEntry_GetStartedAt(tt *testing.T) { - var zeroValue Timestamp - a := &AuditEntry{StartedAt: &zeroValue} - a.GetStartedAt() - a = &AuditEntry{} - a.GetStartedAt() - a = nil - a.GetStartedAt() -} - -func TestAuditEntry_GetTargetLogin(tt *testing.T) { - var zeroValue string - a := &AuditEntry{TargetLogin: &zeroValue} - a.GetTargetLogin() - a = &AuditEntry{} - a.GetTargetLogin() - a = nil - a.GetTargetLogin() -} - -func TestAuditEntry_GetTargetVersion(tt *testing.T) { - var zeroValue string - a := &AuditEntry{TargetVersion: &zeroValue} - a.GetTargetVersion() - a = &AuditEntry{} - a.GetTargetVersion() - a = nil - a.GetTargetVersion() -} - -func TestAuditEntry_GetTeam(tt *testing.T) { - var zeroValue string - a := &AuditEntry{Team: &zeroValue} - a.GetTeam() - a = &AuditEntry{} - a.GetTeam() - a = nil - a.GetTeam() -} - func TestAuditEntry_GetTimestamp(tt *testing.T) { var zeroValue Timestamp a := &AuditEntry{Timestamp: &zeroValue} @@ -1901,46 +1410,6 @@ func TestAuditEntry_GetTokenScopes(tt *testing.T) { a.GetTokenScopes() } -func TestAuditEntry_GetTopic(tt *testing.T) { - var zeroValue string - a := &AuditEntry{Topic: &zeroValue} - a.GetTopic() - a = &AuditEntry{} - a.GetTopic() - a = nil - a.GetTopic() -} - -func TestAuditEntry_GetTransportProtocol(tt *testing.T) { - var zeroValue int - a := &AuditEntry{TransportProtocol: &zeroValue} - a.GetTransportProtocol() - a = &AuditEntry{} - a.GetTransportProtocol() - a = nil - a.GetTransportProtocol() -} - -func TestAuditEntry_GetTransportProtocolName(tt *testing.T) { - var zeroValue string - a := &AuditEntry{TransportProtocolName: &zeroValue} - a.GetTransportProtocolName() - a = &AuditEntry{} - a.GetTransportProtocolName() - a = nil - a.GetTransportProtocolName() -} - -func TestAuditEntry_GetTriggerID(tt *testing.T) { - var zeroValue int64 - a := &AuditEntry{TriggerID: &zeroValue} - a.GetTriggerID() - a = &AuditEntry{} - a.GetTriggerID() - a = nil - a.GetTriggerID() -} - func TestAuditEntry_GetUser(tt *testing.T) { var zeroValue string a := &AuditEntry{User: &zeroValue} @@ -1951,64 +1420,14 @@ func TestAuditEntry_GetUser(tt *testing.T) { a.GetUser() } -func TestAuditEntry_GetUserAgent(tt *testing.T) { - var zeroValue string - a := &AuditEntry{UserAgent: &zeroValue} - a.GetUserAgent() - a = &AuditEntry{} - a.GetUserAgent() - a = nil - a.GetUserAgent() -} - -func TestAuditEntry_GetVisibility(tt *testing.T) { - var zeroValue string - a := &AuditEntry{Visibility: &zeroValue} - a.GetVisibility() - a = &AuditEntry{} - a.GetVisibility() - a = nil - a.GetVisibility() -} - -func TestAuditEntry_GetWorkflowID(tt *testing.T) { - var zeroValue int64 - a := &AuditEntry{WorkflowID: &zeroValue} - a.GetWorkflowID() - a = &AuditEntry{} - a.GetWorkflowID() - a = nil - a.GetWorkflowID() -} - -func TestAuditEntry_GetWorkflowRunID(tt *testing.T) { +func TestAuditEntry_GetUserID(tt *testing.T) { var zeroValue int64 - a := &AuditEntry{WorkflowRunID: &zeroValue} - a.GetWorkflowRunID() + a := &AuditEntry{UserID: &zeroValue} + a.GetUserID() a = &AuditEntry{} - a.GetWorkflowRunID() - a = nil - a.GetWorkflowRunID() -} - -func TestAuditEntryData_GetOldLogin(tt *testing.T) { - var zeroValue string - a := &AuditEntryData{OldLogin: &zeroValue} - a.GetOldLogin() - a = &AuditEntryData{} - a.GetOldLogin() + a.GetUserID() a = nil - a.GetOldLogin() -} - -func TestAuditEntryData_GetOldName(tt *testing.T) { - var zeroValue string - a := &AuditEntryData{OldName: &zeroValue} - a.GetOldName() - a = &AuditEntryData{} - a.GetOldName() - a = nil - a.GetOldName() + a.GetUserID() } func TestAuthorization_GetApp(tt *testing.T) { @@ -16919,26 +16338,6 @@ func TestPlan_GetSpace(tt *testing.T) { p.GetSpace() } -func TestPolicyOverrideReason_GetCode(tt *testing.T) { - var zeroValue string - p := &PolicyOverrideReason{Code: &zeroValue} - p.GetCode() - p = &PolicyOverrideReason{} - p.GetCode() - p = nil - p.GetCode() -} - -func TestPolicyOverrideReason_GetMessage(tt *testing.T) { - var zeroValue string - p := &PolicyOverrideReason{Message: &zeroValue} - p.GetMessage() - p = &PolicyOverrideReason{} - p.GetMessage() - p = nil - p.GetMessage() -} - func TestPreReceiveHook_GetConfigURL(tt *testing.T) { var zeroValue string p := &PreReceiveHook{ConfigURL: &zeroValue} diff --git a/github/github_test.go b/github/github_test.go index b994496cc01..85acacccd2b 100644 --- a/github/github_test.go +++ b/github/github_test.go @@ -275,6 +275,15 @@ func testErrorResponseForStatusCode(t *testing.T, code int) { } } +func assertNoDiff(t *testing.T, want, actual interface{}) { + t.Helper() + diff := cmp.Diff(want, actual) + if diff == "" { + return + } + t.Errorf("unexpected diff: %s", diff) +} + func assertNilError(t *testing.T, err error) { t.Helper() if err != nil { diff --git a/github/orgs_audit_log.go b/github/orgs_audit_log.go index e3afd3117f5..33460a8923f 100644 --- a/github/orgs_audit_log.go +++ b/github/orgs_audit_log.go @@ -7,6 +7,7 @@ package github import ( "context" + "encoding/json" "fmt" ) @@ -34,103 +35,100 @@ type ActorLocation struct { CountryCode *string `json:"country_code,omitempty"` } -// PolicyOverrideReason contains user-supplied information about why a policy was overridden. -type PolicyOverrideReason struct { - Code *string `json:"code,omitempty"` - Message *string `json:"message,omitempty"` -} - // AuditEntry describes the fields that may be represented by various audit-log "action" entries. +// There are many other fields that may be present depending on the action. You can access those +// in AdditionalFields. // For a list of actions see - https://docs.github.com/github/setting-up-and-managing-organizations-and-teams/reviewing-the-audit-log-for-your-organization#audit-log-actions type AuditEntry struct { - ActorIP *string `json:"actor_ip,omitempty"` - Action *string `json:"action,omitempty"` // The name of the action that was performed, for example `user.login` or `repo.create`. - Active *bool `json:"active,omitempty"` - ActiveWas *bool `json:"active_was,omitempty"` - Actor *string `json:"actor,omitempty"` // The actor who performed the action. - ActorLocation *ActorLocation `json:"actor_location,omitempty"` - BlockedUser *string `json:"blocked_user,omitempty"` - Business *string `json:"business,omitempty"` - CancelledAt *Timestamp `json:"cancelled_at,omitempty"` - CompletedAt *Timestamp `json:"completed_at,omitempty"` - Conclusion *string `json:"conclusion,omitempty"` - Config *HookConfig `json:"config,omitempty"` - ConfigWas *HookConfig `json:"config_was,omitempty"` - ContentType *string `json:"content_type,omitempty"` - CreatedAt *Timestamp `json:"created_at,omitempty"` - DeployKeyFingerprint *string `json:"deploy_key_fingerprint,omitempty"` - DocumentID *string `json:"_document_id,omitempty"` - Emoji *string `json:"emoji,omitempty"` - EnvironmentName *string `json:"environment_name,omitempty"` - Event *string `json:"event,omitempty"` - Events []string `json:"events,omitempty"` - EventsWere []string `json:"events_were,omitempty"` - Explanation *string `json:"explanation,omitempty"` - ExternalIdentityNameID *string `json:"external_identity_nameid,omitempty"` - ExternalIdentityUsername *string `json:"external_identity_username,omitempty"` - Fingerprint *string `json:"fingerprint,omitempty"` - HashedToken *string `json:"hashed_token,omitempty"` - HeadBranch *string `json:"head_branch,omitempty"` - HeadSHA *string `json:"head_sha,omitempty"` - HookID *int64 `json:"hook_id,omitempty"` - IsHostedRunner *bool `json:"is_hosted_runner,omitempty"` - JobName *string `json:"job_name,omitempty"` - JobWorkflowRef *string `json:"job_workflow_ref,omitempty"` - LimitedAvailability *bool `json:"limited_availability,omitempty"` - Message *string `json:"message,omitempty"` - Name *string `json:"name,omitempty"` - OAuthApplicationID *int64 `json:"oauth_application_id,omitempty"` - OldUser *string `json:"old_user,omitempty"` - OldPermission *string `json:"old_permission,omitempty"` // The permission level for membership changes, for example `admin` or `read`. - OpenSSHPublicKey *string `json:"openssh_public_key,omitempty"` - OperationType *string `json:"operation_type,omitempty"` - Org *string `json:"org,omitempty"` - OrgID *int64 `json:"org_id,omitempty"` - OverriddenCodes []string `json:"overridden_codes,omitempty"` - Permission *string `json:"permission,omitempty"` // The permission level for membership changes, for example `admin` or `read`. - PreviousVisibility *string `json:"previous_visibility,omitempty"` - ProgrammaticAccessType *string `json:"programmatic_access_type,omitempty"` - PullRequestID *int64 `json:"pull_request_id,omitempty"` - PullRequestTitle *string `json:"pull_request_title,omitempty"` - PullRequestURL *string `json:"pull_request_url,omitempty"` - ReadOnly *string `json:"read_only,omitempty"` - Reasons []*PolicyOverrideReason `json:"reasons,omitempty"` - Repo *string `json:"repo,omitempty"` - Repository *string `json:"repository,omitempty"` - RepositoryPublic *bool `json:"repository_public,omitempty"` - RunAttempt *int64 `json:"run_attempt,omitempty"` - RunnerGroupID *int64 `json:"runner_group_id,omitempty"` - RunnerGroupName *string `json:"runner_group_name,omitempty"` - RunnerID *int64 `json:"runner_id,omitempty"` - RunnerLabels []string `json:"runner_labels,omitempty"` - RunnerName *string `json:"runner_name,omitempty"` - RunNumber *int64 `json:"run_number,omitempty"` - SecretsPassed []string `json:"secrets_passed,omitempty"` - SourceVersion *string `json:"source_version,omitempty"` - StartedAt *Timestamp `json:"started_at,omitempty"` - TargetLogin *string `json:"target_login,omitempty"` - TargetVersion *string `json:"target_version,omitempty"` - Team *string `json:"team,omitempty"` - Timestamp *Timestamp `json:"@timestamp,omitempty"` // The time the audit log event occurred, given as a [Unix timestamp](http://en.wikipedia.org/wiki/Unix_time). - TokenID *int64 `json:"token_id,omitempty"` - TokenScopes *string `json:"token_scopes,omitempty"` - Topic *string `json:"topic,omitempty"` - TransportProtocolName *string `json:"transport_protocol_name,omitempty"` // A human readable name for the protocol (for example, HTTP or SSH) used to transfer Git data. - TransportProtocol *int `json:"transport_protocol,omitempty"` // The type of protocol (for example, HTTP=1 or SSH=2) used to transfer Git data. - TriggerID *int64 `json:"trigger_id,omitempty"` - User *string `json:"user,omitempty"` // The user that was affected by the action performed (if available). - UserAgent *string `json:"user_agent,omitempty"` - Visibility *string `json:"visibility,omitempty"` // The repository visibility, for example `public` or `private`. - WorkflowID *int64 `json:"workflow_id,omitempty"` - WorkflowRunID *int64 `json:"workflow_run_id,omitempty"` - - Data *AuditEntryData `json:"data,omitempty"` + Action *string `json:"action,omitempty"` // The name of the action that was performed, for example `user.login` or `repo.create`. + Actor *string `json:"actor,omitempty"` // The actor who performed the action. + ActorID *int64 `json:"actor_id,omitempty"` + ActorLocation *ActorLocation `json:"actor_location,omitempty"` + Business *string `json:"business,omitempty"` + BusinessID *int64 `json:"business_id,omitempty"` + CreatedAt *Timestamp `json:"created_at,omitempty"` + DocumentID *string `json:"_document_id,omitempty"` + ExternalIdentityNameID *string `json:"external_identity_nameid,omitempty"` + ExternalIdentityUsername *string `json:"external_identity_username,omitempty"` + HashedToken *string `json:"hashed_token,omitempty"` + Org *string `json:"org,omitempty"` + OrgID *int64 `json:"org_id,omitempty"` + Timestamp *Timestamp `json:"@timestamp,omitempty"` // The time the audit log event occurred, given as a [Unix timestamp](http://en.wikipedia.org/wiki/Unix_time). + TokenID *int64 `json:"token_id,omitempty"` + TokenScopes *string `json:"token_scopes,omitempty"` + User *string `json:"user,omitempty"` // The user that was affected by the action performed (if available). + UserID *int64 `json:"user_id,omitempty"` + + // Some events types have a data field that contains additional information about the event. + Data map[string]interface{} `json:"data,omitempty"` + + // All fields that are not explicitly defined in the struct are captured here. + AdditionalFields map[string]interface{} `json:"-"` +} + +func (a *AuditEntry) UnmarshalJSON(data []byte) error { + type entryAlias AuditEntry + var v entryAlias + err := json.Unmarshal(data, &v) + if err != nil { + return err + } + + rawDefinedFields, err := json.Marshal(v) + if err != nil { + return err + } + definedFields := map[string]interface{}{} + err = json.Unmarshal(rawDefinedFields, &definedFields) + if err != nil { + return err + } + + err = json.Unmarshal(data, &v.AdditionalFields) + if err != nil { + return err + } + + for key, val := range v.AdditionalFields { + _, defined := definedFields[key] + if defined || val == nil { + delete(v.AdditionalFields, key) + } + } + + *a = AuditEntry(v) + if len(v.AdditionalFields) == 0 { + a.AdditionalFields = nil + } + return nil } -// AuditEntryData represents additional information stuffed into a `data` field. -type AuditEntryData struct { - OldName *string `json:"old_name,omitempty"` // The previous name of the repository, for a name change - OldLogin *string `json:"old_login,omitempty"` // The previous name of the organization, for a name change +func (a *AuditEntry) MarshalJSON() ([]byte, error) { + type entryAlias AuditEntry + v := entryAlias(*a) + defBytes, err := json.Marshal(v) + if err != nil { + return nil, err + } + if len(a.AdditionalFields) == 0 { + return defBytes, err + } + resMap := map[string]interface{}{} + err = json.Unmarshal(defBytes, &resMap) + if err != nil { + return nil, err + } + for key, val := range a.AdditionalFields { + if val == nil { + continue + } + _, defined := resMap[key] + if defined { + return nil, fmt.Errorf("unexpected field in AdditionalFields: %s", key) + } + resMap[key] = val + } + return json.Marshal(resMap) } // GetAuditLog gets the audit-log entries for an organization. diff --git a/github/orgs_audit_log_test.go b/github/orgs_audit_log_test.go index 1a82471face..24efc623485 100644 --- a/github/orgs_audit_log_test.go +++ b/github/orgs_audit_log_test.go @@ -12,8 +12,6 @@ import ( "strings" "testing" "time" - - "github.com/google/go-cmp/cmp" ) func TestOrganizationService_GetAuditLog(t *testing.T) { @@ -54,7 +52,6 @@ func TestOrganizationService_GetAuditLog(t *testing.T) { "run_number": 1, "token_id": 1, "token_scopes": "gist,repo:read", - "topic": "cp1-iad.ingest.github.actions.v0.WorkflowUpdate", "job_workflow_ref": "testorg/testrepo/.github/workflows/testjob.yml@refs/pull/1/merge", "oauth_application_id": 1, "org_id": 1, @@ -91,8 +88,8 @@ func TestOrganizationService_GetAuditLog(t *testing.T) { if err != nil { t.Errorf("Organizations.GetAuditLog returned error: %v", err) } - startedAt, _ := time.Parse(time.RFC3339, "2021-03-07T00:33:04.000Z") - completedAt, _ := time.Parse(time.RFC3339, "2021-03-07T00:35:08.000Z") + //startedAt, _ := time.Parse(time.RFC3339, "2021-03-07T00:33:04.000Z") + //completedAt, _ := time.Parse(time.RFC3339, "2021-03-07T00:35:08.000Z") timestamp := time.Unix(0, 1615077308538*1e6) want := []*AuditEntry{ @@ -101,56 +98,55 @@ func TestOrganizationService_GetAuditLog(t *testing.T) { DocumentID: String("beeZYapIUe-wKg5-beadb33"), Action: String("workflows.completed_workflow_run"), Actor: String("testactor"), - ActorIP: String("10.0.0.1"), ActorLocation: &ActorLocation{ CountryCode: String("US"), }, - Active: Bool(true), - CompletedAt: &Timestamp{completedAt}, - Conclusion: String("success"), - CreatedAt: &Timestamp{timestamp}, - Event: String("schedule"), - HashedToken: String("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="), - HeadBranch: String("master"), - HeadSHA: String("5acdeadbeef64d1a62388e901e5cdc9358644b37"), - JobWorkflowRef: String("testorg/testrepo/.github/workflows/testjob.yml@refs/pull/1/merge"), - Name: String("Code scanning - action"), - OAuthApplicationID: Int64(1), - OldPermission: String("read"), - Org: String("o"), - OrgID: Int64(1), - OverriddenCodes: []string{"review_policy_not_satisfied"}, - Permission: String("admin"), - ProgrammaticAccessType: String("GitHub App server-to-server token"), - PullRequestID: Int64(1), - PullRequestTitle: String("a pr title"), - PullRequestURL: String("https://github.com/testorg/testrepo/pull/1"), - Reasons: []*PolicyOverrideReason{{ - Code: String("a code"), - Message: String("a message"), - }}, - Repo: String("o/blue-crayon-1"), - RunAttempt: Int64(1), - RunNumber: Int64(1), - StartedAt: &Timestamp{startedAt}, - TokenID: Int64(1), - TokenScopes: String("gist,repo:read"), - Topic: String("cp1-iad.ingest.github.actions.v0.WorkflowUpdate"), - UserAgent: String("a user agent"), - WorkflowID: Int64(123456), - WorkflowRunID: Int64(628312345), - Events: []string{"code_scanning_alert"}, - Config: &HookConfig{ - ContentType: String("json"), - InsecureSSL: String("0"), - URL: String("https://example.com/deadbeef-new-hook"), + CreatedAt: &Timestamp{timestamp}, + HashedToken: String("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="), + Org: String("o"), + OrgID: Int64(1), + TokenID: Int64(1), + TokenScopes: String("gist,repo:read"), + AdditionalFields: map[string]interface{}{ + "actor_ip": "10.0.0.1", + "active": true, + "completed_at": "2021-03-07T00:35:08.000Z", + "conclusion": "success", + "event": "schedule", + "head_branch": "master", + "head_sha": "5acdeadbeef64d1a62388e901e5cdc9358644b37", + "job_workflow_ref": "testorg/testrepo/.github/workflows/testjob.yml@refs/pull/1/merge", + "name": "Code scanning - action", + "oauth_application_id": float64(1), + "old_permission": "read", + "overridden_codes": []interface{}{"review_policy_not_satisfied"}, + "permission": "admin", + "programmatic_access_type": "GitHub App server-to-server token", + "pull_request_id": float64(1), + "pull_request_title": "a pr title", + "pull_request_url": "https://github.com/testorg/testrepo/pull/1", + "reasons": []interface{}{map[string]interface{}{ + "code": "a code", + "message": "a message", + }}, + "repo": "o/blue-crayon-1", + "run_attempt": float64(1), + "run_number": float64(1), + "started_at": "2021-03-07T00:33:04.000Z", + "user_agent": "a user agent", + "workflow_id": float64(123456), + "workflow_run_id": float64(628312345), + "events": []interface{}{"code_scanning_alert"}, + "config": map[string]interface{}{ + "content_type": "json", + "insecure_ssl": "0", + "url": "https://example.com/deadbeef-new-hook", + }, }, }, } - if !cmp.Equal(auditEntries, want) { - t.Errorf("Organizations.GetAuditLog return \ngot: %+v,\nwant:%+v", auditEntries, want) - } + assertNoDiff(t, want, auditEntries) // assert query string has lower case params requestedQuery := resp.Request.URL.RawQuery @@ -224,86 +220,91 @@ func TestAuditEntry_Marshal(t *testing.T) { u := &AuditEntry{ Action: String("a"), - Active: Bool(false), - ActiveWas: Bool(false), Actor: String("ac"), - ActorIP: String("aip"), ActorLocation: &ActorLocation{CountryCode: String("alcc")}, - BlockedUser: String("bu"), Business: String("b"), - CancelledAt: &Timestamp{referenceTime}, - CompletedAt: &Timestamp{referenceTime}, - Conclusion: String("c"), - Config: &HookConfig{URL: String("s")}, - ConfigWas: &HookConfig{URL: String("s")}, - ContentType: String("ct"), CreatedAt: &Timestamp{referenceTime}, - DeployKeyFingerprint: String("dkf"), DocumentID: String("did"), - Emoji: String("e"), - EnvironmentName: String("en"), - Event: String("e"), - Events: []string{"s"}, - EventsWere: []string{"s"}, - Explanation: String("e"), ExternalIdentityNameID: String("ein"), ExternalIdentityUsername: String("eiu"), - Fingerprint: String("f"), HashedToken: String("ht"), - HeadBranch: String("hb"), - HeadSHA: String("hsha"), - HookID: Int64(1), - IsHostedRunner: Bool(false), - JobName: String("jn"), - LimitedAvailability: Bool(false), - Message: String("m"), - Name: String("n"), - OldPermission: String("op"), - OldUser: String("ou"), - OpenSSHPublicKey: String("osshpk"), Org: String("o"), OrgID: Int64(1), - Permission: String("p"), - PreviousVisibility: String("pv"), - ProgrammaticAccessType: String("pat"), - PullRequestID: Int64(1), - PullRequestTitle: String("prt"), - PullRequestURL: String("pru"), - Reasons: []*PolicyOverrideReason{{ - Code: String("c"), - Message: String("m"), - }}, - ReadOnly: String("ro"), - Repo: String("r"), - Repository: String("repo"), - RepositoryPublic: Bool(false), - RunAttempt: Int64(1), - RunnerGroupID: Int64(1), - RunnerGroupName: String("rgn"), - RunnerID: Int64(1), - RunnerLabels: []string{"s"}, - RunnerName: String("rn"), - SecretsPassed: []string{"s"}, - SourceVersion: String("sv"), - StartedAt: &Timestamp{referenceTime}, - TargetLogin: String("tl"), - TargetVersion: String("tv"), - Team: String("t"), - Timestamp: &Timestamp{referenceTime}, - TokenID: Int64(1), - TokenScopes: String("ts"), - Topic: String("tp"), - TransportProtocolName: String("tpn"), - TransportProtocol: Int(1), - TriggerID: Int64(1), - User: String("u"), - UserAgent: String("ua"), - Visibility: String("v"), - WorkflowID: Int64(1), - WorkflowRunID: Int64(1), - Data: &AuditEntryData{ - OldName: String("on"), - OldLogin: String("ol"), + Timestamp: &Timestamp{referenceTime}, + TokenID: Int64(1), + TokenScopes: String("ts"), + User: String("u"), + Data: map[string]interface{}{ + "old_name": "on", + "old_login": "ol", + }, + AdditionalFields: map[string]interface{}{ + "active": false, + "active_was": false, + "actor_ip": "aip", + "blocked_user": "bu", + "conclusion": "c", + "config": map[string]interface{}{ + "url": "s", + }, + "config_was": map[string]interface{}{ + "url": "s", + }, + "content_type": "ct", + "deploy_key_fingerprint": "dkf", + "emoji": "e", + "environment_name": "en", + "event": "e", + "events": []interface{}{"s"}, + "events_were": []interface{}{"s"}, + "explanation": "e", + "fingerprint": "f", + "head_branch": "hb", + "head_sha": "hsha", + "hook_id": float64(1), + "is_hosted_runner": false, + "job_name": "jn", + "limited_availability": false, + "message": "m", + "name": "n", + "old_permission": "op", + "old_user": "ou", + "openssh_public_key": "osshpk", + "permission": "p", + "previous_visibility": "pv", + "programmatic_access_type": "pat", + "pull_request_id": float64(1), + "pull_request_title": "prt", + "pull_request_url": "pru", + "read_only": "ro", + "reasons": []interface{}{ + map[string]interface{}{ + "code": "c", + "message": "m", + }, + }, + "repo": "r", + "repository": "repo", + "repository_public": false, + "run_attempt": 1, + "runner_group_id": 1, + "runner_group_name": "rgn", + "runner_id": 1, + "runner_labels": []interface{}{"s"}, + "runner_name": "rn", + "secrets_passed": []interface{}{"s"}, + "source_version": "sv", + "started_at": "2006-01-02T15:04:05Z", + "target_login": "tl", + "target_version": "tv", + "team": "t", + "transport_protocol": 1, + "transport_protocol_name": "tpn", + "trigger_id": 1, + "user_agent": "ua", + "visibility": "v", + "workflow_id": 1, + "workflow_run_id": 1, }, } @@ -318,8 +319,6 @@ func TestAuditEntry_Marshal(t *testing.T) { }, "blocked_user": "bu", "business": "b", - "cancelled_at": ` + referenceTimeStr + `, - "completed_at": ` + referenceTimeStr + `, "conclusion": "c", "config": { "url": "s" @@ -391,7 +390,6 @@ func TestAuditEntry_Marshal(t *testing.T) { "@timestamp": ` + referenceTimeStr + `, "token_id": 1, "token_scopes": "ts", - "topic": "tp", "transport_protocol_name": "tpn", "transport_protocol": 1, "trigger_id": 1, diff --git a/test/integration/audit_log_test.go b/test/integration/audit_log_test.go index 7819f9292ff..639ea7a6780 100644 --- a/test/integration/audit_log_test.go +++ b/test/integration/audit_log_test.go @@ -28,6 +28,6 @@ func TestOrganizationAuditLog(t *testing.T) { } for _, e := range entries { - t.Log(e.GetAction(), e.GetActor(), e.GetTimestamp(), e.GetUser(), e.GetActive()) + t.Log(e.GetAction(), e.GetActor(), e.GetTimestamp(), e.GetUser()) } } From 28b5125a2309c76aa067333045e11e0cb3f7638d Mon Sep 17 00:00:00 2001 From: Will Roden Date: Tue, 5 Dec 2023 15:21:12 -0600 Subject: [PATCH 02/13] remove commented code --- github/orgs_audit_log_test.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/github/orgs_audit_log_test.go b/github/orgs_audit_log_test.go index 24efc623485..bfe3a52566d 100644 --- a/github/orgs_audit_log_test.go +++ b/github/orgs_audit_log_test.go @@ -88,8 +88,6 @@ func TestOrganizationService_GetAuditLog(t *testing.T) { if err != nil { t.Errorf("Organizations.GetAuditLog returned error: %v", err) } - //startedAt, _ := time.Parse(time.RFC3339, "2021-03-07T00:33:04.000Z") - //completedAt, _ := time.Parse(time.RFC3339, "2021-03-07T00:35:08.000Z") timestamp := time.Unix(0, 1615077308538*1e6) want := []*AuditEntry{ From a1c447291bb7bdcba82db2524cfb869512a70fcb Mon Sep 17 00:00:00 2001 From: Will Roden Date: Wed, 6 Dec 2023 10:11:32 -0600 Subject: [PATCH 03/13] apply review suggestions --- github/orgs_audit_log.go | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/github/orgs_audit_log.go b/github/orgs_audit_log.go index 33460a8923f..28ac079bb3b 100644 --- a/github/orgs_audit_log.go +++ b/github/orgs_audit_log.go @@ -69,8 +69,7 @@ type AuditEntry struct { func (a *AuditEntry) UnmarshalJSON(data []byte) error { type entryAlias AuditEntry var v entryAlias - err := json.Unmarshal(data, &v) - if err != nil { + if err := json.Unmarshal(data, &v); err != nil { return err } @@ -79,19 +78,16 @@ func (a *AuditEntry) UnmarshalJSON(data []byte) error { return err } definedFields := map[string]interface{}{} - err = json.Unmarshal(rawDefinedFields, &definedFields) - if err != nil { + if err := json.Unmarshal(rawDefinedFields, &definedFields); err != nil { return err } - err = json.Unmarshal(data, &v.AdditionalFields) - if err != nil { + if err := json.Unmarshal(data, &v.AdditionalFields); err != nil { return err } for key, val := range v.AdditionalFields { - _, defined := definedFields[key] - if defined || val == nil { + if _, ok := definedFields[key]; ok || val == nil { delete(v.AdditionalFields, key) } } @@ -114,17 +110,15 @@ func (a *AuditEntry) MarshalJSON() ([]byte, error) { return defBytes, err } resMap := map[string]interface{}{} - err = json.Unmarshal(defBytes, &resMap) - if err != nil { + if err := json.Unmarshal(defBytes, &resMap); err != nil { return nil, err } for key, val := range a.AdditionalFields { if val == nil { continue } - _, defined := resMap[key] - if defined { - return nil, fmt.Errorf("unexpected field in AdditionalFields: %s", key) + if _, ok := resMap[key]; ok { + return nil, fmt.Errorf("unexpected field in AdditionalFields: %v", key) } resMap[key] = val } From 3e58e366cb6d769794959cbe2f6a88976c584a67 Mon Sep 17 00:00:00 2001 From: Peter Aglen <86360391+peter-aglen@users.noreply.github.com> Date: Fri, 8 Dec 2023 14:36:23 +0100 Subject: [PATCH 04/13] Fix broken CreateOrUpdateRepoCustomPropertyValues (#3023) Fixes: #3021. --- github/orgs_properties.go | 6 +++--- github/orgs_properties_test.go | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/github/orgs_properties.go b/github/orgs_properties.go index 45e3f1f964d..2e88b7f4f98 100644 --- a/github/orgs_properties.go +++ b/github/orgs_properties.go @@ -178,12 +178,12 @@ func (s *OrganizationsService) ListCustomPropertyValues(ctx context.Context, org // GitHub API docs: https://docs.github.com/rest/orgs/custom-properties#create-or-update-custom-property-values-for-organization-repositories // //meta:operation PATCH /orgs/{org}/properties/values -func (s *OrganizationsService) CreateOrUpdateRepoCustomPropertyValues(ctx context.Context, org string, repoNames []string, properties []*CustomProperty) (*Response, error) { +func (s *OrganizationsService) CreateOrUpdateRepoCustomPropertyValues(ctx context.Context, org string, repoNames []string, properties []*CustomPropertyValue) (*Response, error) { u := fmt.Sprintf("orgs/%v/properties/values", org) params := struct { - RepositoryNames []string `json:"repository_names"` - Properties []*CustomProperty `json:"properties"` + RepositoryNames []string `json:"repository_names"` + Properties []*CustomPropertyValue `json:"properties"` }{ RepositoryNames: repoNames, Properties: properties, diff --git a/github/orgs_properties_test.go b/github/orgs_properties_test.go index 1a372306046..86daedb3a5b 100644 --- a/github/orgs_properties_test.go +++ b/github/orgs_properties_test.go @@ -347,14 +347,14 @@ func TestOrganizationsService_CreateOrUpdateRepoCustomPropertyValues(t *testing. mux.HandleFunc("/orgs/o/properties/values", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "PATCH") - testBody(t, r, `{"repository_names":["repo"],"properties":[{"property_name":"service","value_type":"string"}]}`+"\n") + testBody(t, r, `{"repository_names":["repo"],"properties":[{"property_name":"service","value":"string"}]}`+"\n") }) ctx := context.Background() - _, err := client.Organizations.CreateOrUpdateRepoCustomPropertyValues(ctx, "o", []string{"repo"}, []*CustomProperty{ + _, err := client.Organizations.CreateOrUpdateRepoCustomPropertyValues(ctx, "o", []string{"repo"}, []*CustomPropertyValue{ { - PropertyName: String("service"), - ValueType: "string", + PropertyName: "service", + Value: String("string"), }, }) if err != nil { From 23328758b6dfeaca184fca63a691601c60ebec80 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Dec 2023 14:28:57 -0500 Subject: [PATCH 05/13] Bump actions/setup-go from 4 to 5 (#3027) --- .github/workflows/linter.yml | 2 +- .github/workflows/tests.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index f9d6d7e4639..24f3d909db4 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: go-version: 1.x cache-dependency-path: "**/go.sum" diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index b3abd8b6f92..3067b1b0bec 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -39,7 +39,7 @@ jobs: runs-on: ${{ matrix.platform }} steps: - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: go-version: ${{ matrix.go-version }} - uses: actions/checkout@v4 From 0c16a61c6fb74bf806d11596b9b2cc2679879e1b Mon Sep 17 00:00:00 2001 From: Tomasz Adam Skrzypczak Date: Thu, 14 Dec 2023 09:14:41 -0500 Subject: [PATCH 06/13] Add scanning validity checks (#3026) Fixes: #3006. --- .../enterprise_code_security_and_analysis.go | 1 + ...erprise_code_security_and_analysis_test.go | 5 ++- github/github-accessors.go | 32 ++++++++++++++++ github/github-accessors_test.go | 37 +++++++++++++++++++ github/github-stringify_test.go | 20 +++++----- github/orgs.go | 2 + github/repos.go | 8 ++++ github/repos_test.go | 4 +- 8 files changed, 97 insertions(+), 12 deletions(-) diff --git a/github/enterprise_code_security_and_analysis.go b/github/enterprise_code_security_and_analysis.go index af8eb0ffb2f..159aeae4dca 100644 --- a/github/enterprise_code_security_and_analysis.go +++ b/github/enterprise_code_security_and_analysis.go @@ -16,6 +16,7 @@ type EnterpriseSecurityAnalysisSettings struct { 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"` + SecretScanningValidityChecksEnabled *bool `json:"secret_scanning_validity_checks_enabled,omitempty"` } // GetCodeSecurityAndAnalysis gets code security and analysis features for an enterprise. diff --git a/github/enterprise_code_security_and_analysis_test.go b/github/enterprise_code_security_and_analysis_test.go index 25dbd941702..17bbe18beae 100644 --- a/github/enterprise_code_security_and_analysis_test.go +++ b/github/enterprise_code_security_and_analysis_test.go @@ -27,7 +27,8 @@ func TestEnterpriseService_GetCodeSecurityAndAnalysis(t *testing.T) { "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" + "secret_scanning_push_protection_custom_link": "https://github.com/test-org/test-repo/blob/main/README.md", + "secret_scanning_validity_checks_enabled": true }`) }) @@ -44,6 +45,7 @@ func TestEnterpriseService_GetCodeSecurityAndAnalysis(t *testing.T) { SecretScanningEnabledForNewRepositories: Bool(true), SecretScanningPushProtectionEnabledForNewRepositories: Bool(true), SecretScanningPushProtectionCustomLink: String("https://github.com/test-org/test-repo/blob/main/README.md"), + SecretScanningValidityChecksEnabled: Bool(true), } if !cmp.Equal(settings, want) { @@ -73,6 +75,7 @@ func TestEnterpriseService_UpdateCodeSecurityAndAnalysis(t *testing.T) { SecretScanningEnabledForNewRepositories: Bool(true), SecretScanningPushProtectionEnabledForNewRepositories: Bool(true), SecretScanningPushProtectionCustomLink: String("https://github.com/test-org/test-repo/blob/main/README.md"), + SecretScanningValidityChecksEnabled: Bool(true), } mux.HandleFunc("/enterprises/e/code_security_and_analysis", func(w http.ResponseWriter, r *http.Request) { diff --git a/github/github-accessors.go b/github/github-accessors.go index f32865c14ab..c90ee88d8ce 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -6502,6 +6502,14 @@ func (e *EnterpriseSecurityAnalysisSettings) GetSecretScanningPushProtectionEnab return *e.SecretScanningPushProtectionEnabledForNewRepositories } +// GetSecretScanningValidityChecksEnabled returns the SecretScanningValidityChecksEnabled field if it's non-nil, zero value otherwise. +func (e *EnterpriseSecurityAnalysisSettings) GetSecretScanningValidityChecksEnabled() bool { + if e == nil || e.SecretScanningValidityChecksEnabled == nil { + return false + } + return *e.SecretScanningValidityChecksEnabled +} + // GetCanAdminsBypass returns the CanAdminsBypass field if it's non-nil, zero value otherwise. func (e *Environment) GetCanAdminsBypass() bool { if e == nil || e.CanAdminsBypass == nil { @@ -12262,6 +12270,14 @@ func (o *Organization) GetSecretScanningPushProtectionEnabledForNewRepos() bool return *o.SecretScanningPushProtectionEnabledForNewRepos } +// GetSecretScanningValidityChecksEnabled returns the SecretScanningValidityChecksEnabled field if it's non-nil, zero value otherwise. +func (o *Organization) GetSecretScanningValidityChecksEnabled() bool { + if o == nil || o.SecretScanningValidityChecksEnabled == nil { + return false + } + return *o.SecretScanningValidityChecksEnabled +} + // GetTotalPrivateRepos returns the TotalPrivateRepos field if it's non-nil, zero value otherwise. func (o *Organization) GetTotalPrivateRepos() int64 { if o == nil || o.TotalPrivateRepos == nil { @@ -21102,6 +21118,14 @@ func (s *SecretScanningPushProtection) GetStatus() string { return *s.Status } +// GetStatus returns the Status field if it's non-nil, zero value otherwise. +func (s *SecretScanningValidityChecks) GetStatus() string { + if s == nil || s.Status == nil { + return "" + } + return *s.Status +} + // GetAuthor returns the Author field. func (s *SecurityAdvisory) GetAuthor() *User { if s == nil { @@ -21342,6 +21366,14 @@ func (s *SecurityAndAnalysis) GetSecretScanningPushProtection() *SecretScanningP return s.SecretScanningPushProtection } +// GetSecretScanningValidityChecks returns the SecretScanningValidityChecks field. +func (s *SecurityAndAnalysis) GetSecretScanningValidityChecks() *SecretScanningValidityChecks { + if s == nil { + return nil + } + return s.SecretScanningValidityChecks +} + // GetFrom returns the From field. func (s *SecurityAndAnalysisChange) GetFrom() *SecurityAndAnalysisChangeFrom { if s == nil { diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index 2e8f9bacb43..19c7f381c25 100644 --- a/github/github-accessors_test.go +++ b/github/github-accessors_test.go @@ -7594,6 +7594,16 @@ func TestEnterpriseSecurityAnalysisSettings_GetSecretScanningPushProtectionEnabl e.GetSecretScanningPushProtectionEnabledForNewRepositories() } +func TestEnterpriseSecurityAnalysisSettings_GetSecretScanningValidityChecksEnabled(tt *testing.T) { + var zeroValue bool + e := &EnterpriseSecurityAnalysisSettings{SecretScanningValidityChecksEnabled: &zeroValue} + e.GetSecretScanningValidityChecksEnabled() + e = &EnterpriseSecurityAnalysisSettings{} + e.GetSecretScanningValidityChecksEnabled() + e = nil + e.GetSecretScanningValidityChecksEnabled() +} + func TestEnvironment_GetCanAdminsBypass(tt *testing.T) { var zeroValue bool e := &Environment{CanAdminsBypass: &zeroValue} @@ -14347,6 +14357,16 @@ func TestOrganization_GetSecretScanningPushProtectionEnabledForNewRepos(tt *test o.GetSecretScanningPushProtectionEnabledForNewRepos() } +func TestOrganization_GetSecretScanningValidityChecksEnabled(tt *testing.T) { + var zeroValue bool + o := &Organization{SecretScanningValidityChecksEnabled: &zeroValue} + o.GetSecretScanningValidityChecksEnabled() + o = &Organization{} + o.GetSecretScanningValidityChecksEnabled() + o = nil + o.GetSecretScanningValidityChecksEnabled() +} + func TestOrganization_GetTotalPrivateRepos(tt *testing.T) { var zeroValue int64 o := &Organization{TotalPrivateRepos: &zeroValue} @@ -24548,6 +24568,16 @@ func TestSecretScanningPushProtection_GetStatus(tt *testing.T) { s.GetStatus() } +func TestSecretScanningValidityChecks_GetStatus(tt *testing.T) { + var zeroValue string + s := &SecretScanningValidityChecks{Status: &zeroValue} + s.GetStatus() + s = &SecretScanningValidityChecks{} + s.GetStatus() + s = nil + s.GetStatus() +} + func TestSecurityAdvisory_GetAuthor(tt *testing.T) { s := &SecurityAdvisory{} s.GetAuthor() @@ -24803,6 +24833,13 @@ func TestSecurityAndAnalysis_GetSecretScanningPushProtection(tt *testing.T) { s.GetSecretScanningPushProtection() } +func TestSecurityAndAnalysis_GetSecretScanningValidityChecks(tt *testing.T) { + s := &SecurityAndAnalysis{} + s.GetSecretScanningValidityChecks() + s = nil + s.GetSecretScanningValidityChecks() +} + func TestSecurityAndAnalysisChange_GetFrom(tt *testing.T) { s := &SecurityAndAnalysisChange{} s.GetFrom() diff --git a/github/github-stringify_test.go b/github/github-stringify_test.go index 7472edfd59a..bb69ce1ad5a 100644 --- a/github/github-stringify_test.go +++ b/github/github-stringify_test.go @@ -1051,15 +1051,16 @@ func TestOrganization_String(t *testing.T) { DependencyGraphEnabledForNewRepos: Bool(false), SecretScanningEnabledForNewRepos: Bool(false), SecretScanningPushProtectionEnabledForNewRepos: Bool(false), - URL: String(""), - EventsURL: String(""), - HooksURL: String(""), - IssuesURL: String(""), - MembersURL: String(""), - PublicMembersURL: String(""), - ReposURL: String(""), + SecretScanningValidityChecksEnabled: Bool(false), + URL: String(""), + EventsURL: String(""), + HooksURL: String(""), + IssuesURL: String(""), + MembersURL: String(""), + PublicMembersURL: String(""), + ReposURL: String(""), } - want := `github.Organization{Login:"", ID:0, NodeID:"", AvatarURL:"", HTMLURL:"", Name:"", Company:"", Blog:"", Location:"", Email:"", TwitterUsername:"", Description:"", PublicRepos:0, PublicGists:0, Followers:0, Following:0, CreatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, UpdatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, TotalPrivateRepos:0, OwnedPrivateRepos:0, PrivateGists:0, DiskUsage:0, Collaborators:0, BillingEmail:"", Type:"", Plan:github.Plan{}, TwoFactorRequirementEnabled:false, IsVerified:false, HasOrganizationProjects:false, HasRepositoryProjects:false, DefaultRepoPermission:"", DefaultRepoSettings:"", MembersCanCreateRepos:false, MembersCanCreatePublicRepos:false, MembersCanCreatePrivateRepos:false, MembersCanCreateInternalRepos:false, MembersCanForkPrivateRepos:false, MembersAllowedRepositoryCreationType:"", MembersCanCreatePages:false, MembersCanCreatePublicPages:false, MembersCanCreatePrivatePages:false, WebCommitSignoffRequired:false, AdvancedSecurityEnabledForNewRepos:false, DependabotAlertsEnabledForNewRepos:false, DependabotSecurityUpdatesEnabledForNewRepos:false, DependencyGraphEnabledForNewRepos:false, SecretScanningEnabledForNewRepos:false, SecretScanningPushProtectionEnabledForNewRepos:false, URL:"", EventsURL:"", HooksURL:"", IssuesURL:"", MembersURL:"", PublicMembersURL:"", ReposURL:""}` + want := `github.Organization{Login:"", ID:0, NodeID:"", AvatarURL:"", HTMLURL:"", Name:"", Company:"", Blog:"", Location:"", Email:"", TwitterUsername:"", Description:"", PublicRepos:0, PublicGists:0, Followers:0, Following:0, CreatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, UpdatedAt:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}, TotalPrivateRepos:0, OwnedPrivateRepos:0, PrivateGists:0, DiskUsage:0, Collaborators:0, BillingEmail:"", Type:"", Plan:github.Plan{}, TwoFactorRequirementEnabled:false, IsVerified:false, HasOrganizationProjects:false, HasRepositoryProjects:false, DefaultRepoPermission:"", DefaultRepoSettings:"", MembersCanCreateRepos:false, MembersCanCreatePublicRepos:false, MembersCanCreatePrivateRepos:false, MembersCanCreateInternalRepos:false, MembersCanForkPrivateRepos:false, MembersAllowedRepositoryCreationType:"", MembersCanCreatePages:false, MembersCanCreatePublicPages:false, MembersCanCreatePrivatePages:false, WebCommitSignoffRequired:false, AdvancedSecurityEnabledForNewRepos:false, DependabotAlertsEnabledForNewRepos:false, DependabotSecurityUpdatesEnabledForNewRepos:false, DependencyGraphEnabledForNewRepos:false, SecretScanningEnabledForNewRepos:false, SecretScanningPushProtectionEnabledForNewRepos:false, SecretScanningValidityChecksEnabled:false, URL:"", EventsURL:"", HooksURL:"", IssuesURL:"", MembersURL:"", PublicMembersURL:"", ReposURL:""}` if got := v.String(); got != want { t.Errorf("Organization.String = %v, want %v", got, want) } @@ -1826,8 +1827,9 @@ func TestSecurityAndAnalysis_String(t *testing.T) { SecretScanning: &SecretScanning{}, SecretScanningPushProtection: &SecretScanningPushProtection{}, DependabotSecurityUpdates: &DependabotSecurityUpdates{}, + SecretScanningValidityChecks: &SecretScanningValidityChecks{}, } - want := `github.SecurityAndAnalysis{AdvancedSecurity:github.AdvancedSecurity{}, SecretScanning:github.SecretScanning{}, SecretScanningPushProtection:github.SecretScanningPushProtection{}, DependabotSecurityUpdates:github.DependabotSecurityUpdates{}}` + want := `github.SecurityAndAnalysis{AdvancedSecurity:github.AdvancedSecurity{}, SecretScanning:github.SecretScanning{}, SecretScanningPushProtection:github.SecretScanningPushProtection{}, DependabotSecurityUpdates:github.DependabotSecurityUpdates{}, SecretScanningValidityChecks:github.SecretScanningValidityChecks{}}` if got := v.String(); got != want { t.Errorf("SecurityAndAnalysis.String = %v, want %v", got, want) } diff --git a/github/orgs.go b/github/orgs.go index 4d3465271b6..27c0f102842 100644 --- a/github/orgs.go +++ b/github/orgs.go @@ -95,6 +95,8 @@ type Organization struct { SecretScanningEnabledForNewRepos *bool `json:"secret_scanning_enabled_for_new_repositories,omitempty"` // SecretScanningPushProtectionEnabledForNewRepos toggles whether secret scanning push protection is enabled on new repositories. SecretScanningPushProtectionEnabledForNewRepos *bool `json:"secret_scanning_push_protection_enabled_for_new_repositories,omitempty"` + // SecretScanningValidityChecksEnabled toggles whether secret scanning validity check is enabled. + SecretScanningValidityChecksEnabled *bool `json:"secret_scanning_validity_checks_enabled,omitempty"` // API URLs URL *string `json:"url,omitempty"` diff --git a/github/repos.go b/github/repos.go index 5fcf219b3cf..a7574d72f07 100644 --- a/github/repos.go +++ b/github/repos.go @@ -198,6 +198,7 @@ type SecurityAndAnalysis struct { SecretScanning *SecretScanning `json:"secret_scanning,omitempty"` SecretScanningPushProtection *SecretScanningPushProtection `json:"secret_scanning_push_protection,omitempty"` DependabotSecurityUpdates *DependabotSecurityUpdates `json:"dependabot_security_updates,omitempty"` + SecretScanningValidityChecks *SecretScanningValidityChecks `json:"secret_scanning_validity_checks,omitempty"` } func (s SecurityAndAnalysis) String() string { @@ -248,6 +249,13 @@ func (d DependabotSecurityUpdates) String() string { return Stringify(d) } +// SecretScanningValidityChecks represents the state of secret scanning validity checks on a repository. +// +// GitHub API docs: https://docs.github.com/en/enterprise-cloud@latest/repositories/managing-your-repositorys-settings-and-features/enabling-features-for-your-repository/managing-security-and-analysis-settings-for-your-repository#allowing-validity-checks-for-partner-patterns-in-a-repository +type SecretScanningValidityChecks struct { + Status *string `json:"status,omitempty"` +} + // List calls either RepositoriesService.ListByUser or RepositoriesService.ListByAuthenticatedUser // depending on whether user is empty. // diff --git a/github/repos_test.go b/github/repos_test.go index fa49ddd4f5c..2e61aeb1b1f 100644 --- a/github/repos_test.go +++ b/github/repos_test.go @@ -360,7 +360,7 @@ func TestRepositoriesService_Get(t *testing.T) { mux.HandleFunc("/repos/o/r", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") testHeader(t, r, "Accept", strings.Join(wantAcceptHeaders, ", ")) - fmt.Fprint(w, `{"id":1,"name":"n","description":"d","owner":{"login":"l"},"license":{"key":"mit"},"security_and_analysis":{"advanced_security":{"status":"enabled"},"secret_scanning":{"status":"enabled"},"secret_scanning_push_protection":{"status":"enabled"},"dependabot_security_updates":{"status": "enabled"}}}`) + fmt.Fprint(w, `{"id":1,"name":"n","description":"d","owner":{"login":"l"},"license":{"key":"mit"},"security_and_analysis":{"advanced_security":{"status":"enabled"},"secret_scanning":{"status":"enabled"},"secret_scanning_push_protection":{"status":"enabled"},"dependabot_security_updates":{"status": "enabled"}, "secret_scanning_validity_checks":{"status":"enabled"}}}`) }) ctx := context.Background() @@ -369,7 +369,7 @@ func TestRepositoriesService_Get(t *testing.T) { t.Errorf("Repositories.Get returned error: %v", err) } - want := &Repository{ID: Int64(1), Name: String("n"), Description: String("d"), Owner: &User{Login: String("l")}, License: &License{Key: String("mit")}, SecurityAndAnalysis: &SecurityAndAnalysis{AdvancedSecurity: &AdvancedSecurity{Status: String("enabled")}, SecretScanning: &SecretScanning{String("enabled")}, SecretScanningPushProtection: &SecretScanningPushProtection{String("enabled")}, DependabotSecurityUpdates: &DependabotSecurityUpdates{String("enabled")}}} + want := &Repository{ID: Int64(1), Name: String("n"), Description: String("d"), Owner: &User{Login: String("l")}, License: &License{Key: String("mit")}, SecurityAndAnalysis: &SecurityAndAnalysis{AdvancedSecurity: &AdvancedSecurity{Status: String("enabled")}, SecretScanning: &SecretScanning{String("enabled")}, SecretScanningPushProtection: &SecretScanningPushProtection{String("enabled")}, DependabotSecurityUpdates: &DependabotSecurityUpdates{String("enabled")}, SecretScanningValidityChecks: &SecretScanningValidityChecks{String("enabled")}}} if !cmp.Equal(got, want) { t.Errorf("Repositories.Get returned %+v, want %+v", got, want) } From bf8d5d554c1b8e3b4a29a93fa0029afdf0835572 Mon Sep 17 00:00:00 2001 From: Khanh Ngo Date: Fri, 15 Dec 2023 18:55:20 +0100 Subject: [PATCH 07/13] Add Referrer field to AuditEntry (#3032) Fixes: #3031. --- github/github-accessors.go | 179 +++++++++++++++++++++++++ github/github-accessors_test.go | 223 ++++++++++++++++++++++++++++++++ github/orgs_audit_log.go | 84 ++++++++++++ 3 files changed, 486 insertions(+) diff --git a/github/github-accessors.go b/github/github-accessors.go index c90ee88d8ce..289fff8ad49 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -1166,6 +1166,185 @@ func (a *AuditEntry) GetOrgID() int64 { return *a.OrgID } +<<<<<<< HEAD +======= +// GetPermission returns the Permission field if it's non-nil, zero value otherwise. +func (a *AuditEntry) GetPermission() string { + if a == nil || a.Permission == nil { + return "" + } + return *a.Permission +} + +// GetPreviousVisibility returns the PreviousVisibility field if it's non-nil, zero value otherwise. +func (a *AuditEntry) GetPreviousVisibility() string { + if a == nil || a.PreviousVisibility == nil { + return "" + } + return *a.PreviousVisibility +} + +// GetProgrammaticAccessType returns the ProgrammaticAccessType field if it's non-nil, zero value otherwise. +func (a *AuditEntry) GetProgrammaticAccessType() string { + if a == nil || a.ProgrammaticAccessType == nil { + return "" + } + return *a.ProgrammaticAccessType +} + +// GetPullRequestID returns the PullRequestID field if it's non-nil, zero value otherwise. +func (a *AuditEntry) GetPullRequestID() int64 { + if a == nil || a.PullRequestID == nil { + return 0 + } + return *a.PullRequestID +} + +// GetPullRequestTitle returns the PullRequestTitle field if it's non-nil, zero value otherwise. +func (a *AuditEntry) GetPullRequestTitle() string { + if a == nil || a.PullRequestTitle == nil { + return "" + } + return *a.PullRequestTitle +} + +// GetPullRequestURL returns the PullRequestURL field if it's non-nil, zero value otherwise. +func (a *AuditEntry) GetPullRequestURL() string { + if a == nil || a.PullRequestURL == nil { + return "" + } + return *a.PullRequestURL +} + +// GetReadOnly returns the ReadOnly field if it's non-nil, zero value otherwise. +func (a *AuditEntry) GetReadOnly() string { + if a == nil || a.ReadOnly == nil { + return "" + } + return *a.ReadOnly +} + +// GetReferrer returns the Referrer field if it's non-nil, zero value otherwise. +func (a *AuditEntry) GetReferrer() string { + if a == nil || a.Referrer == nil { + return "" + } + return *a.Referrer +} + +// GetRepo returns the Repo field if it's non-nil, zero value otherwise. +func (a *AuditEntry) GetRepo() string { + if a == nil || a.Repo == nil { + return "" + } + return *a.Repo +} + +// GetRepository returns the Repository field if it's non-nil, zero value otherwise. +func (a *AuditEntry) GetRepository() string { + if a == nil || a.Repository == nil { + return "" + } + return *a.Repository +} + +// GetRepositoryPublic returns the RepositoryPublic field if it's non-nil, zero value otherwise. +func (a *AuditEntry) GetRepositoryPublic() bool { + if a == nil || a.RepositoryPublic == nil { + return false + } + return *a.RepositoryPublic +} + +// GetRunAttempt returns the RunAttempt field if it's non-nil, zero value otherwise. +func (a *AuditEntry) GetRunAttempt() int64 { + if a == nil || a.RunAttempt == nil { + return 0 + } + return *a.RunAttempt +} + +// GetRunnerGroupID returns the RunnerGroupID field if it's non-nil, zero value otherwise. +func (a *AuditEntry) GetRunnerGroupID() int64 { + if a == nil || a.RunnerGroupID == nil { + return 0 + } + return *a.RunnerGroupID +} + +// GetRunnerGroupName returns the RunnerGroupName field if it's non-nil, zero value otherwise. +func (a *AuditEntry) GetRunnerGroupName() string { + if a == nil || a.RunnerGroupName == nil { + return "" + } + return *a.RunnerGroupName +} + +// GetRunnerID returns the RunnerID field if it's non-nil, zero value otherwise. +func (a *AuditEntry) GetRunnerID() int64 { + if a == nil || a.RunnerID == nil { + return 0 + } + return *a.RunnerID +} + +// GetRunnerName returns the RunnerName field if it's non-nil, zero value otherwise. +func (a *AuditEntry) GetRunnerName() string { + if a == nil || a.RunnerName == nil { + return "" + } + return *a.RunnerName +} + +// GetRunNumber returns the RunNumber field if it's non-nil, zero value otherwise. +func (a *AuditEntry) GetRunNumber() int64 { + if a == nil || a.RunNumber == nil { + return 0 + } + return *a.RunNumber +} + +// GetSourceVersion returns the SourceVersion field if it's non-nil, zero value otherwise. +func (a *AuditEntry) GetSourceVersion() string { + if a == nil || a.SourceVersion == nil { + return "" + } + return *a.SourceVersion +} + +// GetStartedAt returns the StartedAt field if it's non-nil, zero value otherwise. +func (a *AuditEntry) GetStartedAt() Timestamp { + if a == nil || a.StartedAt == nil { + return Timestamp{} + } + return *a.StartedAt +} + +// GetTargetLogin returns the TargetLogin field if it's non-nil, zero value otherwise. +func (a *AuditEntry) GetTargetLogin() string { + if a == nil || a.TargetLogin == nil { + return "" + } + return *a.TargetLogin +} + +// GetTargetVersion returns the TargetVersion field if it's non-nil, zero value otherwise. +func (a *AuditEntry) GetTargetVersion() string { + if a == nil || a.TargetVersion == nil { + return "" + } + return *a.TargetVersion +} + +// GetTeam returns the Team field if it's non-nil, zero value otherwise. +func (a *AuditEntry) GetTeam() string { + if a == nil || a.Team == nil { + return "" + } + return *a.Team +} + +>>>>>>> d47936f (Add Referrer field to AuditEntry (#3032)) // GetTimestamp returns the Timestamp field if it's non-nil, zero value otherwise. func (a *AuditEntry) GetTimestamp() Timestamp { if a == nil || a.Timestamp == nil { diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index 19c7f381c25..e4e56bb761a 100644 --- a/github/github-accessors_test.go +++ b/github/github-accessors_test.go @@ -1380,6 +1380,229 @@ func TestAuditEntry_GetOrgID(tt *testing.T) { a.GetOrgID() } +<<<<<<< HEAD +======= +func TestAuditEntry_GetPermission(tt *testing.T) { + var zeroValue string + a := &AuditEntry{Permission: &zeroValue} + a.GetPermission() + a = &AuditEntry{} + a.GetPermission() + a = nil + a.GetPermission() +} + +func TestAuditEntry_GetPreviousVisibility(tt *testing.T) { + var zeroValue string + a := &AuditEntry{PreviousVisibility: &zeroValue} + a.GetPreviousVisibility() + a = &AuditEntry{} + a.GetPreviousVisibility() + a = nil + a.GetPreviousVisibility() +} + +func TestAuditEntry_GetProgrammaticAccessType(tt *testing.T) { + var zeroValue string + a := &AuditEntry{ProgrammaticAccessType: &zeroValue} + a.GetProgrammaticAccessType() + a = &AuditEntry{} + a.GetProgrammaticAccessType() + a = nil + a.GetProgrammaticAccessType() +} + +func TestAuditEntry_GetPullRequestID(tt *testing.T) { + var zeroValue int64 + a := &AuditEntry{PullRequestID: &zeroValue} + a.GetPullRequestID() + a = &AuditEntry{} + a.GetPullRequestID() + a = nil + a.GetPullRequestID() +} + +func TestAuditEntry_GetPullRequestTitle(tt *testing.T) { + var zeroValue string + a := &AuditEntry{PullRequestTitle: &zeroValue} + a.GetPullRequestTitle() + a = &AuditEntry{} + a.GetPullRequestTitle() + a = nil + a.GetPullRequestTitle() +} + +func TestAuditEntry_GetPullRequestURL(tt *testing.T) { + var zeroValue string + a := &AuditEntry{PullRequestURL: &zeroValue} + a.GetPullRequestURL() + a = &AuditEntry{} + a.GetPullRequestURL() + a = nil + a.GetPullRequestURL() +} + +func TestAuditEntry_GetReadOnly(tt *testing.T) { + var zeroValue string + a := &AuditEntry{ReadOnly: &zeroValue} + a.GetReadOnly() + a = &AuditEntry{} + a.GetReadOnly() + a = nil + a.GetReadOnly() +} + +func TestAuditEntry_GetReferrer(tt *testing.T) { + var zeroValue string + a := &AuditEntry{Referrer: &zeroValue} + a.GetReferrer() + a = &AuditEntry{} + a.GetReferrer() + a = nil + a.GetReferrer() +} + +func TestAuditEntry_GetRepo(tt *testing.T) { + var zeroValue string + a := &AuditEntry{Repo: &zeroValue} + a.GetRepo() + a = &AuditEntry{} + a.GetRepo() + a = nil + a.GetRepo() +} + +func TestAuditEntry_GetRepository(tt *testing.T) { + var zeroValue string + a := &AuditEntry{Repository: &zeroValue} + a.GetRepository() + a = &AuditEntry{} + a.GetRepository() + a = nil + a.GetRepository() +} + +func TestAuditEntry_GetRepositoryPublic(tt *testing.T) { + var zeroValue bool + a := &AuditEntry{RepositoryPublic: &zeroValue} + a.GetRepositoryPublic() + a = &AuditEntry{} + a.GetRepositoryPublic() + a = nil + a.GetRepositoryPublic() +} + +func TestAuditEntry_GetRunAttempt(tt *testing.T) { + var zeroValue int64 + a := &AuditEntry{RunAttempt: &zeroValue} + a.GetRunAttempt() + a = &AuditEntry{} + a.GetRunAttempt() + a = nil + a.GetRunAttempt() +} + +func TestAuditEntry_GetRunnerGroupID(tt *testing.T) { + var zeroValue int64 + a := &AuditEntry{RunnerGroupID: &zeroValue} + a.GetRunnerGroupID() + a = &AuditEntry{} + a.GetRunnerGroupID() + a = nil + a.GetRunnerGroupID() +} + +func TestAuditEntry_GetRunnerGroupName(tt *testing.T) { + var zeroValue string + a := &AuditEntry{RunnerGroupName: &zeroValue} + a.GetRunnerGroupName() + a = &AuditEntry{} + a.GetRunnerGroupName() + a = nil + a.GetRunnerGroupName() +} + +func TestAuditEntry_GetRunnerID(tt *testing.T) { + var zeroValue int64 + a := &AuditEntry{RunnerID: &zeroValue} + a.GetRunnerID() + a = &AuditEntry{} + a.GetRunnerID() + a = nil + a.GetRunnerID() +} + +func TestAuditEntry_GetRunnerName(tt *testing.T) { + var zeroValue string + a := &AuditEntry{RunnerName: &zeroValue} + a.GetRunnerName() + a = &AuditEntry{} + a.GetRunnerName() + a = nil + a.GetRunnerName() +} + +func TestAuditEntry_GetRunNumber(tt *testing.T) { + var zeroValue int64 + a := &AuditEntry{RunNumber: &zeroValue} + a.GetRunNumber() + a = &AuditEntry{} + a.GetRunNumber() + a = nil + a.GetRunNumber() +} + +func TestAuditEntry_GetSourceVersion(tt *testing.T) { + var zeroValue string + a := &AuditEntry{SourceVersion: &zeroValue} + a.GetSourceVersion() + a = &AuditEntry{} + a.GetSourceVersion() + a = nil + a.GetSourceVersion() +} + +func TestAuditEntry_GetStartedAt(tt *testing.T) { + var zeroValue Timestamp + a := &AuditEntry{StartedAt: &zeroValue} + a.GetStartedAt() + a = &AuditEntry{} + a.GetStartedAt() + a = nil + a.GetStartedAt() +} + +func TestAuditEntry_GetTargetLogin(tt *testing.T) { + var zeroValue string + a := &AuditEntry{TargetLogin: &zeroValue} + a.GetTargetLogin() + a = &AuditEntry{} + a.GetTargetLogin() + a = nil + a.GetTargetLogin() +} + +func TestAuditEntry_GetTargetVersion(tt *testing.T) { + var zeroValue string + a := &AuditEntry{TargetVersion: &zeroValue} + a.GetTargetVersion() + a = &AuditEntry{} + a.GetTargetVersion() + a = nil + a.GetTargetVersion() +} + +func TestAuditEntry_GetTeam(tt *testing.T) { + var zeroValue string + a := &AuditEntry{Team: &zeroValue} + a.GetTeam() + a = &AuditEntry{} + a.GetTeam() + a = nil + a.GetTeam() +} + +>>>>>>> d47936f (Add Referrer field to AuditEntry (#3032)) func TestAuditEntry_GetTimestamp(tt *testing.T) { var zeroValue Timestamp a := &AuditEntry{Timestamp: &zeroValue} diff --git a/github/orgs_audit_log.go b/github/orgs_audit_log.go index 28ac079bb3b..78761faf24f 100644 --- a/github/orgs_audit_log.go +++ b/github/orgs_audit_log.go @@ -40,6 +40,7 @@ type ActorLocation struct { // in AdditionalFields. // For a list of actions see - https://docs.github.com/github/setting-up-and-managing-organizations-and-teams/reviewing-the-audit-log-for-your-organization#audit-log-actions type AuditEntry struct { +<<<<<<< HEAD Action *string `json:"action,omitempty"` // The name of the action that was performed, for example `user.login` or `repo.create`. Actor *string `json:"actor,omitempty"` // The actor who performed the action. ActorID *int64 `json:"actor_id,omitempty"` @@ -58,6 +59,89 @@ type AuditEntry struct { TokenScopes *string `json:"token_scopes,omitempty"` User *string `json:"user,omitempty"` // The user that was affected by the action performed (if available). UserID *int64 `json:"user_id,omitempty"` +======= + ActorIP *string `json:"actor_ip,omitempty"` + Action *string `json:"action,omitempty"` // The name of the action that was performed, for example `user.login` or `repo.create`. + Active *bool `json:"active,omitempty"` + ActiveWas *bool `json:"active_was,omitempty"` + Actor *string `json:"actor,omitempty"` // The actor who performed the action. + ActorLocation *ActorLocation `json:"actor_location,omitempty"` + BlockedUser *string `json:"blocked_user,omitempty"` + Business *string `json:"business,omitempty"` + CancelledAt *Timestamp `json:"cancelled_at,omitempty"` + CompletedAt *Timestamp `json:"completed_at,omitempty"` + Conclusion *string `json:"conclusion,omitempty"` + Config *HookConfig `json:"config,omitempty"` + ConfigWas *HookConfig `json:"config_was,omitempty"` + ContentType *string `json:"content_type,omitempty"` + CreatedAt *Timestamp `json:"created_at,omitempty"` + DeployKeyFingerprint *string `json:"deploy_key_fingerprint,omitempty"` + DocumentID *string `json:"_document_id,omitempty"` + Emoji *string `json:"emoji,omitempty"` + EnvironmentName *string `json:"environment_name,omitempty"` + Event *string `json:"event,omitempty"` + Events []string `json:"events,omitempty"` + EventsWere []string `json:"events_were,omitempty"` + Explanation *string `json:"explanation,omitempty"` + ExternalIdentityNameID *string `json:"external_identity_nameid,omitempty"` + ExternalIdentityUsername *string `json:"external_identity_username,omitempty"` + Fingerprint *string `json:"fingerprint,omitempty"` + HashedToken *string `json:"hashed_token,omitempty"` + HeadBranch *string `json:"head_branch,omitempty"` + HeadSHA *string `json:"head_sha,omitempty"` + HookID *int64 `json:"hook_id,omitempty"` + IsHostedRunner *bool `json:"is_hosted_runner,omitempty"` + JobName *string `json:"job_name,omitempty"` + JobWorkflowRef *string `json:"job_workflow_ref,omitempty"` + LimitedAvailability *bool `json:"limited_availability,omitempty"` + Message *string `json:"message,omitempty"` + Name *string `json:"name,omitempty"` + OAuthApplicationID *int64 `json:"oauth_application_id,omitempty"` + OldUser *string `json:"old_user,omitempty"` + OldPermission *string `json:"old_permission,omitempty"` // The permission level for membership changes, for example `admin` or `read`. + OpenSSHPublicKey *string `json:"openssh_public_key,omitempty"` + OperationType *string `json:"operation_type,omitempty"` + Org *string `json:"org,omitempty"` + OrgID *int64 `json:"org_id,omitempty"` + OverriddenCodes []string `json:"overridden_codes,omitempty"` + Permission *string `json:"permission,omitempty"` // The permission level for membership changes, for example `admin` or `read`. + PreviousVisibility *string `json:"previous_visibility,omitempty"` + ProgrammaticAccessType *string `json:"programmatic_access_type,omitempty"` + PullRequestID *int64 `json:"pull_request_id,omitempty"` + PullRequestTitle *string `json:"pull_request_title,omitempty"` + PullRequestURL *string `json:"pull_request_url,omitempty"` + ReadOnly *string `json:"read_only,omitempty"` + Reasons []*PolicyOverrideReason `json:"reasons,omitempty"` + Referrer *string `json:"referrer,omitempty"` + Repo *string `json:"repo,omitempty"` + Repository *string `json:"repository,omitempty"` + RepositoryPublic *bool `json:"repository_public,omitempty"` + RunAttempt *int64 `json:"run_attempt,omitempty"` + RunnerGroupID *int64 `json:"runner_group_id,omitempty"` + RunnerGroupName *string `json:"runner_group_name,omitempty"` + RunnerID *int64 `json:"runner_id,omitempty"` + RunnerLabels []string `json:"runner_labels,omitempty"` + RunnerName *string `json:"runner_name,omitempty"` + RunNumber *int64 `json:"run_number,omitempty"` + SecretsPassed []string `json:"secrets_passed,omitempty"` + SourceVersion *string `json:"source_version,omitempty"` + StartedAt *Timestamp `json:"started_at,omitempty"` + TargetLogin *string `json:"target_login,omitempty"` + TargetVersion *string `json:"target_version,omitempty"` + Team *string `json:"team,omitempty"` + Timestamp *Timestamp `json:"@timestamp,omitempty"` // The time the audit log event occurred, given as a [Unix timestamp](http://en.wikipedia.org/wiki/Unix_time). + TokenID *int64 `json:"token_id,omitempty"` + TokenScopes *string `json:"token_scopes,omitempty"` + Topic *string `json:"topic,omitempty"` + TransportProtocolName *string `json:"transport_protocol_name,omitempty"` // A human readable name for the protocol (for example, HTTP or SSH) used to transfer Git data. + TransportProtocol *int `json:"transport_protocol,omitempty"` // The type of protocol (for example, HTTP=1 or SSH=2) used to transfer Git data. + TriggerID *int64 `json:"trigger_id,omitempty"` + User *string `json:"user,omitempty"` // The user that was affected by the action performed (if available). + UserAgent *string `json:"user_agent,omitempty"` + Visibility *string `json:"visibility,omitempty"` // The repository visibility, for example `public` or `private`. + WorkflowID *int64 `json:"workflow_id,omitempty"` + WorkflowRunID *int64 `json:"workflow_run_id,omitempty"` +>>>>>>> d47936f (Add Referrer field to AuditEntry (#3032)) // Some events types have a data field that contains additional information about the event. Data map[string]interface{} `json:"data,omitempty"` From d6af4c8ea90f78ec71f8a0daacf5d2f3d591adc7 Mon Sep 17 00:00:00 2001 From: Rufina Talalaeva Date: Fri, 15 Dec 2023 22:20:07 +0300 Subject: [PATCH 08/13] Add code_search and dependency_snapshots for RateLimits (#3019) Fixes: #3018. --- github/github-accessors.go | 16 ++++++++ github/github-accessors_test.go | 14 +++++++ github/github.go | 14 +++++++ github/github_test.go | 10 +++++ github/rate_limit.go | 8 ++++ github/rate_limit_test.go | 68 +++++++++++++++++++++++++++++++-- 6 files changed, 127 insertions(+), 3 deletions(-) diff --git a/github/github-accessors.go b/github/github-accessors.go index 289fff8ad49..9e8fe0448ca 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -17473,6 +17473,14 @@ func (r *RateLimits) GetCodeScanningUpload() *Rate { return r.CodeScanningUpload } +// GetCodeSearch returns the CodeSearch field. +func (r *RateLimits) GetCodeSearch() *Rate { + if r == nil { + return nil + } + return r.CodeSearch +} + // GetCore returns the Core field. func (r *RateLimits) GetCore() *Rate { if r == nil { @@ -17481,6 +17489,14 @@ func (r *RateLimits) GetCore() *Rate { return r.Core } +// GetDependencySnapshots returns the DependencySnapshots field. +func (r *RateLimits) GetDependencySnapshots() *Rate { + if r == nil { + return nil + } + return r.DependencySnapshots +} + // GetGraphQL returns the GraphQL field. func (r *RateLimits) GetGraphQL() *Rate { if r == nil { diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index e4e56bb761a..e33e713b18b 100644 --- a/github/github-accessors_test.go +++ b/github/github-accessors_test.go @@ -20248,6 +20248,13 @@ func TestRateLimits_GetCodeScanningUpload(tt *testing.T) { r.GetCodeScanningUpload() } +func TestRateLimits_GetCodeSearch(tt *testing.T) { + r := &RateLimits{} + r.GetCodeSearch() + r = nil + r.GetCodeSearch() +} + func TestRateLimits_GetCore(tt *testing.T) { r := &RateLimits{} r.GetCore() @@ -20255,6 +20262,13 @@ func TestRateLimits_GetCore(tt *testing.T) { r.GetCore() } +func TestRateLimits_GetDependencySnapshots(tt *testing.T) { + r := &RateLimits{} + r.GetDependencySnapshots() + r = nil + r.GetDependencySnapshots() +} + func TestRateLimits_GetGraphQL(tt *testing.T) { r := &RateLimits{} r.GetGraphQL() diff --git a/github/github.go b/github/github.go index c248b256f6e..e41036361a8 100644 --- a/github/github.go +++ b/github/github.go @@ -1303,6 +1303,8 @@ const ( codeScanningUploadCategory actionsRunnerRegistrationCategory scimCategory + dependencySnapshotsCategory + codeSearchCategory categories // An array of this length will be able to contain all rate limit categories. ) @@ -1315,6 +1317,12 @@ func category(method, path string) rateLimitCategory { // NOTE: coreCategory is returned for actionsRunnerRegistrationCategory too, // because no API found for this category. return coreCategory + + // https://docs.github.com/en/rest/search/search#search-code + case strings.HasPrefix(path, "/search/code") && + method == http.MethodGet: + return codeSearchCategory + case strings.HasPrefix(path, "/search/"): return searchCategory case path == "/graphql": @@ -1337,6 +1345,12 @@ func category(method, path string) rateLimitCategory { // https://docs.github.com/enterprise-cloud@latest/rest/scim case strings.HasPrefix(path, "/scim/"): return scimCategory + + // https://docs.github.com/en/rest/dependency-graph/dependency-submission#create-a-snapshot-of-dependencies-for-a-repository + case strings.HasPrefix(path, "/repos/") && + strings.HasSuffix(path, "/dependency-graph/snapshots") && + method == http.MethodPost: + return dependencySnapshotsCategory } } diff --git a/github/github_test.go b/github/github_test.go index 85acacccd2b..c513bf9992f 100644 --- a/github/github_test.go +++ b/github/github_test.go @@ -1162,6 +1162,16 @@ func TestDo_rateLimitCategory(t *testing.T) { url: "/scim/v2/organizations/ORG/Users", category: scimCategory, }, + { + method: http.MethodPost, + url: "/repos/google/go-github/dependency-graph/snapshots", + category: dependencySnapshotsCategory, + }, + { + method: http.MethodGet, + url: "/search/code?q=rate", + category: codeSearchCategory, + }, // missing a check for actionsRunnerRegistrationCategory: API not found } diff --git a/github/rate_limit.go b/github/rate_limit.go index 0fc15f815e2..febe5edccfb 100644 --- a/github/rate_limit.go +++ b/github/rate_limit.go @@ -52,6 +52,8 @@ type RateLimits struct { CodeScanningUpload *Rate `json:"code_scanning_upload"` ActionsRunnerRegistration *Rate `json:"actions_runner_registration"` SCIM *Rate `json:"scim"` + DependencySnapshots *Rate `json:"dependency_snapshots"` + CodeSearch *Rate `json:"code_search"` } func (r RateLimits) String() string { @@ -106,6 +108,12 @@ func (s *RateLimitService) Get(ctx context.Context) (*RateLimits, *Response, err if response.Resources.SCIM != nil { s.client.rateLimits[scimCategory] = *response.Resources.SCIM } + if response.Resources.DependencySnapshots != nil { + s.client.rateLimits[dependencySnapshotsCategory] = *response.Resources.DependencySnapshots + } + if response.Resources.CodeSearch != nil { + s.client.rateLimits[codeSearchCategory] = *response.Resources.CodeSearch + } s.client.rateMu.Unlock() } diff --git a/github/rate_limit_test.go b/github/rate_limit_test.go index 167288bc889..da8a68c9106 100644 --- a/github/rate_limit_test.go +++ b/github/rate_limit_test.go @@ -25,8 +25,10 @@ func TestRateLimits_String(t *testing.T) { CodeScanningUpload: &Rate{}, ActionsRunnerRegistration: &Rate{}, SCIM: &Rate{}, + DependencySnapshots: &Rate{}, + CodeSearch: &Rate{}, } - want := `github.RateLimits{Core:github.Rate{Limit:0, Remaining:0, Reset:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}}, Search:github.Rate{Limit:0, Remaining:0, Reset:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}}, GraphQL:github.Rate{Limit:0, Remaining:0, Reset:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}}, IntegrationManifest:github.Rate{Limit:0, Remaining:0, Reset:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}}, SourceImport:github.Rate{Limit:0, Remaining:0, Reset:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}}, CodeScanningUpload:github.Rate{Limit:0, Remaining:0, Reset:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}}, ActionsRunnerRegistration:github.Rate{Limit:0, Remaining:0, Reset:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}}, SCIM:github.Rate{Limit:0, Remaining:0, Reset:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}}}` + want := `github.RateLimits{Core:github.Rate{Limit:0, Remaining:0, Reset:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}}, Search:github.Rate{Limit:0, Remaining:0, Reset:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}}, GraphQL:github.Rate{Limit:0, Remaining:0, Reset:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}}, IntegrationManifest:github.Rate{Limit:0, Remaining:0, Reset:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}}, SourceImport:github.Rate{Limit:0, Remaining:0, Reset:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}}, CodeScanningUpload:github.Rate{Limit:0, Remaining:0, Reset:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}}, ActionsRunnerRegistration:github.Rate{Limit:0, Remaining:0, Reset:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}}, SCIM:github.Rate{Limit:0, Remaining:0, Reset:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}}, DependencySnapshots:github.Rate{Limit:0, Remaining:0, Reset:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}}, CodeSearch:github.Rate{Limit:0, Remaining:0, Reset:github.Timestamp{0001-01-01 00:00:00 +0000 UTC}}}` if got := v.String(); got != want { t.Errorf("RateLimits.String = %v, want %v", got, want) } @@ -46,7 +48,9 @@ func TestRateLimits(t *testing.T) { "source_import": {"limit":6,"remaining":5,"reset":1372700877}, "code_scanning_upload": {"limit":7,"remaining":6,"reset":1372700878}, "actions_runner_registration": {"limit":8,"remaining":7,"reset":1372700879}, - "scim": {"limit":9,"remaining":8,"reset":1372700880} + "scim": {"limit":9,"remaining":8,"reset":1372700880}, + "dependency_snapshots": {"limit":10,"remaining":9,"reset":1372700881}, + "code_search": {"limit":11,"remaining":10,"reset":1372700882} }}`) }) @@ -97,6 +101,16 @@ func TestRateLimits(t *testing.T) { Remaining: 8, Reset: Timestamp{time.Date(2013, time.July, 1, 17, 48, 00, 0, time.UTC).Local()}, }, + DependencySnapshots: &Rate{ + Limit: 10, + Remaining: 9, + Reset: Timestamp{time.Date(2013, time.July, 1, 17, 48, 1, 0, time.UTC).Local()}, + }, + CodeSearch: &Rate{ + Limit: 11, + Remaining: 10, + Reset: Timestamp{time.Date(2013, time.July, 1, 17, 48, 2, 0, time.UTC).Local()}, + }, } if !cmp.Equal(rate, want) { t.Errorf("RateLimits returned %+v, want %+v", rate, want) @@ -137,6 +151,14 @@ func TestRateLimits(t *testing.T) { category: scimCategory, rate: want.SCIM, }, + { + category: dependencySnapshotsCategory, + rate: want.DependencySnapshots, + }, + { + category: codeSearchCategory, + rate: want.CodeSearch, + }, } for _, tt := range tests { @@ -177,7 +199,9 @@ func TestRateLimits_overQuota(t *testing.T) { "source_import": {"limit":6,"remaining":5,"reset":1372700877}, "code_scanning_upload": {"limit":7,"remaining":6,"reset":1372700878}, "actions_runner_registration": {"limit":8,"remaining":7,"reset":1372700879}, - "scim": {"limit":9,"remaining":8,"reset":1372700880} + "scim": {"limit":9,"remaining":8,"reset":1372700880}, + "dependency_snapshots": {"limit":10,"remaining":9,"reset":1372700881}, + "code_search": {"limit":11,"remaining":10,"reset":1372700882} }}`) }) @@ -228,6 +252,16 @@ func TestRateLimits_overQuota(t *testing.T) { Remaining: 8, Reset: Timestamp{time.Date(2013, time.July, 1, 17, 48, 00, 0, time.UTC).Local()}, }, + DependencySnapshots: &Rate{ + Limit: 10, + Remaining: 9, + Reset: Timestamp{time.Date(2013, time.July, 1, 17, 48, 1, 0, time.UTC).Local()}, + }, + CodeSearch: &Rate{ + Limit: 11, + Remaining: 10, + Reset: Timestamp{time.Date(2013, time.July, 1, 17, 48, 2, 0, time.UTC).Local()}, + }, } if !cmp.Equal(rate, want) { t.Errorf("RateLimits returned %+v, want %+v", rate, want) @@ -269,6 +303,14 @@ func TestRateLimits_overQuota(t *testing.T) { category: scimCategory, rate: want.SCIM, }, + { + category: dependencySnapshotsCategory, + rate: want.DependencySnapshots, + }, + { + category: codeSearchCategory, + rate: want.CodeSearch, + }, } for _, tt := range tests { if got, want := client.rateLimits[tt.category], *tt.rate; got != want { @@ -321,6 +363,16 @@ func TestRateLimits_Marshal(t *testing.T) { Remaining: 1, Reset: Timestamp{referenceTime}, }, + DependencySnapshots: &Rate{ + Limit: 1, + Remaining: 1, + Reset: Timestamp{referenceTime}, + }, + CodeSearch: &Rate{ + Limit: 1, + Remaining: 1, + Reset: Timestamp{referenceTime}, + }, } want := `{ @@ -363,6 +415,16 @@ func TestRateLimits_Marshal(t *testing.T) { "limit": 1, "remaining": 1, "reset": ` + referenceTimeStr + ` + }, + "dependency_snapshots": { + "limit": 1, + "remaining": 1, + "reset": ` + referenceTimeStr + ` + }, + "code_search": { + "limit": 1, + "remaining": 1, + "reset": ` + referenceTimeStr + ` } }` From 574f3a7b62a27831539d672a4a86345aac52f142 Mon Sep 17 00:00:00 2001 From: Kiyofumi Sano <62272140+Kiyo510@users.noreply.github.com> Date: Sat, 16 Dec 2023 07:22:57 +0900 Subject: [PATCH 09/13] Support temporary private fork creation via API (#3025) Fixes: #3007. --- github/security_advisories.go | 31 ++ github/security_advisories_test.go | 474 ++++++++++++++++++++++++++++- 2 files changed, 501 insertions(+), 4 deletions(-) diff --git a/github/security_advisories.go b/github/security_advisories.go index 635263748d4..b5a43f1aac8 100644 --- a/github/security_advisories.go +++ b/github/security_advisories.go @@ -7,6 +7,7 @@ package github import ( "context" + "encoding/json" "fmt" ) @@ -148,6 +149,36 @@ func (s *SecurityAdvisoriesService) RequestCVE(ctx context.Context, owner, repo, return resp, nil } +// CreateTemporaryPrivateFork creates a temporary private fork to collaborate on fixing a security vulnerability in your repository. +// The ghsaID is the GitHub Security Advisory identifier of the advisory. +// +// GitHub API docs: https://docs.github.com/rest/security-advisories/repository-advisories#create-a-temporary-private-fork +// +//meta:operation POST /repos/{owner}/{repo}/security-advisories/{ghsa_id}/forks +func (s *SecurityAdvisoriesService) CreateTemporaryPrivateFork(ctx context.Context, owner, repo, ghsaID string) (*Repository, *Response, error) { + url := fmt.Sprintf("repos/%v/%v/security-advisories/%v/forks", owner, repo, ghsaID) + + req, err := s.client.NewRequest("POST", url, nil) + if err != nil { + return nil, nil, err + } + + fork := new(Repository) + resp, err := s.client.Do(ctx, req, fork) + if err != nil { + if aerr, ok := err.(*AcceptedError); ok { + if err := json.Unmarshal(aerr.Raw, fork); err != nil { + return fork, resp, err + } + + return fork, resp, err + } + return nil, resp, err + } + + return fork, resp, nil +} + // ListRepositorySecurityAdvisoriesForOrg lists the repository security advisories for an organization. // // GitHub API docs: https://docs.github.com/rest/security-advisories/repository-advisories#list-repository-security-advisories-for-an-organization diff --git a/github/security_advisories_test.go b/github/security_advisories_test.go index 918e3e05002..eb8e7d317d6 100644 --- a/github/security_advisories_test.go +++ b/github/security_advisories_test.go @@ -56,6 +56,472 @@ func TestSecurityAdvisoriesService_RequestCVE(t *testing.T) { }) } +func TestSecurityAdvisoriesService_CreateTemporaryPrivateFork(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/security-advisories/ghsa_id/forks", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "POST") + fmt.Fprint(w, `{ + "id": 1, + "node_id": "R_kgDPP3c6pQ", + "owner": { + "login": "owner", + "id": 2, + "node_id": "MDQ6VXFGcjYyMjcyMTQw", + "avatar_url": "https://avatars.githubusercontent.com/u/111111?v=4", + "html_url": "https://github.com/xxxxx", + "gravatar_id": "", + "type": "User", + "site_admin": false, + "url": "https://api.github.com/users/owner", + "events_url": "https://api.github.com/users/owner/events{/privacy}", + "following_url": "https://api.github.com/users/owner/following{/other_user}", + "followers_url": "https://api.github.com/users/owner/followers", + "gists_url": "https://api.github.com/users/owner/gists{/gist_id}", + "organizations_url": "https://api.github.com/users/owner/orgs", + "received_events_url": "https://api.github.com/users/owner/received_events", + "repos_url": "https://api.github.com/users/owner/repos", + "starred_url": "https://api.github.com/users/owner/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/owner/subscriptions" + }, + "name": "repo-ghsa-xxxx-xxxx-xxxx", + "full_name": "owner/repo-ghsa-xxxx-xxxx-xxxx", + "default_branch": "master", + "created_at": "2023-12-08T17:22:41Z", + "pushed_at": "2023-12-03T11:27:08Z", + "updated_at": "2023-12-08T17:22:42Z", + "html_url": "https://github.com/owner/repo-ghsa-xxxx-xxxx-xxxx", + "clone_url": "https://github.com/owner/repo-ghsa-xxxx-xxxx-xxxx.git", + "git_url": "git://github.com/owner/repo-ghsa-xxxx-xxxx-xxxx.git", + "ssh_url": "git@github.com:owner/repo-ghsa-xxxx-xxxx-xxxx.git", + "svn_url": "https://github.com/owner/repo-ghsa-xxxx-xxxx-xxxx", + "fork": false, + "forks_count": 0, + "network_count": 0, + "open_issues_count": 0, + "open_issues": 0, + "stargazers_count": 0, + "subscribers_count": 0, + "watchers_count": 0, + "watchers": 0, + "size": 0, + "permissions": { + "admin": true, + "maintain": true, + "pull": true, + "push": true, + "triage": true + }, + "allow_forking": true, + "web_commit_signoff_required": false, + "archived": false, + "disabled": false, + "private": true, + "has_issues": false, + "has_wiki": false, + "has_pages": false, + "has_projects": false, + "has_downloads": false, + "has_discussions": false, + "is_template": false, + "url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx", + "archive_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/{archive_format}{/ref}", + "assignees_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/assignees{/user}", + "blobs_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/branches{/branch}", + "collaborators_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/comments{/number}", + "commits_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/commits{/sha}", + "compare_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/contents/{+path}", + "contributors_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/contributors", + "deployments_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/deployments", + "downloads_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/downloads", + "events_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/events", + "forks_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/forks", + "git_commits_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/git/tags{/sha}", + "hooks_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/hooks", + "issue_comment_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/issues/events{/number}", + "issues_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/issues{/number}", + "keys_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/keys{/key_id}", + "labels_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/labels{/name}", + "languages_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/languages", + "merges_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/merges", + "milestones_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/milestones{/number}", + "notifications_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/notifications{?since,all,participating}", + "pulls_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/pulls{/number}", + "releases_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/releases{/id}", + "stargazers_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/stargazers", + "statuses_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/subscribers", + "subscription_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/subscription", + "tags_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/tags", + "teams_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/teams", + "visibility": "private" + }`) + }) + + ctx := context.Background() + fork, _, err := client.SecurityAdvisories.CreateTemporaryPrivateFork(ctx, "o", "r", "ghsa_id") + if err != nil { + t.Errorf("SecurityAdvisoriesService.CreateTemporaryPrivateFork returned error: %v", err) + } + + want := &Repository{ + ID: Int64(1), + NodeID: String("R_kgDPP3c6pQ"), + Owner: &User{ + Login: String("owner"), + ID: Int64(2), + NodeID: String("MDQ6VXFGcjYyMjcyMTQw"), + AvatarURL: String("https://avatars.githubusercontent.com/u/111111?v=4"), + HTMLURL: String("https://github.com/xxxxx"), + GravatarID: String(""), + Type: String("User"), + SiteAdmin: Bool(false), + URL: String("https://api.github.com/users/owner"), + EventsURL: String("https://api.github.com/users/owner/events{/privacy}"), + FollowingURL: String("https://api.github.com/users/owner/following{/other_user}"), + FollowersURL: String("https://api.github.com/users/owner/followers"), + GistsURL: String("https://api.github.com/users/owner/gists{/gist_id}"), + OrganizationsURL: String("https://api.github.com/users/owner/orgs"), + ReceivedEventsURL: String("https://api.github.com/users/owner/received_events"), + ReposURL: String("https://api.github.com/users/owner/repos"), + StarredURL: String("https://api.github.com/users/owner/starred{/owner}{/repo}"), + SubscriptionsURL: String("https://api.github.com/users/owner/subscriptions"), + }, + Name: String("repo-ghsa-xxxx-xxxx-xxxx"), + FullName: String("owner/repo-ghsa-xxxx-xxxx-xxxx"), + DefaultBranch: String("master"), + CreatedAt: &Timestamp{time.Date(2023, time.December, 8, 17, 22, 41, 0, time.UTC)}, + PushedAt: &Timestamp{time.Date(2023, time.December, 3, 11, 27, 8, 0, time.UTC)}, + UpdatedAt: &Timestamp{time.Date(2023, time.December, 8, 17, 22, 42, 0, time.UTC)}, + HTMLURL: String("https://github.com/owner/repo-ghsa-xxxx-xxxx-xxxx"), + CloneURL: String("https://github.com/owner/repo-ghsa-xxxx-xxxx-xxxx.git"), + GitURL: String("git://github.com/owner/repo-ghsa-xxxx-xxxx-xxxx.git"), + SSHURL: String("git@github.com:owner/repo-ghsa-xxxx-xxxx-xxxx.git"), + SVNURL: String("https://github.com/owner/repo-ghsa-xxxx-xxxx-xxxx"), + Fork: Bool(false), + ForksCount: Int(0), + NetworkCount: Int(0), + OpenIssuesCount: Int(0), + OpenIssues: Int(0), + StargazersCount: Int(0), + SubscribersCount: Int(0), + WatchersCount: Int(0), + Watchers: Int(0), + Size: Int(0), + Permissions: map[string]bool{ + "admin": true, + "maintain": true, + "pull": true, + "push": true, + "triage": true, + }, + AllowForking: Bool(true), + WebCommitSignoffRequired: Bool(false), + Archived: Bool(false), + Disabled: Bool(false), + Private: Bool(true), + HasIssues: Bool(false), + HasWiki: Bool(false), + HasPages: Bool(false), + HasProjects: Bool(false), + HasDownloads: Bool(false), + HasDiscussions: Bool(false), + IsTemplate: Bool(false), + URL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx"), + ArchiveURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/{archive_format}{/ref}"), + AssigneesURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/assignees{/user}"), + BlobsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/git/blobs{/sha}"), + BranchesURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/branches{/branch}"), + CollaboratorsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/collaborators{/collaborator}"), + CommentsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/comments{/number}"), + CommitsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/commits{/sha}"), + CompareURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/compare/{base}...{head}"), + ContentsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/contents/{+path}"), + ContributorsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/contributors"), + DeploymentsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/deployments"), + DownloadsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/downloads"), + EventsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/events"), + ForksURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/forks"), + GitCommitsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/git/commits{/sha}"), + GitRefsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/git/refs{/sha}"), + GitTagsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/git/tags{/sha}"), + HooksURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/hooks"), + IssueCommentURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/issues/comments{/number}"), + IssueEventsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/issues/events{/number}"), + IssuesURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/issues{/number}"), + KeysURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/keys{/key_id}"), + LabelsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/labels{/name}"), + LanguagesURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/languages"), + MergesURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/merges"), + MilestonesURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/milestones{/number}"), + NotificationsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/notifications{?since,all,participating}"), + PullsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/pulls{/number}"), + ReleasesURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/releases{/id}"), + StargazersURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/stargazers"), + StatusesURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/statuses/{sha}"), + SubscribersURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/subscribers"), + SubscriptionURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/subscription"), + TagsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/tags"), + TeamsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/teams"), + Visibility: String("private"), + } + if !cmp.Equal(fork, want) { + t.Errorf("SecurityAdvisoriesService.CreateTemporaryPrivateFork returned %+v, want %+v", fork, want) + } + + const methodName = "CreateTemporaryPrivateFork" + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.SecurityAdvisories.CreateTemporaryPrivateFork(ctx, "\n", "\n", "\n") + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.SecurityAdvisories.CreateTemporaryPrivateFork(ctx, "o", "r", "ghsa_id") + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestSecurityAdvisoriesService_CreateTemporaryPrivateFork_deferred(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/security-advisories/ghsa_id/forks", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "POST") + w.WriteHeader(http.StatusAccepted) + fmt.Fprint(w, `{ + "id": 1, + "node_id": "R_kgDPP3c6pQ", + "owner": { + "login": "owner", + "id": 2, + "node_id": "MDQ6VXFGcjYyMjcyMTQw", + "avatar_url": "https://avatars.githubusercontent.com/u/111111?v=4", + "html_url": "https://github.com/xxxxx", + "gravatar_id": "", + "type": "User", + "site_admin": false, + "url": "https://api.github.com/users/owner", + "events_url": "https://api.github.com/users/owner/events{/privacy}", + "following_url": "https://api.github.com/users/owner/following{/other_user}", + "followers_url": "https://api.github.com/users/owner/followers", + "gists_url": "https://api.github.com/users/owner/gists{/gist_id}", + "organizations_url": "https://api.github.com/users/owner/orgs", + "received_events_url": "https://api.github.com/users/owner/received_events", + "repos_url": "https://api.github.com/users/owner/repos", + "starred_url": "https://api.github.com/users/owner/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/owner/subscriptions" + }, + "name": "repo-ghsa-xxxx-xxxx-xxxx", + "full_name": "owner/repo-ghsa-xxxx-xxxx-xxxx", + "default_branch": "master", + "created_at": "2023-12-08T17:22:41Z", + "pushed_at": "2023-12-03T11:27:08Z", + "updated_at": "2023-12-08T17:22:42Z", + "html_url": "https://github.com/owner/repo-ghsa-xxxx-xxxx-xxxx", + "clone_url": "https://github.com/owner/repo-ghsa-xxxx-xxxx-xxxx.git", + "git_url": "git://github.com/owner/repo-ghsa-xxxx-xxxx-xxxx.git", + "ssh_url": "git@github.com:owner/repo-ghsa-xxxx-xxxx-xxxx.git", + "svn_url": "https://github.com/owner/repo-ghsa-xxxx-xxxx-xxxx", + "fork": false, + "forks_count": 0, + "network_count": 0, + "open_issues_count": 0, + "open_issues": 0, + "stargazers_count": 0, + "subscribers_count": 0, + "watchers_count": 0, + "watchers": 0, + "size": 0, + "permissions": { + "admin": true, + "maintain": true, + "pull": true, + "push": true, + "triage": true + }, + "allow_forking": true, + "web_commit_signoff_required": false, + "archived": false, + "disabled": false, + "private": true, + "has_issues": false, + "has_wiki": false, + "has_pages": false, + "has_projects": false, + "has_downloads": false, + "has_discussions": false, + "is_template": false, + "url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx", + "archive_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/{archive_format}{/ref}", + "assignees_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/assignees{/user}", + "blobs_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/git/blobs{/sha}", + "branches_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/branches{/branch}", + "collaborators_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/collaborators{/collaborator}", + "comments_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/comments{/number}", + "commits_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/commits{/sha}", + "compare_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/compare/{base}...{head}", + "contents_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/contents/{+path}", + "contributors_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/contributors", + "deployments_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/deployments", + "downloads_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/downloads", + "events_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/events", + "forks_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/forks", + "git_commits_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/git/commits{/sha}", + "git_refs_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/git/refs{/sha}", + "git_tags_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/git/tags{/sha}", + "hooks_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/hooks", + "issue_comment_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/issues/comments{/number}", + "issue_events_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/issues/events{/number}", + "issues_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/issues{/number}", + "keys_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/keys{/key_id}", + "labels_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/labels{/name}", + "languages_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/languages", + "merges_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/merges", + "milestones_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/milestones{/number}", + "notifications_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/notifications{?since,all,participating}", + "pulls_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/pulls{/number}", + "releases_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/releases{/id}", + "stargazers_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/stargazers", + "statuses_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/statuses/{sha}", + "subscribers_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/subscribers", + "subscription_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/subscription", + "tags_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/tags", + "teams_url": "https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/teams", + "visibility": "private" + }`) + }) + + ctx := context.Background() + fork, _, err := client.SecurityAdvisories.CreateTemporaryPrivateFork(ctx, "o", "r", "ghsa_id") + if _, ok := err.(*AcceptedError); !ok { + t.Errorf("SecurityAdvisoriesService.CreateTemporaryPrivateFork returned error: %v (want AcceptedError)", err) + } + + want := &Repository{ + ID: Int64(1), + NodeID: String("R_kgDPP3c6pQ"), + Owner: &User{ + Login: String("owner"), + ID: Int64(2), + NodeID: String("MDQ6VXFGcjYyMjcyMTQw"), + AvatarURL: String("https://avatars.githubusercontent.com/u/111111?v=4"), + HTMLURL: String("https://github.com/xxxxx"), + GravatarID: String(""), + Type: String("User"), + SiteAdmin: Bool(false), + URL: String("https://api.github.com/users/owner"), + EventsURL: String("https://api.github.com/users/owner/events{/privacy}"), + FollowingURL: String("https://api.github.com/users/owner/following{/other_user}"), + FollowersURL: String("https://api.github.com/users/owner/followers"), + GistsURL: String("https://api.github.com/users/owner/gists{/gist_id}"), + OrganizationsURL: String("https://api.github.com/users/owner/orgs"), + ReceivedEventsURL: String("https://api.github.com/users/owner/received_events"), + ReposURL: String("https://api.github.com/users/owner/repos"), + StarredURL: String("https://api.github.com/users/owner/starred{/owner}{/repo}"), + SubscriptionsURL: String("https://api.github.com/users/owner/subscriptions"), + }, + Name: String("repo-ghsa-xxxx-xxxx-xxxx"), + FullName: String("owner/repo-ghsa-xxxx-xxxx-xxxx"), + DefaultBranch: String("master"), + CreatedAt: &Timestamp{time.Date(2023, time.December, 8, 17, 22, 41, 0, time.UTC)}, + PushedAt: &Timestamp{time.Date(2023, time.December, 3, 11, 27, 8, 0, time.UTC)}, + UpdatedAt: &Timestamp{time.Date(2023, time.December, 8, 17, 22, 42, 0, time.UTC)}, + HTMLURL: String("https://github.com/owner/repo-ghsa-xxxx-xxxx-xxxx"), + CloneURL: String("https://github.com/owner/repo-ghsa-xxxx-xxxx-xxxx.git"), + GitURL: String("git://github.com/owner/repo-ghsa-xxxx-xxxx-xxxx.git"), + SSHURL: String("git@github.com:owner/repo-ghsa-xxxx-xxxx-xxxx.git"), + SVNURL: String("https://github.com/owner/repo-ghsa-xxxx-xxxx-xxxx"), + Fork: Bool(false), + ForksCount: Int(0), + NetworkCount: Int(0), + OpenIssuesCount: Int(0), + OpenIssues: Int(0), + StargazersCount: Int(0), + SubscribersCount: Int(0), + WatchersCount: Int(0), + Watchers: Int(0), + Size: Int(0), + Permissions: map[string]bool{ + "admin": true, + "maintain": true, + "pull": true, + "push": true, + "triage": true, + }, + AllowForking: Bool(true), + WebCommitSignoffRequired: Bool(false), + Archived: Bool(false), + Disabled: Bool(false), + Private: Bool(true), + HasIssues: Bool(false), + HasWiki: Bool(false), + HasPages: Bool(false), + HasProjects: Bool(false), + HasDownloads: Bool(false), + HasDiscussions: Bool(false), + IsTemplate: Bool(false), + URL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx"), + ArchiveURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/{archive_format}{/ref}"), + AssigneesURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/assignees{/user}"), + BlobsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/git/blobs{/sha}"), + BranchesURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/branches{/branch}"), + CollaboratorsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/collaborators{/collaborator}"), + CommentsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/comments{/number}"), + CommitsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/commits{/sha}"), + CompareURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/compare/{base}...{head}"), + ContentsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/contents/{+path}"), + ContributorsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/contributors"), + DeploymentsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/deployments"), + DownloadsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/downloads"), + EventsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/events"), + ForksURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/forks"), + GitCommitsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/git/commits{/sha}"), + GitRefsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/git/refs{/sha}"), + GitTagsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/git/tags{/sha}"), + HooksURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/hooks"), + IssueCommentURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/issues/comments{/number}"), + IssueEventsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/issues/events{/number}"), + IssuesURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/issues{/number}"), + KeysURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/keys{/key_id}"), + LabelsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/labels{/name}"), + LanguagesURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/languages"), + MergesURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/merges"), + MilestonesURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/milestones{/number}"), + NotificationsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/notifications{?since,all,participating}"), + PullsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/pulls{/number}"), + ReleasesURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/releases{/id}"), + StargazersURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/stargazers"), + StatusesURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/statuses/{sha}"), + SubscribersURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/subscribers"), + SubscriptionURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/subscription"), + TagsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/tags"), + TeamsURL: String("https://api.github.com/repos/owner/repo-ghsa-xxxx-xxxx-xxxx/teams"), + Visibility: String("private"), + } + if !cmp.Equal(fork, want) { + t.Errorf("SecurityAdvisoriesService.CreateTemporaryPrivateFork returned %+v, want %+v", fork, want) + } +} + +func TestSecurityAdvisoriesService_CreateTemporaryPrivateFork_invalidOwner(t *testing.T) { + client, _, _, teardown := setup() + defer teardown() + + ctx := context.Background() + _, _, err := client.SecurityAdvisories.CreateTemporaryPrivateFork(ctx, "%", "r", "ghsa_id") + testURLParseError(t, err) +} + func TestSecurityAdvisoriesService_ListRepositorySecurityAdvisoriesForOrg_BadRequest(t *testing.T) { client, mux, _, teardown := setup() defer teardown() @@ -146,8 +612,8 @@ func TestSecurityAdvisoriesService_ListRepositorySecurityAdvisoriesForOrg(t *tes assertWrite(t, w, []byte(`[ { "ghsa_id": "GHSA-abcd-1234-efgh", - "cve_id": "CVE-2050-00000" - } + "cve_id": "CVE-2050-00000" + } ]`)) }) @@ -277,8 +743,8 @@ func TestSecurityAdvisoriesService_ListRepositorySecurityAdvisories(t *testing.T assertWrite(t, w, []byte(`[ { "ghsa_id": "GHSA-abcd-1234-efgh", - "cve_id": "CVE-2050-00000" - } + "cve_id": "CVE-2050-00000" + } ]`)) }) From c57201c305f1a3412023894beec2be9e567d4dda Mon Sep 17 00:00:00 2001 From: Benjamin Nater Date: Sat, 16 Dec 2023 02:01:49 +0100 Subject: [PATCH 10/13] Escape package names to support names which include a slash (#3002) --- github/orgs_packages.go | 29 ++++++++--- github/orgs_packages_test.go | 95 +++++++++++++++++++++--------------- 2 files changed, 79 insertions(+), 45 deletions(-) diff --git a/github/orgs_packages.go b/github/orgs_packages.go index 4fb9a63b428..edd8e508fb4 100644 --- a/github/orgs_packages.go +++ b/github/orgs_packages.go @@ -8,6 +8,7 @@ package github import ( "context" "fmt" + "net/url" ) // ListPackages lists the packages for an organization. @@ -38,11 +39,13 @@ func (s *OrganizationsService) ListPackages(ctx context.Context, org string, opt // GetPackage gets a package by name from an organization. // +// Note that packageName is escaped for the URL path so that you don't need to. +// // GitHub API docs: https://docs.github.com/rest/packages/packages#get-a-package-for-an-organization // //meta:operation GET /orgs/{org}/packages/{package_type}/{package_name} func (s *OrganizationsService) GetPackage(ctx context.Context, org, packageType, packageName string) (*Package, *Response, error) { - u := fmt.Sprintf("orgs/%v/packages/%v/%v", org, packageType, packageName) + u := fmt.Sprintf("orgs/%v/packages/%v/%v", org, packageType, url.PathEscape(packageName)) req, err := s.client.NewRequest("GET", u, nil) if err != nil { return nil, nil, err @@ -59,11 +62,13 @@ func (s *OrganizationsService) GetPackage(ctx context.Context, org, packageType, // DeletePackage deletes a package from an organization. // +// Note that packageName is escaped for the URL path so that you don't need to. +// // GitHub API docs: https://docs.github.com/rest/packages/packages#delete-a-package-for-an-organization // //meta:operation DELETE /orgs/{org}/packages/{package_type}/{package_name} func (s *OrganizationsService) DeletePackage(ctx context.Context, org, packageType, packageName string) (*Response, error) { - u := fmt.Sprintf("orgs/%v/packages/%v/%v", org, packageType, packageName) + u := fmt.Sprintf("orgs/%v/packages/%v/%v", org, packageType, url.PathEscape(packageName)) req, err := s.client.NewRequest("DELETE", u, nil) if err != nil { return nil, err @@ -74,11 +79,13 @@ func (s *OrganizationsService) DeletePackage(ctx context.Context, org, packageTy // RestorePackage restores a package to an organization. // +// Note that packageName is escaped for the URL path so that you don't need to. +// // GitHub API docs: https://docs.github.com/rest/packages/packages#restore-a-package-for-an-organization // //meta:operation POST /orgs/{org}/packages/{package_type}/{package_name}/restore func (s *OrganizationsService) RestorePackage(ctx context.Context, org, packageType, packageName string) (*Response, error) { - u := fmt.Sprintf("orgs/%v/packages/%v/%v/restore", org, packageType, packageName) + u := fmt.Sprintf("orgs/%v/packages/%v/%v/restore", org, packageType, url.PathEscape(packageName)) req, err := s.client.NewRequest("POST", u, nil) if err != nil { return nil, err @@ -89,11 +96,13 @@ func (s *OrganizationsService) RestorePackage(ctx context.Context, org, packageT // PackageGetAllVersions gets all versions of a package in an organization. // +// Note that packageName is escaped for the URL path so that you don't need to. +// // GitHub API docs: https://docs.github.com/rest/packages/packages#list-package-versions-for-a-package-owned-by-an-organization // //meta:operation GET /orgs/{org}/packages/{package_type}/{package_name}/versions func (s *OrganizationsService) PackageGetAllVersions(ctx context.Context, org, packageType, packageName string, opts *PackageListOptions) ([]*PackageVersion, *Response, error) { - u := fmt.Sprintf("orgs/%v/packages/%v/%v/versions", org, packageType, packageName) + u := fmt.Sprintf("orgs/%v/packages/%v/%v/versions", org, packageType, url.PathEscape(packageName)) u, err := addOptions(u, opts) if err != nil { return nil, nil, err @@ -115,11 +124,13 @@ func (s *OrganizationsService) PackageGetAllVersions(ctx context.Context, org, p // PackageGetVersion gets a specific version of a package in an organization. // +// Note that packageName is escaped for the URL path so that you don't need to. +// // GitHub API docs: https://docs.github.com/rest/packages/packages#get-a-package-version-for-an-organization // //meta:operation GET /orgs/{org}/packages/{package_type}/{package_name}/versions/{package_version_id} func (s *OrganizationsService) PackageGetVersion(ctx context.Context, org, packageType, packageName string, packageVersionID int64) (*PackageVersion, *Response, error) { - u := fmt.Sprintf("orgs/%v/packages/%v/%v/versions/%v", org, packageType, packageName, packageVersionID) + u := fmt.Sprintf("orgs/%v/packages/%v/%v/versions/%v", org, packageType, url.PathEscape(packageName), packageVersionID) req, err := s.client.NewRequest("GET", u, nil) if err != nil { return nil, nil, err @@ -136,11 +147,13 @@ func (s *OrganizationsService) PackageGetVersion(ctx context.Context, org, packa // PackageDeleteVersion deletes a package version from an organization. // +// Note that packageName is escaped for the URL path so that you don't need to. +// // GitHub API docs: https://docs.github.com/rest/packages/packages#delete-package-version-for-an-organization // //meta:operation DELETE /orgs/{org}/packages/{package_type}/{package_name}/versions/{package_version_id} func (s *OrganizationsService) PackageDeleteVersion(ctx context.Context, org, packageType, packageName string, packageVersionID int64) (*Response, error) { - u := fmt.Sprintf("orgs/%v/packages/%v/%v/versions/%v", org, packageType, packageName, packageVersionID) + u := fmt.Sprintf("orgs/%v/packages/%v/%v/versions/%v", org, packageType, url.PathEscape(packageName), packageVersionID) req, err := s.client.NewRequest("DELETE", u, nil) if err != nil { return nil, err @@ -151,11 +164,13 @@ func (s *OrganizationsService) PackageDeleteVersion(ctx context.Context, org, pa // PackageRestoreVersion restores a package version to an organization. // +// Note that packageName is escaped for the URL path so that you don't need to. +// // GitHub API docs: https://docs.github.com/rest/packages/packages#restore-package-version-for-an-organization // //meta:operation POST /orgs/{org}/packages/{package_type}/{package_name}/versions/{package_version_id}/restore func (s *OrganizationsService) PackageRestoreVersion(ctx context.Context, org, packageType, packageName string, packageVersionID int64) (*Response, error) { - u := fmt.Sprintf("orgs/%v/packages/%v/%v/versions/%v/restore", org, packageType, packageName, packageVersionID) + u := fmt.Sprintf("orgs/%v/packages/%v/%v/versions/%v/restore", org, packageType, url.PathEscape(packageName), packageVersionID) req, err := s.client.NewRequest("POST", u, nil) if err != nil { return nil, err diff --git a/github/orgs_packages_test.go b/github/orgs_packages_test.go index f8c8701d300..097cae76282 100644 --- a/github/orgs_packages_test.go +++ b/github/orgs_packages_test.go @@ -7,7 +7,7 @@ package github import ( "context" - "fmt" + "io" "net/http" "testing" @@ -20,7 +20,7 @@ func TestOrganizationsService_ListPackages(t *testing.T) { mux.HandleFunc("/orgs/o/packages", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - fmt.Fprint(w, `[{ + _, err := io.WriteString(w, `[{ "id": 197, "name": "hello_docker", "package_type": "container", @@ -52,6 +52,9 @@ func TestOrganizationsService_ListPackages(t *testing.T) { "html_url": "https://github.com/orgs/github/packages/container/package/hello_docker" } ]`) + if err != nil { + t.Fatal("Failed to write test response: ", err) + } }) ctx := context.Background() @@ -114,35 +117,39 @@ func TestOrganizationsService_GetPackage(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - mux.HandleFunc("/orgs/o/packages/container/hello_docker", func(w http.ResponseWriter, r *http.Request) { + // don't url escape the package name here since mux will convert it to a slash automatically + mux.HandleFunc("/orgs/o/packages/container/hello/hello_docker", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - fmt.Fprint(w, `{ + _, err := io.WriteString(w, `{ "id": 197, - "name": "hello_docker", + "name": "hello/hello_docker", "package_type": "container", "version_count": 1, "visibility": "private", - "url": "https://api.github.com/orgs/github/packages/container/hello_docker", + "url": "https://api.github.com/orgs/github/packages/container/hello%2Fhello_docker", "created_at": `+referenceTimeStr+`, "updated_at": `+referenceTimeStr+`, - "html_url": "https://github.com/orgs/github/packages/container/package/hello_docker" + "html_url": "https://github.com/orgs/github/packages/container/package/hello%2Fhello_docker" }`) + if err != nil { + t.Fatal("Failed to write test response: ", err) + } }) ctx := context.Background() - packages, _, err := client.Organizations.GetPackage(ctx, "o", "container", "hello_docker") + packages, _, err := client.Organizations.GetPackage(ctx, "o", "container", "hello/hello_docker") if err != nil { t.Errorf("Organizations.GetPackage returned error: %v", err) } want := &Package{ ID: Int64(197), - Name: String("hello_docker"), + Name: String("hello/hello_docker"), PackageType: String("container"), VersionCount: Int64(1), Visibility: String("private"), - URL: String("https://api.github.com/orgs/github/packages/container/hello_docker"), - HTMLURL: String("https://github.com/orgs/github/packages/container/package/hello_docker"), + URL: String("https://api.github.com/orgs/github/packages/container/hello%2Fhello_docker"), + HTMLURL: String("https://github.com/orgs/github/packages/container/package/hello%2Fhello_docker"), CreatedAt: &Timestamp{referenceTime}, UpdatedAt: &Timestamp{referenceTime}, } @@ -169,12 +176,13 @@ func TestOrganizationsService_DeletePackage(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - mux.HandleFunc("/orgs/o/packages/container/hello_docker", func(w http.ResponseWriter, r *http.Request) { + // don't url escape the package name here since mux will convert it to a slash automatically + mux.HandleFunc("/orgs/o/packages/container/hello/hello_docker", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "DELETE") }) ctx := context.Background() - _, err := client.Organizations.DeletePackage(ctx, "o", "container", "hello_docker") + _, err := client.Organizations.DeletePackage(ctx, "o", "container", "hello/hello_docker") if err != nil { t.Errorf("Organizations.DeletePackage returned error: %v", err) } @@ -198,12 +206,13 @@ func TestOrganizationsService_RestorePackage(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - mux.HandleFunc("/orgs/o/packages/container/hello_docker/restore", func(w http.ResponseWriter, r *http.Request) { + // don't url escape the package name here since mux will convert it to a slash automatically + mux.HandleFunc("/orgs/o/packages/container/hello/hello_docker/restore", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "POST") }) ctx := context.Background() - _, err := client.Organizations.RestorePackage(ctx, "o", "container", "hello_docker") + _, err := client.Organizations.RestorePackage(ctx, "o", "container", "hello/hello_docker") if err != nil { t.Errorf("Organizations.RestorePackage returned error: %v", err) } @@ -215,7 +224,7 @@ func TestOrganizationsService_RestorePackage(t *testing.T) { }) testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - return client.Organizations.RestorePackage(ctx, "", "container", "hello_docker") + return client.Organizations.RestorePackage(ctx, "", "container", "hello/hello_docker") }) } @@ -223,18 +232,19 @@ func TestOrganizationsService_ListPackagesVersions(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - mux.HandleFunc("/orgs/o/packages/container/hello_docker/versions", func(w http.ResponseWriter, r *http.Request) { + // don't url escape the package name here since mux will convert it to a slash automatically + mux.HandleFunc("/orgs/o/packages/container/hello/hello_docker/versions", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") testFormValues(t, r, values{"per_page": "2", "page": "1", "state": "deleted", "visibility": "internal", "package_type": "container"}) - fmt.Fprint(w, `[ + _, err := io.WriteString(w, `[ { "id": 45763, "name": "sha256:08a44bab0bddaddd8837a8b381aebc2e4b933768b981685a9e088360af0d3dd9", - "url": "https://api.github.com/users/octocat/packages/container/hello_docker/versions/45763", - "package_html_url": "https://github.com/users/octocat/packages/container/package/hello_docker", + "url": "https://api.github.com/users/octocat/packages/container/hello%2Fhello_docker/versions/45763", + "package_html_url": "https://github.com/users/octocat/packages/container/package/hello%2Fhello_docker", "created_at": `+referenceTimeStr+`, "updated_at": `+referenceTimeStr+`, - "html_url": "https://github.com/users/octocat/packages/container/hello_docker/45763", + "html_url": "https://github.com/users/octocat/packages/container/hello%2Fhello_docker/45763", "metadata": { "package_type": "container", "container": { @@ -244,13 +254,16 @@ func TestOrganizationsService_ListPackagesVersions(t *testing.T) { } } }]`) + if err != nil { + t.Fatal("Failed to write test response: ", err) + } }) ctx := context.Background() opts := &PackageListOptions{ String("internal"), String("container"), String("deleted"), ListOptions{Page: 1, PerPage: 2}, } - packages, _, err := client.Organizations.PackageGetAllVersions(ctx, "o", "container", "hello_docker", opts) + packages, _, err := client.Organizations.PackageGetAllVersions(ctx, "o", "container", "hello/hello_docker", opts) if err != nil { t.Errorf("Organizations.PackageGetAllVersions returned error: %v", err) } @@ -258,11 +271,11 @@ func TestOrganizationsService_ListPackagesVersions(t *testing.T) { want := []*PackageVersion{{ ID: Int64(45763), Name: String("sha256:08a44bab0bddaddd8837a8b381aebc2e4b933768b981685a9e088360af0d3dd9"), - URL: String("https://api.github.com/users/octocat/packages/container/hello_docker/versions/45763"), - PackageHTMLURL: String("https://github.com/users/octocat/packages/container/package/hello_docker"), + URL: String("https://api.github.com/users/octocat/packages/container/hello%2Fhello_docker/versions/45763"), + PackageHTMLURL: String("https://github.com/users/octocat/packages/container/package/hello%2Fhello_docker"), CreatedAt: &Timestamp{referenceTime}, UpdatedAt: &Timestamp{referenceTime}, - HTMLURL: String("https://github.com/users/octocat/packages/container/hello_docker/45763"), + HTMLURL: String("https://github.com/users/octocat/packages/container/hello%2Fhello_docker/45763"), Metadata: &PackageMetadata{ PackageType: String("container"), Container: &PackageContainerMetadata{ @@ -293,17 +306,18 @@ func TestOrganizationsService_PackageGetVersion(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - mux.HandleFunc("/orgs/o/packages/container/hello_docker/versions/45763", func(w http.ResponseWriter, r *http.Request) { + // don't url escape the package name here since mux will convert it to a slash automatically + mux.HandleFunc("/orgs/o/packages/container/hello/hello_docker/versions/45763", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "GET") - fmt.Fprint(w, ` + _, err := io.WriteString(w, ` { "id": 45763, "name": "sha256:08a44bab0bddaddd8837a8b381aebc2e4b933768b981685a9e088360af0d3dd9", - "url": "https://api.github.com/users/octocat/packages/container/hello_docker/versions/45763", - "package_html_url": "https://github.com/users/octocat/packages/container/package/hello_docker", + "url": "https://api.github.com/users/octocat/packages/container/hello%2Fhello_docker/versions/45763", + "package_html_url": "https://github.com/users/octocat/packages/container/package/hello%2Fhello_docker", "created_at": `+referenceTimeStr+`, "updated_at": `+referenceTimeStr+`, - "html_url": "https://github.com/users/octocat/packages/container/hello_docker/45763", + "html_url": "https://github.com/users/octocat/packages/container/hello%2Fhello_docker/45763", "metadata": { "package_type": "container", "container": { @@ -313,10 +327,13 @@ func TestOrganizationsService_PackageGetVersion(t *testing.T) { } } }`) + if err != nil { + t.Fatal("Failed to write test response: ", err) + } }) ctx := context.Background() - packages, _, err := client.Organizations.PackageGetVersion(ctx, "o", "container", "hello_docker", 45763) + packages, _, err := client.Organizations.PackageGetVersion(ctx, "o", "container", "hello/hello_docker", 45763) if err != nil { t.Errorf("Organizations.PackageGetVersion returned error: %v", err) } @@ -324,11 +341,11 @@ func TestOrganizationsService_PackageGetVersion(t *testing.T) { want := &PackageVersion{ ID: Int64(45763), Name: String("sha256:08a44bab0bddaddd8837a8b381aebc2e4b933768b981685a9e088360af0d3dd9"), - URL: String("https://api.github.com/users/octocat/packages/container/hello_docker/versions/45763"), - PackageHTMLURL: String("https://github.com/users/octocat/packages/container/package/hello_docker"), + URL: String("https://api.github.com/users/octocat/packages/container/hello%2Fhello_docker/versions/45763"), + PackageHTMLURL: String("https://github.com/users/octocat/packages/container/package/hello%2Fhello_docker"), CreatedAt: &Timestamp{referenceTime}, UpdatedAt: &Timestamp{referenceTime}, - HTMLURL: String("https://github.com/users/octocat/packages/container/hello_docker/45763"), + HTMLURL: String("https://github.com/users/octocat/packages/container/hello%2Fhello_docker/45763"), Metadata: &PackageMetadata{ PackageType: String("container"), Container: &PackageContainerMetadata{ @@ -359,12 +376,13 @@ func TestOrganizationsService_PackageDeleteVersion(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - mux.HandleFunc("/orgs/o/packages/container/hello_docker/versions/45763", func(w http.ResponseWriter, r *http.Request) { + // don't url escape the package name here since mux will convert it to a slash automatically + mux.HandleFunc("/orgs/o/packages/container/hello/hello_docker/versions/45763", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "DELETE") }) ctx := context.Background() - _, err := client.Organizations.PackageDeleteVersion(ctx, "o", "container", "hello_docker", 45763) + _, err := client.Organizations.PackageDeleteVersion(ctx, "o", "container", "hello/hello_docker", 45763) if err != nil { t.Errorf("Organizations.PackageDeleteVersion returned error: %v", err) } @@ -384,12 +402,13 @@ func TestOrganizationsService_PackageRestoreVersion(t *testing.T) { client, mux, _, teardown := setup() defer teardown() - mux.HandleFunc("/orgs/o/packages/container/hello_docker/versions/45763/restore", func(w http.ResponseWriter, r *http.Request) { + // don't url escape the package name here since mux will convert it to a slash automatically + mux.HandleFunc("/orgs/o/packages/container/hello/hello_docker/versions/45763/restore", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, "POST") }) ctx := context.Background() - _, err := client.Organizations.PackageRestoreVersion(ctx, "o", "container", "hello_docker", 45763) + _, err := client.Organizations.PackageRestoreVersion(ctx, "o", "container", "hello/hello_docker", 45763) if err != nil { t.Errorf("Organizations.PackageRestoreVersion returned error: %v", err) } From 2664df0ee07234faa9cfd8ec5419900ca4d0b68a Mon Sep 17 00:00:00 2001 From: WillAbides <233500+WillAbides@users.noreply.github.com> Date: Fri, 15 Dec 2023 19:07:07 -0600 Subject: [PATCH 11/13] Don't update httpClient passed to NewClient (#3011) --- github/github.go | 8 ++++++- github/github_test.go | 51 +++++++++++++++++++++++++++++-------------- 2 files changed, 42 insertions(+), 17 deletions(-) diff --git a/github/github.go b/github/github.go index e41036361a8..da4f2d067ee 100644 --- a/github/github.go +++ b/github/github.go @@ -220,6 +220,8 @@ type service struct { } // Client returns the http.Client used by this GitHub client. +// This should only be used for requests to the GitHub API because +// request headers will contain an authorization token. func (c *Client) Client() *http.Client { c.clientMu.Lock() defer c.clientMu.Unlock() @@ -315,7 +317,11 @@ func addOptions(s string, opts interface{}) (string, error) { // an http.Client that will perform the authentication for you (such as that // provided by the golang.org/x/oauth2 library). func NewClient(httpClient *http.Client) *Client { - c := &Client{client: httpClient} + if httpClient == nil { + httpClient = &http.Client{} + } + httpClient2 := *httpClient + c := &Client{client: &httpClient2} c.initialize() return c } diff --git a/github/github_test.go b/github/github_test.go index c513bf9992f..773309a8e51 100644 --- a/github/github_test.go +++ b/github/github_test.go @@ -330,26 +330,45 @@ func TestClient(t *testing.T) { func TestWithAuthToken(t *testing.T) { token := "gh_test_token" - var gotAuthHeaderVals []string - wantAuthHeaderVals := []string{"Bearer " + token} - srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - gotAuthHeaderVals = r.Header["Authorization"] - })) - validate := func(c *Client) { + + validate := func(t *testing.T, c *http.Client, token string) { t.Helper() - gotAuthHeaderVals = nil - _, err := c.Client().Get(srv.URL) - if err != nil { - t.Fatalf("Get returned unexpected error: %v", err) + want := token + if want != "" { + want = "Bearer " + want + } + gotReq := false + headerVal := "" + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + gotReq = true + headerVal = r.Header.Get("Authorization") + })) + _, err := c.Get(srv.URL) + assertNilError(t, err) + if !gotReq { + t.Error("request not sent") } - diff := cmp.Diff(wantAuthHeaderVals, gotAuthHeaderVals) - if diff != "" { - t.Errorf("Authorization header values mismatch (-want +got):\n%s", diff) + if headerVal != want { + t.Errorf("Authorization header is %v, want %v", headerVal, want) } } - validate(NewClient(nil).WithAuthToken(token)) - validate(new(Client).WithAuthToken(token)) - validate(NewTokenClient(context.Background(), token)) + + t.Run("zero-value Client", func(t *testing.T) { + c := new(Client).WithAuthToken(token) + validate(t, c.Client(), token) + }) + + t.Run("NewClient", func(t *testing.T) { + httpClient := &http.Client{} + client := NewClient(httpClient).WithAuthToken(token) + validate(t, client.Client(), token) + // make sure the original client isn't setting auth headers now + validate(t, httpClient, "") + }) + + t.Run("NewTokenClient", func(t *testing.T) { + validate(t, NewTokenClient(context.Background(), token).Client(), token) + }) } func TestWithEnterpriseURLs(t *testing.T) { From d42e0be83cc913cc930814cb17f09772982ff864 Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Sun, 17 Dec 2023 19:35:25 -0500 Subject: [PATCH 12/13] Merge master Signed-off-by: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> --- github/github-accessors.go | 179 ------------------------- github/github-accessors_test.go | 223 -------------------------------- github/github_test.go | 8 +- github/orgs_audit_log.go | 84 ------------ 4 files changed, 3 insertions(+), 491 deletions(-) diff --git a/github/github-accessors.go b/github/github-accessors.go index 9e8fe0448ca..f41409f9e6c 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -1166,185 +1166,6 @@ func (a *AuditEntry) GetOrgID() int64 { return *a.OrgID } -<<<<<<< HEAD -======= -// GetPermission returns the Permission field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetPermission() string { - if a == nil || a.Permission == nil { - return "" - } - return *a.Permission -} - -// GetPreviousVisibility returns the PreviousVisibility field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetPreviousVisibility() string { - if a == nil || a.PreviousVisibility == nil { - return "" - } - return *a.PreviousVisibility -} - -// GetProgrammaticAccessType returns the ProgrammaticAccessType field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetProgrammaticAccessType() string { - if a == nil || a.ProgrammaticAccessType == nil { - return "" - } - return *a.ProgrammaticAccessType -} - -// GetPullRequestID returns the PullRequestID field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetPullRequestID() int64 { - if a == nil || a.PullRequestID == nil { - return 0 - } - return *a.PullRequestID -} - -// GetPullRequestTitle returns the PullRequestTitle field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetPullRequestTitle() string { - if a == nil || a.PullRequestTitle == nil { - return "" - } - return *a.PullRequestTitle -} - -// GetPullRequestURL returns the PullRequestURL field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetPullRequestURL() string { - if a == nil || a.PullRequestURL == nil { - return "" - } - return *a.PullRequestURL -} - -// GetReadOnly returns the ReadOnly field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetReadOnly() string { - if a == nil || a.ReadOnly == nil { - return "" - } - return *a.ReadOnly -} - -// GetReferrer returns the Referrer field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetReferrer() string { - if a == nil || a.Referrer == nil { - return "" - } - return *a.Referrer -} - -// GetRepo returns the Repo field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetRepo() string { - if a == nil || a.Repo == nil { - return "" - } - return *a.Repo -} - -// GetRepository returns the Repository field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetRepository() string { - if a == nil || a.Repository == nil { - return "" - } - return *a.Repository -} - -// GetRepositoryPublic returns the RepositoryPublic field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetRepositoryPublic() bool { - if a == nil || a.RepositoryPublic == nil { - return false - } - return *a.RepositoryPublic -} - -// GetRunAttempt returns the RunAttempt field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetRunAttempt() int64 { - if a == nil || a.RunAttempt == nil { - return 0 - } - return *a.RunAttempt -} - -// GetRunnerGroupID returns the RunnerGroupID field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetRunnerGroupID() int64 { - if a == nil || a.RunnerGroupID == nil { - return 0 - } - return *a.RunnerGroupID -} - -// GetRunnerGroupName returns the RunnerGroupName field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetRunnerGroupName() string { - if a == nil || a.RunnerGroupName == nil { - return "" - } - return *a.RunnerGroupName -} - -// GetRunnerID returns the RunnerID field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetRunnerID() int64 { - if a == nil || a.RunnerID == nil { - return 0 - } - return *a.RunnerID -} - -// GetRunnerName returns the RunnerName field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetRunnerName() string { - if a == nil || a.RunnerName == nil { - return "" - } - return *a.RunnerName -} - -// GetRunNumber returns the RunNumber field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetRunNumber() int64 { - if a == nil || a.RunNumber == nil { - return 0 - } - return *a.RunNumber -} - -// GetSourceVersion returns the SourceVersion field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetSourceVersion() string { - if a == nil || a.SourceVersion == nil { - return "" - } - return *a.SourceVersion -} - -// GetStartedAt returns the StartedAt field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetStartedAt() Timestamp { - if a == nil || a.StartedAt == nil { - return Timestamp{} - } - return *a.StartedAt -} - -// GetTargetLogin returns the TargetLogin field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetTargetLogin() string { - if a == nil || a.TargetLogin == nil { - return "" - } - return *a.TargetLogin -} - -// GetTargetVersion returns the TargetVersion field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetTargetVersion() string { - if a == nil || a.TargetVersion == nil { - return "" - } - return *a.TargetVersion -} - -// GetTeam returns the Team field if it's non-nil, zero value otherwise. -func (a *AuditEntry) GetTeam() string { - if a == nil || a.Team == nil { - return "" - } - return *a.Team -} - ->>>>>>> d47936f (Add Referrer field to AuditEntry (#3032)) // GetTimestamp returns the Timestamp field if it's non-nil, zero value otherwise. func (a *AuditEntry) GetTimestamp() Timestamp { if a == nil || a.Timestamp == nil { diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index e33e713b18b..5b0b9911bdb 100644 --- a/github/github-accessors_test.go +++ b/github/github-accessors_test.go @@ -1380,229 +1380,6 @@ func TestAuditEntry_GetOrgID(tt *testing.T) { a.GetOrgID() } -<<<<<<< HEAD -======= -func TestAuditEntry_GetPermission(tt *testing.T) { - var zeroValue string - a := &AuditEntry{Permission: &zeroValue} - a.GetPermission() - a = &AuditEntry{} - a.GetPermission() - a = nil - a.GetPermission() -} - -func TestAuditEntry_GetPreviousVisibility(tt *testing.T) { - var zeroValue string - a := &AuditEntry{PreviousVisibility: &zeroValue} - a.GetPreviousVisibility() - a = &AuditEntry{} - a.GetPreviousVisibility() - a = nil - a.GetPreviousVisibility() -} - -func TestAuditEntry_GetProgrammaticAccessType(tt *testing.T) { - var zeroValue string - a := &AuditEntry{ProgrammaticAccessType: &zeroValue} - a.GetProgrammaticAccessType() - a = &AuditEntry{} - a.GetProgrammaticAccessType() - a = nil - a.GetProgrammaticAccessType() -} - -func TestAuditEntry_GetPullRequestID(tt *testing.T) { - var zeroValue int64 - a := &AuditEntry{PullRequestID: &zeroValue} - a.GetPullRequestID() - a = &AuditEntry{} - a.GetPullRequestID() - a = nil - a.GetPullRequestID() -} - -func TestAuditEntry_GetPullRequestTitle(tt *testing.T) { - var zeroValue string - a := &AuditEntry{PullRequestTitle: &zeroValue} - a.GetPullRequestTitle() - a = &AuditEntry{} - a.GetPullRequestTitle() - a = nil - a.GetPullRequestTitle() -} - -func TestAuditEntry_GetPullRequestURL(tt *testing.T) { - var zeroValue string - a := &AuditEntry{PullRequestURL: &zeroValue} - a.GetPullRequestURL() - a = &AuditEntry{} - a.GetPullRequestURL() - a = nil - a.GetPullRequestURL() -} - -func TestAuditEntry_GetReadOnly(tt *testing.T) { - var zeroValue string - a := &AuditEntry{ReadOnly: &zeroValue} - a.GetReadOnly() - a = &AuditEntry{} - a.GetReadOnly() - a = nil - a.GetReadOnly() -} - -func TestAuditEntry_GetReferrer(tt *testing.T) { - var zeroValue string - a := &AuditEntry{Referrer: &zeroValue} - a.GetReferrer() - a = &AuditEntry{} - a.GetReferrer() - a = nil - a.GetReferrer() -} - -func TestAuditEntry_GetRepo(tt *testing.T) { - var zeroValue string - a := &AuditEntry{Repo: &zeroValue} - a.GetRepo() - a = &AuditEntry{} - a.GetRepo() - a = nil - a.GetRepo() -} - -func TestAuditEntry_GetRepository(tt *testing.T) { - var zeroValue string - a := &AuditEntry{Repository: &zeroValue} - a.GetRepository() - a = &AuditEntry{} - a.GetRepository() - a = nil - a.GetRepository() -} - -func TestAuditEntry_GetRepositoryPublic(tt *testing.T) { - var zeroValue bool - a := &AuditEntry{RepositoryPublic: &zeroValue} - a.GetRepositoryPublic() - a = &AuditEntry{} - a.GetRepositoryPublic() - a = nil - a.GetRepositoryPublic() -} - -func TestAuditEntry_GetRunAttempt(tt *testing.T) { - var zeroValue int64 - a := &AuditEntry{RunAttempt: &zeroValue} - a.GetRunAttempt() - a = &AuditEntry{} - a.GetRunAttempt() - a = nil - a.GetRunAttempt() -} - -func TestAuditEntry_GetRunnerGroupID(tt *testing.T) { - var zeroValue int64 - a := &AuditEntry{RunnerGroupID: &zeroValue} - a.GetRunnerGroupID() - a = &AuditEntry{} - a.GetRunnerGroupID() - a = nil - a.GetRunnerGroupID() -} - -func TestAuditEntry_GetRunnerGroupName(tt *testing.T) { - var zeroValue string - a := &AuditEntry{RunnerGroupName: &zeroValue} - a.GetRunnerGroupName() - a = &AuditEntry{} - a.GetRunnerGroupName() - a = nil - a.GetRunnerGroupName() -} - -func TestAuditEntry_GetRunnerID(tt *testing.T) { - var zeroValue int64 - a := &AuditEntry{RunnerID: &zeroValue} - a.GetRunnerID() - a = &AuditEntry{} - a.GetRunnerID() - a = nil - a.GetRunnerID() -} - -func TestAuditEntry_GetRunnerName(tt *testing.T) { - var zeroValue string - a := &AuditEntry{RunnerName: &zeroValue} - a.GetRunnerName() - a = &AuditEntry{} - a.GetRunnerName() - a = nil - a.GetRunnerName() -} - -func TestAuditEntry_GetRunNumber(tt *testing.T) { - var zeroValue int64 - a := &AuditEntry{RunNumber: &zeroValue} - a.GetRunNumber() - a = &AuditEntry{} - a.GetRunNumber() - a = nil - a.GetRunNumber() -} - -func TestAuditEntry_GetSourceVersion(tt *testing.T) { - var zeroValue string - a := &AuditEntry{SourceVersion: &zeroValue} - a.GetSourceVersion() - a = &AuditEntry{} - a.GetSourceVersion() - a = nil - a.GetSourceVersion() -} - -func TestAuditEntry_GetStartedAt(tt *testing.T) { - var zeroValue Timestamp - a := &AuditEntry{StartedAt: &zeroValue} - a.GetStartedAt() - a = &AuditEntry{} - a.GetStartedAt() - a = nil - a.GetStartedAt() -} - -func TestAuditEntry_GetTargetLogin(tt *testing.T) { - var zeroValue string - a := &AuditEntry{TargetLogin: &zeroValue} - a.GetTargetLogin() - a = &AuditEntry{} - a.GetTargetLogin() - a = nil - a.GetTargetLogin() -} - -func TestAuditEntry_GetTargetVersion(tt *testing.T) { - var zeroValue string - a := &AuditEntry{TargetVersion: &zeroValue} - a.GetTargetVersion() - a = &AuditEntry{} - a.GetTargetVersion() - a = nil - a.GetTargetVersion() -} - -func TestAuditEntry_GetTeam(tt *testing.T) { - var zeroValue string - a := &AuditEntry{Team: &zeroValue} - a.GetTeam() - a = &AuditEntry{} - a.GetTeam() - a = nil - a.GetTeam() -} - ->>>>>>> d47936f (Add Referrer field to AuditEntry (#3032)) func TestAuditEntry_GetTimestamp(tt *testing.T) { var zeroValue Timestamp a := &AuditEntry{Timestamp: &zeroValue} diff --git a/github/github_test.go b/github/github_test.go index 773309a8e51..45ac57c0019 100644 --- a/github/github_test.go +++ b/github/github_test.go @@ -275,13 +275,11 @@ func testErrorResponseForStatusCode(t *testing.T, code int) { } } -func assertNoDiff(t *testing.T, want, actual interface{}) { +func assertNoDiff(t *testing.T, want, got interface{}) { t.Helper() - diff := cmp.Diff(want, actual) - if diff == "" { - return + if diff := cmp.Diff(want, got); diff != "" { + t.Errorf("diff mismatch (-want +got):\n%v", diff) } - t.Errorf("unexpected diff: %s", diff) } func assertNilError(t *testing.T, err error) { diff --git a/github/orgs_audit_log.go b/github/orgs_audit_log.go index 78761faf24f..28ac079bb3b 100644 --- a/github/orgs_audit_log.go +++ b/github/orgs_audit_log.go @@ -40,7 +40,6 @@ type ActorLocation struct { // in AdditionalFields. // For a list of actions see - https://docs.github.com/github/setting-up-and-managing-organizations-and-teams/reviewing-the-audit-log-for-your-organization#audit-log-actions type AuditEntry struct { -<<<<<<< HEAD Action *string `json:"action,omitempty"` // The name of the action that was performed, for example `user.login` or `repo.create`. Actor *string `json:"actor,omitempty"` // The actor who performed the action. ActorID *int64 `json:"actor_id,omitempty"` @@ -59,89 +58,6 @@ type AuditEntry struct { TokenScopes *string `json:"token_scopes,omitempty"` User *string `json:"user,omitempty"` // The user that was affected by the action performed (if available). UserID *int64 `json:"user_id,omitempty"` -======= - ActorIP *string `json:"actor_ip,omitempty"` - Action *string `json:"action,omitempty"` // The name of the action that was performed, for example `user.login` or `repo.create`. - Active *bool `json:"active,omitempty"` - ActiveWas *bool `json:"active_was,omitempty"` - Actor *string `json:"actor,omitempty"` // The actor who performed the action. - ActorLocation *ActorLocation `json:"actor_location,omitempty"` - BlockedUser *string `json:"blocked_user,omitempty"` - Business *string `json:"business,omitempty"` - CancelledAt *Timestamp `json:"cancelled_at,omitempty"` - CompletedAt *Timestamp `json:"completed_at,omitempty"` - Conclusion *string `json:"conclusion,omitempty"` - Config *HookConfig `json:"config,omitempty"` - ConfigWas *HookConfig `json:"config_was,omitempty"` - ContentType *string `json:"content_type,omitempty"` - CreatedAt *Timestamp `json:"created_at,omitempty"` - DeployKeyFingerprint *string `json:"deploy_key_fingerprint,omitempty"` - DocumentID *string `json:"_document_id,omitempty"` - Emoji *string `json:"emoji,omitempty"` - EnvironmentName *string `json:"environment_name,omitempty"` - Event *string `json:"event,omitempty"` - Events []string `json:"events,omitempty"` - EventsWere []string `json:"events_were,omitempty"` - Explanation *string `json:"explanation,omitempty"` - ExternalIdentityNameID *string `json:"external_identity_nameid,omitempty"` - ExternalIdentityUsername *string `json:"external_identity_username,omitempty"` - Fingerprint *string `json:"fingerprint,omitempty"` - HashedToken *string `json:"hashed_token,omitempty"` - HeadBranch *string `json:"head_branch,omitempty"` - HeadSHA *string `json:"head_sha,omitempty"` - HookID *int64 `json:"hook_id,omitempty"` - IsHostedRunner *bool `json:"is_hosted_runner,omitempty"` - JobName *string `json:"job_name,omitempty"` - JobWorkflowRef *string `json:"job_workflow_ref,omitempty"` - LimitedAvailability *bool `json:"limited_availability,omitempty"` - Message *string `json:"message,omitempty"` - Name *string `json:"name,omitempty"` - OAuthApplicationID *int64 `json:"oauth_application_id,omitempty"` - OldUser *string `json:"old_user,omitempty"` - OldPermission *string `json:"old_permission,omitempty"` // The permission level for membership changes, for example `admin` or `read`. - OpenSSHPublicKey *string `json:"openssh_public_key,omitempty"` - OperationType *string `json:"operation_type,omitempty"` - Org *string `json:"org,omitempty"` - OrgID *int64 `json:"org_id,omitempty"` - OverriddenCodes []string `json:"overridden_codes,omitempty"` - Permission *string `json:"permission,omitempty"` // The permission level for membership changes, for example `admin` or `read`. - PreviousVisibility *string `json:"previous_visibility,omitempty"` - ProgrammaticAccessType *string `json:"programmatic_access_type,omitempty"` - PullRequestID *int64 `json:"pull_request_id,omitempty"` - PullRequestTitle *string `json:"pull_request_title,omitempty"` - PullRequestURL *string `json:"pull_request_url,omitempty"` - ReadOnly *string `json:"read_only,omitempty"` - Reasons []*PolicyOverrideReason `json:"reasons,omitempty"` - Referrer *string `json:"referrer,omitempty"` - Repo *string `json:"repo,omitempty"` - Repository *string `json:"repository,omitempty"` - RepositoryPublic *bool `json:"repository_public,omitempty"` - RunAttempt *int64 `json:"run_attempt,omitempty"` - RunnerGroupID *int64 `json:"runner_group_id,omitempty"` - RunnerGroupName *string `json:"runner_group_name,omitempty"` - RunnerID *int64 `json:"runner_id,omitempty"` - RunnerLabels []string `json:"runner_labels,omitempty"` - RunnerName *string `json:"runner_name,omitempty"` - RunNumber *int64 `json:"run_number,omitempty"` - SecretsPassed []string `json:"secrets_passed,omitempty"` - SourceVersion *string `json:"source_version,omitempty"` - StartedAt *Timestamp `json:"started_at,omitempty"` - TargetLogin *string `json:"target_login,omitempty"` - TargetVersion *string `json:"target_version,omitempty"` - Team *string `json:"team,omitempty"` - Timestamp *Timestamp `json:"@timestamp,omitempty"` // The time the audit log event occurred, given as a [Unix timestamp](http://en.wikipedia.org/wiki/Unix_time). - TokenID *int64 `json:"token_id,omitempty"` - TokenScopes *string `json:"token_scopes,omitempty"` - Topic *string `json:"topic,omitempty"` - TransportProtocolName *string `json:"transport_protocol_name,omitempty"` // A human readable name for the protocol (for example, HTTP or SSH) used to transfer Git data. - TransportProtocol *int `json:"transport_protocol,omitempty"` // The type of protocol (for example, HTTP=1 or SSH=2) used to transfer Git data. - TriggerID *int64 `json:"trigger_id,omitempty"` - User *string `json:"user,omitempty"` // The user that was affected by the action performed (if available). - UserAgent *string `json:"user_agent,omitempty"` - Visibility *string `json:"visibility,omitempty"` // The repository visibility, for example `public` or `private`. - WorkflowID *int64 `json:"workflow_id,omitempty"` - WorkflowRunID *int64 `json:"workflow_run_id,omitempty"` ->>>>>>> d47936f (Add Referrer field to AuditEntry (#3032)) // Some events types have a data field that contains additional information about the event. Data map[string]interface{} `json:"data,omitempty"` From 3a42286091e7846d4a6477d2de5f3a6b271ade62 Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Sun, 17 Dec 2023 20:32:00 -0500 Subject: [PATCH 13/13] Add missing fields like referrer Signed-off-by: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> --- github/orgs_audit_log_test.go | 84 ++++++++++++++++++++--------------- 1 file changed, 49 insertions(+), 35 deletions(-) diff --git a/github/orgs_audit_log_test.go b/github/orgs_audit_log_test.go index bfe3a52566d..7c8de74c650 100644 --- a/github/orgs_audit_log_test.go +++ b/github/orgs_audit_log_test.go @@ -22,45 +22,43 @@ func TestOrganizationService_GetAuditLog(t *testing.T) { testMethod(t, r, "GET") fmt.Fprint(w, `[ - { + { + "@timestamp": 1615077308538, + "_document_id": "beeZYapIUe-wKg5-beadb33", + "action": "workflows.completed_workflow_run", + "active": true, + "actor": "testactor", "actor_ip": "10.0.0.1", "actor_location": { "country_code": "US" }, - "active": true, - "workflow_id": 123456, - "head_branch": "master", - "org": "o", - "trigger_id": null, - "repo": "o/blue-crayon-1", - "created_at": 1615077308538, + "cancelled_at": "2021-03-07T00:35:08.000Z", + "completed_at": "2021-03-07T00:35:08.000Z", + "conclusion": "success", + "config": { + "content_type": "json", + "insecure_ssl": "0", + "url": "https://example.com/deadbeef-new-hook" + }, + "created_at": 1615077308538, + "event": "schedule", + "events": ["code_scanning_alert"], "hashed_token": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=", - "head_sha": "5acdeadbeef64d1a62388e901e5cdc9358644b37", - "conclusion": "success", - "old_permission": "read", - "permission": "admin", - "actor": "testactor", - "completed_at": "2021-03-07T00:35:08.000Z", - "@timestamp": 1615077308538, - "name": "Code scanning - action", - "action": "workflows.completed_workflow_run", - "started_at": "2021-03-07T00:33:04.000Z", - "event": "schedule", - "workflow_run_id": 628312345, - "_document_id": "beeZYapIUe-wKg5-beadb33", - "run_attempt": 1, - "run_number": 1, - "token_id": 1, - "token_scopes": "gist,repo:read", + "head_branch": "master", + "head_sha": "5acdeadbeef64d1a62388e901e5cdc9358644b37", "job_workflow_ref": "testorg/testrepo/.github/workflows/testjob.yml@refs/pull/1/merge", + "name": "Code scanning - action", "oauth_application_id": 1, + "old_permission": "read", + "org": "o", "org_id": 1, - "pull_request_id": 1, - "pull_request_title": "a pr title", - "pull_request_url": "https://github.com/testorg/testrepo/pull/1", "overridden_codes": [ "review_policy_not_satisfied" ], + "permission": "admin", + "pull_request_id": 1, + "pull_request_title": "a pr title", + "pull_request_url": "https://github.com/testorg/testrepo/pull/1", "reasons": [ { "code": "a code", @@ -68,14 +66,19 @@ func TestOrganizationService_GetAuditLog(t *testing.T) { } ], "programmatic_access_type": "GitHub App server-to-server token", + "referrer": "a referrer", + "repo": "o/blue-crayon-1", + "run_attempt": 1, + "run_number": 1, + "started_at": "2021-03-07T00:33:04.000Z", + "token_id": 1, + "token_scopes": "gist,repo:read", + "topic": "cp1-iad.ingest.github.actions.v0.WorkflowUpdate", + "trigger_id": null, "user_agent": "a user agent", - "config": { - "content_type": "json", - "insecure_ssl": "0", - "url": "https://example.com/deadbeef-new-hook" - }, - "events": ["code_scanning_alert"] - }]`) + "workflow_id": 123456, + "workflow_run_id": 628312345 + }]`) }) ctx := context.Background() getOpts := GetAuditLogOptions{ @@ -108,6 +111,7 @@ func TestOrganizationService_GetAuditLog(t *testing.T) { AdditionalFields: map[string]interface{}{ "actor_ip": "10.0.0.1", "active": true, + "cancelled_at": "2021-03-07T00:35:08.000Z", "completed_at": "2021-03-07T00:35:08.000Z", "conclusion": "success", "event": "schedule", @@ -127,10 +131,12 @@ func TestOrganizationService_GetAuditLog(t *testing.T) { "code": "a code", "message": "a message", }}, + "referrer": "a referrer", "repo": "o/blue-crayon-1", "run_attempt": float64(1), "run_number": float64(1), "started_at": "2021-03-07T00:33:04.000Z", + "topic": "cp1-iad.ingest.github.actions.v0.WorkflowUpdate", "user_agent": "a user agent", "workflow_id": float64(123456), "workflow_run_id": float64(628312345), @@ -241,6 +247,8 @@ func TestAuditEntry_Marshal(t *testing.T) { "active_was": false, "actor_ip": "aip", "blocked_user": "bu", + "cancelled_at": "2021-03-07T00:35:08.000Z", + "completed_at": "2021-03-07T00:35:08.000Z", "conclusion": "c", "config": map[string]interface{}{ "url": "s", @@ -281,6 +289,7 @@ func TestAuditEntry_Marshal(t *testing.T) { "message": "m", }, }, + "referrer": "a referrer", "repo": "r", "repository": "repo", "repository_public": false, @@ -296,6 +305,7 @@ func TestAuditEntry_Marshal(t *testing.T) { "target_login": "tl", "target_version": "tv", "team": "t", + "topic": "cp1-iad.ingest.github.actions.v0.WorkflowUpdate", "transport_protocol": 1, "transport_protocol_name": "tpn", "trigger_id": 1, @@ -317,6 +327,8 @@ func TestAuditEntry_Marshal(t *testing.T) { }, "blocked_user": "bu", "business": "b", + "cancelled_at": "2021-03-07T00:35:08.000Z", + "completed_at": "2021-03-07T00:35:08.000Z", "conclusion": "c", "config": { "url": "s" @@ -365,6 +377,7 @@ func TestAuditEntry_Marshal(t *testing.T) { "code": "c", "message": "m" }], + "referrer": "a referrer", "read_only": "ro", "repo": "r", "repository": "repo", @@ -388,6 +401,7 @@ func TestAuditEntry_Marshal(t *testing.T) { "@timestamp": ` + referenceTimeStr + `, "token_id": 1, "token_scopes": "ts", + "topic": "cp1-iad.ingest.github.actions.v0.WorkflowUpdate", "transport_protocol_name": "tpn", "transport_protocol": 1, "trigger_id": 1,