Skip to content

Commit adad347

Browse files
refactor: Refactor audit logs count to support filtering (#4113)
1 parent 6f82ad0 commit adad347

File tree

9 files changed

+164
-13
lines changed

9 files changed

+164
-13
lines changed

coderd/audit.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,20 @@ func (api *API) auditLogCount(rw http.ResponseWriter, r *http.Request) {
6565
return
6666
}
6767

68-
count, err := api.Database.GetAuditLogCount(ctx)
68+
queryStr := r.URL.Query().Get("q")
69+
filter, errs := auditSearchQuery(queryStr)
70+
if len(errs) > 0 {
71+
httpapi.Write(rw, http.StatusBadRequest, codersdk.Response{
72+
Message: "Invalid audit search query.",
73+
Validations: errs,
74+
})
75+
return
76+
}
77+
78+
count, err := api.Database.GetAuditLogCount(ctx, database.GetAuditLogCountParams{
79+
ResourceType: filter.ResourceType,
80+
Action: filter.Action,
81+
})
6982
if err != nil {
7083
httpapi.InternalServerError(rw, err)
7184
return

coderd/audit_test.go

Lines changed: 72 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ func TestAuditLogs(t *testing.T) {
2323
err := client.CreateTestAuditLog(ctx, codersdk.CreateTestAuditLogRequest{})
2424
require.NoError(t, err)
2525

26-
count, err := client.AuditLogCount(ctx)
26+
count, err := client.AuditLogCount(ctx, codersdk.AuditLogCountRequest{})
2727
require.NoError(t, err)
2828

2929
alogs, err := client.AuditLogs(ctx, codersdk.AuditLogsRequest{
@@ -41,7 +41,7 @@ func TestAuditLogs(t *testing.T) {
4141
func TestAuditLogsFilter(t *testing.T) {
4242
t.Parallel()
4343

44-
t.Run("FilterByResourceType", func(t *testing.T) {
44+
t.Run("Filter", func(t *testing.T) {
4545
t.Parallel()
4646

4747
ctx := context.Background()
@@ -110,3 +110,73 @@ func TestAuditLogsFilter(t *testing.T) {
110110
}
111111
})
112112
}
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)
123+
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) {
173+
t.Parallel()
174+
response, err := client.AuditLogCount(ctx, codersdk.AuditLogCountRequest{
175+
SearchQuery: testCase.SearchQuery,
176+
})
177+
require.NoError(t, err, "fetch audit logs count")
178+
require.Equal(t, response.Count, testCase.ExpectedResult, "expected audit logs count returned")
179+
})
180+
}
181+
})
182+
}

coderd/database/databasefake/databasefake.go

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2402,11 +2402,25 @@ func (q *fakeQuerier) GetAuditLogsOffset(ctx context.Context, arg database.GetAu
24022402
return logs, nil
24032403
}
24042404

2405-
func (q *fakeQuerier) GetAuditLogCount(_ context.Context) (int64, error) {
2405+
func (q *fakeQuerier) GetAuditLogCount(_ context.Context, arg database.GetAuditLogCountParams) (int64, error) {
24062406
q.mutex.RLock()
24072407
defer q.mutex.RUnlock()
24082408

2409-
return int64(len(q.auditLogs)), nil
2409+
logs := make([]database.AuditLog, 0)
2410+
2411+
for _, alog := range q.auditLogs {
2412+
if arg.Action != "" && !strings.Contains(string(alog.Action), arg.Action) {
2413+
continue
2414+
}
2415+
2416+
if arg.ResourceType != "" && !strings.Contains(string(alog.ResourceType), arg.ResourceType) {
2417+
continue
2418+
}
2419+
2420+
logs = append(logs, alog)
2421+
}
2422+
2423+
return int64(len(logs)), nil
24102424
}
24112425

24122426
func (q *fakeQuerier) InsertAuditLog(_ context.Context, arg database.InsertAuditLogParams) (database.AuditLog, error) {

coderd/database/querier.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/queries.sql.go

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

coderd/database/queries/auditlogs.sql

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,20 @@ OFFSET
3737
SELECT
3838
COUNT(*) as count
3939
FROM
40-
audit_logs;
40+
audit_logs
41+
WHERE
42+
-- Filter resource_type
43+
CASE
44+
WHEN @resource_type :: text != '' THEN
45+
resource_type = @resource_type :: resource_type
46+
ELSE true
47+
END
48+
-- Filter action
49+
AND CASE
50+
WHEN @action :: text != '' THEN
51+
action = @action :: audit_action
52+
ELSE true
53+
END;
4154

4255
-- name: InsertAuditLog :one
4356
INSERT INTO

codersdk/audit.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ type AuditLogResponse struct {
103103
AuditLogs []AuditLog `json:"audit_logs"`
104104
}
105105

106+
type AuditLogCountRequest struct {
107+
SearchQuery string `json:"q,omitempty"`
108+
}
109+
106110
type AuditLogCountResponse struct {
107111
Count int64 `json:"count"`
108112
}
@@ -142,8 +146,16 @@ func (c *Client) AuditLogs(ctx context.Context, req AuditLogsRequest) (AuditLogR
142146
}
143147

144148
// AuditLogCount returns the count of all audit logs in the product.
145-
func (c *Client) AuditLogCount(ctx context.Context) (AuditLogCountResponse, error) {
146-
res, err := c.Request(ctx, http.MethodGet, "/api/v2/audit/count", nil)
149+
func (c *Client) AuditLogCount(ctx context.Context, req AuditLogCountRequest) (AuditLogCountResponse, error) {
150+
res, err := c.Request(ctx, http.MethodGet, "/api/v2/audit/count", nil, func(r *http.Request) {
151+
q := r.URL.Query()
152+
var params []string
153+
if req.SearchQuery != "" {
154+
params = append(params, req.SearchQuery)
155+
}
156+
q.Set("q", strings.Join(params, " "))
157+
r.URL.RawQuery = q.Encode()
158+
})
147159
if err != nil {
148160
return AuditLogCountResponse{}, err
149161
}

site/src/api/api.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -446,8 +446,14 @@ export const getAuditLogs = async (
446446
return response.data
447447
}
448448

449-
export const getAuditLogsCount = async (): Promise<TypesGen.AuditLogCountResponse> => {
450-
const response = await axios.get(`/api/v2/audit/count`)
449+
export const getAuditLogsCount = async (
450+
options: TypesGen.AuditLogCountRequest = {},
451+
): Promise<TypesGen.AuditLogCountResponse> => {
452+
const searchParams = new URLSearchParams()
453+
if (options.q) {
454+
searchParams.set("q", options.q)
455+
}
456+
const response = await axios.get(`/api/v2/audit/count?${searchParams.toString()}`)
451457
return response.data
452458
}
453459

site/src/api/typesGenerated.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,11 @@ export interface AuditLog {
7676
readonly user?: User
7777
}
7878

79+
// From codersdk/audit.go
80+
export interface AuditLogCountRequest {
81+
readonly q?: string
82+
}
83+
7984
// From codersdk/audit.go
8085
export interface AuditLogCountResponse {
8186
readonly count: number

0 commit comments

Comments
 (0)