Skip to content

Commit 257db8c

Browse files
authored
Merge branch 'main' into tooldeps2
2 parents 8b3683a + 934124c commit 257db8c

File tree

24 files changed

+322
-106
lines changed

24 files changed

+322
-106
lines changed

models/perm/access/repo_permission.go

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,8 @@ func (p *Permission) LogString() string {
127127
}
128128

129129
// GetUserRepoPermission returns the user permissions to the repository
130-
func GetUserRepoPermission(ctx context.Context, repo *repo_model.Repository, user *user_model.User) (perm Permission, err error) {
130+
func GetUserRepoPermission(ctx context.Context, repo *repo_model.Repository, user *user_model.User) (Permission, error) {
131+
var perm Permission
131132
if log.IsTrace() {
132133
defer func() {
133134
if user == nil {
@@ -147,63 +148,64 @@ func GetUserRepoPermission(ctx context.Context, repo *repo_model.Repository, use
147148
// TODO: anonymous user visit public unit of private repo???
148149
if user == nil && repo.IsPrivate {
149150
perm.AccessMode = perm_model.AccessModeNone
150-
return
151+
return perm, nil
151152
}
152153

153-
var is bool
154+
var isCollaborator bool
155+
var err error
154156
if user != nil {
155-
is, err = repo_model.IsCollaborator(ctx, repo.ID, user.ID)
157+
isCollaborator, err = repo_model.IsCollaborator(ctx, repo.ID, user.ID)
156158
if err != nil {
157159
return perm, err
158160
}
159161
}
160162

161-
if err = repo.LoadOwner(ctx); err != nil {
162-
return
163+
if err := repo.LoadOwner(ctx); err != nil {
164+
return perm, err
163165
}
164166

165167
// Prevent strangers from checking out public repo of private organization/users
166168
// Allow user if they are collaborator of a repo within a private user or a private organization but not a member of the organization itself
167-
if !organization.HasOrgOrUserVisible(ctx, repo.Owner, user) && !is {
169+
if !organization.HasOrgOrUserVisible(ctx, repo.Owner, user) && !isCollaborator {
168170
perm.AccessMode = perm_model.AccessModeNone
169-
return
171+
return perm, nil
170172
}
171173

172-
if err = repo.LoadUnits(ctx); err != nil {
173-
return
174+
if err := repo.LoadUnits(ctx); err != nil {
175+
return perm, err
174176
}
175177

176178
perm.Units = repo.Units
177179

178180
// anonymous visit public repo
179181
if user == nil {
180182
perm.AccessMode = perm_model.AccessModeRead
181-
return
183+
return perm, nil
182184
}
183185

184186
// Admin or the owner has super access to the repository
185187
if user.IsAdmin || user.ID == repo.OwnerID {
186188
perm.AccessMode = perm_model.AccessModeOwner
187-
return
189+
return perm, nil
188190
}
189191

190192
// plain user
191193
perm.AccessMode, err = accessLevel(ctx, user, repo)
192194
if err != nil {
193-
return
195+
return perm, err
194196
}
195197

196-
if err = repo.LoadOwner(ctx); err != nil {
197-
return
198+
if err := repo.LoadOwner(ctx); err != nil {
199+
return perm, err
198200
}
199201
if !repo.Owner.IsOrganization() {
200-
return
202+
return perm, nil
201203
}
202204

203205
perm.UnitsMode = make(map[unit.Type]perm_model.AccessMode)
204206

205207
// Collaborators on organization
206-
if is {
208+
if isCollaborator {
207209
for _, u := range repo.Units {
208210
perm.UnitsMode[u.Type] = perm.AccessMode
209211
}
@@ -212,15 +214,15 @@ func GetUserRepoPermission(ctx context.Context, repo *repo_model.Repository, use
212214
// get units mode from teams
213215
teams, err := organization.GetUserRepoTeams(ctx, repo.OwnerID, user.ID, repo.ID)
214216
if err != nil {
215-
return
217+
return perm, err
216218
}
217219

218220
// if user in an owner team
219221
for _, team := range teams {
220222
if team.AccessMode >= perm_model.AccessModeAdmin {
221223
perm.AccessMode = perm_model.AccessModeOwner
222224
perm.UnitsMode = nil
223-
return
225+
return perm, nil
224226
}
225227
}
226228

models/repo/collaboration_test.go

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,19 @@ func TestRepository_GetCollaborators(t *testing.T) {
3333
test(2)
3434
test(3)
3535
test(4)
36+
37+
// Test db.ListOptions
38+
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 22})
39+
40+
collaborators1, err := repo_model.GetCollaborators(db.DefaultContext, repo.ID, db.ListOptions{PageSize: 1, Page: 1})
41+
assert.NoError(t, err)
42+
assert.Len(t, collaborators1, 1)
43+
44+
collaborators2, err := repo_model.GetCollaborators(db.DefaultContext, repo.ID, db.ListOptions{PageSize: 1, Page: 2})
45+
assert.NoError(t, err)
46+
assert.Len(t, collaborators2, 1)
47+
48+
assert.NotEqualValues(t, collaborators1[0].ID, collaborators2[0].ID)
3649
}
3750

3851
func TestRepository_IsCollaborator(t *testing.T) {
@@ -66,5 +79,80 @@ func TestRepository_ChangeCollaborationAccessMode(t *testing.T) {
6679

6780
assert.NoError(t, repo_model.ChangeCollaborationAccessMode(db.DefaultContext, repo, unittest.NonexistentID, perm.AccessModeAdmin))
6881

82+
// Disvard invalid input.
83+
assert.NoError(t, repo_model.ChangeCollaborationAccessMode(db.DefaultContext, repo, 4, perm.AccessMode(unittest.NonexistentID)))
84+
6985
unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: repo.ID})
7086
}
87+
88+
func TestRepository_CountCollaborators(t *testing.T) {
89+
assert.NoError(t, unittest.PrepareTestDatabase())
90+
91+
repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4})
92+
count, err := repo_model.CountCollaborators(repo1.ID)
93+
assert.NoError(t, err)
94+
assert.EqualValues(t, 2, count)
95+
96+
repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 22})
97+
count, err = repo_model.CountCollaborators(repo2.ID)
98+
assert.NoError(t, err)
99+
assert.EqualValues(t, 2, count)
100+
101+
// Non-existent repository.
102+
count, err = repo_model.CountCollaborators(unittest.NonexistentID)
103+
assert.NoError(t, err)
104+
assert.EqualValues(t, 0, count)
105+
}
106+
107+
func TestRepository_IsOwnerMemberCollaborator(t *testing.T) {
108+
assert.NoError(t, unittest.PrepareTestDatabase())
109+
110+
repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3})
111+
112+
// Organisation owner.
113+
actual, err := repo_model.IsOwnerMemberCollaborator(repo1, 2)
114+
assert.NoError(t, err)
115+
assert.True(t, actual)
116+
117+
// Team member.
118+
actual, err = repo_model.IsOwnerMemberCollaborator(repo1, 4)
119+
assert.NoError(t, err)
120+
assert.True(t, actual)
121+
122+
// Normal user.
123+
actual, err = repo_model.IsOwnerMemberCollaborator(repo1, 1)
124+
assert.NoError(t, err)
125+
assert.False(t, actual)
126+
127+
repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4})
128+
129+
// Collaborator.
130+
actual, err = repo_model.IsOwnerMemberCollaborator(repo2, 4)
131+
assert.NoError(t, err)
132+
assert.True(t, actual)
133+
134+
repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 15})
135+
136+
// Repository owner.
137+
actual, err = repo_model.IsOwnerMemberCollaborator(repo3, 2)
138+
assert.NoError(t, err)
139+
assert.True(t, actual)
140+
}
141+
142+
func TestRepo_GetCollaboration(t *testing.T) {
143+
assert.NoError(t, unittest.PrepareTestDatabase())
144+
145+
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4})
146+
147+
// Existing collaboration.
148+
collab, err := repo_model.GetCollaboration(db.DefaultContext, repo.ID, 4)
149+
assert.NoError(t, err)
150+
assert.NotNil(t, collab)
151+
assert.EqualValues(t, 4, collab.UserID)
152+
assert.EqualValues(t, 4, collab.RepoID)
153+
154+
// Non-existing collaboration.
155+
collab, err = repo_model.GetCollaboration(db.DefaultContext, repo.ID, 1)
156+
assert.NoError(t, err)
157+
assert.Nil(t, collab)
158+
}

