Skip to content

Commit aa162ca

Browse files
authored
Merge branch 'main' into luny/fix_review_request_webhook_3
2 parents 78d59bf + e03a68c commit aa162ca

Some content is hidden

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

70 files changed

+1841
-1508
lines changed

.golangci.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ linters:
153153
text: '(?i)exitAfterDefer:'
154154
paths:
155155
- node_modules
156+
- .venv
156157
- public
157158
- web_src
158159
- third_party$
@@ -172,6 +173,7 @@ formatters:
172173
generated: lax
173174
paths:
174175
- node_modules
176+
- .venv
175177
- public
176178
- web_src
177179
- third_party$

Makefile

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,11 @@ XGO_VERSION := go-1.25.x
3131

3232
AIR_PACKAGE ?= github.com/air-verse/air@v1
3333
EDITORCONFIG_CHECKER_PACKAGE ?= github.com/editorconfig-checker/editorconfig-checker/v3/cmd/editorconfig-checker@v3
34-
GOFUMPT_PACKAGE ?= mvdan.cc/[email protected].1
35-
GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.4.0
34+
GOFUMPT_PACKAGE ?= mvdan.cc/[email protected].2
35+
GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.5.0
3636
GXZ_PACKAGE ?= github.com/ulikunitz/xz/cmd/[email protected]
3737
MISSPELL_PACKAGE ?= github.com/golangci/misspell/cmd/[email protected]
38-
SWAGGER_PACKAGE ?= github.com/go-swagger/go-swagger/cmd/swagger@717e3cb29becaaf00e56953556c6d80f8a01b286
38+
SWAGGER_PACKAGE ?= github.com/go-swagger/go-swagger/cmd/swagger@v0.33.1
3939
XGO_PACKAGE ?= src.techknowlogick.com/xgo@latest
4040
GO_LICENSES_PACKAGE ?= github.com/google/go-licenses@v1
4141
GOVULNCHECK_PACKAGE ?= golang.org/x/vuln/cmd/govulncheck@v1
@@ -258,7 +258,7 @@ clean: ## delete backend and integration files
258258

259259
.PHONY: fmt
260260
fmt: ## format the Go and template code
261-
@GOFUMPT_PACKAGE=$(GOFUMPT_PACKAGE) $(GO) run build/code-batch-process.go gitea-fmt -w '{file-list}'
261+
@GOFUMPT_PACKAGE=$(GOFUMPT_PACKAGE) $(GO) run tools/code-batch-process.go gitea-fmt -w '{file-list}'
262262
$(eval TEMPLATES := $(shell find templates -type f -name '*.tmpl'))
263263
@# strip whitespace after '{{' or '(' and before '}}' or ')' unless there is only
264264
@# whitespace before it
@@ -472,7 +472,7 @@ test\#%:
472472
coverage:
473473
grep '^\(mode: .*\)\|\(.*:[0-9]\+\.[0-9]\+,[0-9]\+\.[0-9]\+ [0-9]\+ [0-9]\+\)$$' coverage.out > coverage-bodged.out
474474
grep '^\(mode: .*\)\|\(.*:[0-9]\+\.[0-9]\+,[0-9]\+\.[0-9]\+ [0-9]\+ [0-9]\+\)$$' integration.coverage.out > integration.coverage-bodged.out
475-
$(GO) run build/gocovmerge.go integration.coverage-bodged.out coverage-bodged.out > coverage.all
475+
$(GO) run tools/gocovmerge.go integration.coverage-bodged.out coverage-bodged.out > coverage.all
476476

477477
.PHONY: unit-test-coverage
478478
unit-test-coverage:

