github.com/google/go-github/v66@v66.0.0/github/orgs_audit_log.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 "encoding/json" 11 "fmt" 12 ) 13 14 // GetAuditLogOptions sets up optional parameters to query audit-log endpoint. 15 type GetAuditLogOptions struct { 16 Phrase *string `url:"phrase,omitempty"` // A search phrase. (Optional.) 17 Include *string `url:"include,omitempty"` // Event type includes. Can be one of "web", "git", "all". Default: "web". (Optional.) 18 Order *string `url:"order,omitempty"` // The order of audit log events. Can be one of "asc" or "desc". Default: "desc". (Optional.) 19 20 ListCursorOptions 21 } 22 23 // ActorLocation contains information about reported location for an actor. 24 type ActorLocation struct { 25 CountryCode *string `json:"country_code,omitempty"` 26 } 27 28 // AuditEntry describes the fields that may be represented by various audit-log "action" entries. 29 // There are many other fields that may be present depending on the action. You can access those 30 // in AdditionalFields. 31 // For a list of actions see - https://docs.github.com/github/setting-up-and-managing-organizations-and-teams/reviewing-the-audit-log-for-your-organization#audit-log-actions 32 type AuditEntry struct { 33 Action *string `json:"action,omitempty"` // The name of the action that was performed, for example `user.login` or `repo.create`. 34 Actor *string `json:"actor,omitempty"` // The actor who performed the action. 35 ActorID *int64 `json:"actor_id,omitempty"` 36 ActorLocation *ActorLocation `json:"actor_location,omitempty"` 37 Business *string `json:"business,omitempty"` 38 BusinessID *int64 `json:"business_id,omitempty"` 39 CreatedAt *Timestamp `json:"created_at,omitempty"` 40 DocumentID *string `json:"_document_id,omitempty"` 41 ExternalIdentityNameID *string `json:"external_identity_nameid,omitempty"` 42 ExternalIdentityUsername *string `json:"external_identity_username,omitempty"` 43 HashedToken *string `json:"hashed_token,omitempty"` 44 Org *string `json:"org,omitempty"` 45 OrgID *int64 `json:"org_id,omitempty"` 46 Timestamp *Timestamp `json:"@timestamp,omitempty"` // The time the audit log event occurred, given as a [Unix timestamp](http://en.wikipedia.org/wiki/Unix_time). 47 TokenID *int64 `json:"token_id,omitempty"` 48 TokenScopes *string `json:"token_scopes,omitempty"` 49 User *string `json:"user,omitempty"` // The user that was affected by the action performed (if available). 50 UserID *int64 `json:"user_id,omitempty"` 51 52 // Some events types have a data field that contains additional information about the event. 53 Data map[string]interface{} `json:"data,omitempty"` 54 55 // All fields that are not explicitly defined in the struct are captured here. 56 AdditionalFields map[string]interface{} `json:"-"` 57 } 58 59 func (a *AuditEntry) UnmarshalJSON(data []byte) error { 60 type entryAlias AuditEntry 61 var v entryAlias 62 if err := json.Unmarshal(data, &v); err != nil { 63 return err 64 } 65 66 rawDefinedFields, err := json.Marshal(v) 67 if err != nil { 68 return err 69 } 70 definedFields := map[string]interface{}{} 71 if err := json.Unmarshal(rawDefinedFields, &definedFields); err != nil { 72 return err 73 } 74 75 if err := json.Unmarshal(data, &v.AdditionalFields); err != nil { 76 return err 77 } 78 79 for key, val := range v.AdditionalFields { 80 if _, ok := definedFields[key]; ok || val == nil { 81 delete(v.AdditionalFields, key) 82 } 83 } 84 85 *a = AuditEntry(v) 86 if len(v.AdditionalFields) == 0 { 87 a.AdditionalFields = nil 88 } 89 return nil 90 } 91 92 func (a *AuditEntry) MarshalJSON() ([]byte, error) { 93 type entryAlias AuditEntry 94 v := entryAlias(*a) 95 defBytes, err := json.Marshal(v) 96 if err != nil { 97 return nil, err 98 } 99 if len(a.AdditionalFields) == 0 { 100 return defBytes, err 101 } 102 resMap := map[string]interface{}{} 103 if err := json.Unmarshal(defBytes, &resMap); err != nil { 104 return nil, err 105 } 106 for key, val := range a.AdditionalFields { 107 if val == nil { 108 continue 109 } 110 if _, ok := resMap[key]; ok { 111 return nil, fmt.Errorf("unexpected field in AdditionalFields: %v", key) 112 } 113 resMap[key] = val 114 } 115 return json.Marshal(resMap) 116 } 117 118 // GetAuditLog gets the audit-log entries for an organization. 119 // 120 // GitHub API docs: https://docs.github.com/enterprise-cloud@latest/rest/orgs/orgs#get-the-audit-log-for-an-organization 121 // 122 //meta:operation GET /orgs/{org}/audit-log 123 func (s *OrganizationsService) GetAuditLog(ctx context.Context, org string, opts *GetAuditLogOptions) ([]*AuditEntry, *Response, error) { 124 u := fmt.Sprintf("orgs/%v/audit-log", org) 125 u, err := addOptions(u, opts) 126 if err != nil { 127 return nil, nil, err 128 } 129 130 req, err := s.client.NewRequest("GET", u, nil) 131 if err != nil { 132 return nil, nil, err 133 } 134 135 var auditEntries []*AuditEntry 136 resp, err := s.client.Do(ctx, req, &auditEntries) 137 if err != nil { 138 return nil, resp, err 139 } 140 141 return auditEntries, resp, nil 142 }