mirror of
https://github.com/go-gitea/gitea.git
synced 2026-05-13 17:35:18 +02:00
Merge branch 'go-gitea:main' into main
This commit is contained in:
commit
ce000b0c19
@ -108,7 +108,9 @@ curl --connect-timeout 10 --silent --show-error --fail --location -O "$binurl{,.
|
|||||||
sha256sum -c "${binname}.xz.sha256"
|
sha256sum -c "${binname}.xz.sha256"
|
||||||
if [[ -z "${ignore_gpg:-}" ]]; then
|
if [[ -z "${ignore_gpg:-}" ]]; then
|
||||||
require gpg
|
require gpg
|
||||||
gpg --keyserver keys.openpgp.org --recv 7C9E68152594688862D62AF62D9AE806EC1592E2
|
# try to use curl first, it uses standard tcp 443 port and works better behind strict firewall rules
|
||||||
|
curl -fsSL --connect-timeout 10 "https://keys.openpgp.org/vks/v1/by-fingerprint/7C9E68152594688862D62AF62D9AE806EC1592E2" | gpg --import \
|
||||||
|
|| gpg --keyserver keys.openpgp.org --recv 7C9E68152594688862D62AF62D9AE806EC1592E2
|
||||||
gpg --verify "${binname}.xz.asc" "${binname}.xz" || { echo 'Signature does not match'; exit 1; }
|
gpg --verify "${binname}.xz.asc" "${binname}.xz" || { echo 'Signature does not match'; exit 1; }
|
||||||
fi
|
fi
|
||||||
rm "${binname}".xz.{sha256,asc}
|
rm "${binname}".xz.{sha256,asc}
|
||||||
@ -127,6 +129,8 @@ echo "Creating backup in $giteahome"
|
|||||||
giteacmd dump $backupopts
|
giteacmd dump $backupopts
|
||||||
echo "Updating binary at $giteabin"
|
echo "Updating binary at $giteabin"
|
||||||
cp -f "$giteabin" "$giteabin.bak" && mv -f "$binname" "$giteabin"
|
cp -f "$giteabin" "$giteabin.bak" && mv -f "$binname" "$giteabin"
|
||||||
|
# Restore SELinux context if applicable (e.g. RHEL/Fedora)
|
||||||
|
command -v restorecon &>/dev/null && restorecon -v "$giteabin" || true
|
||||||
$service_start
|
$service_start
|
||||||
$service_status
|
$service_status
|
||||||
|
|
||||||
|
|||||||
2
go.mod
2
go.mod
@ -37,6 +37,7 @@ require (
|
|||||||
github.com/charmbracelet/git-lfs-transfer v0.1.1-0.20251013092601-6327009efd21
|
github.com/charmbracelet/git-lfs-transfer v0.1.1-0.20251013092601-6327009efd21
|
||||||
github.com/chi-middleware/proxy v1.1.1
|
github.com/chi-middleware/proxy v1.1.1
|
||||||
github.com/dimiro1/reply v0.0.0-20200315094148-d0136a4c9e21
|
github.com/dimiro1/reply v0.0.0-20200315094148-d0136a4c9e21
|
||||||
|
github.com/dlclark/regexp2 v1.11.5
|
||||||
github.com/dsnet/compress v0.0.2-0.20230904184137-39efe44ab707
|
github.com/dsnet/compress v0.0.2-0.20230904184137-39efe44ab707
|
||||||
github.com/dustin/go-humanize v1.0.1
|
github.com/dustin/go-humanize v1.0.1
|
||||||
github.com/editorconfig/editorconfig-core-go/v2 v2.6.4
|
github.com/editorconfig/editorconfig-core-go/v2 v2.6.4
|
||||||
@ -183,7 +184,6 @@ require (
|
|||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||||
github.com/davidmz/go-pageant v1.0.2 // indirect
|
github.com/davidmz/go-pageant v1.0.2 // indirect
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||||
github.com/dlclark/regexp2 v1.11.5 // indirect
|
|
||||||
github.com/emersion/go-sasl v0.0.0-20241020182733-b788ff22d5a6 // indirect
|
github.com/emersion/go-sasl v0.0.0-20241020182733-b788ff22d5a6 // indirect
|
||||||
github.com/fatih/color v1.18.0 // indirect
|
github.com/fatih/color v1.18.0 // indirect
|
||||||
github.com/fxamacker/cbor/v2 v2.9.0 // indirect
|
github.com/fxamacker/cbor/v2 v2.9.0 // indirect
|
||||||
|
|||||||
@ -9,7 +9,6 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"regexp"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/db"
|
"code.gitea.io/gitea/models/db"
|
||||||
@ -24,6 +23,7 @@ import (
|
|||||||
"code.gitea.io/gitea/modules/timeutil"
|
"code.gitea.io/gitea/modules/timeutil"
|
||||||
"code.gitea.io/gitea/modules/util"
|
"code.gitea.io/gitea/modules/util"
|
||||||
|
|
||||||
|
"github.com/dlclark/regexp2"
|
||||||
"xorm.io/builder"
|
"xorm.io/builder"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -861,7 +861,7 @@ func GetCodeOwnersFromContent(ctx context.Context, data string) ([]*CodeOwnerRul
|
|||||||
}
|
}
|
||||||
|
|
||||||
type CodeOwnerRule struct {
|
type CodeOwnerRule struct {
|
||||||
Rule *regexp.Regexp
|
Rule *regexp2.Regexp // it supports negative lookahead, does better for end users
|
||||||
Negative bool
|
Negative bool
|
||||||
Users []*user_model.User
|
Users []*user_model.User
|
||||||
Teams []*org_model.Team
|
Teams []*org_model.Team
|
||||||
@ -877,7 +877,8 @@ func ParseCodeOwnersLine(ctx context.Context, tokens []string) (*CodeOwnerRule,
|
|||||||
|
|
||||||
warnings := make([]string, 0)
|
warnings := make([]string, 0)
|
||||||
|
|
||||||
rule.Rule, err = regexp.Compile(fmt.Sprintf("^%s$", strings.TrimPrefix(tokens[0], "!")))
|
expr := fmt.Sprintf("^%s$", strings.TrimPrefix(tokens[0], "!"))
|
||||||
|
rule.Rule, err = regexp2.Compile(expr, regexp2.None)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
warnings = append(warnings, fmt.Sprintf("incorrect codeowner regexp: %s", err))
|
warnings = append(warnings, fmt.Sprintf("incorrect codeowner regexp: %s", err))
|
||||||
return nil, warnings
|
return nil, warnings
|
||||||
|
|||||||
@ -402,7 +402,7 @@ func DropTableColumns(sess *xorm.Session, tableName string, columnNames ...strin
|
|||||||
cols += "DROP COLUMN `" + col + "` CASCADE"
|
cols += "DROP COLUMN `" + col + "` CASCADE"
|
||||||
}
|
}
|
||||||
if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `%s` %s", tableName, cols)); err != nil {
|
if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `%s` %s", tableName, cols)); err != nil {
|
||||||
return fmt.Errorf("Drop table `%s` columns %v: %v", tableName, columnNames, err)
|
return fmt.Errorf("drop table `%s` columns %v: %w", tableName, columnNames, err)
|
||||||
}
|
}
|
||||||
case setting.Database.Type.IsMySQL():
|
case setting.Database.Type.IsMySQL():
|
||||||
// Drop indexes on columns first
|
// Drop indexes on columns first
|
||||||
@ -430,7 +430,7 @@ func DropTableColumns(sess *xorm.Session, tableName string, columnNames ...strin
|
|||||||
cols += "DROP COLUMN `" + col + "`"
|
cols += "DROP COLUMN `" + col + "`"
|
||||||
}
|
}
|
||||||
if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `%s` %s", tableName, cols)); err != nil {
|
if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `%s` %s", tableName, cols)); err != nil {
|
||||||
return fmt.Errorf("Drop table `%s` columns %v: %v", tableName, columnNames, err)
|
return fmt.Errorf("drop table `%s` columns %v: %w", tableName, columnNames, err)
|
||||||
}
|
}
|
||||||
case setting.Database.Type.IsMSSQL():
|
case setting.Database.Type.IsMSSQL():
|
||||||
cols := ""
|
cols := ""
|
||||||
@ -444,27 +444,27 @@ func DropTableColumns(sess *xorm.Session, tableName string, columnNames ...strin
|
|||||||
tableName, strings.ReplaceAll(cols, "`", "'"))
|
tableName, strings.ReplaceAll(cols, "`", "'"))
|
||||||
constraints := make([]string, 0)
|
constraints := make([]string, 0)
|
||||||
if err := sess.SQL(sql).Find(&constraints); err != nil {
|
if err := sess.SQL(sql).Find(&constraints); err != nil {
|
||||||
return fmt.Errorf("Find constraints: %v", err)
|
return fmt.Errorf("find constraints: %w", err)
|
||||||
}
|
}
|
||||||
for _, constraint := range constraints {
|
for _, constraint := range constraints {
|
||||||
if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `%s` DROP CONSTRAINT `%s`", tableName, constraint)); err != nil {
|
if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `%s` DROP CONSTRAINT `%s`", tableName, constraint)); err != nil {
|
||||||
return fmt.Errorf("Drop table `%s` default constraint `%s`: %v", tableName, constraint, err)
|
return fmt.Errorf("drop table `%s` default constraint `%s`: %w", tableName, constraint, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sql = fmt.Sprintf("SELECT DISTINCT Name FROM sys.indexes INNER JOIN sys.index_columns ON indexes.index_id = index_columns.index_id AND indexes.object_id = index_columns.object_id WHERE indexes.object_id = OBJECT_ID('%[1]s') AND index_columns.column_id IN (SELECT column_id FROM sys.columns WHERE LOWER(name) IN (%[2]s) AND object_id = OBJECT_ID('%[1]s'))",
|
sql = fmt.Sprintf("SELECT DISTINCT Name FROM sys.indexes INNER JOIN sys.index_columns ON indexes.index_id = index_columns.index_id AND indexes.object_id = index_columns.object_id WHERE indexes.object_id = OBJECT_ID('%[1]s') AND index_columns.column_id IN (SELECT column_id FROM sys.columns WHERE LOWER(name) IN (%[2]s) AND object_id = OBJECT_ID('%[1]s'))",
|
||||||
tableName, strings.ReplaceAll(cols, "`", "'"))
|
tableName, strings.ReplaceAll(cols, "`", "'"))
|
||||||
constraints = make([]string, 0)
|
constraints = make([]string, 0)
|
||||||
if err := sess.SQL(sql).Find(&constraints); err != nil {
|
if err := sess.SQL(sql).Find(&constraints); err != nil {
|
||||||
return fmt.Errorf("Find constraints: %v", err)
|
return fmt.Errorf("find constraints: %w", err)
|
||||||
}
|
}
|
||||||
for _, constraint := range constraints {
|
for _, constraint := range constraints {
|
||||||
if _, err := sess.Exec(fmt.Sprintf("DROP INDEX `%[2]s` ON `%[1]s`", tableName, constraint)); err != nil {
|
if _, err := sess.Exec(fmt.Sprintf("DROP INDEX `%[2]s` ON `%[1]s`", tableName, constraint)); err != nil {
|
||||||
return fmt.Errorf("Drop index `%[2]s` on `%[1]s`: %v", tableName, constraint, err)
|
return fmt.Errorf("drop index `%[2]s` on `%[1]s`: %[3]w", tableName, constraint, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `%s` DROP COLUMN %s", tableName, cols)); err != nil {
|
if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `%s` DROP COLUMN %s", tableName, cols)); err != nil {
|
||||||
return fmt.Errorf("Drop table `%s` columns %v: %v", tableName, columnNames, err)
|
return fmt.Errorf("drop table `%s` columns %v: %w", tableName, columnNames, err)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
log.Fatal("Unrecognized DB")
|
log.Fatal("Unrecognized DB")
|
||||||
|
|||||||
@ -96,6 +96,7 @@ func (s *linkifyParser) Parse(parent ast.Node, block text.Reader, pc parser.Cont
|
|||||||
m[1] -= closing
|
m[1] -= closing
|
||||||
}
|
}
|
||||||
} else if lastChar == ';' {
|
} else if lastChar == ';' {
|
||||||
|
// exclude HTML entity reference, e.g.: exclude " " from "http://example.com?foo=1 "
|
||||||
i := m[1] - 2
|
i := m[1] - 2
|
||||||
for ; i >= m[0]; i-- {
|
for ; i >= m[0]; i-- {
|
||||||
if util.IsAlphaNumeric(line[i]) {
|
if util.IsAlphaNumeric(line[i]) {
|
||||||
@ -105,7 +106,7 @@ func (s *linkifyParser) Parse(parent ast.Node, block text.Reader, pc parser.Cont
|
|||||||
}
|
}
|
||||||
if i != m[1]-2 {
|
if i != m[1]-2 {
|
||||||
if line[i] == '&' {
|
if line[i] == '&' {
|
||||||
m[1] -= m[1] - i
|
m[1] = i
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3644,6 +3644,7 @@
|
|||||||
"actions.runners.id": "ID",
|
"actions.runners.id": "ID",
|
||||||
"actions.runners.name": "Ainm",
|
"actions.runners.name": "Ainm",
|
||||||
"actions.runners.owner_type": "Cineál",
|
"actions.runners.owner_type": "Cineál",
|
||||||
|
"actions.runners.availability": "Infhaighteacht",
|
||||||
"actions.runners.description": "Cur síos",
|
"actions.runners.description": "Cur síos",
|
||||||
"actions.runners.labels": "Lipéid",
|
"actions.runners.labels": "Lipéid",
|
||||||
"actions.runners.last_online": "Am Ar Líne Deiridh",
|
"actions.runners.last_online": "Am Ar Líne Deiridh",
|
||||||
@ -3659,6 +3660,12 @@
|
|||||||
"actions.runners.update_runner": "Nuashonrú Athruithe",
|
"actions.runners.update_runner": "Nuashonrú Athruithe",
|
||||||
"actions.runners.update_runner_success": "Nuashonraíodh an Reathaí",
|
"actions.runners.update_runner_success": "Nuashonraíodh an Reathaí",
|
||||||
"actions.runners.update_runner_failed": "Theip ar an reathaí a nuashonrú",
|
"actions.runners.update_runner_failed": "Theip ar an reathaí a nuashonrú",
|
||||||
|
"actions.runners.enable_runner": "Cumasaigh an ritheoir seo",
|
||||||
|
"actions.runners.enable_runner_success": "Cumasaíodh an rithire go rathúil",
|
||||||
|
"actions.runners.enable_runner_failed": "Theip ar an rithire a chumasú",
|
||||||
|
"actions.runners.disable_runner": "Díchumasaigh an ritheoir seo",
|
||||||
|
"actions.runners.disable_runner_success": "Díchumasaíodh an ritheoir go rathúil",
|
||||||
|
"actions.runners.disable_runner_failed": "Theip ar an ritheoir a dhíchumasú",
|
||||||
"actions.runners.delete_runner": "Scrios an reathaí seo",
|
"actions.runners.delete_runner": "Scrios an reathaí seo",
|
||||||
"actions.runners.delete_runner_success": "Scriosadh an reathaí go rathúil",
|
"actions.runners.delete_runner_success": "Scriosadh an reathaí go rathúil",
|
||||||
"actions.runners.delete_runner_failed": "Theip ar an reathaí a scriosadh",
|
"actions.runners.delete_runner_failed": "Theip ar an reathaí a scriosadh",
|
||||||
|
|||||||
@ -3644,6 +3644,7 @@
|
|||||||
"actions.runners.id": "ID",
|
"actions.runners.id": "ID",
|
||||||
"actions.runners.name": "이름",
|
"actions.runners.name": "이름",
|
||||||
"actions.runners.owner_type": "유형",
|
"actions.runners.owner_type": "유형",
|
||||||
|
"actions.runners.availability": "가용성",
|
||||||
"actions.runners.description": "설명",
|
"actions.runners.description": "설명",
|
||||||
"actions.runners.labels": "레이블",
|
"actions.runners.labels": "레이블",
|
||||||
"actions.runners.last_online": "최근 접속 시간",
|
"actions.runners.last_online": "최근 접속 시간",
|
||||||
@ -3659,6 +3660,12 @@
|
|||||||
"actions.runners.update_runner": "변경사항 업데이트",
|
"actions.runners.update_runner": "변경사항 업데이트",
|
||||||
"actions.runners.update_runner_success": "러너가 성공적으로 업데이트됨",
|
"actions.runners.update_runner_success": "러너가 성공적으로 업데이트됨",
|
||||||
"actions.runners.update_runner_failed": "러너 업데이트 실패함",
|
"actions.runners.update_runner_failed": "러너 업데이트 실패함",
|
||||||
|
"actions.runners.enable_runner": "이 러너를 활성화",
|
||||||
|
"actions.runners.enable_runner_success": "러너가 성공적으로 활성화됨",
|
||||||
|
"actions.runners.enable_runner_failed": "러너 활성화 실패함",
|
||||||
|
"actions.runners.disable_runner": "이 러너를 비활성화",
|
||||||
|
"actions.runners.disable_runner_success": "러너 비활성화가 성공함",
|
||||||
|
"actions.runners.disable_runner_failed": "러너 비활성화 실패함",
|
||||||
"actions.runners.delete_runner": "이 러너를 삭제",
|
"actions.runners.delete_runner": "이 러너를 삭제",
|
||||||
"actions.runners.delete_runner_success": "러너가 성공적으로 삭제됨",
|
"actions.runners.delete_runner_success": "러너가 성공적으로 삭제됨",
|
||||||
"actions.runners.delete_runner_failed": "러너 삭제를 실패함",
|
"actions.runners.delete_runner_failed": "러너 삭제를 실패함",
|
||||||
|
|||||||
@ -88,7 +88,11 @@ func reqPackageAccess(accessMode perm.AccessMode) func(ctx *context.Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func verifyAuth(r *web.Router, authMethods []auth.Method) {
|
type verifyAuthOptions struct {
|
||||||
|
afterAuthCallback func(ctx *context.Context, err error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func verifyAuth(r *web.Router, authMethods []auth.Method, opts verifyAuthOptions) {
|
||||||
if setting.Service.EnableReverseProxyAuth {
|
if setting.Service.EnableReverseProxyAuth {
|
||||||
authMethods = append(authMethods, &auth.ReverseProxy{})
|
authMethods = append(authMethods, &auth.ReverseProxy{})
|
||||||
}
|
}
|
||||||
@ -97,12 +101,13 @@ func verifyAuth(r *web.Router, authMethods []auth.Method) {
|
|||||||
r.AfterRouting(func(ctx *context.Context) {
|
r.AfterRouting(func(ctx *context.Context) {
|
||||||
var err error
|
var err error
|
||||||
ctx.Doer, err = authGroup.Verify(ctx.Req, ctx.Resp, ctx, ctx.Session)
|
ctx.Doer, err = authGroup.Verify(ctx.Req, ctx.Resp, ctx, ctx.Session)
|
||||||
if err != nil {
|
ctx.IsSigned = ctx.Doer != nil
|
||||||
|
if opts.afterAuthCallback != nil {
|
||||||
|
opts.afterAuthCallback(ctx, err)
|
||||||
|
} else if err != nil {
|
||||||
log.Error("Failed to verify user: %v", err)
|
log.Error("Failed to verify user: %v", err)
|
||||||
ctx.HTTPError(http.StatusUnauthorized, "Failed to authenticate user")
|
ctx.HTTPError(http.StatusUnauthorized, "Failed to authenticate user")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
ctx.IsSigned = ctx.Doer != nil
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,7 +124,7 @@ func CommonRoutes() *web.Router {
|
|||||||
&nuget.Auth{},
|
&nuget.Auth{},
|
||||||
&Auth{},
|
&Auth{},
|
||||||
&chef.Auth{},
|
&chef.Auth{},
|
||||||
})
|
}, verifyAuthOptions{})
|
||||||
|
|
||||||
r.Group("/{username}", func() {
|
r.Group("/{username}", func() {
|
||||||
r.Group("/alpine", func() {
|
r.Group("/alpine", func() {
|
||||||
@ -537,8 +542,15 @@ func ContainerRoutes() *web.Router {
|
|||||||
|
|
||||||
verifyAuth(r, []auth.Method{
|
verifyAuth(r, []auth.Method{
|
||||||
&auth.Basic{},
|
&auth.Basic{},
|
||||||
// container auth requires an token, so container.Authenticate issues a Ghost user token for anonymous access
|
// container auth requires token, so container.Authenticate issues a Ghost user token for anonymous access
|
||||||
&Auth{AllowGhostUser: true},
|
&Auth{AllowGhostUser: true},
|
||||||
|
}, verifyAuthOptions{
|
||||||
|
afterAuthCallback: func(ctx *context.Context, err error) {
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Failed to verify container user: %v", err)
|
||||||
|
container.APIUnauthorizedError(ctx)
|
||||||
|
}
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
// TODO: Content Discovery / References (not implemented yet)
|
// TODO: Content Discovery / References (not implemented yet)
|
||||||
|
|||||||
@ -120,17 +120,19 @@ func apiErrorDefined(ctx *context.Context, err *namedError) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func apiUnauthorizedError(ctx *context.Context) {
|
func APIUnauthorizedError(ctx *context.Context) {
|
||||||
// container registry requires that the "/v2" must be in the root, so the sub-path in AppURL should be removed
|
// container registry requires that the "/v2" must be in the root, so the sub-path in AppURL should be removed
|
||||||
realmURL := httplib.GuessCurrentHostURL(ctx) + "/v2/token"
|
realmURL := httplib.GuessCurrentHostURL(ctx) + "/v2/token"
|
||||||
ctx.Resp.Header().Add("WWW-Authenticate", `Bearer realm="`+realmURL+`",service="container_registry",scope="*"`)
|
ctx.Resp.Header().Add("WWW-Authenticate", `Bearer realm="`+realmURL+`",service="container_registry",scope="*"`)
|
||||||
|
// support apple container like: container registry login <gitea-host> -u
|
||||||
|
ctx.Resp.Header().Add("WWW-Authenticate", `Basic realm="Gitea Container Registry"`)
|
||||||
apiErrorDefined(ctx, errUnauthorized)
|
apiErrorDefined(ctx, errUnauthorized)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReqContainerAccess is a middleware which checks the current user valid (real user or ghost if anonymous access is enabled)
|
// ReqContainerAccess is a middleware which checks the current user valid (real user or ghost if anonymous access is enabled)
|
||||||
func ReqContainerAccess(ctx *context.Context) {
|
func ReqContainerAccess(ctx *context.Context) {
|
||||||
if ctx.Doer == nil || (setting.Service.RequireSignInViewStrict && ctx.Doer.IsGhost()) {
|
if ctx.Doer == nil || (setting.Service.RequireSignInViewStrict && ctx.Doer.IsGhost()) {
|
||||||
apiUnauthorizedError(ctx)
|
APIUnauthorizedError(ctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,7 +158,7 @@ func Authenticate(ctx *context.Context) {
|
|||||||
packageScope := auth_service.GetAccessScope(ctx.Data)
|
packageScope := auth_service.GetAccessScope(ctx.Data)
|
||||||
if u == nil {
|
if u == nil {
|
||||||
if setting.Service.RequireSignInViewStrict {
|
if setting.Service.RequireSignInViewStrict {
|
||||||
apiUnauthorizedError(ctx)
|
APIUnauthorizedError(ctx)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,7 +172,7 @@ func Authenticate(ctx *context.Context) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Error checking access scope: %v", err)
|
log.Error("Error checking access scope: %v", err)
|
||||||
}
|
}
|
||||||
apiUnauthorizedError(ctx)
|
APIUnauthorizedError(ctx)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -118,7 +118,7 @@ func SignInOAuthCallback(ctx *context.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err, ok := err.(*go_oauth2.RetrieveError); ok {
|
if err, ok := err.(*go_oauth2.RetrieveError); ok {
|
||||||
ctx.Flash.Error("OAuth2 RetrieveError: "+err.Error(), true)
|
ctx.Flash.Error("OAuth2 RetrieveError: " + err.Error())
|
||||||
ctx.Redirect(setting.AppSubURL + "/user/login")
|
ctx.Redirect(setting.AppSubURL + "/user/login")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@ -95,7 +95,9 @@ func PullRequestCodeOwnersReview(ctx context.Context, pr *issues_model.PullReque
|
|||||||
uniqTeams := make(map[string]*org_model.Team)
|
uniqTeams := make(map[string]*org_model.Team)
|
||||||
for _, rule := range rules {
|
for _, rule := range rules {
|
||||||
for _, f := range changedFiles {
|
for _, f := range changedFiles {
|
||||||
if (rule.Rule.MatchString(f) && !rule.Negative) || (!rule.Rule.MatchString(f) && rule.Negative) {
|
shouldMatch := !rule.Negative
|
||||||
|
matched, _ := rule.Rule.MatchString(f) // err only happens when timeouts, any error can be considered as not matched
|
||||||
|
if matched == shouldMatch {
|
||||||
for _, u := range rule.Users {
|
for _, u := range rule.Users {
|
||||||
uniqUsers[u.ID] = u
|
uniqUsers[u.ID] = u
|
||||||
}
|
}
|
||||||
|
|||||||
@ -61,33 +61,18 @@ func GetTreeBySHA(ctx context.Context, repo *repo_model.Repository, gitRepo *git
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
apiURL := repo.APIURL()
|
apiURL := repo.APIURL()
|
||||||
apiURLLen := len(apiURL)
|
blobURLBase := apiURL + "/git/blobs/"
|
||||||
objectFormat := git.ObjectFormatFromName(repo.ObjectFormatName)
|
treeURLBase := apiURL + "/git/trees/"
|
||||||
hashLen := objectFormat.FullLength()
|
|
||||||
|
|
||||||
const gitBlobsPath = "/git/blobs/"
|
|
||||||
blobURL := make([]byte, apiURLLen+hashLen+len(gitBlobsPath))
|
|
||||||
copy(blobURL, apiURL)
|
|
||||||
copy(blobURL[apiURLLen:], []byte(gitBlobsPath))
|
|
||||||
|
|
||||||
const gitTreePath = "/git/trees/"
|
|
||||||
treeURL := make([]byte, apiURLLen+hashLen+len(gitTreePath))
|
|
||||||
copy(treeURL, apiURL)
|
|
||||||
copy(treeURL[apiURLLen:], []byte(gitTreePath))
|
|
||||||
|
|
||||||
// copyPos is at the start of the hash
|
|
||||||
copyPos := len(treeURL) - hashLen
|
|
||||||
|
|
||||||
if perPage <= 0 || perPage > setting.API.DefaultGitTreesPerPage {
|
if perPage <= 0 || perPage > setting.API.DefaultGitTreesPerPage {
|
||||||
perPage = setting.API.DefaultGitTreesPerPage
|
perPage = setting.API.DefaultGitTreesPerPage
|
||||||
}
|
}
|
||||||
if page <= 0 {
|
page = max(page, 1)
|
||||||
page = 1
|
|
||||||
}
|
|
||||||
tree.Page = page
|
tree.Page = page
|
||||||
tree.TotalCount = len(entries)
|
tree.TotalCount = len(entries)
|
||||||
rangeStart := perPage * (page - 1)
|
rangeStart := perPage * (page - 1) // int might overflow
|
||||||
if rangeStart >= len(entries) {
|
if rangeStart < 0 || rangeStart >= len(entries) {
|
||||||
return tree, nil
|
return tree, nil
|
||||||
}
|
}
|
||||||
rangeEnd := min(rangeStart+perPage, len(entries))
|
rangeEnd := min(rangeStart+perPage, len(entries))
|
||||||
@ -103,16 +88,14 @@ func GetTreeBySHA(ctx context.Context, repo *repo_model.Repository, gitRepo *git
|
|||||||
tree.Entries[i].SHA = entries[e].ID.String()
|
tree.Entries[i].SHA = entries[e].ID.String()
|
||||||
|
|
||||||
if entries[e].IsDir() {
|
if entries[e].IsDir() {
|
||||||
copy(treeURL[copyPos:], entries[e].ID.String())
|
tree.Entries[i].URL = treeURLBase + entries[e].ID.String()
|
||||||
tree.Entries[i].URL = string(treeURL)
|
|
||||||
} else if entries[e].IsSubModule() {
|
} else if entries[e].IsSubModule() {
|
||||||
// In Github Rest API Version=2022-11-28, if a tree entry is a submodule,
|
// In GitHub Rest API Version=2022-11-28, if a tree entry is a submodule,
|
||||||
// its url will be returned as an empty string.
|
// its url will be returned as an empty string.
|
||||||
// So the URL will be set to "" here.
|
// So the URL will be set to "" here.
|
||||||
tree.Entries[i].URL = ""
|
tree.Entries[i].URL = ""
|
||||||
} else {
|
} else {
|
||||||
copy(blobURL[copyPos:], entries[e].ID.String())
|
tree.Entries[i].URL = blobURLBase + entries[e].ID.String()
|
||||||
tree.Entries[i].URL = string(blobURL)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return tree, nil
|
return tree, nil
|
||||||
|
|||||||
@ -88,7 +88,10 @@ func TestPackageContainer(t *testing.T) {
|
|||||||
Token string `json:"token"`
|
Token string `json:"token"`
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultAuthenticateValues := []string{`Bearer realm="` + setting.AppURL + `v2/token",service="container_registry",scope="*"`}
|
defaultAuthenticateValues := []string{
|
||||||
|
`Bearer realm="` + setting.AppURL + `v2/token",service="container_registry",scope="*"`,
|
||||||
|
`Basic realm="Gitea Container Registry"`,
|
||||||
|
}
|
||||||
|
|
||||||
t.Run("Anonymous", func(t *testing.T) {
|
t.Run("Anonymous", func(t *testing.T) {
|
||||||
defer tests.PrintCurrentTest(t)()
|
defer tests.PrintCurrentTest(t)()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user