fix(admin): offer --purge for users who own repositories and show roles

admin user delete of a user who owns repositories failed with Gitea's raw
HTTP 422. The error now says what blocks the deletion and how to proceed,
and --purge deletes the account with its repositories, packages and
organization memberships after typing the username on a terminal.

admin user list shows ROLE and STATUS columns (admin, restricted, user;
active, inactive, login prohibited) with the email and creation date
instead of admin=true/active=true cells, and --query filters by username,
name or email. admin user view shows the account instead of its list
row. create asks for a missing username and email address with readable
labels and re-asks for invalid answers, mutations print ✓ lines, usernames
complete, and every command has examples.

Signed-off-by: bircni <bircni@icloud.com>
This commit is contained in:
bircni committed 2026-10-11 23:42:49 +02:00
1 parent ef8cfbc4b7
commit c18dae6685
6 files changed
+465 -195

No files matched your search

+26
View File
@@ -10,6 +10,7 @@ import (
"net/url"
"strconv"
"strings"
"time"
"gitea.dev/tea/internal/clierr"
"gitea.dev/tea/internal/services"
@@ -35,6 +36,22 @@ func (a *application) jsonResult(cmd *cobra.Command, item any) error {
return a.writeJSON(cmd, item)
}
// timeField shows an API timestamp relative to now on a TTY, and as RFC3339 for scripts.
func timeField(label, raw string, d terminal.Display) terminal.Field {
t := terminal.ParseTime(raw)
if t.IsZero() {
return terminal.Field{Label: label}
}
if !d.TTY {
return terminal.Field{Label: label, Value: terminal.Timestamp(t)}
}
now := d.Now
if now.IsZero() {
now = time.Now()
}
return terminal.Field{Label: label, Value: terminal.RelativeTime(now, t)}
}
func yesNo(value bool) string {
if value {
return "yes"
@@ -111,6 +128,7 @@ $ tea org list --all`,
}
cmd.Flags().BoolVar(&all, "all", false, "List every organization you can see instead of your memberships")
cmd.Flags().StringVar(&username, "username", "", "List the organizations of this user")
_ = cmd.RegisterFlagCompletionFunc("username", a.completeInstanceUsers())
pageFlags(cmd, &limit, &page)
return cmd
}
@@ -469,3 +487,11 @@ func (a *application) organizationMemberRemoveCommand() *cobra.Command {
},
}
}
// completeInstanceUsers completes the usernames of the instance that contain the typed text.
func (a *application) completeInstanceUsers() cobra.CompletionFunc {
return a.apiCompletion(false, func(ctx context.Context, t target, toComplete string) ([]cobra.Completion, error) {
users, err := (services.AdminUsers{Client: t.client}).Search(ctx, toComplete, completionLimit)
return describe(users, func(user services.AdminUser) (string, string) { return user.Username, user.FullName }), err
})
}