mirror of
https://github.com/go-gitea/gitea.git
synced 2026-04-04 05:45:23 +02:00
148 lines
3.9 KiB
Go
148 lines
3.9 KiB
Go
// Copyright 2025 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package group
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"code.gitea.io/gitea/models/db"
|
|
group_model "code.gitea.io/gitea/models/group"
|
|
org_model "code.gitea.io/gitea/models/organization"
|
|
"code.gitea.io/gitea/models/perm"
|
|
|
|
"xorm.io/builder"
|
|
)
|
|
|
|
func AddTeamToGroup(ctx context.Context, group *group_model.Group, tname string) error {
|
|
t, err := org_model.GetTeam(ctx, group.OwnerID, tname)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
has := group_model.HasTeamGroup(ctx, group.OwnerID, t.ID, group.ID)
|
|
if has {
|
|
return fmt.Errorf("team '%s' already exists in group[%d]", tname, group.ID)
|
|
}
|
|
parentGroup, err := group_model.FindGroupTeamByTeamID(ctx, group.ID, t.ID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
mode := t.AccessMode
|
|
canCreateIn := t.CanCreateOrgRepo
|
|
if parentGroup != nil {
|
|
mode = max(t.AccessMode, parentGroup.AccessMode)
|
|
canCreateIn = parentGroup.CanCreateIn || t.CanCreateOrgRepo
|
|
}
|
|
if err = group.LoadParentGroup(ctx); err != nil {
|
|
return err
|
|
}
|
|
err = group_model.AddTeamGroup(ctx, group.ID, t.ID, group.ID, mode, canCreateIn)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func DeleteTeamFromGroup(ctx context.Context, group *group_model.Group, org int64, teamName string) error {
|
|
team, err := org_model.GetTeam(ctx, org, teamName)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return group_model.RemoveTeamGroup(ctx, org, team.ID, group.ID)
|
|
}
|
|
|
|
func UpdateGroupTeam(ctx context.Context, gt *group_model.RepoGroupTeam) (err error) {
|
|
ctx, committer, err := db.TxContext(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer committer.Close()
|
|
sess := db.GetEngine(ctx)
|
|
|
|
if _, err = sess.ID(gt.ID).AllCols().Update(gt); err != nil {
|
|
return fmt.Errorf("update: %w", err)
|
|
}
|
|
for _, unit := range gt.Units {
|
|
unit.TeamID = gt.TeamID
|
|
if _, err = sess.
|
|
Where("team_id=?", gt.TeamID).
|
|
And("group_id=?", gt.GroupID).
|
|
And("type = ?", unit.Type).
|
|
Update(unit); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return committer.Commit()
|
|
}
|
|
|
|
// RecalculateGroupAccess recalculates team access to a group.
|
|
// should only be called if and only if a group was moved from another group.
|
|
func RecalculateGroupAccess(ctx context.Context, g *group_model.Group, isNew bool) error {
|
|
var err error
|
|
sess := db.GetEngine(ctx)
|
|
if err = g.LoadParentGroup(ctx); err != nil {
|
|
return err
|
|
}
|
|
var teams []*org_model.Team
|
|
if g.ParentGroup == nil {
|
|
teams, err = org_model.FindOrgTeams(ctx, g.OwnerID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
} else {
|
|
teams, err = org_model.GetTeamsWithAccessToGroup(ctx, g.OwnerID, g.ParentGroupID, perm.AccessModeRead)
|
|
}
|
|
for _, t := range teams {
|
|
var gt *group_model.RepoGroupTeam
|
|
if gt, err = group_model.FindGroupTeamByTeamID(ctx, g.ParentGroupID, t.ID); err != nil {
|
|
return err
|
|
}
|
|
if gt != nil {
|
|
if err = group_model.UpdateTeamGroup(ctx, g.OwnerID, t.ID, g.ID, gt.AccessMode, gt.CanCreateIn, isNew); err != nil {
|
|
return err
|
|
}
|
|
} else {
|
|
if err = group_model.UpdateTeamGroup(ctx, g.OwnerID, t.ID, g.ID, t.AccessMode, t.IsOwnerTeam() || t.AccessMode >= perm.AccessModeAdmin || t.CanCreateOrgRepo, isNew); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
if err = t.LoadUnits(ctx); err != nil {
|
|
return err
|
|
}
|
|
for _, u := range t.Units {
|
|
newAccessMode := u.AccessMode
|
|
if g.ParentGroup == nil {
|
|
gu, err := group_model.GetGroupUnit(ctx, g.ID, t.ID, u.Type)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
newAccessMode = min(newAccessMode, gu.AccessMode)
|
|
}
|
|
if isNew {
|
|
if _, err = sess.Table("repo_group_unit").Insert(&group_model.RepoGroupUnit{
|
|
Type: u.Type,
|
|
TeamID: t.ID,
|
|
GroupID: g.ID,
|
|
AccessMode: newAccessMode,
|
|
}); err != nil {
|
|
return err
|
|
}
|
|
} else {
|
|
if _, err = sess.Table("repo_group_unit").Where(builder.Eq{
|
|
"type": u.Type,
|
|
"team_id": t.ID,
|
|
"group_id": g.ID,
|
|
}).Cols("access_mode").Update(&group_model.RepoGroupUnit{
|
|
AccessMode: newAccessMode,
|
|
}); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return err
|
|
}
|