custom/conf/app.example.ini

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2540,7 +2540,19 @@ LEVEL = Info
25402540
;; * sanitized: Sanitize the content and render it inside current page, default to only allow a few HTML tags and attributes. Customized sanitizer rules can be defined in [markup.sanitizer.*] .
25412541
;; * no-sanitizer: Disable the sanitizer and render the content inside current page. It's **insecure** and may lead to XSS attack if the content contains malicious code.
25422542
;; * iframe: Render the content in a separate standalone page and embed it into current page by iframe. The iframe is in sandbox mode with same-origin disabled, and the JS code are safely isolated from parent page.
2543-
;RENDER_CONTENT_MODE=sanitized
2543+
;RENDER_CONTENT_MODE = sanitized
2544+
;; The sandbox applied to the iframe and Content-Security-Policy header when RENDER_CONTENT_MODE is `iframe`.
2545+
;; It defaults to a safe set of "allow-*" restrictions (space separated).
2546+
;; You can also set it by your requirements or use "disabled" to disable the sandbox completely.
2547+
;; When set it, make sure there is no security risk:
2548+
;; * PDF-only content: generally safe to use "disabled", and it needs to be "disabled" because PDF only renders with no sandbox.
2549+
;; * HTML content with JS: if the "RENDER_COMMAND" can guarantee there is no XSS, then it is safe, otherwise, you need to fine tune the "allow-*" restrictions.
2550+
;RENDER_CONTENT_SANDBOX =
2551+
;; Whether post-process the rendered HTML content, including:
2552+
;; resolve relative links and image sources, recognizing issue/commit references, escaping invisible characters,
2553+
;; mentioning users, rendering permlink code blocks, replacing emoji shorthands, etc.
2554+
;; By default, this is true when RENDER_CONTENT_MODE is `sanitized`, otherwise false.
2555+
;NEED_POST_PROCESS = false
25442556

25452557
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25462558
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

