0
0
mirror of https://github.com/go-gitea/gitea.git synced 2026-04-04 12:26:12 +02:00

fix deadlock caused by differing contexts when retrieving group ancestry with ParentGroupCond/GetParentGroupChain when using a sqlite db

This commit is contained in:
☙◦ The Tablet ❀ GamerGirlandCo ◦❧ 2025-08-12 23:55:46 -04:00
parent 1f46d46151
commit 3711d573e6
No known key found for this signature in database
GPG Key ID: 924A5F6AF051E87C
3 changed files with 58 additions and 6 deletions

View File

@ -195,7 +195,7 @@ func ParentGroupCondByRepoID(ctx context.Context, repoID int64, idStr string) bu
if err != nil {
return builder.In(idStr)
}
return ParentGroupCond(idStr, g.ID)
return ParentGroupCond(ctx, idStr, g.ID)
}
type FindGroupsOptions struct {
@ -313,8 +313,8 @@ func GetParentGroupIDChain(ctx context.Context, groupID int64) (ids []int64, err
}
// ParentGroupCond returns a condition matching a group and its ancestors
func ParentGroupCond(idStr string, groupID int64) builder.Cond {
groupList, err := GetParentGroupIDChain(db.DefaultContext, groupID)
func ParentGroupCond(ctx context.Context, idStr string, groupID int64) builder.Cond {
groupList, err := GetParentGroupIDChain(ctx, groupID)
if err != nil {
log.Info("Error building group cond: %w", err)
return builder.NotIn(idStr)
@ -331,7 +331,7 @@ func UpdateGroup(ctx context.Context, group *Group) error {
func MoveGroup(ctx context.Context, group *Group, newParent int64, newSortOrder int) error {
sess := db.GetEngine(ctx)
ng, err := GetGroupByID(ctx, newParent)
if err != nil && !IsErrGroupNotExist(err) {
if !IsErrGroupNotExist(err) {
return err
}
if ng != nil {

View File

@ -10,7 +10,7 @@ import (
func GetTeamsWithAccessToGroup(ctx context.Context, orgID, groupID int64, mode perm.AccessMode) ([]*Team, error) {
teams := make([]*Team, 0)
inCond := group_model.ParentGroupCond("group_team.group_id", groupID)
inCond := group_model.ParentGroupCond(ctx, "group_team.group_id", groupID)
return teams, db.GetEngine(ctx).Distinct("team.*").Where("group_team.access_mode >= ?", mode).
Join("INNER", "group_team", "group_team.team_id = team.id and group_team.org_id = ?", orgID).
And("group_team.org_id = ?", orgID).
@ -21,7 +21,7 @@ func GetTeamsWithAccessToGroup(ctx context.Context, orgID, groupID int64, mode p
func GetTeamsWithAccessToGroupUnit(ctx context.Context, orgID, groupID int64, mode perm.AccessMode, unitType unit.Type) ([]*Team, error) {
teams := make([]*Team, 0)
inCond := group_model.ParentGroupCond("group_team.group_id", groupID)
inCond := group_model.ParentGroupCond(ctx, "group_team.group_id", groupID)
return teams, db.GetEngine(ctx).Where("group_team.access_mode >= ?", mode).
Join("INNER", "group_team", "group_team.team_id = team.id").
Join("INNER", "group_unit", "group_unit.team_id = team.id").

View File

@ -0,0 +1,52 @@
package group
import (
"code.gitea.io/gitea/models/db"
group_model "code.gitea.io/gitea/models/group"
organization_model "code.gitea.io/gitea/models/organization"
user_model "code.gitea.io/gitea/models/user"
"context"
"xorm.io/builder"
)
// FindGroupMembers finds all users who have access to a group via team membership
func FindGroupMembers(ctx context.Context, groupID int64, opts *organization_model.FindOrgMembersOpts) (user_model.UserList, error) {
cond := builder.
Select("`team_user`.uid").
From("team_user").
InnerJoin("org_user", "`org_user`.uid = team_user.uid").
InnerJoin("group_team", "`group_team`.team_id = team_user.team_id").
Where(builder.Eq{"`org_user`.org_id": opts.OrgID}).
And(group_model.ParentGroupCond(context.TODO(), "`group_team`.group_id", groupID))
if opts.PublicOnly() {
cond = cond.And(builder.Eq{"`org_user`.is_public": true})
}
sess := db.GetEngine(ctx).Where(builder.In("`user`.id", cond))
if opts.ListOptions.PageSize > 0 {
sess = db.SetSessionPagination(sess, opts)
users := make([]*user_model.User, 0, opts.ListOptions.PageSize)
return users, sess.Find(&users)
}
var users []*user_model.User
err := sess.Find(&users)
return users, err
}
func GetGroupTeams(ctx context.Context, groupID int64) (teams []*organization_model.Team, err error) {
err = db.GetEngine(ctx).
Where("`group_team`.group_id = ?", groupID).
Join("INNER", "group_team", "`group_team`.team_id = `team`.id").
Asc("`team`.name").
Find(&teams)
return
}
func IsGroupMember(ctx context.Context, groupID, userID int64) (bool, error) {
return db.GetEngine(ctx).
Where("`group_team`.group_id = ?", groupID).
Join("INNER", "group_team", "`group_team`.team_id = `team_user`.team_id").
And("`team_user`.uid = ?", userID).
Table("team_user").
Exist()
}