mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
fix(coderd): ensure that clearing invalid oauth refresh tokens works with dbcrypt (#15721)
https://github.com/coder/coder/pull/15608 introduced a buggy behaviour with dbcrypt enabled. When clearing an oauth refresh token, we had been setting the value to the empty string. The database encryption package considers decrypting an empty string to be an error, as an empty encrypted string value will still have a nonce associated with it and thus not actually be empty when stored at rest. Instead of 'deleting' the refresh token, 'update' it to be the empty string. This plays nicely with dbcrypt. It also adds a 'utility test' in the dbcrypt package to help encrypt a value. This was useful when manually fixing users affected by this bug on our dogfood instance.
This commit is contained in:
@@ -3367,13 +3367,6 @@ func (q *querier) RegisterWorkspaceProxy(ctx context.Context, arg database.Regis
|
||||
return updateWithReturn(q.log, q.auth, fetch, q.db.RegisterWorkspaceProxy)(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) RemoveRefreshToken(ctx context.Context, arg database.RemoveRefreshTokenParams) error {
|
||||
fetch := func(ctx context.Context, arg database.RemoveRefreshTokenParams) (database.ExternalAuthLink, error) {
|
||||
return q.db.GetExternalAuthLink(ctx, database.GetExternalAuthLinkParams{UserID: arg.UserID, ProviderID: arg.ProviderID})
|
||||
}
|
||||
return fetchAndExec(q.log, q.auth, policy.ActionUpdatePersonal, fetch, q.db.RemoveRefreshToken)(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) RemoveUserFromAllGroups(ctx context.Context, userID uuid.UUID) error {
|
||||
// This is a system function to clear user groups in group sync.
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdate, rbac.ResourceSystem); err != nil {
|
||||
@@ -3472,6 +3465,13 @@ func (q *querier) UpdateExternalAuthLink(ctx context.Context, arg database.Updat
|
||||
return fetchAndQuery(q.log, q.auth, policy.ActionUpdatePersonal, fetch, q.db.UpdateExternalAuthLink)(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) UpdateExternalAuthLinkRefreshToken(ctx context.Context, arg database.UpdateExternalAuthLinkRefreshTokenParams) error {
|
||||
fetch := func(ctx context.Context, arg database.UpdateExternalAuthLinkRefreshTokenParams) (database.ExternalAuthLink, error) {
|
||||
return q.db.GetExternalAuthLink(ctx, database.GetExternalAuthLinkParams{UserID: arg.UserID, ProviderID: arg.ProviderID})
|
||||
}
|
||||
return fetchAndExec(q.log, q.auth, policy.ActionUpdatePersonal, fetch, q.db.UpdateExternalAuthLinkRefreshToken)(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) UpdateGitSSHKey(ctx context.Context, arg database.UpdateGitSSHKeyParams) (database.GitSSHKey, error) {
|
||||
fetch := func(ctx context.Context, arg database.UpdateGitSSHKeyParams) (database.GitSSHKey, error) {
|
||||
return q.db.GetGitSSHKey(ctx, arg.UserID)
|
||||
|
||||
@@ -1282,12 +1282,14 @@ func (s *MethodTestSuite) TestUser() {
|
||||
UserID: u.ID,
|
||||
}).Asserts(u, policy.ActionUpdatePersonal)
|
||||
}))
|
||||
s.Run("RemoveRefreshToken", s.Subtest(func(db database.Store, check *expects) {
|
||||
s.Run("UpdateExternalAuthLinkRefreshToken", s.Subtest(func(db database.Store, check *expects) {
|
||||
link := dbgen.ExternalAuthLink(s.T(), db, database.ExternalAuthLink{})
|
||||
check.Args(database.RemoveRefreshTokenParams{
|
||||
ProviderID: link.ProviderID,
|
||||
UserID: link.UserID,
|
||||
UpdatedAt: link.UpdatedAt,
|
||||
check.Args(database.UpdateExternalAuthLinkRefreshTokenParams{
|
||||
OAuthRefreshToken: "",
|
||||
OAuthRefreshTokenKeyID: "",
|
||||
ProviderID: link.ProviderID,
|
||||
UserID: link.UserID,
|
||||
UpdatedAt: link.UpdatedAt,
|
||||
}).Asserts(rbac.ResourceUserObject(link.UserID), policy.ActionUpdatePersonal)
|
||||
}))
|
||||
s.Run("UpdateExternalAuthLink", s.Subtest(func(db database.Store, check *expects) {
|
||||
|
||||
Reference in New Issue
Block a user