Skip to content

Commit 421a496

Browse files
authored
Merge branch 'main' into lunny/add_transaction_set_merged
2 parents 4eff10f + 3c1c508 commit 421a496

Some content is hidden

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

48 files changed

+679
-1007
lines changed

go.mod

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ require (
7171
github.com/google/uuid v1.6.0
7272
github.com/gorilla/feeds v1.2.0
7373
github.com/gorilla/sessions v1.4.0
74-
github.com/h2non/gock v1.2.0
7574
github.com/hashicorp/go-version v1.7.0
7675
github.com/hashicorp/golang-lru/v2 v2.0.7
7776
github.com/huandu/xstrings v1.5.0
@@ -230,7 +229,6 @@ require (
230229
github.com/gorilla/handlers v1.5.2 // indirect
231230
github.com/gorilla/mux v1.8.1 // indirect
232231
github.com/gorilla/securecookie v1.1.2 // indirect
233-
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 // indirect
234232
github.com/hashicorp/errwrap v1.1.0 // indirect
235233
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
236234
github.com/hashicorp/go-multierror v1.1.1 // indirect

go.sum

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -452,10 +452,6 @@ github.com/gorilla/sessions v1.2.0/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/z
452452
github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
453453
github.com/gorilla/sessions v1.4.0 h1:kpIYOp/oi6MG/p5PgxApU8srsSw9tuFbt46Lt7auzqQ=
454454
github.com/gorilla/sessions v1.4.0/go.mod h1:FLWm50oby91+hl7p/wRxDth9bWSuk0qVL2emc7lT5ik=
455-
github.com/h2non/gock v1.2.0 h1:K6ol8rfrRkUOefooBC8elXoaNGYkpp7y2qcxGG6BzUE=
456-
github.com/h2non/gock v1.2.0/go.mod h1:tNhoxHYW2W42cYkYb1WqzdbYIieALC99kpYr7rH/BQk=
457-
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw=
458-
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI=
459455
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
460456
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
461457
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
@@ -599,8 +595,6 @@ github.com/msteinert/pam v1.2.0 h1:mYfjlvN2KYs2Pb9G6nb/1f/nPfAttT/Jee5Sq9r3bGE=
599595
github.com/msteinert/pam v1.2.0/go.mod h1:d2n0DCUK8rGecChV3JzvmsDjOY4R7AYbsNxAT+ftQl0=
600596
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
601597
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
602-
github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32 h1:W6apQkHrMkS0Muv8G/TipAy/FJl/rCYT0+EuS8+Z0z4=
603-
github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms=
604598
github.com/niklasfasching/go-org v1.7.0 h1:vyMdcMWWTe/XmANk19F4k8XGBYg0GQ/gJGMimOjGMek=
605599
github.com/niklasfasching/go-org v1.7.0/go.mod h1:WuVm4d45oePiE0eX25GqTDQIt/qPW1T9DGkRscqLW5o=
606600
github.com/nwaples/rardecode v1.1.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0=

models/repo/repo.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,8 @@ func (repo *Repository) IsBroken() bool {
279279
}
280280

281281
// MarkAsBrokenEmpty marks the repo as broken and empty
282+
// FIXME: the status "broken" and "is_empty" were abused,
283+
// The code always set them together, no way to distinguish whether a repo is really "empty" or "broken"
282284
func (repo *Repository) MarkAsBrokenEmpty() {
283285
repo.Status = RepositoryBroken
284286
repo.IsEmpty = true

modules/auth/password/pwn/pwn_test.go

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,46 +4,57 @@
44
package pwn
55

66
import (
7+
"errors"
8+
"io"
79
"net/http"
10+
"strings"
811
"testing"
9-
"time"
1012

11-
"github.com/h2non/gock"
1213
"github.com/stretchr/testify/assert"
1314
)
1415

15-
var client = New(WithHTTP(&http.Client{
16-
Timeout: time.Second * 2,
17-
}))
16+
type mockTransport struct{}
17+
18+
func (mockTransport) RoundTrip(req *http.Request) (*http.Response, error) {
19+
if req.URL.Host != "api.pwnedpasswords.com" {
20+
return nil, errors.New("unsupported host")
21+
}
22+
respMap := map[string]string{
23+
"/range/5c1d8": "EAF2F254732680E8AC339B84F3266ECCBB5:1\r\nFC446EB88938834178CB9322C1EE273C2A7:2",
24+
"/range/ba189": "FD4CB34F0378BCB15D23F6FFD28F0775C9E:3\r\nFDF342FCD8C3611DAE4D76E8A992A3E4169:4",
25+
"/range/a1733": "C4CE0F1F0062B27B9E2F41AF0C08218017C:1\r\nFC446EB88938834178CB9322C1EE273C2A7:2\r\nFE81480327C992FE62065A827429DD1318B:0",
26+
"/range/5617b": "FD4CB34F0378BCB15D23F6FFD28F0775C9E:3\r\nFDF342FCD8C3611DAE4D76E8A992A3E4169:4\r\nFE81480327C992FE62065A827429DD1318B:0",
27+
"/range/79082": "FDF342FCD8C3611DAE4D76E8A992A3E4169:4\r\nFE81480327C992FE62065A827429DD1318B:0\r\nAFEF386F56EB0B4BE314E07696E5E6E6536:0",
28+
}
29+
if resp, ok := respMap[req.URL.Path]; ok {
30+
return &http.Response{Request: req, Body: io.NopCloser(strings.NewReader(resp))}, nil
31+
}
32+
return nil, errors.New("unsupported path")
33+
}
1834

1935
func TestPassword(t *testing.T) {
20-
defer gock.Off()
36+
client := New(WithHTTP(&http.Client{Transport: mockTransport{}}))
2137

2238
count, err := client.CheckPassword("", false)
2339
assert.ErrorIs(t, err, ErrEmptyPassword, "blank input should return ErrEmptyPassword")
2440
assert.Equal(t, -1, count)
2541

26-
gock.New("https://api.pwnedpasswords.com").Get("/range/5c1d8").Times(1).Reply(200).BodyString("EAF2F254732680E8AC339B84F3266ECCBB5:1\r\nFC446EB88938834178CB9322C1EE273C2A7:2")
2742
count, err = client.CheckPassword("pwned", false)
2843
assert.NoError(t, err)
2944
assert.Equal(t, 1, count)
3045

31-
gock.New("https://api.pwnedpasswords.com").Get("/range/ba189").Times(1).Reply(200).BodyString("FD4CB34F0378BCB15D23F6FFD28F0775C9E:3\r\nFDF342FCD8C3611DAE4D76E8A992A3E4169:4")
3246
count, err = client.CheckPassword("notpwned", false)
3347
assert.NoError(t, err)
3448
assert.Equal(t, 0, count)
3549

36-
gock.New("https://api.pwnedpasswords.com").Get("/range/a1733").Times(1).Reply(200).BodyString("C4CE0F1F0062B27B9E2F41AF0C08218017C:1\r\nFC446EB88938834178CB9322C1EE273C2A7:2\r\nFE81480327C992FE62065A827429DD1318B:0")
3750
count, err = client.CheckPassword("paddedpwned", true)
3851
assert.NoError(t, err)
3952
assert.Equal(t, 1, count)
4053

41-
gock.New("https://api.pwnedpasswords.com").Get("/range/5617b").Times(1).Reply(200).BodyString("FD4CB34F0378BCB15D23F6FFD28F0775C9E:3\r\nFDF342FCD8C3611DAE4D76E8A992A3E4169:4\r\nFE81480327C992FE62065A827429DD1318B:0")
4254
count, err = client.CheckPassword("paddednotpwned", true)
4355
assert.NoError(t, err)
4456
assert.Equal(t, 0, count)
4557

46-
gock.New("https://api.pwnedpasswords.com").Get("/range/79082").Times(1).Reply(200).BodyString("FDF342FCD8C3611DAE4D76E8A992A3E4169:4\r\nFE81480327C992FE62065A827429DD1318B:0\r\nAFEF386F56EB0B4BE314E07696E5E6E6536:0")
4758
count, err = client.CheckPassword("paddednotpwnedzero", true)
4859
assert.NoError(t, err)
4960
assert.Equal(t, 0, count)

options/locale/locale_en-US.ini

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1235,6 +1235,7 @@ create_new_repo_command = Creating a new repository on the command line
12351235
push_exist_repo = Pushing an existing repository from the command line
12361236
empty_message = This repository does not contain any content.
12371237
broken_message = The Git data underlying this repository cannot be read. Contact the administrator of this instance or delete this repository.
1238+
no_branch = This repository doesn’t have any branches.
12381239
12391240
code = Code
12401241
code.desc = Access source code, files, commits and branches.
@@ -3764,6 +3765,7 @@ workflow.not_found = Workflow '%s' not found.
37643765
workflow.run_success = Workflow '%s' run successfully.
37653766
workflow.from_ref = Use workflow from
37663767
workflow.has_workflow_dispatch = This workflow has a workflow_dispatch event trigger.
3768+
workflow.has_no_workflow_dispatch = Workflow '%s' has no workflow_dispatch event trigger.
37673769

37683770
need_approval_desc = Need approval to run workflows for fork pull request.
37693771

options/locale/locale_pt-PT.ini

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -495,7 +495,7 @@ register_notify.text_3=Se esta conta foi criada para si, <a href="%s">defina a s
495495

496496
reset_password=Recupere a sua conta
497497
reset_password.title=%s, você pediu para recuperar a sua conta
498-
reset_password.text=Por favor clique na seguinte ligação para recuperar a sua conta em <b>%s</b>:
498+
reset_password.text=Para recuperar a sua conta, clique na ligação seguinte (válida por <b>%s</b>):
499499

500500
register_success=Inscrição bem sucedida
501501

@@ -1017,6 +1017,8 @@ owner=Proprietário(a)
10171017
owner_helper=Algumas organizações podem não aparecer na lista suspensa devido a um limite máximo de contagem de repositórios.
10181018
repo_name=Nome do repositório
10191019
repo_name_profile_public_hint=.profile é um repositório especial que pode usar para adicionar README.md ao seu perfil público da organização, visível para qualquer pessoa. Certifique-se que é público e inicialize-o com um README na pasta do perfil para começar.
1020+
repo_name_profile_private_hint=.profile-private é um repositório especial que pode usar para adicionar um README.md ao seu perfil de membro da organização, visível apenas para membros da organização. Certifique-se que é privado e inicialize-o com um README na pasta de perfil para começar.
1021+
repo_name_helper=Bons nomes de repositórios usam palavras-chave curtas, memorizáveis e únicas. Um repositório chamado ".profile" ou ".profile-private" pode ser usado para adicionar um README.md ao perfil do utilizador ou da organização.
10201022
repo_size=Tamanho do repositório
10211023
template=Modelo
10221024
template_select=Escolha um modelo.
@@ -1233,6 +1235,7 @@ create_new_repo_command=Criando um novo repositório na linha de comandos
12331235
push_exist_repo=Enviando, pela linha de comandos, um repositório existente
12341236
empty_message=Este repositório não contém qualquer conteúdo.
12351237
broken_message=Os dados Git subjacentes a este repositório não podem ser lidos. Contacte o administrador desta instância ou elimine este repositório.
1238+
no_branch=Este repositório não tem quaisquer ramos.
12361239

12371240
code=Código
12381241
code.desc=Aceder ao código fonte, ficheiros, cometimentos e ramos.

routers/api/packages/pypi/pypi.go

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"regexp"
1111
"sort"
1212
"strings"
13+
"unicode"
1314

1415
packages_model "code.gitea.io/gitea/models/packages"
1516
packages_module "code.gitea.io/gitea/modules/packages"
@@ -139,9 +140,30 @@ func UploadPackageFile(ctx *context.Context) {
139140
return
140141
}
141142

142-
projectURL := ctx.Req.FormValue("home_page")
143-
if !validation.IsValidURL(projectURL) {
144-
projectURL = ""
143+
// Ensure ctx.Req.Form exists.
144+
_ = ctx.Req.ParseForm()
145+
146+
var homepageURL string
147+
projectURLs := ctx.Req.Form["project_urls"]
148+
for _, purl := range projectURLs {
149+
label, url, found := strings.Cut(purl, ",")
150+
if !found {
151+
continue
152+
}
153+
if normalizeLabel(label) != "homepage" {
154+
continue
155+
}
156+
homepageURL = strings.TrimSpace(url)
157+
break
158+
}
159+
160+
if len(homepageURL) == 0 {
161+
// TODO: Home-page is a deprecated metadata field. Remove this branch once it's no longer apart of the spec.
162+
homepageURL = ctx.Req.FormValue("home_page")
163+
}
164+
165+
if !validation.IsValidURL(homepageURL) {
166+
homepageURL = ""
145167
}
146168

147169
_, _, err = packages_service.CreatePackageOrAddFileToExisting(
@@ -160,7 +182,7 @@ func UploadPackageFile(ctx *context.Context) {
160182
Description: ctx.Req.FormValue("description"),
161183
LongDescription: ctx.Req.FormValue("long_description"),
162184
Summary: ctx.Req.FormValue("summary"),
163-
ProjectURL: projectURL,
185+
ProjectURL: homepageURL,
164186
License: ctx.Req.FormValue("license"),
165187
RequiresPython: ctx.Req.FormValue("requires_python"),
166188
},
@@ -189,6 +211,23 @@ func UploadPackageFile(ctx *context.Context) {
189211
ctx.Status(http.StatusCreated)
190212
}
191213

214+
// Normalizes a Project-URL label.
215+
// See https://packaging.python.org/en/latest/specifications/well-known-project-urls/#label-normalization.
216+
func normalizeLabel(label string) string {
217+
var builder strings.Builder
218+
219+
// "A label is normalized by deleting all ASCII punctuation and whitespace, and then converting the result
220+
// to lowercase."
221+
for _, r := range label {
222+
if unicode.IsPunct(r) || unicode.IsSpace(r) {
223+
continue
224+
}
225+
builder.WriteRune(unicode.ToLower(r))
226+
}
227+
228+
return builder.String()
229+
}
230+
192231
func isValidNameAndVersion(packageName, packageVersion string) bool {
193232
return nameMatcher.MatchString(packageName) && versionMatcher.MatchString(packageVersion)
194233
}

routers/api/packages/pypi/pypi_test.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,13 @@ func TestIsValidNameAndVersion(t *testing.T) {
3636
assert.False(t, isValidNameAndVersion("test-name", "1.0.1aa"))
3737
assert.False(t, isValidNameAndVersion("test-name", "1.0.0-alpha.beta"))
3838
}
39+
40+
func TestNormalizeLabel(t *testing.T) {
41+
// Cases fetched from https://packaging.python.org/en/latest/specifications/well-known-project-urls/#label-normalization.
42+
assert.Equal(t, "homepage", normalizeLabel("Homepage"))
43+
assert.Equal(t, "homepage", normalizeLabel("Home-page"))
44+
assert.Equal(t, "homepage", normalizeLabel("Home page"))
45+
assert.Equal(t, "changelog", normalizeLabel("Change_Log"))
46+
assert.Equal(t, "whatsnew", normalizeLabel("What's New?"))
47+
assert.Equal(t, "github", normalizeLabel("github"))
48+
}

0 commit comments

Comments
 (0)