github.com/google/go-github/v60@v60.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 client, mux, _, teardown := setup() 19 defer teardown() 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: 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 timestamp := time.Unix(0, 1615077308538*1e6) 95 96 want := []*AuditEntry{ 97 { 98 Timestamp: &Timestamp{timestamp}, 99 DocumentID: String("beeZYapIUe-wKg5-beadb33"), 100 Action: String("workflows.completed_workflow_run"), 101 Actor: String("testactor"), 102 ActorLocation: &ActorLocation{ 103 CountryCode: String("US"), 104 }, 105 CreatedAt: &Timestamp{timestamp}, 106 HashedToken: String("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="), 107 Org: String("o"), 108 OrgID: Int64(1), 109 TokenID: Int64(1), 110 TokenScopes: String("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 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 Actor: String("ac"), 228 ActorLocation: &ActorLocation{CountryCode: String("alcc")}, 229 Business: String("b"), 230 CreatedAt: &Timestamp{referenceTime}, 231 DocumentID: String("did"), 232 ExternalIdentityNameID: String("ein"), 233 ExternalIdentityUsername: String("eiu"), 234 HashedToken: String("ht"), 235 Org: String("o"), 236 OrgID: Int64(1), 237 Timestamp: &Timestamp{referenceTime}, 238 TokenID: Int64(1), 239 TokenScopes: String("ts"), 240 User: String("u"), 241 Data: map[string]interface{}{ 242 "old_name": "on", 243 "old_login": "ol", 244 }, 245 AdditionalFields: map[string]interface{}{ 246 "active": false, 247 "active_was": false, 248 "actor_ip": "aip", 249 "blocked_user": "bu", 250 "cancelled_at": "2021-03-07T00:35:08.000Z", 251 "completed_at": "2021-03-07T00:35:08.000Z", 252 "conclusion": "c", 253 "config": map[string]interface{}{ 254 "url": "s", 255 }, 256 "config_was": map[string]interface{}{ 257 "url": "s", 258 }, 259 "content_type": "ct", 260 "deploy_key_fingerprint": "dkf", 261 "emoji": "e", 262 "environment_name": "en", 263 "event": "e", 264 "events": []interface{}{"s"}, 265 "events_were": []interface{}{"s"}, 266 "explanation": "e", 267 "fingerprint": "f", 268 "head_branch": "hb", 269 "head_sha": "hsha", 270 "hook_id": float64(1), 271 "is_hosted_runner": false, 272 "job_name": "jn", 273 "limited_availability": false, 274 "message": "m", 275 "name": "n", 276 "old_permission": "op", 277 "old_user": "ou", 278 "openssh_public_key": "osshpk", 279 "permission": "p", 280 "previous_visibility": "pv", 281 "programmatic_access_type": "pat", 282 "pull_request_id": float64(1), 283 "pull_request_title": "prt", 284 "pull_request_url": "pru", 285 "read_only": "ro", 286 "reasons": []interface{}{ 287 map[string]interface{}{ 288 "code": "c", 289 "message": "m", 290 }, 291 }, 292 "referrer": "a referrer", 293 "repo": "r", 294 "repository": "repo", 295 "repository_public": false, 296 "run_attempt": 1, 297 "runner_group_id": 1, 298 "runner_group_name": "rgn", 299 "runner_id": 1, 300 "runner_labels": []interface{}{"s"}, 301 "runner_name": "rn", 302 "secrets_passed": []interface{}{"s"}, 303 "source_version": "sv", 304 "started_at": "2006-01-02T15:04:05Z", 305 "target_login": "tl", 306 "target_version": "tv", 307 "team": "t", 308 "topic": "cp1-iad.ingest.github.actions.v0.WorkflowUpdate", 309 "transport_protocol": 1, 310 "transport_protocol_name": "tpn", 311 "trigger_id": 1, 312 "user_agent": "ua", 313 "visibility": "v", 314 "workflow_id": 1, 315 "workflow_run_id": 1, 316 }, 317 } 318 319 want := `{ 320 "action": "a", 321 "active": false, 322 "active_was": false, 323 "actor": "ac", 324 "actor_ip": "aip", 325 "actor_location": { 326 "country_code": "alcc" 327 }, 328 "blocked_user": "bu", 329 "business": "b", 330 "cancelled_at": "2021-03-07T00:35:08.000Z", 331 "completed_at": "2021-03-07T00:35:08.000Z", 332 "conclusion": "c", 333 "config": { 334 "url": "s" 335 }, 336 "config_was": { 337 "url": "s" 338 }, 339 "content_type": "ct", 340 "created_at": ` + referenceTimeStr + `, 341 "deploy_key_fingerprint": "dkf", 342 "_document_id": "did", 343 "emoji": "e", 344 "environment_name": "en", 345 "event": "e", 346 "events": [ 347 "s" 348 ], 349 "events_were": [ 350 "s" 351 ], 352 "explanation": "e", 353 "external_identity_nameid": "ein", 354 "external_identity_username": "eiu", 355 "fingerprint": "f", 356 "hashed_token": "ht", 357 "head_branch": "hb", 358 "head_sha": "hsha", 359 "hook_id": 1, 360 "is_hosted_runner": false, 361 "job_name": "jn", 362 "limited_availability": false, 363 "message": "m", 364 "name": "n", 365 "old_permission": "op", 366 "old_user": "ou", 367 "openssh_public_key": "osshpk", 368 "org": "o", 369 "org_id": 1, 370 "permission": "p", 371 "previous_visibility": "pv", 372 "programmatic_access_type": "pat", 373 "pull_request_id": 1, 374 "pull_request_title": "prt", 375 "pull_request_url": "pru", 376 "reasons": [{ 377 "code": "c", 378 "message": "m" 379 }], 380 "referrer": "a referrer", 381 "read_only": "ro", 382 "repo": "r", 383 "repository": "repo", 384 "repository_public": false, 385 "run_attempt": 1, 386 "runner_group_id": 1, 387 "runner_group_name": "rgn", 388 "runner_id": 1, 389 "runner_labels": [ 390 "s" 391 ], 392 "runner_name": "rn", 393 "secrets_passed": [ 394 "s" 395 ], 396 "source_version": "sv", 397 "started_at": ` + referenceTimeStr + `, 398 "target_login": "tl", 399 "target_version": "tv", 400 "team": "t", 401 "@timestamp": ` + referenceTimeStr + `, 402 "token_id": 1, 403 "token_scopes": "ts", 404 "topic": "cp1-iad.ingest.github.actions.v0.WorkflowUpdate", 405 "transport_protocol_name": "tpn", 406 "transport_protocol": 1, 407 "trigger_id": 1, 408 "user": "u", 409 "user_agent": "ua", 410 "visibility": "v", 411 "workflow_id": 1, 412 "workflow_run_id": 1, 413 "data": { 414 "old_name": "on", 415 "old_login": "ol" 416 } 417 }` 418 419 testJSONMarshal(t, u, want) 420 }