mirror of
https://github.com/go-gitea/gitea
synced 2025-07-23 18:58:38 +00:00
Use db.WithTx/WithTx2 instead of TxContext when possible (#35130)
This commit is contained in:
@@ -228,17 +228,10 @@ func DeleteGPGKey(ctx context.Context, doer *user_model.User, id int64) (err err
|
||||
return fmt.Errorf("GetPublicKeyByID: %w", err)
|
||||
}
|
||||
|
||||
ctx, committer, err := db.TxContext(ctx)
|
||||
if err != nil {
|
||||
return db.WithTx(ctx, func(ctx context.Context) error {
|
||||
_, err = deleteGPGKey(ctx, key.KeyID)
|
||||
return err
|
||||
}
|
||||
defer committer.Close()
|
||||
|
||||
if _, err = deleteGPGKey(ctx, key.KeyID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return committer.Commit()
|
||||
})
|
||||
}
|
||||
|
||||
func FindGPGKeyWithSubKeys(ctx context.Context, keyID string) ([]*GPGKey, error) {
|
||||
|
@@ -14,97 +14,76 @@ import (
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
)
|
||||
|
||||
// __________________ ________ ____ __.
|
||||
// / _____/\______ \/ _____/ | |/ _|____ ___.__.
|
||||
// / \ ___ | ___/ \ ___ | <_/ __ < | |
|
||||
// \ \_\ \| | \ \_\ \ | | \ ___/\___ |
|
||||
// \______ /|____| \______ / |____|__ \___ > ____|
|
||||
// \/ \/ \/ \/\/
|
||||
// ____ ____ .__ _____
|
||||
// \ \ / /___________|__|/ ____\__.__.
|
||||
// \ Y // __ \_ __ \ \ __< | |
|
||||
// \ /\ ___/| | \/ || | \___ |
|
||||
// \___/ \___ >__| |__||__| / ____|
|
||||
// \/ \/
|
||||
|
||||
// This file provides functions relating verifying gpg keys
|
||||
|
||||
// VerifyGPGKey marks a GPG key as verified
|
||||
func VerifyGPGKey(ctx context.Context, ownerID int64, keyID, token, signature string) (string, error) {
|
||||
ctx, committer, err := db.TxContext(ctx)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer committer.Close()
|
||||
return db.WithTx2(ctx, func(ctx context.Context) (string, error) {
|
||||
key := new(GPGKey)
|
||||
|
||||
key := new(GPGKey)
|
||||
|
||||
has, err := db.GetEngine(ctx).Where("owner_id = ? AND key_id = ?", ownerID, keyID).Get(key)
|
||||
if err != nil {
|
||||
return "", err
|
||||
} else if !has {
|
||||
return "", ErrGPGKeyNotExist{}
|
||||
}
|
||||
|
||||
if err := key.LoadSubKeys(ctx); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
sig, err := ExtractSignature(signature)
|
||||
if err != nil {
|
||||
return "", ErrGPGInvalidTokenSignature{
|
||||
ID: key.KeyID,
|
||||
Wrapped: err,
|
||||
has, err := db.GetEngine(ctx).Where("owner_id = ? AND key_id = ?", ownerID, keyID).Get(key)
|
||||
if err != nil {
|
||||
return "", err
|
||||
} else if !has {
|
||||
return "", ErrGPGKeyNotExist{}
|
||||
}
|
||||
}
|
||||
|
||||
signer, err := hashAndVerifyWithSubKeys(sig, token, key)
|
||||
if err != nil {
|
||||
return "", ErrGPGInvalidTokenSignature{
|
||||
ID: key.KeyID,
|
||||
Wrapped: err,
|
||||
if err := key.LoadSubKeys(ctx); err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
if signer == nil {
|
||||
signer, err = hashAndVerifyWithSubKeys(sig, token+"\n", key)
|
||||
|
||||
sig, err := ExtractSignature(signature)
|
||||
if err != nil {
|
||||
return "", ErrGPGInvalidTokenSignature{
|
||||
ID: key.KeyID,
|
||||
Wrapped: err,
|
||||
}
|
||||
}
|
||||
}
|
||||
if signer == nil {
|
||||
signer, err = hashAndVerifyWithSubKeys(sig, token+"\n\n", key)
|
||||
|
||||
signer, err := hashAndVerifyWithSubKeys(sig, token, key)
|
||||
if err != nil {
|
||||
return "", ErrGPGInvalidTokenSignature{
|
||||
ID: key.KeyID,
|
||||
Wrapped: err,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if signer == nil {
|
||||
log.Debug("VerifyGPGKey failed: no signer")
|
||||
return "", ErrGPGInvalidTokenSignature{
|
||||
ID: key.KeyID,
|
||||
if signer == nil {
|
||||
signer, err = hashAndVerifyWithSubKeys(sig, token+"\n", key)
|
||||
if err != nil {
|
||||
return "", ErrGPGInvalidTokenSignature{
|
||||
ID: key.KeyID,
|
||||
Wrapped: err,
|
||||
}
|
||||
}
|
||||
}
|
||||
if signer == nil {
|
||||
signer, err = hashAndVerifyWithSubKeys(sig, token+"\n\n", key)
|
||||
if err != nil {
|
||||
return "", ErrGPGInvalidTokenSignature{
|
||||
ID: key.KeyID,
|
||||
Wrapped: err,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if signer.PrimaryKeyID != key.KeyID && signer.KeyID != key.KeyID {
|
||||
return "", ErrGPGKeyNotExist{}
|
||||
}
|
||||
if signer == nil {
|
||||
log.Debug("VerifyGPGKey failed: no signer")
|
||||
return "", ErrGPGInvalidTokenSignature{
|
||||
ID: key.KeyID,
|
||||
}
|
||||
}
|
||||
|
||||
key.Verified = true
|
||||
if _, err := db.GetEngine(ctx).ID(key.ID).SetExpr("verified", true).Update(new(GPGKey)); err != nil {
|
||||
return "", err
|
||||
}
|
||||
if signer.PrimaryKeyID != key.KeyID && signer.KeyID != key.KeyID {
|
||||
return "", ErrGPGKeyNotExist{}
|
||||
}
|
||||
|
||||
if err := committer.Commit(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
key.Verified = true
|
||||
if _, err := db.GetEngine(ctx).ID(key.ID).SetExpr("verified", true).Update(new(GPGKey)); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return key.KeyID, nil
|
||||
return key.KeyID, nil
|
||||
})
|
||||
}
|
||||
|
||||
// VerificationToken returns token for the user that will be valid in minutes (time)
|
||||
|
@@ -99,40 +99,36 @@ func AddPublicKey(ctx context.Context, ownerID int64, name, content string, auth
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ctx, committer, err := db.TxContext(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer committer.Close()
|
||||
return db.WithTx2(ctx, func(ctx context.Context) (*PublicKey, error) {
|
||||
if err := checkKeyFingerprint(ctx, fingerprint); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := checkKeyFingerprint(ctx, fingerprint); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Key name of same user cannot be duplicated.
|
||||
has, err := db.GetEngine(ctx).
|
||||
Where("owner_id = ? AND name = ?", ownerID, name).
|
||||
Get(new(PublicKey))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if has {
|
||||
return nil, ErrKeyNameAlreadyUsed{ownerID, name}
|
||||
}
|
||||
|
||||
// Key name of same user cannot be duplicated.
|
||||
has, err := db.GetEngine(ctx).
|
||||
Where("owner_id = ? AND name = ?", ownerID, name).
|
||||
Get(new(PublicKey))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if has {
|
||||
return nil, ErrKeyNameAlreadyUsed{ownerID, name}
|
||||
}
|
||||
key := &PublicKey{
|
||||
OwnerID: ownerID,
|
||||
Name: name,
|
||||
Fingerprint: fingerprint,
|
||||
Content: content,
|
||||
Mode: perm.AccessModeWrite,
|
||||
Type: KeyTypeUser,
|
||||
LoginSourceID: authSourceID,
|
||||
}
|
||||
if err = addKey(ctx, key); err != nil {
|
||||
return nil, fmt.Errorf("addKey: %w", err)
|
||||
}
|
||||
|
||||
key := &PublicKey{
|
||||
OwnerID: ownerID,
|
||||
Name: name,
|
||||
Fingerprint: fingerprint,
|
||||
Content: content,
|
||||
Mode: perm.AccessModeWrite,
|
||||
Type: KeyTypeUser,
|
||||
LoginSourceID: authSourceID,
|
||||
}
|
||||
if err = addKey(ctx, key); err != nil {
|
||||
return nil, fmt.Errorf("addKey: %w", err)
|
||||
}
|
||||
|
||||
return key, committer.Commit()
|
||||
return key, nil
|
||||
})
|
||||
}
|
||||
|
||||
// GetPublicKeyByID returns public key by given ID.
|
||||
@@ -288,33 +284,24 @@ func PublicKeyIsExternallyManaged(ctx context.Context, id int64) (bool, error) {
|
||||
|
||||
// deleteKeysMarkedForDeletion returns true if ssh keys needs update
|
||||
func deleteKeysMarkedForDeletion(ctx context.Context, keys []string) (bool, error) {
|
||||
// Start session
|
||||
ctx, committer, err := db.TxContext(ctx)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
defer committer.Close()
|
||||
|
||||
// Delete keys marked for deletion
|
||||
var sshKeysNeedUpdate bool
|
||||
for _, KeyToDelete := range keys {
|
||||
key, err := SearchPublicKeyByContent(ctx, KeyToDelete)
|
||||
if err != nil {
|
||||
log.Error("SearchPublicKeyByContent: %v", err)
|
||||
continue
|
||||
return db.WithTx2(ctx, func(ctx context.Context) (bool, error) {
|
||||
// Delete keys marked for deletion
|
||||
var sshKeysNeedUpdate bool
|
||||
for _, KeyToDelete := range keys {
|
||||
key, err := SearchPublicKeyByContent(ctx, KeyToDelete)
|
||||
if err != nil {
|
||||
log.Error("SearchPublicKeyByContent: %v", err)
|
||||
continue
|
||||
}
|
||||
if _, err = db.DeleteByID[PublicKey](ctx, key.ID); err != nil {
|
||||
log.Error("DeleteByID[PublicKey]: %v", err)
|
||||
continue
|
||||
}
|
||||
sshKeysNeedUpdate = true
|
||||
}
|
||||
if _, err = db.DeleteByID[PublicKey](ctx, key.ID); err != nil {
|
||||
log.Error("DeleteByID[PublicKey]: %v", err)
|
||||
continue
|
||||
}
|
||||
sshKeysNeedUpdate = true
|
||||
}
|
||||
|
||||
if err := committer.Commit(); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return sshKeysNeedUpdate, nil
|
||||
return sshKeysNeedUpdate, nil
|
||||
})
|
||||
}
|
||||
|
||||
// AddPublicKeysBySource add a users public keys. Returns true if there are changes.
|
||||
|
@@ -125,39 +125,35 @@ func AddDeployKey(ctx context.Context, repoID int64, name, content string, readO
|
||||
accessMode = perm.AccessModeWrite
|
||||
}
|
||||
|
||||
ctx, committer, err := db.TxContext(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer committer.Close()
|
||||
|
||||
pkey, exist, err := db.Get[PublicKey](ctx, builder.Eq{"fingerprint": fingerprint})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if exist {
|
||||
if pkey.Type != KeyTypeDeploy {
|
||||
return nil, ErrKeyAlreadyExist{0, fingerprint, ""}
|
||||
return db.WithTx2(ctx, func(ctx context.Context) (*DeployKey, error) {
|
||||
pkey, exist, err := db.Get[PublicKey](ctx, builder.Eq{"fingerprint": fingerprint})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if exist {
|
||||
if pkey.Type != KeyTypeDeploy {
|
||||
return nil, ErrKeyAlreadyExist{0, fingerprint, ""}
|
||||
}
|
||||
} else {
|
||||
// First time use this deploy key.
|
||||
pkey = &PublicKey{
|
||||
Fingerprint: fingerprint,
|
||||
Mode: accessMode,
|
||||
Type: KeyTypeDeploy,
|
||||
Content: content,
|
||||
Name: name,
|
||||
}
|
||||
if err = addKey(ctx, pkey); err != nil {
|
||||
return nil, fmt.Errorf("addKey: %w", err)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// First time use this deploy key.
|
||||
pkey = &PublicKey{
|
||||
Fingerprint: fingerprint,
|
||||
Mode: accessMode,
|
||||
Type: KeyTypeDeploy,
|
||||
Content: content,
|
||||
Name: name,
|
||||
}
|
||||
if err = addKey(ctx, pkey); err != nil {
|
||||
return nil, fmt.Errorf("addKey: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
key, err := addDeployKey(ctx, pkey.ID, repoID, name, pkey.Fingerprint, accessMode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
key, err := addDeployKey(ctx, pkey.ID, repoID, name, pkey.Fingerprint, accessMode)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return key, committer.Commit()
|
||||
return key, nil
|
||||
})
|
||||
}
|
||||
|
||||
// GetDeployKeyByID returns deploy key by given ID.
|
||||
|
@@ -15,41 +15,33 @@ import (
|
||||
|
||||
// VerifySSHKey marks a SSH key as verified
|
||||
func VerifySSHKey(ctx context.Context, ownerID int64, fingerprint, token, signature string) (string, error) {
|
||||
ctx, committer, err := db.TxContext(ctx)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer committer.Close()
|
||||
return db.WithTx2(ctx, func(ctx context.Context) (string, error) {
|
||||
key := new(PublicKey)
|
||||
|
||||
key := new(PublicKey)
|
||||
has, err := db.GetEngine(ctx).Where("owner_id = ? AND fingerprint = ?", ownerID, fingerprint).Get(key)
|
||||
if err != nil {
|
||||
return "", err
|
||||
} else if !has {
|
||||
return "", ErrKeyNotExist{}
|
||||
}
|
||||
|
||||
has, err := db.GetEngine(ctx).Where("owner_id = ? AND fingerprint = ?", ownerID, fingerprint).Get(key)
|
||||
if err != nil {
|
||||
return "", err
|
||||
} else if !has {
|
||||
return "", ErrKeyNotExist{}
|
||||
}
|
||||
|
||||
err = sshsig.Verify(strings.NewReader(token), []byte(signature), []byte(key.Content), "gitea")
|
||||
if err != nil {
|
||||
// edge case for Windows based shells that will add CR LF if piped to ssh-keygen command
|
||||
// see https://github.com/PowerShell/PowerShell/issues/5974
|
||||
if sshsig.Verify(strings.NewReader(token+"\r\n"), []byte(signature), []byte(key.Content), "gitea") != nil {
|
||||
log.Debug("VerifySSHKey sshsig.Verify failed: %v", err)
|
||||
return "", ErrSSHInvalidTokenSignature{
|
||||
Fingerprint: key.Fingerprint,
|
||||
err = sshsig.Verify(strings.NewReader(token), []byte(signature), []byte(key.Content), "gitea")
|
||||
if err != nil {
|
||||
// edge case for Windows based shells that will add CR LF if piped to ssh-keygen command
|
||||
// see https://github.com/PowerShell/PowerShell/issues/5974
|
||||
if sshsig.Verify(strings.NewReader(token+"\r\n"), []byte(signature), []byte(key.Content), "gitea") != nil {
|
||||
log.Debug("VerifySSHKey sshsig.Verify failed: %v", err)
|
||||
return "", ErrSSHInvalidTokenSignature{
|
||||
Fingerprint: key.Fingerprint,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
key.Verified = true
|
||||
if _, err := db.GetEngine(ctx).ID(key.ID).Cols("verified").Update(key); err != nil {
|
||||
return "", err
|
||||
}
|
||||
key.Verified = true
|
||||
if _, err := db.GetEngine(ctx).ID(key.ID).Cols("verified").Update(key); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if err := committer.Commit(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return key.Fingerprint, nil
|
||||
return key.Fingerprint, nil
|
||||
})
|
||||
}
|
||||
|
Reference in New Issue
Block a user