Skip to content

Commit 7b8544c

Browse files
authored
Merge branch 'main' into fix-markdown-frontmatter
2 parents 31af204 + f94ee4f commit 7b8544c

34 files changed

+636
-343
lines changed

cmd/admin_user_create.go

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"context"
88
"errors"
99
"fmt"
10+
"strings"
1011

1112
auth_model "code.gitea.io/gitea/models/auth"
1213
"code.gitea.io/gitea/models/db"
@@ -66,6 +67,16 @@ var microcmdUserCreate = &cli.Command{
6667
Name: "access-token",
6768
Usage: "Generate access token for the user",
6869
},
70+
&cli.StringFlag{
71+
Name: "access-token-name",
72+
Usage: `Name of the generated access token`,
73+
Value: "gitea-admin",
74+
},
75+
&cli.StringFlag{
76+
Name: "access-token-scopes",
77+
Usage: `Scopes of the generated access token, comma separated. Examples: "all", "public-only,read:issue", "write:repository,write:user"`,
78+
Value: "all",
79+
},
6980
&cli.BoolFlag{
7081
Name: "restricted",
7182
Usage: "Make a restricted user account",
@@ -187,23 +198,40 @@ func runCreateUser(c *cli.Context) error {
187198
IsRestricted: restricted,
188199
}
189200

201+
var accessTokenName string
202+
var accessTokenScope auth_model.AccessTokenScope
203+
if c.IsSet("access-token") {
204+
accessTokenName = strings.TrimSpace(c.String("access-token-name"))
205+
if accessTokenName == "" {
206+
return errors.New("access-token-name cannot be empty")
207+
}
208+
var err error
209+
accessTokenScope, err = auth_model.AccessTokenScope(c.String("access-token-scopes")).Normalize()
210+
if err != nil {
211+
return fmt.Errorf("invalid access token scope provided: %w", err)
212+
}
213+
if !accessTokenScope.HasPermissionScope() {
214+
return errors.New("access token does not have any permission")
215+
}
216+
} else if c.IsSet("access-token-name") || c.IsSet("access-token-scopes") {
217+
return errors.New("access-token-name and access-token-scopes flags are only valid when access-token flag is set")
218+
}
219+
220+
// arguments should be prepared before creating the user & access token, in case there is anything wrong
221+
222+
// create the user
190223
if err := user_model.CreateUser(ctx, u, &user_model.Meta{}, overwriteDefault); err != nil {
191224
return fmt.Errorf("CreateUser: %w", err)
192225
}
226+
fmt.Printf("New user '%s' has been successfully created!\n", username)
193227

194-
if c.Bool("access-token") {
195-
t := &auth_model.AccessToken{
196-
Name: "gitea-admin",
197-
UID: u.ID,
198-
}
199-
228+
// create the access token
229+
if accessTokenScope != "" {
230+
t := &auth_model.AccessToken{Name: accessTokenName, UID: u.ID, Scope: accessTokenScope}
200231
if err := auth_model.NewAccessToken(ctx, t); err != nil {
201232
return err
202233
}
203-
204234
fmt.Printf("Access token was successfully created... %s\n", t.Token)
205235
}
206-
207-
fmt.Printf("New user '%s' has been successfully created!\n", username)
208236
return nil
209237
}

cmd/admin_user_create_test.go

Lines changed: 58 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"strings"
99
"testing"
1010

11+
auth_model "code.gitea.io/gitea/models/auth"
1112
"code.gitea.io/gitea/models/db"
1213
"code.gitea.io/gitea/models/unittest"
1314
user_model "code.gitea.io/gitea/models/user"
@@ -22,6 +23,7 @@ func TestAdminUserCreate(t *testing.T) {
2223
reset := func() {
2324
require.NoError(t, db.TruncateBeans(db.DefaultContext, &user_model.User{}))
2425
require.NoError(t, db.TruncateBeans(db.DefaultContext, &user_model.EmailAddress{}))
26+
require.NoError(t, db.TruncateBeans(db.DefaultContext, &auth_model.AccessToken{}))
2527
}
2628

2729
t.Run("MustChangePassword", func(t *testing.T) {
@@ -48,11 +50,11 @@ func TestAdminUserCreate(t *testing.T) {
4850
assert.Equal(t, check{IsAdmin: false, MustChangePassword: false}, createCheck("u5", "--must-change-password=false"))
4951
})
5052

51-
t.Run("UserType", func(t *testing.T) {
52-
createUser := func(name, args string) error {
53-
return app.Run(strings.Fields(fmt.Sprintf("./gitea admin user create --username %s --email %[email protected] %s", name, name, args)))
54-
}
53+
createUser := func(name, args string) error {
54+
return app.Run(strings.Fields(fmt.Sprintf("./gitea admin user create --username %s --email %[email protected] %s", name, name, args)))
55+
}
5556

57+
t.Run("UserType", func(t *testing.T) {
5658
reset()
5759
assert.ErrorContains(t, createUser("u", "--user-type invalid"), "invalid user type")
5860
assert.ErrorContains(t, createUser("u", "--user-type bot --password 123"), "can only be set for individual users")
@@ -63,4 +65,56 @@ func TestAdminUserCreate(t *testing.T) {
6365
assert.Equal(t, user_model.UserTypeBot, u.Type)
6466
assert.Empty(t, u.Passwd)
6567
})
68+
69+
t.Run("AccessToken", func(t *testing.T) {
70+
// no generated access token
71+
reset()
72+
assert.NoError(t, createUser("u", "--random-password"))
73+
assert.Equal(t, 1, unittest.GetCount(t, &user_model.User{}))
74+
assert.Equal(t, 0, unittest.GetCount(t, &auth_model.AccessToken{}))
75+
76+
// using "--access-token" only means "all" access
77+
reset()
78+
assert.NoError(t, createUser("u", "--random-password --access-token"))
79+
assert.Equal(t, 1, unittest.GetCount(t, &user_model.User{}))
80+
assert.Equal(t, 1, unittest.GetCount(t, &auth_model.AccessToken{}))
81+
accessToken := unittest.AssertExistsAndLoadBean(t, &auth_model.AccessToken{Name: "gitea-admin"})
82+
hasScopes, err := accessToken.Scope.HasScope(auth_model.AccessTokenScopeWriteAdmin, auth_model.AccessTokenScopeWriteRepository)
83+
assert.NoError(t, err)
84+
assert.True(t, hasScopes)
85+
86+
// using "--access-token" with name & scopes
87+
reset()
88+
assert.NoError(t, createUser("u", "--random-password --access-token --access-token-name new-token-name --access-token-scopes read:issue,read:user"))
89+
assert.Equal(t, 1, unittest.GetCount(t, &user_model.User{}))
90+
assert.Equal(t, 1, unittest.GetCount(t, &auth_model.AccessToken{}))
91+
accessToken = unittest.AssertExistsAndLoadBean(t, &auth_model.AccessToken{Name: "new-token-name"})
92+
hasScopes, err = accessToken.Scope.HasScope(auth_model.AccessTokenScopeReadIssue, auth_model.AccessTokenScopeReadUser)
93+
assert.NoError(t, err)
94+
assert.True(t, hasScopes)
95+
hasScopes, err = accessToken.Scope.HasScope(auth_model.AccessTokenScopeWriteAdmin, auth_model.AccessTokenScopeWriteRepository)
96+
assert.NoError(t, err)
97+
assert.False(t, hasScopes)
98+
99+
// using "--access-token-name" without "--access-token"
100+
reset()
101+
err = createUser("u", "--random-password --access-token-name new-token-name")
102+
assert.Equal(t, 0, unittest.GetCount(t, &user_model.User{}))
103+
assert.Equal(t, 0, unittest.GetCount(t, &auth_model.AccessToken{}))
104+
assert.ErrorContains(t, err, "access-token-name and access-token-scopes flags are only valid when access-token flag is set")
105+
106+
// using "--access-token-scopes" without "--access-token"
107+
reset()
108+
err = createUser("u", "--random-password --access-token-scopes read:issue")
109+
assert.Equal(t, 0, unittest.GetCount(t, &user_model.User{}))
110+
assert.Equal(t, 0, unittest.GetCount(t, &auth_model.AccessToken{}))
111+
assert.ErrorContains(t, err, "access-token-name and access-token-scopes flags are only valid when access-token flag is set")
112+
113+
// empty permission
114+
reset()
115+
err = createUser("u", "--random-password --access-token --access-token-scopes public-only")
116+
assert.Equal(t, 0, unittest.GetCount(t, &user_model.User{}))
117+
assert.Equal(t, 0, unittest.GetCount(t, &auth_model.AccessToken{}))
118+
assert.ErrorContains(t, err, "access token does not have any permission")
119+
})
66120
}

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
@@ -295,6 +295,10 @@ func (s AccessTokenScope) Normalize() (AccessTokenScope, error) {
295295
return bitmap.toScope(), nil
296296
}
297297

298+
func (s AccessTokenScope) HasPermissionScope() bool {
299+
return s != "" && s != AccessTokenScopePublicOnly
300+
}
301+
298302
// PublicOnly checks if this token scope is limited to public resources
299303
func (s AccessTokenScope) PublicOnly() (bool, error) {
300304
bitmap, err := s.parse()

models/fixtures/branch.yml

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,3 +93,111 @@
9393
is_deleted: false
9494
deleted_by_id: 0
9595
deleted_unix: 0
96+
97+
-
98+
id: 16
99+
repo_id: 16
100+
name: 'master'
101+
commit_id: '69554a64c1e6030f051e5c3f94bfbd773cd6a324'
102+
commit_message: 'not signed commit'
103+
commit_time: 1502042309
104+
pusher_id: 2
105+
is_deleted: false
106+
deleted_by_id: 0
107+
deleted_unix: 0
108+
109+
-
110+
id: 17
111+
repo_id: 16
112+
name: 'not-signed'
113+
commit_id: '69554a64c1e6030f051e5c3f94bfbd773cd6a324'
114+
commit_message: 'not signed commit'
115+
commit_time: 1502042309
116+
pusher_id: 2
117+
is_deleted: false
118+
deleted_by_id: 0
119+
deleted_unix: 0
120+
121+
-
122+
id: 18
123+
repo_id: 16
124+
name: 'good-sign-not-yet-validated'
125+
commit_id: '27566bd5738fc8b4e3fef3c5e72cce608537bd95'
126+
commit_message: 'good signed commit (with not yet validated email)'
127+
commit_time: 1502042234
128+
pusher_id: 2
129+
is_deleted: false
130+
deleted_by_id: 0
131+
deleted_unix: 0
132+
133+
-
134+
id: 19
135+
repo_id: 16
136+
name: 'good-sign'
137+
commit_id: 'f27c2b2b03dcab38beaf89b0ab4ff61f6de63441'
138+
commit_message: 'good signed commit'
139+
commit_time: 1502042101
140+
pusher_id: 2
141+
is_deleted: false
142+
deleted_by_id: 0
143+
deleted_unix: 0
144+
145+
-
146+
id: 20
147+
repo_id: 1
148+
name: 'feature/1'
149+
commit_id: '65f1bf27bc3bf70f64657658635e66094edbcb4d'
150+
commit_message: 'Initial commit'
151+
commit_time: 1489950479
152+
pusher_id: 2
153+
is_deleted: false
154+
deleted_by_id: 0
155+
deleted_unix: 0
156+
157+
-
158+
id: 21
159+
repo_id: 49
160+
name: 'master'
161+
commit_id: 'aacbdfe9e1c4b47f60abe81849045fa4e96f1d75'
162+
commit_message: "Add 'test/test.txt'"
163+
commit_time: 1572535577
164+
pusher_id: 2
165+
is_deleted: false
166+
deleted_by_id: 0
167+
deleted_unix: 0
168+
169+
-
170+
id: 22
171+
repo_id: 1
172+
name: 'develop'
173+
commit_id: '65f1bf27bc3bf70f64657658635e66094edbcb4d'
174+
commit_message: "Initial commit"
175+
commit_time: 1489927679
176+
pusher_id: 1
177+
is_deleted: false
178+
deleted_by_id: 0
179+
deleted_unix: 0
180+
181+
-
182+
id: 23
183+
repo_id: 3
184+
name: 'master'
185+
commit_id: '2a47ca4b614a9f5a43abbd5ad851a54a616ffee6'
186+
commit_message: "init project"
187+
commit_time: 1497448461
188+
pusher_id: 1
189+
is_deleted: false
190+
deleted_by_id: 0
191+
deleted_unix: 0
192+
193+
-
194+
id: 24
195+
repo_id: 3
196+
name: 'test_branch'
197+
commit_id: 'd22b4d4daa5be07329fcef6ed458f00cf3392da0'
198+
commit_message: "test commit"
199+
commit_time: 1602935385
200+
pusher_id: 1
201+
is_deleted: false
202+
deleted_by_id: 0
203+
deleted_unix: 0

modules/actions/workflows.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -463,7 +463,7 @@ func matchPullRequestEvent(gitRepo *git.Repository, commit *git.Commit, prPayloa
463463
matchTimes++
464464
}
465465
case "paths":
466-
filesChanged, err := headCommit.GetFilesChangedSinceCommit(prPayload.PullRequest.Base.Ref)
466+
filesChanged, err := headCommit.GetFilesChangedSinceCommit(prPayload.PullRequest.MergeBase)
467467
if err != nil {
468468
log.Error("GetFilesChangedSinceCommit [commit_sha1: %s]: %v", headCommit.ID.String(), err)
469469
} else {
@@ -476,7 +476,7 @@ func matchPullRequestEvent(gitRepo *git.Repository, commit *git.Commit, prPayloa
476476
}
477477
}
478478
case "paths-ignore":
479-
filesChanged, err := headCommit.GetFilesChangedSinceCommit(prPayload.PullRequest.Base.Ref)
479+
filesChanged, err := headCommit.GetFilesChangedSinceCommit(prPayload.PullRequest.MergeBase)
480480
if err != nil {
481481
log.Error("GetFilesChangedSinceCommit [commit_sha1: %s]: %v", headCommit.ID.String(), err)
482482
} else {

0 commit comments

Comments
 (0)