mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-11-14 14:49:32 +01:00
Merge pull request '[gitea] week 2024-38 cherry pick (gitea/main -> forgejo)' (#5325) from algernon/wcp/2024-38 into forgejo
Some checks are pending
/ release (push) Waiting to run
testing / backend-checks (push) Waiting to run
testing / frontend-checks (push) Waiting to run
testing / test-unit (push) Blocked by required conditions
testing / test-remote-cacher (map[image:docker.io/bitnami/redis:7.2 port:6379]) (push) Blocked by required conditions
testing / test-remote-cacher (map[image:ghcr.io/microsoft/garnet-alpine:1.0.14 port:6379]) (push) Blocked by required conditions
testing / test-remote-cacher (map[image:registry.redict.io/redict:7.3.0-scratch port:6379]) (push) Blocked by required conditions
testing / test-remote-cacher (map[image:docker.io/bitnami/valkey:7.2 port:6379]) (push) Blocked by required conditions
testing / test-mysql (push) Blocked by required conditions
testing / test-pgsql (push) Blocked by required conditions
testing / test-sqlite (push) Blocked by required conditions
testing / security-check (push) Blocked by required conditions
Some checks are pending
/ release (push) Waiting to run
testing / backend-checks (push) Waiting to run
testing / frontend-checks (push) Waiting to run
testing / test-unit (push) Blocked by required conditions
testing / test-remote-cacher (map[image:docker.io/bitnami/redis:7.2 port:6379]) (push) Blocked by required conditions
testing / test-remote-cacher (map[image:ghcr.io/microsoft/garnet-alpine:1.0.14 port:6379]) (push) Blocked by required conditions
testing / test-remote-cacher (map[image:registry.redict.io/redict:7.3.0-scratch port:6379]) (push) Blocked by required conditions
testing / test-remote-cacher (map[image:docker.io/bitnami/valkey:7.2 port:6379]) (push) Blocked by required conditions
testing / test-mysql (push) Blocked by required conditions
testing / test-pgsql (push) Blocked by required conditions
testing / test-sqlite (push) Blocked by required conditions
testing / security-check (push) Blocked by required conditions
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/5325 Reviewed-by: Gusted <gusted@noreply.codeberg.org> Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
This commit is contained in:
commit
64d3fcd403
19 changed files with 181 additions and 35 deletions
|
@ -163,6 +163,9 @@ code.gitea.io/gitea/modules/graceful
|
|||
code.gitea.io/gitea/modules/hcaptcha
|
||||
WithHTTP
|
||||
|
||||
code.gitea.io/gitea/modules/hostmatcher
|
||||
HostMatchList.AppendPattern
|
||||
|
||||
code.gitea.io/gitea/modules/json
|
||||
StdJSON.Marshal
|
||||
StdJSON.Unmarshal
|
||||
|
|
12
modules/cache/context.go
vendored
12
modules/cache/context.go
vendored
|
@ -63,9 +63,9 @@ func (cc *cacheContext) isDiscard() bool {
|
|||
}
|
||||
|
||||
// cacheContextLifetime is the max lifetime of cacheContext.
|
||||
// Since cacheContext is used to cache data in a request level context, 10s is enough.
|
||||
// If a cacheContext is used more than 10s, it's probably misuse.
|
||||
const cacheContextLifetime = 10 * time.Second
|
||||
// Since cacheContext is used to cache data in a request level context, 5 minutes is enough.
|
||||
// If a cacheContext is used more than 5 minutes, it's probably misuse.
|
||||
const cacheContextLifetime = 5 * time.Minute
|
||||
|
||||
var timeNow = time.Now
|
||||
|
||||
|
@ -133,7 +133,7 @@ func GetContextData(ctx context.Context, tp, key any) any {
|
|||
if c.Expired() {
|
||||
// The warning means that the cache context is misused for long-life task,
|
||||
// it can be resolved with WithNoCacheContext(ctx).
|
||||
log.Warn("cache context is expired, may be misused for long-life tasks: %v", c)
|
||||
log.Warn("cache context is expired, is highly likely to be misused for long-life tasks: %v", c)
|
||||
return nil
|
||||
}
|
||||
return c.Get(tp, key)
|
||||
|
@ -146,7 +146,7 @@ func SetContextData(ctx context.Context, tp, key, value any) {
|
|||
if c.Expired() {
|
||||
// The warning means that the cache context is misused for long-life task,
|
||||
// it can be resolved with WithNoCacheContext(ctx).
|
||||
log.Warn("cache context is expired, may be misused for long-life tasks: %v", c)
|
||||
log.Warn("cache context is expired, is highly likely to be misused for long-life tasks: %v", c)
|
||||
return
|
||||
}
|
||||
c.Put(tp, key, value)
|
||||
|
@ -159,7 +159,7 @@ func RemoveContextData(ctx context.Context, tp, key any) {
|
|||
if c.Expired() {
|
||||
// The warning means that the cache context is misused for long-life task,
|
||||
// it can be resolved with WithNoCacheContext(ctx).
|
||||
log.Warn("cache context is expired, may be misused for long-life tasks: %v", c)
|
||||
log.Warn("cache context is expired, is highly likely to be misused for long-life tasks: %v", c)
|
||||
return
|
||||
}
|
||||
c.Delete(tp, key)
|
||||
|
|
2
modules/cache/context_test.go
vendored
2
modules/cache/context_test.go
vendored
|
@ -46,7 +46,7 @@ func TestWithCacheContext(t *testing.T) {
|
|||
timeNow = now
|
||||
}()
|
||||
timeNow = func() time.Time {
|
||||
return now().Add(10 * time.Second)
|
||||
return now().Add(5 * time.Minute)
|
||||
}
|
||||
v = GetContextData(ctx, field, "my_config1")
|
||||
assert.Nil(t, v)
|
||||
|
|
|
@ -13,11 +13,7 @@ import (
|
|||
)
|
||||
|
||||
// NewDialContext returns a DialContext for Transport, the DialContext will do allow/block list check
|
||||
func NewDialContext(usage string, allowList, blockList *HostMatchList) func(ctx context.Context, network, addr string) (net.Conn, error) {
|
||||
return NewDialContextWithProxy(usage, allowList, blockList, nil)
|
||||
}
|
||||
|
||||
func NewDialContextWithProxy(usage string, allowList, blockList *HostMatchList, proxy *url.URL) func(ctx context.Context, network, addr string) (net.Conn, error) {
|
||||
func NewDialContext(usage string, allowList, blockList *HostMatchList, proxy *url.URL) func(ctx context.Context, network, addr string) (net.Conn, error) {
|
||||
// How Go HTTP Client works with redirection:
|
||||
// transport.RoundTrip URL=http://domain.com, Host=domain.com
|
||||
// transport.DialContext addrOrHost=domain.com:80
|
||||
|
|
14
options/gitignore/Hexo
Normal file
14
options/gitignore/Hexo
Normal file
|
@ -0,0 +1,14 @@
|
|||
# gitignore template for Hexo sites
|
||||
# website: https://hexo.io/
|
||||
# Recommended: Node.gitignore
|
||||
|
||||
# Ignore generated directory
|
||||
public/
|
||||
|
||||
# Ignore temp files
|
||||
tmp/
|
||||
.tmp*
|
||||
|
||||
# additional files
|
||||
db.json
|
||||
.deploy*/
|
3
options/gitignore/ReScript
Normal file
3
options/gitignore/ReScript
Normal file
|
@ -0,0 +1,3 @@
|
|||
/node_modules/
|
||||
/lib/
|
||||
.bsb.lock
|
3
options/gitignore/Terragrunt
Normal file
3
options/gitignore/Terragrunt
Normal file
|
@ -0,0 +1,3 @@
|
|||
# Ignore the default terragrunt cache directory
|
||||
# https://terragrunt.gruntwork.io/docs/features/caching/
|
||||
.terragrunt-cache
|
13
options/license/DocBook-Stylesheet
Normal file
13
options/license/DocBook-Stylesheet
Normal file
|
@ -0,0 +1,13 @@
|
|||
Copyright 2005 Norman Walsh, Sun Microsystems,
|
||||
Inc., and the Organization for the Advancement
|
||||
of Structured Information Standards (OASIS).
|
||||
|
||||
Release: $Id: db4-upgrade.xsl 8905 2010-09-12 11:47:07Z bobstayton $
|
||||
|
||||
Permission to use, copy, modify and distribute this stylesheet
|
||||
and its accompanying documentation for any purpose and
|
||||
without fee is hereby granted in perpetuity, provided that
|
||||
the above copyright notice and this paragraph appear in
|
||||
all copies. The copyright holders make no representation
|
||||
about the suitability of the schema for any purpose. It
|
||||
is provided "as is" without expressed or implied warranty.
|
10
options/license/GPL-3.0-389-ds-base-exception
Normal file
10
options/license/GPL-3.0-389-ds-base-exception
Normal file
|
@ -0,0 +1,10 @@
|
|||
Additional permission under GPLv3 section 7:
|
||||
|
||||
If you modify this Program, or any covered work, by
|
||||
linking or combining it with OpenSSL, or a modified
|
||||
version of OpenSSL licensed under the OpenSSL license
|
||||
(https://www.openssl.org/source/license.html), the licensors of this
|
||||
Program grant you additional permission to convey the resulting work.
|
||||
Corresponding Source for a non-source form of such a combination
|
||||
shall include the source code for the parts that are licensed
|
||||
under the OpenSSL license as well as that of the covered work.
|
30
options/license/MIT-Click
Normal file
30
options/license/MIT-Click
Normal file
|
@ -0,0 +1,30 @@
|
|||
Portions of this software are subject to the license below. The relevant
|
||||
source files are clearly marked; they refer to this file using the phrase
|
||||
"the Click LICENSE file". This license is an MIT license, plus a clause
|
||||
(taken from the W3C license) requiring prior written permission to use our
|
||||
names in publicity.
|
||||
|
||||
===========================================================================
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
The name and trademarks of copyright holders may NOT be used in advertising
|
||||
or publicity pertaining to the Software without specific, written prior
|
||||
permission. Title to copyright in this Software and any associated
|
||||
documentation will at all times remain with copyright holders.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
58
options/license/TrustedQSL
Normal file
58
options/license/TrustedQSL
Normal file
|
@ -0,0 +1,58 @@
|
|||
Copyright (C) 2001-2015 American Radio Relay League, Inc. All rights
|
||||
reserved.
|
||||
|
||||
Portions (C) 2003-2023 The TrustedQSL Developers. Please see the AUTHORS.txt
|
||||
file for contributors.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Any redistribution of source code must retain the above copyright
|
||||
notice, this list of conditions and the disclaimer shown in
|
||||
Paragraph 5 (below).
|
||||
|
||||
2. Redistribution in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the disclaimer shown in
|
||||
Paragraph 5 (below) in the documentation and/or other materials
|
||||
provided with the distribution.
|
||||
|
||||
3. Products derived from or including this software may not use
|
||||
"Logbook of the World" or "LoTW" or any other American Radio Relay
|
||||
League, Incorporated trademarks or servicemarks in their names
|
||||
without prior written permission of the ARRL. See Paragraph 6
|
||||
(below) for contact information.
|
||||
|
||||
4. Use of this software does not imply endorsement by ARRL of
|
||||
products derived from or including this software and vendors may not
|
||||
claim such endorsement.
|
||||
|
||||
5. Disclaimer: This software is provided "as-is" without
|
||||
representation, guarantee or warranty of any kind, either express or
|
||||
implied, including but not limited to the implied warranties of
|
||||
merchantability or of fitness for a particular purpose. The entire
|
||||
risk as to the quality and performance of the software is solely
|
||||
with you. Should the software prove defective, you (and not the
|
||||
American Radio Relay League, its officers, directors, employees or
|
||||
agents) assume the entire cost of all necessary servicing, repair or
|
||||
correction. In no event will ARRL be liable to you or to any third
|
||||
party for any damages, whether direct or indirect, including lost
|
||||
profits, lost savings, or other incidental or consequential damages
|
||||
arising out of the use or inability to use such software, regardless
|
||||
of whether ARRL has been advised of the possibility of such damages.
|
||||
|
||||
6. Contact information:
|
||||
|
||||
American Radio Relay League, Inc.
|
||||
Attn: Logbook of the World Manager
|
||||
225 Main St
|
||||
Newington, CT 06111
|
||||
voice: 860-594-0200
|
||||
fax: 860-594-0259
|
||||
email: logbook@arrl.org
|
||||
Worldwide Web: www.arrl.org
|
||||
|
||||
This software consists of voluntary contributions made by many
|
||||
individuals on behalf of the ARRL. More information on the "Logbook
|
||||
of The World" project and the ARRL is available from the ARRL Web
|
||||
site at www.arrl.org.
|
|
@ -12,6 +12,7 @@ import (
|
|||
"code.gitea.io/gitea/models/perm"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/models/unit"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/web"
|
||||
"code.gitea.io/gitea/routers/api/v1/utils"
|
||||
|
@ -252,6 +253,8 @@ func CreateRelease(ctx *context.APIContext) {
|
|||
ctx.Error(http.StatusConflict, "ReleaseAlreadyExist", err)
|
||||
} else if models.IsErrProtectedTagName(err) {
|
||||
ctx.Error(http.StatusUnprocessableEntity, "ProtectedTagName", err)
|
||||
} else if git.IsErrNotExist(err) {
|
||||
ctx.Error(http.StatusNotFound, "ErrNotExist", fmt.Errorf("target \"%v\" not found: %w", rel.Target, err))
|
||||
} else {
|
||||
ctx.Error(http.StatusInternalServerError, "CreateRelease", err)
|
||||
}
|
||||
|
|
|
@ -236,12 +236,12 @@ func SignInPost(ctx *context.Context) {
|
|||
if err != nil {
|
||||
if errors.Is(err, util.ErrNotExist) || errors.Is(err, util.ErrInvalidArgument) {
|
||||
ctx.RenderWithErr(ctx.Tr("form.username_password_incorrect"), tplSignIn, &form)
|
||||
log.Info("Failed authentication attempt for %s from %s: %v", form.UserName, ctx.RemoteAddr(), err)
|
||||
log.Warn("Failed authentication attempt for %s from %s: %v", form.UserName, ctx.RemoteAddr(), err)
|
||||
} else if user_model.IsErrEmailAlreadyUsed(err) {
|
||||
ctx.RenderWithErr(ctx.Tr("form.email_been_used"), tplSignIn, &form)
|
||||
log.Info("Failed authentication attempt for %s from %s: %v", form.UserName, ctx.RemoteAddr(), err)
|
||||
log.Warn("Failed authentication attempt for %s from %s: %v", form.UserName, ctx.RemoteAddr(), err)
|
||||
} else if user_model.IsErrUserProhibitLogin(err) {
|
||||
log.Info("Failed authentication attempt for %s from %s: %v", form.UserName, ctx.RemoteAddr(), err)
|
||||
log.Warn("Failed authentication attempt for %s from %s: %v", form.UserName, ctx.RemoteAddr(), err)
|
||||
ctx.Data["Title"] = ctx.Tr("auth.prohibit_login")
|
||||
ctx.HTML(http.StatusOK, "user/auth/prohibit_login")
|
||||
} else if user_model.IsErrUserInactive(err) {
|
||||
|
@ -249,7 +249,7 @@ func SignInPost(ctx *context.Context) {
|
|||
ctx.Data["Title"] = ctx.Tr("auth.active_your_account")
|
||||
ctx.HTML(http.StatusOK, TplActivate)
|
||||
} else {
|
||||
log.Info("Failed authentication attempt for %s from %s: %v", form.UserName, ctx.RemoteAddr(), err)
|
||||
log.Warn("Failed authentication attempt for %s from %s: %v", form.UserName, ctx.RemoteAddr(), err)
|
||||
ctx.Data["Title"] = ctx.Tr("auth.prohibit_login")
|
||||
ctx.HTML(http.StatusOK, "user/auth/prohibit_login")
|
||||
}
|
||||
|
|
|
@ -480,6 +480,7 @@ func ToLFSLock(ctx context.Context, l *git_model.LFSLock) *api.LFSLock {
|
|||
// ToChangedFile convert a gitdiff.DiffFile to api.ChangedFile
|
||||
func ToChangedFile(f *gitdiff.DiffFile, repo *repo_model.Repository, commit string) *api.ChangedFile {
|
||||
status := "changed"
|
||||
previousFilename := ""
|
||||
if f.IsDeleted {
|
||||
status = "deleted"
|
||||
} else if f.IsCreated {
|
||||
|
@ -488,23 +489,21 @@ func ToChangedFile(f *gitdiff.DiffFile, repo *repo_model.Repository, commit stri
|
|||
status = "copied"
|
||||
} else if f.IsRenamed && f.Type == gitdiff.DiffFileRename {
|
||||
status = "renamed"
|
||||
previousFilename = f.OldName
|
||||
} else if f.Addition == 0 && f.Deletion == 0 {
|
||||
status = "unchanged"
|
||||
}
|
||||
|
||||
file := &api.ChangedFile{
|
||||
Filename: f.GetDiffFileName(),
|
||||
Status: status,
|
||||
Additions: f.Addition,
|
||||
Deletions: f.Deletion,
|
||||
Changes: f.Addition + f.Deletion,
|
||||
HTMLURL: fmt.Sprint(repo.HTMLURL(), "/src/commit/", commit, "/", util.PathEscapeSegments(f.GetDiffFileName())),
|
||||
ContentsURL: fmt.Sprint(repo.APIURL(), "/contents/", util.PathEscapeSegments(f.GetDiffFileName()), "?ref=", commit),
|
||||
RawURL: fmt.Sprint(repo.HTMLURL(), "/raw/commit/", commit, "/", util.PathEscapeSegments(f.GetDiffFileName())),
|
||||
}
|
||||
|
||||
if status == "rename" {
|
||||
file.PreviousFilename = f.OldName
|
||||
Filename: f.GetDiffFileName(),
|
||||
Status: status,
|
||||
Additions: f.Addition,
|
||||
Deletions: f.Deletion,
|
||||
Changes: f.Addition + f.Deletion,
|
||||
PreviousFilename: previousFilename,
|
||||
HTMLURL: fmt.Sprint(repo.HTMLURL(), "/src/commit/", commit, "/", util.PathEscapeSegments(f.GetDiffFileName())),
|
||||
ContentsURL: fmt.Sprint(repo.APIURL(), "/contents/", util.PathEscapeSegments(f.GetDiffFileName()), "?ref=", commit),
|
||||
RawURL: fmt.Sprint(repo.HTMLURL(), "/raw/commit/", commit, "/", util.PathEscapeSegments(f.GetDiffFileName())),
|
||||
}
|
||||
|
||||
return file
|
||||
|
|
|
@ -24,6 +24,6 @@ func NewMigrationHTTPTransport() *http.Transport {
|
|||
return &http.Transport{
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: setting.Migrations.SkipTLSVerify},
|
||||
Proxy: proxy.Proxy(),
|
||||
DialContext: hostmatcher.NewDialContext("migration", allowList, blockList),
|
||||
DialContext: hostmatcher.NewDialContext("migration", allowList, blockList, setting.Proxy.ProxyURLFixed),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -506,9 +506,5 @@ func Init() error {
|
|||
// TODO: at the moment, if ALLOW_LOCALNETWORKS=false, ALLOWED_DOMAINS=domain.com, and domain.com has IP 127.0.0.1, then it's still allowed.
|
||||
// if we want to block such case, the private&loopback should be added to the blockList when ALLOW_LOCALNETWORKS=false
|
||||
|
||||
if setting.Proxy.Enabled && setting.Proxy.ProxyURLFixed != nil {
|
||||
allowList.AppendPattern(setting.Proxy.ProxyURLFixed.Host)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@ func createTag(ctx context.Context, gitRepo *git.Repository, rel *repo_model.Rel
|
|||
|
||||
commit, err := gitRepo.GetCommit(rel.Target)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("createTag::GetCommit[%v]: %w", rel.Target, err)
|
||||
return false, err
|
||||
}
|
||||
|
||||
if len(msg) > 0 {
|
||||
|
|
|
@ -212,7 +212,7 @@ func Init() error {
|
|||
Transport: &http.Transport{
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: setting.Webhook.SkipTLSVerify},
|
||||
Proxy: webhookProxy(allowedHostMatcher),
|
||||
DialContext: hostmatcher.NewDialContextWithProxy("webhook", allowedHostMatcher, nil, setting.Webhook.ProxyURLFixed),
|
||||
DialContext: hostmatcher.NewDialContext("webhook", allowedHostMatcher, nil, setting.Webhook.ProxyURLFixed),
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -214,6 +214,24 @@ func TestAPICreateReleaseToDefaultBranchOnExistingTag(t *testing.T) {
|
|||
createNewReleaseUsingAPI(t, token, owner, repo, "v0.0.1", "", "v0.0.1", "test")
|
||||
}
|
||||
|
||||
func TestAPICreateReleaseGivenInvalidTarget(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
|
||||
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
|
||||
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
|
||||
session := loginUser(t, owner.LowerName)
|
||||
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)
|
||||
|
||||
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/releases", owner.Name, repo.Name)
|
||||
req := NewRequestWithJSON(t, "POST", urlStr, &api.CreateReleaseOption{
|
||||
TagName: "i-point-to-an-invalid-target",
|
||||
Title: "Invalid Target",
|
||||
Target: "invalid-target",
|
||||
}).AddTokenAuth(token)
|
||||
|
||||
MakeRequest(t, req, http.StatusNotFound)
|
||||
}
|
||||
|
||||
func TestAPIGetLatestRelease(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
|
||||
|
|
Loading…
Reference in a new issue