Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a73dd4f

Browse files
Audit date filter/kira pilot (#4845)
* sql query * added time_to * added validation error * documentation * attempt to add test * removed whiitespace * fix: ensure date_from and date_to are applied correct audit logs * added more tests * ran make gen * PR feedback Co-authored-by: Dean Sheather <[email protected]>
1 parent 6bfdccd commit a73dd4f

File tree

9 files changed

+131
-3
lines changed

9 files changed

+131
-3
lines changed

coderd/audit.go

+29-1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ func (api *API) auditLogs(rw http.ResponseWriter, r *http.Request) {
5050
Action: filter.Action,
5151
Username: filter.Username,
5252
Email: filter.Email,
53+
DateFrom: filter.DateFrom,
54+
DateTo: filter.DateTo,
5355
})
5456
if err != nil {
5557
httpapi.InternalServerError(rw, err)
@@ -84,6 +86,8 @@ func (api *API) auditLogCount(rw http.ResponseWriter, r *http.Request) {
8486
Action: filter.Action,
8587
Username: filter.Username,
8688
Email: filter.Email,
89+
DateFrom: filter.DateFrom,
90+
DateTo: filter.DateTo,
8791
})
8892
if err != nil {
8993
httpapi.InternalServerError(rw, err)
@@ -142,10 +146,13 @@ func (api *API) generateFakeAuditLog(rw http.ResponseWriter, r *http.Request) {
142146
if params.ResourceID == uuid.Nil {
143147
params.ResourceID = uuid.New()
144148
}
149+
if params.Time.IsZero() {
150+
params.Time = time.Now()
151+
}
145152

146153
_, err = api.Database.InsertAuditLog(ctx, database.InsertAuditLogParams{
147154
ID: uuid.New(),
148-
Time: time.Now(),
155+
Time: params.Time,
149156
UserID: user.ID,
150157
Ip: ipNet,
151158
UserAgent: r.UserAgent(),
@@ -273,12 +280,33 @@ func auditSearchQuery(query string) (database.GetAuditLogsOffsetParams, []coders
273280
// Using the query param parser here just returns consistent errors with
274281
// other parsing.
275282
parser := httpapi.NewQueryParamParser()
283+
const layout = "2006-01-02"
284+
285+
var (
286+
dateFromString = parser.String(searchParams, "", "date_from")
287+
dateToString = parser.String(searchParams, "", "date_to")
288+
parsedDateFrom, _ = time.Parse(layout, dateFromString)
289+
parsedDateTo, _ = time.Parse(layout, dateToString)
290+
)
291+
292+
if dateToString != "" {
293+
parsedDateTo = parsedDateTo.Add(23*time.Hour + 59*time.Minute + 59*time.Second) // parsedDateTo goes to 23:59
294+
}
295+
296+
if dateToString != "" && parsedDateTo.Before(parsedDateFrom) {
297+
return database.GetAuditLogsOffsetParams{}, []codersdk.ValidationError{
298+
{Field: "q", Detail: fmt.Sprintf("DateTo value %q cannot be before than DateFrom", parsedDateTo)},
299+
}
300+
}
301+
276302
filter := database.GetAuditLogsOffsetParams{
277303
ResourceType: resourceTypeFromString(parser.String(searchParams, "", "resource_type")),
278304
ResourceID: parser.UUID(searchParams, uuid.Nil, "resource_id"),
279305
Action: actionFromString(parser.String(searchParams, "", "action")),
280306
Username: parser.String(searchParams, "", "username"),
281307
Email: parser.String(searchParams, "", "email"),
308+
DateFrom: parsedDateFrom,
309+
DateTo: parsedDateTo,
282310
}
283311

284312
return filter, parser.Errors

coderd/audit_test.go

+19
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package coderd_test
33
import (
44
"context"
55
"testing"
6+
"time"
67

78
"github.com/google/uuid"
89
"github.com/stretchr/testify/require"
@@ -54,12 +55,14 @@ func TestAuditLogsFilter(t *testing.T) {
5455
err := client.CreateTestAuditLog(ctx, codersdk.CreateTestAuditLogRequest{
5556
Action: codersdk.AuditActionCreate,
5657
ResourceType: codersdk.ResourceTypeTemplate,
58+
Time: time.Date(2022, 8, 15, 14, 30, 45, 100, time.UTC), // 2022-8-15 14:30:45
5759
})
5860
require.NoError(t, err)
5961
err = client.CreateTestAuditLog(ctx, codersdk.CreateTestAuditLogRequest{
6062
Action: codersdk.AuditActionCreate,
6163
ResourceType: codersdk.ResourceTypeUser,
6264
ResourceID: userResourceID,
65+
Time: time.Date(2022, 8, 16, 14, 30, 45, 100, time.UTC), // 2022-8-16 14:30:45
6366
})
6467
require.NoError(t, err)
6568

@@ -68,6 +71,7 @@ func TestAuditLogsFilter(t *testing.T) {
6871
Action: codersdk.AuditActionDelete,
6972
ResourceType: codersdk.ResourceTypeUser,
7073
ResourceID: userResourceID,
74+
Time: time.Date(2022, 8, 15, 14, 30, 45, 100, time.UTC), // 2022-8-15 14:30:45
7175
})
7276
require.NoError(t, err)
7377

@@ -127,6 +131,21 @@ func TestAuditLogsFilter(t *testing.T) {
127131
SearchQuery: "action:invalid",
128132
ExpectedResult: 3,
129133
},
134+
{
135+
Name: "FilterOnCreateSingleDay",
136+
SearchQuery: "action:create date_from:2022-08-15 date_to:2022-08-15",
137+
ExpectedResult: 1,
138+
},
139+
{
140+
Name: "FilterOnCreateDateFrom",
141+
SearchQuery: "action:create date_from:2022-08-15",
142+
ExpectedResult: 2,
143+
},
144+
{
145+
Name: "FilterOnCreateDateTo",
146+
SearchQuery: "action:create date_to:2022-08-15",
147+
ExpectedResult: 1,
148+
},
130149
}
131150

132151
for _, testCase := range testCases {

coderd/database/databasefake/databasefake.go

+20
Original file line numberDiff line numberDiff line change
@@ -2995,6 +2995,16 @@ func (q *fakeQuerier) GetAuditLogsOffset(ctx context.Context, arg database.GetAu
29952995
continue
29962996
}
29972997
}
2998+
if !arg.DateFrom.IsZero() {
2999+
if alog.Time.Before(arg.DateFrom) {
3000+
continue
3001+
}
3002+
}
3003+
if !arg.DateTo.IsZero() {
3004+
if alog.Time.After(arg.DateTo) {
3005+
continue
3006+
}
3007+
}
29983008

29993009
user, err := q.GetUserByID(ctx, alog.UserID)
30003010
userValid := err == nil
@@ -3057,6 +3067,16 @@ func (q *fakeQuerier) GetAuditLogCount(_ context.Context, arg database.GetAuditL
30573067
continue
30583068
}
30593069
}
3070+
if !arg.DateFrom.IsZero() {
3071+
if alog.Time.Before(arg.DateFrom) {
3072+
continue
3073+
}
3074+
}
3075+
if !arg.DateTo.IsZero() {
3076+
if alog.Time.After(arg.DateTo) {
3077+
continue
3078+
}
3079+
}
30603080

30613081
logs = append(logs, alog)
30623082
}

coderd/database/queries.sql.go

+32
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/queries/auditlogs.sql

+24
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,18 @@ WHERE
5050
users.email = @email
5151
ELSE true
5252
END
53+
-- Filter by date_from
54+
AND CASE
55+
WHEN @date_from :: timestamp with time zone != '0001-01-01 00:00:00' THEN
56+
"time" >= @date_from
57+
ELSE true
58+
END
59+
-- Filter by date_to
60+
AND CASE
61+
WHEN @date_to :: timestamp with time zone != '0001-01-01 00:00:00' THEN
62+
"time" <= @date_to
63+
ELSE true
64+
END
5365
ORDER BY
5466
"time" DESC
5567
LIMIT
@@ -98,6 +110,18 @@ WHERE
98110
WHEN @email :: text != '' THEN
99111
user_id = (SELECT id from users WHERE users.email = @email )
100112
ELSE true
113+
END
114+
-- Filter by date_from
115+
AND CASE
116+
WHEN @date_from :: timestamp with time zone != '0001-01-01 00:00:00' THEN
117+
"time" >= @date_from
118+
ELSE true
119+
END
120+
-- Filter by date_to
121+
AND CASE
122+
WHEN @date_to :: timestamp with time zone != '0001-01-01 00:00:00' THEN
123+
"time" <= @date_to
124+
ELSE true
101125
END;
102126

103127
-- name: InsertAuditLog :one

codersdk/audit.go

+1
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ type CreateTestAuditLogRequest struct {
127127
Action AuditAction `json:"action,omitempty"`
128128
ResourceType ResourceType `json:"resource_type,omitempty"`
129129
ResourceID uuid.UUID `json:"resource_id,omitempty"`
130+
Time time.Time `json:"time,omitempty"`
130131
}
131132

132133
// AuditLogs retrieves audit logs from the given page.

docs/admin/audit-logs.md

+2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ The supported filters are:
3030
- `action`- The action applied to a resource. You can [find here](https://pkg.go.dev/github.com/coder/coder@main/codersdk#AuditAction) all the actions that are supported.
3131
- `username` - The username of the user who triggered the action.
3232
- `email` - The email of the user who triggered the action.
33+
- `date_from` - The inclusive start date with format `YYYY-MM-DD`.
34+
- `date_to ` - the inclusive end date with format `YYYY-MM-DD`.
3335

3436
## Enabling this feature
3537

enterprise/audit/table.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -109,13 +109,14 @@ var AuditableResources = auditMap(map[any]map[string]Action{
109109
"organization_id": ActionIgnore, // Never changes.
110110
"avatar_url": ActionTrack,
111111
},
112-
// We don't show any diff for the WorkspaceBuild resource
112+
// We don't show any diff for the WorkspaceBuild resource,
113+
// save for the template_version_id
113114
&database.WorkspaceBuild{}: {
114115
"id": ActionIgnore,
115116
"created_at": ActionIgnore,
116117
"updated_at": ActionIgnore,
117118
"workspace_id": ActionIgnore,
118-
"template_version_id": ActionIgnore,
119+
"template_version_id": ActionTrack,
119120
"build_number": ActionIgnore,
120121
"transition": ActionIgnore,
121122
"initiator_id": ActionIgnore,

site/src/api/typesGenerated.ts

+1
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ export interface CreateTestAuditLogRequest {
204204
readonly action?: AuditAction
205205
readonly resource_type?: ResourceType
206206
readonly resource_id?: string
207+
readonly time?: string
207208
}
208209

209210
// From codersdk/apikey.go

0 commit comments

Comments
 (0)