fix(org,team): guard the owner team rename, show permission-only team access and tidy member lookups

Signed-off-by: bircni <bircni@icloud.com>
This commit is contained in:
bircni committed 2026-10-18 20:02:11 +02:00
1 parent dd9e05c6b9
commit dfb56eae67
10 files changed
+124 -12

No files matched your search

+9 -5
View File
@@ -197,13 +197,13 @@ $ tea team view 2 --json units`,
return writeView(a, cmd, team, func(team services.Team) terminal.View {
var units []string
for _, unit := range slices.Concat(services.TeamUnits, services.ExternalTeamUnits) {
if access := team.Units[unit]; access != "" && access != "none" {
if access := team.UnitLevel(unit); access != "none" {
units = append(units, strings.TrimPrefix(unit, "repo.")+": "+access)
}
}
memberNames := ""
if !membersHidden {
memberNames = listedNames(members, func(member services.OrganizationMember) string { return member.Username })
memberNames = listedNames(members, func(member services.TeamMember) string { return member.Username })
}
repositories := listedNames(repos, func(repo services.Repository) string { return repo.FullName })
if team.AllRepositories {
@@ -425,6 +425,10 @@ $ tea team edit acme/developers --name devs --description "Core developers"`,
if opts.Units != nil && !opts.ReplaceUnits && (team.Permission == "admin" || team.Permission == "owner") {
return clierr.Wrap(clierr.Usage, fmt.Errorf("--unit cannot restrict the %s access of team %s; pass --permission read or write, or --unit-replace", team.Permission, team.Slug()))
}
// Gitea finds the owner team by its name, so renaming it leaves the organization without owners.
if team.Permission == "owner" && opts.Name != nil && !strings.EqualFold(*opts.Name, team.Name) {
return clierr.Wrap(clierr.Usage, fmt.Errorf("team %s is the organization's owner team and cannot be renamed", team.Slug()))
}
edited, err := service.Edit(cmd.Context(), team.ID, opts)
if err != nil {
return err
@@ -502,9 +506,9 @@ also makes them a member of the organization.`}
if err != nil {
return err
}
return writeTable(a, cmd, members.Items, listSpec[services.OrganizationMember]{
return writeTable(a, cmd, members.Items, listSpec[services.TeamMember]{
Columns: []terminal.Column{{Header: "Username"}, {Header: "Name", Flex: true}},
Row: func(member services.OrganizationMember) []terminal.Cell {
Row: func(member services.TeamMember) []terminal.Cell {
return []terminal.Cell{{Text: member.Username, Link: webURL(target, member.Username), Bold: true}, {Text: member.FullName}}
},
Context: "members of team " + team.Slug(), Empty: "no members in team " + team.Slug(),
@@ -543,7 +547,7 @@ $ tea team member add 2 bob carol`,
Annotations: map[string]string{"tea.text": "team membership changes do not return a resource", "tea.confirm": "true", "tea.arguments": teamArguments},
ValidArgsFunction: a.completeTeamThen(func(ctx context.Context, t target, team services.Team) ([]cobra.Completion, error) {
members, err := services.Teams{Client: t.client}.Members(ctx, team.ID, completionLimit, 1)
return describe(members.Items, func(member services.OrganizationMember) (string, string) { return member.Username, member.FullName }), err
return describe(members.Items, func(member services.TeamMember) (string, string) { return member.Username, member.FullName }), err
}),
RunE: func(cmd *cobra.Command, args []string) error {
_, service, team, err := a.team(cmd, args[0])