From 3bd49f780157494a3ff923a3bcdbb8696a688173 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Sun, 25 Dec 2022 00:19:36 +0000 Subject: [PATCH 01/23] [skip ci] Updated licenses and gitignores --- options/gitignore/Godot | 4 ++++ options/license/Bitstream-Charter | 9 ++++++++ options/license/Graphics-Gems | 5 +++++ options/license/IJG-short | 35 +++++++++++++++++++++++++++++++ options/license/MIT-Wu | 28 +++++++++++++++++++++++++ options/license/TPDL | 2 ++ options/license/TTWL | 8 +++++++ 7 files changed, 91 insertions(+) create mode 100644 options/license/Bitstream-Charter create mode 100644 options/license/Graphics-Gems create mode 100644 options/license/IJG-short create mode 100644 options/license/MIT-Wu create mode 100644 options/license/TPDL create mode 100644 options/license/TTWL diff --git a/options/gitignore/Godot b/options/gitignore/Godot index 4f48ad79f8fb..d9aac213e776 100644 --- a/options/gitignore/Godot +++ b/options/gitignore/Godot @@ -1,3 +1,6 @@ +# Godot 4+ specific ignores +.godot/ + # Godot-specific ignores .import/ export.cfg @@ -9,3 +12,4 @@ export_presets.cfg # Mono-specific ignores .mono/ data_*/ +mono_crash.*.json diff --git a/options/license/Bitstream-Charter b/options/license/Bitstream-Charter new file mode 100644 index 000000000000..7a0cf97a0c98 --- /dev/null +++ b/options/license/Bitstream-Charter @@ -0,0 +1,9 @@ +(c) Copyright 1989-1992, Bitstream Inc., Cambridge, MA. + +You are hereby granted permission under all Bitstream propriety rights +to use, copy, modify, sublicense, sell, and redistribute the 4 Bitstream +Charter (r) Type 1 outline fonts and the 4 Courier Type 1 outline fonts for +any purpose and without restriction; provided, that this notice is left +intact on all copies of such fonts and that Bitstream's trademark is acknowledged +as shown below on all unmodified copies of the 4 Charter Type 1 fonts. +BITSTREAM CHARTER is a registered trademark of Bitstream Inc. diff --git a/options/license/Graphics-Gems b/options/license/Graphics-Gems new file mode 100644 index 000000000000..ec28c4656361 --- /dev/null +++ b/options/license/Graphics-Gems @@ -0,0 +1,5 @@ +LICENSE + +This code repository predates the concept of Open Source, and predates most licenses along such lines. As such, the official license truly is: + +EULA: The Graphics Gems code is copyright-protected. In other words, you cannot claim the text of the code as your own and resell it. Using the code is permitted in any program, product, or library, non-commercial or commercial. Giving credit is not required, though is a nice gesture. The code comes as-is, and if there are any flaws or problems with any Gems code, nobody involved with Gems - authors, editors, publishers, or webmasters - are to be held responsible. Basically, don't be a jerk, and remember that anything free comes with no guarantee. diff --git a/options/license/IJG-short b/options/license/IJG-short new file mode 100644 index 000000000000..bbb0859d804d --- /dev/null +++ b/options/license/IJG-short @@ -0,0 +1,35 @@ +The authors make NO WARRANTY or representation, either express or +implied, with respect to this software, its quality, accuracy, +merchantability, or fitness for a particular purpose. This software is +provided "AS IS", and you, its user, assume the entire risk as to its +quality and accuracy. + +This software is copyright (C) 1991, 1992, Thomas G. Lane. All Rights +Reserved except as specified below. + +Permission is hereby granted to use, copy, modify, and distribute this +software (or portions thereof) for any purpose, without fee, subject to +these conditions: + +(1) If any part of the source code for this software +is distributed, then this README file must be included, with this +copyright and no-warranty notice unaltered; and any additions, +deletions, or changes to the original files must be clearly indicated +in accompanying documentation. + +(2) If only executable code is +distributed, then the accompanying documentation must state that "this +software is based in part on the work of the Independent JPEG Group". + +(3) Permission for use of this software is granted only if the user +accepts full responsibility for any undesirable consequences; the +authors accept NO LIABILITY for damages of any kind. + +Permission is NOT granted for the use of any IJG author's name or +company name in advertising or publicity relating to this software or +products derived from it. This software may be referred to only as +"the Independent JPEG Group's software". + +We specifically permit and encourage the use of this software as the +basis of commercial products, provided that all warranty or liability +claims are assumed by the product vendor. diff --git a/options/license/MIT-Wu b/options/license/MIT-Wu new file mode 100644 index 000000000000..86eec3c517a9 --- /dev/null +++ b/options/license/MIT-Wu @@ -0,0 +1,28 @@ +Copyright (c) 2003-2005 Tom Wu +All Rights Reserved. + +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 SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, +EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY +WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + +IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL, +INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER +RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF +THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT +OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +In addition, the following condition applies: + +All redistributions must retain an intact copy of this copyright notice +and disclaimer. diff --git a/options/license/TPDL b/options/license/TPDL new file mode 100644 index 000000000000..d950f8f19e59 --- /dev/null +++ b/options/license/TPDL @@ -0,0 +1,2 @@ +Copyright (C) 1996-2010 David Muir Sharnoff. Copyright (C) 2011 Google, Inc. +License hereby granted for anyone to use, modify or redistribute this module at their own risk. Please feed useful changes back to cpan@dave.sharnoff.org. diff --git a/options/license/TTWL b/options/license/TTWL new file mode 100644 index 000000000000..c13d3fbe04a4 --- /dev/null +++ b/options/license/TTWL @@ -0,0 +1,8 @@ +Copyright (C) 1996-2002,2005,2006 David Muir Sharnoff. +Copyright (C) 2005 Aristotle Pagaltzis +Copyright (C) 2012-2013 Google, Inc. + +This module may be modified, used, copied, and redistributed at your own risk. +Although allowed by the preceding license, please do not publicly +redistribute modified versions of this code with the name "Text::Tabs" +unless it passes the unmodified Text::Tabs test suite. From f5cd0d93192fc4d04966ba971c7aaaae7475926d Mon Sep 17 00:00:00 2001 From: silverwind Date: Sun, 25 Dec 2022 18:17:48 +0100 Subject: [PATCH 02/23] Add Mermaid copy button, avoid unnecessary tooltip hide (#22225) - Add Copy button to mermaid diagrams which copies their source. - Set tippy to not hide on click and avoid tooltip re-creation for temporary tooltips. This avoids hide and show when copying repo url. Popovers still hide the tooltip as usual. Screenshot 2022-12-23 at 14 02 32 Co-authored-by: Lauris BH Co-authored-by: KN4CK3R --- web_src/js/markup/codecopy.js | 13 ++++++++----- web_src/js/markup/mermaid.js | 10 +++++++++- web_src/js/modules/tippy.js | 3 ++- web_src/less/markup/codecopy.less | 6 ++++-- 4 files changed, 23 insertions(+), 9 deletions(-) diff --git a/web_src/js/markup/codecopy.js b/web_src/js/markup/codecopy.js index 2aa7070c72de..a12802ef7347 100644 --- a/web_src/js/markup/codecopy.js +++ b/web_src/js/markup/codecopy.js @@ -1,15 +1,18 @@ import {svg} from '../svg.js'; -export function renderCodeCopy() { - const els = document.querySelectorAll('.markup .code-block code'); - if (!els.length) return; - +export function makeCodeCopyButton() { const button = document.createElement('button'); button.classList.add('code-copy', 'ui', 'button'); button.innerHTML = svg('octicon-copy'); + return button; +} + +export function renderCodeCopy() { + const els = document.querySelectorAll('.markup .code-block code'); + if (!els.length) return; for (const el of els) { - const btn = button.cloneNode(true); + const btn = makeCodeCopyButton(); btn.setAttribute('data-clipboard-text', el.textContent); el.after(btn); } diff --git a/web_src/js/markup/mermaid.js b/web_src/js/markup/mermaid.js index efd9abbb5692..29fa92552dca 100644 --- a/web_src/js/markup/mermaid.js +++ b/web_src/js/markup/mermaid.js @@ -1,4 +1,6 @@ import {isDarkTheme} from '../utils.js'; +import {makeCodeCopyButton} from './codecopy.js'; + const {mermaidMaxSourceCharacters} = window.config; const iframeCss = ` @@ -58,7 +60,13 @@ export async function renderMermaid() { iframe.sandbox = 'allow-scripts'; iframe.style.height = `${Math.ceil(parseFloat(heightStr))}px`; iframe.srcdoc = ` ${svgStr}`; - el.closest('pre').replaceWith(iframe); + const mermaidBlock = document.createElement('div'); + mermaidBlock.classList.add('mermaid-block'); + mermaidBlock.append(iframe); + const btn = makeCodeCopyButton(); + btn.setAttribute('data-clipboard-text', source); + mermaidBlock.append(btn); + el.closest('pre').replaceWith(mermaidBlock); }); } catch (err) { displayError(el, err); diff --git a/web_src/js/modules/tippy.js b/web_src/js/modules/tippy.js index 6a89151691a9..ce8f0369f11c 100644 --- a/web_src/js/modules/tippy.js +++ b/web_src/js/modules/tippy.js @@ -6,6 +6,7 @@ export function createTippy(target, opts = {}) { placement: target.getAttribute('data-placement') || 'top-start', animation: false, allowHTML: false, + hideOnClick: false, interactiveBorder: 30, ignoreAttributes: true, maxWidth: 500, // increase over default 350px @@ -46,7 +47,7 @@ export function showTemporaryTooltip(target, content) { } tippy.setContent(content); - tippy.show(); + if (!tippy.state.isShown) tippy.show(); tippy.setProps({ onHidden: (tippy) => { if (oldContent) { diff --git a/web_src/less/markup/codecopy.less b/web_src/less/markup/codecopy.less index b2ce77aaa157..f6f9894fc14b 100644 --- a/web_src/less/markup/codecopy.less +++ b/web_src/less/markup/codecopy.less @@ -1,4 +1,5 @@ -.markup .code-block { +.markup .code-block, +.markup .mermaid-block { position: relative; } @@ -26,7 +27,8 @@ background: var(--color-secondary-dark-1) !important; } -.markup .code-block:hover .code-copy { +.markup .code-block:hover .code-copy, +.markup .mermaid-block:hover .code-copy { visibility: visible; animation: fadein .2s both; } From 814b44aeafda0c31b2600895e66d7ea3d5876ca5 Mon Sep 17 00:00:00 2001 From: Jason Song Date: Mon, 26 Dec 2022 16:50:58 +0800 Subject: [PATCH 03/23] Fix typo of Asia/Shanghai (#22242) As the title. --- docs/content/doc/advanced/config-cheat-sheet.en-us.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/doc/advanced/config-cheat-sheet.en-us.md b/docs/content/doc/advanced/config-cheat-sheet.en-us.md index 0268938187de..c2d5ae266709 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.en-us.md +++ b/docs/content/doc/advanced/config-cheat-sheet.en-us.md @@ -1145,7 +1145,7 @@ in this mapping or the filetype using heuristics. ## Time (`time`) - `FORMAT`: Time format to display on UI. i.e. RFC1123 or 2006-01-02 15:04:05 -- `DEFAULT_UI_LOCATION`: Default location of time on the UI, so that we can display correct user's time on UI. i.e. Shanghai/Asia +- `DEFAULT_UI_LOCATION`: Default location of time on the UI, so that we can display correct user's time on UI. i.e. Asia/Shanghai ## Task (`task`) From 83640c449eb6a1b31bc09b1372cc156d114804f8 Mon Sep 17 00:00:00 2001 From: zeripath Date: Tue, 27 Dec 2022 00:34:05 +0000 Subject: [PATCH 04/23] Remove ReverseProxy authentication from the API (#22219) Since we changed the /api/v1/ routes to disallow session authentication we also removed their reliance on CSRF. However, we left the ReverseProxy authentication here - but this means that POSTs to the API are no longer protected by CSRF. Now, ReverseProxy authentication is a kind of session authentication, and is therefore inconsistent with the removal of session from the API. This PR proposes that we simply remove the ReverseProxy authentication from the API and therefore users of the API must explicitly use tokens or basic authentication. Replace #22077 Close #22221 Close #22077 Signed-off-by: Andrew Thornton --- routers/api/v1/api.go | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 82ff7ae0befc..c12ceacdd3b1 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -230,13 +230,10 @@ func reqExploreSignIn() func(ctx *context.APIContext) { } } -func reqBasicOrRevProxyAuth() func(ctx *context.APIContext) { +func reqBasicAuth() func(ctx *context.APIContext) { return func(ctx *context.APIContext) { - if ctx.IsSigned && setting.Service.EnableReverseProxyAuth && ctx.Data["AuthedMethod"].(string) == auth.ReverseProxyMethodName { - return - } if !ctx.Context.IsBasicAuth { - ctx.Error(http.StatusUnauthorized, "reqBasicOrRevProxyAuth", "auth required") + ctx.Error(http.StatusUnauthorized, "reqBasicAuth", "auth required") return } ctx.CheckForOTP() @@ -598,9 +595,6 @@ func buildAuthGroup() *auth.Group { &auth.HTTPSign{}, &auth.Basic{}, // FIXME: this should be removed once we don't allow basic auth in API ) - if setting.Service.EnableReverseProxyAuth { - group.Add(&auth.ReverseProxy{}) - } specialAdd(group) return group @@ -690,7 +684,7 @@ func Routes(ctx gocontext.Context) *web.Route { m.Combo("").Get(user.ListAccessTokens). Post(bind(api.CreateAccessTokenOption{}), user.CreateAccessToken) m.Combo("/{id}").Delete(user.DeleteAccessToken) - }, reqBasicOrRevProxyAuth()) + }, reqBasicAuth()) }, context_service.UserAssignmentAPI()) }) From b48cf03717e99ff33d1e845c97e6f8c469cd2e6d Mon Sep 17 00:00:00 2001 From: Gusted Date: Tue, 27 Dec 2022 02:15:35 +0100 Subject: [PATCH 05/23] Remove deadcode (#22245) - Remove code that isn't being used. Found this is my stash from a few weeks ago, not sure how I found this in the first place. Co-authored-by: Lunny Xiao --- modules/git/repo_attribute.go | 98 ------------------------ modules/git/repo_attribute_test.go | 61 --------------- modules/markup/markdown/markdown.go | 6 -- modules/markup/markdown/markdown_test.go | 22 ------ 4 files changed, 187 deletions(-) diff --git a/modules/git/repo_attribute.go b/modules/git/repo_attribute.go index d3a3dc8c837c..404d9e502c04 100644 --- a/modules/git/repo_attribute.go +++ b/modules/git/repo_attribute.go @@ -9,8 +9,6 @@ import ( "fmt" "io" "os" - "strconv" - "strings" "code.gitea.io/gitea/modules/log" ) @@ -288,102 +286,6 @@ func (wr *nulSeparatedAttributeWriter) Close() error { return nil } -type lineSeparatedAttributeWriter struct { - tmp []byte - attributes chan attributeTriple - closed chan struct{} -} - -func (wr *lineSeparatedAttributeWriter) Write(p []byte) (n int, err error) { - l := len(p) - - nlIdx := bytes.IndexByte(p, '\n') - for nlIdx >= 0 { - wr.tmp = append(wr.tmp, p[:nlIdx]...) - - if len(wr.tmp) == 0 { - // This should not happen - if len(p) > nlIdx+1 { - wr.tmp = wr.tmp[:0] - p = p[nlIdx+1:] - nlIdx = bytes.IndexByte(p, '\n') - continue - } else { - return l, nil - } - } - - working := attributeTriple{} - if wr.tmp[0] == '"' { - sb := new(strings.Builder) - remaining := string(wr.tmp[1:]) - for len(remaining) > 0 { - rn, _, tail, err := strconv.UnquoteChar(remaining, '"') - if err != nil { - if len(remaining) > 2 && remaining[0] == '"' && remaining[1] == ':' && remaining[2] == ' ' { - working.Filename = sb.String() - wr.tmp = []byte(remaining[3:]) - break - } - return l, fmt.Errorf("unexpected tail %s", remaining) - } - _, _ = sb.WriteRune(rn) - remaining = tail - } - } else { - idx := bytes.IndexByte(wr.tmp, ':') - if idx < 0 { - return l, fmt.Errorf("unexpected input %s", string(wr.tmp)) - } - working.Filename = string(wr.tmp[:idx]) - if len(wr.tmp) < idx+2 { - return l, fmt.Errorf("unexpected input %s", string(wr.tmp)) - } - wr.tmp = wr.tmp[idx+2:] - } - - idx := bytes.IndexByte(wr.tmp, ':') - if idx < 0 { - return l, fmt.Errorf("unexpected input %s", string(wr.tmp)) - } - - working.Attribute = string(wr.tmp[:idx]) - if len(wr.tmp) < idx+2 { - return l, fmt.Errorf("unexpected input %s", string(wr.tmp)) - } - - working.Value = string(wr.tmp[idx+2:]) - - wr.attributes <- working - wr.tmp = wr.tmp[:0] - if len(p) > nlIdx+1 { - p = p[nlIdx+1:] - nlIdx = bytes.IndexByte(p, '\n') - continue - } else { - return l, nil - } - } - - wr.tmp = append(wr.tmp, p...) - return l, nil -} - -func (wr *lineSeparatedAttributeWriter) ReadAttribute() <-chan attributeTriple { - return wr.attributes -} - -func (wr *lineSeparatedAttributeWriter) Close() error { - select { - case <-wr.closed: - return nil - default: - } - close(wr.attributes) - close(wr.closed) - return nil -} - // Create a check attribute reader for the current repository and provided commit ID func (repo *Repository) CheckAttributeReader(commitID string) (*CheckAttributeReader, context.CancelFunc) { indexFilename, worktree, deleteTemporaryFile, err := repo.ReadTreeToTemporaryIndex(commitID) diff --git a/modules/git/repo_attribute_test.go b/modules/git/repo_attribute_test.go index 6882874d2dc7..f88ae9540786 100644 --- a/modules/git/repo_attribute_test.go +++ b/modules/git/repo_attribute_test.go @@ -95,64 +95,3 @@ func Test_nulSeparatedAttributeWriter_ReadAttribute(t *testing.T) { Value: "unspecified", }, attr) } - -func Test_lineSeparatedAttributeWriter_ReadAttribute(t *testing.T) { - wr := &lineSeparatedAttributeWriter{ - attributes: make(chan attributeTriple, 5), - } - - testStr := `".gitignore\"\n": linguist-vendored: unspecified -` - n, err := wr.Write([]byte(testStr)) - - assert.Equal(t, n, len(testStr)) - assert.NoError(t, err) - - select { - case attr := <-wr.ReadAttribute(): - assert.Equal(t, ".gitignore\"\n", attr.Filename) - assert.Equal(t, "linguist-vendored", attr.Attribute) - assert.Equal(t, "unspecified", attr.Value) - case <-time.After(100 * time.Millisecond): - assert.Fail(t, "took too long to read an attribute from the list") - } - - // Write a second attribute again - n, err = wr.Write([]byte(testStr)) - - assert.Equal(t, n, len(testStr)) - assert.NoError(t, err) - - select { - case attr := <-wr.ReadAttribute(): - assert.Equal(t, ".gitignore\"\n", attr.Filename) - assert.Equal(t, "linguist-vendored", attr.Attribute) - assert.Equal(t, "unspecified", attr.Value) - case <-time.After(100 * time.Millisecond): - assert.Fail(t, "took too long to read an attribute from the list") - } - - // Write a partial attribute - _, err = wr.Write([]byte("incomplete-file")) - assert.NoError(t, err) - _, err = wr.Write([]byte("name: ")) - assert.NoError(t, err) - select { - case <-wr.ReadAttribute(): - assert.Fail(t, "There should not be an attribute ready to read") - case <-time.After(100 * time.Millisecond): - } - _, err = wr.Write([]byte("attribute: ")) - assert.NoError(t, err) - select { - case <-wr.ReadAttribute(): - assert.Fail(t, "There should not be an attribute ready to read") - case <-time.After(100 * time.Millisecond): - } - _, err = wr.Write([]byte("value\n")) - assert.NoError(t, err) - attr := <-wr.ReadAttribute() - assert.Equal(t, "incomplete-filename", attr.Filename) - assert.Equal(t, "attribute", attr.Attribute) - assert.Equal(t, "value", attr.Value) -} diff --git a/modules/markup/markdown/markdown.go b/modules/markup/markdown/markdown.go index 1e5c4707585e..f1ffea887246 100644 --- a/modules/markup/markdown/markdown.go +++ b/modules/markup/markdown/markdown.go @@ -289,9 +289,3 @@ func RenderRawString(ctx *markup.RenderContext, content string) (string, error) } return buf.String(), nil } - -// IsMarkdownFile reports whether name looks like a Markdown file -// based on its extension. -func IsMarkdownFile(name string) bool { - return markup.IsMarkupFile(name, MarkupName) -} diff --git a/modules/markup/markdown/markdown_test.go b/modules/markup/markdown/markdown_test.go index bb2c47f18e99..cc683dc5b7c7 100644 --- a/modules/markup/markdown/markdown_test.go +++ b/modules/markup/markdown/markdown_test.go @@ -74,28 +74,6 @@ func TestRender_StandardLinks(t *testing.T) { `

