github.com/google/go-github/v74@v74.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]any `json:"data,omitempty"`
    54  
    55  	// All fields that are not explicitly defined in the struct are captured here.
    56  	AdditionalFields map[string]any `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]any{}
    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]any{}
   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  }