eslint.config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ export default defineConfig([
4949
},
5050
linterOptions: {
5151
reportUnusedDisableDirectives: 2,
52+
reportUnusedInlineConfigs: 2,
5253
},
5354
plugins: {
5455
'@eslint-community/eslint-comments': comments,

models/admin/task.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
repo_model "code.gitea.io/gitea/models/repo"
1212
user_model "code.gitea.io/gitea/models/user"
1313
"code.gitea.io/gitea/modules/json"
14+
"code.gitea.io/gitea/modules/log"
1415
"code.gitea.io/gitea/modules/migration"
1516
"code.gitea.io/gitea/modules/secret"
1617
"code.gitea.io/gitea/modules/setting"
@@ -123,17 +124,17 @@ func (task *Task) MigrateConfig() (*migration.MigrateOptions, error) {
123124
// decrypt credentials
124125
if opts.CloneAddrEncrypted != "" {
125126
if opts.CloneAddr, err = secret.DecryptSecret(setting.SecretKey, opts.CloneAddrEncrypted); err != nil {
126-
return nil, err
127+
log.Error("Unable to decrypt CloneAddr, maybe SECRET_KEY is wrong: %v", err)
127128
}
128129
}
129130
if opts.AuthPasswordEncrypted != "" {
130131
if opts.AuthPassword, err = secret.DecryptSecret(setting.SecretKey, opts.AuthPasswordEncrypted); err != nil {
131-
return nil, err
132+
log.Error("Unable to decrypt AuthPassword, maybe SECRET_KEY is wrong: %v", err)
132133
}
133134
}
134135
if opts.AuthTokenEncrypted != "" {
135136
if opts.AuthToken, err = secret.DecryptSecret(setting.SecretKey, opts.AuthTokenEncrypted); err != nil {
136-
return nil, err
137+
log.Error("Unable to decrypt AuthToken, maybe SECRET_KEY is wrong: %v", err)
137138
}
138139
}
139140

models/auth/twofactor.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,11 @@ func (t *TwoFactor) SetSecret(secretString string) error {
111111
func (t *TwoFactor) ValidateTOTP(passcode string) (bool, error) {
112112
decodedStoredSecret, err := base64.StdEncoding.DecodeString(t.Secret)
113113
if err != nil {
114-
return false, err
114+
return false, fmt.Errorf("ValidateTOTP invalid base64: %w", err)
115115
}
116116
secretBytes, err := secret.AesDecrypt(t.getEncryptionKey(), decodedStoredSecret)
117117
if err != nil {
118-
return false, err
118+
return false, fmt.Errorf("ValidateTOTP unable to decrypt (maybe SECRET_KEY is wrong): %w", err)
119119
}
120120
secretStr := string(secretBytes)
121121
return totp.Validate(passcode, secretStr), nil

models/git/lfs.go

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import (
88
"fmt"
99

1010
"code.gitea.io/gitea/models/db"
11-
"code.gitea.io/gitea/models/perm"
1211
repo_model "code.gitea.io/gitea/models/repo"
1312
"code.gitea.io/gitea/models/unit"
1413
user_model "code.gitea.io/gitea/models/user"
@@ -42,30 +41,6 @@ func (err ErrLFSLockNotExist) Unwrap() error {
4241
return util.ErrNotExist
4342
}
4443

45-
// ErrLFSUnauthorizedAction represents a "LFSUnauthorizedAction" kind of error.
46-
type ErrLFSUnauthorizedAction struct {
47-
RepoID int64
48-
UserName string
49-
Mode perm.AccessMode
50-
}
51-
52-
// IsErrLFSUnauthorizedAction checks if an error is a ErrLFSUnauthorizedAction.
53-
func IsErrLFSUnauthorizedAction(err error) bool {
54-
_, ok := err.(ErrLFSUnauthorizedAction)
55-
return ok
56-
}
57-
58-
func (err ErrLFSUnauthorizedAction) Error() string {
59-
if err.Mode == perm.AccessModeWrite {
60-
return fmt.Sprintf("User %s doesn't have write access for lfs lock [rid: %d]", err.UserName, err.RepoID)
61-
}
62-
return fmt.Sprintf("User %s doesn't have read access for lfs lock [rid: %d]", err.UserName, err.RepoID)
63-
}
64-
65-
func (err ErrLFSUnauthorizedAction) Unwrap() error {
66-
return util.ErrPermissionDenied
67-
}
68-
6944
// ErrLFSLockAlreadyExist represents a "LFSLockAlreadyExist" kind of error.
7045
type ErrLFSLockAlreadyExist struct {
7146
RepoID int64
@@ -93,12 +68,6 @@ type ErrLFSFileLocked struct {
9368
UserName string
9469
}
9570

96-
// IsErrLFSFileLocked checks if an error is a ErrLFSFileLocked.
97-
func IsErrLFSFileLocked(err error) bool {
98-
_, ok := err.(ErrLFSFileLocked)
99-
return ok
100-
}
101-
10271
func (err ErrLFSFileLocked) Error() string {
10372
return fmt.Sprintf("File is lfs locked [repo: %d, locked by: %s, path: %s]", err.RepoID, err.UserName, err.Path)
10473
}

models/git/lfs_lock.go

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,7 @@ import (
1111
"time"
1212

1313
"code.gitea.io/gitea/models/db"
14-
"code.gitea.io/gitea/models/perm"
15-
access_model "code.gitea.io/gitea/models/perm/access"
1614
repo_model "code.gitea.io/gitea/models/repo"
17-
"code.gitea.io/gitea/models/unit"
1815
user_model "code.gitea.io/gitea/models/user"
1916
"code.gitea.io/gitea/modules/setting"
2017
"code.gitea.io/gitea/modules/util"
@@ -71,10 +68,6 @@ func (l *LFSLock) LoadOwner(ctx context.Context) error {
7168
// CreateLFSLock creates a new lock.
7269
func CreateLFSLock(ctx context.Context, repo *repo_model.Repository, lock *LFSLock) (*LFSLock, error) {
7370
return db.WithTx2(ctx, func(ctx context.Context) (*LFSLock, error) {
74-
if err := CheckLFSAccessForRepo(ctx, lock.OwnerID, repo, perm.AccessModeWrite); err != nil {
75-
return nil, err
76-
}
77-
7871
lock.Path = util.PathJoinRel(lock.Path)
7972
lock.RepoID = repo.ID
8073

@@ -165,10 +158,6 @@ func DeleteLFSLockByID(ctx context.Context, id int64, repo *repo_model.Repositor
165158
return nil, err
166159
}
167160

168-
if err := CheckLFSAccessForRepo(ctx, u.ID, repo, perm.AccessModeWrite); err != nil {
169-
return nil, err
170-
}
171-
172161
if !force && u.ID != lock.OwnerID {
173162
return nil, errors.New("user doesn't own lock and force flag is not set")
174163
}
@@ -180,22 +169,3 @@ func DeleteLFSLockByID(ctx context.Context, id int64, repo *repo_model.Repositor
180169
return lock, nil
181170
})
182171
}
183-
184-
// CheckLFSAccessForRepo check needed access mode base on action
185-
func CheckLFSAccessForRepo(ctx context.Context, ownerID int64, repo *repo_model.Repository, mode perm.AccessMode) error {
186-
if ownerID == 0 {
187-
return ErrLFSUnauthorizedAction{repo.ID, "undefined", mode}
188-
}
189-
u, err := user_model.GetUserByID(ctx, ownerID)
190-
if err != nil {
191-
return err
192-
}
193-
perm, err := access_model.GetUserRepoPermission(ctx, repo, u)
194-
if err != nil {
195-
return err
196-
}
197-
if !perm.CanAccess(mode, unit.TypeCode) {
198-
return ErrLFSUnauthorizedAction{repo.ID, u.DisplayName(), mode}
199-
}
200-
return nil
201-
}

models/git/protected_branch.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ package git
55

66
import (
77
"context"
8-
"errors"
98
"fmt"
109
"slices"
1110
"strings"
@@ -25,7 +24,7 @@ import (
2524
"xorm.io/builder"
2625
)
2726

28-
var ErrBranchIsProtected = errors.New("branch is protected")
27+
var ErrBranchIsProtected = util.ErrorWrap(util.ErrPermissionDenied, "branch is protected")
2928

3029
// ProtectedBranch struct
3130
type ProtectedBranch struct {

models/perm/access/repo_permission.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@ package access
55

66
import (
77
"context"
8+
"errors"
89
"fmt"
910
"slices"
1011

12+
actions_model "code.gitea.io/gitea/models/actions"
1113
"code.gitea.io/gitea/models/db"
1214
"code.gitea.io/gitea/models/organization"
1315
perm_model "code.gitea.io/gitea/models/perm"
@@ -253,6 +255,34 @@ func finalProcessRepoUnitPermission(user *user_model.User, perm *Permission) {
253255
}
254256
}
255257

258+
// GetActionsUserRepoPermission returns the actions user permissions to the repository
259+
func GetActionsUserRepoPermission(ctx context.Context, repo *repo_model.Repository, actionsUser *user_model.User, taskID int64) (perm Permission, err error) {
260+
if actionsUser.ID != user_model.ActionsUserID {
261+
return perm, errors.New("api GetActionsUserRepoPermission can only be called by the actions user")
262+
}
263+
task, err := actions_model.GetTaskByID(ctx, taskID)
264+
if err != nil {
265+
return perm, err
266+
}
267+
if task.RepoID != repo.ID {
268+
// FIXME allow public repo read access if tokenless pull is enabled
269+
return perm, nil
270+
}
271+
272+
var accessMode perm_model.AccessMode
273+
if task.IsForkPullRequest {
274+
accessMode = perm_model.AccessModeRead
275+
} else {
276+
accessMode = perm_model.AccessModeWrite
277+
}
278+
279+
if err := repo.LoadUnits(ctx); err != nil {
280+
return perm, err
281+
}
282+
perm.SetUnitsWithDefaultAccessMode(repo.Units, accessMode)
283+
return perm, nil
284+
}
285+
256286
// GetUserRepoPermission returns the user permissions to the repository
257287
func GetUserRepoPermission(ctx context.Context, repo *repo_model.Repository, user *user_model.User) (perm Permission, err error) {
258288
defer func() {

0 commit comments

Comments
 (0)