Skip to content

Commit 43e45f4

Browse files
authored
fix: fill out zero-value user properties in /audit (#13604)
1 parent 57b38e5 commit 43e45f4

File tree

5 files changed

+151
-63
lines changed

5 files changed

+151
-63
lines changed

coderd/audit.go

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import (
2020
"github.com/coder/coder/v2/coderd/database/db2sdk"
2121
"github.com/coder/coder/v2/coderd/httpapi"
2222
"github.com/coder/coder/v2/coderd/httpmw"
23-
"github.com/coder/coder/v2/coderd/rbac"
2423
"github.com/coder/coder/v2/coderd/searchquery"
2524
"github.com/coder/coder/v2/codersdk"
2625
)
@@ -183,27 +182,26 @@ func (api *API) convertAuditLog(ctx context.Context, dblog database.GetAuditLogs
183182
_ = json.Unmarshal(dblog.Diff, &diff)
184183

185184
var user *codersdk.User
186-
187185
if dblog.UserUsername.Valid {
188-
user = &codersdk.User{
189-
ReducedUser: codersdk.ReducedUser{
190-
MinimalUser: codersdk.MinimalUser{
191-
ID: dblog.UserID,
192-
Username: dblog.UserUsername.String,
193-
AvatarURL: dblog.UserAvatarUrl.String,
194-
},
195-
Email: dblog.UserEmail.String,
196-
CreatedAt: dblog.UserCreatedAt.Time,
197-
Status: codersdk.UserStatus(dblog.UserStatus.UserStatus),
198-
},
199-
Roles: []codersdk.SlimRole{},
200-
}
201-
202-
for _, input := range dblog.UserRoles {
203-
roleName, _ := rbac.RoleNameFromString(input)
204-
rbacRole, _ := rbac.RoleByName(roleName)
205-
user.Roles = append(user.Roles, db2sdk.SlimRole(rbacRole))
206-
}
186+
// Leaving the organization IDs blank for now; not sure they are useful for
187+
// the audit query anyway?
188+
sdkUser := db2sdk.User(database.User{
189+
ID: dblog.UserID,
190+
Email: dblog.UserEmail.String,
191+
Username: dblog.UserUsername.String,
192+
CreatedAt: dblog.UserCreatedAt.Time,
193+
UpdatedAt: dblog.UserUpdatedAt.Time,
194+
Status: dblog.UserStatus.UserStatus,
195+
RBACRoles: dblog.UserRoles,
196+
LoginType: dblog.UserLoginType.LoginType,
197+
AvatarURL: dblog.UserAvatarUrl.String,
198+
Deleted: dblog.UserDeleted.Bool,
199+
LastSeenAt: dblog.UserLastSeenAt.Time,
200+
QuietHoursSchedule: dblog.UserQuietHoursSchedule.String,
201+
ThemePreference: dblog.UserThemePreference.String,
202+
Name: dblog.UserName.String,
203+
}, []uuid.UUID{})
204+
user = &sdkUser
207205
}
208206

209207
var (

coderd/audit_test.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@ import (
88
"testing"
99
"time"
1010

11+
"github.com/google/uuid"
1112
"github.com/stretchr/testify/require"
1213

1314
"github.com/coder/coder/v2/coderd/audit"
1415
"github.com/coder/coder/v2/coderd/coderdtest"
1516
"github.com/coder/coder/v2/coderd/database"
17+
"github.com/coder/coder/v2/coderd/rbac"
1618
"github.com/coder/coder/v2/codersdk"
1719
)
1820

@@ -42,6 +44,55 @@ func TestAuditLogs(t *testing.T) {
4244
require.Len(t, alogs.AuditLogs, 1)
4345
})
4446

47+
t.Run("User", func(t *testing.T) {
48+
t.Parallel()
49+
50+
ctx := context.Background()
51+
client := coderdtest.New(t, nil)
52+
user := coderdtest.CreateFirstUser(t, client)
53+
client2, user2 := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleOwner())
54+
55+
err := client2.CreateTestAuditLog(ctx, codersdk.CreateTestAuditLogRequest{
56+
ResourceID: user2.ID,
57+
})
58+
require.NoError(t, err)
59+
60+
alogs, err := client.AuditLogs(ctx, codersdk.AuditLogsRequest{
61+
Pagination: codersdk.Pagination{
62+
Limit: 1,
63+
},
64+
})
65+
require.NoError(t, err)
66+
require.Equal(t, int64(1), alogs.Count)
67+
require.Len(t, alogs.AuditLogs, 1)
68+
69+
// Make sure the returned user is fully populated.
70+
foundUser, err := client.User(ctx, user2.ID.String())
71+
foundUser.OrganizationIDs = []uuid.UUID{} // Not included.
72+
require.NoError(t, err)
73+
require.Equal(t, foundUser, *alogs.AuditLogs[0].User)
74+
75+
// Delete the user and try again. This is a soft delete so nothing should
76+
// change. If users are hard deleted we should get nil, but there is no way
77+
// to test this at the moment.
78+
err = client.DeleteUser(ctx, user2.ID)
79+
require.NoError(t, err)
80+
81+
alogs, err = client.AuditLogs(ctx, codersdk.AuditLogsRequest{
82+
Pagination: codersdk.Pagination{
83+
Limit: 1,
84+
},
85+
})
86+
require.NoError(t, err)
87+
require.Equal(t, int64(1), alogs.Count)
88+
require.Len(t, alogs.AuditLogs, 1)
89+
90+
foundUser, err = client.User(ctx, user2.ID.String())
91+
foundUser.OrganizationIDs = []uuid.UUID{} // Not included.
92+
require.NoError(t, err)
93+
require.Equal(t, foundUser, *alogs.AuditLogs[0].User)
94+
})
95+
4596
t.Run("WorkspaceBuildAuditLink", func(t *testing.T) {
4697
t.Parallel()
4798

coderd/database/dbmem/dbmem.go

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1969,26 +1969,33 @@ func (q *FakeQuerier) GetAuditLogsOffset(_ context.Context, arg database.GetAudi
19691969
userValid := err == nil
19701970

19711971
logs = append(logs, database.GetAuditLogsOffsetRow{
1972-
ID: alog.ID,
1973-
RequestID: alog.RequestID,
1974-
OrganizationID: alog.OrganizationID,
1975-
Ip: alog.Ip,
1976-
UserAgent: alog.UserAgent,
1977-
ResourceType: alog.ResourceType,
1978-
ResourceID: alog.ResourceID,
1979-
ResourceTarget: alog.ResourceTarget,
1980-
ResourceIcon: alog.ResourceIcon,
1981-
Action: alog.Action,
1982-
Diff: alog.Diff,
1983-
StatusCode: alog.StatusCode,
1984-
AdditionalFields: alog.AdditionalFields,
1985-
UserID: alog.UserID,
1986-
UserUsername: sql.NullString{String: user.Username, Valid: userValid},
1987-
UserEmail: sql.NullString{String: user.Email, Valid: userValid},
1988-
UserCreatedAt: sql.NullTime{Time: user.CreatedAt, Valid: userValid},
1989-
UserStatus: database.NullUserStatus{UserStatus: user.Status, Valid: userValid},
1990-
UserRoles: user.RBACRoles,
1991-
Count: 0,
1972+
ID: alog.ID,
1973+
RequestID: alog.RequestID,
1974+
OrganizationID: alog.OrganizationID,
1975+
Ip: alog.Ip,
1976+
UserAgent: alog.UserAgent,
1977+
ResourceType: alog.ResourceType,
1978+
ResourceID: alog.ResourceID,
1979+
ResourceTarget: alog.ResourceTarget,
1980+
ResourceIcon: alog.ResourceIcon,
1981+
Action: alog.Action,
1982+
Diff: alog.Diff,
1983+
StatusCode: alog.StatusCode,
1984+
AdditionalFields: alog.AdditionalFields,
1985+
UserID: alog.UserID,
1986+
UserUsername: sql.NullString{String: user.Username, Valid: userValid},
1987+
UserName: sql.NullString{String: user.Name, Valid: userValid},
1988+
UserEmail: sql.NullString{String: user.Email, Valid: userValid},
1989+
UserCreatedAt: sql.NullTime{Time: user.CreatedAt, Valid: userValid},
1990+
UserUpdatedAt: sql.NullTime{Time: user.UpdatedAt, Valid: userValid},
1991+
UserLastSeenAt: sql.NullTime{Time: user.LastSeenAt, Valid: userValid},
1992+
UserLoginType: database.NullLoginType{LoginType: user.LoginType, Valid: userValid},
1993+
UserDeleted: sql.NullBool{Bool: user.Deleted, Valid: userValid},
1994+
UserThemePreference: sql.NullString{String: user.ThemePreference, Valid: userValid},
1995+
UserQuietHoursSchedule: sql.NullString{String: user.QuietHoursSchedule, Valid: userValid},
1996+
UserStatus: database.NullUserStatus{UserStatus: user.Status, Valid: userValid},
1997+
UserRoles: user.RBACRoles,
1998+
Count: 0,
19921999
})
19932000

19942001
if len(logs) >= int(arg.Limit) {

coderd/database/queries.sql.go

Lines changed: 45 additions & 22 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: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,21 @@
33
-- name: GetAuditLogsOffset :many
44
SELECT
55
audit_logs.*,
6+
-- sqlc.embed(users) would be nice but it does not seem to play well with
7+
-- left joins.
68
users.username AS user_username,
9+
users.name AS user_name,
710
users.email AS user_email,
811
users.created_at AS user_created_at,
12+
users.updated_at AS user_updated_at,
13+
users.last_seen_at AS user_last_seen_at,
914
users.status AS user_status,
15+
users.login_type AS user_login_type,
1016
users.rbac_roles AS user_roles,
1117
users.avatar_url AS user_avatar_url,
18+
users.deleted AS user_deleted,
19+
users.theme_preference AS user_theme_preference,
20+
users.quiet_hours_schedule AS user_quiet_hours_schedule,
1221
COUNT(audit_logs.*) OVER () AS count
1322
FROM
1423
audit_logs

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy