-
Notifications
You must be signed in to change notification settings - Fork 10
/
audit_logs.go
144 lines (117 loc) · 5.01 KB
/
audit_logs.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package planetscale
import (
"context"
"fmt"
"net/http"
"time"
"github.com/pkg/errors"
)
// AuditLogEvent represents an audit log's event type
type AuditLogEvent string
const (
AuditLogEventBranchCreated AuditLogEvent = "branch.created"
AuditLogEventBranchDeleted AuditLogEvent = "branch.deleted"
AuditLogEventDatabaseCreated AuditLogEvent = "database.created"
AuditLogEventDatabaseDeleted AuditLogEvent = "database.deleted"
AuditLogEventDeployRequestApproved AuditLogEvent = "deploy_request.approved"
AuditLogEventDeployRequestClosed AuditLogEvent = "deploy_request.closed"
AuditLogEventDeployRequestCreated AuditLogEvent = "deploy_request.created"
AuditLogEventDeployRequestDeleted AuditLogEvent = "deploy_request.deleted"
AuditLogEventDeployRequestQueued AuditLogEvent = "deploy_request.queued"
AuditLogEventDeployRequestUnqueued AuditLogEvent = "deploy_request.unqueued"
AuditLogEventIntegrationCreated AuditLogEvent = "integration.created"
AuditLogEventIntegrationDeleted AuditLogEvent = "integration.deleted"
AuditLogEventOrganizationInvitationCreated AuditLogEvent = "organization_invitation.created"
AuditLogEventOrganizationInvitationDeleted AuditLogEvent = "organization_invitation.deleted"
AuditLogEventOrganizationMembershipCreated AuditLogEvent = "organization_membership.created"
AuditLogEventOrganizationJoined AuditLogEvent = "organization.joined"
AuditLogEventOrganizationRemovedMember AuditLogEvent = "organization.removed_member"
AuditLogEventOrganizationDisabledSSO AuditLogEvent = "organization.disabled_sso"
AuditLogEventOrganizationEnabledSSO AuditLogEvent = "organization.enabled_sso"
AuditLogEventOrganizationUpdatedRole AuditLogEvent = "organization.updated_role"
AuditLogEventServiceTokenCreated AuditLogEvent = "service_token.created"
AuditLogEventServiceTokenDeleted AuditLogEvent = "service_token.deleted"
AuditLogEventServiceTokenGrantedAccess AuditLogEvent = "service_token.granted_access"
)
var _ AuditLogsService = &auditlogsService{}
// AuditLogsService is an interface for communicating with the PlanetScale
// AuditLogs API endpoints.
type AuditLogsService interface {
List(context.Context, *ListAuditLogsRequest, ...ListOption) (*CursorPaginatedResponse[*AuditLog], error)
}
// ListAuditLogsRequest encapsulates the request for listing the audit logs of
// an organization.
type ListAuditLogsRequest struct {
Organization string
// Events can be used to filter out only the given audit log events.
Events []AuditLogEvent
}
// AuditLog represents a PlanetScale audit log.
type AuditLog struct {
ID string `json:"id"`
Type string `json:"type"`
ActorID string `json:"actor_id"`
ActorType string `json:"actor_type"`
ActorDisplayName string `json:"actor_display_name"`
AuditableID string `json:"auditable_id"`
AuditableType string `json:"auditable_type"`
AuditableDisplayName string `json:"auditable_display_name"`
AuditAction string `json:"audit_action"`
Action string `json:"action"`
Location string `json:"location"`
RemoteIP string `json:"remote_ip"`
TargetID string `json:"target_id"`
TargetType string `json:"target_type"`
TargetDisplayName string `json:"target_display_name"`
Metadata map[string]interface{} `json:"metadata"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
type auditlogsService struct {
client *Client
}
func NewAuditLogsService(client *Client) *auditlogsService {
return &auditlogsService{
client: client,
}
}
// WithEventFilters sets filters on a set of list filters from audit log events.
// For example, `audit_action:database.created`,
// `audit_action:database.deleted`, etc.
func WithEventFilters(events []AuditLogEvent) ListOption {
return func(opt *ListOptions) error {
values := opt.URLValues
if len(events) != 0 {
for _, action := range events {
values.Add("filters[]", fmt.Sprintf("audit_action:%s", action))
}
}
return nil
}
}
// List returns the audit logs for an organization.
func (o *auditlogsService) List(ctx context.Context, listReq *ListAuditLogsRequest, opts ...ListOption) (*CursorPaginatedResponse[*AuditLog], error) {
if listReq.Organization == "" {
return nil, errors.New("organization is not set")
}
path := auditlogsAPIPath(listReq.Organization)
defaultOpts := defaultListOptions(WithEventFilters(listReq.Events))
for _, opt := range opts {
opt(defaultOpts)
}
if vals := defaultOpts.URLValues.Encode(); vals != "" {
path += "?" + vals
}
req, err := o.client.newRequest(http.MethodGet, path, nil)
if err != nil {
return nil, errors.Wrap(err, "error creating request for listing audit logs")
}
resp := &CursorPaginatedResponse[*AuditLog]{}
if err := o.client.do(ctx, req, &resp); err != nil {
return nil, err
}
return resp, nil
}
func auditlogsAPIPath(org string) string {
return fmt.Sprintf("%s/%s/audit-log", organizationsAPIPath, org)
}