From d0a2c1e82bf7d6505c268bc106d2ff57be6eb7d7 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Sun, 5 Jun 2022 00:02:10 +0800 Subject: [PATCH 01/11] use exact search instead of fuzzy search for branch filter dropdown (#19885) --- web_src/js/features/repo-common.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/web_src/js/features/repo-common.js b/web_src/js/features/repo-common.js index 89dae26277080..b0ecc5a651275 100644 --- a/web_src/js/features/repo-common.js +++ b/web_src/js/features/repo-common.js @@ -110,14 +110,14 @@ export function initRepoCommonBranchOrTagDropdown(selector) { export function initRepoCommonFilterSearchDropdown(selector) { const $dropdown = $(selector); $dropdown.dropdown({ - fullTextSearch: true, + fullTextSearch: 'exact', selectOnKeydown: false, onChange(_text, _value, $choice) { - if ($choice.data('url')) { - window.location.href = $choice.data('url'); + if ($choice.attr('data-url')) { + window.location.href = $choice.attr('data-url'); } }, - message: {noResults: $dropdown.data('no-results')}, + message: {noResults: $dropdown.attr('data-no-results')}, }); } From 449ea6005fb613212102126ff267f5c16f7c40b8 Mon Sep 17 00:00:00 2001 From: zeripath Date: Sat, 4 Jun 2022 19:30:01 +0100 Subject: [PATCH 02/11] Exclude Archived repos from Dashboard Milestones (#19882) Milestones in archived repos should not be displayed on `/milestones`. Therefore we should exclude these repositories from milestones page. Fix #18257 Signed-off-by: Andrew Thornton --- models/fixtures/repository.yml | 3 ++- routers/web/user/home.go | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/models/fixtures/repository.yml b/models/fixtures/repository.yml index 450c2f26af0fa..82b3ed16dcccf 100644 --- a/models/fixtures/repository.yml +++ b/models/fixtures/repository.yml @@ -618,7 +618,8 @@ num_forks: 0 num_issues: 1 num_milestones: 1 - is_mirror: false + is_mirror: + is_archived: false - id: 43 diff --git a/routers/web/user/home.go b/routers/web/user/home.go index 455761d039236..297d76d4aa582 100644 --- a/routers/web/user/home.go +++ b/routers/web/user/home.go @@ -170,8 +170,9 @@ func Milestones(ctx *context.Context) { Actor: ctxUser, OwnerID: ctxUser.ID, Private: true, - AllPublic: false, // Include also all public repositories of users and public organisations - AllLimited: false, // Include also all public repositories of limited organisations + AllPublic: false, // Include also all public repositories of users and public organisations + AllLimited: false, // Include also all public repositories of limited organisations + Archived: util.OptionalBoolFalse, HasMilestones: util.OptionalBoolTrue, // Just needs display repos has milestones } From 12c742f8dc25e4148c44d1265d119c35f161bf74 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Sun, 5 Jun 2022 03:18:50 +0800 Subject: [PATCH 03/11] Fix order by parameter (#19849) Upgrade builder to v0.3.11 Upgrade xorm to v1.3.1 and fixed some hidden bugs. Replace #19821 Replace #19834 Included #19850 Co-authored-by: zeripath --- go.mod | 4 +- go.sum | 118 ++++++++++++++++++++++---- integrations/api_admin_test.go | 1 - integrations/api_keys_test.go | 12 +-- integrations/api_releases_test.go | 14 +-- integrations/api_repo_test.go | 5 ++ models/action.go | 4 +- models/asymkey/ssh_key.go | 4 +- models/asymkey/ssh_key_deploy.go | 2 +- models/asymkey/ssh_key_fingerprint.go | 3 +- models/consistency.go | 7 +- models/db/engine.go | 5 +- models/issue.go | 10 +-- models/migrations/v151.go | 23 ++--- models/migrations/v165.go | 10 ++- models/migrations/v179.go | 3 +- models/migrations/v205.go | 8 +- models/repo_collaboration.go | 5 +- models/repo_list.go | 9 +- 19 files changed, 175 insertions(+), 72 deletions(-) diff --git a/go.mod b/go.mod index 23e922ecef2df..82d137d360450 100644 --- a/go.mod +++ b/go.mod @@ -98,8 +98,8 @@ require ( gopkg.in/yaml.v2 v2.4.0 mvdan.cc/xurls/v2 v2.4.0 strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251 - xorm.io/builder v0.3.10 - xorm.io/xorm v1.2.5 + xorm.io/builder v0.3.11 + xorm.io/xorm v1.3.1 ) require ( diff --git a/go.sum b/go.sum index 3af17c070b0fa..d351992b1be73 100644 --- a/go.sum +++ b/go.sum @@ -82,6 +82,7 @@ gitea.com/lunny/levelqueue v0.4.1 h1:RZ+AFx5gBsZuyqCvofhAkPQ9uaVDPJnsULoJZIYaJNw gitea.com/lunny/levelqueue v0.4.1/go.mod h1:HBqmLbz56JWpfEGG0prskAV97ATNRoj5LDmPicD22hU= gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s= gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU= +gitee.com/travelliu/dm v1.8.11192/go.mod h1:DHTzyhCrM843x9VdKVbZ+GKXGRbKM2sJ4LxihRxShkE= github.com/42wim/sshsig v0.0.0-20211121163825-841cf5bbc121 h1:r3qt8PCHnfjOv9PN3H+XXKmDA1dfFMIN1AislhlA/ps= github.com/42wim/sshsig v0.0.0-20211121163825-841cf5bbc121/go.mod h1:Ock8XgA7pvULhIaHGAk/cDnRfNrF9Jey81nPcc403iU= github.com/6543/go-version v1.3.1 h1:HvOp+Telns7HWJ2Xo/05YXQSB2bE0WmVgbHqwMPZT4U= @@ -636,7 +637,7 @@ github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/V github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= -github.com/goccy/go-json v0.7.4/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/goccy/go-json v0.8.1/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/goccy/go-json v0.9.5/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/goccy/go-json v0.9.6/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/goccy/go-json v0.9.7 h1:IcB+Aqpx/iMHu5Yooh7jEzJk1JZ7Pjtmys2ukPr7EeM= @@ -1126,7 +1127,7 @@ github.com/mattn/go-shellwords v1.0.10/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lL github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v1.14.7/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= -github.com/mattn/go-sqlite3 v1.14.8/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +github.com/mattn/go-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v1.14.12 h1:TJ1bhYJPV44phC+IMu1u2K/i5RriLTPe+yc68XDJ1Z0= github.com/mattn/go-sqlite3 v1.14.12/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-zglob v0.0.1/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo= @@ -1918,6 +1919,7 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210902050250-f475640dd07b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -2281,31 +2283,113 @@ honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 honnef.co/go/tools v0.1.4/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= lukechampine.com/uint128 v1.1.1 h1:pnxCASz787iMf+02ssImqk6OLt+Z5QHMoZyUXR4z6JU= lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= -modernc.org/cc/v3 v3.33.6 h1:r63dgSzVzRxUpAJFPQWHy1QeZeY1ydNENUDaBx1GqYc= modernc.org/cc/v3 v3.33.6/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= -modernc.org/ccgo/v3 v3.9.5 h1:dEuUSf8WN51rDkprFuAqjfchKEzN0WttP/Py3enBwjk= +modernc.org/cc/v3 v3.33.9/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= +modernc.org/cc/v3 v3.33.11/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= +modernc.org/cc/v3 v3.34.0/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= +modernc.org/cc/v3 v3.35.0/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= +modernc.org/cc/v3 v3.35.4/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= +modernc.org/cc/v3 v3.35.5/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= +modernc.org/cc/v3 v3.35.7/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= +modernc.org/cc/v3 v3.35.8/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= +modernc.org/cc/v3 v3.35.10/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= +modernc.org/cc/v3 v3.35.15/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= +modernc.org/cc/v3 v3.35.16/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= +modernc.org/cc/v3 v3.35.17/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= +modernc.org/cc/v3 v3.35.18 h1:rMZhRcWrba0y3nVmdiQ7kxAgOOSq2m2f2VzjHLgEs6U= +modernc.org/cc/v3 v3.35.18/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g= modernc.org/ccgo/v3 v3.9.5/go.mod h1:umuo2EP2oDSBnD3ckjaVUXMrmeAw8C8OSICVa0iFf60= +modernc.org/ccgo/v3 v3.10.0/go.mod h1:c0yBmkRFi7uW4J7fwx/JiijwOjeAeR2NoSaRVFPmjMw= +modernc.org/ccgo/v3 v3.11.0/go.mod h1:dGNposbDp9TOZ/1KBxghxtUp/bzErD0/0QW4hhSaBMI= +modernc.org/ccgo/v3 v3.11.1/go.mod h1:lWHxfsn13L3f7hgGsGlU28D9eUOf6y3ZYHKoPaKU0ag= +modernc.org/ccgo/v3 v3.11.3/go.mod h1:0oHunRBMBiXOKdaglfMlRPBALQqsfrCKXgw9okQ3GEw= +modernc.org/ccgo/v3 v3.12.4/go.mod h1:Bk+m6m2tsooJchP/Yk5ji56cClmN6R1cqc9o/YtbgBQ= +modernc.org/ccgo/v3 v3.12.6/go.mod h1:0Ji3ruvpFPpz+yu+1m0wk68pdr/LENABhTrDkMDWH6c= +modernc.org/ccgo/v3 v3.12.8/go.mod h1:Hq9keM4ZfjCDuDXxaHptpv9N24JhgBZmUG5q60iLgUo= +modernc.org/ccgo/v3 v3.12.11/go.mod h1:0jVcmyDwDKDGWbcrzQ+xwJjbhZruHtouiBEvDfoIsdg= +modernc.org/ccgo/v3 v3.12.14/go.mod h1:GhTu1k0YCpJSuWwtRAEHAol5W7g1/RRfS4/9hc9vF5I= +modernc.org/ccgo/v3 v3.12.18/go.mod h1:jvg/xVdWWmZACSgOiAhpWpwHWylbJaSzayCqNOJKIhs= +modernc.org/ccgo/v3 v3.12.20/go.mod h1:aKEdssiu7gVgSy/jjMastnv/q6wWGRbszbheXgWRHc8= +modernc.org/ccgo/v3 v3.12.21/go.mod h1:ydgg2tEprnyMn159ZO/N4pLBqpL7NOkJ88GT5zNU2dE= +modernc.org/ccgo/v3 v3.12.22/go.mod h1:nyDVFMmMWhMsgQw+5JH6B6o4MnZ+UQNw1pp52XYFPRk= +modernc.org/ccgo/v3 v3.12.25/go.mod h1:UaLyWI26TwyIT4+ZFNjkyTbsPsY3plAEB6E7L/vZV3w= +modernc.org/ccgo/v3 v3.12.29/go.mod h1:FXVjG7YLf9FetsS2OOYcwNhcdOLGt8S9bQ48+OP75cE= +modernc.org/ccgo/v3 v3.12.36/go.mod h1:uP3/Fiezp/Ga8onfvMLpREq+KUjUmYMxXPO8tETHtA8= +modernc.org/ccgo/v3 v3.12.38/go.mod h1:93O0G7baRST1vNj4wnZ49b1kLxt0xCW5Hsa2qRaZPqc= +modernc.org/ccgo/v3 v3.12.43/go.mod h1:k+DqGXd3o7W+inNujK15S5ZYuPoWYLpF5PYougCmthU= +modernc.org/ccgo/v3 v3.12.46/go.mod h1:UZe6EvMSqOxaJ4sznY7b23/k13R8XNlyWsO5bAmSgOE= +modernc.org/ccgo/v3 v3.12.47/go.mod h1:m8d6p0zNps187fhBwzY/ii6gxfjob1VxWb919Nk1HUk= +modernc.org/ccgo/v3 v3.12.50/go.mod h1:bu9YIwtg+HXQxBhsRDE+cJjQRuINuT9PUK4orOco/JI= +modernc.org/ccgo/v3 v3.12.51/go.mod h1:gaIIlx4YpmGO2bLye04/yeblmvWEmE4BBBls4aJXFiE= +modernc.org/ccgo/v3 v3.12.53/go.mod h1:8xWGGTFkdFEWBEsUmi+DBjwu/WLy3SSOrqEmKUjMeEg= +modernc.org/ccgo/v3 v3.12.54/go.mod h1:yANKFTm9llTFVX1FqNKHE0aMcQb1fuPJx6p8AcUx+74= +modernc.org/ccgo/v3 v3.12.55/go.mod h1:rsXiIyJi9psOwiBkplOaHye5L4MOOaCjHg1Fxkj7IeU= +modernc.org/ccgo/v3 v3.12.56/go.mod h1:ljeFks3faDseCkr60JMpeDb2GSO3TKAmrzm7q9YOcMU= +modernc.org/ccgo/v3 v3.12.57/go.mod h1:hNSF4DNVgBl8wYHpMvPqQWDQx8luqxDnNGCMM4NFNMc= +modernc.org/ccgo/v3 v3.12.60/go.mod h1:k/Nn0zdO1xHVWjPYVshDeWKqbRWIfif5dtsIOCUVMqM= +modernc.org/ccgo/v3 v3.12.65/go.mod h1:D6hQtKxPNZiY6wDBtehSGKFKmyXn53F8nGTpH+POmS4= +modernc.org/ccgo/v3 v3.12.66/go.mod h1:jUuxlCFZTUZLMV08s7B1ekHX5+LIAurKTTaugUr/EhQ= +modernc.org/ccgo/v3 v3.12.67/go.mod h1:Bll3KwKvGROizP2Xj17GEGOTrlvB1XcVaBrC90ORO84= +modernc.org/ccgo/v3 v3.12.73/go.mod h1:hngkB+nUUqzOf3iqsM48Gf1FZhY599qzVg1iX+BT3cQ= +modernc.org/ccgo/v3 v3.12.81/go.mod h1:p2A1duHoBBg1mFtYvnhAnQyI6vL0uw5PGYLSIgF6rYY= +modernc.org/ccgo/v3 v3.12.82 h1:wudcnJyjLj1aQQCXF3IM9Gz2X6UNjw+afIghzdtn0v8= +modernc.org/ccgo/v3 v3.12.82/go.mod h1:ApbflUfa5BKadjHynCficldU1ghjen84tuM5jRynB7w= +modernc.org/ccorpus v1.11.1/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ= modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM= -modernc.org/libc v1.7.13-0.20210308123627-12f642a52bb8/go.mod h1:U1eq8YWr/Kc1RWCMFUWEdkTg8OTcfLw2kY8EDwl039w= modernc.org/libc v1.9.8/go.mod h1:U1eq8YWr/Kc1RWCMFUWEdkTg8OTcfLw2kY8EDwl039w= -modernc.org/libc v1.9.11 h1:QUxZMs48Ahg2F7SN41aERvMfGLY2HU/ADnB9DC4Yts8= modernc.org/libc v1.9.11/go.mod h1:NyF3tsA5ArIjJ83XB0JlqhjTabTCHm9aX4XMPHyQn0Q= +modernc.org/libc v1.11.0/go.mod h1:2lOfPmj7cz+g1MrPNmX65QCzVxgNq2C5o0jdLY2gAYg= +modernc.org/libc v1.11.2/go.mod h1:ioIyrl3ETkugDO3SGZ+6EOKvlP3zSOycUETe4XM4n8M= +modernc.org/libc v1.11.5/go.mod h1:k3HDCP95A6U111Q5TmG3nAyUcp3kR5YFZTeDS9v8vSU= +modernc.org/libc v1.11.6/go.mod h1:ddqmzR6p5i4jIGK1d/EiSw97LBcE3dK24QEwCFvgNgE= +modernc.org/libc v1.11.11/go.mod h1:lXEp9QOOk4qAYOtL3BmMve99S5Owz7Qyowzvg6LiZso= +modernc.org/libc v1.11.13/go.mod h1:ZYawJWlXIzXy2Pzghaf7YfM8OKacP3eZQI81PDLFdY8= +modernc.org/libc v1.11.16/go.mod h1:+DJquzYi+DMRUtWI1YNxrlQO6TcA5+dRRiq8HWBWRC8= +modernc.org/libc v1.11.19/go.mod h1:e0dgEame6mkydy19KKaVPBeEnyJB4LGNb0bBH1EtQ3I= +modernc.org/libc v1.11.24/go.mod h1:FOSzE0UwookyT1TtCJrRkvsOrX2k38HoInhw+cSCUGk= +modernc.org/libc v1.11.26/go.mod h1:SFjnYi9OSd2W7f4ct622o/PAYqk7KHv6GS8NZULIjKY= +modernc.org/libc v1.11.27/go.mod h1:zmWm6kcFXt/jpzeCgfvUNswM0qke8qVwxqZrnddlDiE= +modernc.org/libc v1.11.28/go.mod h1:Ii4V0fTFcbq3qrv3CNn+OGHAvzqMBvC7dBNyC4vHZlg= +modernc.org/libc v1.11.31/go.mod h1:FpBncUkEAtopRNJj8aRo29qUiyx5AvAlAxzlx9GNaVM= +modernc.org/libc v1.11.34/go.mod h1:+Tzc4hnb1iaX/SKAutJmfzES6awxfU1BPvrrJO0pYLg= +modernc.org/libc v1.11.37/go.mod h1:dCQebOwoO1046yTrfUE5nX1f3YpGZQKNcITUYWlrAWo= +modernc.org/libc v1.11.39/go.mod h1:mV8lJMo2S5A31uD0k1cMu7vrJbSA3J3waQJxpV4iqx8= +modernc.org/libc v1.11.42/go.mod h1:yzrLDU+sSjLE+D4bIhS7q1L5UwXDOw99PLSX0BlZvSQ= +modernc.org/libc v1.11.44/go.mod h1:KFq33jsma7F5WXiYelU8quMJasCCTnHK0mkri4yPHgA= +modernc.org/libc v1.11.45/go.mod h1:Y192orvfVQQYFzCNsn+Xt0Hxt4DiO4USpLNXBlXg/tM= +modernc.org/libc v1.11.47/go.mod h1:tPkE4PzCTW27E6AIKIR5IwHAQKCAtudEIeAV1/SiyBg= +modernc.org/libc v1.11.49/go.mod h1:9JrJuK5WTtoTWIFQ7QjX2Mb/bagYdZdscI3xrvHbXjE= +modernc.org/libc v1.11.51/go.mod h1:R9I8u9TS+meaWLdbfQhq2kFknTW0O3aw3kEMqDDxMaM= +modernc.org/libc v1.11.53/go.mod h1:5ip5vWYPAoMulkQ5XlSJTy12Sz5U6blOQiYasilVPsU= +modernc.org/libc v1.11.54/go.mod h1:S/FVnskbzVUrjfBqlGFIPA5m7UwB3n9fojHhCNfSsnw= +modernc.org/libc v1.11.55/go.mod h1:j2A5YBRm6HjNkoSs/fzZrSxCuwWqcMYTDPLNx0URn3M= +modernc.org/libc v1.11.56/go.mod h1:pakHkg5JdMLt2OgRadpPOTnyRXm/uzu+Yyg/LSLdi18= +modernc.org/libc v1.11.58/go.mod h1:ns94Rxv0OWyoQrDqMFfWwka2BcaF6/61CqJRK9LP7S8= +modernc.org/libc v1.11.70/go.mod h1:DUOmMYe+IvKi9n6Mycyx3DbjfzSKrdr/0Vgt3j7P5gw= +modernc.org/libc v1.11.71/go.mod h1:DUOmMYe+IvKi9n6Mycyx3DbjfzSKrdr/0Vgt3j7P5gw= +modernc.org/libc v1.11.75/go.mod h1:dGRVugT6edz361wmD9gk6ax1AbDSe0x5vji0dGJiPT0= +modernc.org/libc v1.11.82/go.mod h1:NF+Ek1BOl2jeC7lw3a7Jj5PWyHPwWD4aq3wVKxqV1fI= +modernc.org/libc v1.11.86/go.mod h1:ePuYgoQLmvxdNT06RpGnaDKJmDNEkV7ZPKI2jnsvZoE= +modernc.org/libc v1.11.87 h1:PzIzOqtlzMDDcCzJ5cUP6h/Ku6Fa9iyflP2ccTY64aE= +modernc.org/libc v1.11.87/go.mod h1:Qvd5iXTeLhI5PS0XSyqMY99282y+3euapQFxM7jYnpY= modernc.org/mathutil v1.1.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= -modernc.org/mathutil v1.4.0 h1:GCjoRaBew8ECCKINQA2nYjzvufFW9YiEuuB+rQ9bn2E= modernc.org/mathutil v1.4.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= -modernc.org/memory v1.0.4 h1:utMBrFcpnQDdNsmM6asmyH/FM9TqLPS7XF7otpJmrwM= +modernc.org/mathutil v1.4.1 h1:ij3fYGe8zBF4Vu+g0oT7mB06r8sqGWKuJu1yXeR4by8= +modernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= modernc.org/memory v1.0.4/go.mod h1:nV2OApxradM3/OVbs2/0OsP6nPfakXpi50C7dcoHXlc= +modernc.org/memory v1.0.5 h1:XRch8trV7GgvTec2i7jc33YlUI0RKVDBvZ5eZ5m8y14= +modernc.org/memory v1.0.5/go.mod h1:B7OYswTRnfGg+4tDH1t1OeUNnsy2viGTdME4tzd+IjM= modernc.org/opt v0.1.1 h1:/0RX92k9vwVeDXj+Xn23DKp2VJubL7k8qNffND6qn3A= modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= -modernc.org/sqlite v1.11.2 h1:ShWQpeD3ag/bmx6TqidBlIWonWmQaSQKls3aenCbt+w= -modernc.org/sqlite v1.11.2/go.mod h1:+mhs/P1ONd+6G7hcAs6irwDi/bjTQ7nLW6LHRBsEa3A= +modernc.org/sqlite v1.14.2 h1:ohsW2+e+Qe2To1W6GNezzKGwjXwSax6R+CrhRxVaFbE= +modernc.org/sqlite v1.14.2/go.mod h1:yqfn85u8wVOE6ub5UT8VI9JjhrwBUUCNyTACN0h6Sx8= modernc.org/strutil v1.1.1 h1:xv+J1BXY3Opl2ALrBwyfEikFAj8pmqcpnfmuwUwcozs= modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw= -modernc.org/tcl v1.5.5/go.mod h1:ADkaTUuwukkrlhqwERyq0SM8OvyXo7+TjFz7yAF56EI= +modernc.org/tcl v1.8.13/go.mod h1:V+q/Ef0IJaNUSECieLU4o+8IScapxnMyFV6i/7uQlAY= modernc.org/token v1.0.0 h1:a0jaWiNMDhDUtqOj09wvjWWAqd3q7WpBulmL9H2egsk= modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= -modernc.org/z v1.0.1/go.mod h1:8/SRk5C/HgiQWCgXdfpb+1RvhORdkz5sw72d3jjtyqA= +modernc.org/z v1.2.19/go.mod h1:+ZpP0pc4zz97eukOzW3xagV/lS82IpPN9NGG5pNF9vY= mvdan.cc/xurls/v2 v2.4.0 h1:tzxjVAj+wSBmDcF6zBB7/myTy3gX9xvi8Tyr28AuQgc= mvdan.cc/xurls/v2 v2.4.0/go.mod h1:+GEjq9uNjqs8LQfM9nVnM8rff0OQ5Iash5rzX+N1CSg= pack.ag/amqp v0.11.2/go.mod h1:4/cbmt4EJXSKlG6LCfWHoqmN0uFdy5i/+YFz+fTfhV4= @@ -2318,8 +2402,8 @@ sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251 h1:mUcz5b3FJbP5Cvdq7Khzn6J9OCUQJaBwgBkCR+MOwSs= strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251/go.mod h1:FJGmPh3vz9jSos1L/F91iAgnC/aejc0wIIrF2ZwJxdY= -xorm.io/builder v0.3.9/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE= -xorm.io/builder v0.3.10 h1:Rvkncad3Lo9YIVqCbgIf6QnpR/HcW3IEr0AANNpuyMQ= -xorm.io/builder v0.3.10/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE= -xorm.io/xorm v1.2.5 h1:tqN7OhN8P9xi52qBb76I8m5maAJMz/SSbgK2RGPCPbo= -xorm.io/xorm v1.2.5/go.mod h1:fTG8tSjk6O1BYxwuohZUK+S1glnRycsCF05L1qQyEU0= +xorm.io/builder v0.3.11-0.20220531020008-1bd24a7dc978/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE= +xorm.io/builder v0.3.11 h1:naLkJitGyYW7ZZdncsh/JW+HF4HshmvTHTyUyPwJS00= +xorm.io/builder v0.3.11/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE= +xorm.io/xorm v1.3.1 h1:z5egKrDoOLqZFhMjcGF4FBHiTmE5/feQoHclfhNidfM= +xorm.io/xorm v1.3.1/go.mod h1:9NbjqdnjX6eyjRRhh01GHm64r6N9shTb/8Ak3YRt8Nw= diff --git a/integrations/api_admin_test.go b/integrations/api_admin_test.go index b935d3eac5948..62c7d7eaf7d32 100644 --- a/integrations/api_admin_test.go +++ b/integrations/api_admin_test.go @@ -37,7 +37,6 @@ func TestAPIAdminCreateAndDeleteSSHKey(t *testing.T) { unittest.AssertExistsAndLoadBean(t, &asymkey_model.PublicKey{ ID: newPublicKey.ID, Name: newPublicKey.Title, - Content: newPublicKey.Key, Fingerprint: newPublicKey.Fingerprint, OwnerID: keyOwner.ID, }) diff --git a/integrations/api_keys_test.go b/integrations/api_keys_test.go index b1f455d9323c1..198da29b8a10c 100644 --- a/integrations/api_keys_test.go +++ b/integrations/api_keys_test.go @@ -116,12 +116,14 @@ func TestCreateUserKey(t *testing.T) { var newPublicKey api.PublicKey DecodeJSON(t, resp, &newPublicKey) + fingerprint, err := asymkey_model.CalcFingerprint(rawKeyBody.Key) + assert.NoError(t, err) unittest.AssertExistsAndLoadBean(t, &asymkey_model.PublicKey{ - ID: newPublicKey.ID, - OwnerID: user.ID, - Name: rawKeyBody.Title, - Content: rawKeyBody.Key, - Mode: perm.AccessModeWrite, + ID: newPublicKey.ID, + OwnerID: user.ID, + Name: rawKeyBody.Title, + Fingerprint: fingerprint, + Mode: perm.AccessModeWrite, }) // Search by fingerprint diff --git a/integrations/api_releases_test.go b/integrations/api_releases_test.go index ebb76cc163966..74639e900739d 100644 --- a/integrations/api_releases_test.go +++ b/integrations/api_releases_test.go @@ -84,12 +84,13 @@ func createNewReleaseUsingAPI(t *testing.T, session *TestSession, token string, var newRelease api.Release DecodeJSON(t, resp, &newRelease) - unittest.AssertExistsAndLoadBean(t, &models.Release{ + rel := &models.Release{ ID: newRelease.ID, TagName: newRelease.TagName, Title: newRelease.Title, - Note: newRelease.Note, - }) + } + unittest.AssertExistsAndLoadBean(t, rel) + assert.EqualValues(t, newRelease.Note, rel.Note) return &newRelease } @@ -137,12 +138,13 @@ func TestAPICreateAndUpdateRelease(t *testing.T) { resp = session.MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &newRelease) - unittest.AssertExistsAndLoadBean(t, &models.Release{ + rel := &models.Release{ ID: newRelease.ID, TagName: newRelease.TagName, Title: newRelease.Title, - Note: newRelease.Note, - }) + } + unittest.AssertExistsAndLoadBean(t, rel) + assert.EqualValues(t, rel.Note, newRelease.Note) } func TestAPICreateReleaseToDefaultBranch(t *testing.T) { diff --git a/integrations/api_repo_test.go b/integrations/api_repo_test.go index 8f08da16a107a..57fe65f4bf90b 100644 --- a/integrations/api_repo_test.go +++ b/integrations/api_repo_test.go @@ -109,6 +109,11 @@ func TestAPISearchRepo(t *testing.T) { user2: {count: 7, repoName: "big_test_"}, }, }, + { + name: "RepositoriesByName", requestURL: fmt.Sprintf("/api/v1/repos/search?q=%s&private=false", "user2/big_test_"), expectedResults: expectedResults{ + user2: {count: 2, repoName: "big_test_"}, + }, + }, { name: "RepositoriesAccessibleAndRelatedToUser", requestURL: fmt.Sprintf("/api/v1/repos/search?uid=%d", user.ID), expectedResults: expectedResults{ nil: {count: 5}, diff --git a/models/action.go b/models/action.go index 29e2ea47bd181..87bfcbbbad4b6 100644 --- a/models/action.go +++ b/models/action.go @@ -492,7 +492,7 @@ func notifyWatchers(ctx context.Context, actions ...*Action) error { if act.Repo.Owner.IsOrganization() && act.ActUserID != act.Repo.Owner.ID { act.ID = 0 act.UserID = act.Repo.Owner.ID - if _, err = e.InsertOne(act); err != nil { + if err = db.Insert(ctx, act); err != nil { return fmt.Errorf("insert new actioner: %v", err) } } @@ -545,7 +545,7 @@ func notifyWatchers(ctx context.Context, actions ...*Action) error { } } - if _, err = e.InsertOne(act); err != nil { + if err = db.Insert(ctx, act); err != nil { return fmt.Errorf("insert new action: %v", err) } } diff --git a/models/asymkey/ssh_key.go b/models/asymkey/ssh_key.go index 10220ea93788f..107a29e985f71 100644 --- a/models/asymkey/ssh_key.go +++ b/models/asymkey/ssh_key.go @@ -77,7 +77,7 @@ func (key *PublicKey) AuthorizedString() string { func addKey(ctx context.Context, key *PublicKey) (err error) { if len(key.Fingerprint) == 0 { - key.Fingerprint, err = calcFingerprint(key.Content) + key.Fingerprint, err = CalcFingerprint(key.Content) if err != nil { return err } @@ -95,7 +95,7 @@ func addKey(ctx context.Context, key *PublicKey) (err error) { func AddPublicKey(ownerID int64, name, content string, authSourceID int64) (*PublicKey, error) { log.Trace(content) - fingerprint, err := calcFingerprint(content) + fingerprint, err := CalcFingerprint(content) if err != nil { return nil, err } diff --git a/models/asymkey/ssh_key_deploy.go b/models/asymkey/ssh_key_deploy.go index 9a97d37f93219..22fcefff69a5a 100644 --- a/models/asymkey/ssh_key_deploy.go +++ b/models/asymkey/ssh_key_deploy.go @@ -116,7 +116,7 @@ func HasDeployKey(keyID, repoID int64) bool { // AddDeployKey add new deploy key to database and authorized_keys file. func AddDeployKey(repoID int64, name, content string, readOnly bool) (*DeployKey, error) { - fingerprint, err := calcFingerprint(content) + fingerprint, err := CalcFingerprint(content) if err != nil { return nil, err } diff --git a/models/asymkey/ssh_key_fingerprint.go b/models/asymkey/ssh_key_fingerprint.go index 283b3d3b64b23..747a7e6473c4d 100644 --- a/models/asymkey/ssh_key_fingerprint.go +++ b/models/asymkey/ssh_key_fingerprint.go @@ -76,7 +76,8 @@ func calcFingerprintNative(publicKeyContent string) (string, error) { return ssh.FingerprintSHA256(pk), nil } -func calcFingerprint(publicKeyContent string) (string, error) { +// CalcFingerprint calculate public key's fingerprint +func CalcFingerprint(publicKeyContent string) (string, error) { // Call the method based on configuration var ( fnName, fp string diff --git a/models/consistency.go b/models/consistency.go index abef7243f17e6..e817b691762ff 100644 --- a/models/consistency.go +++ b/models/consistency.go @@ -86,7 +86,6 @@ func DeleteOrphanedIssueLabels() error { _, err := db.GetEngine(db.DefaultContext). NotIn("label_id", builder.Select("id").From("label")). Delete(IssueLabel{}) - return err } @@ -95,7 +94,8 @@ func CountOrphanedIssues() (int64, error) { return db.GetEngine(db.DefaultContext).Table("issue"). Join("LEFT", "repository", "issue.repo_id=repository.id"). Where(builder.IsNull{"repository.id"}). - Count("id") + Select("COUNT(`issue`.`id`)"). + Count() } // DeleteOrphanedIssues delete issues without a repo @@ -141,7 +141,8 @@ func CountOrphanedObjects(subject, refobject, joinCond string) (int64, error) { return db.GetEngine(db.DefaultContext).Table("`"+subject+"`"). Join("LEFT", "`"+refobject+"`", joinCond). Where(builder.IsNull{"`" + refobject + "`.id"}). - Count("id") + Select("COUNT(`" + subject + "`.`id`)"). + Count() } // DeleteOrphanedObjects delete subjects with have no existing refobject anymore diff --git a/models/db/engine.go b/models/db/engine.go index 9f38af3c67060..23eb59dcf5371 100755 --- a/models/db/engine.go +++ b/models/db/engine.go @@ -41,12 +41,11 @@ type Engine interface { Delete(...interface{}) (int64, error) Exec(...interface{}) (sql.Result, error) Find(interface{}, ...interface{}) error - Get(interface{}) (bool, error) + Get(beans ...interface{}) (bool, error) ID(interface{}) *xorm.Session In(string, ...interface{}) *xorm.Session Incr(column string, arg ...interface{}) *xorm.Session Insert(...interface{}) (int64, error) - InsertOne(interface{}) (int64, error) Iterate(interface{}, xorm.IterFunc) error Join(joinOperator string, tablename interface{}, condition string, args ...interface{}) *xorm.Session SQL(interface{}, ...interface{}) *xorm.Session @@ -59,7 +58,7 @@ type Engine interface { Sync2(...interface{}) error Select(string) *xorm.Session NotIn(string, ...interface{}) *xorm.Session - OrderBy(string) *xorm.Session + OrderBy(interface{}, ...interface{}) *xorm.Session Exist(...interface{}) (bool, error) Distinct(...string) *xorm.Session Query(...interface{}) ([]map[string][]byte, error) diff --git a/models/issue.go b/models/issue.go index 1a66e5e95bbaa..4150d66a65ecf 100644 --- a/models/issue.go +++ b/models/issue.go @@ -1220,9 +1220,9 @@ func sortIssuesSession(sess *xorm.Session, sortType string, priorityRepoID int64 Desc("issue.created_unix"). Desc("issue.id") case "priorityrepo": - sess.OrderBy("CASE " + - "WHEN issue.repo_id = " + strconv.FormatInt(priorityRepoID, 10) + " THEN 1 " + - "ELSE 2 END ASC"). + sess.OrderBy("CASE "+ + "WHEN issue.repo_id = ? THEN 1 "+ + "ELSE 2 END ASC", priorityRepoID). Desc("issue.created_unix"). Desc("issue.id") case "project-column-sorting": @@ -2124,7 +2124,7 @@ func (issue *Issue) BlockedByDependencies(ctx context.Context) (issueDeps []*Dep Join("INNER", "issue_dependency", "issue_dependency.dependency_id = issue.id"). Where("issue_id = ?", issue.ID). // sort by repo id then created date, with the issues of the same repo at the beginning of the list - OrderBy("CASE WHEN issue.repo_id = " + strconv.FormatInt(issue.RepoID, 10) + " THEN 0 ELSE issue.repo_id END, issue.created_unix DESC"). + OrderBy("CASE WHEN issue.repo_id = ? THEN 0 ELSE issue.repo_id END, issue.created_unix DESC", issue.RepoID). Find(&issueDeps) for _, depInfo := range issueDeps { @@ -2142,7 +2142,7 @@ func (issue *Issue) BlockingDependencies(ctx context.Context) (issueDeps []*Depe Join("INNER", "issue_dependency", "issue_dependency.issue_id = issue.id"). Where("dependency_id = ?", issue.ID). // sort by repo id then created date, with the issues of the same repo at the beginning of the list - OrderBy("CASE WHEN issue.repo_id = " + strconv.FormatInt(issue.RepoID, 10) + " THEN 0 ELSE issue.repo_id END, issue.created_unix DESC"). + OrderBy("CASE WHEN issue.repo_id = ? THEN 0 ELSE issue.repo_id END, issue.created_unix DESC", issue.RepoID). Find(&issueDeps) for _, depInfo := range issueDeps { diff --git a/models/migrations/v151.go b/models/migrations/v151.go index ba6eee3440265..50314d816236c 100644 --- a/models/migrations/v151.go +++ b/models/migrations/v151.go @@ -5,6 +5,7 @@ package migrations import ( + "context" "fmt" "strings" @@ -86,21 +87,23 @@ func setDefaultPasswordToArgon2(x *xorm.Engine) error { } return x.Sync2(new(User)) } + + tempTableName := "tmp_recreate__user" + column.Default = "'argon2'" + + createTableSQL, _, err := x.Dialect().CreateTableSQL(context.Background(), x.DB(), table, tempTableName) + if err != nil { + return err + } + sess := x.NewSession() defer sess.Close() if err := sess.Begin(); err != nil { return err } - - tempTableName := "tmp_recreate__user" - column.Default = "'argon2'" - - createTableSQL, _ := x.Dialect().CreateTableSQL(table, tempTableName) - for _, sql := range createTableSQL { - if _, err := sess.Exec(sql); err != nil { - log.Error("Unable to create table %s. Error: %v\n", tempTableName, err, createTableSQL) - return err - } + if _, err := sess.Exec(createTableSQL); err != nil { + log.Error("Unable to create table %s. Error: %v\n", tempTableName, err, createTableSQL) + return err } for _, index := range table.Indexes { if _, err := sess.Exec(x.Dialect().CreateIndexSQL(tempTableName, index)); err != nil { diff --git a/models/migrations/v165.go b/models/migrations/v165.go index d7df0f07a97c1..87e1a24f2812a 100644 --- a/models/migrations/v165.go +++ b/models/migrations/v165.go @@ -24,8 +24,9 @@ func convertHookTaskTypeToVarcharAndTrim(x *xorm.Engine) error { SQLType: schemas.SQLType{ Name: "VARCHAR", }, - Length: 16, - Nullable: true, // To keep compatible as nullable + Length: 16, + Nullable: true, // To keep compatible as nullable + DefaultIsEmpty: true, }); err != nil { return err } @@ -49,8 +50,9 @@ func convertHookTaskTypeToVarcharAndTrim(x *xorm.Engine) error { SQLType: schemas.SQLType{ Name: "VARCHAR", }, - Length: 16, - Nullable: true, // To keep compatible as nullable + Length: 16, + Nullable: true, // To keep compatible as nullable + DefaultIsEmpty: true, }); err != nil { return err } diff --git a/models/migrations/v179.go b/models/migrations/v179.go index 735e6b62dd2c5..e6dddef27333a 100644 --- a/models/migrations/v179.go +++ b/models/migrations/v179.go @@ -21,6 +21,7 @@ func convertAvatarURLToText(x *xorm.Engine) error { SQLType: schemas.SQLType{ Name: schemas.Text, }, - Nullable: true, + Nullable: true, + DefaultIsEmpty: true, }) } diff --git a/models/migrations/v205.go b/models/migrations/v205.go index 755cb1024583f..7aefa0431ac19 100644 --- a/models/migrations/v205.go +++ b/models/migrations/v205.go @@ -23,7 +23,8 @@ func migrateUserPasswordSalt(x *xorm.Engine) error { }, Length: 32, // MySQL will like us again. - Nullable: true, + Nullable: true, + DefaultIsEmpty: true, }); err != nil { return err } @@ -33,7 +34,8 @@ func migrateUserPasswordSalt(x *xorm.Engine) error { SQLType: schemas.SQLType{ Name: "VARCHAR", }, - Length: 32, - Nullable: true, + Length: 32, + Nullable: true, + DefaultIsEmpty: true, }) } diff --git a/models/repo_collaboration.go b/models/repo_collaboration.go index e20e96815c0a7..8cbd836a426af 100644 --- a/models/repo_collaboration.go +++ b/models/repo_collaboration.go @@ -25,9 +25,8 @@ func addCollaborator(ctx context.Context, repo *repo_model.Repository, u *user_m RepoID: repo.ID, UserID: u.ID, } - e := db.GetEngine(ctx) - has, err := e.Get(collaboration) + has, err := db.GetByBean(ctx, collaboration) if err != nil { return err } else if has { @@ -35,7 +34,7 @@ func addCollaborator(ctx context.Context, repo *repo_model.Repository, u *user_m } collaboration.Mode = perm.AccessModeWrite - if _, err = e.InsertOne(collaboration); err != nil { + if err = db.Insert(ctx, collaboration); err != nil { return err } diff --git a/models/repo_list.go b/models/repo_list.go index 906b7548d4a64..45fb10c3642bf 100644 --- a/models/repo_list.go +++ b/models/repo_list.go @@ -556,12 +556,15 @@ func searchRepositoryByCondition(ctx context.Context, opts *SearchRepoOptions, c opts.OrderBy = db.SearchOrderByAlphabetically } + args := make([]interface{}, 0) if opts.PriorityOwnerID > 0 { - opts.OrderBy = db.SearchOrderBy(fmt.Sprintf("CASE WHEN owner_id = %d THEN 0 ELSE owner_id END, %s", opts.PriorityOwnerID, opts.OrderBy)) + opts.OrderBy = db.SearchOrderBy(fmt.Sprintf("CASE WHEN owner_id = ? THEN 0 ELSE owner_id END, %s", opts.OrderBy)) + args = append(args, opts.PriorityOwnerID) } else if strings.Count(opts.Keyword, "/") == 1 { // With "owner/repo" search times, prioritise results which match the owner field orgName := strings.Split(opts.Keyword, "/")[0] - opts.OrderBy = db.SearchOrderBy(fmt.Sprintf("CASE WHEN owner_name LIKE '%s' THEN 0 ELSE 1 END, %s", orgName, opts.OrderBy)) + opts.OrderBy = db.SearchOrderBy(fmt.Sprintf("CASE WHEN owner_name LIKE ? THEN 0 ELSE 1 END, %s", opts.OrderBy)) + args = append(args, orgName) } sess := db.GetEngine(ctx) @@ -577,7 +580,7 @@ func searchRepositoryByCondition(ctx context.Context, opts *SearchRepoOptions, c } } - sess = sess.Where(cond).OrderBy(opts.OrderBy.String()) + sess = sess.Where(cond).OrderBy(opts.OrderBy.String(), args...) if opts.PageSize > 0 { sess = sess.Limit(opts.PageSize, (opts.Page-1)*opts.PageSize) } From 744e45218579fe2fd130b91d9fb95ec4becd314d Mon Sep 17 00:00:00 2001 From: Gusted Date: Sat, 4 Jun 2022 20:10:54 +0000 Subject: [PATCH 04/11] Move `/info` outside authorization (#19888) - To use the web's API to get information about a issue/pull on a repository, doesn't require authorization(nor that the repository isn't archived). - Regressed by: #19318 Signed-off-by: Andrew Thornton Co-authored-by: Andrew Thornton --- routers/web/repo/issue.go | 15 +++++++++++++++ routers/web/web.go | 6 +++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go index 079ccbf6cf968..d418907a1f17c 100644 --- a/routers/web/repo/issue.go +++ b/routers/web/repo/issue.go @@ -1799,6 +1799,21 @@ func GetIssueInfo(ctx *context.Context) { } return } + + if issue.IsPull { + // Need to check if Pulls are enabled and we can read Pulls + if !ctx.Repo.Repository.CanEnablePulls() || !ctx.Repo.CanRead(unit.TypePullRequests) { + ctx.Error(http.StatusNotFound) + return + } + } else { + // Need to check if Issues are enabled and we can read Issues + if !ctx.Repo.CanRead(unit.TypeIssues) { + ctx.Error(http.StatusNotFound) + return + } + } + ctx.JSON(http.StatusOK, convert.ToAPIIssue(issue)) } diff --git a/routers/web/web.go b/routers/web/web.go index 1e550286f9eb1..3e837c62d09d1 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -835,6 +835,11 @@ func RegisterRoutes(m *web.Route) { m.Combo("/compare/*", repo.MustBeNotEmpty, reqRepoCodeReader, repo.SetEditorconfigIfExists). Get(ignSignIn, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.CompareDiff). Post(reqSignIn, context.RepoMustNotBeArchived(), reqRepoPullsReader, repo.MustAllowPulls, bindIgnErr(forms.CreateIssueForm{}), repo.SetWhitespaceBehavior, repo.CompareAndPullRequestPost) + m.Group("/{type:issues|pulls}", func() { + m.Group("/{index}", func() { + m.Get("/info", repo.GetIssueInfo) + }) + }) }, context.RepoAssignment, context.UnitTypes()) // Grouping for those endpoints that do require authentication @@ -851,7 +856,6 @@ func RegisterRoutes(m *web.Route) { // So they can apply their own enable/disable logic on routers. m.Group("/{type:issues|pulls}", func() { m.Group("/{index}", func() { - m.Get("/info", repo.GetIssueInfo) m.Post("/title", repo.UpdateIssueTitle) m.Post("/content", repo.UpdateIssueContent) m.Post("/deadline", bindIgnErr(structs.EditDeadlineOption{}), repo.UpdateIssueDeadline) From 090d89e0f9db2bbbe6bc63d887647e2f898c0a18 Mon Sep 17 00:00:00 2001 From: Mai-Lapyst <67418776+Mai-Lapyst@users.noreply.github.com> Date: Sat, 4 Jun 2022 22:12:14 +0200 Subject: [PATCH 05/11] Fixing wrong paging when filtering on the issue dashboard (#19801) Fixes #19791 by adding an check if filtering after any repo; if yes, simply set the total count for the pageing to the sum of the issue count for each selected repo by utilize `issueCountByRepo`. Fix #19791 --- routers/web/user/home.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/routers/web/user/home.go b/routers/web/user/home.go index 297d76d4aa582..1412f6cfef2e3 100644 --- a/routers/web/user/home.go +++ b/routers/web/user/home.go @@ -610,6 +610,12 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) { shownIssues = int(issueStats.ClosedCount) ctx.Data["TotalIssueCount"] = shownIssues } + if len(repoIDs) != 0 { + shownIssues = 0 + for _, repoID := range repoIDs { + shownIssues += int(issueCountByRepo[repoID]) + } + } ctx.Data["IsShowClosed"] = isShowClosed From abb7d4ae5d1bb96e89a87de475a0453ce85f6404 Mon Sep 17 00:00:00 2001 From: Gusted Date: Sat, 4 Jun 2022 21:43:25 +0000 Subject: [PATCH 06/11] Fix typo (#19889) --- integrations/testlogger.go | 2 +- models/migrations/testlogger_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/integrations/testlogger.go b/integrations/testlogger.go index 70efa95cce91c..373ad80752d33 100644 --- a/integrations/testlogger.go +++ b/integrations/testlogger.go @@ -126,7 +126,7 @@ func PrintCurrentTest(t testing.TB, skip ...int) func() { if log.CanColorStdout { fmt.Fprintf(os.Stdout, "+++ %s is a slow test (took %v)\n", fmt.Formatter(log.NewColoredValue(t.Name(), log.Bold, log.FgYellow)), fmt.Formatter(log.NewColoredValue(took, log.Bold, log.FgYellow))) } else { - fmt.Fprintf(os.Stdout, "+++ %s is a slow tets (took %v)\n", t.Name(), took) + fmt.Fprintf(os.Stdout, "+++ %s is a slow test (took %v)\n", t.Name(), took) } } timer := time.AfterFunc(slowFlush, func() { diff --git a/models/migrations/testlogger_test.go b/models/migrations/testlogger_test.go index c087e311c2aea..adbf19c0dbed6 100644 --- a/models/migrations/testlogger_test.go +++ b/models/migrations/testlogger_test.go @@ -111,7 +111,7 @@ func PrintCurrentTest(t testing.TB, skip ...int) func() { if log.CanColorStdout { fmt.Fprintf(os.Stdout, "+++ %s is a slow test (took %v)\n", fmt.Formatter(log.NewColoredValue(t.Name(), log.Bold, log.FgYellow)), fmt.Formatter(log.NewColoredValue(took, log.Bold, log.FgYellow))) } else { - fmt.Fprintf(os.Stdout, "+++ %s is a slow tets (took %v)\n", t.Name(), took) + fmt.Fprintf(os.Stdout, "+++ %s is a slow test (took %v)\n", t.Name(), took) } } timer := time.AfterFunc(slowFlush, func() { From dadcaa48369c809c1f22315ddd7db01f33a7ad24 Mon Sep 17 00:00:00 2001 From: Bo-Yi Wu Date: Sun, 5 Jun 2022 10:42:24 +0800 Subject: [PATCH 07/11] fix(CI/CD): correct CI variable. (#19886) default value is true for CI variable see https://docs.drone.io/pipeline/environment/reference/ci/ Signed-off-by: Bo-Yi Wu Co-authored-by: Lunny Xiao --- Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 8ce7a0aa63f07..d2ed8d3294691 100644 --- a/Makefile +++ b/Makefile @@ -616,27 +616,27 @@ release-windows: | $(DIST_DIRS) ifeq (,$(findstring gogit,$(TAGS))) CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) run $(XGO_PACKAGE) -go $(XGO_VERSION) -buildmode exe -dest $(DIST)/binaries -tags 'netgo osusergo gogit $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'windows/*' -out gitea-$(VERSION)-gogit . endif -ifeq ($(CI),drone) +ifeq ($(CI),true) cp /build/* $(DIST)/binaries endif .PHONY: release-linux release-linux: | $(DIST_DIRS) CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) run $(XGO_PACKAGE) -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets '$(LINUX_ARCHS)' -out gitea-$(VERSION) . -ifeq ($(CI),drone) +ifeq ($(CI),true) cp /build/* $(DIST)/binaries endif .PHONY: release-darwin release-darwin: | $(DIST_DIRS) CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) run $(XGO_PACKAGE) -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '$(LDFLAGS)' -targets 'darwin-10.12/amd64,darwin-10.12/arm64' -out gitea-$(VERSION) . -ifeq ($(CI),drone) +ifeq ($(CI),true) cp /build/* $(DIST)/binaries endif .PHONY: release-copy release-copy: | $(DIST_DIRS) - cd $(DIST); for file in `find /build -type f -name "*"`; do cp $${file} ./release/; done; + cd $(DIST); for file in `find . -type f -name "*"`; do cp $${file} ./release/; done; .PHONY: release-check release-check: | $(DIST_DIRS) From 48be5e77e502f88cae104735ee706c2fbeab8a2a Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Sun, 5 Jun 2022 12:24:51 +0800 Subject: [PATCH 08/11] Increment tests time out from 40m to 50m because sometimes the machine is slow (#19887) --- .drone.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.drone.yml b/.drone.yml index ce922f8c60f66..1aac10a828093 100644 --- a/.drone.yml +++ b/.drone.yml @@ -331,7 +331,7 @@ steps: image: gitea/test_env:linux-amd64 # https://gitea.com/gitea/test-env user: gitea commands: - - timeout -s ABRT 40m make test-mysql8-migration test-mysql8 + - timeout -s ABRT 50m make test-mysql8-migration test-mysql8 environment: GOPROXY: https://goproxy.io TAGS: bindata @@ -469,7 +469,7 @@ steps: image: gitea/test_env:linux-arm64 # https://gitea.com/gitea/test-env user: gitea commands: - - timeout -s ABRT 40m make test-sqlite-migration test-sqlite + - timeout -s ABRT 50m make test-sqlite-migration test-sqlite environment: GOPROXY: https://goproxy.io TAGS: bindata gogit sqlite sqlite_unlock_notify @@ -485,7 +485,7 @@ steps: image: gitea/test_env:linux-arm64 # https://gitea.com/gitea/test-env user: gitea commands: - - timeout -s ABRT 40m make test-pgsql-migration test-pgsql + - timeout -s ABRT 50m make test-pgsql-migration test-pgsql environment: GOPROXY: https://goproxy.io TAGS: bindata gogit From e528e2b435466bd854b1f7a4619bdc16c058b8ba Mon Sep 17 00:00:00 2001 From: Wim Date: Sun, 5 Jun 2022 09:16:14 +0200 Subject: [PATCH 09/11] Implement http signatures support for the API (#17565) Fixes #12338 This allows use to talk to the API with our ssh certificate (and/or ssh-agent) without needing to fetch an API key or tokens. It will just automatically work when users have added their ssh principal in gitea. This needs client code in tea Update: also support normal pubkeys ref: https://tools.ietf.org/html/draft-cavage-http-signatures Co-authored-by: Lunny Xiao Co-authored-by: zeripath Signed-off-by: Andrew Thornton --- go.mod | 1 + go.sum | 2 + integrations/api_httpsig_test.go | 137 +++++++++++++++++++ integrations/mssql.ini.tmpl | 1 + integrations/mysql.ini.tmpl | 1 + integrations/mysql8.ini.tmpl | 1 + integrations/pgsql.ini.tmpl | 1 + integrations/sqlite.ini.tmpl | 1 + modules/ssh/ssh.go | 3 +- routers/api/v1/api.go | 1 + services/auth/httpsign.go | 217 +++++++++++++++++++++++++++++++ 11 files changed, 365 insertions(+), 1 deletion(-) create mode 100644 integrations/api_httpsig_test.go create mode 100644 services/auth/httpsign.go diff --git a/go.mod b/go.mod index 82d137d360450..ed86dcdd9f855 100644 --- a/go.mod +++ b/go.mod @@ -29,6 +29,7 @@ require ( github.com/go-chi/chi/v5 v5.0.7 github.com/go-chi/cors v1.2.1 github.com/go-enry/go-enry/v2 v2.8.2 + github.com/go-fed/httpsig v1.1.0 github.com/go-git/go-billy/v5 v5.3.1 github.com/go-git/go-git/v5 v5.4.3-0.20210630082519-b4368b2a2ca4 github.com/go-ldap/ldap/v3 v3.4.3 diff --git a/go.sum b/go.sum index d351992b1be73..e962391334963 100644 --- a/go.sum +++ b/go.sum @@ -468,6 +468,8 @@ github.com/go-enry/go-enry/v2 v2.8.2 h1:uiGmC+3K8sVd/6DOe2AOJEOihJdqda83nPyJNtMR github.com/go-enry/go-enry/v2 v2.8.2/go.mod h1:GVzIiAytiS5uT/QiuakK7TF1u4xDab87Y8V5EJRpsIQ= github.com/go-enry/go-oniguruma v1.2.1 h1:k8aAMuJfMrqm/56SG2lV9Cfti6tC4x8673aHCcBk+eo= github.com/go-enry/go-oniguruma v1.2.1/go.mod h1:bWDhYP+S6xZQgiRL7wlTScFYBe023B6ilRZbCAD5Hf4= +github.com/go-fed/httpsig v1.1.0 h1:9M+hb0jkEICD8/cAiNqEB66R87tTINszBRTjwjQzWcI= +github.com/go-fed/httpsig v1.1.0/go.mod h1:RCMrTZvN1bJYtofsG4rd5NaO5obxQ5xBkdiS7xsT7bM= github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= github.com/go-git/go-billy/v5 v5.2.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= diff --git a/integrations/api_httpsig_test.go b/integrations/api_httpsig_test.go new file mode 100644 index 0000000000000..7197e9afb9921 --- /dev/null +++ b/integrations/api_httpsig_test.go @@ -0,0 +1,137 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package integrations + +import ( + "encoding/base64" + "fmt" + "net/http" + "net/url" + "testing" + + api "code.gitea.io/gitea/modules/structs" + + "github.com/go-fed/httpsig" + "golang.org/x/crypto/ssh" +) + +const ( + httpsigPrivateKey = `-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABFwAAAAdzc2gtcn +NhAAAAAwEAAQAAAQEAqjmQeb5Eb1xV7qbNf9ErQ0XRvKZWzUsLFhJzZz+Ab7q8WtPs91vQ +fBiypw4i8OTG6WzDcgZaV8Ndxn7iHnIstdA1k89MVG4stydymmwmk9+mrCMNsu5OmdIy9F +AZ61RDcKuf5VG2WKkmeK0VO+OMJIYfE1C6czNeJ6UAmcIOmhGxvjMI83XUO9n0ftwTwayp ++XU5prvKx/fTvlPjbraPNU4OzwPjVLqXBzpoXYhBquPaZYFRVyvfFZLObYsmy+BrsxcloM +l+9w4P0ATJ9njB7dRDL+RrN4uhhYSihqOK4w4vaiOj1+aA0eC0zXunEfLXfGIVQ/FhWcCy +5f72mMiKnQAAA9AxSmzFMUpsxQAAAAdzc2gtcnNhAAABAQCqOZB5vkRvXFXups1/0StDRd +G8plbNSwsWEnNnP4Bvurxa0+z3W9B8GLKnDiLw5MbpbMNyBlpXw13GfuIeciy10DWTz0xU +biy3J3KabCaT36asIw2y7k6Z0jL0UBnrVENwq5/lUbZYqSZ4rRU744wkhh8TULpzM14npQ +CZwg6aEbG+MwjzddQ72fR+3BPBrKn5dTmmu8rH99O+U+Nuto81Tg7PA+NUupcHOmhdiEGq +49plgVFXK98Vks5tiybL4GuzFyWgyX73Dg/QBMn2eMHt1EMv5Gs3i6GFhKKGo4rjDi9qI6 +PX5oDR4LTNe6cR8td8YhVD8WFZwLLl/vaYyIqdAAAAAwEAAQAAAQBz+nyBNi2SYir6SxPA +flcnoq5gBkUl4ndPNosCUbXEakpi5/mQHzJRGtK+F1efIYCVEdGoIsPy/90onNKbQ9dKmO +2oI5kx/U7iCzJ+HCm8nqkEp21x+AP9scWdx+Wg/OxmG8j5iU7f4X+gwOyyvTqCuA78Lgia +7Oi9wiJCoIEqXr6dRYGJzfASwKA2dj995HzATexleLSD5fQCmZTF+Vh5OQ5WmE+c53JdZS +T3Plie/P/smgSWBtf1fWr6JL2+EBsqQsIK1Jo7r/7rxsz+ILoVfnneNQY4QSa9W+t6ZAI+ +caSA0Guv7vC92ewjlMVlwKa3XaEjMJb5sFlg1r6TYMwBAAAAgQDQwXvgSXNaSHIeH53/Ab +t4BlNibtxK8vY8CZFloAKXkjrivKSlDAmQCM0twXOweX2ScPjE+XlSMV4AUsv/J6XHGHci +W3+PGIBfc/fQRBpiyhzkoXYDVrlkSKHffCnAqTUQlYkhr0s7NkZpEeqPE0doAUs4dK3Iqb +zdtz8e5BPXZwAAAIEA4U/JskIu5Oge8Is2OLOhlol0EJGw5JGodpFyhbMC+QYK9nYqy7wI +a6mZ2EfOjjwIZD/+wYyulw6cRve4zXwgzUEXLIKp8/H3sYvJK2UMeP7y68sQFqGxbm6Rnh +tyBBSaJQnOXVOFf9gqZGCyO/J0Illg3AXTuC8KS/cxwasC38EAAACBAMFo/6XQoR6E3ynj +VBaz2SilWqQBixUyvcNz8LY73IIDCecoccRMFSEKhWtvlJijxvFbF9M8g9oKAVPuub4V5r +CGmwVPEd5yt4C2iyV0PhLp1PA2/i42FpCSnHaz/EXSz6ncTZcOMMuDqUbgUUpQg4VSUDl9 +fhTNAzWwZoQ91aHdAAAAFHUwMDIyMTQ2QGljdHMtcC1ueC03AQIDBAUG +-----END OPENSSH PRIVATE KEY-----` + httpsigCertificate = `ssh-rsa-cert-v01@openssh.com AAAAHHNzaC1yc2EtY2VydC12MDFAb3BlbnNzaC5jb20AAAAgiR7SU8gmZLhopx4Y03nOXVuAb+4fyMcJYjMGcE1Z2oEAAAADAQABAAABAQCqOZB5vkRvXFXups1/0StDRdG8plbNSwsWEnNnP4Bvurxa0+z3W9B8GLKnDiLw5MbpbMNyBlpXw13GfuIeciy10DWTz0xUbiy3J3KabCaT36asIw2y7k6Z0jL0UBnrVENwq5/lUbZYqSZ4rRU744wkhh8TULpzM14npQCZwg6aEbG+MwjzddQ72fR+3BPBrKn5dTmmu8rH99O+U+Nuto81Tg7PA+NUupcHOmhdiEGq49plgVFXK98Vks5tiybL4GuzFyWgyX73Dg/QBMn2eMHt1EMv5Gs3i6GFhKKGo4rjDi9qI6PX5oDR4LTNe6cR8td8YhVD8WFZwLLl/vaYyIqdAAAAAAAAAAEAAAABAAAABXVzZXIxAAAACQAAAAV1c2VyMQAAAABimoIOAAAAAMCWkRMAAAAAAAAAggAAABVwZXJtaXQtWDExLWZvcndhcmRpbmcAAAAAAAAAF3Blcm1pdC1hZ2VudC1mb3J3YXJkaW5nAAAAAAAAABZwZXJtaXQtcG9ydC1mb3J3YXJkaW5nAAAAAAAAAApwZXJtaXQtcHR5AAAAAAAAAA5wZXJtaXQtdXNlci1yYwAAAAAAAAAAAAABlwAAAAdzc2gtcnNhAAAAAwEAAQAAAYEAm+AwtXTBZyeqV1qOxjMU3Ibc5iR2M3zerGfRQDxUeIozC3xpIvqJbzjDuRapdf8hpxn2xC0GtUusuLIUr4/+Svs1BUnJhF2H9xnK/O0aopS5MpNekUvnBzQdbvO8Ux2xE2mt58giXhkEaXeCEODSqG++OZsA2e40AR/AGRJ4OdDofMvH4vLJAQQc2mKdYpYL8xu+NC+7nsenx1etpsqtEl3gmvqCVI6t9uhVPMvlbGt9h/AN3u7ToF2T3bdk1TZbcdkvR9ljvETIuy32ksAETX8tc7vm30edK+nn/GMeWCgjM+MFm9Uh1NRkvNNJozo5SJy0DkWETTJUsEdfry5VQ3IjqhWqQ0m4/mDlTmsEdEdWqpUiqWZLd9w7jgT8fanuglZyIu2fj8fyqjPjiws5S2P0Uvi28UKQ1nH01UYj/kuakU3BNzN1IqDf3tARP9fjKV/dCBqb1ZAOtyC2GyhGuGzNwEi+woUwq+sTeV0/hqVSb3hSitXHzcfRMRyOK82BAAABlAAAAAxyc2Etc2hhMi01MTIAAAGAMBfgZFvz4BdxriGKYd6eRhMo6hf+I8S9uzNRsflJXHuA+HR9ExIm/Q9JjKmfThQzNyGGBOBILaDU205SAJuG+kk3SieSQDd75ZQd8YmNlCc+516AriOsTiyVCupnf3I2euTjMZqEZbJcBbkBljppTOWQVN7xxE8QakDfGhg0+RjJE9wYOTmkKpDBfII5Nw8V5DoOD7kNEpXYqHdy/8lVxpqUYNIP1J0dNP4f6qBcZcM1PDA12q8zwIGqSNNjf2UXY/Nr8nv9CnK4fB8NDOPKTBa4cm48BGbvM/X0l6dYKswuZ9Np8lw+y6+GxTgznGCrkzMmuEV4FzSq4xHp41H2L2MTwUkwYaeyG1VP6aWkvn6zPkSxaaJDfQX7CAFe17IhIGXR0UPLjKjh35nDLzMWb/W6/W1lK9YkZNHXSf7Z9m9MUAZN7yQgOggGsuYEW4imZxvZizMd+fdDu9mbhr0FDis89I7MSJDnyYRE9FXS7p3QpppBwGcss/9yV3JV3Bjc` +) + +func TestHTTPSigPubKey(t *testing.T) { + // Add our public key to user1 + defer prepareTestEnv(t)() + session := loginUser(t, "user1") + token := url.QueryEscape(getTokenForLoggedInUser(t, session)) + keysURL := fmt.Sprintf("/api/v1/user/keys?token=%s", token) + keyType := "ssh-rsa" + keyContent := "AAAAB3NzaC1yc2EAAAADAQABAAABAQCqOZB5vkRvXFXups1/0StDRdG8plbNSwsWEnNnP4Bvurxa0+z3W9B8GLKnDiLw5MbpbMNyBlpXw13GfuIeciy10DWTz0xUbiy3J3KabCaT36asIw2y7k6Z0jL0UBnrVENwq5/lUbZYqSZ4rRU744wkhh8TULpzM14npQCZwg6aEbG+MwjzddQ72fR+3BPBrKn5dTmmu8rH99O+U+Nuto81Tg7PA+NUupcHOmhdiEGq49plgVFXK98Vks5tiybL4GuzFyWgyX73Dg/QBMn2eMHt1EMv5Gs3i6GFhKKGo4rjDi9qI6PX5oDR4LTNe6cR8td8YhVD8WFZwLLl/vaYyIqd" + rawKeyBody := api.CreateKeyOption{ + Title: "test-key", + Key: keyType + " " + keyContent, + } + req := NewRequestWithJSON(t, "POST", keysURL, rawKeyBody) + session.MakeRequest(t, req, http.StatusCreated) + + // parse our private key and create the httpsig request + sshSigner, _ := ssh.ParsePrivateKey([]byte(httpsigPrivateKey)) + keyID := ssh.FingerprintSHA256(sshSigner.PublicKey()) + + // create the request + req = NewRequest(t, "GET", "/api/v1/admin/users") + + signer, _, err := httpsig.NewSSHSigner(sshSigner, httpsig.DigestSha512, []string{httpsig.RequestTarget, "(created)", "(expires)"}, httpsig.Signature, 10) + if err != nil { + t.Fatal(err) + } + + // sign the request + err = signer.SignRequest(keyID, req, nil) + if err != nil { + t.Fatal(err) + } + + // make the request + MakeRequest(t, req, http.StatusOK) +} + +func TestHTTPSigCert(t *testing.T) { + // Add our public key to user1 + defer prepareTestEnv(t)() + session := loginUser(t, "user1") + + csrf := GetCSRF(t, session, "/user/settings/keys") + req := NewRequestWithValues(t, "POST", "/user/settings/keys", map[string]string{ + "_csrf": csrf, + "content": "user1", + "title": "principal", + "type": "principal", + }) + + session.MakeRequest(t, req, http.StatusSeeOther) + pkcert, _, _, _, err := ssh.ParseAuthorizedKey([]byte(httpsigCertificate)) + if err != nil { + t.Fatal(err) + } + + // parse our private key and create the httpsig request + sshSigner, _ := ssh.ParsePrivateKey([]byte(httpsigPrivateKey)) + keyID := "gitea" + + // create our certificate signer using the ssh signer and our certificate + certSigner, err := ssh.NewCertSigner(pkcert.(*ssh.Certificate), sshSigner) + if err != nil { + t.Fatal(err) + } + + // create the request + req = NewRequest(t, "GET", "/api/v1/admin/users") + + // add our cert to the request + certString := base64.RawStdEncoding.EncodeToString(pkcert.(*ssh.Certificate).Marshal()) + req.Header.Add("x-ssh-certificate", certString) + + signer, _, err := httpsig.NewSSHSigner(certSigner, httpsig.DigestSha512, []string{httpsig.RequestTarget, "(created)", "(expires)", "x-ssh-certificate"}, httpsig.Signature, 10) + if err != nil { + t.Fatal(err) + } + + // sign the request + err = signer.SignRequest(keyID, req, nil) + if err != nil { + t.Fatal(err) + } + + // make the request + MakeRequest(t, req, http.StatusOK) +} diff --git a/integrations/mssql.ini.tmpl b/integrations/mssql.ini.tmpl index b076bb863c72b..da15e9ef69ee4 100644 --- a/integrations/mssql.ini.tmpl +++ b/integrations/mssql.ini.tmpl @@ -49,6 +49,7 @@ OFFLINE_MODE = false LFS_JWT_SECRET = Tv_MjmZuHqpIY6GFl12ebgkRAMt4RlWt0v4EHKSXO0w APP_DATA_PATH = integrations/gitea-integration-mssql/data BUILTIN_SSH_SERVER_USER = git +SSH_TRUSTED_USER_CA_KEYS = ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCb4DC1dMFnJ6pXWo7GMxTchtzmJHYzfN6sZ9FAPFR4ijMLfGki+olvOMO5Fql1/yGnGfbELQa1S6y4shSvj/5K+zUFScmEXYf3Gcr87RqilLkyk16RS+cHNB1u87xTHbETaa3nyCJeGQRpd4IQ4NKob745mwDZ7jQBH8AZEng50Oh8y8fi8skBBBzaYp1ilgvzG740L7uex6fHV62myq0SXeCa+oJUjq326FU8y+Vsa32H8A3e7tOgXZPdt2TVNltx2S9H2WO8RMi7LfaSwARNfy1zu+bfR50r6ef8Yx5YKCMz4wWb1SHU1GS800mjOjlInLQORYRNMlSwR1+vLlVDciOqFapDSbj+YOVOawR0R1aqlSKpZkt33DuOBPx9qe6CVnIi7Z+Px/KqM+OLCzlLY/RS+LbxQpDWcfTVRiP+S5qRTcE3M3UioN/e0BE/1+MpX90IGpvVkA63ILYbKEa4bM3ASL7ChTCr6xN5XT+GpVJveFKK1cfNx9ExHI4rzYE= [attachment] PATH = integrations/gitea-integration-mssql/data/attachments diff --git a/integrations/mysql.ini.tmpl b/integrations/mysql.ini.tmpl index 6a0fd4ab86b77..4df49336424a6 100644 --- a/integrations/mysql.ini.tmpl +++ b/integrations/mysql.ini.tmpl @@ -51,6 +51,7 @@ OFFLINE_MODE = false LFS_START_SERVER = true LFS_JWT_SECRET = Tv_MjmZuHqpIY6GFl12ebgkRAMt4RlWt0v4EHKSXO0w +SSH_TRUSTED_USER_CA_KEYS = ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCb4DC1dMFnJ6pXWo7GMxTchtzmJHYzfN6sZ9FAPFR4ijMLfGki+olvOMO5Fql1/yGnGfbELQa1S6y4shSvj/5K+zUFScmEXYf3Gcr87RqilLkyk16RS+cHNB1u87xTHbETaa3nyCJeGQRpd4IQ4NKob745mwDZ7jQBH8AZEng50Oh8y8fi8skBBBzaYp1ilgvzG740L7uex6fHV62myq0SXeCa+oJUjq326FU8y+Vsa32H8A3e7tOgXZPdt2TVNltx2S9H2WO8RMi7LfaSwARNfy1zu+bfR50r6ef8Yx5YKCMz4wWb1SHU1GS800mjOjlInLQORYRNMlSwR1+vLlVDciOqFapDSbj+YOVOawR0R1aqlSKpZkt33DuOBPx9qe6CVnIi7Z+Px/KqM+OLCzlLY/RS+LbxQpDWcfTVRiP+S5qRTcE3M3UioN/e0BE/1+MpX90IGpvVkA63ILYbKEa4bM3ASL7ChTCr6xN5XT+GpVJveFKK1cfNx9ExHI4rzYE= [lfs] MINIO_BASE_PATH = lfs/ diff --git a/integrations/mysql8.ini.tmpl b/integrations/mysql8.ini.tmpl index 16f8851fe527f..4b63dd51a1fdd 100644 --- a/integrations/mysql8.ini.tmpl +++ b/integrations/mysql8.ini.tmpl @@ -49,6 +49,7 @@ OFFLINE_MODE = false LFS_JWT_SECRET = Tv_MjmZuHqpIY6GFl12ebgkRAMt4RlWt0v4EHKSXO0w APP_DATA_PATH = integrations/gitea-integration-mysql8/data BUILTIN_SSH_SERVER_USER = git +SSH_TRUSTED_USER_CA_KEYS = ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCb4DC1dMFnJ6pXWo7GMxTchtzmJHYzfN6sZ9FAPFR4ijMLfGki+olvOMO5Fql1/yGnGfbELQa1S6y4shSvj/5K+zUFScmEXYf3Gcr87RqilLkyk16RS+cHNB1u87xTHbETaa3nyCJeGQRpd4IQ4NKob745mwDZ7jQBH8AZEng50Oh8y8fi8skBBBzaYp1ilgvzG740L7uex6fHV62myq0SXeCa+oJUjq326FU8y+Vsa32H8A3e7tOgXZPdt2TVNltx2S9H2WO8RMi7LfaSwARNfy1zu+bfR50r6ef8Yx5YKCMz4wWb1SHU1GS800mjOjlInLQORYRNMlSwR1+vLlVDciOqFapDSbj+YOVOawR0R1aqlSKpZkt33DuOBPx9qe6CVnIi7Z+Px/KqM+OLCzlLY/RS+LbxQpDWcfTVRiP+S5qRTcE3M3UioN/e0BE/1+MpX90IGpvVkA63ILYbKEa4bM3ASL7ChTCr6xN5XT+GpVJveFKK1cfNx9ExHI4rzYE= [attachment] PATH = integrations/gitea-integration-mysql8/data/attachments diff --git a/integrations/pgsql.ini.tmpl b/integrations/pgsql.ini.tmpl index 5c4fbcc829626..5b54a02c9fac8 100644 --- a/integrations/pgsql.ini.tmpl +++ b/integrations/pgsql.ini.tmpl @@ -50,6 +50,7 @@ OFFLINE_MODE = false LFS_JWT_SECRET = Tv_MjmZuHqpIY6GFl12ebgkRAMt4RlWt0v4EHKSXO0w APP_DATA_PATH = integrations/gitea-integration-pgsql/data BUILTIN_SSH_SERVER_USER = git +SSH_TRUSTED_USER_CA_KEYS = ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCb4DC1dMFnJ6pXWo7GMxTchtzmJHYzfN6sZ9FAPFR4ijMLfGki+olvOMO5Fql1/yGnGfbELQa1S6y4shSvj/5K+zUFScmEXYf3Gcr87RqilLkyk16RS+cHNB1u87xTHbETaa3nyCJeGQRpd4IQ4NKob745mwDZ7jQBH8AZEng50Oh8y8fi8skBBBzaYp1ilgvzG740L7uex6fHV62myq0SXeCa+oJUjq326FU8y+Vsa32H8A3e7tOgXZPdt2TVNltx2S9H2WO8RMi7LfaSwARNfy1zu+bfR50r6ef8Yx5YKCMz4wWb1SHU1GS800mjOjlInLQORYRNMlSwR1+vLlVDciOqFapDSbj+YOVOawR0R1aqlSKpZkt33DuOBPx9qe6CVnIi7Z+Px/KqM+OLCzlLY/RS+LbxQpDWcfTVRiP+S5qRTcE3M3UioN/e0BE/1+MpX90IGpvVkA63ILYbKEa4bM3ASL7ChTCr6xN5XT+GpVJveFKK1cfNx9ExHI4rzYE= [attachment] PATH = integrations/gitea-integration-pgsql/data/attachments diff --git a/integrations/sqlite.ini.tmpl b/integrations/sqlite.ini.tmpl index c180148891100..2da7fd65d392b 100644 --- a/integrations/sqlite.ini.tmpl +++ b/integrations/sqlite.ini.tmpl @@ -46,6 +46,7 @@ LFS_JWT_SECRET = Tv_MjmZuHqpIY6GFl12ebgkRAMt4RlWt0v4EHKSXO0w APP_DATA_PATH = integrations/gitea-integration-sqlite/data ENABLE_GZIP = true BUILTIN_SSH_SERVER_USER = git +SSH_TRUSTED_USER_CA_KEYS = ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCb4DC1dMFnJ6pXWo7GMxTchtzmJHYzfN6sZ9FAPFR4ijMLfGki+olvOMO5Fql1/yGnGfbELQa1S6y4shSvj/5K+zUFScmEXYf3Gcr87RqilLkyk16RS+cHNB1u87xTHbETaa3nyCJeGQRpd4IQ4NKob745mwDZ7jQBH8AZEng50Oh8y8fi8skBBBzaYp1ilgvzG740L7uex6fHV62myq0SXeCa+oJUjq326FU8y+Vsa32H8A3e7tOgXZPdt2TVNltx2S9H2WO8RMi7LfaSwARNfy1zu+bfR50r6ef8Yx5YKCMz4wWb1SHU1GS800mjOjlInLQORYRNMlSwR1+vLlVDciOqFapDSbj+YOVOawR0R1aqlSKpZkt33DuOBPx9qe6CVnIi7Z+Px/KqM+OLCzlLY/RS+LbxQpDWcfTVRiP+S5qRTcE3M3UioN/e0BE/1+MpX90IGpvVkA63ILYbKEa4bM3ASL7ChTCr6xN5XT+GpVJveFKK1cfNx9ExHI4rzYE= [attachment] PATH = integrations/gitea-integration-sqlite/data/attachments diff --git a/modules/ssh/ssh.go b/modules/ssh/ssh.go index a240c013191ba..2affeb781a998 100644 --- a/modules/ssh/ssh.go +++ b/modules/ssh/ssh.go @@ -188,8 +188,9 @@ func publicKeyHandler(ctx ssh.Context, key ssh.PublicKey) bool { c := &gossh.CertChecker{ IsUserAuthority: func(auth gossh.PublicKey) bool { + marshaled := auth.Marshal() for _, k := range setting.SSH.TrustedUserCAKeysParsed { - if bytes.Equal(auth.Marshal(), k.Marshal()) { + if bytes.Equal(marshaled, k.Marshal()) { return true } } diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 1492ef07a7599..03f7a57d5c861 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -592,6 +592,7 @@ func bind(obj interface{}) http.HandlerFunc { func buildAuthGroup() *auth.Group { group := auth.NewGroup( &auth.OAuth2{}, + &auth.HTTPSign{}, &auth.Basic{}, // FIXME: this should be removed once we don't allow basic auth in API ) if setting.Service.EnableReverseProxyAuth { diff --git a/services/auth/httpsign.go b/services/auth/httpsign.go new file mode 100644 index 0000000000000..67053d2b77730 --- /dev/null +++ b/services/auth/httpsign.go @@ -0,0 +1,217 @@ +// Copyright 2021 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package auth + +import ( + "bytes" + "encoding/base64" + "errors" + "fmt" + "net/http" + "strings" + + asymkey_model "code.gitea.io/gitea/models/asymkey" + user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/setting" + + "github.com/go-fed/httpsig" + "golang.org/x/crypto/ssh" +) + +// Ensure the struct implements the interface. +var ( + _ Method = &HTTPSign{} + _ Named = &HTTPSign{} +) + +// HTTPSign implements the Auth interface and authenticates requests (API requests +// only) by looking for http signature data in the "Signature" header. +// more information can be found on https://github.com/go-fed/httpsig +type HTTPSign struct{} + +// Name represents the name of auth method +func (h *HTTPSign) Name() string { + return "httpsign" +} + +// 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 { + sigHead := req.Header.Get("Signature") + if len(sigHead) == 0 { + return nil + } + + var ( + publicKey *asymkey_model.PublicKey + err error + ) + + if len(req.Header.Get("X-Ssh-Certificate")) != 0 { + // Handle Signature signed by SSH certificates + if len(setting.SSH.TrustedUserCAKeys) == 0 { + return 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 + } + } else { + // Handle Signature signed by Public Key + publicKey, err = VerifyPubKey(req) + 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 + } + } + + u, err := user_model.GetUserByID(publicKey.OwnerID) + if err != nil { + log.Error("GetUserByID: %v", err) + return nil + } + + store.GetData()["IsApiToken"] = true + + log.Trace("HTTP Sign: Logged in user %-v", u) + + return u +} + +func VerifyPubKey(r *http.Request) (*asymkey_model.PublicKey, error) { + verifier, err := httpsig.NewVerifier(r) + if err != nil { + return nil, fmt.Errorf("httpsig.NewVerifier failed: %s", err) + } + + keyID := verifier.KeyId() + + publicKeys, err := asymkey_model.SearchPublicKey(0, keyID) + if err != nil { + return nil, err + } + + if len(publicKeys) == 0 { + return nil, fmt.Errorf("no public key found for keyid %s", keyID) + } + + sshPublicKey, _, _, _, err := ssh.ParseAuthorizedKey([]byte(publicKeys[0].Content)) + if err != nil { + return nil, err + } + + if err := doVerify(verifier, []ssh.PublicKey{sshPublicKey}); err != nil { + return nil, err + } + + return publicKeys[0], nil +} + +// VerifyCert verifies the validity of the ssh certificate and returns the publickey of the signer +// We verify that the certificate is signed with the correct CA +// We verify that the http request is signed with the private key (of the public key mentioned in the certificate) +func VerifyCert(r *http.Request) (*asymkey_model.PublicKey, error) { + // Get our certificate from the header + bcert, err := base64.RawStdEncoding.DecodeString(r.Header.Get("x-ssh-certificate")) + if err != nil { + return nil, err + } + + pk, err := ssh.ParsePublicKey(bcert) + if err != nil { + return nil, err + } + + // Check if it's really a ssh certificate + cert, ok := pk.(*ssh.Certificate) + if !ok { + return nil, fmt.Errorf("no certificate found") + } + + c := &ssh.CertChecker{ + IsUserAuthority: func(auth ssh.PublicKey) bool { + marshaled := auth.Marshal() + + for _, k := range setting.SSH.TrustedUserCAKeysParsed { + if bytes.Equal(marshaled, k.Marshal()) { + return true + } + } + + return false + }, + } + + // check the CA of the cert + if !c.IsUserAuthority(cert.SignatureKey) { + return nil, fmt.Errorf("CA check failed") + } + + // Create a verifier + verifier, err := httpsig.NewVerifier(r) + if err != nil { + return nil, fmt.Errorf("httpsig.NewVerifier failed: %s", err) + } + + // now verify that this request was signed with the private key that matches the certificate public key + if err := doVerify(verifier, []ssh.PublicKey{cert.Key}); err != nil { + return nil, err + } + + // Now for each of the certificate valid principals + for _, principal := range cert.ValidPrincipals { + // Look in the db for the public key + publicKey, err := asymkey_model.SearchPublicKeyByContentExact(r.Context(), principal) + if asymkey_model.IsErrKeyNotExist(err) { + // No public key matches this principal - try the next principal + continue + } else if err != nil { + // this error will be a db error therefore we can't solve this and we should abort + log.Error("SearchPublicKeyByContentExact: %v", err) + return nil, err + } + + // Validate the cert for this principal + if err := c.CheckCert(principal, cert); err != nil { + // however, because principal is a member of ValidPrincipals - if this fails then the certificate itself is invalid + return nil, err + } + + // OK we have a public key for a principal matching a valid certificate whose key has signed this request. + return publicKey, nil + } + + // No public key matching a principal in the certificate is registered in gitea + return nil, fmt.Errorf("no valid principal found") +} + +// doVerify iterates across the provided public keys attempting the verify the current request against each key in turn +func doVerify(verifier httpsig.Verifier, sshPublicKeys []ssh.PublicKey) error { + for _, publicKey := range sshPublicKeys { + cryptoPubkey := publicKey.(ssh.CryptoPublicKey).CryptoPublicKey() + + var algos []httpsig.Algorithm + + switch { + case strings.HasPrefix(publicKey.Type(), "ssh-ed25519"): + algos = []httpsig.Algorithm{httpsig.ED25519} + case strings.HasPrefix(publicKey.Type(), "ssh-rsa"): + algos = []httpsig.Algorithm{httpsig.RSA_SHA1, httpsig.RSA_SHA256, httpsig.RSA_SHA512} + } + for _, algo := range algos { + if err := verifier.Verify(cryptoPubkey, algo); err == nil { + return nil + } + } + } + + return errors.New("verification failed") +} From 89a8b3e1634e37e7ab6f1a4f919827de8fcdd89f Mon Sep 17 00:00:00 2001 From: Martijn de Boer Date: Sun, 5 Jun 2022 10:09:50 +0200 Subject: [PATCH 10/11] Limit max-height of CodeMirror editors for issue comment and wiki (#18271) * Make the wiki editor bar sticky for longer wiki edits On codeberg community it was requested to make the wiki editor toolbar sticky for longer wiki posts, so one wouldn't have to scroll to the top to use it. (Reference; https://codeberg.org/Codeberg/Community/issues/533). In order to make this happen, the .editor-toolbar class needs to become position: sticky, and we need to fix it's transparent background and border-bottom. Because the bottom disappears, we add it. This makes the border become a double border, because the CodeMirror area defines borders for all. As such I've added a border-top: none, on the wiki write tab for the CodeMirror class. * Make the issue bar in the issue view sticky for issue #10675 In issue #10675 it's requested to make the issue bar sticky upon scrolling in the issue view. The proposed change changes inline html, which is not desirable. As such I've added the position sticky option to it's container, and fix the background upon scrolling. * Make linter happy on _repository.less Fix 0px -> 0 to make the linter happy. * Make linter happy on _editor.less Fix 0px -> 0 to make the linter happy. * Change z-index to the lowest boundary of 1 As per review of @silverwind change the z-index to it's lowest requirement of 1. * Change z-index to the lowest boundary of 1 As per review of @silverwind change the z-index to it's lowest requirement of 1. * Revert changes made to wiki editor (unsticky) and add max-height Fixes the max-height to 85vh, on the proposed 90vh it just came out just slightly too large. Unstickies the changes from the sticky commits. * Revert changes for the sticky title editor Removes the changes as done by the sticky title editor. * Add max-height definition to CodeMirror-scroll Add the max-height definition for the CodeMirror-scroll class in order to generalize the changes spoken about in PR #18271 * Remove CodeMirror-scroll definition Remove the max-height in CodeMirror-scroll definition, in order to generalize it in the CodeMirror less file. As per discussion in #18271. * fine tune CodeMirror min-height/max-height Co-authored-by: 6543 <6543@obermui.de> Co-authored-by: wxiaoguang Co-authored-by: Lunny Xiao --- web_src/less/_base.less | 9 --------- web_src/less/_repository.less | 8 ++++++++ 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/web_src/less/_base.less b/web_src/less/_base.less index 461195df01804..62119fbb99187 100644 --- a/web_src/less/_base.less +++ b/web_src/less/_base.less @@ -2008,15 +2008,6 @@ table th[data-sortt-desc] { text-overflow: ellipsis; } -.dropdown:not(.selection) > .menu.review-box > * { - @media (max-height: 700px) { - .CodeMirror, - .CodeMirror-scroll { - min-height: 100px; - } - } -} - .ui.dropdown .menu .item { border-radius: 0; } diff --git a/web_src/less/_repository.less b/web_src/less/_repository.less index 37c8b9cc21696..0cae04d1154e6 100644 --- a/web_src/less/_repository.less +++ b/web_src/less/_repository.less @@ -1226,6 +1226,10 @@ height: 200px; font-family: var(--fonts-monospace); } + + .CodeMirror-scroll { + max-height: 85vh; + } } } @@ -2107,6 +2111,10 @@ } } + .form .CodeMirror-scroll { + max-height: 85vh; + } + @media @mediaSm { .dividing.header .stackable.grid .button { margin-top: 2px; From 73382d2132f8f242245d83f66c92761e0b477b91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Jaenisch?= Date: Sun, 5 Jun 2022 11:41:51 +0200 Subject: [PATCH 11/11] Add alt text to logo (#19892) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The recommended way is to use the name of the organisation followed by "logo". however, since this is my first contribution, I am not entirely sure, whether this is the best approach here. The organisation is different from the organisation you can create as part of the application. Instead, it is more related to the site hosting the instance. Plus, I don't know how to best handle it when the logo image is swapped out. Therefore, I use plain "Logo" and hope that the person visiting the site has enough context. Signed-off-by: André Jaenisch Co-authored-by: Lunny Xiao --- options/locale/locale_en-US.ini | 1 + templates/base/head_navbar.tmpl | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 5dfe9290091ce..d52fe05569496 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -2,6 +2,7 @@ home = Home dashboard = Dashboard explore = Explore help = Help +logo = Logo sign_in = Sign In sign_in_with = Sign In With sign_out = Sign Out diff --git a/templates/base/head_navbar.tmpl b/templates/base/head_navbar.tmpl index babf244f9380a..37a579142c566 100644 --- a/templates/base/head_navbar.tmpl +++ b/templates/base/head_navbar.tmpl @@ -1,7 +1,7 @@