github.com/google/go-github/v68@v68.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  }