Skip to content

Commit f7b1996

Browse files
kemzebwxiaoguang
authored andcommitted
Add new CLI flags to set name and scopes when creating a user with access token (go-gitea#34080)
Resolves go-gitea#33474. --------- Co-authored-by: wxiaoguang <[email protected]> (cherry picked from commit 55a69ae)
1 parent 02d9c7c commit f7b1996

File tree

4 files changed

+50
-12
lines changed

4 files changed

+50
-12
lines changed

cmd/admin_user_create.go

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package cmd
66
import (
77
"errors"
88
"fmt"
9+
"strings"
910

1011
auth_model "forgejo.org/models/auth"
1112
"forgejo.org/models/db"
@@ -61,6 +62,16 @@ var microcmdUserCreate = &cli.Command{
6162
Name: "access-token",
6263
Usage: "Generate access token for the user",
6364
},
65+
&cli.StringFlag{
66+
Name: "access-token-name",
67+
Usage: `Name of the generated access token`,
68+
Value: "gitea-admin",
69+
},
70+
&cli.StringFlag{
71+
Name: "access-token-scopes",
72+
Usage: `Scopes of the generated access token, comma separated. Examples: "all", "public-only,read:issue", "write:repository,write:user"`,
73+
Value: "all",
74+
},
6475
&cli.BoolFlag{
6576
Name: "restricted",
6677
Usage: "Make a restricted user account",
@@ -157,23 +168,40 @@ func runCreateUser(c *cli.Context) error {
157168
IsRestricted: restricted,
158169
}
159170

171+
var accessTokenName string
172+
var accessTokenScope auth_model.AccessTokenScope
173+
if c.IsSet("access-token") {
174+
accessTokenName = strings.TrimSpace(c.String("access-token-name"))
175+
if accessTokenName == "" {
176+
return errors.New("access-token-name cannot be empty")
177+
}
178+
var err error
179+
accessTokenScope, err = auth_model.AccessTokenScope(c.String("access-token-scopes")).Normalize()
180+
if err != nil {
181+
return fmt.Errorf("invalid access token scope provided: %w", err)
182+
}
183+
if !accessTokenScope.HasPermissionScope() {
184+
return errors.New("access token does not have any permission")
185+
}
186+
} else if c.IsSet("access-token-name") || c.IsSet("access-token-scopes") {
187+
return errors.New("access-token-name and access-token-scopes flags are only valid when access-token flag is set")
188+
}
189+
190+
// arguments should be prepared before creating the user & access token, in case there is anything wrong
191+
192+
// create the user
160193
if err := user_model.CreateUser(ctx, u, overwriteDefault); err != nil {
161194
return fmt.Errorf("CreateUser: %w", err)
162195
}
196+
fmt.Printf("New user '%s' has been successfully created!\n", username)
163197

164-
if c.Bool("access-token") {
165-
t := &auth_model.AccessToken{
166-
Name: "gitea-admin",
167-
UID: u.ID,
168-
}
169-
198+
// create the access token
199+
if accessTokenScope != "" {
200+
t := &auth_model.AccessToken{Name: accessTokenName, UID: u.ID, Scope: accessTokenScope}
170201
if err := auth_model.NewAccessToken(ctx, t); err != nil {
171202
return err
172203
}
173-
174204
fmt.Printf("Access token was successfully created... %s\n", t.Token)
175205
}
176-
177-
fmt.Printf("New user '%s' has been successfully created!\n", username)
178206
return nil
179207
}

cmd/admin_user_generate_access_token.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,16 @@ var microcmdUserGenerateAccessToken = &cli.Command{
3434
},
3535
&cli.StringFlag{
3636
Name: "scopes",
37-
Value: "",
38-
Usage: "Comma separated list of scopes to apply to access token",
37+
Value: "all",
38+
Usage: `Comma separated list of scopes to apply to access token, examples: "all", "public-only,read:issue", "write:repository,write:user"`,
3939
},
4040
},
4141
Action: runGenerateAccessToken,
4242
}
4343

4444
func runGenerateAccessToken(c *cli.Context) error {
4545
if !c.IsSet("username") {
46-
return errors.New("You must provide a username to generate a token for")
46+
return errors.New("you must provide a username to generate a token for")
4747
}
4848

4949
ctx, cancel := installSignals()
@@ -77,6 +77,9 @@ func runGenerateAccessToken(c *cli.Context) error {
7777
if err != nil {
7878
return fmt.Errorf("invalid access token scope provided: %w", err)
7979
}
80+
if !accessTokenScope.HasPermissionScope() {
81+
return errors.New("access token does not have any permission")
82+
}
8083
t.Scope = accessTokenScope
8184

8285
// create the token

models/auth/access_token_scope.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,10 @@ func (s AccessTokenScope) Normalize() (AccessTokenScope, error) {
283283
return bitmap.toScope(), nil
284284
}
285285

286+
func (s AccessTokenScope) HasPermissionScope() bool {
287+
return s != "" && s != AccessTokenScopePublicOnly
288+
}
289+
286290
// PublicOnly checks if this token scope is limited to public resources
287291
func (s AccessTokenScope) PublicOnly() (bool, error) {
288292
bitmap, err := s.parse()

routers/web/user/setting/applications.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ func ApplicationsPost(ctx *context.Context) {
4949
ctx.ServerError("GetScope", err)
5050
return
5151
}
52+
if !scope.HasPermissionScope() {
53+
ctx.Flash.Error(ctx.Tr("settings.at_least_one_permission"), true)
54+
}
5255
t := &auth_model.AccessToken{
5356
UID: ctx.Doer.ID,
5457
Name: form.Name,

0 commit comments

Comments
 (0)