github.com/google/go-github/v57@v57.0.0/github/orgs_audit_log_test.go (about) 1 // Copyright 2021 The go-github AUTHORS. All rights reserved. 2 // 3 // `Use` of this source code is governed by a BSD-style 4 // license that can be found in the LICENSE file. 5 6 package github 7 8 import ( 9 "context" 10 "fmt" 11 "net/http" 12 "strings" 13 "testing" 14 "time" 15 16 "github.com/google/go-cmp/cmp" 17 ) 18 19 func TestOrganizationService_GetAuditLog(t *testing.T) { 20 client, mux, _, teardown := setup() 21 defer teardown() 22 23 mux.HandleFunc("/orgs/o/audit-log", func(w http.ResponseWriter, r *http.Request) { 24 testMethod(t, r, "GET") 25 26 fmt.Fprint(w, `[ 27 { 28 "actor_ip": "10.0.0.1", 29 "actor_location": { 30 "country_code": "US" 31 }, 32 "active": true, 33 "workflow_id": 123456, 34 "head_branch": "master", 35 "org": "o", 36 "trigger_id": null, 37 "repo": "o/blue-crayon-1", 38 "created_at": 1615077308538, 39 "hashed_token": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=", 40 "head_sha": "5acdeadbeef64d1a62388e901e5cdc9358644b37", 41 "conclusion": "success", 42 "old_permission": "read", 43 "permission": "admin", 44 "actor": "testactor", 45 "completed_at": "2021-03-07T00:35:08.000Z", 46 "@timestamp": 1615077308538, 47 "name": "Code scanning - action", 48 "action": "workflows.completed_workflow_run", 49 "started_at": "2021-03-07T00:33:04.000Z", 50 "event": "schedule", 51 "workflow_run_id": 628312345, 52 "_document_id": "beeZYapIUe-wKg5-beadb33", 53 "run_attempt": 1, 54 "run_number": 1, 55 "token_id": 1, 56 "token_scopes": "gist,repo:read", 57 "topic": "cp1-iad.ingest.github.actions.v0.WorkflowUpdate", 58 "job_workflow_ref": "testorg/testrepo/.github/workflows/testjob.yml@refs/pull/1/merge", 59 "oauth_application_id": 1, 60 "org_id": 1, 61 "pull_request_id": 1, 62 "pull_request_title": "a pr title", 63 "pull_request_url": "https://github.com/testorg/testrepo/pull/1", 64 "overridden_codes": [ 65 "review_policy_not_satisfied" 66 ], 67 "reasons": [ 68 { 69 "code": "a code", 70 "message": "a message" 71 } 72 ], 73 "programmatic_access_type": "GitHub App server-to-server token", 74 "user_agent": "a user agent", 75 "config": { 76 "content_type": "json", 77 "insecure_ssl": "0", 78 "url": "https://example.com/deadbeef-new-hook" 79 }, 80 "events": ["code_scanning_alert"] 81 }]`) 82 }) 83 ctx := context.Background() 84 getOpts := GetAuditLogOptions{ 85 Include: String("all"), 86 Phrase: String("action:workflows"), 87 Order: String("asc"), 88 } 89 90 auditEntries, resp, err := client.Organizations.GetAuditLog(ctx, "o", &getOpts) 91 if err != nil { 92 t.Errorf("Organizations.GetAuditLog returned error: %v", err) 93 } 94 startedAt, _ := time.Parse(time.RFC3339, "2021-03-07T00:33:04.000Z") 95 completedAt, _ := time.Parse(time.RFC3339, "2021-03-07T00:35:08.000Z") 96 timestamp := time.Unix(0, 1615077308538*1e6) 97 98 want := []*AuditEntry{ 99 { 100 Timestamp: &Timestamp{timestamp}, 101 DocumentID: String("beeZYapIUe-wKg5-beadb33"), 102 Action: String("workflows.completed_workflow_run"), 103 Actor: String("testactor"), 104 ActorIP: String("10.0.0.1"), 105 ActorLocation: &ActorLocation{ 106 CountryCode: String("US"), 107 }, 108 Active: Bool(true), 109 CompletedAt: &Timestamp{completedAt}, 110 Conclusion: String("success"), 111 CreatedAt: &Timestamp{timestamp}, 112 Event: String("schedule"), 113 HashedToken: String("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="), 114 HeadBranch: String("master"), 115 HeadSHA: String("5acdeadbeef64d1a62388e901e5cdc9358644b37"), 116 JobWorkflowRef: String("testorg/testrepo/.github/workflows/testjob.yml@refs/pull/1/merge"), 117 Name: String("Code scanning - action"), 118 OAuthApplicationID: Int64(1), 119 OldPermission: String("read"), 120 Org: String("o"), 121 OrgID: Int64(1), 122 OverriddenCodes: []string{"review_policy_not_satisfied"}, 123 Permission: String("admin"), 124 ProgrammaticAccessType: String("GitHub App server-to-server token"), 125 PullRequestID: Int64(1), 126 PullRequestTitle: String("a pr title"), 127 PullRequestURL: String("https://github.com/testorg/testrepo/pull/1"), 128 Reasons: []*PolicyOverrideReason{{ 129 Code: String("a code"), 130 Message: String("a message"), 131 }}, 132 Repo: String("o/blue-crayon-1"), 133 RunAttempt: Int64(1), 134 RunNumber: Int64(1), 135 StartedAt: &Timestamp{startedAt}, 136 TokenID: Int64(1), 137 TokenScopes: String("gist,repo:read"), 138 Topic: String("cp1-iad.ingest.github.actions.v0.WorkflowUpdate"), 139 UserAgent: String("a user agent"), 140 WorkflowID: Int64(123456), 141 WorkflowRunID: Int64(628312345), 142 Events: []string{"code_scanning_alert"}, 143 Config: &HookConfig{ 144 ContentType: String("json"), 145 InsecureSSL: String("0"), 146 URL: String("https://example.com/deadbeef-new-hook"), 147 }, 148 }, 149 } 150 151 if !cmp.Equal(auditEntries, want) { 152 t.Errorf("Organizations.GetAuditLog return \ngot: %+v,\nwant:%+v", auditEntries, want) 153 } 154 155 // assert query string has lower case params 156 requestedQuery := resp.Request.URL.RawQuery 157 if !strings.Contains(requestedQuery, "phrase") { 158 t.Errorf("Organizations.GetAuditLog query string \ngot: %+v,\nwant:%+v", requestedQuery, "phrase") 159 } 160 161 const methodName = "GetAuditLog" 162 testBadOptions(t, methodName, func() (err error) { 163 _, _, err = client.Organizations.GetAuditLog(ctx, "\n", &getOpts) 164 return err 165 }) 166 167 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 168 got, resp, err := client.Organizations.GetAuditLog(ctx, "o", &GetAuditLogOptions{}) 169 if got != nil { 170 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 171 } 172 return resp, err 173 }) 174 } 175 176 func TestGetAuditLogOptions_Marshal(t *testing.T) { 177 testJSONMarshal(t, &GetAuditLogOptions{}, "{}") 178 179 u := &GetAuditLogOptions{ 180 Phrase: String("p"), 181 Include: String("i"), 182 Order: String("o"), 183 ListCursorOptions: ListCursorOptions{ 184 Page: "p", 185 PerPage: 1, 186 After: "a", 187 Before: "b", 188 }, 189 } 190 191 want := `{ 192 "phrase": "p", 193 "include": "i", 194 "order": "o", 195 "Page": "p", 196 "PerPage": 1, 197 "After": "a", 198 "Before": "b" 199 }` 200 201 testJSONMarshal(t, u, want) 202 } 203 204 func TestHookConfig_Marshal(t *testing.T) { 205 testJSONMarshal(t, &HookConfig{}, "{}") 206 207 u := &HookConfig{ 208 ContentType: String("ct"), 209 InsecureSSL: String("ct"), 210 URL: String("url"), 211 } 212 213 want := `{ 214 "content_type": "ct", 215 "insecure_ssl": "ct", 216 "url": "url" 217 }` 218 219 testJSONMarshal(t, u, want) 220 } 221 222 func TestAuditEntry_Marshal(t *testing.T) { 223 testJSONMarshal(t, &AuditEntry{}, "{}") 224 225 u := &AuditEntry{ 226 Action: String("a"), 227 Active: Bool(false), 228 ActiveWas: Bool(false), 229 Actor: String("ac"), 230 ActorIP: String("aip"), 231 ActorLocation: &ActorLocation{CountryCode: String("alcc")}, 232 BlockedUser: String("bu"), 233 Business: String("b"), 234 CancelledAt: &Timestamp{referenceTime}, 235 CompletedAt: &Timestamp{referenceTime}, 236 Conclusion: String("c"), 237 Config: &HookConfig{URL: String("s")}, 238 ConfigWas: &HookConfig{URL: String("s")}, 239 ContentType: String("ct"), 240 CreatedAt: &Timestamp{referenceTime}, 241 DeployKeyFingerprint: String("dkf"), 242 DocumentID: String("did"), 243 Emoji: String("e"), 244 EnvironmentName: String("en"), 245 Event: String("e"), 246 Events: []string{"s"}, 247 EventsWere: []string{"s"}, 248 Explanation: String("e"), 249 ExternalIdentityNameID: String("ein"), 250 ExternalIdentityUsername: String("eiu"), 251 Fingerprint: String("f"), 252 HashedToken: String("ht"), 253 HeadBranch: String("hb"), 254 HeadSHA: String("hsha"), 255 HookID: Int64(1), 256 IsHostedRunner: Bool(false), 257 JobName: String("jn"), 258 LimitedAvailability: Bool(false), 259 Message: String("m"), 260 Name: String("n"), 261 OldPermission: String("op"), 262 OldUser: String("ou"), 263 OpenSSHPublicKey: String("osshpk"), 264 Org: String("o"), 265 OrgID: Int64(1), 266 Permission: String("p"), 267 PreviousVisibility: String("pv"), 268 ProgrammaticAccessType: String("pat"), 269 PullRequestID: Int64(1), 270 PullRequestTitle: String("prt"), 271 PullRequestURL: String("pru"), 272 Reasons: []*PolicyOverrideReason{{ 273 Code: String("c"), 274 Message: String("m"), 275 }}, 276 ReadOnly: String("ro"), 277 Repo: String("r"), 278 Repository: String("repo"), 279 RepositoryPublic: Bool(false), 280 RunAttempt: Int64(1), 281 RunnerGroupID: Int64(1), 282 RunnerGroupName: String("rgn"), 283 RunnerID: Int64(1), 284 RunnerLabels: []string{"s"}, 285 RunnerName: String("rn"), 286 SecretsPassed: []string{"s"}, 287 SourceVersion: String("sv"), 288 StartedAt: &Timestamp{referenceTime}, 289 TargetLogin: String("tl"), 290 TargetVersion: String("tv"), 291 Team: String("t"), 292 Timestamp: &Timestamp{referenceTime}, 293 TokenID: Int64(1), 294 TokenScopes: String("ts"), 295 Topic: String("tp"), 296 TransportProtocolName: String("tpn"), 297 TransportProtocol: Int(1), 298 TriggerID: Int64(1), 299 User: String("u"), 300 UserAgent: String("ua"), 301 Visibility: String("v"), 302 WorkflowID: Int64(1), 303 WorkflowRunID: Int64(1), 304 Data: &AuditEntryData{ 305 OldName: String("on"), 306 OldLogin: String("ol"), 307 }, 308 } 309 310 want := `{ 311 "action": "a", 312 "active": false, 313 "active_was": false, 314 "actor": "ac", 315 "actor_ip": "aip", 316 "actor_location": { 317 "country_code": "alcc" 318 }, 319 "blocked_user": "bu", 320 "business": "b", 321 "cancelled_at": ` + referenceTimeStr + `, 322 "completed_at": ` + referenceTimeStr + `, 323 "conclusion": "c", 324 "config": { 325 "url": "s" 326 }, 327 "config_was": { 328 "url": "s" 329 }, 330 "content_type": "ct", 331 "created_at": ` + referenceTimeStr + `, 332 "deploy_key_fingerprint": "dkf", 333 "_document_id": "did", 334 "emoji": "e", 335 "environment_name": "en", 336 "event": "e", 337 "events": [ 338 "s" 339 ], 340 "events_were": [ 341 "s" 342 ], 343 "explanation": "e", 344 "external_identity_nameid": "ein", 345 "external_identity_username": "eiu", 346 "fingerprint": "f", 347 "hashed_token": "ht", 348 "head_branch": "hb", 349 "head_sha": "hsha", 350 "hook_id": 1, 351 "is_hosted_runner": false, 352 "job_name": "jn", 353 "limited_availability": false, 354 "message": "m", 355 "name": "n", 356 "old_permission": "op", 357 "old_user": "ou", 358 "openssh_public_key": "osshpk", 359 "org": "o", 360 "org_id": 1, 361 "permission": "p", 362 "previous_visibility": "pv", 363 "programmatic_access_type": "pat", 364 "pull_request_id": 1, 365 "pull_request_title": "prt", 366 "pull_request_url": "pru", 367 "reasons": [{ 368 "code": "c", 369 "message": "m" 370 }], 371 "read_only": "ro", 372 "repo": "r", 373 "repository": "repo", 374 "repository_public": false, 375 "run_attempt": 1, 376 "runner_group_id": 1, 377 "runner_group_name": "rgn", 378 "runner_id": 1, 379 "runner_labels": [ 380 "s" 381 ], 382 "runner_name": "rn", 383 "secrets_passed": [ 384 "s" 385 ], 386 "source_version": "sv", 387 "started_at": ` + referenceTimeStr + `, 388 "target_login": "tl", 389 "target_version": "tv", 390 "team": "t", 391 "@timestamp": ` + referenceTimeStr + `, 392 "token_id": 1, 393 "token_scopes": "ts", 394 "topic": "tp", 395 "transport_protocol_name": "tpn", 396 "transport_protocol": 1, 397 "trigger_id": 1, 398 "user": "u", 399 "user_agent": "ua", 400 "visibility": "v", 401 "workflow_id": 1, 402 "workflow_run_id": 1, 403 "data": { 404 "old_name": "on", 405 "old_login": "ol" 406 } 407 }` 408 409 testJSONMarshal(t, u, want) 410 }