1
2
3
4
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
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 Fingerprint: String("f"),
250 HashedToken: String("ht"),
251 HeadBranch: String("hb"),
252 HeadSHA: String("hsha"),
253 HookID: Int64(1),
254 IsHostedRunner: Bool(false),
255 JobName: String("jn"),
256 LimitedAvailability: Bool(false),
257 Message: String("m"),
258 Name: String("n"),
259 OldPermission: String("op"),
260 OldUser: String("ou"),
261 OpenSSHPublicKey: String("osshpk"),
262 Org: String("o"),
263 OrgID: Int64(1),
264 Permission: String("p"),
265 PreviousVisibility: String("pv"),
266 ProgrammaticAccessType: String("pat"),
267 PullRequestID: Int64(1),
268 PullRequestTitle: String("prt"),
269 PullRequestURL: String("pru"),
270 Reasons: []*PolicyOverrideReason{{
271 Code: String("c"),
272 Message: String("m"),
273 }},
274 ReadOnly: String("ro"),
275 Repo: String("r"),
276 Repository: String("repo"),
277 RepositoryPublic: Bool(false),
278 RunAttempt: Int64(1),
279 RunnerGroupID: Int64(1),
280 RunnerGroupName: String("rgn"),
281 RunnerID: Int64(1),
282 RunnerLabels: []string{"s"},
283 RunnerName: String("rn"),
284 SecretsPassed: []string{"s"},
285 SourceVersion: String("sv"),
286 StartedAt: &Timestamp{referenceTime},
287 TargetLogin: String("tl"),
288 TargetVersion: String("tv"),
289 Team: String("t"),
290 Timestamp: &Timestamp{referenceTime},
291 TokenID: Int64(1),
292 TokenScopes: String("ts"),
293 Topic: String("tp"),
294 TransportProtocolName: String("tpn"),
295 TransportProtocol: Int(1),
296 TriggerID: Int64(1),
297 User: String("u"),
298 UserAgent: String("ua"),
299 Visibility: String("v"),
300 WorkflowID: Int64(1),
301 WorkflowRunID: Int64(1),
302 Data: &AuditEntryData{
303 OldName: String("on"),
304 OldLogin: String("ol"),
305 },
306 }
307
308 want := `{
309 "action": "a",
310 "active": false,
311 "active_was": false,
312 "actor": "ac",
313 "actor_ip": "aip",
314 "actor_location": {
315 "country_code": "alcc"
316 },
317 "blocked_user": "bu",
318 "business": "b",
319 "cancelled_at": ` + referenceTimeStr + `,
320 "completed_at": ` + referenceTimeStr + `,
321 "conclusion": "c",
322 "config": {
323 "url": "s"
324 },
325 "config_was": {
326 "url": "s"
327 },
328 "content_type": "ct",
329 "created_at": ` + referenceTimeStr + `,
330 "deploy_key_fingerprint": "dkf",
331 "_document_id": "did",
332 "emoji": "e",
333 "environment_name": "en",
334 "event": "e",
335 "events": [
336 "s"
337 ],
338 "events_were": [
339 "s"
340 ],
341 "explanation": "e",
342 "fingerprint": "f",
343 "hashed_token": "ht",
344 "head_branch": "hb",
345 "head_sha": "hsha",
346 "hook_id": 1,
347 "is_hosted_runner": false,
348 "job_name": "jn",
349 "limited_availability": false,
350 "message": "m",
351 "name": "n",
352 "old_permission": "op",
353 "old_user": "ou",
354 "openssh_public_key": "osshpk",
355 "org": "o",
356 "org_id": 1,
357 "permission": "p",
358 "previous_visibility": "pv",
359 "programmatic_access_type": "pat",
360 "pull_request_id": 1,
361 "pull_request_title": "prt",
362 "pull_request_url": "pru",
363 "reasons": [{
364 "code": "c",
365 "message": "m"
366 }],
367 "read_only": "ro",
368 "repo": "r",
369 "repository": "repo",
370 "repository_public": false,
371 "run_attempt": 1,
372 "runner_group_id": 1,
373 "runner_group_name": "rgn",
374 "runner_id": 1,
375 "runner_labels": [
376 "s"
377 ],
378 "runner_name": "rn",
379 "secrets_passed": [
380 "s"
381 ],
382 "source_version": "sv",
383 "started_at": ` + referenceTimeStr + `,
384 "target_login": "tl",
385 "target_version": "tv",
386 "team": "t",
387 "@timestamp": ` + referenceTimeStr + `,
388 "token_id": 1,
389 "token_scopes": "ts",
390 "topic": "tp",
391 "transport_protocol_name": "tpn",
392 "transport_protocol": 1,
393 "trigger_id": 1,
394 "user": "u",
395 "user_agent": "ua",
396 "visibility": "v",
397 "workflow_id": 1,
398 "workflow_run_id": 1,
399 "data": {
400 "old_name": "on",
401 "old_login": "ol"
402 }
403 }`
404
405 testJSONMarshal(t, u, want)
406 }
407
View as plain text