Compare commits

...

30 Commits

Author SHA1 Message Date
Lunny Xiao
9879e23c57 Changelog for v1.15.7 (#17871)
* Changelog for v1.15.7

Co-authored-by: zeripath <art27@cantab.net>
Co-authored-by: 6543 <6543@obermui.de>
2021-12-02 21:16:33 +01:00
Lunny Xiao
56a3b50136 Check if column exist before rename if exist, just return with no error (#17870) (#17882)
* Check if column exist before rename if exist, just return with no error

* Also check if errors column exist

* Add comment for migration

* Fix sqlite test
2021-12-02 18:12:11 +01:00
a1012112796
9a8532d928 fix 500 error while use a reserved name in org rename (#17878) (#17881)
fix #17876

Signed-off-by: a1012112796 <1012112796@qq.com>
2021-12-02 19:52:08 +08:00
Lunny Xiao
d29a0fc3be Fix user primary email changed (#17840) 2021-11-28 12:04:44 +01:00
Gusted
04517e17d6 Use correct user on releases (#17818)
- Backport #17806
2021-11-26 07:06:26 +00:00
KN4CK3R
3a222ee416 Fixed commit count (#17698) (#17790)
* Fixed commit count (#17698)

Added "Tag" label.
Unified branch, tag and commit name.

* Keep 1.15 behaviour.

* Removed locale change.
2021-11-26 00:21:56 +01:00
silverwind
add85f5a85 Preserve color when inverting emojis (#17799)
Fixes: https://github.com/go-gitea/gitea/issues/17795
2021-11-24 22:43:22 +08:00
Gusted
76ad83f05e backport: use correct sender on title change (#17792) 2021-11-24 03:53:18 -05:00
Lunny Xiao
714ecd9f1e Fix close issue but time watcher still running (#17761)
* Fix bug

* Update models/issue_stopwatch.go

Co-authored-by: zeripath <art27@cantab.net>

Co-authored-by: zeripath <art27@cantab.net>
2021-11-23 20:05:44 +08:00
Lunny Xiao
a08856606e Return 400 but not 500 when request archive with wrong format (#17691) (#17700)
* Return 400 but not 500 when request archive with wrong format (#17691)
* Remove bundle because it's not in this version
2021-11-20 00:31:29 +08:00
99rgosse
7be2d7b136 Fix Migrate Description - backport (#17727) 2021-11-19 17:52:47 +08:00
Lunny Xiao
6f3596e33c Fix bug when project board get open issue number (#17703) (#17726)
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: techknowlogick <techknowlogick@gitea.io>

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: techknowlogick <techknowlogick@gitea.io>
2021-11-19 14:28:37 +08:00
Lunny Xiao
0305a73633 Fix bug when read mysql database max lifetime (#17682) (#17690) 2021-11-17 21:28:41 +08:00
wxiaoguang
6cd1ccef3d Backport #17649, fix database deadlock when update issue labels (#17665) 2021-11-17 13:32:31 +08:00
Gusted
ea0fe83888 Fix golangci-lint warnings (#17598 et al) (#17668)
Backport #17598 
Backport #17606 
Backport #17608 
Backport #17609

- Since https://gitea.com/gitea/test-env/pulls/10 the golangci-lint has been upgraded and is erroring about new warnings in the code, this PR fixes those warnings.
2021-11-16 20:38:49 +00:00
Lunny Xiao
1cec7f5ab5 Fix bug on detect issue/comment writer (#17592) 2021-11-09 16:00:40 +08:00
Gusted
1cb1101d44 backport(1.15): Fix stats upon searching issues (#17578)
- Backport of https://github.com/go-gitea/gitea/pull/17566

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: zeripath <art27@cantab.net>
2021-11-08 23:14:57 +02:00
zeripath
653dff4e57 Remove appSubUrl from pasted images (#17572) (#17588)
Backport #17572

* Remove appSubUrl from pasted images

Since we fixed the url base for the links in repositories we no longer need to add
the appsuburl to pasted image links.

Fix #17057

Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-11-08 20:28:10 +00:00
Gusted
b661bbaed7 backport(1.15): make ParsePatch more robust (#17580)
- Backport of https://github.com/go-gitea/gitea/pull/17573
2021-11-08 11:28:16 +08:00
wxiaoguang
20ae184967 Only allow webhook to send requests to allowed hosts (#17482) (#17510)
Backport #17482

* Only allow webhook to send requests to allowed hosts (backport #17482)

* use ALLOWED_HOST_LIST=* for default to keep the legacy behavior in 1.15.x
2021-11-06 09:23:43 +00:00
zeripath
15b44496ec Escape issue titles in comments list (#17555) (#17556)
Signed-off-by: Andrew Thornton <art27@cantab.net>

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2021-11-05 23:20:51 +00:00
Gusted
0d0ff5e32a backport(1.15): Use correct defaultValue for stracktrace (#17557)
- Backporting https://github.com/go-gitea/gitea/pull/17552
2021-11-05 22:55:33 +08:00
Lunny Xiao
f25f7c592f Fix zero created time bug on commit api (#17547)
Co-authored-by: zeripath <art27@cantab.net>
2021-11-05 14:15:44 +08:00
delvh
e8cf04bad7 Show correct "No" icon (#17538) 2021-11-04 15:29:37 -04:00
Lunny Xiao
251fdaaf41 Fix database keyword quote problem on migration v161 (#17523)
* support rerun migration v161
2021-11-03 06:33:38 +02:00
Lunny Xiao
f572fb906f fix email with + when active (#17518) (#17520)
Co-authored-by: zeripath <art27@cantab.net>
2021-11-03 00:52:38 +02:00
zeripath
9340269d84 Stop double encoding blame commit messages (#17498) (#17500)
Backport #17498

The call to html.EscapeString in routers/web/repo/blame.go:renderBlame is extraneous
as the commit message is now rendered by the template. The template will correctly
escape strings - therefore we are currently double escaping.

This PR fixes this.

Fix #17492

Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-10-31 17:46:51 +08:00
zeripath
34650b925b Quote the table name in CountOrphanedObjects (#17487) (#17488)
Backport #17487

CountOrphanedObjects needs to quote the table it is joining with as this table may
be `user`.

Fix #17485

Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-10-30 12:01:22 +02:00
zeripath
718e0db12e Run Migrate in Install rather than just SyncTables (#17475) (#17486)
Backport #17475

The underlying problem in #17328 appears to be that users are re-running the install
page during upgrades. The function that tests and creates the db did not intend for
this and thus instead the migration scripts being run - a simple sync tables occurs.

This then causes a weird partially migrated DB which causes, in this release cycle,
the duplicate column in task table error. It is likely the cause of some weird
partial migration errors in other cycles too.

This PR simply ensures that the migration scripts are also run at this point too.

Fix #17328

Signed-off-by: Andrew Thornton <art27@cantab.net>
2021-10-30 10:28:11 +01:00
qwerty287
6110ddc280 Fix login redirection links (#17473) 2021-10-28 21:47:26 +08:00
152 changed files with 946 additions and 287 deletions

View File

@@ -9,7 +9,6 @@ linters:
- unused - unused
- structcheck - structcheck
- varcheck - varcheck
- golint
- dupl - dupl
#- gocyclo # The cyclomatic complexety of a lot of functions is too high, we should refactor those another time. #- gocyclo # The cyclomatic complexety of a lot of functions is too high, we should refactor those another time.
- gofmt - gofmt

View File

@@ -4,6 +4,37 @@ This changelog goes through all the changes that have been made in each release
without substantial changes to our git log; to see the highlights of what has without substantial changes to our git log; to see the highlights of what has
been added to each release, please refer to the [blog](https://blog.gitea.io). been added to each release, please refer to the [blog](https://blog.gitea.io).
## [1.15.7](https://github.com/go-gitea/gitea/releases/tag/v1.15.7) - 2021-12-01
* ENHANCEMENTS
* Only allow webhook to send requests to allowed hosts (#17482) (#17510)
* Fix login redirection links (#17451) (#17473)
* BUGFIXES
* Fix database inconsistent when admin change user email (#17549) (#17840)
* Use correct user on releases (#17806) (#17818)
* Fix commit count in tag view (#17698) (#17790)
* Fix close issue but time watcher still running (#17643) (#17761)
* Fix Migrate Description (#17692) (#17727)
* Fix bug when project board get open issue number (#17703) (#17726)
* Return 400 but not 500 when request archive with wrong format (#17691) (#17700)
* Fix bug when read mysql database max lifetime (#17682) (#17690)
* Fix database deadlock when update issue labels (#17649) (#17665)
* Fix bug on detect issue/comment writer (#17592)
* Remove appSubUrl from pasted images (#17572) (#17588)
* Make `ParsePatch` more robust (#17573) (#17580)
* Fix stats upon searching issues (#17566) (#17578)
* Escape issue titles in comments list (#17555) (#17556)
* Fix zero created time bug on commit api (#17546) (#17547)
* Fix database keyword quote problem on migration v161 (#17522) (#17523)
* Fix email with + when active (#17518) (#17520)
* Stop double encoding blame commit messages (#17498) (#17500)
* Quote the table name in CountOrphanedObjects (#17487) (#17488)
* Run Migrate in Install rather than just SyncTables (#17475) (#17486)
* BUILD
* Fix golangci-lint warnings (#17598 et al) (#17668)
* MISC
* Preserve color when inverting emojis (#17797) (#17799)
## [1.15.6](https://github.com/go-gitea/gitea/releases/tag/v1.15.6) - 2021-10-28 ## [1.15.6](https://github.com/go-gitea/gitea/releases/tag/v1.15.6) - 2021-10-28
* BUGFIXES * BUGFIXES

View File

@@ -2,7 +2,8 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//+build vendor //go:build vendor
// +build vendor
package main package main

View File

@@ -2,6 +2,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build ignore
// +build ignore // +build ignore
package main package main

View File

@@ -3,6 +3,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build ignore
// +build ignore // +build ignore
package main package main

View File

@@ -1,3 +1,4 @@
//go:build ignore
// +build ignore // +build ignore
package main package main

View File

@@ -1,3 +1,4 @@
//go:build ignore
// +build ignore // +build ignore
package main package main

View File

@@ -6,6 +6,7 @@
// gocovmerge takes the results from multiple `go test -coverprofile` runs and // gocovmerge takes the results from multiple `go test -coverprofile` runs and
// merges them into one profile // merges them into one profile
//go:build ignore
// +build ignore // +build ignore
package main package main

View File

@@ -43,7 +43,11 @@ func runDocs(ctx *cli.Context) error {
// Clean up markdown. The following bug was fixed in v2, but is present in v1. // Clean up markdown. The following bug was fixed in v2, but is present in v1.
// It affects markdown output (even though the issue is referring to man pages) // It affects markdown output (even though the issue is referring to man pages)
// https://github.com/urfave/cli/issues/1040 // https://github.com/urfave/cli/issues/1040
docs = docs[strings.Index(docs, "#"):] firstHashtagIndex := strings.Index(docs, "#")
if firstHashtagIndex > 0 {
docs = docs[firstHashtagIndex:]
}
} }
out := os.Stdout out := os.Stdout

View File

@@ -2,6 +2,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build bindata
// +build bindata // +build bindata
package cmd package cmd

View File

@@ -2,6 +2,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build !bindata
// +build !bindata // +build !bindata
package cmd package cmd

View File

@@ -194,6 +194,10 @@ func listen(m http.Handler, handleRedirector bool) error {
listenAddr = net.JoinHostPort(listenAddr, setting.HTTPPort) listenAddr = net.JoinHostPort(listenAddr, setting.HTTPPort)
} }
log.Info("Listen: %v://%s%s", setting.Protocol, listenAddr, setting.AppSubURL) log.Info("Listen: %v://%s%s", setting.Protocol, listenAddr, setting.AppSubURL)
// This can be useful for users, many users do wrong to their config and get strange behaviors behind a reverse-proxy.
// A user may fix the configuration mistake when he sees this log.
// And this is also very helpful to maintainers to provide help to users to resolve their configuration problems.
log.Info("AppURL(ROOT_URL): %s", setting.AppURL)
if setting.LFS.StartServer { if setting.LFS.StartServer {
log.Info("LFS server enabled") log.Info("LFS server enabled")

View File

@@ -1388,6 +1388,13 @@ PATH =
;; Deliver timeout in seconds ;; Deliver timeout in seconds
;DELIVER_TIMEOUT = 5 ;DELIVER_TIMEOUT = 5
;; ;;
;; Webhook can only call allowed hosts for security reasons. Comma separated list, eg: external, 192.168.1.0/24, *.mydomain.com
;; Built-in: loopback (for localhost), private (for LAN/intranet), external (for public hosts on internet), * (for all hosts)
;; CIDR list: 1.2.3.0/8, 2001:db8::/32
;; Wildcard hosts: *.mydomain.com, 192.168.100.*
;; Default to * for 1.15.x, external for 1.16 and later
;ALLOWED_HOST_LIST = *
;;
;; Allow insecure certification ;; Allow insecure certification
;SKIP_TLS_VERIFY = false ;SKIP_TLS_VERIFY = false
;; ;;

View File

@@ -545,6 +545,14 @@ Define allowed algorithms and their minimum key length (use -1 to disable a type
- `QUEUE_LENGTH`: **1000**: Hook task queue length. Use caution when editing this value. - `QUEUE_LENGTH`: **1000**: Hook task queue length. Use caution when editing this value.
- `DELIVER_TIMEOUT`: **5**: Delivery timeout (sec) for shooting webhooks. - `DELIVER_TIMEOUT`: **5**: Delivery timeout (sec) for shooting webhooks.
- `ALLOWED_HOST_LIST`: `*`: Default to `*` for 1.15.x, `external` for 1.16 and later. Webhook can only call allowed hosts for security reasons. Comma separated list.
- Built-in networks:
- `loopback`: 127.0.0.0/8 for IPv4 and ::1/128 for IPv6, localhost is included.
- `private`: RFC 1918 (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) and RFC 4193 (FC00::/7). Also called LAN/Intranet.
- `external`: A valid non-private unicast IP, you can access all hosts on public internet.
- `*`: All hosts are allowed.
- CIDR list: `1.2.3.0/8` for IPv4 and `2001:db8::/32` for IPv6
- Wildcard hosts: `*.mydomain.com`, `192.168.100.*`
- `SKIP_TLS_VERIFY`: **false**: Allow insecure certification. - `SKIP_TLS_VERIFY`: **false**: Allow insecure certification.
- `PAGING_NUM`: **10**: Number of webhook history events that are shown in one page. - `PAGING_NUM`: **10**: Number of webhook history events that are shown in one page.
- `PROXY_URL`: ****: Proxy server URL, support http://, https//, socks://, blank will follow environment http_proxy/https_proxy - `PROXY_URL`: ****: Proxy server URL, support http://, https//, socks://, blank will follow environment http_proxy/https_proxy

View File

@@ -0,0 +1,44 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package integrations
import (
"fmt"
"io"
"net/http"
"net/url"
"testing"
"code.gitea.io/gitea/models"
"github.com/stretchr/testify/assert"
)
func TestAPIDownloadArchive(t *testing.T) {
defer prepareTestEnv(t)()
repo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 1}).(*models.Repository)
user2 := models.AssertExistsAndLoadBean(t, &models.User{ID: 2}).(*models.User)
session := loginUser(t, user2.LowerName)
token := getTokenForLoggedInUser(t, session)
link, _ := url.Parse(fmt.Sprintf("/api/v1/repos/%s/%s/archive/master.zip", user2.Name, repo.Name))
link.RawQuery = url.Values{"token": {token}}.Encode()
resp := MakeRequest(t, NewRequest(t, "GET", link.String()), http.StatusOK)
bs, err := io.ReadAll(resp.Body)
assert.NoError(t, err)
assert.EqualValues(t, 320, len(bs))
link, _ = url.Parse(fmt.Sprintf("/api/v1/repos/%s/%s/archive/master.tar.gz", user2.Name, repo.Name))
link.RawQuery = url.Values{"token": {token}}.Encode()
resp = MakeRequest(t, NewRequest(t, "GET", link.String()), http.StatusOK)
bs, err = io.ReadAll(resp.Body)
assert.NoError(t, err)
assert.EqualValues(t, 266, len(bs))
link, _ = url.Parse(fmt.Sprintf("/api/v1/repos/%s/%s/archive/master", user2.Name, repo.Name))
link.RawQuery = url.Values{"token": {token}}.Encode()
MakeRequest(t, NewRequest(t, "GET", link.String()), http.StatusBadRequest)
}

View File

@@ -302,7 +302,7 @@ func DeleteOrphanedIssues() error {
// CountOrphanedObjects count subjects with have no existing refobject anymore // CountOrphanedObjects count subjects with have no existing refobject anymore
func CountOrphanedObjects(subject, refobject, joinCond string) (int64, error) { func CountOrphanedObjects(subject, refobject, joinCond string) (int64, error) {
return x.Table("`"+subject+"`"). return x.Table("`"+subject+"`").
Join("LEFT", refobject, joinCond). Join("LEFT", "`"+refobject+"`", joinCond).
Where(builder.IsNull{"`" + refobject + "`.id"}). Where(builder.IsNull{"`" + refobject + "`.id"}).
Count("id") Count("id")
} }

View File

@@ -1517,12 +1517,12 @@ func GetIssueStats(opts *IssueStatsOptions) (*IssueStats, error) {
func getIssueStatsChunk(opts *IssueStatsOptions, issueIDs []int64) (*IssueStats, error) { func getIssueStatsChunk(opts *IssueStatsOptions, issueIDs []int64) (*IssueStats, error) {
stats := &IssueStats{} stats := &IssueStats{}
countSession := func(opts *IssueStatsOptions) *xorm.Session { countSession := func(opts *IssueStatsOptions, issueIDs []int64) *xorm.Session {
sess := x. sess := x.
Where("issue.repo_id = ?", opts.RepoID) Where("issue.repo_id = ?", opts.RepoID)
if len(opts.IssueIDs) > 0 { if len(issueIDs) > 0 {
sess.In("issue.id", opts.IssueIDs) sess.In("issue.id", issueIDs)
} }
if len(opts.Labels) > 0 && opts.Labels != "0" { if len(opts.Labels) > 0 && opts.Labels != "0" {
@@ -1572,13 +1572,13 @@ func getIssueStatsChunk(opts *IssueStatsOptions, issueIDs []int64) (*IssueStats,
} }
var err error var err error
stats.OpenCount, err = countSession(opts). stats.OpenCount, err = countSession(opts, issueIDs).
And("issue.is_closed = ?", false). And("issue.is_closed = ?", false).
Count(new(Issue)) Count(new(Issue))
if err != nil { if err != nil {
return stats, err return stats, err
} }
stats.ClosedCount, err = countSession(opts). stats.ClosedCount, err = countSession(opts, issueIDs).
And("issue.is_closed = ?", true). And("issue.is_closed = ?", true).
Count(new(Issue)) Count(new(Issue))
return stats, err return stats, err

View File

@@ -13,6 +13,26 @@ import (
"xorm.io/xorm" "xorm.io/xorm"
) )
// ErrIssueStopwatchNotExist represents an error that stopwatch is not exist
type ErrIssueStopwatchNotExist struct {
UserID int64
IssueID int64
}
func (err ErrIssueStopwatchNotExist) Error() string {
return fmt.Sprintf("issue stopwatch doesn't exist[uid: %d, issue_id: %d", err.UserID, err.IssueID)
}
// ErrIssueStopwatchAlreadyExist represents an error that stopwatch is already exist
type ErrIssueStopwatchAlreadyExist struct {
UserID int64
IssueID int64
}
func (err ErrIssueStopwatchAlreadyExist) Error() string {
return fmt.Sprintf("issue stopwatch already exists[uid: %d, issue_id: %d", err.UserID, err.IssueID)
}
// Stopwatch represents a stopwatch for time tracking. // Stopwatch represents a stopwatch for time tracking.
type Stopwatch struct { type Stopwatch struct {
ID int64 `xorm:"pk autoincr"` ID int64 `xorm:"pk autoincr"`
@@ -74,91 +94,141 @@ func hasUserStopwatch(e Engine, userID int64) (exists bool, sw *Stopwatch, err e
return return
} }
// FinishIssueStopwatchIfPossible if stopwatch exist then finish it otherwise ignore
func FinishIssueStopwatchIfPossible(user *User, issue *Issue) error {
_, exists, err := getStopwatch(x, user.ID, issue.ID)
if err != nil {
return err
}
if !exists {
return nil
}
return FinishIssueStopwatch(user, issue)
}
// CreateOrStopIssueStopwatch will create or remove a stopwatch and will log it into issue's timeline. // CreateOrStopIssueStopwatch will create or remove a stopwatch and will log it into issue's timeline.
func CreateOrStopIssueStopwatch(user *User, issue *Issue) error { func CreateOrStopIssueStopwatch(user *User, issue *Issue) error {
_, exists, err := getStopwatch(x, user.ID, issue.ID)
if err != nil {
return err
}
if exists {
return FinishIssueStopwatch(user, issue)
}
return CreateIssueStopwatch(user, issue)
}
// FinishIssueStopwatch if stopwatch exist then finish it otherwise return an error
func FinishIssueStopwatch(user *User, issue *Issue) error {
sess := x.NewSession() sess := x.NewSession()
defer sess.Close() defer sess.Close()
if err := sess.Begin(); err != nil { if err := sess.Begin(); err != nil {
return err return err
} }
if err := createOrStopIssueStopwatch(sess, user, issue); err != nil { if err := finishIssueStopwatch(sess, user, issue); err != nil {
return err return err
} }
return sess.Commit() return sess.Commit()
} }
func createOrStopIssueStopwatch(e *xorm.Session, user *User, issue *Issue) error { func finishIssueStopwatch(e *xorm.Session, user *User, issue *Issue) error {
sw, exists, err := getStopwatch(e, user.ID, issue.ID) sw, exists, err := getStopwatch(e, user.ID, issue.ID)
if err != nil { if err != nil {
return err return err
} }
if !exists {
return ErrIssueStopwatchNotExist{
UserID: user.ID,
IssueID: issue.ID,
}
}
// Create tracked time out of the time difference between start date and actual date
timediff := time.Now().Unix() - int64(sw.CreatedUnix)
// Create TrackedTime
tt := &TrackedTime{
Created: time.Now(),
IssueID: issue.ID,
UserID: user.ID,
Time: timediff,
}
if _, err := e.Insert(tt); err != nil {
return err
}
if err := issue.loadRepo(e); err != nil {
return err
}
if _, err := createComment(e, &CreateCommentOptions{
Doer: user,
Issue: issue,
Repo: issue.Repo,
Content: SecToTime(timediff),
Type: CommentTypeStopTracking,
TimeID: tt.ID,
}); err != nil {
return err
}
_, err = e.Delete(sw)
return err
}
// CreateIssueStopwatch creates a stopwatch if not exist, otherwise return an error
func CreateIssueStopwatch(user *User, issue *Issue) error {
sess := x.NewSession()
defer sess.Close()
if err := sess.Begin(); err != nil {
return err
}
if err := createIssueStopwatch(sess, user, issue); err != nil {
return err
}
return sess.Commit()
}
func createIssueStopwatch(e *xorm.Session, user *User, issue *Issue) error {
if err := issue.loadRepo(e); err != nil { if err := issue.loadRepo(e); err != nil {
return err return err
} }
// if another stopwatch is running: stop it
exists, sw, err := hasUserStopwatch(e, user.ID)
if err != nil {
return err
}
if exists { if exists {
// Create tracked time out of the time difference between start date and actual date issue, err := getIssueByID(e, sw.IssueID)
timediff := time.Now().Unix() - int64(sw.CreatedUnix)
// Create TrackedTime
tt := &TrackedTime{
Created: time.Now(),
IssueID: issue.ID,
UserID: user.ID,
Time: timediff,
}
if _, err := e.Insert(tt); err != nil {
return err
}
if _, err := createComment(e, &CreateCommentOptions{
Doer: user,
Issue: issue,
Repo: issue.Repo,
Content: SecToTime(timediff),
Type: CommentTypeStopTracking,
TimeID: tt.ID,
}); err != nil {
return err
}
if _, err := e.Delete(sw); err != nil {
return err
}
} else {
// if another stopwatch is running: stop it
exists, sw, err := hasUserStopwatch(e, user.ID)
if err != nil { if err != nil {
return err return err
} }
if exists { if err := finishIssueStopwatch(e, user, issue); err != nil {
issue, err := getIssueByID(e, sw.IssueID)
if err != nil {
return err
}
if err := createOrStopIssueStopwatch(e, user, issue); err != nil {
return err
}
}
// Create stopwatch
sw = &Stopwatch{
UserID: user.ID,
IssueID: issue.ID,
}
if _, err := e.Insert(sw); err != nil {
return err return err
} }
}
if _, err := createComment(e, &CreateCommentOptions{ // Create stopwatch
Doer: user, sw = &Stopwatch{
Issue: issue, UserID: user.ID,
Repo: issue.Repo, IssueID: issue.ID,
Type: CommentTypeStartTracking, }
}); err != nil {
return err if _, err := e.Insert(sw); err != nil {
} return err
}
if err := issue.loadRepo(e); err != nil {
return err
}
if _, err := createComment(e, &CreateCommentOptions{
Doer: user,
Issue: issue,
Repo: issue.Repo,
Type: CommentTypeStartTracking,
}); err != nil {
return err
} }
return nil return nil
} }

View File

@@ -5,7 +5,9 @@
package models package models
import ( import (
"fmt"
"sort" "sort"
"sync"
"testing" "testing"
"time" "time"
@@ -417,3 +419,43 @@ func TestIssue_ResolveMentions(t *testing.T) {
// Private repo, whole team // Private repo, whole team
testSuccess("user17", "big_test_private_4", "user15", []string{"user17/owners"}, []int64{18}) testSuccess("user17", "big_test_private_4", "user15", []string{"user17/owners"}, []int64{18})
} }
func TestCorrectIssueStats(t *testing.T) {
assert.NoError(t, PrepareTestDatabase())
// Because the condition is to have chunked database look-ups,
// We have to more issues than `maxQueryParameters`, we will insert.
// maxQueryParameters + 10 issues into the testDatabase.
// Each new issues will have a constant description "Bugs are nasty"
// Which will be used later on.
issueAmount := maxQueryParameters + 10
var wg sync.WaitGroup
for i := 0; i < issueAmount; i++ {
wg.Add(1)
go func(i int) {
testInsertIssue(t, fmt.Sprintf("Issue %d", i+1), "Bugs are nasty", 0)
wg.Done()
}(i)
}
wg.Wait()
// Now we will get all issueID's that match the "Bugs are nasty" query.
total, ids, err := SearchIssueIDsByKeyword("Bugs are nasty", []int64{1}, issueAmount, 0)
// Just to be sure.
assert.NoError(t, err)
assert.EqualValues(t, issueAmount, total)
// Now we will call the GetIssueStats with these IDs and if working,
// get the correct stats back.
issueStats, err := GetIssueStats(&IssueStatsOptions{
RepoID: 1,
IssueIDs: ids,
})
// Now check the values.
assert.NoError(t, err)
assert.EqualValues(t, issueStats.OpenCount, issueAmount)
}

View File

@@ -7,6 +7,7 @@ package migrations
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"os" "os"
"reflect" "reflect"
@@ -762,8 +763,14 @@ func dropTableColumns(sess *xorm.Session, tableName string, columnNames ...strin
} }
tableSQL := string(res[0]["sql"]) tableSQL := string(res[0]["sql"])
// Get the string offset for column definitions: `CREATE TABLE ( column-definitions... )`
columnDefinitionsIndex := strings.Index(tableSQL, "(")
if columnDefinitionsIndex < 0 {
return errors.New("couldn't find column definitions")
}
// Separate out the column definitions // Separate out the column definitions
tableSQL = tableSQL[strings.Index(tableSQL, "("):] tableSQL = tableSQL[columnDefinitionsIndex:]
// Remove the required columnNames // Remove the required columnNames
for _, name := range columnNames { for _, name := range columnNames {

View File

@@ -5,6 +5,8 @@
package migrations package migrations
import ( import (
"context"
"xorm.io/xorm" "xorm.io/xorm"
) )
@@ -40,8 +42,17 @@ func convertTaskTypeToString(x *xorm.Engine) error {
return err return err
} }
// to keep the migration could be rerun
exist, err := x.Dialect().IsColumnExist(x.DB(), context.Background(), "hook_task", "type")
if err != nil {
return err
}
if !exist {
return nil
}
for i, s := range hookTaskTypes { for i, s := range hookTaskTypes {
if _, err := x.Exec("UPDATE hook_task set typ = ? where type=?", s, i); err != nil { if _, err := x.Exec("UPDATE hook_task set typ = ? where `type`=?", s, i); err != nil {
return err return err
} }
} }

View File

@@ -5,6 +5,7 @@
package migrations package migrations
import ( import (
"context"
"fmt" "fmt"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
@@ -19,6 +20,22 @@ func renameTaskErrorsToMessage(x *xorm.Engine) error {
Status int `xorm:"index"` Status int `xorm:"index"`
} }
// This migration maybe rerun so that we should check if it has been run
messageExist, err := x.Dialect().IsColumnExist(x.DB(), context.Background(), "task", "message")
if err != nil {
return err
}
if messageExist {
errorsExist, err := x.Dialect().IsColumnExist(x.DB(), context.Background(), "task", "errors")
if err != nil {
return err
}
if !errorsExist {
return nil
}
}
sess := x.NewSession() sess := x.NewSession()
defer sess.Close() defer sess.Close()
if err := sess.Begin(); err != nil { if err := sess.Begin(); err != nil {
@@ -29,6 +46,13 @@ func renameTaskErrorsToMessage(x *xorm.Engine) error {
return fmt.Errorf("error on Sync2: %v", err) return fmt.Errorf("error on Sync2: %v", err)
} }
if messageExist {
// if both errors and message exist, drop message at first
if err := dropTableColumns(sess, "task", "message"); err != nil {
return err
}
}
switch { switch {
case setting.Database.UseMySQL: case setting.Database.UseMySQL:
if _, err := sess.Exec("ALTER TABLE `task` CHANGE errors message text"); err != nil { if _, err := sess.Exec("ALTER TABLE `task` CHANGE errors message text"); err != nil {

View File

@@ -179,16 +179,35 @@ func syncTables() error {
return x.StoreEngine("InnoDB").Sync2(tables...) return x.StoreEngine("InnoDB").Sync2(tables...)
} }
// NewTestEngine sets a new test xorm.Engine // NewInstallTestEngine creates a new xorm.Engine for testing during install
func NewTestEngine() (err error) { //
// This function will cause the basic database schema to be created
func NewInstallTestEngine(ctx context.Context, migrateFunc func(*xorm.Engine) error) (err error) {
x, err = GetNewEngine() x, err = GetNewEngine()
if err != nil { if err != nil {
return fmt.Errorf("Connect to database: %v", err) return fmt.Errorf("failed to connect to database: %w", err)
} }
x.SetMapper(names.GonicMapper{}) x.SetMapper(names.GonicMapper{})
x.SetLogger(NewXORMLogger(!setting.IsProd())) x.SetLogger(NewXORMLogger(!setting.IsProd()))
x.ShowSQL(!setting.IsProd()) x.ShowSQL(!setting.IsProd())
x.SetDefaultContext(ctx)
if err = x.Ping(); err != nil {
return err
}
// We have to run migrateFunc here in case the user is re-running installation on a previously created DB.
// If we do not then table schemas will be changed and there will be conflicts when the migrations run properly.
//
// Installation should only be being re-run if users want to recover an old database.
// However, we should think carefully about should we support re-install on an installed instance,
// as there may be other problems due to secret reinitialization.
if err = migrateFunc(x); err != nil {
return fmt.Errorf("migrate: %v", err)
}
return syncTables() return syncTables()
} }

View File

@@ -115,7 +115,9 @@ func (p *Project) NumClosedIssues() int {
func (p *Project) NumOpenIssues() int { func (p *Project) NumOpenIssues() int {
c, err := x.Table("project_issue"). c, err := x.Table("project_issue").
Join("INNER", "issue", "project_issue.issue_id=issue.id"). Join("INNER", "issue", "project_issue.issue_id=issue.id").
Where("project_issue.project_id=? AND issue.is_closed=?", p.ID, false).Count("issue.id") Where("project_issue.project_id=? AND issue.is_closed=?", p.ID, false).
Cols("issue_id").
Count()
if err != nil { if err != nil {
return 0 return 0
} }

View File

@@ -77,9 +77,6 @@ var (
// ErrEmailNotActivated e-mail address has not been activated error // ErrEmailNotActivated e-mail address has not been activated error
ErrEmailNotActivated = errors.New("E-mail address has not been activated") ErrEmailNotActivated = errors.New("E-mail address has not been activated")
// ErrUserNameIllegal user name contains illegal characters error
ErrUserNameIllegal = errors.New("User name contains illegal characters")
// ErrLoginSourceNotActived login source is not actived error // ErrLoginSourceNotActived login source is not actived error
ErrLoginSourceNotActived = errors.New("Login source is not actived") ErrLoginSourceNotActived = errors.New("Login source is not actived")
@@ -1072,18 +1069,46 @@ func validateUser(u *User) error {
return ValidateEmail(u.Email) return ValidateEmail(u.Email)
} }
func updateUser(e Engine, u *User) error { func updateUser(e Engine, u *User, changePrimaryEmail bool) error {
if err := validateUser(u); err != nil { if err := validateUser(u); err != nil {
return err return err
} }
if changePrimaryEmail {
var emailAddress EmailAddress
has, err := e.Where("lower_email=?", strings.ToLower(u.Email)).Get(&emailAddress)
if err != nil {
return err
}
if !has {
// 1. Update old primary email
if _, err = e.Where("uid=? AND is_primary=?", u.ID, true).Cols("is_primary").Update(&EmailAddress{
IsPrimary: false,
}); err != nil {
return err
}
emailAddress.Email = u.Email
emailAddress.UID = u.ID
emailAddress.IsActivated = true
emailAddress.IsPrimary = true
if _, err := e.Insert(&emailAddress); err != nil {
return err
}
} else if _, err := e.ID(emailAddress).Cols("is_primary").Update(&EmailAddress{
IsPrimary: true,
}); err != nil {
return err
}
}
_, err := e.ID(u.ID).AllCols().Update(u) _, err := e.ID(u.ID).AllCols().Update(u)
return err return err
} }
// UpdateUser updates user's information. // UpdateUser updates user's information.
func UpdateUser(u *User) error { func UpdateUser(u *User, changePrimaryEmail bool) error {
return updateUser(x, u) return updateUser(x, u, changePrimaryEmail)
} }
// UpdateUserCols update user according special columns // UpdateUserCols update user according special columns
@@ -1112,7 +1137,7 @@ func UpdateUserSetting(u *User) (err error) {
return err return err
} }
} }
if err = updateUser(sess, u); err != nil { if err = updateUser(sess, u, false); err != nil {
return err return err
} }
return sess.Commit() return sess.Commit()

View File

@@ -475,17 +475,17 @@ func TestUpdateUser(t *testing.T) {
user := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User) user := AssertExistsAndLoadBean(t, &User{ID: 2}).(*User)
user.KeepActivityPrivate = true user.KeepActivityPrivate = true
assert.NoError(t, UpdateUser(user)) assert.NoError(t, UpdateUser(user, false))
user = AssertExistsAndLoadBean(t, &User{ID: 2}).(*User) user = AssertExistsAndLoadBean(t, &User{ID: 2}).(*User)
assert.True(t, user.KeepActivityPrivate) assert.True(t, user.KeepActivityPrivate)
setting.Service.AllowedUserVisibilityModesSlice = []bool{true, false, false} setting.Service.AllowedUserVisibilityModesSlice = []bool{true, false, false}
user.KeepActivityPrivate = false user.KeepActivityPrivate = false
user.Visibility = structs.VisibleTypePrivate user.Visibility = structs.VisibleTypePrivate
assert.Error(t, UpdateUser(user)) assert.Error(t, UpdateUser(user, false))
user = AssertExistsAndLoadBean(t, &User{ID: 2}).(*User) user = AssertExistsAndLoadBean(t, &User{ID: 2}).(*User)
assert.True(t, user.KeepActivityPrivate) assert.True(t, user.KeepActivityPrivate)
user.Email = "no mail@mail.org" user.Email = "no mail@mail.org"
assert.Error(t, UpdateUser(user)) assert.Error(t, UpdateUser(user, true))
} }

View File

@@ -1,3 +1,4 @@
//go:build pam
// +build pam // +build pam
// Copyright 2014 The Gogs Authors. All rights reserved. // Copyright 2014 The Gogs Authors. All rights reserved.

View File

@@ -1,9 +1,10 @@
// +build !pam
// Copyright 2014 The Gogs Authors. All rights reserved. // Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build !pam
// +build !pam
package pam package pam
import ( import (

View File

@@ -1,3 +1,4 @@
//go:build pam
// +build pam // +build pam
// Copyright 2021 The Gitea Authors. All rights reserved. // Copyright 2021 The Gitea Authors. All rights reserved.

View File

@@ -58,6 +58,7 @@ type Repository struct {
Commit *git.Commit Commit *git.Commit
Tag *git.Tag Tag *git.Tag
GitRepo *git.Repository GitRepo *git.Repository
RefName string
BranchName string BranchName string
TagName string TagName string
TreePath string TreePath string
@@ -190,9 +191,9 @@ func (r *Repository) BranchNameSubURL() string {
case r.IsViewBranch: case r.IsViewBranch:
return "branch/" + r.BranchName return "branch/" + r.BranchName
case r.IsViewTag: case r.IsViewTag:
return "tag/" + r.BranchName return "tag/" + r.TagName
case r.IsViewCommit: case r.IsViewCommit:
return "commit/" + r.BranchName return "commit/" + r.CommitID
} }
log.Error("Unknown view type for repo: %v", r) log.Error("Unknown view type for repo: %v", r)
return "" return ""
@@ -562,8 +563,6 @@ func RepoAssignment(ctx *Context) (cancel context.CancelFunc) {
ctx.Data["Branches"] = brs ctx.Data["Branches"] = brs
ctx.Data["BranchesCount"] = len(brs) ctx.Data["BranchesCount"] = len(brs)
ctx.Data["TagName"] = ctx.Repo.TagName
// If not branch selected, try default one. // If not branch selected, try default one.
// If default branch doesn't exists, fall back to some other branch. // If default branch doesn't exists, fall back to some other branch.
if len(ctx.Repo.BranchName) == 0 { if len(ctx.Repo.BranchName) == 0 {
@@ -572,9 +571,9 @@ func RepoAssignment(ctx *Context) (cancel context.CancelFunc) {
} else if len(brs) > 0 { } else if len(brs) > 0 {
ctx.Repo.BranchName = brs[0] ctx.Repo.BranchName = brs[0]
} }
ctx.Repo.RefName = ctx.Repo.BranchName
} }
ctx.Data["BranchName"] = ctx.Repo.BranchName ctx.Data["BranchName"] = ctx.Repo.BranchName
ctx.Data["CommitID"] = ctx.Repo.CommitID
// People who have push access or have forked repository can propose a new pull request. // People who have push access or have forked repository can propose a new pull request.
canPush := ctx.Repo.CanWrite(models.UnitTypeCode) || (ctx.IsSigned && ctx.User.HasForkedRepo(ctx.Repo.Repository.ID)) canPush := ctx.Repo.CanWrite(models.UnitTypeCode) || (ctx.IsSigned && ctx.User.HasForkedRepo(ctx.Repo.Repository.ID))
@@ -759,7 +758,6 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context
// Get default branch. // Get default branch.
if len(ctx.Params("*")) == 0 { if len(ctx.Params("*")) == 0 {
refName = ctx.Repo.Repository.DefaultBranch refName = ctx.Repo.Repository.DefaultBranch
ctx.Repo.BranchName = refName
if !ctx.Repo.GitRepo.IsBranchExist(refName) { if !ctx.Repo.GitRepo.IsBranchExist(refName) {
brs, _, err := ctx.Repo.GitRepo.GetBranches(0, 0) brs, _, err := ctx.Repo.GitRepo.GetBranches(0, 0)
if err != nil { if err != nil {
@@ -773,6 +771,8 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context
} }
refName = brs[0] refName = brs[0]
} }
ctx.Repo.RefName = refName
ctx.Repo.BranchName = refName
ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetBranchCommit(refName) ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetBranchCommit(refName)
if err != nil { if err != nil {
ctx.ServerError("GetBranchCommit", err) ctx.ServerError("GetBranchCommit", err)
@@ -783,9 +783,10 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context
} else { } else {
refName = getRefName(ctx, refType) refName = getRefName(ctx, refType)
ctx.Repo.BranchName = refName ctx.Repo.RefName = refName
if refType.RefTypeIncludesBranches() && ctx.Repo.GitRepo.IsBranchExist(refName) { if refType.RefTypeIncludesBranches() && ctx.Repo.GitRepo.IsBranchExist(refName) {
ctx.Repo.IsViewBranch = true ctx.Repo.IsViewBranch = true
ctx.Repo.BranchName = refName
ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetBranchCommit(refName) ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetBranchCommit(refName)
if err != nil { if err != nil {
@@ -796,6 +797,8 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context
} else if refType.RefTypeIncludesTags() && ctx.Repo.GitRepo.IsTagExist(refName) { } else if refType.RefTypeIncludesTags() && ctx.Repo.GitRepo.IsTagExist(refName) {
ctx.Repo.IsViewTag = true ctx.Repo.IsViewTag = true
ctx.Repo.TagName = refName
ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetTagCommit(refName) ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetTagCommit(refName)
if err != nil { if err != nil {
ctx.ServerError("GetTagCommit", err) ctx.ServerError("GetTagCommit", err)
@@ -837,6 +840,7 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context
ctx.Data["BranchName"] = ctx.Repo.BranchName ctx.Data["BranchName"] = ctx.Repo.BranchName
ctx.Data["BranchNameSubURL"] = ctx.Repo.BranchNameSubURL() ctx.Data["BranchNameSubURL"] = ctx.Repo.BranchNameSubURL()
ctx.Data["TagName"] = ctx.Repo.TagName
ctx.Data["CommitID"] = ctx.Repo.CommitID ctx.Data["CommitID"] = ctx.Repo.CommitID
ctx.Data["TreePath"] = ctx.Repo.TreePath ctx.Data["TreePath"] = ctx.Repo.TreePath
ctx.Data["IsViewBranch"] = ctx.Repo.IsViewBranch ctx.Data["IsViewBranch"] = ctx.Repo.IsViewBranch

View File

@@ -147,8 +147,9 @@ func ToCommit(repo *models.Repository, commit *git.Commit, userCache map[string]
return &api.Commit{ return &api.Commit{
CommitMeta: &api.CommitMeta{ CommitMeta: &api.CommitMeta{
URL: repo.APIURL() + "/git/commits/" + commit.ID.String(), URL: repo.APIURL() + "/git/commits/" + commit.ID.String(),
SHA: commit.ID.String(), SHA: commit.ID.String(),
Created: commit.Committer.When,
}, },
HTMLURL: repo.HTMLURL() + "/commit/" + commit.ID.String(), HTMLURL: repo.HTMLURL() + "/commit/" + commit.ID.String(),
RepoCommit: &api.RepoCommit{ RepoCommit: &api.RepoCommit{
@@ -169,8 +170,9 @@ func ToCommit(repo *models.Repository, commit *git.Commit, userCache map[string]
}, },
Message: commit.Message(), Message: commit.Message(),
Tree: &api.CommitMeta{ Tree: &api.CommitMeta{
URL: repo.APIURL() + "/git/trees/" + commit.ID.String(), URL: repo.APIURL() + "/git/trees/" + commit.ID.String(),
SHA: commit.ID.String(), SHA: commit.ID.String(),
Created: commit.Committer.When,
}, },
}, },
Author: apiAuthor, Author: apiAuthor,

View File

@@ -3,6 +3,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build gogit
// +build gogit // +build gogit
package git package git

View File

@@ -2,6 +2,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build !gogit
// +build !gogit // +build !gogit
package git package git

View File

@@ -2,6 +2,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build race
// +build race // +build race
package git package git

View File

@@ -3,6 +3,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build gogit
// +build gogit // +build gogit
package git package git

View File

@@ -2,6 +2,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build gogit
// +build gogit // +build gogit
package git package git

View File

@@ -2,6 +2,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build !gogit
// +build !gogit // +build !gogit
package git package git

View File

@@ -2,6 +2,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build gogit
// +build gogit // +build gogit
package git package git

View File

@@ -2,6 +2,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build !gogit
// +build !gogit // +build !gogit
package git package git

View File

@@ -2,6 +2,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build gogit
// +build gogit // +build gogit
package git package git

View File

@@ -2,6 +2,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build !gogit
// +build !gogit // +build !gogit
package git package git

View File

@@ -2,6 +2,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build gogit
// +build gogit // +build gogit
package git package git

View File

@@ -2,6 +2,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build gogit
// +build gogit // +build gogit
package git package git

View File

@@ -2,6 +2,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build !gogit
// +build !gogit // +build !gogit
package git package git

View File

@@ -2,6 +2,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build !gogit
// +build !gogit // +build !gogit
package git package git

View File

@@ -2,6 +2,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build gogit
// +build gogit // +build gogit
package pipeline package pipeline

View File

@@ -2,6 +2,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build !gogit
// +build !gogit // +build !gogit
package pipeline package pipeline

View File

@@ -3,6 +3,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build gogit
// +build gogit // +build gogit
package git package git

View File

@@ -3,6 +3,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build !gogit
// +build !gogit // +build !gogit
package git package git

View File

@@ -2,6 +2,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build gogit
// +build gogit // +build gogit
package git package git

View File

@@ -2,6 +2,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build !gogit
// +build !gogit // +build !gogit
package git package git

View File

@@ -3,6 +3,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build gogit
// +build gogit // +build gogit
package git package git

View File

@@ -3,6 +3,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build !gogit
// +build !gogit // +build !gogit
package git package git

View File

@@ -3,6 +3,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build gogit
// +build gogit // +build gogit
package git package git

View File

@@ -2,6 +2,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build !gogit
// +build !gogit // +build !gogit
package git package git

View File

@@ -3,6 +3,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build gogit
// +build gogit // +build gogit
package git package git

View File

@@ -2,6 +2,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build gogit
// +build gogit // +build gogit
package git package git

View File

@@ -2,6 +2,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build !gogit
// +build !gogit // +build !gogit
package git package git

View File

@@ -2,6 +2,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build gogit
// +build gogit // +build gogit
package git package git

View File

@@ -2,6 +2,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build !gogit
// +build !gogit // +build !gogit
package git package git

View File

@@ -3,6 +3,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build gogit
// +build gogit // +build gogit
package git package git

View File

@@ -3,6 +3,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build !gogit
// +build !gogit // +build !gogit
package git package git

View File

@@ -3,6 +3,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build gogit
// +build gogit // +build gogit
package git package git

View File

@@ -2,6 +2,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build !gogit
// +build !gogit // +build !gogit
package git package git

View File

@@ -3,6 +3,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build gogit
// +build gogit // +build gogit
package git package git

View File

@@ -3,6 +3,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build !gogit
// +build !gogit // +build !gogit
package git package git

View File

@@ -3,6 +3,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build gogit
// +build gogit // +build gogit
package git package git

View File

@@ -3,6 +3,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build !gogit
// +build !gogit // +build !gogit
package git package git

View File

@@ -52,9 +52,7 @@ func getRefURL(refURL, urlPrefix, repoFullName, sshDomain string) string {
urlPrefixHostname = prefixURL.Host urlPrefixHostname = prefixURL.Host
} }
if strings.HasSuffix(urlPrefix, "/") { urlPrefix = strings.TrimSuffix(urlPrefix, "/")
urlPrefix = urlPrefix[:len(urlPrefix)-1]
}
// FIXME: Need to consider branch - which will require changes in modules/git/commit.go:GetSubModules // FIXME: Need to consider branch - which will require changes in modules/git/commit.go:GetSubModules
// Relative url prefix check (according to git submodule documentation) // Relative url prefix check (according to git submodule documentation)

View File

@@ -3,6 +3,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build gogit
// +build gogit // +build gogit
package git package git

View File

@@ -2,6 +2,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build !gogit
// +build !gogit // +build !gogit
package git package git

View File

@@ -3,6 +3,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build gogit
// +build gogit // +build gogit
package git package git

View File

@@ -2,6 +2,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build !gogit
// +build !gogit // +build !gogit
package git package git

View File

@@ -2,6 +2,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build gogit
// +build gogit // +build gogit
package git package git

View File

@@ -3,6 +3,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build gogit
// +build gogit // +build gogit
package git package git

View File

@@ -2,6 +2,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build !gogit
// +build !gogit // +build !gogit
package git package git

View File

@@ -217,11 +217,9 @@ func newRefsFromRefNames(refNames []byte) []git.Reference {
continue continue
} }
refName := string(refNameBytes) refName := string(refNameBytes)
if strings.HasPrefix(refName, "tag: ") { refName = strings.TrimPrefix(refName, "tag: ")
refName = strings.TrimPrefix(refName, "tag: ") refName = strings.TrimPrefix(refName, "HEAD -> ")
} else if strings.HasPrefix(refName, "HEAD -> ") {
refName = strings.TrimPrefix(refName, "HEAD -> ")
}
refs = append(refs, git.Reference{ refs = append(refs, git.Reference{
Name: refName, Name: refName,
}) })

View File

@@ -1,9 +1,10 @@
// +build !windows
// Copyright 2019 The Gitea Authors. All rights reserved. // Copyright 2019 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build !windows
// +build !windows
package graceful package graceful
import ( import (

View File

@@ -1,10 +1,11 @@
// +build windows
// Copyright 2019 The Gitea Authors. All rights reserved. // Copyright 2019 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// This code is heavily inspired by the archived gofacebook/gracenet/net.go handler // This code is heavily inspired by the archived gofacebook/gracenet/net.go handler
//go:build windows
// +build windows
package graceful package graceful
import ( import (

View File

@@ -1,10 +1,11 @@
// +build !windows
// Copyright 2019 The Gitea Authors. All rights reserved. // Copyright 2019 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// This code is heavily inspired by the archived gofacebook/gracenet/net.go handler // This code is heavily inspired by the archived gofacebook/gracenet/net.go handler
//go:build !windows
// +build !windows
package graceful package graceful
import ( import (

View File

@@ -1,10 +1,11 @@
// +build windows
// Copyright 2019 The Gitea Authors. All rights reserved. // Copyright 2019 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// This code is heavily inspired by the archived gofacebook/gracenet/net.go handler // This code is heavily inspired by the archived gofacebook/gracenet/net.go handler
//go:build windows
// +build windows
package graceful package graceful
import "net" import "net"

View File

@@ -1,10 +1,11 @@
// +build !windows
// Copyright 2019 The Gitea Authors. All rights reserved. // Copyright 2019 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// This code is heavily inspired by the archived gofacebook/gracenet/net.go handler // This code is heavily inspired by the archived gofacebook/gracenet/net.go handler
//go:build !windows
// +build !windows
package graceful package graceful
import ( import (

View File

@@ -0,0 +1,94 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package hostmatcher
import (
"net"
"path/filepath"
"strings"
"code.gitea.io/gitea/modules/util"
)
// HostMatchList is used to check if a host or IP is in a list.
// If you only need to do wildcard matching, consider to use modules/matchlist
type HostMatchList struct {
hosts []string
ipNets []*net.IPNet
}
// MatchBuiltinAll all hosts are matched
const MatchBuiltinAll = "*"
// MatchBuiltinExternal A valid non-private unicast IP, all hosts on public internet are matched
const MatchBuiltinExternal = "external"
// MatchBuiltinPrivate RFC 1918 (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) and RFC 4193 (FC00::/7). Also called LAN/Intranet.
const MatchBuiltinPrivate = "private"
// MatchBuiltinLoopback 127.0.0.0/8 for IPv4 and ::1/128 for IPv6, localhost is included.
const MatchBuiltinLoopback = "loopback"
// ParseHostMatchList parses the host list HostMatchList
func ParseHostMatchList(hostList string) *HostMatchList {
hl := &HostMatchList{}
for _, s := range strings.Split(hostList, ",") {
s = strings.ToLower(strings.TrimSpace(s))
if s == "" {
continue
}
_, ipNet, err := net.ParseCIDR(s)
if err == nil {
hl.ipNets = append(hl.ipNets, ipNet)
} else {
hl.hosts = append(hl.hosts, s)
}
}
return hl
}
// MatchesHostOrIP checks if the host or IP matches an allow/deny(block) list
func (hl *HostMatchList) MatchesHostOrIP(host string, ip net.IP) bool {
var matched bool
host = strings.ToLower(host)
ipStr := ip.String()
loop:
for _, hostInList := range hl.hosts {
switch hostInList {
case "":
continue
case MatchBuiltinAll:
matched = true
break loop
case MatchBuiltinExternal:
if matched = ip.IsGlobalUnicast() && !util.IsIPPrivate(ip); matched {
break loop
}
case MatchBuiltinPrivate:
if matched = util.IsIPPrivate(ip); matched {
break loop
}
case MatchBuiltinLoopback:
if matched = ip.IsLoopback(); matched {
break loop
}
default:
if matched, _ = filepath.Match(hostInList, host); matched {
break loop
}
if matched, _ = filepath.Match(hostInList, ipStr); matched {
break loop
}
}
}
if !matched {
for _, ipNet := range hl.ipNets {
if matched = ipNet.Contains(ip); matched {
break
}
}
}
return matched
}

View File

@@ -0,0 +1,119 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package hostmatcher
import (
"net"
"testing"
"github.com/stretchr/testify/assert"
)
func TestHostOrIPMatchesList(t *testing.T) {
type tc struct {
host string
ip net.IP
expected bool
}
// for IPv6: "::1" is loopback, "fd00::/8" is private
hl := ParseHostMatchList("private, External, *.myDomain.com, 169.254.1.0/24")
cases := []tc{
{"", net.IPv4zero, false},
{"", net.IPv6zero, false},
{"", net.ParseIP("127.0.0.1"), false},
{"", net.ParseIP("::1"), false},
{"", net.ParseIP("10.0.1.1"), true},
{"", net.ParseIP("192.168.1.1"), true},
{"", net.ParseIP("fd00::1"), true},
{"", net.ParseIP("8.8.8.8"), true},
{"", net.ParseIP("1001::1"), true},
{"mydomain.com", net.IPv4zero, false},
{"sub.mydomain.com", net.IPv4zero, true},
{"", net.ParseIP("169.254.1.1"), true},
{"", net.ParseIP("169.254.2.2"), false},
}
for _, c := range cases {
assert.Equalf(t, c.expected, hl.MatchesHostOrIP(c.host, c.ip), "case %s(%v)", c.host, c.ip)
}
hl = ParseHostMatchList("loopback")
cases = []tc{
{"", net.IPv4zero, false},
{"", net.ParseIP("127.0.0.1"), true},
{"", net.ParseIP("10.0.1.1"), false},
{"", net.ParseIP("192.168.1.1"), false},
{"", net.ParseIP("8.8.8.8"), false},
{"", net.ParseIP("::1"), true},
{"", net.ParseIP("fd00::1"), false},
{"", net.ParseIP("1000::1"), false},
{"mydomain.com", net.IPv4zero, false},
}
for _, c := range cases {
assert.Equalf(t, c.expected, hl.MatchesHostOrIP(c.host, c.ip), "case %s(%v)", c.host, c.ip)
}
hl = ParseHostMatchList("private")
cases = []tc{
{"", net.IPv4zero, false},
{"", net.ParseIP("127.0.0.1"), false},
{"", net.ParseIP("10.0.1.1"), true},
{"", net.ParseIP("192.168.1.1"), true},
{"", net.ParseIP("8.8.8.8"), false},
{"", net.ParseIP("::1"), false},
{"", net.ParseIP("fd00::1"), true},
{"", net.ParseIP("1000::1"), false},
{"mydomain.com", net.IPv4zero, false},
}
for _, c := range cases {
assert.Equalf(t, c.expected, hl.MatchesHostOrIP(c.host, c.ip), "case %s(%v)", c.host, c.ip)
}
hl = ParseHostMatchList("external")
cases = []tc{
{"", net.IPv4zero, false},
{"", net.ParseIP("127.0.0.1"), false},
{"", net.ParseIP("10.0.1.1"), false},
{"", net.ParseIP("192.168.1.1"), false},
{"", net.ParseIP("8.8.8.8"), true},
{"", net.ParseIP("::1"), false},
{"", net.ParseIP("fd00::1"), false},
{"", net.ParseIP("1000::1"), true},
{"mydomain.com", net.IPv4zero, false},
}
for _, c := range cases {
assert.Equalf(t, c.expected, hl.MatchesHostOrIP(c.host, c.ip), "case %s(%v)", c.host, c.ip)
}
hl = ParseHostMatchList("*")
cases = []tc{
{"", net.IPv4zero, true},
{"", net.ParseIP("127.0.0.1"), true},
{"", net.ParseIP("10.0.1.1"), true},
{"", net.ParseIP("192.168.1.1"), true},
{"", net.ParseIP("8.8.8.8"), true},
{"", net.ParseIP("::1"), true},
{"", net.ParseIP("fd00::1"), true},
{"", net.ParseIP("1000::1"), true},
{"mydomain.com", net.IPv4zero, true},
}
for _, c := range cases {
assert.Equalf(t, c.expected, hl.MatchesHostOrIP(c.host, c.ip), "case %s(%v)", c.host, c.ip)
}
}

View File

@@ -174,6 +174,10 @@ func NewBleveIndexer(indexDir string) (*BleveIndexer, bool, error) {
indexDir: indexDir, indexDir: indexDir,
} }
created, err := indexer.init() created, err := indexer.init()
if err != nil {
indexer.Close()
return nil, false, err
}
return indexer, created, err return indexer, created, err
} }

View File

@@ -83,7 +83,10 @@ func NewElasticSearchIndexer(url, indexerName string) (*ElasticSearchIndexer, bo
indexerAliasName: indexerName, indexerAliasName: indexerName,
} }
exists, err := indexer.init() exists, err := indexer.init()
if err != nil {
indexer.Close()
return nil, false, err
}
return indexer, !exists, err return indexer, !exists, err
} }

View File

@@ -188,9 +188,6 @@ func Init() {
rIndexer, populate, err = NewBleveIndexer(setting.Indexer.RepoPath) rIndexer, populate, err = NewBleveIndexer(setting.Indexer.RepoPath)
if err != nil { if err != nil {
if rIndexer != nil {
rIndexer.Close()
}
cancel() cancel()
indexer.Close() indexer.Close()
close(waitChannel) close(waitChannel)
@@ -208,9 +205,6 @@ func Init() {
rIndexer, populate, err = NewElasticSearchIndexer(setting.Indexer.RepoConnStr, setting.Indexer.RepoIndexerName) rIndexer, populate, err = NewElasticSearchIndexer(setting.Indexer.RepoConnStr, setting.Indexer.RepoIndexerName)
if err != nil { if err != nil {
if rIndexer != nil {
rIndexer.Close()
}
cancel() cancel()
indexer.Close() indexer.Close()
close(waitChannel) close(waitChannel)

View File

@@ -27,7 +27,7 @@ func handle(data ...queue.Data) {
} }
func initStatsQueue() error { func initStatsQueue() error {
statsQueue = queue.CreateUniqueQueue("repo_stats_update", handle, int64(0)).(queue.UniqueQueue) statsQueue = queue.CreateUniqueQueue("repo_stats_update", handle, int64(0))
if statsQueue == nil { if statsQueue == nil {
return fmt.Errorf("Unable to create repo_stats_update Queue") return fmt.Errorf("Unable to create repo_stats_update Queue")
} }

View File

@@ -29,9 +29,7 @@ func endpointFromCloneURL(rawurl string) *url.URL {
return ep return ep
} }
if strings.HasSuffix(ep.Path, "/") { ep.Path = strings.TrimSuffix(ep.Path, "/")
ep.Path = ep.Path[:len(ep.Path)-1]
}
if ep.Scheme == "file" { if ep.Scheme == "file" {
return ep return ep

View File

@@ -2,6 +2,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build gogit
// +build gogit // +build gogit
package lfs package lfs

View File

@@ -2,6 +2,7 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build !gogit
// +build !gogit // +build !gogit
package lfs package lfs

View File

@@ -126,7 +126,7 @@ type Footnote struct {
func (n *Footnote) Dump(source []byte, level int) { func (n *Footnote) Dump(source []byte, level int) {
m := map[string]string{} m := map[string]string{}
m["Index"] = fmt.Sprintf("%v", n.Index) m["Index"] = fmt.Sprintf("%v", n.Index)
m["Ref"] = fmt.Sprintf("%s", n.Ref) m["Ref"] = string(n.Ref)
m["Name"] = fmt.Sprintf("%v", n.Name) m["Name"] = fmt.Sprintf("%v", n.Name)
ast.DumpHelper(n, source, level, m, nil) ast.DumpHelper(n, source, level, m, nil)
} }

View File

@@ -109,6 +109,7 @@ func (g *GiteaLocalUploader) CreateRepo(repo *base.Repository, opts base.Migrate
return err return err
} }
r.DefaultBranch = repo.DefaultBranch r.DefaultBranch = repo.DefaultBranch
r.Description = repo.Description
r, err = repository.MigrateRepositoryGitData(g.ctx, owner, r, base.MigrateOptions{ r, err = repository.MigrateRepositoryGitData(g.ctx, owner, r, base.MigrateOptions{
RepoName: g.repoName, RepoName: g.repoName,

View File

@@ -89,7 +89,7 @@ func IsMigrateURLAllowed(remoteURL string, doer *models.User) error {
return &models.ErrInvalidCloneAddr{Host: u.Host, NotResolvedIP: true} return &models.ErrInvalidCloneAddr{Host: u.Host, NotResolvedIP: true}
} }
for _, addr := range addrList { for _, addr := range addrList {
if isIPPrivate(addr) || !addr.IsGlobalUnicast() { if util.IsIPPrivate(addr) || !addr.IsGlobalUnicast() {
return &models.ErrInvalidCloneAddr{Host: u.Host, PrivateNet: addr.String(), IsPermissionDenied: true} return &models.ErrInvalidCloneAddr{Host: u.Host, PrivateNet: addr.String(), IsPermissionDenied: true}
} }
} }
@@ -486,16 +486,3 @@ func Init() error {
return nil return nil
} }
// isIPPrivate reports whether ip is a private address, according to
// RFC 1918 (IPv4 addresses) and RFC 4193 (IPv6 addresses).
// from https://github.com/golang/go/pull/42793
// TODO remove if https://github.com/golang/go/issues/29146 got resolved
func isIPPrivate(ip net.IP) bool {
if ip4 := ip.To4(); ip4 != nil {
return ip4[0] == 10 ||
(ip4[0] == 172 && ip4[1]&0xf0 == 16) ||
(ip4[0] == 192 && ip4[1] == 168)
}
return len(ip) == net.IPv6len && ip[0]&0xfe == 0xfc
}

View File

@@ -212,7 +212,7 @@ func (m *webhookNotifier) NotifyIssueChangeTitle(doer *models.User, issue *model
}, },
Issue: convert.ToAPIIssue(issue), Issue: convert.ToAPIIssue(issue),
Repository: convert.ToRepo(issue.Repo, mode), Repository: convert.ToRepo(issue.Repo, mode),
Sender: convert.ToUser(issue.Poster, nil), Sender: convert.ToUser(doer, nil),
}) })
} }
@@ -766,12 +766,12 @@ func sendReleaseHook(doer *models.User, rel *models.Release, action api.HookRele
return return
} }
mode, _ := models.AccessLevel(rel.Publisher, rel.Repo) mode, _ := models.AccessLevel(doer, rel.Repo)
if err := webhook_services.PrepareWebhooks(rel.Repo, models.HookEventRelease, &api.ReleasePayload{ if err := webhook_services.PrepareWebhooks(rel.Repo, models.HookEventRelease, &api.ReleasePayload{
Action: action, Action: action,
Release: convert.ToRelease(rel), Release: convert.ToRelease(rel),
Repository: convert.ToRepo(rel.Repo, mode), Repository: convert.ToRepo(rel.Repo, mode),
Sender: convert.ToUser(rel.Publisher, nil), Sender: convert.ToUser(doer, nil),
}); err != nil { }); err != nil {
log.Error("PrepareWebhooks: %v", err) log.Error("PrepareWebhooks: %v", err)
} }

View File

@@ -1,9 +1,10 @@
// +build !bindata
// Copyright 2016 The Gitea Authors. All rights reserved. // Copyright 2016 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build !bindata
// +build !bindata
package options package options
import ( import (

View File

@@ -2,7 +2,8 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//+build bindata //go:build bindata
// +build bindata
package options package options

View File

@@ -1,3 +1,4 @@
//go:build bindata
// +build bindata // +build bindata
// Copyright 2016 The Gitea Authors. All rights reserved. // Copyright 2016 The Gitea Authors. All rights reserved.

View File

@@ -1,9 +1,10 @@
// +build !bindata
// Copyright 2016 The Gitea Authors. All rights reserved. // Copyright 2016 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build !bindata
// +build !bindata
package public package public
import ( import (

View File

@@ -2,7 +2,8 @@
// Use of this source code is governed by a MIT-style // Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//+build bindata //go:build bindata
// +build bindata
package public package public

Some files were not shown because too many files have changed in this diff Show More