diff --git a/.deadcode-out b/.deadcode-out index 72d5df86dc..f6a194b17f 100644 --- a/.deadcode-out +++ b/.deadcode-out @@ -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 diff --git a/modules/cache/context.go b/modules/cache/context.go index 5f0ca81e8d..f9bdf52044 100644 --- a/modules/cache/context.go +++ b/modules/cache/context.go @@ -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) diff --git a/modules/cache/context_test.go b/modules/cache/context_test.go index 1ee3d2dd52..072c39440f 100644 --- a/modules/cache/context_test.go +++ b/modules/cache/context_test.go @@ -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) diff --git a/modules/hostmatcher/http.go b/modules/hostmatcher/http.go index c743f6efb3..8828902034 100644 --- a/modules/hostmatcher/http.go +++ b/modules/hostmatcher/http.go @@ -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 diff --git a/options/gitignore/Hexo b/options/gitignore/Hexo new file mode 100644 index 0000000000..570a5e7b5d --- /dev/null +++ b/options/gitignore/Hexo @@ -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*/ diff --git a/options/gitignore/ReScript b/options/gitignore/ReScript new file mode 100644 index 0000000000..b7364c932a --- /dev/null +++ b/options/gitignore/ReScript @@ -0,0 +1,3 @@ +/node_modules/ +/lib/ +.bsb.lock diff --git a/options/gitignore/Terragrunt b/options/gitignore/Terragrunt new file mode 100644 index 0000000000..ea4808637f --- /dev/null +++ b/options/gitignore/Terragrunt @@ -0,0 +1,3 @@ +# Ignore the default terragrunt cache directory +# https://terragrunt.gruntwork.io/docs/features/caching/ +.terragrunt-cache diff --git a/options/license/DocBook-Stylesheet b/options/license/DocBook-Stylesheet new file mode 100644 index 0000000000..e986ed4235 --- /dev/null +++ b/options/license/DocBook-Stylesheet @@ -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. diff --git a/options/license/GPL-3.0-389-ds-base-exception b/options/license/GPL-3.0-389-ds-base-exception new file mode 100644 index 0000000000..52be470c10 --- /dev/null +++ b/options/license/GPL-3.0-389-ds-base-exception @@ -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. diff --git a/options/license/MIT-Click b/options/license/MIT-Click new file mode 100644 index 0000000000..82054edc39 --- /dev/null +++ b/options/license/MIT-Click @@ -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. diff --git a/options/license/TrustedQSL b/options/license/TrustedQSL new file mode 100644 index 0000000000..982d4269f6 --- /dev/null +++ b/options/license/TrustedQSL @@ -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. diff --git a/routers/api/v1/repo/release.go b/routers/api/v1/repo/release.go index 979ab42b31..5ea4dc8cfc 100644 --- a/routers/api/v1/repo/release.go +++ b/routers/api/v1/repo/release.go @@ -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) } diff --git a/routers/web/auth/auth.go b/routers/web/auth/auth.go index 785b99173c..bb20309030 100644 --- a/routers/web/auth/auth.go +++ b/routers/web/auth/auth.go @@ -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") } diff --git a/services/convert/convert.go b/services/convert/convert.go index d6dc3c9858..7a094494e4 100644 --- a/services/convert/convert.go +++ b/services/convert/convert.go @@ -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 diff --git a/services/migrations/http_client.go b/services/migrations/http_client.go index 9e3caec191..0b997e08f4 100644 --- a/services/migrations/http_client.go +++ b/services/migrations/http_client.go @@ -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), } } diff --git a/services/migrations/migrate.go b/services/migrations/migrate.go index 6854a56284..29b815d521 100644 --- a/services/migrations/migrate.go +++ b/services/migrations/migrate.go @@ -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 } diff --git a/services/release/release.go b/services/release/release.go index 11740e4cc8..99851ed1b7 100644 --- a/services/release/release.go +++ b/services/release/release.go @@ -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 { diff --git a/services/webhook/deliver.go b/services/webhook/deliver.go index 8db1c72572..25668143e6 100644 --- a/services/webhook/deliver.go +++ b/services/webhook/deliver.go @@ -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), }, } diff --git a/tests/integration/api_releases_test.go b/tests/integration/api_releases_test.go index ad29343b7b..1bd8a643ad 100644 --- a/tests/integration/api_releases_test.go +++ b/tests/integration/api_releases_test.go @@ -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)()