WikiPage

`) } -func TestMisc_IsMarkdownFile(t *testing.T) { - setting.Markdown.FileExtensions = []string{".md", ".markdown", ".mdown", ".mkd"} - trueTestCases := []string{ - "test.md", - "wow.MARKDOWN", - "LOL.mDoWn", - } - falseTestCases := []string{ - "test", - "abcdefg", - "abcdefghijklmnopqrstuvwxyz", - "test.md.test", - } - - for _, testCase := range trueTestCases { - assert.True(t, IsMarkdownFile(testCase)) - } - for _, testCase := range falseTestCases { - assert.False(t, IsMarkdownFile(testCase)) - } -} - func TestRender_Images(t *testing.T) { setting.AppURL = AppURL setting.AppSubURL = AppSubURL From 90237d8abd0e6479c1464ac0f32fff6a2ce4a0b4 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Tue, 27 Dec 2022 14:00:34 +0800 Subject: [PATCH 06/23] Add more test directory to exclude dir of air, remove watching templates from air include dir because gitea has internal mechanism (#22246) Since #20218 introduced internal watching template, template watching should be removed from `air`. This will prevent restart the whole server once the template files changed to speed up developing when using `make watch`. To ensure `make watch` will reuse template watching, this PR introduced a new ENV `GITEA_RUN_MODE` to make sure `make watch` will always run in a dev mode of Gitea so that template watching will open. This PR also added more exclude testdata directories. --- .air.toml | 4 ++-- Makefile | 2 +- modules/setting/setting.go | 5 ++++- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/.air.toml b/.air.toml index 061008830317..069a88924388 100644 --- a/.air.toml +++ b/.air.toml @@ -5,6 +5,6 @@ tmp_dir = ".air" cmd = "make backend" bin = "gitea" include_ext = ["go", "tmpl"] -exclude_dir = ["modules/git/tests", "services/gitdiff/testdata", "modules/avatar/testdata"] -include_dir = ["cmd", "models", "modules", "options", "routers", "services", "templates"] +exclude_dir = ["modules/git/tests", "services/gitdiff/testdata", "modules/avatar/testdata", "models/fixtures", "models/migrations/fixtures", "modules/migration/file_format_testdata", "modules/avatar/identicon/testdata"] +include_dir = ["cmd", "models", "modules", "options", "routers", "services"] exclude_regex = ["_test.go$", "_gen.go$"] diff --git a/Makefile b/Makefile index d1122984a7d8..06a0d1c18e22 100644 --- a/Makefile +++ b/Makefile @@ -359,7 +359,7 @@ watch-frontend: node-check node_modules .PHONY: watch-backend watch-backend: go-check - $(GO) run $(AIR_PACKAGE) -c .air.toml + GITEA_RUN_MODE=dev $(GO) run $(AIR_PACKAGE) -c .air.toml .PHONY: test test: test-frontend test-backend diff --git a/modules/setting/setting.go b/modules/setting/setting.go index 47e0ae2cda1f..07290fbfeb9f 100644 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -1043,7 +1043,10 @@ func loadFromConf(allowEmpty bool, extraConfig string) { // The following is a purposefully undocumented option. Please do not run Gitea as root. It will only cause future headaches. // Please don't use root as a bandaid to "fix" something that is broken, instead the broken thing should instead be fixed properly. unsafeAllowRunAsRoot := Cfg.Section("").Key("I_AM_BEING_UNSAFE_RUNNING_AS_ROOT").MustBool(false) - RunMode = Cfg.Section("").Key("RUN_MODE").MustString("prod") + RunMode = os.Getenv("GITEA_RUN_MODE") + if RunMode == "" { + RunMode = Cfg.Section("").Key("RUN_MODE").MustString("prod") + } IsProd = strings.EqualFold(RunMode, "prod") // Does not check run user when the install lock is off. if InstallLock { From 6cf09ccab402fe84a5313e1d3e755e284ebbc845 Mon Sep 17 00:00:00 2001 From: Jason Song Date: Tue, 27 Dec 2022 21:12:49 +0800 Subject: [PATCH 07/23] Use complete SHA to create and query commit status (#22244) Fix #13485. Co-authored-by: delvh Co-authored-by: Lauris BH Co-authored-by: Lunny Xiao --- models/activities/action.go | 2 +- models/git/commit_status.go | 4 ++++ modules/context/api.go | 2 +- modules/context/repo.go | 8 +++---- modules/git/repo_commit_gogit.go | 2 +- modules/git/repo_commit_nogogit.go | 2 +- modules/git/repo_index.go | 2 +- modules/git/repo_tree_gogit.go | 2 +- modules/git/repo_tree_nogogit.go | 2 +- modules/git/sha1.go | 5 ++++- routers/api/v1/repo/status.go | 1 + routers/api/v1/utils/git.go | 29 ++++++++++++++++++++++++++ routers/web/repo/commit.go | 2 +- services/pull/check.go | 12 +++++------ services/pull/merge.go | 2 +- services/pull/temp_repo.go | 2 +- services/repository/files/commit.go | 5 ++++- services/repository/files/tree.go | 2 +- tests/integration/repo_commits_test.go | 5 +++++ 19 files changed, 68 insertions(+), 23 deletions(-) diff --git a/models/activities/action.go b/models/activities/action.go index 1ac1be7135d8..4baedbfe124b 100644 --- a/models/activities/action.go +++ b/models/activities/action.go @@ -272,7 +272,7 @@ func (a *Action) GetRefLink() string { return a.GetRepoLink() + "/src/branch/" + util.PathEscapeSegments(strings.TrimPrefix(a.RefName, git.BranchPrefix)) case strings.HasPrefix(a.RefName, git.TagPrefix): return a.GetRepoLink() + "/src/tag/" + util.PathEscapeSegments(strings.TrimPrefix(a.RefName, git.TagPrefix)) - case len(a.RefName) == 40 && git.IsValidSHAPattern(a.RefName): + case len(a.RefName) == git.SHAFullLength && git.IsValidSHAPattern(a.RefName): return a.GetRepoLink() + "/src/commit/" + a.RefName default: // FIXME: we will just assume it's a branch - this was the old way - at some point we may want to enforce that there is always a ref here. diff --git a/models/git/commit_status.go b/models/git/commit_status.go index 0fb0bc66af9a..07e0b9fb73b4 100644 --- a/models/git/commit_status.go +++ b/models/git/commit_status.go @@ -279,6 +279,10 @@ func NewCommitStatus(opts NewCommitStatusOptions) error { return fmt.Errorf("NewCommitStatus[%s, %s]: no user specified", repoPath, opts.SHA) } + if _, err := git.NewIDFromString(opts.SHA); err != nil { + return fmt.Errorf("NewCommitStatus[%s, %s]: invalid sha: %w", repoPath, opts.SHA, err) + } + ctx, committer, err := db.TxContext(db.DefaultContext) if err != nil { return fmt.Errorf("NewCommitStatus[repo_id: %d, user_id: %d, sha: %s]: %w", opts.Repo.ID, opts.Creator.ID, opts.SHA, err) diff --git a/modules/context/api.go b/modules/context/api.go index f49997a7875f..1349f91ec0fb 100644 --- a/modules/context/api.go +++ b/modules/context/api.go @@ -387,7 +387,7 @@ func RepoRefForAPI(next http.Handler) http.Handler { return } ctx.Repo.CommitID = ctx.Repo.Commit.ID.String() - } else if len(refName) == 40 { + } else if len(refName) == git.SHAFullLength { ctx.Repo.CommitID = refName ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetCommit(refName) if err != nil { diff --git a/modules/context/repo.go b/modules/context/repo.go index 71a2b3c0c6ef..d15d28cab783 100644 --- a/modules/context/repo.go +++ b/modules/context/repo.go @@ -817,7 +817,7 @@ func getRefName(ctx *Context, pathType RepoRefType) string { } // For legacy and API support only full commit sha parts := strings.Split(path, "/") - if len(parts) > 0 && len(parts[0]) == 40 { + if len(parts) > 0 && len(parts[0]) == git.SHAFullLength { ctx.Repo.TreePath = strings.Join(parts[1:], "/") return parts[0] } @@ -853,7 +853,7 @@ func getRefName(ctx *Context, pathType RepoRefType) string { return getRefNameFromPath(ctx, path, ctx.Repo.GitRepo.IsTagExist) case RepoRefCommit: parts := strings.Split(path, "/") - if len(parts) > 0 && len(parts[0]) >= 7 && len(parts[0]) <= 40 { + if len(parts) > 0 && len(parts[0]) >= 7 && len(parts[0]) <= git.SHAFullLength { ctx.Repo.TreePath = strings.Join(parts[1:], "/") return parts[0] } @@ -962,7 +962,7 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context return } ctx.Repo.CommitID = ctx.Repo.Commit.ID.String() - } else if len(refName) >= 7 && len(refName) <= 40 { + } else if len(refName) >= 7 && len(refName) <= git.SHAFullLength { ctx.Repo.IsViewCommit = true ctx.Repo.CommitID = refName @@ -972,7 +972,7 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context return } // If short commit ID add canonical link header - if len(refName) < 40 { + if len(refName) < git.SHAFullLength { ctx.RespHeader().Set("Link", fmt.Sprintf("<%s>; rel=\"canonical\"", util.URLJoin(setting.AppURL, strings.Replace(ctx.Req.URL.RequestURI(), util.PathEscapeSegments(refName), url.PathEscape(ctx.Repo.Commit.ID.String()), 1)))) } diff --git a/modules/git/repo_commit_gogit.go b/modules/git/repo_commit_gogit.go index b6c42a802f0d..72de158e6e11 100644 --- a/modules/git/repo_commit_gogit.go +++ b/modules/git/repo_commit_gogit.go @@ -41,7 +41,7 @@ func (repo *Repository) RemoveReference(name string) error { // ConvertToSHA1 returns a Hash object from a potential ID string func (repo *Repository) ConvertToSHA1(commitID string) (SHA1, error) { - if len(commitID) == 40 { + if len(commitID) == SHAFullLength { sha1, err := NewIDFromString(commitID) if err == nil { return sha1, nil diff --git a/modules/git/repo_commit_nogogit.go b/modules/git/repo_commit_nogogit.go index 35a705fea30f..7373d01c8efb 100644 --- a/modules/git/repo_commit_nogogit.go +++ b/modules/git/repo_commit_nogogit.go @@ -137,7 +137,7 @@ func (repo *Repository) getCommitFromBatchReader(rd *bufio.Reader, id SHA1) (*Co // ConvertToSHA1 returns a Hash object from a potential ID string func (repo *Repository) ConvertToSHA1(commitID string) (SHA1, error) { - if len(commitID) == 40 && IsValidSHAPattern(commitID) { + if len(commitID) == SHAFullLength && IsValidSHAPattern(commitID) { sha1, err := NewIDFromString(commitID) if err == nil { return sha1, nil diff --git a/modules/git/repo_index.go b/modules/git/repo_index.go index 99eb2b540b1a..5ff2a2e4fc9d 100644 --- a/modules/git/repo_index.go +++ b/modules/git/repo_index.go @@ -16,7 +16,7 @@ import ( // ReadTreeToIndex reads a treeish to the index func (repo *Repository) ReadTreeToIndex(treeish string, indexFilename ...string) error { - if len(treeish) != 40 { + if len(treeish) != SHAFullLength { res, _, err := NewCommand(repo.Ctx, "rev-parse", "--verify").AddDynamicArguments(treeish).RunStdString(&RunOpts{Dir: repo.Path}) if err != nil { return err diff --git a/modules/git/repo_tree_gogit.go b/modules/git/repo_tree_gogit.go index e0e5e73fa335..a7b1081b15f1 100644 --- a/modules/git/repo_tree_gogit.go +++ b/modules/git/repo_tree_gogit.go @@ -19,7 +19,7 @@ func (repo *Repository) getTree(id SHA1) (*Tree, error) { // GetTree find the tree object in the repository. func (repo *Repository) GetTree(idStr string) (*Tree, error) { - if len(idStr) != 40 { + if len(idStr) != SHAFullLength { res, _, err := NewCommand(repo.Ctx, "rev-parse", "--verify").AddDynamicArguments(idStr).RunStdString(&RunOpts{Dir: repo.Path}) if err != nil { return nil, err diff --git a/modules/git/repo_tree_nogogit.go b/modules/git/repo_tree_nogogit.go index 16ea6bbd8a31..4fd77df2b824 100644 --- a/modules/git/repo_tree_nogogit.go +++ b/modules/git/repo_tree_nogogit.go @@ -66,7 +66,7 @@ func (repo *Repository) getTree(id SHA1) (*Tree, error) { // GetTree find the tree object in the repository. func (repo *Repository) GetTree(idStr string) (*Tree, error) { - if len(idStr) != 40 { + if len(idStr) != SHAFullLength { res, err := repo.GetRefCommitID(idStr) if err != nil { return nil, err diff --git a/modules/git/sha1.go b/modules/git/sha1.go index 3a02484bc23b..4d69653e09ac 100644 --- a/modules/git/sha1.go +++ b/modules/git/sha1.go @@ -17,6 +17,9 @@ const EmptySHA = "0000000000000000000000000000000000000000" // EmptyTreeSHA is the SHA of an empty tree const EmptyTreeSHA = "4b825dc642cb6eb9a060e54bf8d69288fbee4904" +// SHAFullLength is the full length of a git SHA +const SHAFullLength = 40 + // SHAPattern can be used to determine if a string is an valid sha var shaPattern = regexp.MustCompile(`^[0-9a-f]{4,40}$`) @@ -50,7 +53,7 @@ func MustIDFromString(s string) SHA1 { func NewIDFromString(s string) (SHA1, error) { var id SHA1 s = strings.TrimSpace(s) - if len(s) != 40 { + if len(s) != SHAFullLength { return id, fmt.Errorf("Length must be 40: %s", s) } b, err := hex.DecodeString(s) diff --git a/routers/api/v1/repo/status.go b/routers/api/v1/repo/status.go index 0b196d162c27..3202722581ca 100644 --- a/routers/api/v1/repo/status.go +++ b/routers/api/v1/repo/status.go @@ -183,6 +183,7 @@ func getCommitStatuses(ctx *context.APIContext, sha string) { ctx.Error(http.StatusBadRequest, "ref/sha not given", nil) return } + sha = utils.MustConvertToSHA1(ctx.Context, sha) repo := ctx.Repo.Repository listOptions := utils.GetListOptions(ctx) diff --git a/routers/api/v1/utils/git.go b/routers/api/v1/utils/git.go index 2801dee8babe..eaf0f5fd37fc 100644 --- a/routers/api/v1/utils/git.go +++ b/routers/api/v1/utils/git.go @@ -33,6 +33,8 @@ func ResolveRefOrSha(ctx *context.APIContext, ref string) string { } } + sha = MustConvertToSHA1(ctx.Context, sha) + if ctx.Repo.GitRepo != nil { err := ctx.Repo.GitRepo.AddLastCommitCache(ctx.Repo.Repository.GetCommitsCountCacheKey(ref, ref != sha), ctx.Repo.Repository.FullName(), sha) if err != nil { @@ -65,3 +67,30 @@ func searchRefCommitByType(ctx *context.APIContext, refType, filter string) (str } return "", "", nil } + +// ConvertToSHA1 returns a full-length SHA1 from a potential ID string +func ConvertToSHA1(ctx *context.Context, commitID string) (git.SHA1, error) { + if len(commitID) == git.SHAFullLength && git.IsValidSHAPattern(commitID) { + sha1, err := git.NewIDFromString(commitID) + if err == nil { + return sha1, nil + } + } + + gitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, ctx.Repo.Repository.RepoPath()) + if err != nil { + return git.SHA1{}, fmt.Errorf("RepositoryFromContextOrOpen: %w", err) + } + defer closer.Close() + + return gitRepo.ConvertToSHA1(commitID) +} + +// MustConvertToSHA1 returns a full-length SHA1 string from a potential ID string, or returns origin input if it can't convert to SHA1 +func MustConvertToSHA1(ctx *context.Context, commitID string) string { + sha, err := ConvertToSHA1(ctx, commitID) + if err != nil { + return commitID + } + return sha.String() +} diff --git a/routers/web/repo/commit.go b/routers/web/repo/commit.go index efc216661cae..6eda3fca10b3 100644 --- a/routers/web/repo/commit.go +++ b/routers/web/repo/commit.go @@ -283,7 +283,7 @@ func Diff(ctx *context.Context) { } return } - if len(commitID) != 40 { + if len(commitID) != git.SHAFullLength { commitID = commit.ID.String() } diff --git a/services/pull/check.go b/services/pull/check.go index ed4b18107caf..86460cd49cad 100644 --- a/services/pull/check.go +++ b/services/pull/check.go @@ -199,19 +199,19 @@ func getMergeCommit(ctx context.Context, pr *issues_model.PullRequest) (*git.Com return nil, fmt.Errorf("ReadFile(%s): %w", headFile, err) } commitID := string(commitIDBytes) - if len(commitID) < 40 { + if len(commitID) < git.SHAFullLength { return nil, fmt.Errorf(`ReadFile(%s): invalid commit-ID "%s"`, headFile, commitID) } - cmd := commitID[:40] + ".." + pr.BaseBranch + cmd := commitID[:git.SHAFullLength] + ".." + pr.BaseBranch // Get the commit from BaseBranch where the pull request got merged mergeCommit, _, err := git.NewCommand(ctx, "rev-list", "--ancestry-path", "--merges", "--reverse").AddDynamicArguments(cmd). RunStdString(&git.RunOpts{Dir: "", Env: []string{"GIT_INDEX_FILE=" + indexTmpPath, "GIT_DIR=" + pr.BaseRepo.RepoPath()}}) if err != nil { return nil, fmt.Errorf("git rev-list --ancestry-path --merges --reverse: %w", err) - } else if len(mergeCommit) < 40 { + } else if len(mergeCommit) < git.SHAFullLength { // PR was maybe fast-forwarded, so just use last commit of PR - mergeCommit = commitID[:40] + mergeCommit = commitID[:git.SHAFullLength] } gitRepo, err := git.OpenRepository(ctx, pr.BaseRepo.RepoPath()) @@ -220,9 +220,9 @@ func getMergeCommit(ctx context.Context, pr *issues_model.PullRequest) (*git.Com } defer gitRepo.Close() - commit, err := gitRepo.GetCommit(mergeCommit[:40]) + commit, err := gitRepo.GetCommit(mergeCommit[:git.SHAFullLength]) if err != nil { - return nil, fmt.Errorf("GetMergeCommit[%v]: %w", mergeCommit[:40], err) + return nil, fmt.Errorf("GetMergeCommit[%v]: %w", mergeCommit[:git.SHAFullLength], err) } return commit, nil diff --git a/services/pull/merge.go b/services/pull/merge.go index 1c42c1c17b8b..41ba45c17762 100644 --- a/services/pull/merge.go +++ b/services/pull/merge.go @@ -839,7 +839,7 @@ func MergedManually(pr *issues_model.PullRequest, doer *user_model.User, baseGit return models.ErrInvalidMergeStyle{ID: pr.BaseRepo.ID, Style: repo_model.MergeStyleManuallyMerged} } - if len(commitID) < 40 { + if len(commitID) < git.SHAFullLength { return fmt.Errorf("Wrong commit ID") } diff --git a/services/pull/temp_repo.go b/services/pull/temp_repo.go index 842719467f36..d49a15cea00a 100644 --- a/services/pull/temp_repo.go +++ b/services/pull/temp_repo.go @@ -166,7 +166,7 @@ func createTemporaryRepo(ctx context.Context, pr *issues_model.PullRequest) (str var headBranch string if pr.Flow == issues_model.PullRequestFlowGithub { headBranch = git.BranchPrefix + pr.HeadBranch - } else if len(pr.HeadCommitID) == 40 { // for not created pull request + } else if len(pr.HeadCommitID) == git.SHAFullLength { // for not created pull request headBranch = pr.HeadCommitID } else { headBranch = pr.GetGitRefName() diff --git a/services/repository/files/commit.go b/services/repository/files/commit.go index c49b03d60854..74f9eb868d00 100644 --- a/services/repository/files/commit.go +++ b/services/repository/files/commit.go @@ -29,9 +29,12 @@ func CreateCommitStatus(ctx context.Context, repo *repo_model.Repository, creato } defer closer.Close() - if _, err := gitRepo.GetCommit(sha); err != nil { + if commit, err := gitRepo.GetCommit(sha); err != nil { gitRepo.Close() return fmt.Errorf("GetCommit[%s]: %w", sha, err) + } else if len(sha) != git.SHAFullLength { + // use complete commit sha + sha = commit.ID.String() } gitRepo.Close() diff --git a/services/repository/files/tree.go b/services/repository/files/tree.go index 1aa6d0df36de..f4304ea6306e 100644 --- a/services/repository/files/tree.go +++ b/services/repository/files/tree.go @@ -49,7 +49,7 @@ func GetTreeBySHA(ctx context.Context, repo *repo_model.Repository, gitRepo *git copy(treeURL[apiURLLen:], "/git/trees/") // 40 is the size of the sha1 hash in hexadecimal format. - copyPos := len(treeURL) - 40 + copyPos := len(treeURL) - git.SHAFullLength if perPage <= 0 || perPage > setting.API.DefaultGitTreesPerPage { perPage = setting.API.DefaultGitTreesPerPage diff --git a/tests/integration/repo_commits_test.go b/tests/integration/repo_commits_test.go index 0d794cec757b..ab90e72877e5 100644 --- a/tests/integration/repo_commits_test.go +++ b/tests/integration/repo_commits_test.go @@ -68,6 +68,11 @@ func doTestRepoCommitWithStatus(t *testing.T, state string, classes ...string) { reqOne := NewRequest(t, "GET", "/api/v1/repos/user2/repo1/commits/"+path.Base(commitURL)+"/status") testRepoCommitsWithStatus(t, session.MakeRequest(t, req, http.StatusOK), session.MakeRequest(t, reqOne, http.StatusOK), state) + // By short SHA + req = NewRequest(t, "GET", "/api/v1/repos/user2/repo1/commits/"+path.Base(commitURL)[:10]+"/statuses") + reqOne = NewRequest(t, "GET", "/api/v1/repos/user2/repo1/commits/"+path.Base(commitURL)[:10]+"/status") + testRepoCommitsWithStatus(t, session.MakeRequest(t, req, http.StatusOK), session.MakeRequest(t, reqOne, http.StatusOK), state) + // By Ref req = NewRequest(t, "GET", "/api/v1/repos/user2/repo1/commits/master/statuses") reqOne = NewRequest(t, "GET", "/api/v1/repos/user2/repo1/commits/master/status") From d0c3d0ba2688ce13e62bd5522446e0f49a70df50 Mon Sep 17 00:00:00 2001 From: Christian Ullrich Date: Tue, 27 Dec 2022 16:38:15 +0100 Subject: [PATCH 08/23] Add the 'ui.user' section to the cheat sheet (#22249) The `ui.user` ini section with its single setting is not yet mentioned in the config cheat sheet. Co-authored-by: Lunny Xiao --- docs/content/doc/advanced/config-cheat-sheet.en-us.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/content/doc/advanced/config-cheat-sheet.en-us.md b/docs/content/doc/advanced/config-cheat-sheet.en-us.md index c2d5ae266709..9d7a375ad361 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.en-us.md +++ b/docs/content/doc/advanced/config-cheat-sheet.en-us.md @@ -239,6 +239,10 @@ The following configuration set `Content-Type: application/vnd.android.package-a - `NOTICE_PAGING_NUM`: **25**: Number of notices that are shown in one page. - `ORG_PAGING_NUM`: **50**: Number of organizations that are shown in one page. +### UI - User (`ui.user`) + +- `REPO_PAGING_NUM`: **15**: Number of repos that are shown in one page. + ### UI - Metadata (`ui.meta`) - `AUTHOR`: **Gitea - Git with a cup of tea**: Author meta tag of the homepage. From 22a6e9759739af05a862fb5098aec0659aed2e84 Mon Sep 17 00:00:00 2001 From: Yarden Shoham Date: Tue, 27 Dec 2022 19:51:23 +0200 Subject: [PATCH 09/23] Update standard copyright header to use a placeholder year (#22254) --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index bd5672643a67..fbf2a331dd48 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -441,7 +441,7 @@ be reviewed by two maintainers and must pass the automatic tests. Code that you contribute should use the standard copyright header: ``` -// Copyright 2022 The Gitea Authors. All rights reserved. +// Copyright The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT ``` From 7cc7db73b922143a1288d26b39eee9e8e59f7106 Mon Sep 17 00:00:00 2001 From: Xinyu Zhou Date: Wed, 28 Dec 2022 05:21:14 +0800 Subject: [PATCH 10/23] Add option to prohibit fork if user reached maximum limit of repositories (#21848) If user has reached the maximum limit of repositories: - Before - disallow create - allow fork without limit - This patch: - disallow create - disallow fork - Add option `ALLOW_FORK_WITHOUT_MAXIMUM_LIMIT` (Default **true**) : enable this allow user fork repositories without maximum number limit fixed https://github.com/go-gitea/gitea/issues/21847 Signed-off-by: Xinyu Zhou --- custom/conf/app.example.ini | 3 +++ .../doc/advanced/config-cheat-sheet.en-us.md | 1 + models/user/user.go | 9 +++++++++ modules/setting/repository.go | 2 ++ routers/api/v1/repo/fork.go | 2 +- routers/web/repo/pull.go | 13 +++++++++++++ services/repository/fork.go | 7 +++++++ services/repository/fork_test.go | 16 ++++++++++++++++ templates/repo/pulls/fork.tmpl | 2 +- 9 files changed, 53 insertions(+), 2 deletions(-) diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index 754eab452ff9..cec5e8cf0382 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -957,6 +957,9 @@ ROUTER = console ;; Don't allow download source archive files from UI ;DISABLE_DOWNLOAD_SOURCE_ARCHIVES = false +;; Allow fork repositories without maximum number limit +;ALLOW_FORK_WITHOUT_MAXIMUM_LIMIT = true + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;[repository.editor] diff --git a/docs/content/doc/advanced/config-cheat-sheet.en-us.md b/docs/content/doc/advanced/config-cheat-sheet.en-us.md index 9d7a375ad361..3ccef3130cac 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.en-us.md +++ b/docs/content/doc/advanced/config-cheat-sheet.en-us.md @@ -112,6 +112,7 @@ In addition there is _`StaticRootPath`_ which can be set as a built-in at build - `ALLOW_ADOPTION_OF_UNADOPTED_REPOSITORIES`: **false**: Allow non-admin users to adopt unadopted repositories - `ALLOW_DELETION_OF_UNADOPTED_REPOSITORIES`: **false**: Allow non-admin users to delete unadopted repositories - `DISABLE_DOWNLOAD_SOURCE_ARCHIVES`: **false**: Don't allow download source archive files from UI +- `ALLOW_FORK_WITHOUT_MAXIMUM_LIMIT`: **true**: Allow fork repositories without maximum number limit ### Repository - Editor (`repository.editor`) diff --git a/models/user/user.go b/models/user/user.go index 71b036b06f10..825223201b67 100644 --- a/models/user/user.go +++ b/models/user/user.go @@ -275,6 +275,15 @@ func (u *User) CanEditGitHook() bool { return !setting.DisableGitHooks && (u.IsAdmin || u.AllowGitHook) } +// CanForkRepo returns if user login can fork a repository +// It checks especially that the user can create repos, and potentially more +func (u *User) CanForkRepo() bool { + if setting.Repository.AllowForkWithoutMaximumLimit { + return true + } + return u.CanCreateRepo() +} + // CanImportLocal returns true if user can migrate repository by local path. func (u *User) CanImportLocal() bool { if !setting.ImportLocalPaths || u == nil { diff --git a/modules/setting/repository.go b/modules/setting/repository.go index ea288d2ed29d..d78b63a1f3f7 100644 --- a/modules/setting/repository.go +++ b/modules/setting/repository.go @@ -48,6 +48,7 @@ var ( AllowAdoptionOfUnadoptedRepositories bool AllowDeleteOfUnadoptedRepositories bool DisableDownloadSourceArchives bool + AllowForkWithoutMaximumLimit bool // Repository editor settings Editor struct { @@ -160,6 +161,7 @@ var ( DisableMigrations: false, DisableStars: false, DefaultBranch: "main", + AllowForkWithoutMaximumLimit: true, // Repository editor settings Editor: struct { diff --git a/routers/api/v1/repo/fork.go b/routers/api/v1/repo/fork.go index f2cd10e711af..97c1dc7ba7fc 100644 --- a/routers/api/v1/repo/fork.go +++ b/routers/api/v1/repo/fork.go @@ -141,7 +141,7 @@ func CreateFork(ctx *context.APIContext) { Description: repo.Description, }) if err != nil { - if repo_model.IsErrRepoAlreadyExist(err) { + if repo_model.IsErrReachLimitOfRepo(err) || repo_model.IsErrRepoAlreadyExist(err) { ctx.Error(http.StatusConflict, "ForkRepository", err) } else { ctx.Error(http.StatusInternalServerError, "ForkRepository", err) diff --git a/routers/web/repo/pull.go b/routers/web/repo/pull.go index bea6bfe433c1..8929a183ee7e 100644 --- a/routers/web/repo/pull.go +++ b/routers/web/repo/pull.go @@ -182,6 +182,15 @@ func getForkRepository(ctx *context.Context) *repo_model.Repository { func Fork(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("new_fork") + if ctx.Doer.CanForkRepo() { + ctx.Data["CanForkRepo"] = true + } else { + maxCreationLimit := ctx.Doer.MaxCreationLimit() + msg := ctx.TrN(maxCreationLimit, "repo.form.reach_limit_of_creation_1", "repo.form.reach_limit_of_creation_n", maxCreationLimit) + ctx.Data["Flash"] = ctx.Flash + ctx.Flash.Error(msg) + } + getForkRepository(ctx) if ctx.Written() { return @@ -254,6 +263,10 @@ func ForkPost(ctx *context.Context) { if err != nil { ctx.Data["Err_RepoName"] = true switch { + case repo_model.IsErrReachLimitOfRepo(err): + maxCreationLimit := ctxUser.MaxCreationLimit() + msg := ctx.TrN(maxCreationLimit, "repo.form.reach_limit_of_creation_1", "repo.form.reach_limit_of_creation_n", maxCreationLimit) + ctx.RenderWithErr(msg, tplFork, &form) case repo_model.IsErrRepoAlreadyExist(err): ctx.RenderWithErr(ctx.Tr("repo.settings.new_owner_has_same_repo"), tplFork, &form) case db.IsErrNameReserved(err): diff --git a/services/repository/fork.go b/services/repository/fork.go index 3ed0f4ffa516..ad534be887f1 100644 --- a/services/repository/fork.go +++ b/services/repository/fork.go @@ -51,6 +51,13 @@ type ForkRepoOptions struct { // ForkRepository forks a repository func ForkRepository(ctx context.Context, doer, owner *user_model.User, opts ForkRepoOptions) (*repo_model.Repository, error) { + // Fork is prohibited, if user has reached maximum limit of repositories + if !owner.CanForkRepo() { + return nil, repo_model.ErrReachLimitOfRepo{ + Limit: owner.MaxRepoCreation, + } + } + forkedRepo, err := repo_model.GetUserFork(ctx, opts.BaseRepo.ID, owner.ID) if err != nil { return nil, err diff --git a/services/repository/fork_test.go b/services/repository/fork_test.go index c809ed4529ce..452798b25b49 100644 --- a/services/repository/fork_test.go +++ b/services/repository/fork_test.go @@ -10,6 +10,7 @@ import ( "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/setting" "github.com/stretchr/testify/assert" ) @@ -29,4 +30,19 @@ func TestForkRepository(t *testing.T) { assert.Nil(t, fork) assert.Error(t, err) assert.True(t, IsErrForkAlreadyExist(err)) + + // user not reached maximum limit of repositories + assert.False(t, repo_model.IsErrReachLimitOfRepo(err)) + + // change AllowForkWithoutMaximumLimit to false for the test + setting.Repository.AllowForkWithoutMaximumLimit = false + // user has reached maximum limit of repositories + user.MaxRepoCreation = 0 + fork2, err := ForkRepository(git.DefaultContext, user, user, ForkRepoOptions{ + BaseRepo: repo, + Name: "test", + Description: "test", + }) + assert.Nil(t, fork2) + assert.True(t, repo_model.IsErrReachLimitOfRepo(err)) } diff --git a/templates/repo/pulls/fork.tmpl b/templates/repo/pulls/fork.tmpl index 28ba8e2e2527..4e20642cf612 100644 --- a/templates/repo/pulls/fork.tmpl +++ b/templates/repo/pulls/fork.tmpl @@ -58,7 +58,7 @@
-
From ca67c5a8a72f3d26bb0808ba7a63cd4875cd5229 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Wed, 28 Dec 2022 13:53:28 +0800 Subject: [PATCH 11/23] refactor auth interface to return error when verify failure (#22119) This PR changed the Auth interface signature from `Verify(http *http.Request, w http.ResponseWriter, store DataStore, sess SessionStore) *user_model.User` to `Verify(http *http.Request, w http.ResponseWriter, store DataStore, sess SessionStore) (*user_model.User, error)`. There is a new return argument `error` which means the verification condition matched but verify process failed, we should stop the auth process. Before this PR, when return a `nil` user, we don't know the reason why it returned `nil`. If the match condition is not satisfied or it verified failure? For these two different results, we should have different handler. If the match condition is not satisfied, we should try next auth method and if there is no more auth method, it's an anonymous user. If the condition matched but verify failed, the auth process should be stop and return immediately. This will fix #20563 Co-authored-by: KN4CK3R Co-authored-by: Jason Song --- modules/context/api.go | 8 +++++++- modules/context/context.go | 8 +++++++- routers/api/packages/api.go | 17 +++++++++++++++-- routers/api/packages/conan/auth.go | 10 +++++----- routers/api/packages/container/auth.go | 12 ++++++------ routers/api/packages/nuget/auth.go | 9 +++++---- services/auth/basic.go | 22 +++++++++++----------- services/auth/group.go | 17 ++++++++--------- services/auth/httpsign.go | 14 +++++++------- services/auth/interface.go | 5 +++-- services/auth/oauth2.go | 14 +++++--------- services/auth/reverseproxy.go | 19 +++++++++++-------- services/auth/session.go | 6 +++--- services/auth/sspi_windows.go | 18 +++++++++--------- services/packages/auth.go | 11 +++++++++-- 15 files changed, 111 insertions(+), 79 deletions(-) diff --git a/modules/context/api.go b/modules/context/api.go index 1349f91ec0fb..3f52c54d4cfd 100644 --- a/modules/context/api.go +++ b/modules/context/api.go @@ -219,7 +219,13 @@ func (ctx *APIContext) CheckForOTP() { func APIAuth(authMethod auth_service.Method) func(*APIContext) { return func(ctx *APIContext) { // Get user from session if logged in. - ctx.Doer = authMethod.Verify(ctx.Req, ctx.Resp, ctx, ctx.Session) + var err error + ctx.Doer, err = authMethod.Verify(ctx.Req, ctx.Resp, ctx, ctx.Session) + if err != nil { + ctx.Error(http.StatusUnauthorized, "APIAuth", err) + return + } + if ctx.Doer != nil { if ctx.Locale.Language() != ctx.Doer.Language { ctx.Locale = middleware.Locale(ctx.Resp, ctx.Req) diff --git a/modules/context/context.go b/modules/context/context.go index 0fe00bf787e3..6273093060a1 100644 --- a/modules/context/context.go +++ b/modules/context/context.go @@ -662,7 +662,13 @@ func getCsrfOpts() CsrfOptions { // Auth converts auth.Auth as a middleware func Auth(authMethod auth.Method) func(*Context) { return func(ctx *Context) { - ctx.Doer = authMethod.Verify(ctx.Req, ctx.Resp, ctx, ctx.Session) + var err error + ctx.Doer, err = authMethod.Verify(ctx.Req, ctx.Resp, ctx, ctx.Session) + if err != nil { + log.Error("Failed to verify user %v: %v", ctx.Req.RemoteAddr, err) + ctx.Error(http.StatusUnauthorized, "Verify") + return + } if ctx.Doer != nil { if ctx.Locale.Language() != ctx.Doer.Language { ctx.Locale = middleware.Locale(ctx.Resp, ctx.Req) diff --git a/routers/api/packages/api.go b/routers/api/packages/api.go index b523725c4895..78eb5e860be2 100644 --- a/routers/api/packages/api.go +++ b/routers/api/packages/api.go @@ -11,6 +11,7 @@ import ( "code.gitea.io/gitea/models/perm" "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/packages/composer" @@ -58,7 +59,13 @@ func CommonRoutes(ctx gocontext.Context) *web.Route { authGroup := auth.NewGroup(authMethods...) r.Use(func(ctx *context.Context) { - ctx.Doer = authGroup.Verify(ctx.Req, ctx.Resp, ctx, ctx.Session) + var err error + ctx.Doer, err = authGroup.Verify(ctx.Req, ctx.Resp, ctx, ctx.Session) + if err != nil { + log.Error("Verify: %v", err) + ctx.Error(http.StatusUnauthorized, "authGroup.Verify") + return + } ctx.IsSigned = ctx.Doer != nil }) @@ -321,7 +328,13 @@ func ContainerRoutes(ctx gocontext.Context) *web.Route { authGroup := auth.NewGroup(authMethods...) r.Use(func(ctx *context.Context) { - ctx.Doer = authGroup.Verify(ctx.Req, ctx.Resp, ctx, ctx.Session) + var err error + ctx.Doer, err = authGroup.Verify(ctx.Req, ctx.Resp, ctx, ctx.Session) + if err != nil { + log.Error("Failed to verify user: %v", err) + ctx.Error(http.StatusUnauthorized, "Verify") + return + } ctx.IsSigned = ctx.Doer != nil }) diff --git a/routers/api/packages/conan/auth.go b/routers/api/packages/conan/auth.go index f3adaf7beee6..ca02d61e7615 100644 --- a/routers/api/packages/conan/auth.go +++ b/routers/api/packages/conan/auth.go @@ -19,22 +19,22 @@ func (a *Auth) Name() string { } // Verify extracts the user from the Bearer token -func (a *Auth) Verify(req *http.Request, w http.ResponseWriter, store auth.DataStore, sess auth.SessionStore) *user_model.User { +func (a *Auth) Verify(req *http.Request, w http.ResponseWriter, store auth.DataStore, sess auth.SessionStore) (*user_model.User, error) { uid, err := packages.ParseAuthorizationToken(req) if err != nil { log.Trace("ParseAuthorizationToken: %v", err) - return nil + return nil, err } if uid == 0 { - return nil + return nil, nil } u, err := user_model.GetUserByID(req.Context(), uid) if err != nil { log.Error("GetUserByID: %v", err) - return nil + return nil, err } - return u + return u, nil } diff --git a/routers/api/packages/container/auth.go b/routers/api/packages/container/auth.go index e134f74c8f27..33f439ec3e58 100644 --- a/routers/api/packages/container/auth.go +++ b/routers/api/packages/container/auth.go @@ -20,25 +20,25 @@ func (a *Auth) Name() string { // Verify extracts the user from the Bearer token // If it's an anonymous session a ghost user is returned -func (a *Auth) Verify(req *http.Request, w http.ResponseWriter, store auth.DataStore, sess auth.SessionStore) *user_model.User { +func (a *Auth) Verify(req *http.Request, w http.ResponseWriter, store auth.DataStore, sess auth.SessionStore) (*user_model.User, error) { uid, err := packages.ParseAuthorizationToken(req) if err != nil { log.Trace("ParseAuthorizationToken: %v", err) - return nil + return nil, err } if uid == 0 { - return nil + return nil, nil } if uid == -1 { - return user_model.NewGhostUser() + return user_model.NewGhostUser(), nil } u, err := user_model.GetUserByID(req.Context(), uid) if err != nil { log.Error("GetUserByID: %v", err) - return nil + return nil, err } - return u + return u, nil } diff --git a/routers/api/packages/nuget/auth.go b/routers/api/packages/nuget/auth.go index 890c93018409..54b33d89c0a8 100644 --- a/routers/api/packages/nuget/auth.go +++ b/routers/api/packages/nuget/auth.go @@ -20,19 +20,20 @@ func (a *Auth) Name() string { } // https://docs.microsoft.com/en-us/nuget/api/package-publish-resource#request-parameters -func (a *Auth) Verify(req *http.Request, w http.ResponseWriter, store auth.DataStore, sess auth.SessionStore) *user_model.User { +func (a *Auth) Verify(req *http.Request, w http.ResponseWriter, store auth.DataStore, sess auth.SessionStore) (*user_model.User, error) { token, err := auth_model.GetAccessTokenBySHA(req.Header.Get("X-NuGet-ApiKey")) if err != nil { if !(auth_model.IsErrAccessTokenNotExist(err) || auth_model.IsErrAccessTokenEmpty(err)) { log.Error("GetAccessTokenBySHA: %v", err) + return nil, err } - return nil + return nil, nil } u, err := user_model.GetUserByID(req.Context(), token.UID) if err != nil { log.Error("GetUserByID: %v", err) - return nil + return nil, err } token.UpdatedUnix = timeutil.TimeStampNow() @@ -40,5 +41,5 @@ func (a *Auth) Verify(req *http.Request, w http.ResponseWriter, store auth.DataS log.Error("UpdateAccessToken: %v", err) } - return u + return u, nil } diff --git a/services/auth/basic.go b/services/auth/basic.go index 839aaa7a4ed6..5fb80703ab5a 100644 --- a/services/auth/basic.go +++ b/services/auth/basic.go @@ -40,20 +40,20 @@ func (b *Basic) Name() string { // "Authorization" header of the request and returns the corresponding user object for that // name/token on successful validation. // Returns nil if header is empty or validation fails. -func (b *Basic) Verify(req *http.Request, w http.ResponseWriter, store DataStore, sess SessionStore) *user_model.User { +func (b *Basic) Verify(req *http.Request, w http.ResponseWriter, store DataStore, sess SessionStore) (*user_model.User, error) { // Basic authentication should only fire on API, Download or on Git or LFSPaths if !middleware.IsAPIPath(req) && !isContainerPath(req) && !isAttachmentDownload(req) && !isGitRawReleaseOrLFSPath(req) { - return nil + return nil, nil } baHead := req.Header.Get("Authorization") if len(baHead) == 0 { - return nil + return nil, nil } auths := strings.SplitN(baHead, " ", 2) if len(auths) != 2 || (strings.ToLower(auths[0]) != "basic") { - return nil + return nil, nil } uname, passwd, _ := base.BasicAuthDecode(auths[1]) @@ -77,11 +77,11 @@ func (b *Basic) Verify(req *http.Request, w http.ResponseWriter, store DataStore u, err := user_model.GetUserByID(req.Context(), uid) if err != nil { log.Error("GetUserByID: %v", err) - return nil + return nil, err } store.GetData()["IsApiToken"] = true - return u + return u, nil } token, err := auth_model.GetAccessTokenBySHA(authToken) @@ -90,7 +90,7 @@ func (b *Basic) Verify(req *http.Request, w http.ResponseWriter, store DataStore u, err := user_model.GetUserByID(req.Context(), token.UID) if err != nil { log.Error("GetUserByID: %v", err) - return nil + return nil, err } token.UpdatedUnix = timeutil.TimeStampNow() @@ -99,13 +99,13 @@ func (b *Basic) Verify(req *http.Request, w http.ResponseWriter, store DataStore } store.GetData()["IsApiToken"] = true - return u + return u, nil } else if !auth_model.IsErrAccessTokenNotExist(err) && !auth_model.IsErrAccessTokenEmpty(err) { log.Error("GetAccessTokenBySha: %v", err) } if !setting.Service.EnableBasicAuth { - return nil + return nil, nil } log.Trace("Basic Authorization: Attempting SignIn for %s", uname) @@ -114,7 +114,7 @@ func (b *Basic) Verify(req *http.Request, w http.ResponseWriter, store DataStore if !user_model.IsErrUserNotExist(err) { log.Error("UserSignIn: %v", err) } - return nil + return nil, err } if skipper, ok := source.Cfg.(LocalTwoFASkipper); ok && skipper.IsSkipLocalTwoFA() { @@ -123,5 +123,5 @@ func (b *Basic) Verify(req *http.Request, w http.ResponseWriter, store DataStore log.Trace("Basic Authorization: Logged in user %-v", u) - return u + return u, nil } diff --git a/services/auth/group.go b/services/auth/group.go index a9112029c54c..0a0330b3aa95 100644 --- a/services/auth/group.go +++ b/services/auth/group.go @@ -9,7 +9,6 @@ import ( "reflect" "strings" - "code.gitea.io/gitea/models/db" user_model "code.gitea.io/gitea/models/user" ) @@ -80,23 +79,23 @@ func (b *Group) Free() error { } // Verify extracts and validates -func (b *Group) Verify(req *http.Request, w http.ResponseWriter, store DataStore, sess SessionStore) *user_model.User { - if !db.HasEngine { - return nil - } - +func (b *Group) Verify(req *http.Request, w http.ResponseWriter, store DataStore, sess SessionStore) (*user_model.User, error) { // Try to sign in with each of the enabled plugins for _, ssoMethod := range b.methods { - user := ssoMethod.Verify(req, w, store, sess) + user, err := ssoMethod.Verify(req, w, store, sess) + if err != nil { + return nil, err + } + if user != nil { if store.GetData()["AuthedMethod"] == nil { if named, ok := ssoMethod.(Named); ok { store.GetData()["AuthedMethod"] = named.Name() } } - return user + return user, nil } } - return nil + return nil, nil } diff --git a/services/auth/httpsign.go b/services/auth/httpsign.go index e73db4f24807..4d52315381c3 100644 --- a/services/auth/httpsign.go +++ b/services/auth/httpsign.go @@ -39,10 +39,10 @@ func (h *HTTPSign) Name() string { // Verify extracts and validates HTTPsign from the Signature header of the request and returns // the corresponding user object on successful validation. // Returns nil if header is empty or validation fails. -func (h *HTTPSign) Verify(req *http.Request, w http.ResponseWriter, store DataStore, sess SessionStore) *user_model.User { +func (h *HTTPSign) Verify(req *http.Request, w http.ResponseWriter, store DataStore, sess SessionStore) (*user_model.User, error) { sigHead := req.Header.Get("Signature") if len(sigHead) == 0 { - return nil + return nil, nil } var ( @@ -53,14 +53,14 @@ func (h *HTTPSign) Verify(req *http.Request, w http.ResponseWriter, store DataSt if len(req.Header.Get("X-Ssh-Certificate")) != 0 { // Handle Signature signed by SSH certificates if len(setting.SSH.TrustedUserCAKeys) == 0 { - return nil + return nil, nil } publicKey, err = VerifyCert(req) if err != nil { log.Debug("VerifyCert on request from %s: failed: %v", req.RemoteAddr, err) log.Warn("Failed authentication attempt from %s", req.RemoteAddr) - return nil + return nil, nil } } else { // Handle Signature signed by Public Key @@ -68,21 +68,21 @@ func (h *HTTPSign) Verify(req *http.Request, w http.ResponseWriter, store DataSt if err != nil { log.Debug("VerifyPubKey on request from %s: failed: %v", req.RemoteAddr, err) log.Warn("Failed authentication attempt from %s", req.RemoteAddr) - return nil + return nil, nil } } u, err := user_model.GetUserByID(req.Context(), publicKey.OwnerID) if err != nil { log.Error("GetUserByID: %v", err) - return nil + return nil, err } store.GetData()["IsApiToken"] = true log.Trace("HTTP Sign: Logged in user %-v", u) - return u + return u, nil } func VerifyPubKey(r *http.Request) (*asymkey_model.PublicKey, error) { diff --git a/services/auth/interface.go b/services/auth/interface.go index d238a408560b..f2f1aaf39cb0 100644 --- a/services/auth/interface.go +++ b/services/auth/interface.go @@ -24,8 +24,9 @@ type Method interface { // If verification is successful returns either an existing user object (with id > 0) // or a new user object (with id = 0) populated with the information that was found // in the authentication data (username or email). - // Returns nil if verification fails. - Verify(http *http.Request, w http.ResponseWriter, store DataStore, sess SessionStore) *user_model.User + // Second argument returns err if verification fails, otherwise + // First return argument returns nil if no matched verification condition + Verify(http *http.Request, w http.ResponseWriter, store DataStore, sess SessionStore) (*user_model.User, error) } // Initializable represents a structure that requires initialization diff --git a/services/auth/oauth2.go b/services/auth/oauth2.go index 7aea3eadf36d..c0a8250e9547 100644 --- a/services/auth/oauth2.go +++ b/services/auth/oauth2.go @@ -108,18 +108,14 @@ func (o *OAuth2) userIDFromToken(req *http.Request, store DataStore) int64 { // or the "Authorization" header and returns the corresponding user object for that ID. // If verification is successful returns an existing user object. // Returns nil if verification fails. -func (o *OAuth2) Verify(req *http.Request, w http.ResponseWriter, store DataStore, sess SessionStore) *user_model.User { - if !db.HasEngine { - return nil - } - +func (o *OAuth2) Verify(req *http.Request, w http.ResponseWriter, store DataStore, sess SessionStore) (*user_model.User, error) { if !middleware.IsAPIPath(req) && !isAttachmentDownload(req) && !isAuthenticatedTokenRequest(req) { - return nil + return nil, nil } id := o.userIDFromToken(req, store) if id <= 0 { - return nil + return nil, nil } log.Trace("OAuth2 Authorization: Found token for user[%d]", id) @@ -128,11 +124,11 @@ func (o *OAuth2) Verify(req *http.Request, w http.ResponseWriter, store DataStor if !user_model.IsErrUserNotExist(err) { log.Error("GetUserByName: %v", err) } - return nil + return nil, err } log.Trace("OAuth2 Authorization: Logged in user %-v", user) - return user + return user, nil } func isAuthenticatedTokenRequest(req *http.Request) bool { diff --git a/services/auth/reverseproxy.go b/services/auth/reverseproxy.go index 2d5b6611b58c..0206ccdf667d 100644 --- a/services/auth/reverseproxy.go +++ b/services/auth/reverseproxy.go @@ -51,10 +51,10 @@ func (r *ReverseProxy) Name() string { // If a username is available in the "setting.ReverseProxyAuthUser" header an existing // user object is returned (populated with username or email found in header). // Returns nil if header is empty. -func (r *ReverseProxy) getUserFromAuthUser(req *http.Request) *user_model.User { +func (r *ReverseProxy) getUserFromAuthUser(req *http.Request) (*user_model.User, error) { username := r.getUserName(req) if len(username) == 0 { - return nil + return nil, nil } log.Trace("ReverseProxy Authorization: Found username: %s", username) @@ -62,11 +62,11 @@ func (r *ReverseProxy) getUserFromAuthUser(req *http.Request) *user_model.User { if err != nil { if !user_model.IsErrUserNotExist(err) || !r.isAutoRegisterAllowed() { log.Error("GetUserByName: %v", err) - return nil + return nil, err } user = r.newUser(req) } - return user + return user, nil } // getEmail extracts the email from the "setting.ReverseProxyAuthEmail" header @@ -106,12 +106,15 @@ func (r *ReverseProxy) getUserFromAuthEmail(req *http.Request) *user_model.User // First it will attempt to load it based on the username (see docs for getUserFromAuthUser), // and failing that it will attempt to load it based on the email (see docs for getUserFromAuthEmail). // Returns nil if the headers are empty or the user is not found. -func (r *ReverseProxy) Verify(req *http.Request, w http.ResponseWriter, store DataStore, sess SessionStore) *user_model.User { - user := r.getUserFromAuthUser(req) +func (r *ReverseProxy) Verify(req *http.Request, w http.ResponseWriter, store DataStore, sess SessionStore) (*user_model.User, error) { + user, err := r.getUserFromAuthUser(req) + if err != nil { + return nil, err + } if user == nil { user = r.getUserFromAuthEmail(req) if user == nil { - return nil + return nil, nil } } @@ -124,7 +127,7 @@ func (r *ReverseProxy) Verify(req *http.Request, w http.ResponseWriter, store Da store.GetData()["IsReverseProxy"] = true log.Trace("ReverseProxy Authorization: Logged in user %-v", user) - return user + return user, nil } // isAutoRegisterAllowed checks if EnableReverseProxyAutoRegister setting is true diff --git a/services/auth/session.go b/services/auth/session.go index ef2c35d58a19..c75113573810 100644 --- a/services/auth/session.go +++ b/services/auth/session.go @@ -29,12 +29,12 @@ func (s *Session) Name() string { // Verify checks if there is a user uid stored in the session and returns the user // object for that uid. // Returns nil if there is no user uid stored in the session. -func (s *Session) Verify(req *http.Request, w http.ResponseWriter, store DataStore, sess SessionStore) *user_model.User { +func (s *Session) Verify(req *http.Request, w http.ResponseWriter, store DataStore, sess SessionStore) (*user_model.User, error) { user := SessionUser(sess) if user != nil { - return user + return user, nil } - return nil + return nil, nil } // SessionUser returns the user object corresponding to the "uid" session variable. diff --git a/services/auth/sspi_windows.go b/services/auth/sspi_windows.go index 988afb473034..045834b6911a 100644 --- a/services/auth/sspi_windows.go +++ b/services/auth/sspi_windows.go @@ -77,15 +77,15 @@ func (s *SSPI) Free() error { // If authentication is successful, returns the corresponding user object. // If negotiation should continue or authentication fails, immediately returns a 401 HTTP // response code, as required by the SPNEGO protocol. -func (s *SSPI) Verify(req *http.Request, w http.ResponseWriter, store DataStore, sess SessionStore) *user_model.User { +func (s *SSPI) Verify(req *http.Request, w http.ResponseWriter, store DataStore, sess SessionStore) (*user_model.User, error) { if !s.shouldAuthenticate(req) { - return nil + return nil, nil } cfg, err := s.getConfig() if err != nil { log.Error("could not get SSPI config: %v", err) - return nil + return nil, err } log.Trace("SSPI Authorization: Attempting to authenticate") @@ -108,7 +108,7 @@ func (s *SSPI) Verify(req *http.Request, w http.ResponseWriter, store DataStore, log.Error("%v", err) } - return nil + return nil, err } if outToken != "" { sspiAuth.AppendAuthenticateHeader(w, outToken) @@ -116,7 +116,7 @@ func (s *SSPI) Verify(req *http.Request, w http.ResponseWriter, store DataStore, username := sanitizeUsername(userInfo.Username, cfg) if len(username) == 0 { - return nil + return nil, nil } log.Info("Authenticated as %s\n", username) @@ -124,16 +124,16 @@ func (s *SSPI) Verify(req *http.Request, w http.ResponseWriter, store DataStore, if err != nil { if !user_model.IsErrUserNotExist(err) { log.Error("GetUserByName: %v", err) - return nil + return nil, err } if !cfg.AutoCreateUsers { log.Error("User '%s' not found", username) - return nil + return nil, nil } user, err = s.newUser(username, cfg) if err != nil { log.Error("CreateUser: %v", err) - return nil + return nil, err } } @@ -143,7 +143,7 @@ func (s *SSPI) Verify(req *http.Request, w http.ResponseWriter, store DataStore, } log.Trace("SSPI Authorization: Logged in user %-v", user) - return user + return user, nil } // getConfig retrieves the SSPI configuration from login sources diff --git a/services/packages/auth.go b/services/packages/auth.go index 9b84ac79a6c3..a7acdaf1c3a9 100644 --- a/services/packages/auth.go +++ b/services/packages/auth.go @@ -10,6 +10,7 @@ import ( "time" user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "github.com/golang-jwt/jwt/v4" @@ -41,9 +42,15 @@ func CreateAuthorizationToken(u *user_model.User) (string, error) { } func ParseAuthorizationToken(req *http.Request) (int64, error) { - parts := strings.SplitN(req.Header.Get("Authorization"), " ", 2) + h := req.Header.Get("Authorization") + if h == "" { + return 0, nil + } + + parts := strings.SplitN(h, " ", 2) if len(parts) != 2 { - return 0, fmt.Errorf("no token") + log.Error("split token failed: %s", h) + return 0, fmt.Errorf("split token failed") } token, err := jwt.ParseWithClaims(parts[1], &packageClaims{}, func(t *jwt.Token) (interface{}, error) { From 309e86a9bf305e807ead2854fa757c4d704dcfce Mon Sep 17 00:00:00 2001 From: KN4CK3R Date: Thu, 29 Dec 2022 00:31:54 +0100 Subject: [PATCH 12/23] Use dynamic package type list (#22263) Replace the hardcoded list with the dynamic list. --- routers/web/admin/packages.go | 1 + routers/web/repo/packages.go | 1 + routers/web/user/package.go | 1 + templates/admin/packages/list.tmpl | 15 +++------------ templates/package/shared/list.tmpl | 15 +++------------ 5 files changed, 9 insertions(+), 24 deletions(-) diff --git a/routers/web/admin/packages.go b/routers/web/admin/packages.go index 80cec51275cf..7c6d1ed840f5 100644 --- a/routers/web/admin/packages.go +++ b/routers/web/admin/packages.go @@ -62,6 +62,7 @@ func Packages(ctx *context.Context) { ctx.Data["PageIsAdminPackages"] = true ctx.Data["Query"] = query ctx.Data["PackageType"] = packageType + ctx.Data["AvailableTypes"] = packages_model.TypeList ctx.Data["SortType"] = sort ctx.Data["PackageDescriptors"] = pds ctx.Data["Total"] = total diff --git a/routers/web/repo/packages.go b/routers/web/repo/packages.go index 83324711da72..6ad2f71b5c2d 100644 --- a/routers/web/repo/packages.go +++ b/routers/web/repo/packages.go @@ -61,6 +61,7 @@ func Packages(ctx *context.Context) { ctx.Data["ContextUser"] = ctx.ContextUser ctx.Data["Query"] = query ctx.Data["PackageType"] = packageType + ctx.Data["AvailableTypes"] = packages.TypeList ctx.Data["HasPackages"] = hasPackages if ctx.Repo != nil { ctx.Data["CanWritePackages"] = ctx.IsUserRepoWriter([]unit.Type{unit.TypePackages}) || ctx.IsUserSiteAdmin() diff --git a/routers/web/user/package.go b/routers/web/user/package.go index 3782f46b4242..c0aba7583fc0 100644 --- a/routers/web/user/package.go +++ b/routers/web/user/package.go @@ -89,6 +89,7 @@ func ListPackages(ctx *context.Context) { ctx.Data["ContextUser"] = ctx.ContextUser ctx.Data["Query"] = query ctx.Data["PackageType"] = packageType + ctx.Data["AvailableTypes"] = packages_model.TypeList ctx.Data["HasPackages"] = hasPackages ctx.Data["PackageDescriptors"] = pds ctx.Data["Total"] = total diff --git a/templates/admin/packages/list.tmpl b/templates/admin/packages/list.tmpl index 3aab2873c6b7..c39f5fc12881 100644 --- a/templates/admin/packages/list.tmpl +++ b/templates/admin/packages/list.tmpl @@ -13,18 +13,9 @@ diff --git a/templates/package/shared/list.tmpl b/templates/package/shared/list.tmpl index 37c47cef335d..ec2e88c8541d 100644 --- a/templates/package/shared/list.tmpl +++ b/templates/package/shared/list.tmpl @@ -6,18 +6,9 @@ From a35749893b91db48310d91ae0a32fee3ad3bb901 Mon Sep 17 00:00:00 2001 From: KN4CK3R Date: Thu, 29 Dec 2022 03:57:15 +0100 Subject: [PATCH 13/23] Move `convert` package to services (#22264) Addition to #22256 The `convert` package relies heavily on different models which is [disallowed by our definition of modules](https://github.com/go-gitea/gitea/blob/main/CONTRIBUTING.md#design-guideline). This helps to prevent possible import cycles. Co-authored-by: Lunny Xiao --- cmd/dump_repo.go | 2 +- modules/eventsource/manager_run.go | 2 +- modules/notification/webhook/webhook.go | 2 +- routers/api/packages/composer/composer.go | 2 +- routers/api/v1/admin/org.go | 2 +- routers/api/v1/admin/user.go | 2 +- routers/api/v1/notify/repo.go | 2 +- routers/api/v1/notify/threads.go | 2 +- routers/api/v1/notify/user.go | 2 +- routers/api/v1/org/hook.go | 2 +- routers/api/v1/org/label.go | 2 +- routers/api/v1/org/member.go | 2 +- routers/api/v1/org/org.go | 2 +- routers/api/v1/org/team.go | 2 +- routers/api/v1/packages/package.go | 2 +- routers/api/v1/repo/branch.go | 2 +- routers/api/v1/repo/collaborators.go | 2 +- routers/api/v1/repo/commits.go | 2 +- routers/api/v1/repo/fork.go | 2 +- routers/api/v1/repo/git_hook.go | 2 +- routers/api/v1/repo/hook.go | 2 +- routers/api/v1/repo/issue.go | 2 +- routers/api/v1/repo/issue_attachment.go | 2 +- routers/api/v1/repo/issue_comment.go | 2 +- routers/api/v1/repo/issue_comment_attachment.go | 2 +- routers/api/v1/repo/issue_label.go | 2 +- routers/api/v1/repo/issue_reaction.go | 2 +- routers/api/v1/repo/issue_stopwatch.go | 2 +- routers/api/v1/repo/issue_subscription.go | 2 +- routers/api/v1/repo/issue_tracked_time.go | 2 +- routers/api/v1/repo/key.go | 2 +- routers/api/v1/repo/label.go | 2 +- routers/api/v1/repo/migrate.go | 2 +- routers/api/v1/repo/milestone.go | 2 +- routers/api/v1/repo/mirror.go | 2 +- routers/api/v1/repo/notes.go | 2 +- routers/api/v1/repo/pull.go | 2 +- routers/api/v1/repo/pull_review.go | 2 +- routers/api/v1/repo/release.go | 2 +- routers/api/v1/repo/release_attachment.go | 2 +- routers/api/v1/repo/release_tags.go | 2 +- routers/api/v1/repo/repo.go | 2 +- routers/api/v1/repo/star.go | 2 +- routers/api/v1/repo/status.go | 2 +- routers/api/v1/repo/subscriber.go | 2 +- routers/api/v1/repo/tag.go | 2 +- routers/api/v1/repo/teams.go | 2 +- routers/api/v1/repo/topic.go | 2 +- routers/api/v1/repo/transfer.go | 2 +- routers/api/v1/repo/wiki.go | 2 +- routers/api/v1/user/app.go | 2 +- routers/api/v1/user/email.go | 2 +- routers/api/v1/user/follower.go | 2 +- routers/api/v1/user/gpg_key.go | 2 +- routers/api/v1/user/key.go | 2 +- routers/api/v1/user/repo.go | 2 +- routers/api/v1/user/settings.go | 2 +- routers/api/v1/user/star.go | 2 +- routers/api/v1/user/user.go | 2 +- routers/api/v1/user/watch.go | 2 +- routers/api/v1/utils/hook.go | 2 +- routers/api/v1/utils/page.go | 2 +- routers/web/explore/topic.go | 2 +- routers/web/org/teams.go | 2 +- routers/web/repo/issue.go | 2 +- routers/web/repo/repo.go | 2 +- routers/web/repo/webhook.go | 2 +- routers/web/user/search.go | 2 +- routers/web/user/stop_watch.go | 2 +- {modules => services}/convert/attachment.go | 0 {modules => services}/convert/convert.go | 0 {modules => services}/convert/git_commit.go | 0 {modules => services}/convert/git_commit_test.go | 0 {modules => services}/convert/issue.go | 0 {modules => services}/convert/issue_comment.go | 0 {modules => services}/convert/issue_test.go | 0 {modules => services}/convert/main_test.go | 0 {modules => services}/convert/mirror.go | 0 {modules => services}/convert/notification.go | 0 {modules => services}/convert/package.go | 0 {modules => services}/convert/pull.go | 0 {modules => services}/convert/pull_review.go | 0 {modules => services}/convert/pull_test.go | 0 {modules => services}/convert/release.go | 0 {modules => services}/convert/repository.go | 0 {modules => services}/convert/status.go | 0 {modules => services}/convert/user.go | 0 {modules => services}/convert/user_test.go | 0 {modules => services}/convert/utils.go | 0 {modules => services}/convert/utils_test.go | 0 {modules => services}/convert/wiki.go | 0 services/lfs/locks.go | 2 +- tests/integration/api_comment_attachment_test.go | 2 +- tests/integration/api_comment_test.go | 2 +- tests/integration/api_issue_reaction_test.go | 2 +- tests/integration/api_team_test.go | 2 +- tests/integration/api_team_user_test.go | 2 +- 97 files changed, 75 insertions(+), 75 deletions(-) rename {modules => services}/convert/attachment.go (100%) rename {modules => services}/convert/convert.go (100%) rename {modules => services}/convert/git_commit.go (100%) rename {modules => services}/convert/git_commit_test.go (100%) rename {modules => services}/convert/issue.go (100%) rename {modules => services}/convert/issue_comment.go (100%) rename {modules => services}/convert/issue_test.go (100%) rename {modules => services}/convert/main_test.go (100%) rename {modules => services}/convert/mirror.go (100%) rename {modules => services}/convert/notification.go (100%) rename {modules => services}/convert/package.go (100%) rename {modules => services}/convert/pull.go (100%) rename {modules => services}/convert/pull_review.go (100%) rename {modules => services}/convert/pull_test.go (100%) rename {modules => services}/convert/release.go (100%) rename {modules => services}/convert/repository.go (100%) rename {modules => services}/convert/status.go (100%) rename {modules => services}/convert/user.go (100%) rename {modules => services}/convert/user_test.go (100%) rename {modules => services}/convert/utils.go (100%) rename {modules => services}/convert/utils_test.go (100%) rename {modules => services}/convert/wiki.go (100%) diff --git a/cmd/dump_repo.go b/cmd/dump_repo.go index 2e78877afed2..b7b9b3ccc734 100644 --- a/cmd/dump_repo.go +++ b/cmd/dump_repo.go @@ -10,13 +10,13 @@ import ( "os" "strings" - "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" base "code.gitea.io/gitea/modules/migration" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/services/convert" "code.gitea.io/gitea/services/migrations" "github.com/urfave/cli" diff --git a/modules/eventsource/manager_run.go b/modules/eventsource/manager_run.go index 97d08aa8a87e..35dfc62f1ed9 100644 --- a/modules/eventsource/manager_run.go +++ b/modules/eventsource/manager_run.go @@ -9,13 +9,13 @@ import ( activities_model "code.gitea.io/gitea/models/activities" issues_model "code.gitea.io/gitea/models/issues" - "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/process" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" + "code.gitea.io/gitea/services/convert" ) // Init starts this eventsource diff --git a/modules/notification/webhook/webhook.go b/modules/notification/webhook/webhook.go index cf056f54c138..97d5e04340d9 100644 --- a/modules/notification/webhook/webhook.go +++ b/modules/notification/webhook/webhook.go @@ -14,13 +14,13 @@ import ( "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/models/webhook" - "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/notification/base" "code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/services/convert" webhook_services "code.gitea.io/gitea/services/webhook" ) diff --git a/routers/api/packages/composer/composer.go b/routers/api/packages/composer/composer.go index c6e0593b42f5..58571fff14d0 100644 --- a/routers/api/packages/composer/composer.go +++ b/routers/api/packages/composer/composer.go @@ -14,12 +14,12 @@ import ( "code.gitea.io/gitea/models/db" packages_model "code.gitea.io/gitea/models/packages" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" packages_module "code.gitea.io/gitea/modules/packages" composer_module "code.gitea.io/gitea/modules/packages/composer" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/api/packages/helper" + "code.gitea.io/gitea/services/convert" packages_service "code.gitea.io/gitea/services/packages" "github.com/hashicorp/go-version" diff --git a/routers/api/v1/admin/org.go b/routers/api/v1/admin/org.go index 9d0725e3e85d..ff6624418442 100644 --- a/routers/api/v1/admin/org.go +++ b/routers/api/v1/admin/org.go @@ -11,10 +11,10 @@ import ( "code.gitea.io/gitea/models/organization" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/convert" ) // CreateOrg api for create organization diff --git a/routers/api/v1/admin/user.go b/routers/api/v1/admin/user.go index 183ade8a0a5e..6b48ce4a9d4d 100644 --- a/routers/api/v1/admin/user.go +++ b/routers/api/v1/admin/user.go @@ -16,7 +16,6 @@ import ( "code.gitea.io/gitea/models/db" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/password" "code.gitea.io/gitea/modules/setting" @@ -26,6 +25,7 @@ import ( "code.gitea.io/gitea/routers/api/v1/user" "code.gitea.io/gitea/routers/api/v1/utils" asymkey_service "code.gitea.io/gitea/services/asymkey" + "code.gitea.io/gitea/services/convert" "code.gitea.io/gitea/services/mailer" user_service "code.gitea.io/gitea/services/user" ) diff --git a/routers/api/v1/notify/repo.go b/routers/api/v1/notify/repo.go index a2e72cb48de0..bd3b86a6f152 100644 --- a/routers/api/v1/notify/repo.go +++ b/routers/api/v1/notify/repo.go @@ -10,9 +10,9 @@ import ( activities_model "code.gitea.io/gitea/models/activities" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/services/convert" ) func statusStringToNotificationStatus(status string) activities_model.NotificationStatus { diff --git a/routers/api/v1/notify/threads.go b/routers/api/v1/notify/threads.go index 47d0e4972143..6a1bce4de41a 100644 --- a/routers/api/v1/notify/threads.go +++ b/routers/api/v1/notify/threads.go @@ -11,7 +11,7 @@ import ( "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" + "code.gitea.io/gitea/services/convert" ) // GetThread get notification by ID diff --git a/routers/api/v1/notify/user.go b/routers/api/v1/notify/user.go index 725eeff017fc..2261610c0923 100644 --- a/routers/api/v1/notify/user.go +++ b/routers/api/v1/notify/user.go @@ -9,8 +9,8 @@ import ( activities_model "code.gitea.io/gitea/models/activities" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/services/convert" ) // ListNotifications list users's notification threads diff --git a/routers/api/v1/org/hook.go b/routers/api/v1/org/hook.go index 2e9d7c656a76..ef08a08be0e4 100644 --- a/routers/api/v1/org/hook.go +++ b/routers/api/v1/org/hook.go @@ -8,10 +8,10 @@ import ( "code.gitea.io/gitea/models/webhook" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/convert" ) // ListHooks list an organziation's webhooks diff --git a/routers/api/v1/org/label.go b/routers/api/v1/org/label.go index c95a6be3d20a..5d0455cdd4f4 100644 --- a/routers/api/v1/org/label.go +++ b/routers/api/v1/org/label.go @@ -11,10 +11,10 @@ import ( issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/convert" ) // ListLabels list all the labels of an organization diff --git a/routers/api/v1/org/member.go b/routers/api/v1/org/member.go index fe071439588e..33c994497803 100644 --- a/routers/api/v1/org/member.go +++ b/routers/api/v1/org/member.go @@ -10,11 +10,11 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/organization" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/routers/api/v1/user" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/convert" ) // listMembers list an organization's members diff --git a/routers/api/v1/org/org.go b/routers/api/v1/org/org.go index cf985d44fbb0..a1b071d4887a 100644 --- a/routers/api/v1/org/org.go +++ b/routers/api/v1/org/org.go @@ -12,11 +12,11 @@ import ( "code.gitea.io/gitea/models/perm" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/user" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/convert" "code.gitea.io/gitea/services/org" ) diff --git a/routers/api/v1/org/team.go b/routers/api/v1/org/team.go index 798b792e71e5..8f87e8276485 100644 --- a/routers/api/v1/org/team.go +++ b/routers/api/v1/org/team.go @@ -15,12 +15,12 @@ import ( repo_model "code.gitea.io/gitea/models/repo" unit_model "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/log" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/user" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/convert" org_service "code.gitea.io/gitea/services/org" ) diff --git a/routers/api/v1/packages/package.go b/routers/api/v1/packages/package.go index 433a79939cc7..6f9083ba327b 100644 --- a/routers/api/v1/packages/package.go +++ b/routers/api/v1/packages/package.go @@ -8,10 +8,10 @@ import ( "code.gitea.io/gitea/models/packages" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/convert" packages_service "code.gitea.io/gitea/services/packages" ) diff --git a/routers/api/v1/repo/branch.go b/routers/api/v1/repo/branch.go index 3060cf24064d..46fcc2fcd366 100644 --- a/routers/api/v1/repo/branch.go +++ b/routers/api/v1/repo/branch.go @@ -14,11 +14,11 @@ import ( "code.gitea.io/gitea/models/organization" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" "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" + "code.gitea.io/gitea/services/convert" pull_service "code.gitea.io/gitea/services/pull" repo_service "code.gitea.io/gitea/services/repository" ) diff --git a/routers/api/v1/repo/collaborators.go b/routers/api/v1/repo/collaborators.go index 202418bd2bec..293778420bc2 100644 --- a/routers/api/v1/repo/collaborators.go +++ b/routers/api/v1/repo/collaborators.go @@ -14,11 +14,11 @@ import ( repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" repo_module "code.gitea.io/gitea/modules/repository" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/convert" ) // ListCollaborators list a repository's collaborators diff --git a/routers/api/v1/repo/commits.go b/routers/api/v1/repo/commits.go index 682044407dfe..68a92ca2a840 100644 --- a/routers/api/v1/repo/commits.go +++ b/routers/api/v1/repo/commits.go @@ -12,11 +12,11 @@ import ( user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/convert" ) // GetSingleCommit get a commit via sha diff --git a/routers/api/v1/repo/fork.go b/routers/api/v1/repo/fork.go index 97c1dc7ba7fc..e4c7eb70414a 100644 --- a/routers/api/v1/repo/fork.go +++ b/routers/api/v1/repo/fork.go @@ -14,10 +14,10 @@ import ( repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/convert" repo_service "code.gitea.io/gitea/services/repository" ) diff --git a/routers/api/v1/repo/git_hook.go b/routers/api/v1/repo/git_hook.go index 963cbc719f42..40bd35542888 100644 --- a/routers/api/v1/repo/git_hook.go +++ b/routers/api/v1/repo/git_hook.go @@ -7,10 +7,10 @@ import ( "net/http" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/git" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/convert" ) // ListGitHooks list all Git hooks of a repository diff --git a/routers/api/v1/repo/hook.go b/routers/api/v1/repo/hook.go index 0c3d59a41938..757ae7247bf7 100644 --- a/routers/api/v1/repo/hook.go +++ b/routers/api/v1/repo/hook.go @@ -10,12 +10,12 @@ import ( "code.gitea.io/gitea/models/perm" "code.gitea.io/gitea/models/webhook" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/convert" webhook_service "code.gitea.io/gitea/services/webhook" ) diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go index 30dc7a68326c..fecb601dd533 100644 --- a/routers/api/v1/repo/issue.go +++ b/routers/api/v1/repo/issue.go @@ -19,7 +19,6 @@ import ( "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" issue_indexer "code.gitea.io/gitea/modules/indexer/issues" "code.gitea.io/gitea/modules/notification" "code.gitea.io/gitea/modules/setting" @@ -28,6 +27,7 @@ import ( "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/convert" issue_service "code.gitea.io/gitea/services/issue" ) diff --git a/routers/api/v1/repo/issue_attachment.go b/routers/api/v1/repo/issue_attachment.go index 4cf108b41378..8cbd2e11b699 100644 --- a/routers/api/v1/repo/issue_attachment.go +++ b/routers/api/v1/repo/issue_attachment.go @@ -9,12 +9,12 @@ import ( issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/services/attachment" + "code.gitea.io/gitea/services/convert" issue_service "code.gitea.io/gitea/services/issue" ) diff --git a/routers/api/v1/repo/issue_comment.go b/routers/api/v1/repo/issue_comment.go index 9097004186f4..40c92998d19c 100644 --- a/routers/api/v1/repo/issue_comment.go +++ b/routers/api/v1/repo/issue_comment.go @@ -14,10 +14,10 @@ import ( repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/convert" issue_service "code.gitea.io/gitea/services/issue" ) diff --git a/routers/api/v1/repo/issue_comment_attachment.go b/routers/api/v1/repo/issue_comment_attachment.go index 2198a6a33d51..4c8452380f03 100644 --- a/routers/api/v1/repo/issue_comment_attachment.go +++ b/routers/api/v1/repo/issue_comment_attachment.go @@ -9,12 +9,12 @@ import ( issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/services/attachment" + "code.gitea.io/gitea/services/convert" issue_service "code.gitea.io/gitea/services/issue" ) diff --git a/routers/api/v1/repo/issue_label.go b/routers/api/v1/repo/issue_label.go index 04d70913c7a6..1f0d21141bcc 100644 --- a/routers/api/v1/repo/issue_label.go +++ b/routers/api/v1/repo/issue_label.go @@ -9,9 +9,9 @@ import ( issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/convert" issue_service "code.gitea.io/gitea/services/issue" ) diff --git a/routers/api/v1/repo/issue_reaction.go b/routers/api/v1/repo/issue_reaction.go index dcfe7967b58e..1b998a535424 100644 --- a/routers/api/v1/repo/issue_reaction.go +++ b/routers/api/v1/repo/issue_reaction.go @@ -9,10 +9,10 @@ import ( issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/convert" ) // GetIssueCommentReactions list reactions of a comment from an issue diff --git a/routers/api/v1/repo/issue_stopwatch.go b/routers/api/v1/repo/issue_stopwatch.go index 110139cc36b6..9ab3c61deb4f 100644 --- a/routers/api/v1/repo/issue_stopwatch.go +++ b/routers/api/v1/repo/issue_stopwatch.go @@ -9,8 +9,8 @@ import ( issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/convert" ) // StartIssueStopwatch creates a stopwatch for the given issue. diff --git a/routers/api/v1/repo/issue_subscription.go b/routers/api/v1/repo/issue_subscription.go index 32832d83f79a..6d22c82652ef 100644 --- a/routers/api/v1/repo/issue_subscription.go +++ b/routers/api/v1/repo/issue_subscription.go @@ -10,9 +10,9 @@ import ( issues_model "code.gitea.io/gitea/models/issues" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/convert" ) // AddIssueSubscription Subscribe user to issue diff --git a/routers/api/v1/repo/issue_tracked_time.go b/routers/api/v1/repo/issue_tracked_time.go index ede60a2ed810..16bb8cb73d6c 100644 --- a/routers/api/v1/repo/issue_tracked_time.go +++ b/routers/api/v1/repo/issue_tracked_time.go @@ -13,10 +13,10 @@ import ( "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/convert" ) // ListTrackedTimes list all the tracked times of an issue diff --git a/routers/api/v1/repo/key.go b/routers/api/v1/repo/key.go index 54313e8e764f..d496c4a73c11 100644 --- a/routers/api/v1/repo/key.go +++ b/routers/api/v1/repo/key.go @@ -15,12 +15,12 @@ import ( "code.gitea.io/gitea/models/perm" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" asymkey_service "code.gitea.io/gitea/services/asymkey" + "code.gitea.io/gitea/services/convert" ) // appendPrivateInformation appends the owner and key type information to api.PublicKey diff --git a/routers/api/v1/repo/label.go b/routers/api/v1/repo/label.go index 8b49becd37bb..411c0274e6c7 100644 --- a/routers/api/v1/repo/label.go +++ b/routers/api/v1/repo/label.go @@ -12,10 +12,10 @@ import ( issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/convert" ) // ListLabels list all the labels of a repository diff --git a/routers/api/v1/repo/migrate.go b/routers/api/v1/repo/migrate.go index 35516ff58f36..09e857b5fcfe 100644 --- a/routers/api/v1/repo/migrate.go +++ b/routers/api/v1/repo/migrate.go @@ -17,7 +17,6 @@ import ( repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/graceful" "code.gitea.io/gitea/modules/lfs" "code.gitea.io/gitea/modules/log" @@ -28,6 +27,7 @@ import ( api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/convert" "code.gitea.io/gitea/services/forms" "code.gitea.io/gitea/services/migrations" ) diff --git a/routers/api/v1/repo/milestone.go b/routers/api/v1/repo/milestone.go index 2b80b4df7345..b77fe8aca8a9 100644 --- a/routers/api/v1/repo/milestone.go +++ b/routers/api/v1/repo/milestone.go @@ -11,11 +11,11 @@ import ( issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/convert" ) // ListMilestones list milestones for a repository diff --git a/routers/api/v1/repo/mirror.go b/routers/api/v1/repo/mirror.go index b693c0e7db46..5fce5a4a803f 100644 --- a/routers/api/v1/repo/mirror.go +++ b/routers/api/v1/repo/mirror.go @@ -14,13 +14,13 @@ import ( repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" mirror_module "code.gitea.io/gitea/modules/mirror" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/convert" "code.gitea.io/gitea/services/forms" "code.gitea.io/gitea/services/migrations" mirror_service "code.gitea.io/gitea/services/mirror" diff --git a/routers/api/v1/repo/notes.go b/routers/api/v1/repo/notes.go index 91eebb4c724d..8eaa503ff7cc 100644 --- a/routers/api/v1/repo/notes.go +++ b/routers/api/v1/repo/notes.go @@ -8,9 +8,9 @@ import ( "net/http" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/git" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/services/convert" ) // GetNote Get a note corresponding to a single commit from a repository diff --git a/routers/api/v1/repo/pull.go b/routers/api/v1/repo/pull.go index ed23b267f287..300357e1ec24 100644 --- a/routers/api/v1/repo/pull.go +++ b/routers/api/v1/repo/pull.go @@ -21,7 +21,6 @@ import ( "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/notification" @@ -32,6 +31,7 @@ import ( "code.gitea.io/gitea/routers/api/v1/utils" asymkey_service "code.gitea.io/gitea/services/asymkey" "code.gitea.io/gitea/services/automerge" + "code.gitea.io/gitea/services/convert" "code.gitea.io/gitea/services/forms" "code.gitea.io/gitea/services/gitdiff" issue_service "code.gitea.io/gitea/services/issue" diff --git a/routers/api/v1/repo/pull_review.go b/routers/api/v1/repo/pull_review.go index 2f357afb79f7..96dc1fc2dee1 100644 --- a/routers/api/v1/repo/pull_review.go +++ b/routers/api/v1/repo/pull_review.go @@ -13,11 +13,11 @@ import ( access_model "code.gitea.io/gitea/models/perm/access" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" "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" + "code.gitea.io/gitea/services/convert" issue_service "code.gitea.io/gitea/services/issue" pull_service "code.gitea.io/gitea/services/pull" ) diff --git a/routers/api/v1/repo/release.go b/routers/api/v1/repo/release.go index 4e1927ea3d92..d0b20102f7a4 100644 --- a/routers/api/v1/repo/release.go +++ b/routers/api/v1/repo/release.go @@ -11,10 +11,10 @@ import ( repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/convert" release_service "code.gitea.io/gitea/services/release" ) diff --git a/routers/api/v1/repo/release_attachment.go b/routers/api/v1/repo/release_attachment.go index e7dbb42c7411..5aaea693c03b 100644 --- a/routers/api/v1/repo/release_attachment.go +++ b/routers/api/v1/repo/release_attachment.go @@ -8,13 +8,13 @@ import ( repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/upload" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/services/attachment" + "code.gitea.io/gitea/services/convert" ) // GetReleaseAttachment gets a single attachment of the release diff --git a/routers/api/v1/repo/release_tags.go b/routers/api/v1/repo/release_tags.go index 5e1f1860ae77..7cc846fdc443 100644 --- a/routers/api/v1/repo/release_tags.go +++ b/routers/api/v1/repo/release_tags.go @@ -9,7 +9,7 @@ import ( "code.gitea.io/gitea/models" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" + "code.gitea.io/gitea/services/convert" releaseservice "code.gitea.io/gitea/services/release" ) diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go index 349040507810..e0cae5f82c7a 100644 --- a/routers/api/v1/repo/repo.go +++ b/routers/api/v1/repo/repo.go @@ -18,7 +18,6 @@ import ( unit_model "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" repo_module "code.gitea.io/gitea/modules/repository" @@ -28,6 +27,7 @@ import ( "code.gitea.io/gitea/modules/validation" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/convert" repo_service "code.gitea.io/gitea/services/repository" ) diff --git a/routers/api/v1/repo/star.go b/routers/api/v1/repo/star.go index a3d110587390..c7b2eb01ff65 100644 --- a/routers/api/v1/repo/star.go +++ b/routers/api/v1/repo/star.go @@ -8,9 +8,9 @@ import ( repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/convert" ) // ListStargazers list a repository's stargazers diff --git a/routers/api/v1/repo/status.go b/routers/api/v1/repo/status.go index 3202722581ca..19f57b1cea98 100644 --- a/routers/api/v1/repo/status.go +++ b/routers/api/v1/repo/status.go @@ -9,10 +9,10 @@ import ( git_model "code.gitea.io/gitea/models/git" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/convert" files_service "code.gitea.io/gitea/services/repository/files" ) diff --git a/routers/api/v1/repo/subscriber.go b/routers/api/v1/repo/subscriber.go index 5cc94abd487f..6cd369898eba 100644 --- a/routers/api/v1/repo/subscriber.go +++ b/routers/api/v1/repo/subscriber.go @@ -8,9 +8,9 @@ import ( repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/convert" ) // ListSubscribers list a repo's subscribers (i.e. watchers) diff --git a/routers/api/v1/repo/tag.go b/routers/api/v1/repo/tag.go index 6b38a08c2f7b..cb65e2b651b0 100644 --- a/routers/api/v1/repo/tag.go +++ b/routers/api/v1/repo/tag.go @@ -11,10 +11,10 @@ import ( "code.gitea.io/gitea/models" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/convert" releaseservice "code.gitea.io/gitea/services/release" ) diff --git a/routers/api/v1/repo/teams.go b/routers/api/v1/repo/teams.go index 1ea3ae0008a8..eafe4236ec3a 100644 --- a/routers/api/v1/repo/teams.go +++ b/routers/api/v1/repo/teams.go @@ -10,7 +10,7 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/organization" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" + "code.gitea.io/gitea/services/convert" org_service "code.gitea.io/gitea/services/org" ) diff --git a/routers/api/v1/repo/topic.go b/routers/api/v1/repo/topic.go index 316b19025986..7d27fe7d25a0 100644 --- a/routers/api/v1/repo/topic.go +++ b/routers/api/v1/repo/topic.go @@ -9,11 +9,11 @@ import ( repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/log" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/convert" ) // ListTopics returns list of current topics for repo diff --git a/routers/api/v1/repo/transfer.go b/routers/api/v1/repo/transfer.go index 5154c5afa3cb..aec398da7a41 100644 --- a/routers/api/v1/repo/transfer.go +++ b/routers/api/v1/repo/transfer.go @@ -13,10 +13,10 @@ import ( repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/log" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/convert" repo_service "code.gitea.io/gitea/services/repository" ) diff --git a/routers/api/v1/repo/wiki.go b/routers/api/v1/repo/wiki.go index 0b55a9b2818f..764530a671e6 100644 --- a/routers/api/v1/repo/wiki.go +++ b/routers/api/v1/repo/wiki.go @@ -11,13 +11,13 @@ import ( repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/notification" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/convert" wiki_service "code.gitea.io/gitea/services/wiki" ) diff --git a/routers/api/v1/user/app.go b/routers/api/v1/user/app.go index 6cb7b812b233..7b2f0d8c30d2 100644 --- a/routers/api/v1/user/app.go +++ b/routers/api/v1/user/app.go @@ -12,10 +12,10 @@ import ( auth_model "code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/convert" ) // ListAccessTokens list all the access tokens diff --git a/routers/api/v1/user/email.go b/routers/api/v1/user/email.go index 84823aaed207..fc74c8d14846 100644 --- a/routers/api/v1/user/email.go +++ b/routers/api/v1/user/email.go @@ -9,10 +9,10 @@ import ( user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/convert" ) // ListEmails list all of the authenticated user's email addresses diff --git a/routers/api/v1/user/follower.go b/routers/api/v1/user/follower.go index 38ddf990c47e..e9d4ae478b3d 100644 --- a/routers/api/v1/user/follower.go +++ b/routers/api/v1/user/follower.go @@ -9,9 +9,9 @@ import ( user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/convert" ) func responseAPIUsers(ctx *context.APIContext, users []*user_model.User) { diff --git a/routers/api/v1/user/gpg_key.go b/routers/api/v1/user/gpg_key.go index 7c91d2ac6563..84327cc92a43 100644 --- a/routers/api/v1/user/gpg_key.go +++ b/routers/api/v1/user/gpg_key.go @@ -11,10 +11,10 @@ import ( asymkey_model "code.gitea.io/gitea/models/asymkey" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/convert" ) func listGPGKeys(ctx *context.APIContext, uid int64, listOptions db.ListOptions) { diff --git a/routers/api/v1/user/key.go b/routers/api/v1/user/key.go index 25bda0444a54..8aad69884fd8 100644 --- a/routers/api/v1/user/key.go +++ b/routers/api/v1/user/key.go @@ -11,13 +11,13 @@ import ( "code.gitea.io/gitea/models/perm" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/api/v1/repo" "code.gitea.io/gitea/routers/api/v1/utils" asymkey_service "code.gitea.io/gitea/services/asymkey" + "code.gitea.io/gitea/services/convert" ) // appendPrivateInformation appends the owner and key type information to api.PublicKey diff --git a/routers/api/v1/user/repo.go b/routers/api/v1/user/repo.go index e79a9d8f8b1d..d566c072fba7 100644 --- a/routers/api/v1/user/repo.go +++ b/routers/api/v1/user/repo.go @@ -11,9 +11,9 @@ import ( repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/convert" ) // listUserRepos - List the repositories owned by the given user. diff --git a/routers/api/v1/user/settings.go b/routers/api/v1/user/settings.go index 89bfd83efc15..53794c82f838 100644 --- a/routers/api/v1/user/settings.go +++ b/routers/api/v1/user/settings.go @@ -8,9 +8,9 @@ import ( user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/convert" ) // GetUserSettings returns user settings diff --git a/routers/api/v1/user/star.go b/routers/api/v1/user/star.go index 0475489640ec..ad5a8bee33be 100644 --- a/routers/api/v1/user/star.go +++ b/routers/api/v1/user/star.go @@ -13,9 +13,9 @@ import ( repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/convert" ) // getStarredRepos returns the repos that the user with the specified userID has diff --git a/routers/api/v1/user/user.go b/routers/api/v1/user/user.go index 8a21c2c7cacd..55f3df40b9cc 100644 --- a/routers/api/v1/user/user.go +++ b/routers/api/v1/user/user.go @@ -10,8 +10,8 @@ import ( activities_model "code.gitea.io/gitea/models/activities" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/convert" ) // Search search users diff --git a/routers/api/v1/user/watch.go b/routers/api/v1/user/watch.go index 707e5da0903b..211f36459a83 100644 --- a/routers/api/v1/user/watch.go +++ b/routers/api/v1/user/watch.go @@ -12,9 +12,9 @@ import ( repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/routers/api/v1/utils" + "code.gitea.io/gitea/services/convert" ) // getWatchedRepos returns the repos that the user with the specified userID is watching diff --git a/routers/api/v1/utils/hook.go b/routers/api/v1/utils/hook.go index 7faf609ae813..1a27ececfe1c 100644 --- a/routers/api/v1/utils/hook.go +++ b/routers/api/v1/utils/hook.go @@ -10,10 +10,10 @@ import ( "code.gitea.io/gitea/models/webhook" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/json" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" + "code.gitea.io/gitea/services/convert" webhook_service "code.gitea.io/gitea/services/webhook" ) diff --git a/routers/api/v1/utils/page.go b/routers/api/v1/utils/page.go index ef5806fa9218..6910b8293196 100644 --- a/routers/api/v1/utils/page.go +++ b/routers/api/v1/utils/page.go @@ -6,7 +6,7 @@ package utils import ( "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" + "code.gitea.io/gitea/services/convert" ) // GetListOptions returns list options using the page and limit parameters diff --git a/routers/web/explore/topic.go b/routers/web/explore/topic.go index 50df9d1113e2..e172d9e04d01 100644 --- a/routers/web/explore/topic.go +++ b/routers/web/explore/topic.go @@ -9,8 +9,8 @@ import ( "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/services/convert" ) // TopicSearch search for creating topic diff --git a/routers/web/org/teams.go b/routers/web/org/teams.go index 5dd86fdf117f..d9754633bfd9 100644 --- a/routers/web/org/teams.go +++ b/routers/web/org/teams.go @@ -20,11 +20,11 @@ import ( user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/utils" + "code.gitea.io/gitea/services/convert" "code.gitea.io/gitea/services/forms" org_service "code.gitea.io/gitea/services/org" ) diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go index d315525dac87..79a8b2745aba 100644 --- a/routers/web/repo/issue.go +++ b/routers/web/repo/issue.go @@ -31,7 +31,6 @@ import ( "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/git" issue_indexer "code.gitea.io/gitea/modules/indexer/issues" issue_template "code.gitea.io/gitea/modules/issue/template" @@ -47,6 +46,7 @@ import ( "code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/routers/utils" asymkey_service "code.gitea.io/gitea/services/asymkey" + "code.gitea.io/gitea/services/convert" "code.gitea.io/gitea/services/forms" issue_service "code.gitea.io/gitea/services/issue" pull_service "code.gitea.io/gitea/services/pull" diff --git a/routers/web/repo/repo.go b/routers/web/repo/repo.go index 8856ee662684..f9c67f170bec 100644 --- a/routers/web/repo/repo.go +++ b/routers/web/repo/repo.go @@ -19,7 +19,6 @@ import ( user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/log" repo_module "code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/setting" @@ -27,6 +26,7 @@ import ( api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/convert" "code.gitea.io/gitea/services/forms" repo_service "code.gitea.io/gitea/services/repository" archiver_service "code.gitea.io/gitea/services/repository/archiver" diff --git a/routers/web/repo/webhook.go b/routers/web/repo/webhook.go index 18d71c6435a5..2b6f107fafd1 100644 --- a/routers/web/repo/webhook.go +++ b/routers/web/repo/webhook.go @@ -17,13 +17,13 @@ import ( "code.gitea.io/gitea/models/webhook" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/services/convert" "code.gitea.io/gitea/services/forms" webhook_service "code.gitea.io/gitea/services/webhook" ) diff --git a/routers/web/user/search.go b/routers/web/user/search.go index 093de406a978..f9b0e0735864 100644 --- a/routers/web/user/search.go +++ b/routers/web/user/search.go @@ -9,7 +9,7 @@ import ( "code.gitea.io/gitea/models/db" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" + "code.gitea.io/gitea/services/convert" ) // Search search users diff --git a/routers/web/user/stop_watch.go b/routers/web/user/stop_watch.go index 26c7558c115e..d262c777c30f 100644 --- a/routers/web/user/stop_watch.go +++ b/routers/web/user/stop_watch.go @@ -9,7 +9,7 @@ import ( "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" + "code.gitea.io/gitea/services/convert" ) // GetStopwatches get all stopwatches diff --git a/modules/convert/attachment.go b/services/convert/attachment.go similarity index 100% rename from modules/convert/attachment.go rename to services/convert/attachment.go diff --git a/modules/convert/convert.go b/services/convert/convert.go similarity index 100% rename from modules/convert/convert.go rename to services/convert/convert.go diff --git a/modules/convert/git_commit.go b/services/convert/git_commit.go similarity index 100% rename from modules/convert/git_commit.go rename to services/convert/git_commit.go diff --git a/modules/convert/git_commit_test.go b/services/convert/git_commit_test.go similarity index 100% rename from modules/convert/git_commit_test.go rename to services/convert/git_commit_test.go diff --git a/modules/convert/issue.go b/services/convert/issue.go similarity index 100% rename from modules/convert/issue.go rename to services/convert/issue.go diff --git a/modules/convert/issue_comment.go b/services/convert/issue_comment.go similarity index 100% rename from modules/convert/issue_comment.go rename to services/convert/issue_comment.go diff --git a/modules/convert/issue_test.go b/services/convert/issue_test.go similarity index 100% rename from modules/convert/issue_test.go rename to services/convert/issue_test.go diff --git a/modules/convert/main_test.go b/services/convert/main_test.go similarity index 100% rename from modules/convert/main_test.go rename to services/convert/main_test.go diff --git a/modules/convert/mirror.go b/services/convert/mirror.go similarity index 100% rename from modules/convert/mirror.go rename to services/convert/mirror.go diff --git a/modules/convert/notification.go b/services/convert/notification.go similarity index 100% rename from modules/convert/notification.go rename to services/convert/notification.go diff --git a/modules/convert/package.go b/services/convert/package.go similarity index 100% rename from modules/convert/package.go rename to services/convert/package.go diff --git a/modules/convert/pull.go b/services/convert/pull.go similarity index 100% rename from modules/convert/pull.go rename to services/convert/pull.go diff --git a/modules/convert/pull_review.go b/services/convert/pull_review.go similarity index 100% rename from modules/convert/pull_review.go rename to services/convert/pull_review.go diff --git a/modules/convert/pull_test.go b/services/convert/pull_test.go similarity index 100% rename from modules/convert/pull_test.go rename to services/convert/pull_test.go diff --git a/modules/convert/release.go b/services/convert/release.go similarity index 100% rename from modules/convert/release.go rename to services/convert/release.go diff --git a/modules/convert/repository.go b/services/convert/repository.go similarity index 100% rename from modules/convert/repository.go rename to services/convert/repository.go diff --git a/modules/convert/status.go b/services/convert/status.go similarity index 100% rename from modules/convert/status.go rename to services/convert/status.go diff --git a/modules/convert/user.go b/services/convert/user.go similarity index 100% rename from modules/convert/user.go rename to services/convert/user.go diff --git a/modules/convert/user_test.go b/services/convert/user_test.go similarity index 100% rename from modules/convert/user_test.go rename to services/convert/user_test.go diff --git a/modules/convert/utils.go b/services/convert/utils.go similarity index 100% rename from modules/convert/utils.go rename to services/convert/utils.go diff --git a/modules/convert/utils_test.go b/services/convert/utils_test.go similarity index 100% rename from modules/convert/utils_test.go rename to services/convert/utils_test.go diff --git a/modules/convert/wiki.go b/services/convert/wiki.go similarity index 100% rename from modules/convert/wiki.go rename to services/convert/wiki.go diff --git a/services/lfs/locks.go b/services/lfs/locks.go index 0dc51f063c8f..d5fe3f4e314c 100644 --- a/services/lfs/locks.go +++ b/services/lfs/locks.go @@ -11,12 +11,12 @@ import ( git_model "code.gitea.io/gitea/models/git" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/convert" "code.gitea.io/gitea/modules/json" lfs_module "code.gitea.io/gitea/modules/lfs" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/services/convert" ) func handleLockListOut(ctx *context.Context, repo *repo_model.Repository, lock *git_model.LFSLock, err error) { diff --git a/tests/integration/api_comment_attachment_test.go b/tests/integration/api_comment_attachment_test.go index 22bf502ef6d0..b23db53d2810 100644 --- a/tests/integration/api_comment_attachment_test.go +++ b/tests/integration/api_comment_attachment_test.go @@ -17,8 +17,8 @@ import ( repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/services/convert" "code.gitea.io/gitea/tests" "github.com/stretchr/testify/assert" diff --git a/tests/integration/api_comment_test.go b/tests/integration/api_comment_test.go index edd4da88c11c..fb2d41223e7e 100644 --- a/tests/integration/api_comment_test.go +++ b/tests/integration/api_comment_test.go @@ -14,8 +14,8 @@ import ( repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/services/convert" "code.gitea.io/gitea/tests" "github.com/stretchr/testify/assert" diff --git a/tests/integration/api_issue_reaction_test.go b/tests/integration/api_issue_reaction_test.go index ec239d7627d6..4e2ae3d57dc7 100644 --- a/tests/integration/api_issue_reaction_test.go +++ b/tests/integration/api_issue_reaction_test.go @@ -13,8 +13,8 @@ import ( issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/services/convert" "code.gitea.io/gitea/tests" "github.com/stretchr/testify/assert" diff --git a/tests/integration/api_team_test.go b/tests/integration/api_team_test.go index f54c286fc941..06d47bf70b05 100644 --- a/tests/integration/api_team_test.go +++ b/tests/integration/api_team_test.go @@ -14,8 +14,8 @@ import ( "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/services/convert" "code.gitea.io/gitea/tests" "github.com/stretchr/testify/assert" diff --git a/tests/integration/api_team_user_test.go b/tests/integration/api_team_user_test.go index 78f98680c111..a5078aedccb8 100644 --- a/tests/integration/api_team_user_test.go +++ b/tests/integration/api_team_user_test.go @@ -10,8 +10,8 @@ import ( "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/convert" api "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/services/convert" "code.gitea.io/gitea/tests" "github.com/stretchr/testify/assert" From 47efba78ec966631ccdea3e05a50f4cf59ca9fd3 Mon Sep 17 00:00:00 2001 From: Jason Song Date: Thu, 29 Dec 2022 20:40:20 +0800 Subject: [PATCH 14/23] Support template for merge message description (#22248) Fix #21435. Use the first line of the template as the git commit message title, and the rest as the description. ## Snapshots image image image Co-authored-by: delvh --- routers/api/v1/repo/pull.go | 2 +- routers/web/repo/issue.go | 6 +- routers/web/repo/pull.go | 2 +- services/pull/merge.go | 38 +++++++----- services/pull/merge_test.go | 67 +++++++++++++++++++++ services/pull/pull_test.go | 8 +-- templates/repo/issue/view_content/pull.tmpl | 5 +- 7 files changed, 103 insertions(+), 25 deletions(-) create mode 100644 services/pull/merge_test.go diff --git a/routers/api/v1/repo/pull.go b/routers/api/v1/repo/pull.go index 300357e1ec24..1b1aba17d929 100644 --- a/routers/api/v1/repo/pull.go +++ b/routers/api/v1/repo/pull.go @@ -815,7 +815,7 @@ func MergePullRequest(ctx *context.APIContext) { message := strings.TrimSpace(form.MergeTitleField) if len(message) == 0 { - message, err = pull_service.GetDefaultMergeMessage(ctx, ctx.Repo.GitRepo, pr, repo_model.MergeStyle(form.Do)) + message, _, err = pull_service.GetDefaultMergeMessage(ctx, ctx.Repo.GitRepo, pr, repo_model.MergeStyle(form.Do)) if err != nil { ctx.Error(http.StatusInternalServerError, "GetDefaultMergeMessage", err) return diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go index 79a8b2745aba..100e343de49b 100644 --- a/routers/web/repo/issue.go +++ b/routers/web/repo/issue.go @@ -1664,19 +1664,21 @@ func ViewIssue(ctx *context.Context) { ctx.Data["MergeStyle"] = mergeStyle - defaultMergeMessage, err := pull_service.GetDefaultMergeMessage(ctx, ctx.Repo.GitRepo, pull, mergeStyle) + defaultMergeMessage, defaultMergeBody, err := pull_service.GetDefaultMergeMessage(ctx, ctx.Repo.GitRepo, pull, mergeStyle) if err != nil { ctx.ServerError("GetDefaultMergeMessage", err) return } ctx.Data["DefaultMergeMessage"] = defaultMergeMessage + ctx.Data["DefaultMergeBody"] = defaultMergeBody - defaultSquashMergeMessage, err := pull_service.GetDefaultMergeMessage(ctx, ctx.Repo.GitRepo, pull, repo_model.MergeStyleSquash) + defaultSquashMergeMessage, defaultSquashMergeBody, err := pull_service.GetDefaultMergeMessage(ctx, ctx.Repo.GitRepo, pull, repo_model.MergeStyleSquash) if err != nil { ctx.ServerError("GetDefaultSquashMergeMessage", err) return } ctx.Data["DefaultSquashMergeMessage"] = defaultSquashMergeMessage + ctx.Data["DefaultSquashMergeBody"] = defaultSquashMergeBody if err = pull.LoadProtectedBranch(ctx); err != nil { ctx.ServerError("LoadProtectedBranch", err) diff --git a/routers/web/repo/pull.go b/routers/web/repo/pull.go index 8929a183ee7e..a18f9f6a56a5 100644 --- a/routers/web/repo/pull.go +++ b/routers/web/repo/pull.go @@ -986,7 +986,7 @@ func MergePullRequest(ctx *context.Context) { message := strings.TrimSpace(form.MergeTitleField) if len(message) == 0 { var err error - message, err = pull_service.GetDefaultMergeMessage(ctx, ctx.Repo.GitRepo, pr, repo_model.MergeStyle(form.Do)) + message, _, err = pull_service.GetDefaultMergeMessage(ctx, ctx.Repo.GitRepo, pr, repo_model.MergeStyle(form.Do)) if err != nil { ctx.ServerError("GetDefaultMergeMessage", err) return diff --git a/services/pull/merge.go b/services/pull/merge.go index 41ba45c17762..7a936163f1fe 100644 --- a/services/pull/merge.go +++ b/services/pull/merge.go @@ -39,19 +39,19 @@ import ( ) // GetDefaultMergeMessage returns default message used when merging pull request -func GetDefaultMergeMessage(ctx context.Context, baseGitRepo *git.Repository, pr *issues_model.PullRequest, mergeStyle repo_model.MergeStyle) (string, error) { +func GetDefaultMergeMessage(ctx context.Context, baseGitRepo *git.Repository, pr *issues_model.PullRequest, mergeStyle repo_model.MergeStyle) (message, body string, err error) { if err := pr.LoadHeadRepo(ctx); err != nil { - return "", err + return "", "", err } if err := pr.LoadBaseRepo(ctx); err != nil { - return "", err + return "", "", err } if pr.BaseRepo == nil { - return "", repo_model.ErrRepoNotExist{ID: pr.BaseRepoID} + return "", "", repo_model.ErrRepoNotExist{ID: pr.BaseRepoID} } if err := pr.LoadIssue(ctx); err != nil { - return "", err + return "", "", err } isExternalTracker := pr.BaseRepo.UnitEnabled(ctx, unit.TypeExternalTracker) @@ -64,12 +64,12 @@ func GetDefaultMergeMessage(ctx context.Context, baseGitRepo *git.Repository, pr templateFilepath := fmt.Sprintf(".gitea/default_merge_message/%s_TEMPLATE.md", strings.ToUpper(string(mergeStyle))) commit, err := baseGitRepo.GetBranchCommit(pr.BaseRepo.DefaultBranch) if err != nil { - return "", err + return "", "", err } templateContent, err := commit.GetFileContent(templateFilepath, setting.Repository.PullRequest.DefaultMergeMessageSize) if err != nil { if !git.IsErrNotExist(err) { - return "", err + return "", "", err } } else { vars := map[string]string{ @@ -107,27 +107,35 @@ func GetDefaultMergeMessage(ctx context.Context, baseGitRepo *git.Repository, pr vars["ClosingIssues"] = "" } } - - return os.Expand(templateContent, func(s string) string { - return vars[s] - }), nil + message, body = expandDefaultMergeMessage(templateContent, vars) + return message, body, nil } } // Squash merge has a different from other styles. if mergeStyle == repo_model.MergeStyleSquash { - return fmt.Sprintf("%s (%s%d)", pr.Issue.Title, issueReference, pr.Issue.Index), nil + return fmt.Sprintf("%s (%s%d)", pr.Issue.Title, issueReference, pr.Issue.Index), "", nil } if pr.BaseRepoID == pr.HeadRepoID { - return fmt.Sprintf("Merge pull request '%s' (%s%d) from %s into %s", pr.Issue.Title, issueReference, pr.Issue.Index, pr.HeadBranch, pr.BaseBranch), nil + return fmt.Sprintf("Merge pull request '%s' (%s%d) from %s into %s", pr.Issue.Title, issueReference, pr.Issue.Index, pr.HeadBranch, pr.BaseBranch), "", nil } if pr.HeadRepo == nil { - return fmt.Sprintf("Merge pull request '%s' (%s%d) from :%s into %s", pr.Issue.Title, issueReference, pr.Issue.Index, pr.HeadBranch, pr.BaseBranch), nil + return fmt.Sprintf("Merge pull request '%s' (%s%d) from :%s into %s", pr.Issue.Title, issueReference, pr.Issue.Index, pr.HeadBranch, pr.BaseBranch), "", nil } - return fmt.Sprintf("Merge pull request '%s' (%s%d) from %s:%s into %s", pr.Issue.Title, issueReference, pr.Issue.Index, pr.HeadRepo.FullName(), pr.HeadBranch, pr.BaseBranch), nil + return fmt.Sprintf("Merge pull request '%s' (%s%d) from %s:%s into %s", pr.Issue.Title, issueReference, pr.Issue.Index, pr.HeadRepo.FullName(), pr.HeadBranch, pr.BaseBranch), "", nil +} + +func expandDefaultMergeMessage(template string, vars map[string]string) (message, body string) { + message = strings.TrimSpace(template) + if splits := strings.SplitN(message, "\n", 2); len(splits) == 2 { + message = splits[0] + body = strings.TrimSpace(splits[1]) + } + mapping := func(s string) string { return vars[s] } + return os.Expand(message, mapping), os.Expand(body, mapping) } // Merge merges pull request to base repository. diff --git a/services/pull/merge_test.go b/services/pull/merge_test.go new file mode 100644 index 000000000000..6df6f55d4611 --- /dev/null +++ b/services/pull/merge_test.go @@ -0,0 +1,67 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package pull + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func Test_expandDefaultMergeMessage(t *testing.T) { + type args struct { + template string + vars map[string]string + } + tests := []struct { + name string + args args + want string + wantBody string + }{ + { + name: "single line", + args: args{ + template: "Merge ${PullRequestTitle}", + vars: map[string]string{ + "PullRequestTitle": "PullRequestTitle", + "PullRequestDescription": "Pull\nRequest\nDescription\n", + }, + }, + want: "Merge PullRequestTitle", + wantBody: "", + }, + { + name: "multiple lines", + args: args{ + template: "Merge ${PullRequestTitle}\nDescription:\n\n${PullRequestDescription}\n", + vars: map[string]string{ + "PullRequestTitle": "PullRequestTitle", + "PullRequestDescription": "Pull\nRequest\nDescription\n", + }, + }, + want: "Merge PullRequestTitle", + wantBody: "Description:\n\nPull\nRequest\nDescription\n", + }, + { + name: "leading newlines", + args: args{ + template: "\n\n\nMerge ${PullRequestTitle}\n\n\nDescription:\n\n${PullRequestDescription}\n", + vars: map[string]string{ + "PullRequestTitle": "PullRequestTitle", + "PullRequestDescription": "Pull\nRequest\nDescription\n", + }, + }, + want: "Merge PullRequestTitle", + wantBody: "Description:\n\nPull\nRequest\nDescription\n", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, got1 := expandDefaultMergeMessage(tt.args.template, tt.args.vars) + assert.Equalf(t, tt.want, got, "expandDefaultMergeMessage(%v, %v)", tt.args.template, tt.args.vars) + assert.Equalf(t, tt.wantBody, got1, "expandDefaultMergeMessage(%v, %v)", tt.args.template, tt.args.vars) + }) + } +} diff --git a/services/pull/pull_test.go b/services/pull/pull_test.go index cbbdccce9c07..d63227a7d5e9 100644 --- a/services/pull/pull_test.go +++ b/services/pull/pull_test.go @@ -45,13 +45,13 @@ func TestPullRequest_GetDefaultMergeMessage_InternalTracker(t *testing.T) { assert.NoError(t, err) defer gitRepo.Close() - mergeMessage, err := GetDefaultMergeMessage(db.DefaultContext, gitRepo, pr, "") + mergeMessage, _, err := GetDefaultMergeMessage(db.DefaultContext, gitRepo, pr, "") assert.NoError(t, err) assert.Equal(t, "Merge pull request 'issue3' (#3) from branch2 into master", mergeMessage) pr.BaseRepoID = 1 pr.HeadRepoID = 2 - mergeMessage, err = GetDefaultMergeMessage(db.DefaultContext, gitRepo, pr, "") + mergeMessage, _, err = GetDefaultMergeMessage(db.DefaultContext, gitRepo, pr, "") assert.NoError(t, err) assert.Equal(t, "Merge pull request 'issue3' (#3) from user2/repo1:branch2 into master", mergeMessage) } @@ -75,7 +75,7 @@ func TestPullRequest_GetDefaultMergeMessage_ExternalTracker(t *testing.T) { assert.NoError(t, err) defer gitRepo.Close() - mergeMessage, err := GetDefaultMergeMessage(db.DefaultContext, gitRepo, pr, "") + mergeMessage, _, err := GetDefaultMergeMessage(db.DefaultContext, gitRepo, pr, "") assert.NoError(t, err) assert.Equal(t, "Merge pull request 'issue3' (!3) from branch2 into master", mergeMessage) @@ -84,7 +84,7 @@ func TestPullRequest_GetDefaultMergeMessage_ExternalTracker(t *testing.T) { pr.HeadRepoID = 2 pr.BaseRepo = nil pr.HeadRepo = nil - mergeMessage, err = GetDefaultMergeMessage(db.DefaultContext, gitRepo, pr, "") + mergeMessage, _, err = GetDefaultMergeMessage(db.DefaultContext, gitRepo, pr, "") assert.NoError(t, err) assert.Equal(t, "Merge pull request 'issue3' (#3) from user2/repo2:branch2 into master", mergeMessage) diff --git a/templates/repo/issue/view_content/pull.tmpl b/templates/repo/issue/view_content/pull.tmpl index d68f3e541439..665f78205386 100644 --- a/templates/repo/issue/view_content/pull.tmpl +++ b/templates/repo/issue/view_content/pull.tmpl @@ -343,7 +343,8 @@ (() => { const defaultMergeTitle = {{.DefaultMergeMessage}}; const defaultSquashMergeTitle = {{.DefaultSquashMergeMessage}}; - const defaultMergeMessage = 'Reviewed-on: ' + {{$.Issue.HTMLURL}} + '\n' + {{$approvers}}; + const defaultMergeMessage = {{if .DefaultMergeBody}}{{.DefaultMergeBody}}{{else}}'Reviewed-on: ' + {{$.Issue.HTMLURL}} + '\n' + {{$approvers}}{{end}}; + const defaultSquashMergeMessage = {{if .DefaultSquashMergeBody}}{{.DefaultSquashMergeBody}}{{else}}'Reviewed-on: ' + {{$.Issue.HTMLURL}} + '\n' + {{$approvers}}{{end}}; const mergeForm = { 'baseLink': {{.Link}}, 'textCancel': {{$.locale.Tr "cancel"}}, @@ -398,7 +399,7 @@ 'allowed': {{$prUnit.PullRequestsConfig.AllowSquash}}, 'textDoMerge': {{$.locale.Tr "repo.pulls.squash_merge_pull_request"}}, 'mergeTitleFieldText': defaultSquashMergeTitle, - 'mergeMessageFieldText': {{.GetCommitMessages}} + defaultMergeMessage, + 'mergeMessageFieldText': {{.GetCommitMessages}} + defaultSquashMergeMessage, 'hideAutoMerge': generalHideAutoMerge, }, { From a609cae9fbdda5612da9e2ad84dd9afbcf2028ef Mon Sep 17 00:00:00 2001 From: zeripath Date: Fri, 30 Dec 2022 00:06:47 +0000 Subject: [PATCH 15/23] Correctly handle select on multiple channels in Queues (#22146) There are a few places in FlushQueueWithContext which make an incorrect assumption about how `select` on multiple channels works. The problem is best expressed by looking at the following example: ```go package main import "fmt" func main() { closedChan := make(chan struct{}) close(closedChan) toClose := make(chan struct{}) count := 0 for { select { case <-closedChan: count++ fmt.Println(count) if count == 2 { close(toClose) } case <-toClose: return } } } ``` This PR double-checks that the contexts are closed outside of checking if there is data in the dataChan. It also rationalises the WorkerPool FlushWithContext because the previous implementation failed to handle pausing correctly. This will probably fix the underlying problem in #22145 Fix #22145 Signed-off-by: Andrew Thornton Signed-off-by: Andrew Thornton --- modules/queue/queue_channel.go | 26 ---------------- modules/queue/unique_queue_channel.go | 30 ------------------ modules/queue/workerpool.go | 44 ++++++++++++++++++++++++++- 3 files changed, 43 insertions(+), 57 deletions(-) diff --git a/modules/queue/queue_channel.go b/modules/queue/queue_channel.go index 431f48390c8b..6f75b8357eab 100644 --- a/modules/queue/queue_channel.go +++ b/modules/queue/queue_channel.go @@ -109,32 +109,6 @@ func (q *ChannelQueue) Flush(timeout time.Duration) error { return q.FlushWithContext(ctx) } -// FlushWithContext is very similar to CleanUp but it will return as soon as the dataChan is empty -func (q *ChannelQueue) FlushWithContext(ctx context.Context) error { - log.Trace("ChannelQueue: %d Flush", q.qid) - paused, _ := q.IsPausedIsResumed() - for { - select { - case <-paused: - return nil - case data, ok := <-q.dataChan: - if !ok { - return nil - } - if unhandled := q.handle(data); unhandled != nil { - log.Error("Unhandled Data whilst flushing queue %d", q.qid) - } - atomic.AddInt64(&q.numInQueue, -1) - case <-q.baseCtx.Done(): - return q.baseCtx.Err() - case <-ctx.Done(): - return ctx.Err() - default: - return nil - } - } -} - // Shutdown processing from this queue func (q *ChannelQueue) Shutdown() { q.lock.Lock() diff --git a/modules/queue/unique_queue_channel.go b/modules/queue/unique_queue_channel.go index f2d3dbdc970f..c43bd1db3f7d 100644 --- a/modules/queue/unique_queue_channel.go +++ b/modules/queue/unique_queue_channel.go @@ -8,7 +8,6 @@ import ( "fmt" "runtime/pprof" "sync" - "sync/atomic" "time" "code.gitea.io/gitea/modules/container" @@ -167,35 +166,6 @@ func (q *ChannelUniqueQueue) Flush(timeout time.Duration) error { return q.FlushWithContext(ctx) } -// FlushWithContext is very similar to CleanUp but it will return as soon as the dataChan is empty -func (q *ChannelUniqueQueue) FlushWithContext(ctx context.Context) error { - log.Trace("ChannelUniqueQueue: %d Flush", q.qid) - paused, _ := q.IsPausedIsResumed() - for { - select { - case <-paused: - return nil - default: - } - select { - case data, ok := <-q.dataChan: - if !ok { - return nil - } - if unhandled := q.handle(data); unhandled != nil { - log.Error("Unhandled Data whilst flushing queue %d", q.qid) - } - atomic.AddInt64(&q.numInQueue, -1) - case <-q.baseCtx.Done(): - return q.baseCtx.Err() - case <-ctx.Done(): - return ctx.Err() - default: - return nil - } - } -} - // Shutdown processing from this queue func (q *ChannelUniqueQueue) Shutdown() { log.Trace("ChannelUniqueQueue: %s Shutting down", q.name) diff --git a/modules/queue/workerpool.go b/modules/queue/workerpool.go index 244927880e92..b32128cb8214 100644 --- a/modules/queue/workerpool.go +++ b/modules/queue/workerpool.go @@ -463,13 +463,43 @@ func (p *WorkerPool) IsEmpty() bool { return atomic.LoadInt64(&p.numInQueue) == 0 } +// contextError returns either ctx.Done(), the base context's error or nil +func (p *WorkerPool) contextError(ctx context.Context) error { + select { + case <-p.baseCtx.Done(): + return p.baseCtx.Err() + case <-ctx.Done(): + return ctx.Err() + default: + return nil + } +} + // FlushWithContext is very similar to CleanUp but it will return as soon as the dataChan is empty // NB: The worker will not be registered with the manager. func (p *WorkerPool) FlushWithContext(ctx context.Context) error { log.Trace("WorkerPool: %d Flush", p.qid) + paused, _ := p.IsPausedIsResumed() for { + // Because select will return any case that is satisified at random we precheck here before looking at dataChan. + select { + case <-paused: + // Ensure that even if paused that the cancelled error is still sent + return p.contextError(ctx) + case <-p.baseCtx.Done(): + return p.baseCtx.Err() + case <-ctx.Done(): + return ctx.Err() + default: + } + select { - case data := <-p.dataChan: + case <-paused: + return p.contextError(ctx) + case data, ok := <-p.dataChan: + if !ok { + return nil + } if unhandled := p.handle(data); unhandled != nil { log.Error("Unhandled Data whilst flushing queue %d", p.qid) } @@ -495,6 +525,7 @@ func (p *WorkerPool) doWork(ctx context.Context) { paused, _ := p.IsPausedIsResumed() data := make([]Data, 0, p.batchLength) for { + // Because select will return any case that is satisified at random we precheck here before looking at dataChan. select { case <-paused: log.Trace("Worker for Queue %d Pausing", p.qid) @@ -515,8 +546,19 @@ func (p *WorkerPool) doWork(ctx context.Context) { log.Trace("Worker shutting down") return } + case <-ctx.Done(): + if len(data) > 0 { + log.Trace("Handling: %d data, %v", len(data), data) + if unhandled := p.handle(data...); unhandled != nil { + log.Error("Unhandled Data in queue %d", p.qid) + } + atomic.AddInt64(&p.numInQueue, -1*int64(len(data))) + } + log.Trace("Worker shutting down") + return default: } + select { case <-paused: // go back around From b76970f2e45d04d363fd6897439f111db24e4bca Mon Sep 17 00:00:00 2001 From: Gusted Date: Fri, 30 Dec 2022 05:53:05 +0100 Subject: [PATCH 16/23] Fix key signature error page (#22229) - When the GPG key contains an error, such as an invalid signature or an email address that does not match the user.A page will be shown that says you must provide a signature for the token. - This page had two errors: one had the wrong translation key and the other tried to use an undefined variable [`.PaddedKeyID`](https://github.com/go-gitea/gitea/blob/e81ccc406bf723a5a58d685e7782f281736affd4/models/asymkey/gpg_key.go#L65-L72), which is a function implemented on the `GPGKey` struct, given that we don't have that, we use [`KeyID`](https://github.com/go-gitea/gitea/blob/e81ccc406bf723a5a58d685e7782f281736affd4/routers/web/user/setting/keys.go#L102) which is [the fingerprint of the publickey](https://pkg.go.dev/golang.org/x/crypto/openpgp/packet#PublicKey.KeyIdString) and is a valid way for opengpg to refer to a key. Before: ![image](https://user-images.githubusercontent.com/25481501/209404800-0e7c39ce-861a-455b-b234-62498d750aa8.png) After: ![image](https://user-images.githubusercontent.com/25481501/209404821-c70f81c6-fd10-4197-ab58-61cb9fc873d8.png) Co-authored-by: zeripath --- models/asymkey/gpg_key.go | 11 ++++++++--- routers/web/user/setting/keys.go | 12 +++++++++--- templates/user/settings/keys_gpg.tmpl | 2 +- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/models/asymkey/gpg_key.go b/models/asymkey/gpg_key.go index ecd9041e6561..be019184eb5b 100644 --- a/models/asymkey/gpg_key.go +++ b/models/asymkey/gpg_key.go @@ -64,11 +64,16 @@ func (key *GPGKey) AfterLoad(session *xorm.Session) { // PaddedKeyID show KeyID padded to 16 characters func (key *GPGKey) PaddedKeyID() string { - if len(key.KeyID) > 15 { - return key.KeyID + return PaddedKeyID(key.KeyID) +} + +// PaddedKeyID show KeyID padded to 16 characters +func PaddedKeyID(keyID string) string { + if len(keyID) > 15 { + return keyID } zeros := "0000000000000000" - return zeros[0:16-len(key.KeyID)] + key.KeyID + return zeros[0:16-len(keyID)] + keyID } // ListGPGKeys returns a list of public keys belongs to given user. diff --git a/routers/web/user/setting/keys.go b/routers/web/user/setting/keys.go index 89be795599bd..ec50eef9c18d 100644 --- a/routers/web/user/setting/keys.go +++ b/routers/web/user/setting/keys.go @@ -99,14 +99,18 @@ func KeysPost(ctx *context.Context) { loadKeysData(ctx) ctx.Data["Err_Content"] = true ctx.Data["Err_Signature"] = true - ctx.Data["KeyID"] = err.(asymkey_model.ErrGPGInvalidTokenSignature).ID + keyID := err.(asymkey_model.ErrGPGInvalidTokenSignature).ID + ctx.Data["KeyID"] = keyID + ctx.Data["PaddedKeyID"] = asymkey_model.PaddedKeyID(keyID) ctx.RenderWithErr(ctx.Tr("settings.gpg_invalid_token_signature"), tplSettingsKeys, &form) case asymkey_model.IsErrGPGNoEmailFound(err): loadKeysData(ctx) ctx.Data["Err_Content"] = true ctx.Data["Err_Signature"] = true - ctx.Data["KeyID"] = err.(asymkey_model.ErrGPGNoEmailFound).ID + keyID := err.(asymkey_model.ErrGPGNoEmailFound).ID + ctx.Data["KeyID"] = keyID + ctx.Data["PaddedKeyID"] = asymkey_model.PaddedKeyID(keyID) ctx.RenderWithErr(ctx.Tr("settings.gpg_no_key_email_found"), tplSettingsKeys, &form) default: ctx.ServerError("AddPublicKey", err) @@ -138,7 +142,9 @@ func KeysPost(ctx *context.Context) { loadKeysData(ctx) ctx.Data["VerifyingID"] = form.KeyID ctx.Data["Err_Signature"] = true - ctx.Data["KeyID"] = err.(asymkey_model.ErrGPGInvalidTokenSignature).ID + keyID := err.(asymkey_model.ErrGPGInvalidTokenSignature).ID + ctx.Data["KeyID"] = keyID + ctx.Data["PaddedKeyID"] = asymkey_model.PaddedKeyID(keyID) ctx.RenderWithErr(ctx.Tr("settings.gpg_invalid_token_signature"), tplSettingsKeys, &form) default: ctx.ServerError("VerifyGPG", err) diff --git a/templates/user/settings/keys_gpg.tmpl b/templates/user/settings/keys_gpg.tmpl index fe6c0bbeb1f7..0968069c3a0a 100644 --- a/templates/user/settings/keys_gpg.tmpl +++ b/templates/user/settings/keys_gpg.tmpl @@ -18,7 +18,7 @@

{{.locale.Tr "settings.gpg_token_required"}}

-