Skip to content

Commit bc47d7c

Browse files
feat: Add extra fields to the audit filter (coder#4123)
1 parent 3618b09 commit bc47d7c

File tree

7 files changed

+198
-82
lines changed

7 files changed

+198
-82
lines changed

coderd/audit.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,10 @@ func (api *API) auditLogs(rw http.ResponseWriter, r *http.Request) {
4646
Offset: int32(page.Offset),
4747
Limit: int32(page.Limit),
4848
ResourceType: filter.ResourceType,
49+
ResourceID: filter.ResourceID,
4950
Action: filter.Action,
51+
Username: filter.Username,
52+
Email: filter.Email,
5053
})
5154
if err != nil {
5255
httpapi.InternalServerError(rw, err)
@@ -77,7 +80,10 @@ func (api *API) auditLogCount(rw http.ResponseWriter, r *http.Request) {
7780

7881
count, err := api.Database.GetAuditLogCount(ctx, database.GetAuditLogCountParams{
7982
ResourceType: filter.ResourceType,
83+
ResourceID: filter.ResourceID,
8084
Action: filter.Action,
85+
Username: filter.Username,
86+
Email: filter.Email,
8187
})
8288
if err != nil {
8389
httpapi.InternalServerError(rw, err)
@@ -134,6 +140,9 @@ func (api *API) generateFakeAuditLog(rw http.ResponseWriter, r *http.Request) {
134140
if params.ResourceType == "" {
135141
params.ResourceType = codersdk.ResourceTypeUser
136142
}
143+
if params.ResourceID == uuid.Nil {
144+
params.ResourceID = uuid.New()
145+
}
137146

138147
_, err = api.Database.InsertAuditLog(ctx, database.InsertAuditLogParams{
139148
ID: uuid.New(),
@@ -142,7 +151,7 @@ func (api *API) generateFakeAuditLog(rw http.ResponseWriter, r *http.Request) {
142151
Ip: ipNet,
143152
UserAgent: r.UserAgent(),
144153
ResourceType: database.ResourceType(params.ResourceType),
145-
ResourceID: user.ID,
154+
ResourceID: params.ResourceID,
146155
ResourceTarget: user.Username,
147156
Action: database.AuditAction(params.Action),
148157
Diff: diff,
@@ -251,7 +260,10 @@ func auditSearchQuery(query string) (database.GetAuditLogsOffsetParams, []coders
251260
parser := httpapi.NewQueryParamParser()
252261
filter := database.GetAuditLogsOffsetParams{
253262
ResourceType: parser.String(searchParams, "", "resource_type"),
263+
ResourceID: parser.UUID(searchParams, uuid.Nil, "resource_id"),
254264
Action: parser.String(searchParams, "", "action"),
265+
Username: parser.String(searchParams, "", "username"),
266+
Email: parser.String(searchParams, "", "email"),
255267
}
256268

257269
return filter, parser.Errors

coderd/audit_test.go

Lines changed: 23 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"testing"
66

7+
"github.com/google/uuid"
78
"github.com/stretchr/testify/require"
89

910
"github.com/coder/coder/coderd/coderdtest"
@@ -47,6 +48,7 @@ func TestAuditLogsFilter(t *testing.T) {
4748
ctx := context.Background()
4849
client := coderdtest.New(t, nil)
4950
_ = coderdtest.CreateFirstUser(t, client)
51+
userResourceID := uuid.New()
5052

5153
// Create two logs with "Create"
5254
err := client.CreateTestAuditLog(ctx, codersdk.CreateTestAuditLogRequest{
@@ -57,13 +59,15 @@ func TestAuditLogsFilter(t *testing.T) {
5759
err = client.CreateTestAuditLog(ctx, codersdk.CreateTestAuditLogRequest{
5860
Action: codersdk.AuditActionCreate,
5961
ResourceType: codersdk.ResourceTypeUser,
62+
ResourceID: userResourceID,
6063
})
6164
require.NoError(t, err)
6265

6366
// Create one log with "Delete"
6467
err = client.CreateTestAuditLog(ctx, codersdk.CreateTestAuditLogRequest{
6568
Action: codersdk.AuditActionDelete,
6669
ResourceType: codersdk.ResourceTypeUser,
70+
ResourceID: userResourceID,
6771
})
6872
require.NoError(t, err)
6973

@@ -93,9 +97,25 @@ func TestAuditLogsFilter(t *testing.T) {
9397
SearchQuery: "resource_type:template",
9498
ExpectedResult: 1,
9599
},
100+
{
101+
Name: "FilterByEmail",
102+
SearchQuery: "email:" + coderdtest.FirstUserParams.Email,
103+
ExpectedResult: 3,
104+
},
105+
{
106+
Name: "FilterByUsername",
107+
SearchQuery: "username:" + coderdtest.FirstUserParams.Username,
108+
ExpectedResult: 3,
109+
},
110+
{
111+
Name: "FilterByResourceID",
112+
SearchQuery: "resource_id:" + userResourceID.String(),
113+
ExpectedResult: 2,
114+
},
96115
}
97116

98117
for _, testCase := range testCases {
118+
// Test filtering
99119
t.Run(testCase.Name, func(t *testing.T) {
100120
t.Parallel()
101121
auditLogs, err := client.AuditLogs(ctx, codersdk.AuditLogsRequest{
@@ -107,75 +127,15 @@ func TestAuditLogsFilter(t *testing.T) {
107127
require.NoError(t, err, "fetch audit logs")
108128
require.Len(t, auditLogs.AuditLogs, testCase.ExpectedResult, "expected audit logs returned")
109129
})
110-
}
111-
})
112-
}
113-
114-
func TestAuditLogCountFilter(t *testing.T) {
115-
t.Parallel()
116-
117-
t.Run("Filter", func(t *testing.T) {
118-
t.Parallel()
119-
120-
ctx := context.Background()
121-
client := coderdtest.New(t, nil)
122-
_ = coderdtest.CreateFirstUser(t, client)
123130

124-
// Create two logs with "Create"
125-
err := client.CreateTestAuditLog(ctx, codersdk.CreateTestAuditLogRequest{
126-
Action: codersdk.AuditActionCreate,
127-
ResourceType: codersdk.ResourceTypeTemplate,
128-
})
129-
require.NoError(t, err)
130-
err = client.CreateTestAuditLog(ctx, codersdk.CreateTestAuditLogRequest{
131-
Action: codersdk.AuditActionCreate,
132-
ResourceType: codersdk.ResourceTypeUser,
133-
})
134-
require.NoError(t, err)
135-
136-
// Create one log with "Delete"
137-
err = client.CreateTestAuditLog(ctx, codersdk.CreateTestAuditLogRequest{
138-
Action: codersdk.AuditActionDelete,
139-
ResourceType: codersdk.ResourceTypeUser,
140-
})
141-
require.NoError(t, err)
142-
143-
// Test cases
144-
testCases := []struct {
145-
Name string
146-
SearchQuery string
147-
ExpectedResult int64
148-
}{
149-
{
150-
Name: "FilterByCreateAction",
151-
SearchQuery: "action:create",
152-
ExpectedResult: 2,
153-
},
154-
{
155-
Name: "FilterByDeleteAction",
156-
SearchQuery: "action:delete",
157-
ExpectedResult: 1,
158-
},
159-
{
160-
Name: "FilterByUserResourceType",
161-
SearchQuery: "resource_type:user",
162-
ExpectedResult: 2,
163-
},
164-
{
165-
Name: "FilterByTemplateResourceType",
166-
SearchQuery: "resource_type:template",
167-
ExpectedResult: 1,
168-
},
169-
}
170-
171-
for _, testCase := range testCases {
172-
t.Run(testCase.Name, func(t *testing.T) {
131+
// Test count filtering
132+
t.Run("GetCount"+testCase.Name, func(t *testing.T) {
173133
t.Parallel()
174134
response, err := client.AuditLogCount(ctx, codersdk.AuditLogCountRequest{
175135
SearchQuery: testCase.SearchQuery,
176136
})
177137
require.NoError(t, err, "fetch audit logs count")
178-
require.Equal(t, response.Count, testCase.ExpectedResult, "expected audit logs count returned")
138+
require.Equal(t, int(response.Count), testCase.ExpectedResult, "expected audit logs count returned")
179139
})
180140
}
181141
})

coderd/database/databasefake/databasefake.go

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2388,14 +2388,27 @@ func (q *fakeQuerier) GetAuditLogsOffset(ctx context.Context, arg database.GetAu
23882388
arg.Offset--
23892389
continue
23902390
}
2391-
23922391
if arg.Action != "" && !strings.Contains(string(alog.Action), arg.Action) {
23932392
continue
23942393
}
2395-
23962394
if arg.ResourceType != "" && !strings.Contains(string(alog.ResourceType), arg.ResourceType) {
23972395
continue
23982396
}
2397+
if arg.ResourceID != uuid.Nil && alog.ResourceID != arg.ResourceID {
2398+
continue
2399+
}
2400+
if arg.Username != "" {
2401+
user, err := q.GetUserByID(context.Background(), alog.UserID)
2402+
if err == nil && !strings.EqualFold(arg.Username, user.Username) {
2403+
continue
2404+
}
2405+
}
2406+
if arg.Email != "" {
2407+
user, err := q.GetUserByID(context.Background(), alog.UserID)
2408+
if err == nil && !strings.EqualFold(arg.Email, user.Email) {
2409+
continue
2410+
}
2411+
}
23992412

24002413
user, err := q.GetUserByID(ctx, alog.UserID)
24012414
userValid := err == nil
@@ -2440,10 +2453,24 @@ func (q *fakeQuerier) GetAuditLogCount(_ context.Context, arg database.GetAuditL
24402453
if arg.Action != "" && !strings.Contains(string(alog.Action), arg.Action) {
24412454
continue
24422455
}
2443-
24442456
if arg.ResourceType != "" && !strings.Contains(string(alog.ResourceType), arg.ResourceType) {
24452457
continue
24462458
}
2459+
if arg.ResourceID != uuid.Nil && alog.ResourceID != arg.ResourceID {
2460+
continue
2461+
}
2462+
if arg.Username != "" {
2463+
user, err := q.GetUserByID(context.Background(), alog.UserID)
2464+
if err == nil && !strings.EqualFold(arg.Username, user.Username) {
2465+
continue
2466+
}
2467+
}
2468+
if arg.Email != "" {
2469+
user, err := q.GetUserByID(context.Background(), alog.UserID)
2470+
if err == nil && !strings.EqualFold(arg.Email, user.Email) {
2471+
continue
2472+
}
2473+
}
24472474

24482475
logs = append(logs, alog)
24492476
}

coderd/database/queries.sql.go

Lines changed: 80 additions & 13 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)