Skip to content

Commit 7c0543b

Browse files
authored
Merge branch 'main' into fix/35763-project-page-title
2 parents 39a16f3 + 050c948 commit 7c0543b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+355
-602
lines changed

.gitattributes

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@
88
/vendor/** -text -eol linguist-vendored
99
/web_src/js/vendor/** -text -eol linguist-vendored
1010
Dockerfile.* linguist-language=Dockerfile
11+
Makefile.* linguist-language=Makefile

.github/labeler.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ modifies/internal:
5151
- ".github/**"
5252
- ".gitea/**"
5353
- ".devcontainer/**"
54-
- "build.go"
5554
- "build/**"
5655
- "contrib/**"
5756

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,3 +127,6 @@ prime/
127127

128128
# Ignore worktrees when working on multiple branches
129129
.worktrees/
130+
131+
# A Makefile for custom make targets
132+
Makefile.local

Makefile

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ GO_LICENSES_PACKAGE ?= github.com/google/go-licenses@v1
4141
GOVULNCHECK_PACKAGE ?= golang.org/x/vuln/cmd/govulncheck@v1
4242
ACTIONLINT_PACKAGE ?= github.com/rhysd/actionlint/cmd/actionlint@v1
4343
GOPLS_PACKAGE ?= golang.org/x/tools/[email protected]
44-
GOPLS_MODERNIZE_PACKAGE ?= golang.org/x/tools/gopls/internal/analysis/modernize/cmd/[email protected]
4544

4645
DOCKER_IMAGE ?= gitea/gitea
4746
DOCKER_TAG ?= latest
@@ -199,6 +198,10 @@ TEST_MSSQL_DBNAME ?= gitea
199198
TEST_MSSQL_USERNAME ?= sa
200199
TEST_MSSQL_PASSWORD ?= MwantsaSecurePassword1
201200

201+
# Include local Makefile
202+
# Makefile.local is listed in .gitignore
203+
sinclude Makefile.local
204+
202205
.PHONY: all
203206
all: build
204207

@@ -276,19 +279,6 @@ fmt-check: fmt
276279
exit 1; \
277280
fi
278281

279-
.PHONY: fix
280-
fix: ## apply automated fixes to Go code
281-
$(GO) run $(GOPLS_MODERNIZE_PACKAGE) -fix ./...
282-
283-
.PHONY: fix-check
284-
fix-check: fix
285-
@diff=$$(git diff --color=always $(GO_SOURCES)); \
286-
if [ -n "$$diff" ]; then \
287-
echo "Please run 'make fix' and commit the result:"; \
288-
printf "%s" "$${diff}"; \
289-
exit 1; \
290-
fi
291-
292282
.PHONY: $(TAGS_EVIDENCE)
293283
$(TAGS_EVIDENCE):
294284
@mkdir -p $(MAKE_EVIDENCE_DIR)
@@ -328,7 +318,7 @@ checks: checks-frontend checks-backend ## run various consistency checks
328318
checks-frontend: lockfile-check svg-check ## check frontend files
329319

330320
.PHONY: checks-backend
331-
checks-backend: tidy-check swagger-check fmt-check fix-check swagger-validate security-check ## check backend files
321+
checks-backend: tidy-check swagger-check fmt-check swagger-validate security-check ## check backend files
332322

333323
.PHONY: lint
334324
lint: lint-frontend lint-backend lint-spell ## lint everything
@@ -400,8 +390,7 @@ lint-go-windows:
400390
.PHONY: lint-go-gitea-vet
401391
lint-go-gitea-vet: ## lint go files with gitea-vet
402392
@echo "Running gitea-vet..."
403-
@GOOS= GOARCH= $(GO) build code.gitea.io/gitea-vet
404-
@$(GO) vet -vettool=gitea-vet ./...
393+
@$(GO) vet -vettool="$(shell GOOS= GOARCH= go tool -n gitea-vet)" ./...
405394

406395
.PHONY: lint-go-gopls
407396
lint-go-gopls: ## lint go files with gopls
@@ -852,7 +841,6 @@ deps-tools: ## install tool dependencies
852841
$(GO) install $(GOVULNCHECK_PACKAGE) & \
853842
$(GO) install $(ACTIONLINT_PACKAGE) & \
854843
$(GO) install $(GOPLS_PACKAGE) & \
855-
$(GO) install $(GOPLS_MODERNIZE_PACKAGE) & \
856844
wait
857845

858846
node_modules: pnpm-lock.yaml

build.go

Lines changed: 0 additions & 14 deletions
This file was deleted.

go.mod

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
module code.gitea.io/gitea
22

3-
go 1.25.3
3+
go 1.25.0
4+
5+
toolchain go1.25.4
46

57
// rfc5280 said: "The serial number is an integer assigned by the CA to each certificate."
68
// But some CAs use negative serial number, just relax the check. related:
@@ -9,7 +11,6 @@ godebug x509negativeserial=1
911

1012
require (
1113
code.gitea.io/actions-proto-go v0.4.1
12-
code.gitea.io/gitea-vet v0.2.3
1314
code.gitea.io/sdk/gitea v0.22.0
1415
codeberg.org/gusted/mcaptcha v0.0.0-20220723083913-4f3072e1d570
1516
connectrpc.com/connect v1.18.1
@@ -135,6 +136,7 @@ require (
135136

136137
require (
137138
cloud.google.com/go/compute/metadata v0.8.0 // indirect
139+
code.gitea.io/gitea-vet v0.2.3 // indirect
138140
dario.cat/mergo v1.0.2 // indirect
139141
filippo.io/edwards25519 v1.1.0 // indirect
140142
git.sr.ht/~mariusor/go-xsd-duration v0.0.0-20220703122237-02e73435a078 // indirect
@@ -307,3 +309,5 @@ exclude github.com/gofrs/uuid v4.0.0+incompatible
307309
exclude github.com/goccy/go-json v0.4.11
308310

309311
exclude github.com/satori/go.uuid v1.2.0
312+
313+
tool code.gitea.io/gitea-vet

models/git/protected_branch.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -466,11 +466,13 @@ func updateApprovalWhitelist(ctx context.Context, repo *repo_model.Repository, c
466466
return currentWhitelist, nil
467467
}
468468

469+
prUserIDs, err := access_model.GetUserIDsWithUnitAccess(ctx, repo, perm.AccessModeRead, unit.TypePullRequests)
470+
if err != nil {
471+
return nil, err
472+
}
469473
whitelist = make([]int64, 0, len(newWhitelist))
470474
for _, userID := range newWhitelist {
471-
if reader, err := access_model.IsRepoReader(ctx, repo, userID); err != nil {
472-
return nil, err
473-
} else if !reader {
475+
if !prUserIDs.Contains(userID) {
474476
continue
475477
}
476478
whitelist = append(whitelist, userID)

models/organization/team_repo.go

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,24 +53,45 @@ func RemoveTeamRepo(ctx context.Context, teamID, repoID int64) error {
5353
// GetTeamsWithAccessToAnyRepoUnit returns all teams in an organization that have given access level to the repository special unit.
5454
// This function is only used for finding some teams that can be used as branch protection allowlist or reviewers, it isn't really used for access control.
5555
// FIXME: TEAM-UNIT-PERMISSION this logic is not complete, search the fixme keyword to see more details
56-
func GetTeamsWithAccessToAnyRepoUnit(ctx context.Context, orgID, repoID int64, mode perm.AccessMode, unitType unit.Type, unitTypesMore ...unit.Type) ([]*Team, error) {
57-
teams := make([]*Team, 0, 5)
56+
func GetTeamsWithAccessToAnyRepoUnit(ctx context.Context, orgID, repoID int64, mode perm.AccessMode, unitType unit.Type, unitTypesMore ...unit.Type) (teams []*Team, err error) {
57+
teamIDs, err := getTeamIDsWithAccessToAnyRepoUnit(ctx, orgID, repoID, mode, unitType, unitTypesMore...)
58+
if err != nil {
59+
return nil, err
60+
}
61+
if len(teamIDs) == 0 {
62+
return teams, nil
63+
}
64+
err = db.GetEngine(ctx).Where(builder.In("id", teamIDs)).OrderBy("team.name").Find(&teams)
65+
return teams, err
66+
}
5867

68+
func getTeamIDsWithAccessToAnyRepoUnit(ctx context.Context, orgID, repoID int64, mode perm.AccessMode, unitType unit.Type, unitTypesMore ...unit.Type) (teamIDs []int64, err error) {
5969
sub := builder.Select("team_id").From("team_unit").
6070
Where(builder.Expr("team_unit.team_id = team.id")).
6171
And(builder.In("team_unit.type", append([]unit.Type{unitType}, unitTypesMore...))).
6272
And(builder.Expr("team_unit.access_mode >= ?", mode))
6373

64-
err := db.GetEngine(ctx).
74+
err = db.GetEngine(ctx).
75+
Select("team.id").
76+
Table("team").
6577
Join("INNER", "team_repo", "team_repo.team_id = team.id").
66-
And("team_repo.org_id = ?", orgID).
67-
And("team_repo.repo_id = ?", repoID).
78+
And("team_repo.org_id = ? AND team_repo.repo_id = ?", orgID, repoID).
6879
And(builder.Or(
6980
builder.Expr("team.authorize >= ?", mode),
7081
builder.In("team.id", sub),
7182
)).
72-
OrderBy("name").
73-
Find(&teams)
83+
Find(&teamIDs)
84+
return teamIDs, err
85+
}
7486

75-
return teams, err
87+
func GetTeamUserIDsWithAccessToAnyRepoUnit(ctx context.Context, orgID, repoID int64, mode perm.AccessMode, unitType unit.Type, unitTypesMore ...unit.Type) (userIDs []int64, err error) {
88+
teamIDs, err := getTeamIDsWithAccessToAnyRepoUnit(ctx, orgID, repoID, mode, unitType, unitTypesMore...)
89+
if err != nil {
90+
return nil, err
91+
}
92+
if len(teamIDs) == 0 {
93+
return userIDs, nil
94+
}
95+
err = db.GetEngine(ctx).Table("team_user").Select("uid").Where(builder.In("team_id", teamIDs)).Find(&userIDs)
96+
return userIDs, err
7697
}

models/perm/access/repo_permission.go

Lines changed: 28 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
repo_model "code.gitea.io/gitea/models/repo"
1717
"code.gitea.io/gitea/models/unit"
1818
user_model "code.gitea.io/gitea/models/user"
19+
"code.gitea.io/gitea/modules/container"
1920
"code.gitea.io/gitea/modules/log"
2021
"code.gitea.io/gitea/modules/setting"
2122
"code.gitea.io/gitea/modules/util"
@@ -498,54 +499,44 @@ func HasAnyUnitAccess(ctx context.Context, userID int64, repo *repo_model.Reposi
498499
return perm.HasAnyUnitAccess(), nil
499500
}
500501

501-
// getUsersWithAccessMode returns users that have at least given access mode to the repository.
502-
func getUsersWithAccessMode(ctx context.Context, repo *repo_model.Repository, mode perm_model.AccessMode) (_ []*user_model.User, err error) {
503-
if err = repo.LoadOwner(ctx); err != nil {
502+
func GetUsersWithUnitAccess(ctx context.Context, repo *repo_model.Repository, mode perm_model.AccessMode, unitType unit.Type) (users []*user_model.User, err error) {
503+
userIDs, err := GetUserIDsWithUnitAccess(ctx, repo, mode, unitType)
504+
if err != nil {
504505
return nil, err
505506
}
507+
if len(userIDs) == 0 {
508+
return users, nil
509+
}
510+
if err = db.GetEngine(ctx).In("id", userIDs.Values()).OrderBy("`name`").Find(&users); err != nil {
511+
return nil, err
512+
}
513+
return users, nil
514+
}
506515

516+
func GetUserIDsWithUnitAccess(ctx context.Context, repo *repo_model.Repository, mode perm_model.AccessMode, unitType unit.Type) (container.Set[int64], error) {
517+
userIDs := container.Set[int64]{}
507518
e := db.GetEngine(ctx)
508519
accesses := make([]*Access, 0, 10)
509-
if err = e.Where("repo_id = ? AND mode >= ?", repo.ID, mode).Find(&accesses); err != nil {
520+
if err := e.Where("repo_id = ? AND mode >= ?", repo.ID, mode).Find(&accesses); err != nil {
510521
return nil, err
511522
}
523+
for _, a := range accesses {
524+
userIDs.Add(a.UserID)
525+
}
512526

513-
// Leave a seat for owner itself to append later, but if owner is an organization
514-
// and just waste 1 unit is cheaper than re-allocate memory once.
515-
users := make([]*user_model.User, 0, len(accesses)+1)
516-
if len(accesses) > 0 {
517-
userIDs := make([]int64, len(accesses))
518-
for i := 0; i < len(accesses); i++ {
519-
userIDs[i] = accesses[i].UserID
520-
}
521-
522-
if err = e.In("id", userIDs).Find(&users); err != nil {
523-
return nil, err
524-
}
527+
if err := repo.LoadOwner(ctx); err != nil {
528+
return nil, err
525529
}
526530
if !repo.Owner.IsOrganization() {
527-
users = append(users, repo.Owner)
528-
}
529-
530-
return users, nil
531-
}
532-
533-
// GetRepoReaders returns all users that have explicit read access or higher to the repository.
534-
func GetRepoReaders(ctx context.Context, repo *repo_model.Repository) (_ []*user_model.User, err error) {
535-
return getUsersWithAccessMode(ctx, repo, perm_model.AccessModeRead)
536-
}
537-
538-
// GetRepoWriters returns all users that have write access to the repository.
539-
func GetRepoWriters(ctx context.Context, repo *repo_model.Repository) (_ []*user_model.User, err error) {
540-
return getUsersWithAccessMode(ctx, repo, perm_model.AccessModeWrite)
541-
}
542-
543-
// IsRepoReader returns true if user has explicit read access or higher to the repository.
544-
func IsRepoReader(ctx context.Context, repo *repo_model.Repository, userID int64) (bool, error) {
545-
if repo.OwnerID == userID {
546-
return true, nil
531+
userIDs.Add(repo.Owner.ID)
532+
} else {
533+
teamUserIDs, err := organization.GetTeamUserIDsWithAccessToAnyRepoUnit(ctx, repo.OwnerID, repo.ID, mode, unitType)
534+
if err != nil {
535+
return nil, err
536+
}
537+
userIDs.AddMultiple(teamUserIDs...)
547538
}
548-
return db.GetEngine(ctx).Where("repo_id = ? AND user_id = ? AND mode >= ?", repo.ID, userID, perm_model.AccessModeRead).Get(&Access{})
539+
return userIDs, nil
549540
}
550541

551542
// CheckRepoUnitUser check whether user could visit the unit of this repository

models/perm/access/repo_permission_test.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,9 +169,9 @@ func TestGetUserRepoPermission(t *testing.T) {
169169
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4})
170170
team := &organization.Team{OrgID: org.ID, LowerName: "test_team"}
171171
require.NoError(t, db.Insert(ctx, team))
172+
require.NoError(t, db.Insert(ctx, &organization.TeamUser{OrgID: org.ID, TeamID: team.ID, UID: user.ID}))
172173

173174
t.Run("DoerInTeamWithNoRepo", func(t *testing.T) {
174-
require.NoError(t, db.Insert(ctx, &organization.TeamUser{OrgID: org.ID, TeamID: team.ID, UID: user.ID}))
175175
perm, err := GetUserRepoPermission(ctx, repo32, user)
176176
require.NoError(t, err)
177177
assert.Equal(t, perm_model.AccessModeRead, perm.AccessMode)
@@ -219,6 +219,15 @@ func TestGetUserRepoPermission(t *testing.T) {
219219
assert.Equal(t, perm_model.AccessModeNone, perm.AccessMode)
220220
assert.Equal(t, perm_model.AccessModeNone, perm.unitsMode[unit.TypeCode])
221221
assert.Equal(t, perm_model.AccessModeRead, perm.unitsMode[unit.TypeIssues])
222+
223+
users, err := GetUsersWithUnitAccess(ctx, repo3, perm_model.AccessModeRead, unit.TypeIssues)
224+
require.NoError(t, err)
225+
require.Len(t, users, 1)
226+
assert.Equal(t, user.ID, users[0].ID)
227+
228+
users, err = GetUsersWithUnitAccess(ctx, repo3, perm_model.AccessModeWrite, unit.TypeIssues)
229+
require.NoError(t, err)
230+
require.Empty(t, users)
222231
})
223232

224233
require.NoError(t, db.Insert(ctx, repo_model.Collaboration{RepoID: repo3.ID, UserID: user.ID, Mode: perm_model.AccessModeWrite}))
@@ -229,5 +238,10 @@ func TestGetUserRepoPermission(t *testing.T) {
229238
assert.Equal(t, perm_model.AccessModeWrite, perm.AccessMode)
230239
assert.Equal(t, perm_model.AccessModeWrite, perm.unitsMode[unit.TypeCode])
231240
assert.Equal(t, perm_model.AccessModeWrite, perm.unitsMode[unit.TypeIssues])
241+
242+
users, err := GetUsersWithUnitAccess(ctx, repo3, perm_model.AccessModeWrite, unit.TypeIssues)
243+
require.NoError(t, err)
244+
require.Len(t, users, 1)
245+
assert.Equal(t, user.ID, users[0].ID)
232246
})
233247
}

0 commit comments

Comments
 (0)