Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into overflow-menu
Browse files Browse the repository at this point in the history
* origin/main: (29 commits)
  Tweak actions color and borders (go-gitea#29640)
  Add download URL for executable files (go-gitea#28260)
  Move all login and account creation page labels to be above inputs (go-gitea#29432)
  Avoid issue info panic (go-gitea#29625)
  Cache repository default branch commit status to reduce query on commit status table (go-gitea#29444)
  Avoid unexpected panic in graceful manager (go-gitea#29629)
  Add a link for the recently pushed branch notification (go-gitea#29627)
  Fix wrong header of org project view page (go-gitea#29626)
  Detect broken git hooks (go-gitea#29494)
  Sync branches to DB immediately when handle git hook calling (go-gitea#29493)
  Fix wrong line number in code search result (go-gitea#29260)
  Make wiki default branch name changable (go-gitea#29603)
  A small refactor for agit implementation (go-gitea#29614)
  Update Twitter Logo (go-gitea#29621)
  Fix 500 error when adding PR comment (go-gitea#29622)
  Run editorconfig-checker on `locale_en-US.ini` (go-gitea#29608)
  bump protobuf module (go-gitea#29617)
  Add ac claim for old docker/build-push-action@v3 / current buildx gha cache (go-gitea#29584)
  Skip email domain check when admins edit user emails (go-gitea#29609)
  Improve natural sort (go-gitea#29611)
  ...
  • Loading branch information
silverwind committed Mar 6, 2024
2 parents 8718035 + 16f1326 commit de5074c
Show file tree
Hide file tree
Showing 109 changed files with 1,246 additions and 627 deletions.
1 change: 1 addition & 0 deletions .github/workflows/files-changed.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ jobs:
- "Makefile"
- ".golangci.yml"
- ".editorconfig"
- "options/locale/locale_en-US.ini"
frontend:
- "**/*.js"
Expand Down
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ GO_DIRS := build cmd models modules routers services tests
WEB_DIRS := web_src/js web_src/css

SPELLCHECK_FILES := $(GO_DIRS) $(WEB_DIRS) docs/content templates options/locale/locale_en-US.ini .github
EDITORCONFIG_FILES := templates .github/workflows options/locale/locale_en-US.ini

GO_SOURCES := $(wildcard *.go)
GO_SOURCES += $(shell find $(GO_DIRS) -type f -name "*.go" ! -path modules/options/bindata.go ! -path modules/public/bindata.go ! -path modules/templates/bindata.go)
Expand Down Expand Up @@ -426,7 +427,7 @@ lint-go-vet:

.PHONY: lint-editorconfig
lint-editorconfig:
$(GO) run $(EDITORCONFIG_CHECKER_PACKAGE) templates .github/workflows
@$(GO) run $(EDITORCONFIG_CHECKER_PACKAGE) $(EDITORCONFIG_FILES)

.PHONY: lint-actions
lint-actions:
Expand Down
2 changes: 1 addition & 1 deletion docs/content/contributing/guidelines-frontend.en-us.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ We recommend [Google HTML/CSS Style Guide](https://google.github.io/styleguide/h
9. Avoid unnecessary `!important` in CSS, add comments to explain why it's necessary if it can't be avoided.
10. Avoid mixing different events in one event listener, prefer to use individual event listeners for every event.
11. Custom event names are recommended to use `ce-` prefix.
12. Gitea's tailwind-style CSS classes use `gt-` prefix (`gt-relative`), while Gitea's own private framework-level CSS classes use `g-` prefix (`g-modal-confirm`).
12. Prefer using Tailwind CSS which is available via `tw-` prefix, e.g. `tw-relative`. Gitea's helper CSS classes use `gt-` prefix (`gt-df`), while Gitea's own private framework-level CSS classes use `g-` prefix (`g-modal-confirm`).
13. Avoid inline scripts & styles as much as possible, it's recommended to put JS code into JS files and use CSS classes. If inline scripts & styles are unavoidable, explain the reason why it can't be avoided.

### Accessibility / ARIA
Expand Down
2 changes: 1 addition & 1 deletion docs/content/contributing/guidelines-frontend.zh-cn.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ HTML 页面由[Go HTML Template](https://pkg.go.dev/html/template)渲染。
9. 避免在 CSS 中使用不必要的`!important`,如果无法避免,添加注释解释为什么需要它。
10. 避免在一个事件监听器中混合不同的事件,优先为每个事件使用独立的事件监听器。
11. 推荐使用自定义事件名称前缀`ce-`
12. Gitea 的 tailwind-style CSS 类使用`gt-`前缀(`gt-relative`),Gitea 自身的私有框架级 CSS 类使用`g-`前缀(`g-modal-confirm`)。
12. 建议使用 Tailwind CSS,它可以通过 `tw-` 前缀获得,例如 `tw-relative`. Gitea 自身的助手类 CSS 使用 `gt-` 前缀(`gt-df`),Gitea 自身的私有框架级 CSS 类使用 `g-` 前缀(`g-modal-confirm`)。
13. 尽量避免内联脚本和样式,建议将JS代码放入JS文件中并使用CSS类。如果内联脚本和样式不可避免,请解释无法避免的原因。

### 可访问性 / ARIA
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ require (
golang.org/x/text v0.14.0
golang.org/x/tools v0.17.0
google.golang.org/grpc v1.60.1
google.golang.org/protobuf v1.32.0
google.golang.org/protobuf v1.33.0
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
gopkg.in/ini.v1 v1.67.0
gopkg.in/yaml.v3 v3.0.1
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1308,8 +1308,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I=
google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
10 changes: 7 additions & 3 deletions models/activities/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -393,10 +393,14 @@ func (a *Action) GetCreate() time.Time {
return a.CreatedUnix.AsTime()
}

// GetIssueInfos returns a list of issues associated with
// the action.
// GetIssueInfos returns a list of associated information with the action.
func (a *Action) GetIssueInfos() []string {
return strings.SplitN(a.Content, "|", 3)
// make sure it always returns 3 elements, because there are some access to the a[1] and a[2] without checking the length
ret := strings.SplitN(a.Content, "|", 3)
for len(ret) < 3 {
ret = append(ret, "")
}
return ret
}

// GetIssueTitle returns the title of first issue associated with the action.
Expand Down
5 changes: 5 additions & 0 deletions models/git/branch.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,11 @@ func GetBranch(ctx context.Context, repoID int64, branchName string) (*Branch, e
return &branch, nil
}

func GetBranches(ctx context.Context, repoID int64, branchNames []string) ([]*Branch, error) {
branches := make([]*Branch, 0, len(branchNames))
return branches, db.GetEngine(ctx).Where("repo_id=?", repoID).In("name", branchNames).Find(&branches)
}

func AddBranches(ctx context.Context, branches []*Branch) error {
for _, branch := range branches {
if _, err := db.GetEngine(ctx).Insert(branch); err != nil {
Expand Down
2 changes: 2 additions & 0 deletions models/migrations/migrations.go
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,8 @@ var migrations = []Migration{
NewMigration("Use Slug instead of ID for Badges", v1_22.UseSlugInsteadOfIDForBadges),
// v288 -> v289
NewMigration("Add user_blocking table", v1_22.AddUserBlockingTable),
// v289 -> v290
NewMigration("Add default_wiki_branch to repository table", v1_22.AddDefaultWikiBranch),
}

// GetCurrentDBVersion returns the current db version
Expand Down
18 changes: 18 additions & 0 deletions models/migrations/v1_22/v289.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT

package v1_22 //nolint

import "xorm.io/xorm"

func AddDefaultWikiBranch(x *xorm.Engine) error {
type Repository struct {
ID int64
DefaultWikiBranch string
}
if err := x.Sync(&Repository{}); err != nil {
return err
}
_, err := x.Exec("UPDATE `repository` SET default_wiki_branch = 'master' WHERE (default_wiki_branch IS NULL) OR (default_wiki_branch = '')")
return err
}
4 changes: 4 additions & 0 deletions models/repo/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ type Repository struct {
OriginalServiceType api.GitServiceType `xorm:"index"`
OriginalURL string `xorm:"VARCHAR(2048)"`
DefaultBranch string
DefaultWikiBranch string

NumWatches int
NumStars int
Expand Down Expand Up @@ -285,6 +286,9 @@ func (repo *Repository) AfterLoad() {
repo.NumOpenMilestones = repo.NumMilestones - repo.NumClosedMilestones
repo.NumOpenProjects = repo.NumProjects - repo.NumClosedProjects
repo.NumOpenActionRuns = repo.NumActionRuns - repo.NumClosedActionRuns
if repo.DefaultWikiBranch == "" {
repo.DefaultWikiBranch = setting.Repository.DefaultBranch
}
}

// LoadAttributes loads attributes of the repository.
Expand Down
75 changes: 47 additions & 28 deletions models/user/email_address.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,37 +154,18 @@ func UpdateEmailAddress(ctx context.Context, email *EmailAddress) error {

var emailRegexp = regexp.MustCompile("^[a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]*@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$")

// ValidateEmail check if email is a allowed address
// ValidateEmail check if email is a valid & allowed address
func ValidateEmail(email string) error {
if len(email) == 0 {
return ErrEmailInvalid{email}
}

if !emailRegexp.MatchString(email) {
return ErrEmailCharIsNotSupported{email}
}

if email[0] == '-' {
return ErrEmailInvalid{email}
}

if _, err := mail.ParseAddress(email); err != nil {
return ErrEmailInvalid{email}
}

// if there is no allow list, then check email against block list
if len(setting.Service.EmailDomainAllowList) == 0 &&
validation.IsEmailDomainListed(setting.Service.EmailDomainBlockList, email) {
return ErrEmailInvalid{email}
}

// if there is an allow list, then check email against allow list
if len(setting.Service.EmailDomainAllowList) > 0 &&
!validation.IsEmailDomainListed(setting.Service.EmailDomainAllowList, email) {
return ErrEmailInvalid{email}
if err := validateEmailBasic(email); err != nil {
return err
}
return validateEmailDomain(email)
}

return nil
// ValidateEmailForAdmin check if email is a valid address when admins manually add or edit users
func ValidateEmailForAdmin(email string) error {
return validateEmailBasic(email)
// In this case we do not need to check the email domain
}

func GetEmailAddressByEmail(ctx context.Context, email string) (*EmailAddress, error) {
Expand Down Expand Up @@ -534,3 +515,41 @@ func ActivateUserEmail(ctx context.Context, userID int64, email string, activate

return committer.Commit()
}

// validateEmailBasic checks whether the email complies with the rules
func validateEmailBasic(email string) error {
if len(email) == 0 {
return ErrEmailInvalid{email}
}

if !emailRegexp.MatchString(email) {
return ErrEmailCharIsNotSupported{email}
}

if email[0] == '-' {
return ErrEmailInvalid{email}
}

if _, err := mail.ParseAddress(email); err != nil {
return ErrEmailInvalid{email}
}

return nil
}

// validateEmailDomain checks whether the email domain is allowed or blocked
func validateEmailDomain(email string) error {
// if there is no allow list, then check email against block list
if len(setting.Service.EmailDomainAllowList) == 0 &&
validation.IsEmailDomainListed(setting.Service.EmailDomainBlockList, email) {
return ErrEmailInvalid{email}
}

// if there is an allow list, then check email against allow list
if len(setting.Service.EmailDomainAllowList) > 0 &&
!validation.IsEmailDomainListed(setting.Service.EmailDomainAllowList, email) {
return ErrEmailInvalid{email}
}

return nil
}
20 changes: 18 additions & 2 deletions models/user/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,16 @@ type CreateUserOverwriteOptions struct {

// CreateUser creates record of a new user.
func CreateUser(ctx context.Context, u *User, overwriteDefault ...*CreateUserOverwriteOptions) (err error) {
return createUser(ctx, u, false, overwriteDefault...)
}

// AdminCreateUser is used by admins to manually create users
func AdminCreateUser(ctx context.Context, u *User, overwriteDefault ...*CreateUserOverwriteOptions) (err error) {
return createUser(ctx, u, true, overwriteDefault...)
}

// createUser creates record of a new user.
func createUser(ctx context.Context, u *User, createdByAdmin bool, overwriteDefault ...*CreateUserOverwriteOptions) (err error) {
if err = IsUsableUsername(u.Name); err != nil {
return err
}
Expand Down Expand Up @@ -639,8 +649,14 @@ func CreateUser(ctx context.Context, u *User, overwriteDefault ...*CreateUserOve
return err
}

if err := ValidateEmail(u.Email); err != nil {
return err
if createdByAdmin {
if err := ValidateEmailForAdmin(u.Email); err != nil {
return err
}
} else {
if err := ValidateEmail(u.Email); err != nil {
return err
}
}

ctx, committer, err := db.TxContext(ctx)
Expand Down
81 changes: 4 additions & 77 deletions modules/base/natural_sort.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,85 +4,12 @@
package base

import (
"math/big"
"unicode/utf8"
"golang.org/x/text/collate"
"golang.org/x/text/language"
)

// NaturalSortLess compares two strings so that they could be sorted in natural order
func NaturalSortLess(s1, s2 string) bool {
var i1, i2 int
for {
rune1, j1, end1 := getNextRune(s1, i1)
rune2, j2, end2 := getNextRune(s2, i2)
if end1 || end2 {
return end1 != end2 && end1
}
dec1 := isDecimal(rune1)
dec2 := isDecimal(rune2)
var less, equal bool
if dec1 && dec2 {
i1, i2, less, equal = compareByNumbers(s1, i1, s2, i2)
} else if !dec1 && !dec2 {
equal = rune1 == rune2
less = rune1 < rune2
i1 = j1
i2 = j2
} else {
return rune1 < rune2
}
if !equal {
return less
}
}
}

func getNextRune(str string, pos int) (rune, int, bool) {
if pos < len(str) {
r, w := utf8.DecodeRuneInString(str[pos:])
// Fallback to ascii
if r == utf8.RuneError {
r = rune(str[pos])
w = 1
}
return r, pos + w, false
}
return 0, pos, true
}

func isDecimal(r rune) bool {
return '0' <= r && r <= '9'
}

func compareByNumbers(str1 string, pos1 int, str2 string, pos2 int) (i1, i2 int, less, equal bool) {
d1, d2 := true, true
var dec1, dec2 string
for d1 || d2 {
if d1 {
r, j, end := getNextRune(str1, pos1)
if !end && isDecimal(r) {
dec1 += string(r)
pos1 = j
} else {
d1 = false
}
}
if d2 {
r, j, end := getNextRune(str2, pos2)
if !end && isDecimal(r) {
dec2 += string(r)
pos2 = j
} else {
d2 = false
}
}
}
less, equal = compareBigNumbers(dec1, dec2)
return pos1, pos2, less, equal
}

func compareBigNumbers(dec1, dec2 string) (less, equal bool) {
d1, _ := big.NewInt(0).SetString(dec1, 10)
d2, _ := big.NewInt(0).SetString(dec2, 10)
cmp := d1.Cmp(d2)
return cmp < 0, cmp == 0
c := collate.New(language.English, collate.Numeric)
return c.CompareString(s1, s2) < 0
}
9 changes: 8 additions & 1 deletion modules/base/natural_sort_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (

func TestNaturalSortLess(t *testing.T) {
test := func(s1, s2 string, less bool) {
assert.Equal(t, less, NaturalSortLess(s1, s2))
assert.Equal(t, less, NaturalSortLess(s1, s2), "s1=%q, s2=%q", s1, s2)
}
test("v1.20.0", "v1.2.0", false)
test("v1.20.0", "v1.29.0", true)
Expand All @@ -20,4 +20,11 @@ func TestNaturalSortLess(t *testing.T) {
test("a-1-a", "a-1-b", true)
test("2", "12", true)
test("a", "ab", true)

test("A", "b", true)
test("a", "B", true)

test("cafe", "café", true)
test("café", "cafe", false)
test("caff", "café", false)
}
4 changes: 2 additions & 2 deletions modules/git/repo_base_gogit.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ package git

import (
"context"
"errors"
"path/filepath"

gitealog "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"

"github.com/go-git/go-billy/v5"
"github.com/go-git/go-billy/v5/osfs"
Expand Down Expand Up @@ -52,7 +52,7 @@ func OpenRepository(ctx context.Context, repoPath string) (*Repository, error) {
if err != nil {
return nil, err
} else if !isDir(repoPath) {
return nil, errors.New("no such file or directory")
return nil, util.NewNotExistErrorf("no such file or directory")
}

fs := osfs.New(repoPath)
Expand Down
Loading

0 comments on commit de5074c

Please sign in to comment.