models/repo/release.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ func (s releaseMetaSearch) Less(i, j int) bool {
339339
// GetReleaseAttachments retrieves the attachments for releases
340340
func GetReleaseAttachments(ctx context.Context, rels ...*Release) (err error) {
341341
if len(rels) == 0 {
342-
return
342+
return nil
343343
}
344344

345345
// To keep this efficient as possible sort all releases by id,

modules/avatar/hash_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Copyright 2023 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package avatar_test
5+
6+
import (
7+
"bytes"
8+
"image"
9+
"image/png"
10+
"testing"
11+
12+
"code.gitea.io/gitea/modules/avatar"
13+
14+
"github.com/stretchr/testify/assert"
15+
)
16+
17+
func Test_HashAvatar(t *testing.T) {
18+
myImage := image.NewRGBA(image.Rect(0, 0, 32, 32))
19+
var buff bytes.Buffer
20+
png.Encode(&buff, myImage)
21+
22+
assert.EqualValues(t, "9ddb5bac41d57e72aa876321d0c09d71090c05f94bc625303801be2f3240d2cb", avatar.HashAvatar(1, buff.Bytes()))
23+
assert.EqualValues(t, "9a5d44e5d637b9582a976676e8f3de1dccd877c2fe3e66ca3fab1629f2f47609", avatar.HashAvatar(8, buff.Bytes()))
24+
assert.EqualValues(t, "ed7399158672088770de6f5211ce15528ebd675e92fc4fc060c025f4b2794ccb", avatar.HashAvatar(1024, buff.Bytes()))
25+
assert.EqualValues(t, "161178642c7d59eb25a61dddced5e6b66eae1c70880d5f148b1b497b767e72d9", avatar.HashAvatar(1024, []byte{}))
26+
}

modules/indexer/issues/bleve/bleve.go

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import (
2323
const (
2424
issueIndexerAnalyzer = "issueIndexer"
2525
issueIndexerDocType = "issueIndexerDocType"
26-
issueIndexerLatestVersion = 2
26+
issueIndexerLatestVersion = 3
2727
)
2828

2929
// numericEqualityQuery a numeric equality query for the given value and field
@@ -67,15 +67,16 @@ func generateIssueIndexMapping() (mapping.IndexMapping, error) {
6767
docMapping := bleve.NewDocumentMapping()
6868

6969
numericFieldMapping := bleve.NewNumericFieldMapping()
70+
numericFieldMapping.Store = false
7071
numericFieldMapping.IncludeInAll = false
71-
docMapping.AddFieldMappingsAt("RepoID", numericFieldMapping)
72+
docMapping.AddFieldMappingsAt("repo_id", numericFieldMapping)
7273

7374
textFieldMapping := bleve.NewTextFieldMapping()
7475
textFieldMapping.Store = false
7576
textFieldMapping.IncludeInAll = false
76-
docMapping.AddFieldMappingsAt("Title", textFieldMapping)
77-
docMapping.AddFieldMappingsAt("Content", textFieldMapping)
78-
docMapping.AddFieldMappingsAt("Comments", textFieldMapping)
77+
docMapping.AddFieldMappingsAt("title", textFieldMapping)
78+
docMapping.AddFieldMappingsAt("content", textFieldMapping)
79+
docMapping.AddFieldMappingsAt("comments", textFieldMapping)
7980

8081
if err := addUnicodeNormalizeTokenFilter(mapping); err != nil {
8182
return nil, err
@@ -91,6 +92,7 @@ func generateIssueIndexMapping() (mapping.IndexMapping, error) {
9192
mapping.DefaultAnalyzer = issueIndexerAnalyzer
9293
mapping.AddDocumentMapping(issueIndexerDocType, docMapping)
9394
mapping.AddDocumentMapping("_all", bleve.NewDocumentDisabledMapping())
95+
mapping.DefaultMapping = bleve.NewDocumentDisabledMapping() // disable default mapping, avoid indexing unexpected structs
9496

9597
return mapping, nil
9698
}
@@ -116,17 +118,7 @@ func NewIndexer(indexDir string) *Indexer {
116118
func (b *Indexer) Index(_ context.Context, issues []*internal.IndexerData) error {
117119
batch := inner_bleve.NewFlushingBatch(b.inner.Indexer, maxBatchSize)
118120
for _, issue := range issues {
119-
if err := batch.Index(indexer_internal.Base36(issue.ID), struct {
120-
RepoID int64
121-
Title string
122-
Content string
123-
Comments []string
124-
}{
125-
RepoID: issue.RepoID,
126-
Title: issue.Title,
127-
Content: issue.Content,
128-
Comments: issue.Comments,
129-
}); err != nil {
121+
if err := batch.Index(indexer_internal.Base36(issue.ID), (*IndexerData)(issue)); err != nil {
130122
return err
131123
}
132124
}
@@ -149,7 +141,7 @@ func (b *Indexer) Delete(_ context.Context, ids ...int64) error {
149141
func (b *Indexer) Search(ctx context.Context, keyword string, repoIDs []int64, limit, start int) (*internal.SearchResult, error) {
150142
var repoQueriesP []*query.NumericRangeQuery
151143
for _, repoID := range repoIDs {
152-
repoQueriesP = append(repoQueriesP, numericEqualityQuery(repoID, "RepoID"))
144+
repoQueriesP = append(repoQueriesP, numericEqualityQuery(repoID, "repo_id"))
153145
}
154146
repoQueries := make([]query.Query, len(repoQueriesP))
155147
for i, v := range repoQueriesP {
@@ -159,9 +151,9 @@ func (b *Indexer) Search(ctx context.Context, keyword string, repoIDs []int64, l
159151
indexerQuery := bleve.NewConjunctionQuery(
160152
bleve.NewDisjunctionQuery(repoQueries...),
161153
bleve.NewDisjunctionQuery(
162-
newMatchPhraseQuery(keyword, "Title", issueIndexerAnalyzer),
163-
newMatchPhraseQuery(keyword, "Content", issueIndexerAnalyzer),
164-
newMatchPhraseQuery(keyword, "Comments", issueIndexerAnalyzer),
154+
newMatchPhraseQuery(keyword, "title", issueIndexerAnalyzer),
155+
newMatchPhraseQuery(keyword, "content", issueIndexerAnalyzer),
156+
newMatchPhraseQuery(keyword, "comments", issueIndexerAnalyzer),
165157
))
166158
search := bleve.NewSearchRequestOptions(indexerQuery, limit, start, false)
167159
search.SortBy([]string{"-_score"})

options/locale/locale_en-US.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3463,7 +3463,7 @@ runners.reset_registration_token_success = Runner registration token reset succe
34633463
34643464
runs.all_workflows = All Workflows
34653465
runs.commit = Commit
3466-
runs.pushed_by = Pushed by
3466+
runs.pushed_by = pushed by
34673467
runs.invalid_workflow_helper = Workflow config file is invalid. Please check your config file: %s
34683468
runs.no_matching_runner_helper = No matching runner: %s
34693469
runs.actor = Actor

routers/web/auth/auth.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ func SignInPost(ctx *context.Context) {
201201

202202
u, source, err := auth_service.UserSignIn(form.UserName, form.Password)
203203
if err != nil {
204-
if user_model.IsErrUserNotExist(err) || user_model.IsErrEmailAddressNotExist(err) {
204+
if errors.Is(err, util.ErrNotExist) || errors.Is(err, util.ErrInvalidArgument) {
205205
ctx.RenderWithErr(ctx.Tr("form.username_password_incorrect"), tplSignIn, &form)
206206
log.Info("Failed authentication attempt for %s from %s: %v", form.UserName, ctx.RemoteAddr(), err)
207207
} else if user_model.IsErrEmailAlreadyUsed(err) {

routers/web/auth/linkaccount.go

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ import (
1313
user_model "code.gitea.io/gitea/models/user"
1414
"code.gitea.io/gitea/modules/base"
1515
"code.gitea.io/gitea/modules/context"
16+
"code.gitea.io/gitea/modules/log"
1617
"code.gitea.io/gitea/modules/setting"
18+
"code.gitea.io/gitea/modules/util"
1719
"code.gitea.io/gitea/modules/web"
1820
auth_service "code.gitea.io/gitea/services/auth"
1921
"code.gitea.io/gitea/services/auth/source/oauth2"
@@ -81,6 +83,32 @@ func LinkAccount(ctx *context.Context) {
8183
ctx.HTML(http.StatusOK, tplLinkAccount)
8284
}
8385

86+
func handleSignInError(ctx *context.Context, userName string, ptrForm any, tmpl base.TplName, invoker string, err error) {
87+
if errors.Is(err, util.ErrNotExist) {
88+
ctx.RenderWithErr(ctx.Tr("form.username_password_incorrect"), tmpl, ptrForm)
89+
} else if errors.Is(err, util.ErrInvalidArgument) {
90+
ctx.Data["user_exists"] = true
91+
ctx.RenderWithErr(ctx.Tr("form.username_password_incorrect"), tmpl, ptrForm)
92+
} else if user_model.IsErrUserProhibitLogin(err) {
93+
ctx.Data["user_exists"] = true
94+
log.Info("Failed authentication attempt for %s from %s: %v", userName, ctx.RemoteAddr(), err)
95+
ctx.Data["Title"] = ctx.Tr("auth.prohibit_login")
96+
ctx.HTML(http.StatusOK, "user/auth/prohibit_login")
97+
} else if user_model.IsErrUserInactive(err) {
98+
ctx.Data["user_exists"] = true
99+
if setting.Service.RegisterEmailConfirm {
100+
ctx.Data["Title"] = ctx.Tr("auth.active_your_account")
101+
ctx.HTML(http.StatusOK, TplActivate)
102+
} else {
103+
log.Info("Failed authentication attempt for %s from %s: %v", userName, ctx.RemoteAddr(), err)
104+
ctx.Data["Title"] = ctx.Tr("auth.prohibit_login")
105+
ctx.HTML(http.StatusOK, "user/auth/prohibit_login")
106+
}
107+
} else {
108+
ctx.ServerError(invoker, err)
109+
}
110+
}
111+
84112
// LinkAccountPostSignIn handle the coupling of external account with another account using signIn
85113
func LinkAccountPostSignIn(ctx *context.Context) {
86114
signInForm := web.GetForm(ctx).(*forms.SignInForm)
@@ -116,12 +144,7 @@ func LinkAccountPostSignIn(ctx *context.Context) {
116144

117145
u, _, err := auth_service.UserSignIn(signInForm.UserName, signInForm.Password)
118146
if err != nil {
119-
if user_model.IsErrUserNotExist(err) {
120-
ctx.Data["user_exists"] = true
121-
ctx.RenderWithErr(ctx.Tr("form.username_password_incorrect"), tplLinkAccount, &signInForm)
122-
} else {
123-
ctx.ServerError("UserLinkAccount", err)
124-
}
147+
handleSignInError(ctx, signInForm.UserName, &signInForm, tplLinkAccount, "UserLinkAccount", err)
125148
return
126149
}
127150

0 commit comments

Comments
 (0)