|
|
|
|
@@ -6,7 +6,7 @@ package org
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"errors"
|
|
|
|
|
"fmt"
|
|
|
|
|
"maps"
|
|
|
|
|
"net/http"
|
|
|
|
|
"net/url"
|
|
|
|
|
"path"
|
|
|
|
|
@@ -327,51 +327,25 @@ func NewTeam(ctx *context.Context) {
|
|
|
|
|
ctx.HTML(http.StatusOK, tplTeamNew)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// FIXME: TEAM-UNIT-PERMISSION: this design is not right, when a new unit is added in the future,
|
|
|
|
|
// The existing teams won't inherit the correct admin permission for the new unit.
|
|
|
|
|
// The full history is like this:
|
|
|
|
|
// 1. There was only "team", no "team unit", so "team.authorize" was used to determine the team permission.
|
|
|
|
|
// 2. Later, "team unit" was introduced, then the usage of "team.authorize" became inconsistent, and causes various bugs.
|
|
|
|
|
// - Sometimes, "team.authorize" is used to determine the team permission, e.g. admin, owner
|
|
|
|
|
// - Sometimes, "team unit" is used not really used and "team unit" is used.
|
|
|
|
|
// - Some functions like `GetTeamsWithAccessToAnyRepoUnit` use both.
|
|
|
|
|
//
|
|
|
|
|
// 3. After introducing "team unit" and more unclear changes, it becomes difficult to maintain team permissions.
|
|
|
|
|
// - Org owner need to click the permission for each unit, but can't just set a common "write" permission for all units.
|
|
|
|
|
//
|
|
|
|
|
// Ideally, "team.authorize=write" should mean the team has write access to all units including newly (future) added ones.
|
|
|
|
|
func getUnitPerms(forms url.Values, teamPermission perm.AccessMode) map[unit_model.Type]perm.AccessMode {
|
|
|
|
|
unitPerms := make(map[unit_model.Type]perm.AccessMode)
|
|
|
|
|
func paresFormTeamUnits(orgID int64, forms url.Values) (units []*org_model.TeamUnit) {
|
|
|
|
|
for _, ut := range unit_model.AllRepoUnitTypes {
|
|
|
|
|
// Default access mode is none
|
|
|
|
|
unitPerms[ut] = perm.AccessModeNone
|
|
|
|
|
|
|
|
|
|
v, ok := forms[fmt.Sprintf("unit_%d", ut)]
|
|
|
|
|
if ok {
|
|
|
|
|
vv, _ := strconv.Atoi(v[0])
|
|
|
|
|
if teamPermission >= perm.AccessModeAdmin {
|
|
|
|
|
unitPerms[ut] = teamPermission
|
|
|
|
|
// Don't allow `TypeExternal{Tracker,Wiki}` to influence this as they can only be set to READ perms.
|
|
|
|
|
if ut == unit_model.TypeExternalTracker || ut == unit_model.TypeExternalWiki {
|
|
|
|
|
unitPerms[ut] = perm.AccessModeRead
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
unitPerms[ut] = perm.AccessMode(vv)
|
|
|
|
|
if unitPerms[ut] >= perm.AccessModeAdmin {
|
|
|
|
|
unitPerms[ut] = perm.AccessModeWrite
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
v, ok := forms["unit_"+strconv.Itoa(ut.Value())]
|
|
|
|
|
if !ok {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
vv, _ := strconv.Atoi(v[0])
|
|
|
|
|
mode := perm.AccessMode(vv)
|
|
|
|
|
mode = min(mode, perm.AccessModeWrite, unit_model.Units[ut].MaxPerm())
|
|
|
|
|
units = append(units, &org_model.TeamUnit{OrgID: orgID, Type: ut, AccessMode: mode})
|
|
|
|
|
}
|
|
|
|
|
return unitPerms
|
|
|
|
|
return units
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// NewTeamPost response for create new team
|
|
|
|
|
func NewTeamPost(ctx *context.Context) {
|
|
|
|
|
form := web.GetForm[*forms.CreateTeamForm](ctx)
|
|
|
|
|
includesAllRepositories := form.RepoAccess == "all"
|
|
|
|
|
teamPermission := perm.ParseAccessMode(form.Permission, perm.AccessModeNone, perm.AccessModeAdmin)
|
|
|
|
|
unitPerms := getUnitPerms(ctx.Req.Form, teamPermission)
|
|
|
|
|
teamPermission := perm.ParseAccessMode(form.Permission, perm.AccessModeNone, perm.AccessModeWrite, perm.AccessModeAdmin)
|
|
|
|
|
|
|
|
|
|
t := &org_model.Team{
|
|
|
|
|
OrgID: ctx.Org.Organization.ID,
|
|
|
|
|
@@ -383,16 +357,6 @@ func NewTeamPost(ctx *context.Context) {
|
|
|
|
|
Visibility: org_model.NormalizeTeamVisibility(form.Visibility),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
units := make([]*org_model.TeamUnit, 0, len(unitPerms))
|
|
|
|
|
for tp, perm := range unitPerms {
|
|
|
|
|
units = append(units, &org_model.TeamUnit{
|
|
|
|
|
OrgID: ctx.Org.Organization.ID,
|
|
|
|
|
Type: tp,
|
|
|
|
|
AccessMode: perm,
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
t.Units = units
|
|
|
|
|
|
|
|
|
|
ctx.Data["Title"] = ctx.Org.Organization.FullName
|
|
|
|
|
ctx.Data["PageIsOrgTeams"] = true
|
|
|
|
|
ctx.Data["PageIsOrgTeamsNew"] = true
|
|
|
|
|
@@ -404,9 +368,12 @@ func NewTeamPost(ctx *context.Context) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if t.AccessMode < perm.AccessModeAdmin && len(unitPerms) == 0 {
|
|
|
|
|
ctx.RenderWithErrDeprecated(ctx.Tr("form.team_no_units_error"), tplTeamNew, &form)
|
|
|
|
|
return
|
|
|
|
|
if t.AccessMode == perm.AccessModeNone {
|
|
|
|
|
t.Units = paresFormTeamUnits(ctx.Org.Organization.ID, ctx.Req.Form)
|
|
|
|
|
if len(t.Units) == 0 {
|
|
|
|
|
ctx.RenderWithErrDeprecated(ctx.Tr("form.team_no_units_error"), tplTeamNew, &form)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if err := org_service.NewTeam(ctx, t); err != nil {
|
|
|
|
|
@@ -545,10 +512,9 @@ func EditTeam(ctx *context.Context) {
|
|
|
|
|
// EditTeamPost response for modify team information
|
|
|
|
|
func EditTeamPost(ctx *context.Context) {
|
|
|
|
|
form := web.GetForm[*forms.CreateTeamForm](ctx)
|
|
|
|
|
|
|
|
|
|
t := ctx.Org.Team
|
|
|
|
|
teamPermission := perm.ParseAccessMode(form.Permission, perm.AccessModeNone, perm.AccessModeAdmin)
|
|
|
|
|
unitPerms := getUnitPerms(ctx.Req.Form, teamPermission)
|
|
|
|
|
isAuthChanged := false
|
|
|
|
|
teamPermission := perm.ParseAccessMode(form.Permission, perm.AccessModeNone, perm.AccessModeWrite, perm.AccessModeAdmin)
|
|
|
|
|
isIncludeAllChanged := false
|
|
|
|
|
includesAllRepositories := form.RepoAccess == "all"
|
|
|
|
|
|
|
|
|
|
@@ -557,13 +523,10 @@ func EditTeamPost(ctx *context.Context) {
|
|
|
|
|
ctx.Data["Team"] = t
|
|
|
|
|
ctx.Data["Units"] = unit_model.Units
|
|
|
|
|
|
|
|
|
|
oldTeamAccessMode := t.AccessMode
|
|
|
|
|
if !t.IsOwnerTeam() {
|
|
|
|
|
t.Name = form.TeamName
|
|
|
|
|
if t.AccessMode != teamPermission {
|
|
|
|
|
isAuthChanged = true
|
|
|
|
|
t.AccessMode = teamPermission
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
t.AccessMode = teamPermission
|
|
|
|
|
if t.IncludesAllRepositories != includesAllRepositories {
|
|
|
|
|
isIncludeAllChanged = true
|
|
|
|
|
t.IncludesAllRepositories = includesAllRepositories
|
|
|
|
|
@@ -576,28 +539,22 @@ func EditTeamPost(ctx *context.Context) {
|
|
|
|
|
t.Visibility = structs.VisibleTypeLimited
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
t.Description = form.Description
|
|
|
|
|
units := make([]*org_model.TeamUnit, 0, len(unitPerms))
|
|
|
|
|
for tp, perm := range unitPerms {
|
|
|
|
|
units = append(units, &org_model.TeamUnit{
|
|
|
|
|
OrgID: t.OrgID,
|
|
|
|
|
TeamID: t.ID,
|
|
|
|
|
Type: tp,
|
|
|
|
|
AccessMode: perm,
|
|
|
|
|
})
|
|
|
|
|
oldTeamUnitsMap := t.GetUnitsMap()
|
|
|
|
|
if t.AccessMode == perm.AccessModeNone {
|
|
|
|
|
t.Units = paresFormTeamUnits(ctx.Org.Organization.ID, ctx.Req.Form)
|
|
|
|
|
if len(t.Units) == 0 {
|
|
|
|
|
ctx.RenderWithErrDeprecated(ctx.Tr("form.team_no_units_error"), tplTeamNew, &form)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
t.Units = units
|
|
|
|
|
|
|
|
|
|
if ctx.HasError() {
|
|
|
|
|
ctx.HTML(http.StatusOK, tplTeamNew)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if t.AccessMode < perm.AccessModeAdmin && len(unitPerms) == 0 {
|
|
|
|
|
ctx.RenderWithErrDeprecated(ctx.Tr("form.team_no_units_error"), tplTeamNew, &form)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
isAuthChanged := oldTeamAccessMode != t.AccessMode || !maps.Equal(oldTeamUnitsMap, t.GetUnitsMap())
|
|
|
|
|
t.Description = form.Description
|
|
|
|
|
if err := org_service.UpdateTeam(ctx, t, isAuthChanged, isIncludeAllChanged); err != nil {
|
|
|
|
|
ctx.Data["Err_TeamName"] = true
|
|
|
|
|
switch {
|
|
|
|
|
|