Skip to content

Commit e0902a3

Browse files
committed
Force soft delete of users, do not allow un-delete
1 parent 188f03b commit e0902a3

File tree

8 files changed

+77
-109
lines changed

8 files changed

+77
-109
lines changed

coderd/database/dbauthz/dbauthz.go

Lines changed: 4 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -607,16 +607,6 @@ func (q *querier) SoftDeleteTemplateByID(ctx context.Context, id uuid.UUID) erro
607607
return deleteQ(q.log, q.auth, q.db.GetTemplateByID, deleteF)(ctx, id)
608608
}
609609

610-
func (q *querier) SoftDeleteUserByID(ctx context.Context, id uuid.UUID) error {
611-
deleteF := func(ctx context.Context, id uuid.UUID) error {
612-
return q.db.UpdateUserDeletedByID(ctx, database.UpdateUserDeletedByIDParams{
613-
ID: id,
614-
Deleted: true,
615-
})
616-
}
617-
return deleteQ(q.log, q.auth, q.db.GetUserByID, deleteF)(ctx, id)
618-
}
619-
620610
func (q *querier) SoftDeleteWorkspaceByID(ctx context.Context, id uuid.UUID) error {
621611
return deleteQ(q.log, q.auth, q.db.GetWorkspaceByID, func(ctx context.Context, id uuid.UUID) error {
622612
return q.db.UpdateWorkspaceDeletedByID(ctx, database.UpdateWorkspaceDeletedByIDParams{
@@ -2556,6 +2546,10 @@ func (q *querier) RevokeDBCryptKey(ctx context.Context, activeKeyDigest string)
25562546
return q.db.RevokeDBCryptKey(ctx, activeKeyDigest)
25572547
}
25582548

2549+
func (q *querier) SoftDeleteUserByID(ctx context.Context, id uuid.UUID) error {
2550+
return deleteQ(q.log, q.auth, q.db.GetUserByID, q.db.SoftDeleteUserByID)(ctx, id)
2551+
}
2552+
25592553
func (q *querier) TryAcquireLock(ctx context.Context, id int64) (bool, error) {
25602554
return q.db.TryAcquireLock(ctx, id)
25612555
}
@@ -2877,18 +2871,6 @@ func (q *querier) UpdateUserAppearanceSettings(ctx context.Context, arg database
28772871
return q.db.UpdateUserAppearanceSettings(ctx, arg)
28782872
}
28792873

2880-
// UpdateUserDeletedByID
2881-
// Deprecated: Delete this function in favor of 'SoftDeleteUserByID'. Deletes are
2882-
// irreversible.
2883-
func (q *querier) UpdateUserDeletedByID(ctx context.Context, arg database.UpdateUserDeletedByIDParams) error {
2884-
fetch := func(ctx context.Context, arg database.UpdateUserDeletedByIDParams) (database.User, error) {
2885-
return q.db.GetUserByID(ctx, arg.ID)
2886-
}
2887-
// This uses the rbac.ActionDelete action always as this function should always delete.
2888-
// We should delete this function in favor of 'SoftDeleteUserByID'.
2889-
return deleteQ(q.log, q.auth, fetch, q.db.UpdateUserDeletedByID)(ctx, arg)
2890-
}
2891-
28922874
func (q *querier) UpdateUserHashedPassword(ctx context.Context, arg database.UpdateUserHashedPasswordParams) error {
28932875
user, err := q.db.GetUserByID(ctx, arg.ID)
28942876
if err != nil {

coderd/database/dbmem/dbmem.go

Lines changed: 34 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -5573,18 +5573,6 @@ func (q *FakeQuerier) InsertUserGroupsByName(_ context.Context, arg database.Ins
55735573
return nil
55745574
}
55755575

5576-
// Took the error from the real database.
5577-
var deletedUserLinkError = &pq.Error{
5578-
Severity: "ERROR",
5579-
// "raise_exception" error
5580-
Code: "P0001",
5581-
Message: "Cannot create user_link for deleted user",
5582-
Where: "PL/pgSQL function insert_user_links_fail_if_user_deleted() line 7 at RAISE",
5583-
File: "pl_exec.c",
5584-
Line: "3864",
5585-
Routine: "exec_stmt_raise",
5586-
}
5587-
55885576
func (q *FakeQuerier) InsertUserLink(_ context.Context, args database.InsertUserLinkParams) (database.UserLink, error) {
55895577
q.mutex.Lock()
55905578
defer q.mutex.Unlock()
@@ -6138,6 +6126,40 @@ func (q *FakeQuerier) RevokeDBCryptKey(_ context.Context, activeKeyDigest string
61386126
return sql.ErrNoRows
61396127
}
61406128

6129+
// Took the error from the real database.
6130+
var deletedUserLinkError = &pq.Error{
6131+
Severity: "ERROR",
6132+
// "raise_exception" error
6133+
Code: "P0001",
6134+
Message: "Cannot create user_link for deleted user",
6135+
Where: "PL/pgSQL function insert_user_links_fail_if_user_deleted() line 7 at RAISE",
6136+
File: "pl_exec.c",
6137+
Line: "3864",
6138+
Routine: "exec_stmt_raise",
6139+
}
6140+
6141+
func (q *FakeQuerier) SoftDeleteUserByID(ctx context.Context, id uuid.UUID) error {
6142+
q.mutex.Lock()
6143+
defer q.mutex.Unlock()
6144+
6145+
for i, u := range q.users {
6146+
if u.ID == id {
6147+
u.Deleted = true
6148+
q.users[i] = u
6149+
// NOTE: In the real world, this is done by a trigger.
6150+
q.apiKeys = slices.DeleteFunc(q.apiKeys, func(u database.APIKey) bool {
6151+
return id == u.UserID
6152+
})
6153+
6154+
q.userLinks = slices.DeleteFunc(q.userLinks, func(u database.UserLink) bool {
6155+
return id == u.UserID
6156+
})
6157+
return nil
6158+
}
6159+
}
6160+
return sql.ErrNoRows
6161+
}
6162+
61416163
func (*FakeQuerier) TryAcquireLock(_ context.Context, _ int64) (bool, error) {
61426164
return false, xerrors.New("TryAcquireLock must only be called within a transaction")
61436165
}
@@ -6740,34 +6762,6 @@ func (q *FakeQuerier) UpdateUserAppearanceSettings(_ context.Context, arg databa
67406762
return database.User{}, sql.ErrNoRows
67416763
}
67426764

6743-
func (q *FakeQuerier) UpdateUserDeletedByID(_ context.Context, params database.UpdateUserDeletedByIDParams) error {
6744-
if err := validateDatabaseType(params); err != nil {
6745-
return err
6746-
}
6747-
6748-
q.mutex.Lock()
6749-
defer q.mutex.Unlock()
6750-
6751-
for i, u := range q.users {
6752-
if u.ID == params.ID {
6753-
u.Deleted = params.Deleted
6754-
q.users[i] = u
6755-
if params.Deleted {
6756-
// NOTE: In the real world, this is done by a trigger.
6757-
q.apiKeys = slices.DeleteFunc(q.apiKeys, func(u database.APIKey) bool {
6758-
return params.ID == u.UserID
6759-
})
6760-
6761-
q.userLinks = slices.DeleteFunc(q.userLinks, func(u database.UserLink) bool {
6762-
return params.ID == u.UserID
6763-
})
6764-
}
6765-
return nil
6766-
}
6767-
}
6768-
return sql.ErrNoRows
6769-
}
6770-
67716765
func (q *FakeQuerier) UpdateUserHashedPassword(_ context.Context, arg database.UpdateUserHashedPasswordParams) error {
67726766
if err := validateDatabaseType(arg); err != nil {
67736767
return err

coderd/database/dbmetrics/dbmetrics.go

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

coderd/database/dbmock/dbmock.go

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

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: 14 additions & 19 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/queries/users.sql

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,11 +112,11 @@ SET
112112
WHERE
113113
id = $1;
114114

115-
-- name: UpdateUserDeletedByID :exec
115+
-- name: SoftDeleteUserByID :exec
116116
UPDATE
117117
users
118118
SET
119-
deleted = $2
119+
deleted = true
120120
WHERE
121121
id = $1;
122122

coderd/users.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -521,10 +521,7 @@ func (api *API) deleteUser(rw http.ResponseWriter, r *http.Request) {
521521
return
522522
}
523523

524-
err = api.Database.UpdateUserDeletedByID(ctx, database.UpdateUserDeletedByIDParams{
525-
ID: user.ID,
526-
Deleted: true,
527-
})
524+
err = api.Database.SoftDeleteUserByID(ctx, user.ID)
528525
if dbauthz.IsNotAuthorizedError(err) {
529526
httpapi.Forbidden(rw)
530527
return

0 commit comments

Comments
 (0)