Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
148 changes: 71 additions & 77 deletions models/asymkey/gpg_key_add.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,96 +72,90 @@ func AddGPGKey(ctx context.Context, ownerID int64, content, token, signature str
return nil, err
}

ctx, committer, err := db.TxContext(ctx)
if err != nil {
return nil, err
}
defer committer.Close()

keys := make([]*GPGKey, 0, len(ekeys))

verified := false
// Handle provided signature
if signature != "" {
signer, err := openpgp.CheckArmoredDetachedSignature(ekeys, strings.NewReader(token), strings.NewReader(signature), nil)
if err != nil {
signer, err = openpgp.CheckArmoredDetachedSignature(ekeys, strings.NewReader(token+"\n"), strings.NewReader(signature), nil)
}
if err != nil {
signer, err = openpgp.CheckArmoredDetachedSignature(ekeys, strings.NewReader(token+"\r\n"), strings.NewReader(signature), nil)
}
if err != nil {
log.Debug("AddGPGKey CheckArmoredDetachedSignature failed: %v", err)
return nil, ErrGPGInvalidTokenSignature{
ID: ekeys[0].PrimaryKey.KeyIdString(),
Wrapped: err,
return db.WithTx2(ctx, func(ctx context.Context) ([]*GPGKey, error) {
keys := make([]*GPGKey, 0, len(ekeys))

verified := false
// Handle provided signature
if signature != "" {
signer, err := openpgp.CheckArmoredDetachedSignature(ekeys, strings.NewReader(token), strings.NewReader(signature), nil)
if err != nil {
signer, err = openpgp.CheckArmoredDetachedSignature(ekeys, strings.NewReader(token+"\n"), strings.NewReader(signature), nil)
}
if err != nil {
signer, err = openpgp.CheckArmoredDetachedSignature(ekeys, strings.NewReader(token+"\r\n"), strings.NewReader(signature), nil)
}
if err != nil {
log.Debug("AddGPGKey CheckArmoredDetachedSignature failed: %v", err)
return nil, ErrGPGInvalidTokenSignature{
ID: ekeys[0].PrimaryKey.KeyIdString(),
Wrapped: err,
}
}
ekeys = []*openpgp.Entity{signer}
verified = true
}
ekeys = []*openpgp.Entity{signer}
verified = true
}

if len(ekeys) > 1 {
id2key := map[string]*openpgp.Entity{}
newEKeys := make([]*openpgp.Entity, 0, len(ekeys))
for _, ekey := range ekeys {
id := ekey.PrimaryKey.KeyIdString()
if original, has := id2key[id]; has {
// Coalesce this with the other one
for _, subkey := range ekey.Subkeys {
if subkey.PublicKey == nil {
continue
}
found := false

for _, originalSubkey := range original.Subkeys {
if originalSubkey.PublicKey == nil {
if len(ekeys) > 1 {
id2key := map[string]*openpgp.Entity{}
newEKeys := make([]*openpgp.Entity, 0, len(ekeys))
for _, ekey := range ekeys {
id := ekey.PrimaryKey.KeyIdString()
if original, has := id2key[id]; has {
// Coalesce this with the other one
for _, subkey := range ekey.Subkeys {
if subkey.PublicKey == nil {
continue
}
if originalSubkey.PublicKey.KeyId == subkey.PublicKey.KeyId {
found = true
break
found := false

for _, originalSubkey := range original.Subkeys {
if originalSubkey.PublicKey == nil {
continue
}
if originalSubkey.PublicKey.KeyId == subkey.PublicKey.KeyId {
found = true
break
}
}
if !found {
original.Subkeys = append(original.Subkeys, subkey)
}
}
if !found {
original.Subkeys = append(original.Subkeys, subkey)
}
}
for name, identity := range ekey.Identities {
if _, has := original.Identities[name]; has {
continue
for name, identity := range ekey.Identities {
if _, has := original.Identities[name]; has {
continue
}
original.Identities[name] = identity
}
original.Identities[name] = identity
continue
}
continue
id2key[id] = ekey
newEKeys = append(newEKeys, ekey)
}
id2key[id] = ekey
newEKeys = append(newEKeys, ekey)
}
ekeys = newEKeys
}

for _, ekey := range ekeys {
// Key ID cannot be duplicated.
has, err := db.GetEngine(ctx).Where("key_id=?", ekey.PrimaryKey.KeyIdString()).
Get(new(GPGKey))
if err != nil {
return nil, err
} else if has {
return nil, ErrGPGKeyIDAlreadyUsed{ekey.PrimaryKey.KeyIdString()}
ekeys = newEKeys
}

// Get DB session
for _, ekey := range ekeys {
// Key ID cannot be duplicated.
has, err := db.GetEngine(ctx).Where("key_id=?", ekey.PrimaryKey.KeyIdString()).
Get(new(GPGKey))
if err != nil {
return nil, err
} else if has {
return nil, ErrGPGKeyIDAlreadyUsed{ekey.PrimaryKey.KeyIdString()}
}

key, err := parseGPGKey(ctx, ownerID, ekey, verified)
if err != nil {
return nil, err
}
key, err := parseGPGKey(ctx, ownerID, ekey, verified)
if err != nil {
return nil, err
}

if err = addGPGKey(ctx, key, content); err != nil {
return nil, err
if err = addGPGKey(ctx, key, content); err != nil {
return nil, err
}
keys = append(keys, key)
}
keys = append(keys, key)
}
return keys, committer.Commit()
return keys, nil
})
}
173 changes: 81 additions & 92 deletions models/git/branch.go
Original file line number Diff line number Diff line change
Expand Up @@ -334,122 +334,111 @@ func FindRenamedBranch(ctx context.Context, repoID int64, from string) (branch *

// RenameBranch rename a branch
func RenameBranch(ctx context.Context, repo *repo_model.Repository, from, to string, gitAction func(ctx context.Context, isDefault bool) error) (err error) {
ctx, committer, err := db.TxContext(ctx)
if err != nil {
return err
}
defer committer.Close()
return db.WithTx(ctx, func(ctx context.Context) error {
sess := db.GetEngine(ctx)

sess := db.GetEngine(ctx)
// check whether from branch exist
var branch Branch
exist, err := db.GetEngine(ctx).Where("repo_id=? AND name=?", repo.ID, from).Get(&branch)
if err != nil {
return err
} else if !exist || branch.IsDeleted {
return ErrBranchNotExist{
RepoID: repo.ID,
BranchName: from,
}
}

// check whether from branch exist
var branch Branch
exist, err := db.GetEngine(ctx).Where("repo_id=? AND name=?", repo.ID, from).Get(&branch)
if err != nil {
return err
} else if !exist || branch.IsDeleted {
return ErrBranchNotExist{
RepoID: repo.ID,
BranchName: from,
// check whether to branch exist or is_deleted
var dstBranch Branch
exist, err = db.GetEngine(ctx).Where("repo_id=? AND name=?", repo.ID, to).Get(&dstBranch)
if err != nil {
return err
}
}
if exist {
if !dstBranch.IsDeleted {
return ErrBranchAlreadyExists{
BranchName: to,
}
}

// check whether to branch exist or is_deleted
var dstBranch Branch
exist, err = db.GetEngine(ctx).Where("repo_id=? AND name=?", repo.ID, to).Get(&dstBranch)
if err != nil {
return err
}
if exist {
if !dstBranch.IsDeleted {
return ErrBranchAlreadyExists{
BranchName: to,
if _, err := db.GetEngine(ctx).ID(dstBranch.ID).NoAutoCondition().Delete(&dstBranch); err != nil {
return err
}
}

if _, err := db.GetEngine(ctx).ID(dstBranch.ID).NoAutoCondition().Delete(&dstBranch); err != nil {
// 1. update branch in database
if n, err := sess.Where("repo_id=? AND name=?", repo.ID, from).Update(&Branch{
Name: to,
}); err != nil {
return err
} else if n <= 0 {
return ErrBranchNotExist{
RepoID: repo.ID,
BranchName: from,
}
}
}

// 1. update branch in database
if n, err := sess.Where("repo_id=? AND name=?", repo.ID, from).Update(&Branch{
Name: to,
}); err != nil {
return err
} else if n <= 0 {
return ErrBranchNotExist{
RepoID: repo.ID,
BranchName: from,
// 2. update default branch if needed
isDefault := repo.DefaultBranch == from
if isDefault {
repo.DefaultBranch = to
_, err = sess.ID(repo.ID).Cols("default_branch").Update(repo)
if err != nil {
return err
}
}
}

// 2. update default branch if needed
isDefault := repo.DefaultBranch == from
if isDefault {
repo.DefaultBranch = to
_, err = sess.ID(repo.ID).Cols("default_branch").Update(repo)
// 3. Update protected branch if needed
protectedBranch, err := GetProtectedBranchRuleByName(ctx, repo.ID, from)
if err != nil {
return err
}
}

// 3. Update protected branch if needed
protectedBranch, err := GetProtectedBranchRuleByName(ctx, repo.ID, from)
if err != nil {
return err
}
if protectedBranch != nil {
// there is a protect rule for this branch
protectedBranch.RuleName = to
if _, err = sess.ID(protectedBranch.ID).Cols("branch_name").Update(protectedBranch); err != nil {
return err
}
} else {
// some glob protect rules may match this branch
protected, err := IsBranchProtected(ctx, repo.ID, from)
if err != nil {
return err
}
if protected {
return ErrBranchIsProtected
}
}

if protectedBranch != nil {
// there is a protect rule for this branch
protectedBranch.RuleName = to
_, err = sess.ID(protectedBranch.ID).Cols("branch_name").Update(protectedBranch)
// 4. Update all not merged pull request base branch name
_, err = sess.Table("pull_request").Where("base_repo_id=? AND base_branch=? AND has_merged=?",
repo.ID, from, false).
Update(map[string]any{"base_branch": to})
if err != nil {
return err
}
} else {
// some glob protect rules may match this branch
protected, err := IsBranchProtected(ctx, repo.ID, from)
if err != nil {

// 4.1 Update all not merged pull request head branch name
if _, err = sess.Table("pull_request").Where("head_repo_id=? AND head_branch=? AND has_merged=?",
repo.ID, from, false).
Update(map[string]any{"head_branch": to}); err != nil {
return err
}
if protected {
return ErrBranchIsProtected
}
}

// 4. Update all not merged pull request base branch name
_, err = sess.Table("pull_request").Where("base_repo_id=? AND base_branch=? AND has_merged=?",
repo.ID, from, false).
Update(map[string]any{"base_branch": to})
if err != nil {
return err
}

// 4.1 Update all not merged pull request head branch name
if _, err = sess.Table("pull_request").Where("head_repo_id=? AND head_branch=? AND has_merged=?",
repo.ID, from, false).
Update(map[string]any{"head_branch": to}); err != nil {
return err
}

// 5. insert renamed branch record
renamedBranch := &RenamedBranch{
RepoID: repo.ID,
From: from,
To: to,
}
err = db.Insert(ctx, renamedBranch)
if err != nil {
return err
}

// 6. do git action
if err = gitAction(ctx, isDefault); err != nil {
return err
}
// 5. insert renamed branch record
if err = db.Insert(ctx, &RenamedBranch{
RepoID: repo.ID,
From: from,
To: to,
}); err != nil {
return err
}

return committer.Commit()
// 6. do git action
return gitAction(ctx, isDefault)
})
}

type FindRecentlyPushedNewBranchesOptions struct {
Expand Down
Loading