Skip to content

Commit b963fdf

Browse files
committed
Merge remote-tracking branch 'giteaofficial/main'
* giteaofficial/main: Fix http auth header parsing (go-gitea#34936) Don't send trigger for a pending review's comment create/update/delete (go-gitea#34928) Support getting last commit message using contents-ext API (go-gitea#34904) [skip ci] Updated translations via Crowdin Exclude devtest.ts from tailwindcss (go-gitea#34935)
2 parents 87b6f5a + d6d643f commit b963fdf

26 files changed

+311
-236
lines changed

models/issues/comment.go

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -715,7 +715,8 @@ func (c *Comment) LoadReactions(ctx context.Context, repo *repo_model.Repository
715715
return nil
716716
}
717717

718-
func (c *Comment) loadReview(ctx context.Context) (err error) {
718+
// LoadReview loads the associated review
719+
func (c *Comment) LoadReview(ctx context.Context) (err error) {
719720
if c.ReviewID == 0 {
720721
return nil
721722
}
@@ -732,11 +733,6 @@ func (c *Comment) loadReview(ctx context.Context) (err error) {
732733
return nil
733734
}
734735

735-
// LoadReview loads the associated review
736-
func (c *Comment) LoadReview(ctx context.Context) error {
737-
return c.loadReview(ctx)
738-
}
739-
740736
// DiffSide returns "previous" if Comment.Line is a LOC of the previous changes and "proposed" if it is a LOC of the proposed changes.
741737
func (c *Comment) DiffSide() string {
742738
if c.Line < 0 {
@@ -856,7 +852,7 @@ func updateCommentInfos(ctx context.Context, opts *CreateCommentOptions, comment
856852
}
857853
if comment.ReviewID != 0 {
858854
if comment.Review == nil {
859-
if err := comment.loadReview(ctx); err != nil {
855+
if err := comment.LoadReview(ctx); err != nil {
860856
return err
861857
}
862858
}

modules/auth/httpauth/httpauth.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Copyright 2025 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package httpauth
5+
6+
import (
7+
"encoding/base64"
8+
"strings"
9+
10+
"code.gitea.io/gitea/modules/util"
11+
)
12+
13+
type BasicAuth struct {
14+
Username, Password string
15+
}
16+
17+
type BearerToken struct {
18+
Token string
19+
}
20+
21+
type ParsedAuthorizationHeader struct {
22+
BasicAuth *BasicAuth
23+
BearerToken *BearerToken
24+
}
25+
26+
func ParseAuthorizationHeader(header string) (ret ParsedAuthorizationHeader, _ bool) {
27+
parts := strings.Fields(header)
28+
if len(parts) != 2 {
29+
return ret, false
30+
}
31+
if util.AsciiEqualFold(parts[0], "basic") {
32+
s, err := base64.StdEncoding.DecodeString(parts[1])
33+
if err != nil {
34+
return ret, false
35+
}
36+
u, p, ok := strings.Cut(string(s), ":")
37+
if !ok {
38+
return ret, false
39+
}
40+
ret.BasicAuth = &BasicAuth{Username: u, Password: p}
41+
return ret, true
42+
} else if util.AsciiEqualFold(parts[0], "token") || util.AsciiEqualFold(parts[0], "bearer") {
43+
ret.BearerToken = &BearerToken{Token: parts[1]}
44+
return ret, true
45+
}
46+
return ret, false
47+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Copyright 2025 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package httpauth
5+
6+
import (
7+
"encoding/base64"
8+
"testing"
9+
10+
"github.com/stretchr/testify/assert"
11+
)
12+
13+
func TestParseAuthorizationHeader(t *testing.T) {
14+
type parsed = ParsedAuthorizationHeader
15+
type basic = BasicAuth
16+
type bearer = BearerToken
17+
cases := []struct {
18+
headerValue string
19+
expected parsed
20+
ok bool
21+
}{
22+
{"", parsed{}, false},
23+
{"?", parsed{}, false},
24+
{"foo", parsed{}, false},
25+
{"any value", parsed{}, false},
26+
27+
{"Basic ?", parsed{}, false},
28+
{"Basic " + base64.StdEncoding.EncodeToString([]byte("foo")), parsed{}, false},
29+
{"Basic " + base64.StdEncoding.EncodeToString([]byte("foo:bar")), parsed{BasicAuth: &basic{"foo", "bar"}}, true},
30+
{"basic " + base64.StdEncoding.EncodeToString([]byte("foo:bar")), parsed{BasicAuth: &basic{"foo", "bar"}}, true},
31+
32+
{"token value", parsed{BearerToken: &bearer{"value"}}, true},
33+
{"Token value", parsed{BearerToken: &bearer{"value"}}, true},
34+
{"bearer value", parsed{BearerToken: &bearer{"value"}}, true},
35+
{"Bearer value", parsed{BearerToken: &bearer{"value"}}, true},
36+
{"Bearer wrong value", parsed{}, false},
37+
}
38+
for _, c := range cases {
39+
ret, ok := ParseAuthorizationHeader(c.headerValue)
40+
assert.Equal(t, c.ok, ok, "header %q", c.headerValue)
41+
assert.Equal(t, c.expected, ret, "header %q", c.headerValue)
42+
}
43+
}

modules/base/tool.go

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,10 @@ import (
88
"crypto/sha1"
99
"crypto/sha256"
1010
"crypto/subtle"
11-
"encoding/base64"
1211
"encoding/hex"
13-
"errors"
1412
"fmt"
1513
"hash"
1614
"strconv"
17-
"strings"
1815
"time"
1916

2017
"code.gitea.io/gitea/modules/setting"
@@ -36,19 +33,6 @@ func ShortSha(sha1 string) string {
3633
return util.TruncateRunes(sha1, 10)
3734
}
3835

39-
// BasicAuthDecode decode basic auth string
40-
func BasicAuthDecode(encoded string) (string, string, error) {
41-
s, err := base64.StdEncoding.DecodeString(encoded)
42-
if err != nil {
43-
return "", "", err
44-
}
45-
46-
if username, password, ok := strings.Cut(string(s), ":"); ok {
47-
return username, password, nil
48-
}
49-
return "", "", errors.New("invalid basic authentication")
50-
}
51-
5236
// VerifyTimeLimitCode verify time limit code
5337
func VerifyTimeLimitCode(now time.Time, data string, minutes int, code string) bool {
5438
if len(code) <= 18 {

modules/base/tool_test.go

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -26,25 +26,6 @@ func TestShortSha(t *testing.T) {
2626
assert.Equal(t, "veryverylo", ShortSha("veryverylong"))
2727
}
2828

29-
func TestBasicAuthDecode(t *testing.T) {
30-
_, _, err := BasicAuthDecode("?")
31-
assert.Equal(t, "illegal base64 data at input byte 0", err.Error())
32-
33-
user, pass, err := BasicAuthDecode("Zm9vOmJhcg==")
34-
assert.NoError(t, err)
35-
assert.Equal(t, "foo", user)
36-
assert.Equal(t, "bar", pass)
37-
38-
_, _, err = BasicAuthDecode("aW52YWxpZA==")
39-
assert.Error(t, err)
40-
41-
_, _, err = BasicAuthDecode("invalid")
42-
assert.Error(t, err)
43-
44-
_, _, err = BasicAuthDecode("YWxpY2U=") // "alice", no colon
45-
assert.Error(t, err)
46-
}
47-
4829
func TestVerifyTimeLimitCode(t *testing.T) {
4930
defer test.MockVariableValue(&setting.InstallLock, true)()
5031
initGeneralSecret := func(secret string) {

modules/structs/repo_file.go

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -116,14 +116,17 @@ type ContentsExtResponse struct {
116116

117117
// ContentsResponse contains information about a repo's entry's (dir, file, symlink, submodule) metadata and content
118118
type ContentsResponse struct {
119-
Name string `json:"name"`
120-
Path string `json:"path"`
121-
SHA string `json:"sha"`
122-
LastCommitSHA string `json:"last_commit_sha"`
119+
Name string `json:"name"`
120+
Path string `json:"path"`
121+
SHA string `json:"sha"`
122+
123+
LastCommitSHA *string `json:"last_commit_sha,omitempty"`
123124
// swagger:strfmt date-time
124-
LastCommitterDate time.Time `json:"last_committer_date"`
125+
LastCommitterDate *time.Time `json:"last_committer_date,omitempty"`
125126
// swagger:strfmt date-time
126-
LastAuthorDate time.Time `json:"last_author_date"`
127+
LastAuthorDate *time.Time `json:"last_author_date,omitempty"`
128+
LastCommitMessage *string `json:"last_commit_message,omitempty"`
129+
127130
// `type` will be `file`, `dir`, `symlink`, or `submodule`
128131
Type string `json:"type"`
129132
Size int64 `json:"size"`
@@ -141,8 +144,8 @@ type ContentsResponse struct {
141144
SubmoduleGitURL *string `json:"submodule_git_url"`
142145
Links *FileLinksResponse `json:"_links"`
143146

144-
LfsOid *string `json:"lfs_oid"`
145-
LfsSize *int64 `json:"lfs_size"`
147+
LfsOid *string `json:"lfs_oid,omitempty"`
148+
LfsSize *int64 `json:"lfs_size,omitempty"`
146149
}
147150

148151
// FileCommitResponse contains information generated from a Git commit for a repo's file.

modules/util/string.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,3 +110,24 @@ func SplitTrimSpace(input, sep string) []string {
110110
}
111111
return stringList
112112
}
113+
114+
func asciiLower(b byte) byte {
115+
if 'A' <= b && b <= 'Z' {
116+
return b + ('a' - 'A')
117+
}
118+
return b
119+
}
120+
121+
// AsciiEqualFold is from Golang https://cs.opensource.google/go/go/+/refs/tags/go1.24.4:src/net/http/internal/ascii/print.go
122+
// ASCII only. In most cases for protocols, we should only use this but not [strings.EqualFold]
123+
func AsciiEqualFold(s, t string) bool { //nolint:revive // PascalCase
124+
if len(s) != len(t) {
125+
return false
126+
}
127+
for i := 0; i < len(s); i++ {
128+
if asciiLower(s[i]) != asciiLower(t[i]) {
129+
return false
130+
}
131+
}
132+
return true
133+
}

options/locale/locale_fr-FR.ini

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1969,6 +1969,7 @@ pulls.cmd_instruction_checkout_title=Basculer
19691969
pulls.cmd_instruction_checkout_desc=Depuis votre dépôt, basculer sur une nouvelle branche et tester des modifications.
19701970
pulls.cmd_instruction_merge_title=Fusionner
19711971
pulls.cmd_instruction_merge_desc=Fusionner les modifications et mettre à jour sur Gitea.
1972+
pulls.cmd_instruction_merge_warning=Attention : cette opération ne peut pas fusionner la demande d’ajout car la « détection automatique de fusion manuelle » n’a pas été activée
19721973
pulls.clear_merge_message=Effacer le message de fusion
19731974
pulls.clear_merge_message_hint=Effacer le message de fusion ne supprimera que le message de la révision, mais pas les pieds de révision générés tels que "Co-Authored-By:".
19741975

@@ -2768,6 +2769,8 @@ branch.new_branch_from=`Créer une nouvelle branche à partir de "%s"`
27682769
branch.renamed=La branche %s à été renommée en %s.
27692770
branch.rename_default_or_protected_branch_error=Seuls les administrateurs peuvent renommer les branches par défaut ou protégées.
27702771
branch.rename_protected_branch_failed=Cette branche est protégée par des règles de protection basées sur des globs.
2772+
branch.commits_divergence_from=Divergence de révisions : %[1]d en retard et %[2]d en avance sur %[3]s
2773+
branch.commits_no_divergence=Identique à la branche %[1]s
27712774

27722775
tag.create_tag=Créer l'étiquette %s
27732776
tag.create_tag_operation=Créer une étiquette

options/locale/locale_ga-IE.ini

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2769,6 +2769,8 @@ branch.new_branch_from=`Cruthaigh brainse nua ó "%s"`
27692769
branch.renamed=Ainmníodh brainse %s go %s.
27702770
branch.rename_default_or_protected_branch_error=Ní féidir ach le riarthóirí brainsí réamhshocraithe nó cosanta a athainmniú.
27712771
branch.rename_protected_branch_failed=Tá an brainse seo faoi chosaint ag rialacha cosanta domhanda.
2772+
branch.commits_divergence_from=Déanann sé dialltacht a thiomnú: %[1]d taobh thiar agus %[2]d chun tosaigh ar %[3]s
2773+
branch.commits_no_divergence=Mar an gcéanna le brainse %[1]s
27722774
27732775
tag.create_tag=Cruthaigh clib %s
27742776
tag.create_tag_operation=Cruthaigh clib

options/locale/locale_pt-PT.ini

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2769,6 +2769,8 @@ branch.new_branch_from=`Criar um novo ramo a partir do ramo "%s"`
27692769
branch.renamed=O ramo %s foi renomeado para %s.
27702770
branch.rename_default_or_protected_branch_error=Só os administradores é que podem renomear o ramo principal ou ramos protegidos.
27712771
branch.rename_protected_branch_failed=Este ramo está protegido por regras de salvaguarda baseadas em padrões glob.
2772+
branch.commits_divergence_from=Divergência nos cometimentos: %[1]d atrás e %[2]d à frente de %[3]s
2773+
branch.commits_no_divergence=Idêntico ao ramo %[1]s
27722774

27732775
tag.create_tag=Criar etiqueta %s
27742776
tag.create_tag_operation=Criar etiqueta

0 commit comments

Comments
 (0)