Skip to content

Commit 4113828

Browse files
committed
Force soft delete of users, do not allow un-delete
1 parent 520b3ef commit 4113828

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{
@@ -2514,6 +2504,10 @@ func (q *querier) RevokeDBCryptKey(ctx context.Context, activeKeyDigest string)
25142504
return q.db.RevokeDBCryptKey(ctx, activeKeyDigest)
25152505
}
25162506

2507+
func (q *querier) SoftDeleteUserByID(ctx context.Context, id uuid.UUID) error {
2508+
return deleteQ(q.log, q.auth, q.db.GetUserByID, q.db.SoftDeleteUserByID)(ctx, id)
2509+
}
2510+
25172511
func (q *querier) TryAcquireLock(ctx context.Context, id int64) (bool, error) {
25182512
return q.db.TryAcquireLock(ctx, id)
25192513
}
@@ -2835,18 +2829,6 @@ func (q *querier) UpdateUserAppearanceSettings(ctx context.Context, arg database
28352829
return q.db.UpdateUserAppearanceSettings(ctx, arg)
28362830
}
28372831

2838-
// UpdateUserDeletedByID
2839-
// Deprecated: Delete this function in favor of 'SoftDeleteUserByID'. Deletes are
2840-
// irreversible.
2841-
func (q *querier) UpdateUserDeletedByID(ctx context.Context, arg database.UpdateUserDeletedByIDParams) error {
2842-
fetch := func(ctx context.Context, arg database.UpdateUserDeletedByIDParams) (database.User, error) {
2843-
return q.db.GetUserByID(ctx, arg.ID)
2844-
}
2845-
// This uses the rbac.ActionDelete action always as this function should always delete.
2846-
// We should delete this function in favor of 'SoftDeleteUserByID'.
2847-
return deleteQ(q.log, q.auth, fetch, q.db.UpdateUserDeletedByID)(ctx, arg)
2848-
}
2849-
28502832
func (q *querier) UpdateUserHashedPassword(ctx context.Context, arg database.UpdateUserHashedPasswordParams) error {
28512833
user, err := q.db.GetUserByID(ctx, arg.ID)
28522834
if err != nil {

coderd/database/dbmem/dbmem.go

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

5537-
// Took the error from the real database.
5538-
var deletedUserLinkError = &pq.Error{
5539-
Severity: "ERROR",
5540-
// "raise_exception" error
5541-
Code: "P0001",
5542-
Message: "Cannot create user_link for deleted user",
5543-
Where: "PL/pgSQL function insert_user_links_fail_if_user_deleted() line 7 at RAISE",
5544-
File: "pl_exec.c",
5545-
Line: "3864",
5546-
Routine: "exec_stmt_raise",
5547-
}
5548-
55495537
func (q *FakeQuerier) InsertUserLink(_ context.Context, args database.InsertUserLinkParams) (database.UserLink, error) {
55505538
q.mutex.Lock()
55515539
defer q.mutex.Unlock()
@@ -6085,6 +6073,40 @@ func (q *FakeQuerier) RevokeDBCryptKey(_ context.Context, activeKeyDigest string
60856073
return sql.ErrNoRows
60866074
}
60876075

6076+
// Took the error from the real database.
6077+
var deletedUserLinkError = &pq.Error{
6078+
Severity: "ERROR",
6079+
// "raise_exception" error
6080+
Code: "P0001",
6081+
Message: "Cannot create user_link for deleted user",
6082+
Where: "PL/pgSQL function insert_user_links_fail_if_user_deleted() line 7 at RAISE",
6083+
File: "pl_exec.c",
6084+
Line: "3864",
6085+
Routine: "exec_stmt_raise",
6086+
}
6087+
6088+
func (q *FakeQuerier) SoftDeleteUserByID(ctx context.Context, id uuid.UUID) error {
6089+
q.mutex.Lock()
6090+
defer q.mutex.Unlock()
6091+
6092+
for i, u := range q.users {
6093+
if u.ID == id {
6094+
u.Deleted = true
6095+
q.users[i] = u
6096+
// NOTE: In the real world, this is done by a trigger.
6097+
q.apiKeys = slices.DeleteFunc(q.apiKeys, func(u database.APIKey) bool {
6098+
return id == u.UserID
6099+
})
6100+
6101+
q.userLinks = slices.DeleteFunc(q.userLinks, func(u database.UserLink) bool {
6102+
return id == u.UserID
6103+
})
6104+
return nil
6105+
}
6106+
}
6107+
return sql.ErrNoRows
6108+
}
6109+
60886110
func (*FakeQuerier) TryAcquireLock(_ context.Context, _ int64) (bool, error) {
60896111
return false, xerrors.New("TryAcquireLock must only be called within a transaction")
60906112
}
@@ -6686,34 +6708,6 @@ func (q *FakeQuerier) UpdateUserAppearanceSettings(_ context.Context, arg databa
66866708
return database.User{}, sql.ErrNoRows
66876709
}
66886710

6689-
func (q *FakeQuerier) UpdateUserDeletedByID(_ context.Context, params database.UpdateUserDeletedByIDParams) error {
6690-
if err := validateDatabaseType(params); err != nil {
6691-
return err
6692-
}
6693-
6694-
q.mutex.Lock()
6695-
defer q.mutex.Unlock()
6696-
6697-
for i, u := range q.users {
6698-
if u.ID == params.ID {
6699-
u.Deleted = params.Deleted
6700-
q.users[i] = u
6701-
if params.Deleted {
6702-
// NOTE: In the real world, this is done by a trigger.
6703-
q.apiKeys = slices.DeleteFunc(q.apiKeys, func(u database.APIKey) bool {
6704-
return params.ID == u.UserID
6705-
})
6706-
6707-
q.userLinks = slices.DeleteFunc(q.userLinks, func(u database.UserLink) bool {
6708-
return params.ID == u.UserID
6709-
})
6710-
}
6711-
return nil
6712-
}
6713-
}
6714-
return sql.ErrNoRows
6715-
}
6716-
67176711
func (q *FakeQuerier) UpdateUserHashedPassword(_ context.Context, arg database.UpdateUserHashedPasswordParams) error {
67186712
if err := validateDatabaseType(arg); err != nil {
67196713
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)