Skip to content

Commit 20cf4b7

Browse files
lunnywxiaoguang
andauthored
Fix various permission & login related bugs (#36002) (#36004)
Backport #36002 Permission & protection check: - Fix Delete Release permission check - Fix Update Pull Request with rebase branch protection check - Fix Issue Dependency permission check - Fix Delete Comment History ID check Information leaking: - Show unified message for non-existing user and invalid password - Fix #35984 - Don't expose release draft to non-writer users. - Make API returns signature's email address instead of the user profile's. Auth & Login: - Avoid GCM OAuth2 attempt when OAuth2 is disabled - Fix #35510 --------- Co-authored-by: wxiaoguang <[email protected]>
1 parent 5e7207d commit 20cf4b7

File tree

19 files changed

+389
-61
lines changed

19 files changed

+389
-61
lines changed

.editorconfig

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ insert_final_newline = false
2525
[templates/user/auth/oidc_wellknown.tmpl]
2626
indent_style = space
2727

28+
[templates/shared/actions/runner_badge_*.tmpl]
29+
# editconfig lint requires these XML-like files to have charset defined, but the files don't have.
30+
charset = unset
31+
2832
[Makefile]
2933
indent_style = tab
3034

routers/api/v1/api.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ import (
8282
"code.gitea.io/gitea/modules/log"
8383
"code.gitea.io/gitea/modules/setting"
8484
api "code.gitea.io/gitea/modules/structs"
85+
"code.gitea.io/gitea/modules/util"
8586
"code.gitea.io/gitea/modules/web"
8687
"code.gitea.io/gitea/routers/api/v1/activitypub"
8788
"code.gitea.io/gitea/routers/api/v1/admin"
@@ -791,7 +792,9 @@ func apiAuth(authMethod auth.Method) func(*context.APIContext) {
791792
return func(ctx *context.APIContext) {
792793
ar, err := common.AuthShared(ctx.Base, nil, authMethod)
793794
if err != nil {
794-
ctx.APIError(http.StatusUnauthorized, err)
795+
msg, ok := auth.ErrAsUserAuthMessage(err)
796+
msg = util.Iif(ok, msg, "invalid username, password or token")
797+
ctx.APIError(http.StatusUnauthorized, msg)
795798
return
796799
}
797800
ctx.Doer = ar.Doer

routers/api/v1/repo/issue_dependency.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ func CreateIssueDependency(ctx *context.APIContext) {
201201
return
202202
}
203203

204-
dependencyPerm := getPermissionForRepo(ctx, target.Repo)
204+
dependencyPerm := getPermissionForRepo(ctx, dependency.Repo)
205205
if ctx.Written() {
206206
return
207207
}
@@ -262,7 +262,7 @@ func RemoveIssueDependency(ctx *context.APIContext) {
262262
return
263263
}
264264

265-
dependencyPerm := getPermissionForRepo(ctx, target.Repo)
265+
dependencyPerm := getPermissionForRepo(ctx, dependency.Repo)
266266
if ctx.Written() {
267267
return
268268
}

routers/api/v1/repo/release_tags.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"net/http"
88

99
repo_model "code.gitea.io/gitea/models/repo"
10+
unit_model "code.gitea.io/gitea/models/unit"
1011
"code.gitea.io/gitea/services/context"
1112
"code.gitea.io/gitea/services/convert"
1213
release_service "code.gitea.io/gitea/services/release"
@@ -58,6 +59,13 @@ func GetReleaseByTag(ctx *context.APIContext) {
5859
return
5960
}
6061

62+
if release.IsDraft { // only the users with write access can see draft releases
63+
if !ctx.IsSigned || !ctx.Repo.CanWrite(unit_model.TypeReleases) {
64+
ctx.APIErrorNotFound()
65+
return
66+
}
67+
}
68+
6169
if err = release.LoadAttributes(ctx); err != nil {
6270
ctx.APIErrorInternal(err)
6371
return

routers/web/repo/githttp.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,13 @@ func httpBase(ctx *context.Context) *serviceHandler {
147147
// rely on the results of Contexter
148148
if !ctx.IsSigned {
149149
// TODO: support digit auth - which would be Authorization header with digit
150-
ctx.Resp.Header().Set("WWW-Authenticate", `Basic realm="Gitea"`)
150+
if setting.OAuth2.Enabled {
151+
// `Basic realm="Gitea"` tells the GCM to use builtin OAuth2 application: https://github.com/git-ecosystem/git-credential-manager/pull/1442
152+
ctx.Resp.Header().Set("WWW-Authenticate", `Basic realm="Gitea"`)
153+
} else {
154+
// If OAuth2 is disabled, then use another realm to avoid GCM OAuth2 attempt
155+
ctx.Resp.Header().Set("WWW-Authenticate", `Basic realm="Gitea (Basic Auth)"`)
156+
}
151157
ctx.HTTPError(http.StatusUnauthorized)
152158
return nil
153159
}

routers/web/repo/issue_content_history.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -206,12 +206,11 @@ func SoftDeleteContentHistory(ctx *context.Context) {
206206
ctx.NotFound(issues_model.ErrCommentNotExist{})
207207
return
208208
}
209+
if history.CommentID != commentID {
210+
ctx.NotFound(issues_model.ErrCommentNotExist{})
211+
return
212+
}
209213
if commentID != 0 {
210-
if history.CommentID != commentID {
211-
ctx.NotFound(issues_model.ErrCommentNotExist{})
212-
return
213-
}
214-
215214
if comment, err = issues_model.GetCommentByID(ctx, commentID); err != nil {
216215
log.Error("can not get comment for issue content history %v. err=%v", historyID, err)
217216
return

services/auth/auth.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package auth
66

77
import (
8+
"errors"
89
"fmt"
910
"net/http"
1011
"regexp"
@@ -40,6 +41,20 @@ var globalVars = sync.OnceValue(func() *globalVarsStruct {
4041
}
4142
})
4243

44+
type ErrUserAuthMessage string
45+
46+
func (e ErrUserAuthMessage) Error() string {
47+
return string(e)
48+
}
49+
50+
func ErrAsUserAuthMessage(err error) (string, bool) {
51+
var msg ErrUserAuthMessage
52+
if errors.As(err, &msg) {
53+
return msg.Error(), true
54+
}
55+
return "", false
56+
}
57+
4358
// Init should be called exactly once when the application starts to allow plugins
4459
// to allocate necessary resources
4560
func Init() {

services/auth/basic.go

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

77
import (
8-
"errors"
98
"net/http"
109

1110
actions_model "code.gitea.io/gitea/models/actions"
@@ -146,7 +145,7 @@ func (b *Basic) Verify(req *http.Request, w http.ResponseWriter, store DataStore
146145
return nil, err
147146
}
148147
if hasWebAuthn {
149-
return nil, errors.New("basic authorization is not allowed while WebAuthn enrolled")
148+
return nil, ErrUserAuthMessage("basic authorization is not allowed while WebAuthn enrolled")
150149
}
151150

152151
if err := validateTOTP(req, u); err != nil {

services/convert/convert.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -542,8 +542,9 @@ func ToVerification(ctx context.Context, c *git.Commit) *api.PayloadCommitVerifi
542542
}
543543
if verif.SigningUser != nil {
544544
commitVerification.Signer = &api.PayloadUser{
545-
Name: verif.SigningUser.Name,
546-
Email: verif.SigningUser.Email,
545+
UserName: verif.SigningUser.Name,
546+
Name: verif.SigningUser.DisplayName(),
547+
Email: verif.SigningEmail, // Use the email from the signature, not from the user profile
547548
}
548549
}
549550
return commitVerification

services/pull/merge.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -546,11 +546,15 @@ var escapedSymbols = regexp.MustCompile(`([*[?! \\])`)
546546

547547
// IsUserAllowedToMerge check if user is allowed to merge PR with given permissions and branch protections
548548
func IsUserAllowedToMerge(ctx context.Context, pr *issues_model.PullRequest, p access_model.Permission, user *user_model.User) (bool, error) {
549+
return isUserAllowedToMergeInRepoBranch(ctx, pr.BaseRepoID, pr.BaseBranch, p, user)
550+
}
551+
552+
func isUserAllowedToMergeInRepoBranch(ctx context.Context, repoID int64, branch string, p access_model.Permission, user *user_model.User) (bool, error) {
549553
if user == nil {
550554
return false, nil
551555
}
552556

553-
pb, err := git_model.GetFirstMatchProtectedBranchRule(ctx, pr.BaseRepoID, pr.BaseBranch)
557+
pb, err := git_model.GetFirstMatchProtectedBranchRule(ctx, repoID, branch)
554558
if err != nil {
555559
return false, err
556560
}

0 commit comments

Comments
 (0)