Skip to content

Commit 1cd4847

Browse files
committed
modify dbCrypt to not delete rows silently
1 parent d9d050f commit 1cd4847

File tree

1 file changed

+10
-33
lines changed

1 file changed

+10
-33
lines changed

coderd/database/dbcrypt/dbcrypt.go

Lines changed: 10 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"context"
55
"database/sql"
66
"encoding/base64"
7-
"runtime"
87
"strings"
98
"sync/atomic"
109

@@ -56,19 +55,15 @@ func (db *dbCrypt) GetUserLinkByLinkedID(ctx context.Context, linkedID string) (
5655
if err != nil {
5756
return database.UserLink{}, err
5857
}
59-
return link, db.decryptFields(func() error {
60-
return db.Store.DeleteUserLinkByLinkedID(ctx, linkedID)
61-
}, &link.OAuthAccessToken, &link.OAuthRefreshToken)
58+
return link, db.decryptFields(&link.OAuthAccessToken, &link.OAuthRefreshToken)
6259
}
6360

6461
func (db *dbCrypt) GetUserLinkByUserIDLoginType(ctx context.Context, params database.GetUserLinkByUserIDLoginTypeParams) (database.UserLink, error) {
6562
link, err := db.Store.GetUserLinkByUserIDLoginType(ctx, params)
6663
if err != nil {
6764
return database.UserLink{}, err
6865
}
69-
return link, db.decryptFields(func() error {
70-
return db.Store.DeleteUserLinkByLinkedID(ctx, link.LinkedID)
71-
}, &link.OAuthAccessToken, &link.OAuthRefreshToken)
66+
return link, db.decryptFields(&link.OAuthAccessToken, &link.OAuthRefreshToken)
7267
}
7368

7469
func (db *dbCrypt) InsertUserLink(ctx context.Context, params database.InsertUserLinkParams) (database.UserLink, error) {
@@ -100,12 +95,7 @@ func (db *dbCrypt) GetGitAuthLink(ctx context.Context, params database.GetGitAut
10095
if err != nil {
10196
return database.GitAuthLink{}, err
10297
}
103-
return link, db.decryptFields(func() error {
104-
return db.Store.DeleteGitAuthLink(ctx, database.DeleteGitAuthLinkParams{ // nolint:gosimple
105-
ProviderID: params.ProviderID,
106-
UserID: params.UserID,
107-
})
108-
}, &link.OAuthAccessToken, &link.OAuthRefreshToken)
98+
return link, db.decryptFields(&link.OAuthAccessToken, &link.OAuthRefreshToken)
10999
}
110100

111101
func (db *dbCrypt) UpdateGitAuthLink(ctx context.Context, params database.UpdateGitAuthLinkParams) (database.GitAuthLink, error) {
@@ -140,20 +130,7 @@ func (db *dbCrypt) encryptFields(fields ...*string) error {
140130

141131
// decryptFields decrypts the given fields in place.
142132
// If the value fails to decrypt, sql.ErrNoRows will be returned.
143-
func (db *dbCrypt) decryptFields(deleteFn func() error, fields ...*string) error {
144-
doDelete := func(reason string) error {
145-
err := deleteFn()
146-
if err != nil {
147-
return xerrors.Errorf("delete encrypted row: %w", err)
148-
}
149-
pc, _, _, ok := runtime.Caller(2)
150-
details := runtime.FuncForPC(pc)
151-
if ok && details != nil {
152-
db.Logger.Debug(context.Background(), "deleted row", slog.F("reason", reason), slog.F("caller", details.Name()))
153-
}
154-
return sql.ErrNoRows
155-
}
156-
133+
func (db *dbCrypt) decryptFields(fields ...*string) error {
157134
cipherPtr := db.ExternalTokenCipher.Load()
158135
// If no cipher is loaded, then we don't need to encrypt or decrypt anything!
159136
if cipherPtr == nil {
@@ -163,8 +140,8 @@ func (db *dbCrypt) decryptFields(deleteFn func() error, fields ...*string) error
163140
}
164141
if strings.HasPrefix(*field, MagicPrefix) {
165142
// If we have a magic prefix but encryption is disabled,
166-
// we should delete the row.
167-
return doDelete("encryption disabled")
143+
// complain loudly.
144+
return xerrors.Errorf("failed to decrypt field %q: encryption is disabled", *field)
168145
}
169146
}
170147
return nil
@@ -182,13 +159,13 @@ func (db *dbCrypt) decryptFields(deleteFn func() error, fields ...*string) error
182159
}
183160
data, err := base64.StdEncoding.DecodeString((*field)[len(MagicPrefix):])
184161
if err != nil {
185-
// If it's not base64 with the prefix, we should delete the row.
186-
return doDelete("stored value was not base64 encoded")
162+
// If it's not base64 with the prefix, we should complain loudly.
163+
return xerrors.Errorf("malformed encrypted field %q: %w", *field, err)
187164
}
188165
decrypted, err := cipher.Decrypt(data)
189166
if err != nil {
190-
// If the encryption key changed, we should delete the row.
191-
return doDelete("encryption key changed")
167+
// If the encryption key changed, return our special error that unwraps to sql.ErrNoRows.
168+
return &DecryptFailedError{Inner: err}
192169
}
193170
*field = string(decrypted)
194171
}

0 commit comments

Comments
 (0)