github.com/google/go-github/v70@v70.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 17 func TestOrganizationService_GetAuditLog(t *testing.T) { 18 t.Parallel() 19 client, mux, _ := setup(t) 20 21 mux.HandleFunc("/orgs/o/audit-log", func(w http.ResponseWriter, r *http.Request) { 22 testMethod(t, r, "GET") 23 24 fmt.Fprint(w, `[ 25 { 26 "@timestamp": 1615077308538, 27 "_document_id": "beeZYapIUe-wKg5-beadb33", 28 "action": "workflows.completed_workflow_run", 29 "active": true, 30 "actor": "testactor", 31 "actor_ip": "10.0.0.1", 32 "actor_location": { 33 "country_code": "US" 34 }, 35 "cancelled_at": "2021-03-07T00:35:08.000Z", 36 "completed_at": "2021-03-07T00:35:08.000Z", 37 "conclusion": "success", 38 "config": { 39 "content_type": "json", 40 "insecure_ssl": "0", 41 "url": "https://example.com/deadbeef-new-hook" 42 }, 43 "created_at": 1615077308538, 44 "event": "schedule", 45 "events": ["code_scanning_alert"], 46 "hashed_token": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=", 47 "head_branch": "master", 48 "head_sha": "5acdeadbeef64d1a62388e901e5cdc9358644b37", 49 "job_workflow_ref": "testorg/testrepo/.github/workflows/testjob.yml@refs/pull/1/merge", 50 "name": "Code scanning - action", 51 "oauth_application_id": 1, 52 "old_permission": "read", 53 "org": "o", 54 "org_id": 1, 55 "overridden_codes": [ 56 "review_policy_not_satisfied" 57 ], 58 "permission": "admin", 59 "pull_request_id": 1, 60 "pull_request_title": "a pr title", 61 "pull_request_url": "https://github.com/testorg/testrepo/pull/1", 62 "reasons": [ 63 { 64 "code": "a code", 65 "message": "a message" 66 } 67 ], 68 "programmatic_access_type": "GitHub App server-to-server token", 69 "referrer": "a referrer", 70 "repo": "o/blue-crayon-1", 71 "run_attempt": 1, 72 "run_number": 1, 73 "started_at": "2021-03-07T00:33:04.000Z", 74 "token_id": 1, 75 "token_scopes": "gist,repo:read", 76 "topic": "cp1-iad.ingest.github.actions.v0.WorkflowUpdate", 77 "trigger_id": null, 78 "user_agent": "a user agent", 79 "workflow_id": 123456, 80 "workflow_run_id": 628312345 81 }]`) 82 }) 83 ctx := context.Background() 84 getOpts := GetAuditLogOptions{ 85 Include: Ptr("all"), 86 Phrase: Ptr("action:workflows"), 87 Order: Ptr("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 timestamp := time.Unix(0, 1615077308538*1e6) 95 96 want := []*AuditEntry{ 97 { 98 Timestamp: &Timestamp{timestamp}, 99 DocumentID: Ptr("beeZYapIUe-wKg5-beadb33"), 100 Action: Ptr("workflows.completed_workflow_run"), 101 Actor: Ptr("testactor"), 102 ActorLocation: &ActorLocation{ 103 CountryCode: Ptr("US"), 104 }, 105 CreatedAt: &Timestamp{timestamp}, 106 HashedToken: Ptr("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="), 107 Org: Ptr("o"), 108 OrgID: Ptr(int64(1)), 109 TokenID: Ptr(int64(1)), 110 TokenScopes: Ptr("gist,repo:read"), 111 AdditionalFields: map[string]interface{}{ 112 "actor_ip": "10.0.0.1", 113 "active": true, 114 "cancelled_at": "2021-03-07T00:35:08.000Z", 115 "completed_at": "2021-03-07T00:35:08.000Z", 116 "conclusion": "success", 117 "event": "schedule", 118 "head_branch": "master", 119 "head_sha": "5acdeadbeef64d1a62388e901e5cdc9358644b37", 120 "job_workflow_ref": "testorg/testrepo/.github/workflows/testjob.yml@refs/pull/1/merge", 121 "name": "Code scanning - action", 122 "oauth_application_id": float64(1), 123 "old_permission": "read", 124 "overridden_codes": []interface{}{"review_policy_not_satisfied"}, 125 "permission": "admin", 126 "programmatic_access_type": "GitHub App server-to-server token", 127 "pull_request_id": float64(1), 128 "pull_request_title": "a pr title", 129 "pull_request_url": "https://github.com/testorg/testrepo/pull/1", 130 "reasons": []interface{}{map[string]interface{}{ 131 "code": "a code", 132 "message": "a message", 133 }}, 134 "referrer": "a referrer", 135 "repo": "o/blue-crayon-1", 136 "run_attempt": float64(1), 137 "run_number": float64(1), 138 "started_at": "2021-03-07T00:33:04.000Z", 139 "topic": "cp1-iad.ingest.github.actions.v0.WorkflowUpdate", 140 "user_agent": "a user agent", 141 "workflow_id": float64(123456), 142 "workflow_run_id": float64(628312345), 143 "events": []interface{}{"code_scanning_alert"}, 144 "config": map[string]interface{}{ 145 "content_type": "json", 146 "insecure_ssl": "0", 147 "url": "https://example.com/deadbeef-new-hook", 148 }, 149 }, 150 }, 151 } 152 153 assertNoDiff(t, want, auditEntries) 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 testNewRequestAndDoFailureCategory(t, methodName, client, AuditLogCategory, 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 t.Parallel() 178 testJSONMarshal(t, &GetAuditLogOptions{}, "{}") 179 180 u := &GetAuditLogOptions{ 181 Phrase: Ptr("p"), 182 Include: Ptr("i"), 183 Order: Ptr("o"), 184 ListCursorOptions: ListCursorOptions{ 185 Page: "p", 186 PerPage: 1, 187 After: "a", 188 Before: "b", 189 }, 190 } 191 192 want := `{ 193 "phrase": "p", 194 "include": "i", 195 "order": "o", 196 "Page": "p", 197 "PerPage": 1, 198 "After": "a", 199 "Before": "b" 200 }` 201 202 testJSONMarshal(t, u, want) 203 } 204 205 func TestHookConfig_Marshal(t *testing.T) { 206 t.Parallel() 207 testJSONMarshal(t, &HookConfig{}, "{}") 208 209 u := &HookConfig{ 210 ContentType: Ptr("ct"), 211 InsecureSSL: Ptr("ct"), 212 URL: Ptr("url"), 213 } 214 215 want := `{ 216 "content_type": "ct", 217 "insecure_ssl": "ct", 218 "url": "url" 219 }` 220 221 testJSONMarshal(t, u, want) 222 } 223 224 func TestAuditEntry_Marshal(t *testing.T) { 225 t.Parallel() 226 testJSONMarshal(t, &AuditEntry{}, "{}") 227 228 u := &AuditEntry{ 229 Action: Ptr("a"), 230 Actor: Ptr("ac"), 231 ActorLocation: &ActorLocation{CountryCode: Ptr("alcc")}, 232 Business: Ptr("b"), 233 CreatedAt: &Timestamp{referenceTime}, 234 DocumentID: Ptr("did"), 235 ExternalIdentityNameID: Ptr("ein"), 236 ExternalIdentityUsername: Ptr("eiu"), 237 HashedToken: Ptr("ht"), 238 Org: Ptr("o"), 239 OrgID: Ptr(int64(1)), 240 Timestamp: &Timestamp{referenceTime}, 241 TokenID: Ptr(int64(1)), 242 TokenScopes: Ptr("ts"), 243 User: Ptr("u"), 244 Data: map[string]interface{}{ 245 "old_name": "on", 246 "old_login": "ol", 247 }, 248 AdditionalFields: map[string]interface{}{ 249 "active": false, 250 "active_was": false, 251 "actor_ip": "aip", 252 "blocked_user": "bu", 253 "cancelled_at": "2021-03-07T00:35:08.000Z", 254 "completed_at": "2021-03-07T00:35:08.000Z", 255 "conclusion": "c", 256 "config": map[string]interface{}{ 257 "url": "s", 258 }, 259 "config_was": map[string]interface{}{ 260 "url": "s", 261 }, 262 "content_type": "ct", 263 "deploy_key_fingerprint": "dkf", 264 "emoji": "e", 265 "environment_name": "en", 266 "event": "e", 267 "events": []interface{}{"s"}, 268 "events_were": []interface{}{"s"}, 269 "explanation": "e", 270 "fingerprint": "f", 271 "head_branch": "hb", 272 "head_sha": "hsha", 273 "hook_id": float64(1), 274 "is_hosted_runner": false, 275 "job_name": "jn", 276 "limited_availability": false, 277 "message": "m", 278 "name": "n", 279 "old_permission": "op", 280 "old_user": "ou", 281 "openssh_public_key": "osshpk", 282 "permission": "p", 283 "previous_visibility": "pv", 284 "programmatic_access_type": "pat", 285 "pull_request_id": float64(1), 286 "pull_request_title": "prt", 287 "pull_request_url": "pru", 288 "read_only": "ro", 289 "reasons": []interface{}{ 290 map[string]interface{}{ 291 "code": "c", 292 "message": "m", 293 }, 294 }, 295 "referrer": "a referrer", 296 "repo": "r", 297 "repository": "repo", 298 "repository_public": false, 299 "run_attempt": 1, 300 "runner_group_id": 1, 301 "runner_group_name": "rgn", 302 "runner_id": 1, 303 "runner_labels": []interface{}{"s"}, 304 "runner_name": "rn", 305 "secrets_passed": []interface{}{"s"}, 306 "source_version": "sv", 307 "started_at": "2006-01-02T15:04:05Z", 308 "target_login": "tl", 309 "target_version": "tv", 310 "team": "t", 311 "topic": "cp1-iad.ingest.github.actions.v0.WorkflowUpdate", 312 "transport_protocol": 1, 313 "transport_protocol_name": "tpn", 314 "trigger_id": 1, 315 "user_agent": "ua", 316 "visibility": "v", 317 "workflow_id": 1, 318 "workflow_run_id": 1, 319 }, 320 } 321 322 want := `{ 323 "action": "a", 324 "active": false, 325 "active_was": false, 326 "actor": "ac", 327 "actor_ip": "aip", 328 "actor_location": { 329 "country_code": "alcc" 330 }, 331 "blocked_user": "bu", 332 "business": "b", 333 "cancelled_at": "2021-03-07T00:35:08.000Z", 334 "completed_at": "2021-03-07T00:35:08.000Z", 335 "conclusion": "c", 336 "config": { 337 "url": "s" 338 }, 339 "config_was": { 340 "url": "s" 341 }, 342 "content_type": "ct", 343 "created_at": ` + referenceTimeStr + `, 344 "deploy_key_fingerprint": "dkf", 345 "_document_id": "did", 346 "emoji": "e", 347 "environment_name": "en", 348 "event": "e", 349 "events": [ 350 "s" 351 ], 352 "events_were": [ 353 "s" 354 ], 355 "explanation": "e", 356 "external_identity_nameid": "ein", 357 "external_identity_username": "eiu", 358 "fingerprint": "f", 359 "hashed_token": "ht", 360 "head_branch": "hb", 361 "head_sha": "hsha", 362 "hook_id": 1, 363 "is_hosted_runner": false, 364 "job_name": "jn", 365 "limited_availability": false, 366 "message": "m", 367 "name": "n", 368 "old_permission": "op", 369 "old_user": "ou", 370 "openssh_public_key": "osshpk", 371 "org": "o", 372 "org_id": 1, 373 "permission": "p", 374 "previous_visibility": "pv", 375 "programmatic_access_type": "pat", 376 "pull_request_id": 1, 377 "pull_request_title": "prt", 378 "pull_request_url": "pru", 379 "reasons": [{ 380 "code": "c", 381 "message": "m" 382 }], 383 "referrer": "a referrer", 384 "read_only": "ro", 385 "repo": "r", 386 "repository": "repo", 387 "repository_public": false, 388 "run_attempt": 1, 389 "runner_group_id": 1, 390 "runner_group_name": "rgn", 391 "runner_id": 1, 392 "runner_labels": [ 393 "s" 394 ], 395 "runner_name": "rn", 396 "secrets_passed": [ 397 "s" 398 ], 399 "source_version": "sv", 400 "started_at": ` + referenceTimeStr + `, 401 "target_login": "tl", 402 "target_version": "tv", 403 "team": "t", 404 "@timestamp": ` + referenceTimeStr + `, 405 "token_id": 1, 406 "token_scopes": "ts", 407 "topic": "cp1-iad.ingest.github.actions.v0.WorkflowUpdate", 408 "transport_protocol_name": "tpn", 409 "transport_protocol": 1, 410 "trigger_id": 1, 411 "user": "u", 412 "user_agent": "ua", 413 "visibility": "v", 414 "workflow_id": 1, 415 "workflow_run_id": 1, 416 "data": { 417 "old_name": "on", 418 "old_login": "ol" 419 } 420 }` 421 422 testJSONMarshal(t, u, want) 423 }