-
-
Notifications
You must be signed in to change notification settings - Fork 7.1k
feat: manage bot accounts from the admin UI, API and CLI #38966
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
joestump-agent
wants to merge
32
commits into
go-gitea:main
Choose a base branch
from
joestump:feat/bot-user-ui
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
32 commits
Select commit
Hold shift + click to select a range
63b8cba
ui
bircni 966e1b4
refactor: share access token scope parsing between admin and user han…
bircni aade8ce
fix(auth): block bot and organization accounts from interactive sign-in
bircni 1213500
feat: convert users between individual and bot via UI, API and CLI
bircni 5100868
docs: add bot user design document
bircni 5e6da3a
fix: harden bot account creation, conversion and token management
bircni fa53f69
refactor
bircni 30a0cb7
fix lint
bircni 921f945
fixes
bircni ebbe09b
fix(admin): block impersonation of bot users
bircni 58b8e51
feat(admin): add user type filter to the admin user list
bircni c559072
adress comments
bircni 8ffb179
adress comments
bircni 4207ac4
cleanup
bircni 17ef61a
adress feedback
bircni 5b0bf5a
cleanup
bircni 4997349
review: address remaining feedback on bot-account PR
joestump-agent d8efcf5
test(activities): cover org-branch bot skip in repo transfer notifica…
joestump bd3affa
docs: restore and expand the bot user design document
joestump 24ead7f
cleanup
bircni 1577db5
fix: repair tests after rebase onto new form-binding API
joestump-agent dd6b39d
Merge branch 'main' into feat/bot-user-ui
joestump da2a1bd
fix: use checked type assertions in handleAdminCreateUserError
joestump-agent 45b482b
Merge branch 'main' into feat/bot-user-ui
joestump 62ec566
Merge remote-tracking branch 'upstream/main' into restore/bot-user-ui
joestump-agent 86c9a94
review: address silverwind and copilot feedback on bot-account PR
joestump-agent 32cee65
Merge branch 'main' into feat/bot-user-ui
joestump a70845f
fix: resolve merge conflict in reverseproxy_test.go
joestump-agent 138e70a
refactor: prefix admin user form classes with js- for grepability
joestump-agent 199cf8a
Merge branch 'main' into feat/bot-user-ui
joestump c8381d9
Merge remote-tracking branch 'upstream/main' into fix-38966
joestump-agent 7c82f14
Merge branch 'main' into feat/bot-user-ui
joestump File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| // Copyright 2026 The Gitea Authors. All rights reserved. | ||
| // SPDX-License-Identifier: MIT | ||
|
|
||
| package cmd | ||
|
|
||
| import ( | ||
| "context" | ||
| "fmt" | ||
|
|
||
| user_model "gitea.dev/models/user" | ||
| "gitea.dev/modules/setting" | ||
| user_service "gitea.dev/services/user" | ||
|
|
||
| "github.com/urfave/cli/v3" | ||
| ) | ||
|
|
||
| func microcmdUserChangeType() *cli.Command { | ||
| return &cli.Command{ | ||
| Name: "change-type", | ||
| Usage: "Convert a user between the individual and bot types", | ||
| Action: runChangeUserType, | ||
| Flags: []cli.Flag{ | ||
| &cli.StringFlag{ | ||
| Name: "username", | ||
| Aliases: []string{"u"}, | ||
| Usage: "The user to convert", | ||
| Required: true, | ||
| }, | ||
| &cli.StringFlag{ | ||
| Name: "user-type", | ||
| Usage: "New user type: individual or bot", | ||
| Required: true, | ||
| }, | ||
| }, | ||
| } | ||
| } | ||
|
|
||
| func runChangeUserType(ctx context.Context, c *cli.Command) error { | ||
| targetType, err := user_model.ParseUserType(c.String("user-type")) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| if !setting.IsInTesting { | ||
| if err := initDB(ctx); err != nil { | ||
| return err | ||
| } | ||
| } | ||
|
|
||
| user, err := user_model.GetUserByName(ctx, c.String("username")) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| if err := user_service.ConvertUserType(ctx, user, targetType); err != nil { | ||
| return err | ||
| } | ||
|
|
||
| fmt.Printf("%s's type has been successfully changed to %s!\n", user.Name, c.String("user-type")) | ||
|
Check failure on line 59 in cmd/admin_user_change_type.go
|
||
| return nil | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| // Copyright 2026 The Gitea Authors. All rights reserved. | ||
| // SPDX-License-Identifier: MIT | ||
|
|
||
| package cmd | ||
|
|
||
| import ( | ||
| "io" | ||
| "testing" | ||
|
|
||
| "gitea.dev/models/db" | ||
| "gitea.dev/models/unittest" | ||
| user_model "gitea.dev/models/user" | ||
|
|
||
| "github.com/stretchr/testify/assert" | ||
| "github.com/stretchr/testify/require" | ||
| ) | ||
|
|
||
| func TestChangeTypeCommand(t *testing.T) { | ||
| ctx := t.Context() | ||
|
|
||
| defer func() { | ||
| require.NoError(t, db.TruncateBeans(t.Context(), &user_model.User{})) | ||
| require.NoError(t, db.TruncateBeans(t.Context(), &user_model.EmailAddress{})) | ||
| }() | ||
|
|
||
| t.Run("convert individual to bot and back", func(t *testing.T) { | ||
| require.NoError(t, microcmdUserCreate().Run(ctx, []string{"create", "--username", "testuser", "--email", "testuser@gitea.local", "--random-password"})) | ||
| user := unittest.AssertExistsAndLoadBean(t, &user_model.User{LowerName: "testuser"}) | ||
| assert.True(t, user.IsIndividual()) | ||
|
|
||
| require.NoError(t, microcmdUserChangeType().Run(ctx, []string{"change-type", "--username", "testuser", "--user-type", "bot"})) | ||
| user = unittest.AssertExistsAndLoadBean(t, &user_model.User{LowerName: "testuser"}) | ||
| assert.True(t, user.IsTypeBot()) | ||
| assert.Empty(t, user.Passwd) | ||
|
|
||
| require.NoError(t, microcmdUserChangeType().Run(ctx, []string{"change-type", "--username", "testuser", "--user-type", "individual"})) | ||
| user = unittest.AssertExistsAndLoadBean(t, &user_model.User{LowerName: "testuser"}) | ||
| assert.True(t, user.IsIndividual()) | ||
| }) | ||
|
|
||
| t.Run("failure cases", func(t *testing.T) { | ||
| testCases := []struct { | ||
| name string | ||
| args []string | ||
| expectedErr string | ||
| }{ | ||
| { | ||
| name: "invalid user type", | ||
| args: []string{"change-type", "--username", "testuser", "--user-type", "invalid"}, | ||
| expectedErr: "invalid user type", | ||
| }, | ||
| { | ||
| name: "missing username", | ||
| args: []string{"change-type", "--user-type", "bot"}, | ||
| expectedErr: `"username" not set`, | ||
| }, | ||
| { | ||
| name: "missing user-type", | ||
| args: []string{"change-type", "--username", "testuser"}, | ||
| expectedErr: `"user-type" not set`, | ||
| }, | ||
| } | ||
|
|
||
| for _, tc := range testCases { | ||
| t.Run(tc.name, func(t *testing.T) { | ||
| cmd := microcmdUserChangeType() | ||
| cmd.Writer, cmd.ErrWriter = io.Discard, io.Discard | ||
| err := cmd.Run(ctx, tc.args) | ||
| require.Error(t, err) | ||
| require.Contains(t, err.Error(), tc.expectedErr) | ||
| }) | ||
| } | ||
| }) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.