Compare commits

..

7 commits

Author SHA1 Message Date
Nulo (he/him)
b699c23a14 Save files in local storage as umask (#21198)
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Go creates temporary files as 600, but sometimes we want the group to be able to read them (for example,
for another user to back up the storage)

This PR applies the umask to the renamed tmp files in local storage.

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
2022-09-24 15:04:53 -03:00
ad123522d5 gitea.nulo.in: Use NPM cache
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2022-09-16 20:42:21 -03:00
11aacebcf7 gitea.nulo.in: Use APK cache 2022-09-16 20:42:21 -03:00
0f8f77bb59 gitea.nulo.in: Use script to upgrade 2022-09-16 20:42:21 -03:00
4f57897640 gitea.nulo.in: Use Alpine 3.16 2022-09-16 20:42:21 -03:00
43e106a31a Add .woodpecker.yml for gitea.nulo.in 2022-09-16 20:42:21 -03:00
b27dfdcf5d Allow hidden .READMEs 2022-09-06 19:57:33 -03:00
77 changed files with 854 additions and 1188 deletions

View file

@ -4,42 +4,6 @@ This changelog goes through all the changes that have been made in each release
without substantial changes to our git log; to see the highlights of what has
been added to each release, please refer to the [blog](https://blog.gitea.io).
## [1.17.3](https://github.com/go-gitea/gitea/releases/tag/v1.17.3) - 2022-10-15
* SECURITY
* Sanitize and Escape refs in git backend (#21464) (#21463)
* Bump `golang.org/x/text` (#21412) (#21413)
* Update bluemonday (#21281) (#21287)
* ENHANCEMENTS
* Fix empty container layer history and UI (#21251) (#21278)
* Use en-US as fallback when using other default language (#21200) (#21256)
* Make the vscode clone link respect transport protocol (#20557) (#21128)
* BUGFIXES
* Do DB update after merge in hammer context (#21401) (#21416)
* Add Num{Issues,Pulls} stats checks (#21404) (#21414)
* Stop logging CheckPath returns error: context canceled (#21064) (#21405)
* Parse OAuth Authorization header when request omits client secret (#21351) (#21374)
* Ignore port for loopback redirect URIs (#21293) (#21373)
* Set SemverCompatible to false for Conan packages (#21275) (#21366)
* Tag list should include draft releases with existing tags (#21263) (#21365)
* Fix linked account translation (#21331) (#21334)
* Make NuGet service index publicly accessible (#21242) (#21277)
* Foreign ID conflicts if ID is 0 for each item (#21271) (#21272)
* Use absolute links in feeds (#21229) (#21265)
* Prevent invalid behavior for file reviewing when loading more files (#21230) (#21234)
* Respect `REQUIRE_SIGNIN_VIEW` for packages (#20873) (#21232)
* Treat git object mode 40755 as directory (#21195) (#21218)
* Allow uppercase ASCII alphabet in PyPI package names (#21095) (#21217)
* Fix limited user cannot view himself's profile (#21212)
* Fix template bug of admin monitor (#21209)
* Fix reaction of issues (#21185) (#21196)
* Fix CSV diff for added/deleted files (#21189) (#21193)
* Fix pagination limit parameter problem (#21111)
* TESTING
* Fix missing m.Run() in TestMain (#21341)
* BUILD
* Use Go 1.19 fmt for Gitea 1.17, sync emoji data (#21239)
## [1.17.2](https://github.com/go-gitea/gitea/releases/tag/v1.17.2) - 2022-09-06
* SECURITY

View file

@ -33,7 +33,7 @@ GOFUMPT_PACKAGE ?= mvdan.cc/gofumpt@v0.3.1
GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/cmd/golangci-lint@v1.46.0
GXZ_PAGAGE ?= github.com/ulikunitz/xz/cmd/gxz@v0.5.10
MISSPELL_PACKAGE ?= github.com/client9/misspell/cmd/misspell@v0.3.4
SWAGGER_PACKAGE ?= github.com/go-swagger/go-swagger/cmd/swagger@v0.30.0
SWAGGER_PACKAGE ?= github.com/go-swagger/go-swagger/cmd/swagger@v0.29.0
XGO_PACKAGE ?= src.techknowlogick.com/xgo@latest
DOCKER_IMAGE ?= gitea/gitea

File diff suppressed because one or more lines are too long

View file

@ -214,7 +214,8 @@ const hdr = `
package emoji
// Code generated by build/generate-emoji.go. DO NOT EDIT.
// Code generated by gen.go. DO NOT EDIT.
// Sourced from %s
//
var GemojiData = %#v
`

13
go.mod
View file

@ -64,7 +64,7 @@ require (
github.com/mattn/go-isatty v0.0.14
github.com/mattn/go-sqlite3 v1.14.12
github.com/mholt/archiver/v3 v3.5.1
github.com/microcosm-cc/bluemonday v1.0.20
github.com/microcosm-cc/bluemonday v1.0.19
github.com/minio/minio-go/v7 v7.0.26
github.com/msteinert/pam v1.0.0
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
@ -91,11 +91,11 @@ require (
go.jolheiser.com/hcaptcha v0.0.4
go.jolheiser.com/pwn v0.0.3
golang.org/x/crypto v0.0.0-20220507011949-2cf3adece122
golang.org/x/net v0.0.0-20220927171203-f486391704dc
golang.org/x/net v0.0.0-20220630215102-69896b714898
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10
golang.org/x/text v0.3.8
golang.org/x/tools v0.1.12
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a
golang.org/x/text v0.3.7
golang.org/x/tools v0.1.10
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
gopkg.in/ini.v1 v1.66.4
gopkg.in/yaml.v2 v2.4.0
@ -271,8 +271,9 @@ require (
go.uber.org/atomic v1.9.0 // indirect
go.uber.org/multierr v1.8.0 // indirect
go.uber.org/zap v1.21.0 // indirect
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect
golang.org/x/time v0.0.0-20220411224347-583f2d630306 // indirect
golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa // indirect
google.golang.org/grpc v1.43.0 // indirect

27
go.sum
View file

@ -1146,8 +1146,8 @@ github.com/mholt/acmez v1.0.2 h1:C8wsEBIUVi6e0DYoxqCcFuXtwc4AWXL/jgcDjF7mjVo=
github.com/mholt/acmez v1.0.2/go.mod h1:8qnn8QA/Ewx8E3ZSsmscqsIjhhpxuy9vqdgbX2ceceM=
github.com/mholt/archiver/v3 v3.5.1 h1:rDjOBX9JSF5BvoJGvjqK479aL70qh9DIpZCl+k7Clwo=
github.com/mholt/archiver/v3 v3.5.1/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4=
github.com/microcosm-cc/bluemonday v1.0.20 h1:flpzsq4KU3QIYAYGV/szUat7H+GPOXR0B2JU5A1Wp8Y=
github.com/microcosm-cc/bluemonday v1.0.20/go.mod h1:yfBmMi8mxvaZut3Yytv+jTXRY8mxyjJ0/kQBTElld50=
github.com/microcosm-cc/bluemonday v1.0.19 h1:OI7hoF5FY4pFz2VA//RN8TfM0YJ2dJcl4P4APrCWy6c=
github.com/microcosm-cc/bluemonday v1.0.19/go.mod h1:QNzV2UbLK2/53oIIwTOyLUSABMkjZ4tqiyC1g/DyqxE=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
@ -1716,8 +1716,8 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 h1:kQgndtyPBW/JIYERgdxfwMYh3AVStj88WQTlNDi2a+o=
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -1788,8 +1788,8 @@ golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qx
golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220927171203-f486391704dc h1:FxpXZdoBqT8RjqTy6i1E8nXHhW21wK7ptQ/EPIGxzPQ=
golang.org/x/net v0.0.0-20220927171203-f486391704dc/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
golang.org/x/net v0.0.0-20220630215102-69896b714898 h1:K7wO6V1IrczY9QOQ2WkVpw4JQSwCd52UsxVEirZUfiw=
golang.org/x/net v0.0.0-20220630215102-69896b714898/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -1824,8 +1824,8 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -1936,8 +1936,8 @@ golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 h1:WIoqL4EROvwiPdUtaip4VcDdpZ4kha7wBWZrbVKCIZg=
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
@ -1950,9 +1950,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@ -2046,14 +2045,16 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.1.10 h1:QjFRCZxdOhBJ/UNgnBZLbNV13DlbnK0quyivTnXJM20=
golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f h1:GGU+dLjvlC3qDwqYgL6UgRmHXhOOgns0bZu2Ty5mm6U=
golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.5.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=

View file

@ -266,7 +266,7 @@ func TestPackageConan(t *testing.T) {
pd, err := packages.GetPackageDescriptor(db.DefaultContext, pvs[0])
assert.NoError(t, err)
assert.Nil(t, pd.SemVer)
assert.NotNil(t, pd.SemVer)
assert.Equal(t, name, pd.Package.Name)
assert.Equal(t, version1, pd.Version.Version)
assert.IsType(t, &conan_module.Metadata{}, pd.Metadata)

View file

@ -14,7 +14,6 @@ import (
"code.gitea.io/gitea/models/packages"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/setting"
"github.com/stretchr/testify/assert"
)
@ -80,18 +79,6 @@ func TestPackageGeneric(t *testing.T) {
assert.Equal(t, int64(1), pvs[0].DownloadCount)
})
t.Run("RequireSignInView", func(t *testing.T) {
defer PrintCurrentTest(t)()
setting.Service.RequireSignInView = true
defer func() {
setting.Service.RequireSignInView = false
}()
req := NewRequest(t, "GET", url)
MakeRequest(t, req, http.StatusUnauthorized)
})
t.Run("Delete", func(t *testing.T) {
defer PrintCurrentTest(t)()

View file

@ -19,7 +19,6 @@ import (
user_model "code.gitea.io/gitea/models/user"
nuget_module "code.gitea.io/gitea/modules/packages/nuget"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/routers/api/packages/nuget"
"github.com/stretchr/testify/assert"
@ -66,58 +65,39 @@ func TestPackageNuGet(t *testing.T) {
t.Run("ServiceIndex", func(t *testing.T) {
defer PrintCurrentTest(t)()
privateUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{Visibility: structs.VisibleTypePrivate}).(*user_model.User)
req := NewRequest(t, "GET", fmt.Sprintf("%s/index.json", url))
req = AddBasicAuthHeader(req, user.Name)
MakeRequest(t, req, http.StatusOK)
cases := []struct {
Owner string
UseBasicAuth bool
UseTokenAuth bool
}{
{privateUser.Name, false, false},
{privateUser.Name, true, false},
{privateUser.Name, false, true},
{user.Name, false, false},
{user.Name, true, false},
{user.Name, false, true},
}
req = NewRequest(t, "GET", fmt.Sprintf("%s/index.json", url))
req = addNuGetAPIKeyHeader(req, token)
resp := MakeRequest(t, req, http.StatusOK)
for _, c := range cases {
url := fmt.Sprintf("/api/packages/%s/nuget", c.Owner)
var result nuget.ServiceIndexResponse
DecodeJSON(t, resp, &result)
req := NewRequest(t, "GET", fmt.Sprintf("%s/index.json", url))
if c.UseBasicAuth {
req = AddBasicAuthHeader(req, user.Name)
} else if c.UseTokenAuth {
req = addNuGetAPIKeyHeader(req, token)
}
resp := MakeRequest(t, req, http.StatusOK)
assert.Equal(t, "3.0.0", result.Version)
assert.NotEmpty(t, result.Resources)
var result nuget.ServiceIndexResponse
DecodeJSON(t, resp, &result)
assert.Equal(t, "3.0.0", result.Version)
assert.NotEmpty(t, result.Resources)
root := setting.AppURL + url[1:]
for _, r := range result.Resources {
switch r.Type {
case "SearchQueryService":
fallthrough
case "SearchQueryService/3.0.0-beta":
fallthrough
case "SearchQueryService/3.0.0-rc":
assert.Equal(t, root+"/query", r.ID)
case "RegistrationsBaseUrl":
fallthrough
case "RegistrationsBaseUrl/3.0.0-beta":
fallthrough
case "RegistrationsBaseUrl/3.0.0-rc":
assert.Equal(t, root+"/registration", r.ID)
case "PackageBaseAddress/3.0.0":
assert.Equal(t, root+"/package", r.ID)
case "PackagePublish/2.0.0":
assert.Equal(t, root, r.ID)
}
root := setting.AppURL + url[1:]
for _, r := range result.Resources {
switch r.Type {
case "SearchQueryService":
fallthrough
case "SearchQueryService/3.0.0-beta":
fallthrough
case "SearchQueryService/3.0.0-rc":
assert.Equal(t, root+"/query", r.ID)
case "RegistrationsBaseUrl":
fallthrough
case "RegistrationsBaseUrl/3.0.0-beta":
fallthrough
case "RegistrationsBaseUrl/3.0.0-rc":
assert.Equal(t, root+"/registration", r.ID)
case "PackageBaseAddress/3.0.0":
assert.Equal(t, root+"/package", r.ID)
case "PackagePublish/2.0.0":
assert.Equal(t, root, r.ID)
}
}
})

View file

@ -218,11 +218,6 @@ func (a *Action) GetRepoLink() string {
return path.Join(setting.AppSubURL, "/", url.PathEscape(a.GetRepoUserName()), url.PathEscape(a.GetRepoName()))
}
// GetRepoAbsoluteLink returns the absolute link to action repository.
func (a *Action) GetRepoAbsoluteLink() string {
return setting.AppURL + url.PathEscape(a.GetRepoUserName()) + "/" + url.PathEscape(a.GetRepoName())
}
// GetRepositoryFromMatch returns a *repo_model.Repository from a username and repo strings
func GetRepositoryFromMatch(ownerName, repoName string) (*repo_model.Repository, error) {
var err error

View file

@ -9,7 +9,6 @@ import (
"testing"
"code.gitea.io/gitea/models/db"
issue_model "code.gitea.io/gitea/models/issues"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
@ -20,7 +19,7 @@ import (
func TestAction_GetRepoPath(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{}).(*repo_model.Repository)
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
action := &Action{RepoID: repo.ID}
assert.Equal(t, path.Join(owner.Name, repo.Name), action.GetRepoPath())
@ -28,15 +27,12 @@ func TestAction_GetRepoPath(t *testing.T) {
func TestAction_GetRepoLink(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{}).(*repo_model.Repository)
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
comment := unittest.AssertExistsAndLoadBean(t, &issue_model.Comment{ID: 2}).(*issue_model.Comment)
action := &Action{RepoID: repo.ID, CommentID: comment.ID}
action := &Action{RepoID: repo.ID}
setting.AppSubURL = "/suburl"
expected := path.Join(setting.AppSubURL, owner.Name, repo.Name)
assert.Equal(t, expected, action.GetRepoLink())
assert.Equal(t, repo.HTMLURL(), action.GetRepoAbsoluteLink())
assert.Equal(t, comment.HTMLURL(), action.GetCommentLink())
}
func TestGetFeeds(t *testing.T) {

View file

@ -10,7 +10,6 @@ import (
"encoding/base32"
"encoding/base64"
"fmt"
"net"
"net/url"
"strings"
@ -57,18 +56,6 @@ func (app *OAuth2Application) PrimaryRedirectURI() string {
// ContainsRedirectURI checks if redirectURI is allowed for app
func (app *OAuth2Application) ContainsRedirectURI(redirectURI string) bool {
uri, err := url.Parse(redirectURI)
// ignore port for http loopback uris following https://datatracker.ietf.org/doc/html/rfc8252#section-7.3
if err == nil && uri.Scheme == "http" && uri.Port() != "" {
ip := net.ParseIP(uri.Hostname())
if ip != nil && ip.IsLoopback() {
// strip port
uri.Host = uri.Hostname()
if util.IsStringInSlice(uri.String(), app.RedirectURIs, true) {
return true
}
}
}
return util.IsStringInSlice(redirectURI, app.RedirectURIs, true)
}

View file

@ -42,26 +42,6 @@ func TestOAuth2Application_ContainsRedirectURI(t *testing.T) {
assert.False(t, app.ContainsRedirectURI("d"))
}
func TestOAuth2Application_ContainsRedirectURI_WithPort(t *testing.T) {
app := &OAuth2Application{
RedirectURIs: []string{"http://127.0.0.1/", "http://::1/", "http://192.168.0.1/", "http://intranet/", "https://127.0.0.1/"},
}
// http loopback uris should ignore port
// https://datatracker.ietf.org/doc/html/rfc8252#section-7.3
assert.True(t, app.ContainsRedirectURI("http://127.0.0.1:3456/"))
assert.True(t, app.ContainsRedirectURI("http://127.0.0.1/"))
assert.True(t, app.ContainsRedirectURI("http://[::1]:3456/"))
// not http
assert.False(t, app.ContainsRedirectURI("https://127.0.0.1:3456/"))
// not loopback
assert.False(t, app.ContainsRedirectURI("http://192.168.0.1:9954/"))
assert.False(t, app.ContainsRedirectURI("http://intranet:3456/"))
// unparseable
assert.False(t, app.ContainsRedirectURI(":"))
}
func TestOAuth2Application_ValidateClientSecret(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
app := unittest.AssertExistsAndLoadBean(t, &OAuth2Application{ID: 1}).(*OAuth2Application)

View file

@ -181,10 +181,6 @@ func createReaction(ctx context.Context, opts *ReactionOptions) (*Reaction, erro
Reaction: opts.Type,
UserID: opts.DoerID,
}
if findOpts.CommentID == 0 {
// explicit search of Issue Reactions where CommentID = 0
findOpts.CommentID = -1
}
existingR, _, err := FindReactions(ctx, findOpts)
if err != nil {
@ -260,23 +256,16 @@ func DeleteReaction(ctx context.Context, opts *ReactionOptions) error {
CommentID: opts.CommentID,
}
sess := db.GetEngine(ctx).Where("original_author_id = 0")
if opts.CommentID == -1 {
reaction.CommentID = 0
sess.MustCols("comment_id")
}
_, err := sess.Delete(reaction)
_, err := db.GetEngine(ctx).Where("original_author_id = 0").Delete(reaction)
return err
}
// DeleteIssueReaction deletes a reaction on issue.
func DeleteIssueReaction(doerID, issueID int64, content string) error {
return DeleteReaction(db.DefaultContext, &ReactionOptions{
Type: content,
DoerID: doerID,
IssueID: issueID,
CommentID: -1,
Type: content,
DoerID: doerID,
IssueID: issueID,
})
}

View file

@ -170,7 +170,6 @@ type FindReleasesOptions struct {
IsPreRelease util.OptionalBool
IsDraft util.OptionalBool
TagNames []string
HasSha1 util.OptionalBool // useful to find draft releases which are created with existing tags
}
func (opts *FindReleasesOptions) toConds(repoID int64) builder.Cond {
@ -192,13 +191,6 @@ func (opts *FindReleasesOptions) toConds(repoID int64) builder.Cond {
if !opts.IsDraft.IsNone() {
cond = cond.And(builder.Eq{"is_draft": opts.IsDraft.IsTrue()})
}
if !opts.HasSha1.IsNone() {
if opts.HasSha1.IsTrue() {
cond = cond.And(builder.Neq{"sha1": ""})
} else {
cond = cond.And(builder.Eq{"sha1": ""})
}
}
return cond
}

View file

@ -605,27 +605,15 @@ func CheckRepoStats(ctx context.Context) error {
repoStatsCorrectNumStars,
"repository count 'num_stars'",
},
// Repository.NumIssues
{
statsQuery("SELECT repo.id FROM `repository` repo WHERE repo.num_issues!=(SELECT COUNT(*) FROM `issue` WHERE repo_id=repo.id AND is_closed=? AND is_pull=?)", false, false),
repoStatsCorrectNumIssues,
"repository count 'num_issues'",
},
// Repository.NumClosedIssues
{
statsQuery("SELECT repo.id FROM `repository` repo WHERE repo.num_closed_issues!=(SELECT COUNT(*) FROM `issue` WHERE repo_id=repo.id AND is_closed=? AND is_pull=?)", true, false),
repoStatsCorrectNumClosedIssues,
"repository count 'num_closed_issues'",
},
// Repository.NumPulls
{
statsQuery("SELECT repo.id FROM `repository` repo WHERE repo.num_pulls!=(SELECT COUNT(*) FROM `issue` WHERE repo_id=repo.id AND is_closed=? AND is_pull=?)", false, true),
repoStatsCorrectNumPulls,
"repository count 'num_pulls'",
},
// Repository.NumClosedPulls
{
statsQuery("SELECT repo.id FROM `repository` repo WHERE repo.num_closed_pulls!=(SELECT COUNT(*) FROM `issue` WHERE repo_id=repo.id AND is_closed=? AND is_pull=?)", true, true),
statsQuery("SELECT repo.id FROM `repository` repo WHERE repo.num_closed_issues!=(SELECT COUNT(*) FROM `issue` WHERE repo_id=repo.id AND is_closed=? AND is_pull=?)", true, true),
repoStatsCorrectNumClosedPulls,
"repository count 'num_closed_pulls'",
},

View file

@ -1265,7 +1265,7 @@ func isUserVisibleToViewerCond(viewer *User) builder.Cond {
// IsUserVisibleToViewer check if viewer is able to see user profile
func IsUserVisibleToViewer(ctx context.Context, u, viewer *User) bool {
if viewer != nil && (viewer.IsAdmin || viewer.ID == u.ID) {
if viewer != nil && viewer.IsAdmin {
return true
}
@ -1304,7 +1304,7 @@ func IsUserVisibleToViewer(ctx context.Context, u, viewer *User) bool {
return false
}
if count == 0 {
if count < 0 {
// No common organization
return false
}

View file

@ -36,20 +36,20 @@ func drawBlock(img *image.Paletted, x, y, size, angle int, points []int) {
// blank
//
// --------
// | |
// | |
// | |
// --------
// --------
// | |
// | |
// | |
// --------
func b0(img *image.Paletted, x, y, size, angle int) {}
// full-filled
//
// --------
// |######|
// |######|
// |######|
// --------
// --------
// |######|
// |######|
// |######|
// --------
func b1(img *image.Paletted, x, y, size, angle int) {
for i := x; i < x+size; i++ {
for j := y; j < y+size; j++ {
@ -59,13 +59,12 @@ func b1(img *image.Paletted, x, y, size, angle int) {
}
// a small block
//
// ----------
// | |
// | #### |
// | #### |
// | |
// ----------
// ----------
// | |
// | #### |
// | #### |
// | |
// ----------
func b2(img *image.Paletted, x, y, size, angle int) {
l := size / 4
x += l
@ -80,15 +79,15 @@ func b2(img *image.Paletted, x, y, size, angle int) {
// diamond
//
// ---------
// | # |
// | ### |
// | ##### |
// |#######|
// | ##### |
// | ### |
// | # |
// ---------
// ---------
// | # |
// | ### |
// | ##### |
// |#######|
// | ##### |
// | ### |
// | # |
// ---------
func b3(img *image.Paletted, x, y, size, angle int) {
m := size / 2
drawBlock(img, x, y, size, 0, []int{
@ -102,13 +101,13 @@ func b3(img *image.Paletted, x, y, size, angle int) {
// b4
//
// -------
// |#####|
// |#### |
// |### |
// |## |
// |# |
// |------
// -------
// |#####|
// |#### |
// |### |
// |## |
// |# |
// |------
func b4(img *image.Paletted, x, y, size, angle int) {
drawBlock(img, x, y, size, angle, []int{
0, 0,
@ -120,11 +119,11 @@ func b4(img *image.Paletted, x, y, size, angle int) {
// b5
//
// ---------
// | # |
// | ### |
// | ##### |
// |#######|
// ---------
// | # |
// | ### |
// | ##### |
// |#######|
func b5(img *image.Paletted, x, y, size, angle int) {
m := size / 2
drawBlock(img, x, y, size, angle, []int{
@ -137,11 +136,11 @@ func b5(img *image.Paletted, x, y, size, angle int) {
// b6
//
// --------
// |### |
// |### |
// |### |
// --------
// --------
// |### |
// |### |
// |### |
// --------
func b6(img *image.Paletted, x, y, size, angle int) {
m := size / 2
drawBlock(img, x, y, size, angle, []int{
@ -155,12 +154,12 @@ func b6(img *image.Paletted, x, y, size, angle int) {
// b7 italic cone
//
// ---------
// | # |
// | ## |
// | #####|
// | ####|
// |--------
// ---------
// | # |
// | ## |
// | #####|
// | ####|
// |--------
func b7(img *image.Paletted, x, y, size, angle int) {
m := size / 2
drawBlock(img, x, y, size, angle, []int{
@ -174,14 +173,14 @@ func b7(img *image.Paletted, x, y, size, angle int) {
// b8 three small triangles
//
// -----------
// | # |
// | ### |
// | ##### |
// | # # |
// | ### ### |
// |#########|
// -----------
// -----------
// | # |
// | ### |
// | ##### |
// | # # |
// | ### ### |
// |#########|
// -----------
func b8(img *image.Paletted, x, y, size, angle int) {
m := size / 2
mm := m / 2
@ -213,13 +212,13 @@ func b8(img *image.Paletted, x, y, size, angle int) {
// b9 italic triangle
//
// ---------
// |# |
// | #### |
// | #####|
// | #### |
// | # |
// ---------
// ---------
// |# |
// | #### |
// | #####|
// | #### |
// | # |
// ---------
func b9(img *image.Paletted, x, y, size, angle int) {
m := size / 2
drawBlock(img, x, y, size, angle, []int{
@ -232,16 +231,16 @@ func b9(img *image.Paletted, x, y, size, angle int) {
// b10
//
// ----------
// | ####|
// | ### |
// | ## |
// | # |
// |#### |
// |### |
// |## |
// |# |
// ----------
// ----------
// | ####|
// | ### |
// | ## |
// | # |
// |#### |
// |### |
// |## |
// |# |
// ----------
func b10(img *image.Paletted, x, y, size, angle int) {
m := size / 2
drawBlock(img, x, y, size, angle, []int{
@ -261,13 +260,13 @@ func b10(img *image.Paletted, x, y, size, angle int) {
// b11
//
// ----------
// |#### |
// |#### |
// |#### |
// | |
// | |
// ----------
// ----------
// |#### |
// |#### |
// |#### |
// | |
// | |
// ----------
func b11(img *image.Paletted, x, y, size, angle int) {
m := size / 2
drawBlock(img, x, y, size, angle, []int{
@ -281,13 +280,13 @@ func b11(img *image.Paletted, x, y, size, angle int) {
// b12
//
// -----------
// | |
// | |
// |#########|
// | ##### |
// | # |
// -----------
// -----------
// | |
// | |
// |#########|
// | ##### |
// | # |
// -----------
func b12(img *image.Paletted, x, y, size, angle int) {
m := size / 2
drawBlock(img, x, y, size, angle, []int{
@ -300,13 +299,13 @@ func b12(img *image.Paletted, x, y, size, angle int) {
// b13
//
// -----------
// | |
// | |
// | # |
// | ##### |
// |#########|
// -----------
// -----------
// | |
// | |
// | # |
// | ##### |
// |#########|
// -----------
func b13(img *image.Paletted, x, y, size, angle int) {
m := size / 2
drawBlock(img, x, y, size, angle, []int{
@ -319,13 +318,13 @@ func b13(img *image.Paletted, x, y, size, angle int) {
// b14
//
// ---------
// | # |
// | ### |
// |#### |
// | |
// | |
// ---------
// ---------
// | # |
// | ### |
// |#### |
// | |
// | |
// ---------
func b14(img *image.Paletted, x, y, size, angle int) {
m := size / 2
drawBlock(img, x, y, size, angle, []int{
@ -338,13 +337,13 @@ func b14(img *image.Paletted, x, y, size, angle int) {
// b15
//
// ----------
// |##### |
// |### |
// |# |
// | |
// | |
// ----------
// ----------
// |##### |
// |### |
// |# |
// | |
// | |
// ----------
func b15(img *image.Paletted, x, y, size, angle int) {
m := size / 2
drawBlock(img, x, y, size, angle, []int{
@ -357,14 +356,14 @@ func b15(img *image.Paletted, x, y, size, angle int) {
// b16
//
// ---------
// | # |
// | ##### |
// |#######|
// | # |
// | ##### |
// |#######|
// ---------
// ---------
// | # |
// | ##### |
// |#######|
// | # |
// | ##### |
// |#######|
// ---------
func b16(img *image.Paletted, x, y, size, angle int) {
m := size / 2
drawBlock(img, x, y, size, angle, []int{
@ -384,13 +383,13 @@ func b16(img *image.Paletted, x, y, size, angle int) {
// b17
//
// ----------
// |##### |
// |### |
// |# |
// | ##|
// | ##|
// ----------
// ----------
// |##### |
// |### |
// |# |
// | ##|
// | ##|
// ----------
func b17(img *image.Paletted, x, y, size, angle int) {
m := size / 2
@ -413,13 +412,13 @@ func b17(img *image.Paletted, x, y, size, angle int) {
// b18
//
// ----------
// |##### |
// |#### |
// |### |
// |## |
// |# |
// ----------
// ----------
// |##### |
// |#### |
// |### |
// |## |
// |# |
// ----------
func b18(img *image.Paletted, x, y, size, angle int) {
m := size / 2
@ -433,13 +432,13 @@ func b18(img *image.Paletted, x, y, size, angle int) {
// b19
//
// ----------
// |########|
// |### ###|
// |# #|
// |### ###|
// |########|
// ----------
// ----------
// |########|
// |### ###|
// |# #|
// |### ###|
// |########|
// ----------
func b19(img *image.Paletted, x, y, size, angle int) {
m := size / 2
@ -474,13 +473,13 @@ func b19(img *image.Paletted, x, y, size, angle int) {
// b20
//
// ----------
// | ## |
// |### |
// |## |
// |## |
// |# |
// ----------
// ----------
// | ## |
// |### |
// |## |
// |## |
// |# |
// ----------
func b20(img *image.Paletted, x, y, size, angle int) {
m := size / 2
q := size / 4
@ -495,13 +494,13 @@ func b20(img *image.Paletted, x, y, size, angle int) {
// b21
//
// ----------
// | #### |
// |## #####|
// |## ##|
// |## |
// |# |
// ----------
// ----------
// | #### |
// |## #####|
// |## ##|
// |## |
// |# |
// ----------
func b21(img *image.Paletted, x, y, size, angle int) {
m := size / 2
q := size / 4
@ -523,13 +522,13 @@ func b21(img *image.Paletted, x, y, size, angle int) {
// b22
//
// ----------
// | #### |
// |## ### |
// |## ##|
// |## ##|
// |# #|
// ----------
// ----------
// | #### |
// |## ### |
// |## ##|
// |## ##|
// |# #|
// ----------
func b22(img *image.Paletted, x, y, size, angle int) {
m := size / 2
q := size / 4
@ -551,13 +550,13 @@ func b22(img *image.Paletted, x, y, size, angle int) {
// b23
//
// ----------
// | #######|
// |### #|
// |## |
// |## |
// |# |
// ----------
// ----------
// | #######|
// |### #|
// |## |
// |## |
// |# |
// ----------
func b23(img *image.Paletted, x, y, size, angle int) {
m := size / 2
q := size / 4
@ -579,13 +578,13 @@ func b23(img *image.Paletted, x, y, size, angle int) {
// b24
//
// ----------
// | ## ###|
// |### ###|
// |## ## |
// |## ## |
// |# # |
// ----------
// ----------
// | ## ###|
// |### ###|
// |## ## |
// |## ## |
// |# # |
// ----------
func b24(img *image.Paletted, x, y, size, angle int) {
m := size / 2
q := size / 4
@ -607,13 +606,13 @@ func b24(img *image.Paletted, x, y, size, angle int) {
// b25
//
// ----------
// |# #|
// |## ###|
// |## ## |
// |###### |
// |#### |
// ----------
// ----------
// |# #|
// |## ###|
// |## ## |
// |###### |
// |#### |
// ----------
func b25(img *image.Paletted, x, y, size, angle int) {
m := size / 2
q := size / 4
@ -635,13 +634,13 @@ func b25(img *image.Paletted, x, y, size, angle int) {
// b26
//
// ----------
// |# #|
// |### ###|
// | #### |
// |### ###|
// |# #|
// ----------
// ----------
// |# #|
// |### ###|
// | #### |
// |### ###|
// |# #|
// ----------
func b26(img *image.Paletted, x, y, size, angle int) {
m := size / 2
q := size / 4
@ -677,13 +676,13 @@ func b26(img *image.Paletted, x, y, size, angle int) {
// b27
//
// ----------
// |########|
// |## ###|
// |# #|
// |### ##|
// |########|
// ----------
// ----------
// |########|
// |## ###|
// |# #|
// |### ##|
// |########|
// ----------
func b27(img *image.Paletted, x, y, size, angle int) {
m := size / 2
q := size / 4

View file

@ -13,7 +13,6 @@ import (
"code.gitea.io/gitea/models/perm"
"code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/structs"
)
@ -53,11 +52,47 @@ func packageAssignment(ctx *Context, errCb func(int, string, interface{})) {
Owner: ctx.ContextUser,
}
var err error
ctx.Package.AccessMode, err = determineAccessMode(ctx)
if err != nil {
errCb(http.StatusInternalServerError, "determineAccessMode", err)
return
if ctx.Package.Owner.IsOrganization() {
org := organization.OrgFromUser(ctx.Package.Owner)
// 1. Get user max authorize level for the org (may be none, if user is not member of the org)
if ctx.Doer != nil {
var err error
ctx.Package.AccessMode, err = org.GetOrgUserMaxAuthorizeLevel(ctx.Doer.ID)
if err != nil {
errCb(http.StatusInternalServerError, "GetOrgUserMaxAuthorizeLevel", err)
return
}
// If access mode is less than write check every team for more permissions
if ctx.Package.AccessMode < perm.AccessModeWrite {
teams, err := organization.GetUserOrgTeams(ctx, org.ID, ctx.Doer.ID)
if err != nil {
errCb(http.StatusInternalServerError, "GetUserOrgTeams", err)
return
}
for _, t := range teams {
perm := t.UnitAccessModeCtx(ctx, unit.TypePackages)
if ctx.Package.AccessMode < perm {
ctx.Package.AccessMode = perm
}
}
}
}
// 2. If authorize level is none, check if org is visible to user
if ctx.Package.AccessMode == perm.AccessModeNone && organization.HasOrgOrUserVisible(ctx, ctx.Package.Owner, ctx.Doer) {
ctx.Package.AccessMode = perm.AccessModeRead
}
} else {
if ctx.Doer != nil && !ctx.Doer.IsGhost() {
// 1. Check if user is package owner
if ctx.Doer.ID == ctx.Package.Owner.ID {
ctx.Package.AccessMode = perm.AccessModeOwner
} else if ctx.Package.Owner.Visibility == structs.VisibleTypePublic || ctx.Package.Owner.Visibility == structs.VisibleTypeLimited { // 2. Check if package owner is public or limited
ctx.Package.AccessMode = perm.AccessModeRead
}
} else if ctx.Package.Owner.Visibility == structs.VisibleTypePublic { // 3. Check if package owner is public
ctx.Package.AccessMode = perm.AccessModeRead
}
}
packageType := ctx.Params("type")
@ -82,57 +117,6 @@ func packageAssignment(ctx *Context, errCb func(int, string, interface{})) {
}
}
func determineAccessMode(ctx *Context) (perm.AccessMode, error) {
accessMode := perm.AccessModeNone
if setting.Service.RequireSignInView && ctx.Doer == nil {
return accessMode, nil
}
if ctx.Package.Owner.IsOrganization() {
org := organization.OrgFromUser(ctx.Package.Owner)
// 1. Get user max authorize level for the org (may be none, if user is not member of the org)
if ctx.Doer != nil {
var err error
accessMode, err = org.GetOrgUserMaxAuthorizeLevel(ctx.Doer.ID)
if err != nil {
return accessMode, err
}
// If access mode is less than write check every team for more permissions
if accessMode < perm.AccessModeWrite {
teams, err := organization.GetUserOrgTeams(ctx, org.ID, ctx.Doer.ID)
if err != nil {
return accessMode, err
}
for _, t := range teams {
perm := t.UnitAccessModeCtx(ctx, unit.TypePackages)
if accessMode < perm {
accessMode = perm
}
}
}
}
// 2. If authorize level is none, check if org is visible to user
if accessMode == perm.AccessModeNone && organization.HasOrgOrUserVisible(ctx, ctx.Package.Owner, ctx.Doer) {
accessMode = perm.AccessModeRead
}
} else {
if ctx.Doer != nil && !ctx.Doer.IsGhost() {
// 1. Check if user is package owner
if ctx.Doer.ID == ctx.Package.Owner.ID {
accessMode = perm.AccessModeOwner
} else if ctx.Package.Owner.Visibility == structs.VisibleTypePublic || ctx.Package.Owner.Visibility == structs.VisibleTypeLimited { // 2. Check if package owner is public or limited
accessMode = perm.AccessModeRead
}
} else if ctx.Package.Owner.Visibility == structs.VisibleTypePublic { // 3. Check if package owner is public
accessMode = perm.AccessModeRead
}
}
return accessMode, nil
}
// PackageContexter initializes a package context for a request.
func PackageContexter() func(next http.Handler) http.Handler {
return func(next http.Handler) http.Handler {

View file

@ -118,7 +118,7 @@ type CanCommitToBranchResults struct {
}
// CanCommitToBranch returns true if repository is editable and user has proper access level
// and branch is not protected for push
// and branch is not protected for push
func (r *Repository) CanCommitToBranch(ctx context.Context, doer *user_model.User) (CanCommitToBranchResults, error) {
protectedBranch, err := git_model.GetProtectedBranchBy(ctx, r.Repository.ID, r.BranchName)
if err != nil {
@ -524,9 +524,7 @@ func RepoAssignment(ctx *Context) (cancel context.CancelFunc) {
}
ctx.Data["NumTags"], err = models.GetReleaseCountByRepoID(ctx.Repo.Repository.ID, models.FindReleasesOptions{
IncludeDrafts: true,
IncludeTags: true,
HasSha1: util.OptionalBoolTrue, // only draft releases which are created with existing tags
IncludeTags: true,
})
if err != nil {
ctx.ServerError("GetReleaseCountByRepoID", err)

View file

@ -322,7 +322,7 @@ func TestGuessDelimiter(t *testing.T) {
},
// case 3 - tab delimited
{
csv: "1\t2",
csv: "1 2",
expectedDelimiter: '\t',
},
// case 4 - pipe delimited

File diff suppressed because it is too large Load diff

View file

@ -40,7 +40,6 @@ type Command struct {
parentContext context.Context
desc string
globalArgsLength int
brokenArgs []string
}
func (c *Command) String() string {
@ -51,7 +50,6 @@ func (c *Command) String() string {
}
// NewCommand creates and returns a new Git Command based on given command and arguments.
// Each argument should be safe to be trusted. User-provided arguments should be passed to AddDynamicArguments instead.
func NewCommand(ctx context.Context, args ...string) *Command {
// Make an explicit copy of globalCommandArgs, otherwise append might overwrite it
cargs := make([]string, len(globalCommandArgs))
@ -65,13 +63,11 @@ func NewCommand(ctx context.Context, args ...string) *Command {
}
// NewCommandNoGlobals creates and returns a new Git Command based on given command and arguments only with the specify args and don't care global command args
// Each argument should be safe to be trusted. User-provided arguments should be passed to AddDynamicArguments instead.
func NewCommandNoGlobals(args ...string) *Command {
return NewCommandContextNoGlobals(DefaultContext, args...)
}
// NewCommandContextNoGlobals creates and returns a new Git Command based on given command and arguments only with the specify args and don't care global command args
// Each argument should be safe to be trusted. User-provided arguments should be passed to AddDynamicArguments instead.
func NewCommandContextNoGlobals(ctx context.Context, args ...string) *Command {
return &Command{
name: GitExecutable,
@ -93,28 +89,12 @@ func (c *Command) SetDescription(desc string) *Command {
return c
}
// AddArguments adds new argument(s) to the command. Each argument must be safe to be trusted.
// User-provided arguments should be passed to AddDynamicArguments instead.
// AddArguments adds new argument(s) to the command.
func (c *Command) AddArguments(args ...string) *Command {
c.args = append(c.args, args...)
return c
}
// AddDynamicArguments adds new dynamic argument(s) to the command.
// The arguments may come from user input and can not be trusted, so no leading '-' is allowed to avoid passing options
func (c *Command) AddDynamicArguments(args ...string) *Command {
for _, arg := range args {
if arg != "" && arg[0] == '-' {
c.brokenArgs = append(c.brokenArgs, arg)
}
}
if len(c.brokenArgs) != 0 {
return c
}
c.args = append(c.args, args...)
return c
}
// RunOpts represents parameters to run the command. If UseContextTimeout is specified, then Timeout is ignored.
type RunOpts struct {
Env []string
@ -158,14 +138,8 @@ func CommonCmdServEnvs() []string {
return commonBaseEnvs()
}
var ErrBrokenCommand = errors.New("git command is broken")
// Run runs the command with the RunOpts
func (c *Command) Run(opts *RunOpts) error {
if len(c.brokenArgs) != 0 {
log.Error("git command is broken: %s, broken args: %s", c.String(), strings.Join(c.brokenArgs, " "))
return ErrBrokenCommand
}
if opts == nil {
opts = &RunOpts{}
}

View file

@ -26,19 +26,4 @@ func TestRunWithContextStd(t *testing.T) {
assert.Contains(t, err.Error(), "exit status 129 - unknown option:")
assert.Empty(t, stdout)
}
cmd = NewCommand(context.Background())
cmd.AddDynamicArguments("-test")
assert.ErrorIs(t, cmd.Run(&RunOpts{}), ErrBrokenCommand)
cmd = NewCommand(context.Background())
cmd.AddDynamicArguments("--test")
assert.ErrorIs(t, cmd.Run(&RunOpts{}), ErrBrokenCommand)
subCmd := "version"
cmd = NewCommand(context.Background()).AddDynamicArguments(subCmd) // for test purpose only, the sub-command should never be dynamic for production
stdout, stderr, err = cmd.RunStdString(&RunOpts{})
assert.NoError(t, err)
assert.Empty(t, stderr)
assert.Contains(t, stdout, "git version")
}

View file

@ -163,7 +163,7 @@ func AllCommitsCount(ctx context.Context, repoPath string, hidePRRefs bool, file
// CommitsCountFiles returns number of total commits of until given revision.
func CommitsCountFiles(ctx context.Context, repoPath string, revision, relpath []string) (int64, error) {
cmd := NewCommand(ctx, "rev-list", "--count")
cmd.AddDynamicArguments(revision...)
cmd.AddArguments(revision...)
if len(relpath) > 0 {
cmd.AddArguments("--")
cmd.AddArguments(relpath...)

View file

@ -68,7 +68,8 @@ func NewParser(r io.Reader, format Format) *Parser {
//
// It could, for example return something like:
//
// { "objecttype": "tag", "refname:short": "v1.16.4", "object": "f460b7543ed500e49c133c2cd85c8c55ee9dbe27" }
// { "objecttype": "tag", "refname:short": "v1.16.4", "object": "f460b7543ed500e49c133c2cd85c8c55ee9dbe27" }
//
func (p *Parser) Next() map[string]string {
if !p.scanner.Scan() {
return nil
@ -88,7 +89,8 @@ func (p *Parser) Err() error {
// parseRef parses out all key-value pairs from a single reference block, such as
//
// "objecttype tag\0refname:short v1.16.4\0object f460b7543ed500e49c133c2cd85c8c55ee9dbe27"
// "objecttype tag\0refname:short v1.16.4\0object f460b7543ed500e49c133c2cd85c8c55ee9dbe27"
//
func (p *Parser) parseRef(refBlock string) (map[string]string, error) {
if refBlock == "" {
// must be at EOF

View file

@ -44,7 +44,7 @@ func parseTreeEntries(data []byte, ptree *Tree) ([]*TreeEntry, error) {
case "160000":
entry.entryMode = EntryModeCommit
pos += 14 // skip over "160000 object "
case "040000", "040755": // git uses 040000 for tree object, but some users may get 040755 for unknown reasons
case "040000":
entry.entryMode = EntryModeTree
pos += 12 // skip over "040000 tree "
default:
@ -119,7 +119,7 @@ loop:
entry.entryMode = EntryModeSymlink
case "160000":
entry.entryMode = EntryModeCommit
case "40000", "40755": // git uses 40000 for tree object, but some users may get 40755 for unknown reasons
case "40000":
entry.entryMode = EntryModeTree
default:
log.Debug("Unknown mode: %v", string(mode))

View file

@ -191,8 +191,8 @@ func (c *CheckAttributeReader) Run() error {
// CheckPath check attr for given path
func (c *CheckAttributeReader) CheckPath(path string) (rs map[string]string, err error) {
defer func() {
if err != nil && err != c.ctx.Err() {
log.Error("Unexpected error when checking path %s in %s. Error: %v", path, c.Repo.Path, err)
if err != nil {
log.Error("CheckPath returns error: %v", err)
}
}()

View file

@ -158,7 +158,7 @@ func (repo *Repository) searchCommits(id SHA1, opts SearchCommitsOptions) ([]*Co
// add previous arguments except for --grep and --all
hashCmd.AddArguments(args...)
// add keyword as <commit>
hashCmd.AddDynamicArguments(v)
hashCmd.AddArguments(v)
// search with given constraints for commit matching sha hash of v
hashMatching, _, err := hashCmd.RunStdBytes(&RunOpts{Dir: repo.Path})
@ -208,15 +208,14 @@ func (repo *Repository) CommitsByFileAndRange(revision, file string, page int) (
}()
go func() {
stderr := strings.Builder{}
gitCmd := NewCommand(repo.Ctx, "log", prettyLogFormat, "--follow",
"--max-count="+strconv.Itoa(setting.Git.CommitsRangeSize*page))
gitCmd.AddDynamicArguments(revision)
gitCmd.AddArguments("--", file)
err := gitCmd.Run(&RunOpts{
Dir: repo.Path,
Stdout: stdoutWriter,
Stderr: &stderr,
})
err := NewCommand(repo.Ctx, "log", revision, "--follow",
"--max-count="+strconv.Itoa(setting.Git.CommitsRangeSize*page),
prettyLogFormat, "--", file).
Run(&RunOpts{
Dir: repo.Path,
Stdout: stdoutWriter,
Stderr: &stderr,
})
if err != nil {
_ = stdoutWriter.CloseWithError(ConcatenateError(err, (&stderr).String()))
} else {

View file

@ -59,15 +59,15 @@ func (repo *Repository) GetCodeActivityStats(fromTime time.Time, branch string)
_ = stdoutWriter.Close()
}()
gitCmd := NewCommand(repo.Ctx, "log", "--numstat", "--no-merges", "--pretty=format:---%n%h%n%aN%n%aE%n", "--date=iso", fmt.Sprintf("--since='%s'", since))
args := []string{"log", "--numstat", "--no-merges", "--pretty=format:---%n%h%n%aN%n%aE%n", "--date=iso", fmt.Sprintf("--since='%s'", since)}
if len(branch) == 0 {
gitCmd.AddArguments("--branches=*")
args = append(args, "--branches=*")
} else {
gitCmd.AddArguments("--first-parent").AddDynamicArguments(branch)
args = append(args, "--first-parent", branch)
}
stderr := new(strings.Builder)
err = gitCmd.Run(&RunOpts{
err = NewCommand(repo.Ctx, args...).Run(&RunOpts{
Env: []string{},
Dir: repo.Path,
Stdout: stdoutWriter,

View file

@ -19,10 +19,8 @@ import (
type Signature = object.Signature
// Helper to get a signature from the commit line, which looks like these:
//
// author Patrick Gundlach <gundlach@speedata.de> 1378823654 +0200
// author Patrick Gundlach <gundlach@speedata.de> Thu, 07 Apr 2005 22:13:13 +0200
//
// author Patrick Gundlach <gundlach@speedata.de> 1378823654 +0200
// author Patrick Gundlach <gundlach@speedata.de> Thu, 07 Apr 2005 22:13:13 +0200
// but without the "author " at the beginning (this method should)
// be used for author and committer.
//

View file

@ -37,10 +37,8 @@ func (s *Signature) Decode(b []byte) {
}
// Helper to get a signature from the commit line, which looks like these:
//
// author Patrick Gundlach <gundlach@speedata.de> 1378823654 +0200
// author Patrick Gundlach <gundlach@speedata.de> Thu, 07 Apr 2005 22:13:13 +0200
//
// author Patrick Gundlach <gundlach@speedata.de> 1378823654 +0200
// author Patrick Gundlach <gundlach@speedata.de> Thu, 07 Apr 2005 22:13:13 +0200
// but without the "author " at the beginning (this method should)
// be used for author and committer.
func newSignatureFromCommitline(line []byte) (sig *Signature, err error) {

View file

@ -24,17 +24,19 @@ func GetCommitGraph(r *git.Repository, page, maxAllowedColors int, hidePRRefs bo
page = 1
}
graphCmd := git.NewCommand(r.Ctx, "log", "--graph", "--date-order", "--decorate=full")
args := make([]string, 0, 12+len(branches)+len(files))
args = append(args, "--graph", "--date-order", "--decorate=full")
if hidePRRefs {
graphCmd.AddArguments("--exclude=" + git.PullPrefix + "*")
args = append(args, "--exclude="+git.PullPrefix+"*")
}
if len(branches) == 0 {
graphCmd.AddArguments("--all")
args = append(args, "--all")
}
graphCmd.AddArguments(
args = append(args,
"-C",
"-M",
fmt.Sprintf("-n %d", setting.UI.GraphMaxCommitNum*page),
@ -42,12 +44,15 @@ func GetCommitGraph(r *git.Repository, page, maxAllowedColors int, hidePRRefs bo
fmt.Sprintf("--pretty=format:%s", format))
if len(branches) > 0 {
graphCmd.AddDynamicArguments(branches...)
args = append(args, branches...)
}
args = append(args, "--")
if len(files) > 0 {
graphCmd.AddArguments("--")
graphCmd.AddArguments(files...)
args = append(args, files...)
}
graphCmd := git.NewCommand(r.Ctx, "log")
graphCmd.AddArguments(args...)
graph := NewGraph()
stderr := new(strings.Builder)

View file

@ -93,7 +93,6 @@ func NewFileLogger() LoggerProvider {
// Init file logger with json config.
// config like:
//
// {
// "filename":"log/gogs.log",
// "maxsize":1<<30,

View file

@ -48,7 +48,6 @@ func NewSMTPLogger() LoggerProvider {
// Init smtp writer with json config.
// config like:
//
// {
// "Username":"example@gmail.com",
// "password:"password",

View file

@ -7,7 +7,6 @@ package markup_test
import (
"context"
"io"
"os"
"strings"
"testing"
@ -33,7 +32,6 @@ func TestMain(m *testing.M) {
if err := git.InitSimple(context.Background()); err != nil {
log.Fatal("git init failed, err: %v", err)
}
os.Exit(m.Run())
}
func TestRender_Commits(t *testing.T) {
@ -338,7 +336,7 @@ func TestRender_emoji(t *testing.T) {
`<p>Some text with <span class="emoji" aria-label="grinning face with smiling eyes">😄</span><span class="emoji" aria-label="grinning face with smiling eyes">😄</span> 2 emoji next to each other</p>`)
test(
"😎🤪🔐🤑❓",
`<p><span class="emoji" aria-label="smiling face with sunglasses">😎</span><span class="emoji" aria-label="zany face">🤪</span><span class="emoji" aria-label="locked with key">🔐</span><span class="emoji" aria-label="money-mouth face">🤑</span><span class="emoji" aria-label="red question mark">❓</span></p>`)
`<p><span class="emoji" aria-label="smiling face with sunglasses">😎</span><span class="emoji" aria-label="zany face">🤪</span><span class="emoji" aria-label="locked with key">🔐</span><span class="emoji" aria-label="money-mouth face">🤑</span><span class="emoji" aria-label="question mark">❓</span></p>`)
// should match nothing
test(

View file

@ -6,7 +6,6 @@ package markdown_test
import (
"context"
"os"
"strings"
"testing"
@ -38,7 +37,6 @@ func TestMain(m *testing.M) {
if err := git.InitSimple(context.Background()); err != nil {
log.Fatal("git init failed, err: %v", err)
}
os.Exit(m.Run())
}
func TestRender_StandardLinks(t *testing.T) {

View file

@ -141,7 +141,7 @@ func (r *stripRenderer) AddOptions(...renderer.Option) {
}
// StripMarkdown parses markdown content by removing all markup and code blocks
// in order to extract links and other references
// in order to extract links and other references
func StripMarkdown(rawBytes []byte) (string, []string) {
buf, links := StripMarkdownBytes(rawBytes)
return string(buf), links
@ -153,7 +153,7 @@ var (
)
// StripMarkdownBytes parses markdown content by removing all markup and code blocks
// in order to extract links and other references
// in order to extract links and other references
func StripMarkdownBytes(rawBytes []byte) ([]byte, []string) {
once.Do(func() {
gdMarkdown := goldmark.New(

View file

@ -95,9 +95,7 @@ func parseOCIImageConfig(r io.Reader) (*Metadata, error) {
if i := strings.Index(cmd, "#(nop) "); i != -1 {
cmd = strings.TrimSpace(cmd[i+7:])
}
if cmd != "" {
imageLayers = append(imageLayers, cmd)
}
imageLayers = append(imageLayers, cmd)
}
metadata := &Metadata{

View file

@ -25,7 +25,7 @@ func DumpMemProfileForUsername(pprofDataPath, username string) error {
}
// DumpCPUProfileForUsername dumps a CPU profile at pprofDataPath as cpuprofile_<username>_<temporary id>
// the stop function it returns stops, writes and closes the CPU profile file
// it returns the stop function which stops, writes and closes the CPU profile file
func DumpCPUProfileForUsername(pprofDataPath, username string) (func(), error) {
f, err := os.CreateTemp(pprofDataPath, fmt.Sprintf("cpuprofile_%s_", username))
if err != nil {

View file

@ -31,8 +31,8 @@ import (
)
/*
GitHub, GitLab, Gogs: *.wiki.git
BitBucket: *.git/wiki
GitHub, GitLab, Gogs: *.wiki.git
BitBucket: *.git/wiki
*/
var commonWikiURLSuffixes = []string{".wiki.git", ".git/wiki"}

View file

@ -154,7 +154,6 @@ func NewFuncMap() []template.FuncMap {
"DiffTypeToStr": DiffTypeToStr,
"DiffLineTypeToStr": DiffLineTypeToStr,
"ShortSha": base.ShortSha,
"MD5": base.EncodeMD5,
"ActionContent2Commits": ActionContent2Commits,
"PathEscape": url.PathEscape,
"PathEscapeSegments": util.PathEscapeSegments,

View file

@ -41,14 +41,14 @@ func NewLocaleStore() *LocaleStore {
}
// AddLocaleByIni adds locale by ini into the store
func (ls *LocaleStore) AddLocaleByIni(langName, langDesc string, source, moreSource []byte) error {
func (ls *LocaleStore) AddLocaleByIni(langName, langDesc string, localeFile interface{}, otherLocaleFiles ...interface{}) error {
if _, ok := ls.localeMap[langName]; ok {
return ErrLocaleAlreadyExist
}
iniFile, err := ini.LoadSources(ini.LoadOptions{
IgnoreInlineComment: true,
UnescapeValueCommentSymbols: true,
}, source, moreSource)
}, localeFile, otherLocaleFiles...)
if err == nil {
iniFile.BlockMode = false
lc := &locale{store: ls, langName: langName, langDesc: langDesc, messages: iniFile}

View file

@ -10,7 +10,7 @@ import (
"github.com/stretchr/testify/assert"
)
func TestLocaleStore(t *testing.T) {
func Test_Tr(t *testing.T) {
testData1 := []byte(`
.dot.name = Dot Name
fmt = %[1]s %[2]s
@ -28,8 +28,8 @@ sub = Changed Sub String
`)
ls := NewLocaleStore()
assert.NoError(t, ls.AddLocaleByIni("lang1", "Lang1", testData1, nil))
assert.NoError(t, ls.AddLocaleByIni("lang2", "Lang2", testData2, nil))
assert.NoError(t, ls.AddLocaleByIni("lang1", "Lang1", testData1))
assert.NoError(t, ls.AddLocaleByIni("lang2", "Lang2", testData2))
ls.SetDefaultLang("lang1")
result := ls.Tr("lang1", "fmt", "a", "b")
@ -54,21 +54,3 @@ sub = Changed Sub String
assert.Equal(t, []string{"lang1", "lang2"}, langs)
assert.Equal(t, []string{"Lang1", "Lang2"}, descs)
}
func TestLocaleStoreMoreSource(t *testing.T) {
testData1 := []byte(`
a=11
b=12
`)
testData2 := []byte(`
b=21
c=22
`)
ls := NewLocaleStore()
assert.NoError(t, ls.AddLocaleByIni("lang1", "Lang1", testData1, testData2))
assert.Equal(t, "11", ls.Tr("lang1", "a"))
assert.Equal(t, "21", ls.Tr("lang1", "b"))
assert.Equal(t, "22", ls.Tr("lang1", "c"))
}

View file

@ -60,9 +60,9 @@ func InitLocales() {
log.Fatal("Failed to list locale files: %v", err)
}
localeData := make(map[string][]byte, len(localeNames))
localFiles := make(map[string][]byte, len(localeNames))
for _, name := range localeNames {
localeData[name], err = options.Locale(name)
localFiles[name], err = options.Locale(name)
if err != nil {
log.Fatal("Failed to load %s locale file. %v", name, err)
}
@ -75,16 +75,8 @@ func InitLocales() {
matcher = language.NewMatcher(supportedTags)
for i := range setting.Names {
var localeDataBase []byte
if i == 0 && setting.Langs[0] != "en-US" {
// Only en-US has complete translations. When use other language as default, the en-US should still be used as fallback.
localeDataBase = localeData["locale_en-US.ini"]
if localeDataBase == nil {
log.Fatal("Failed to load locale_en-US.ini file.")
}
}
key := "locale_" + setting.Langs[i] + ".ini"
if err = i18n.DefaultLocales.AddLocaleByIni(setting.Langs[i], setting.Names[i], localeDataBase, localeData[key]); err != nil {
if err = i18n.DefaultLocales.AddLocaleByIni(setting.Langs[i], setting.Names[i], localFiles[key]); err != nil {
log.Error("Failed to set messages to %s: %v", setting.Langs[i], err)
}
}

View file

@ -17,13 +17,13 @@ func isSnakeCaseLowerOrNumber(c byte) bool {
// ToSnakeCase convert the input string to snake_case format.
//
// Some samples.
// "FirstName" => "first_name"
// "HTTPServer" => "http_server"
// "NoHTTPS" => "no_https"
// "GO_PATH" => "go_path"
// "GO PATH" => "go_path" // space is converted to underscore.
// "GO-PATH" => "go_path" // hyphen is converted to underscore.
//
// "FirstName" => "first_name"
// "HTTPServer" => "http_server"
// "NoHTTPS" => "no_https"
// "GO_PATH" => "go_path"
// "GO PATH" => "go_path" // space is converted to underscore.
// "GO-PATH" => "go_path" // hyphen is converted to underscore.
func ToSnakeCase(input string) string {
if len(input) == 0 {
return ""

View file

@ -66,7 +66,7 @@ func Routes() *web.Route {
r.Get("/p2/{vendorname}/{projectname}.json", composer.PackageMetadata)
r.Get("/files/{package}/{version}/{filename}", composer.DownloadPackageFile)
r.Put("", reqPackageAccess(perm.AccessModeWrite), composer.UploadPackage)
}, reqPackageAccess(perm.AccessModeRead))
})
r.Group("/conan", func() {
r.Group("/v1", func() {
r.Get("/ping", conan.Ping)
@ -154,7 +154,7 @@ func Routes() *web.Route {
}, conan.ExtractPathParameters)
})
})
}, reqPackageAccess(perm.AccessModeRead))
})
r.Group("/generic", func() {
r.Group("/{packagename}/{packageversion}/{filename}", func() {
r.Get("", generic.DownloadPackageFile)
@ -163,35 +163,33 @@ func Routes() *web.Route {
r.Delete("", generic.DeletePackage)
}, reqPackageAccess(perm.AccessModeWrite))
})
}, reqPackageAccess(perm.AccessModeRead))
})
r.Group("/helm", func() {
r.Get("/index.yaml", helm.Index)
r.Get("/{filename}", helm.DownloadPackageFile)
r.Post("/api/charts", reqPackageAccess(perm.AccessModeWrite), helm.UploadPackage)
}, reqPackageAccess(perm.AccessModeRead))
})
r.Group("/maven", func() {
r.Put("/*", reqPackageAccess(perm.AccessModeWrite), maven.UploadPackageFile)
r.Get("/*", maven.DownloadPackageFile)
}, reqPackageAccess(perm.AccessModeRead))
})
r.Group("/nuget", func() {
r.Get("/index.json", nuget.ServiceIndex) // Needs to be unauthenticated for the NuGet client.
r.Get("/index.json", nuget.ServiceIndex)
r.Get("/query", nuget.SearchService)
r.Group("/registration/{id}", func() {
r.Get("/index.json", nuget.RegistrationIndex)
r.Get("/{version}", nuget.RegistrationLeaf)
})
r.Group("/package/{id}", func() {
r.Get("/index.json", nuget.EnumeratePackageVersions)
r.Get("/{version}/{filename}", nuget.DownloadPackageFile)
})
r.Group("", func() {
r.Get("/query", nuget.SearchService)
r.Group("/registration/{id}", func() {
r.Get("/index.json", nuget.RegistrationIndex)
r.Get("/{version}", nuget.RegistrationLeaf)
})
r.Group("/package/{id}", func() {
r.Get("/index.json", nuget.EnumeratePackageVersions)
r.Get("/{version}/{filename}", nuget.DownloadPackageFile)
})
r.Group("", func() {
r.Put("/", nuget.UploadPackage)
r.Put("/symbolpackage", nuget.UploadSymbolPackage)
r.Delete("/{id}/{version}", nuget.DeletePackage)
}, reqPackageAccess(perm.AccessModeWrite))
r.Get("/symbols/{filename}/{guid:[0-9a-f]{32}}FFFFFFFF/{filename2}", nuget.DownloadSymbolFile)
}, reqPackageAccess(perm.AccessModeRead))
r.Put("/", nuget.UploadPackage)
r.Put("/symbolpackage", nuget.UploadSymbolPackage)
r.Delete("/{id}/{version}", nuget.DeletePackage)
}, reqPackageAccess(perm.AccessModeWrite))
r.Get("/symbols/{filename}/{guid:[0-9a-f]{32}}FFFFFFFF/{filename2}", nuget.DownloadSymbolFile)
})
r.Group("/npm", func() {
r.Group("/@{scope}/{id}", func() {
@ -218,12 +216,12 @@ func Routes() *web.Route {
r.Delete("", npm.DeletePackageTag)
}, reqPackageAccess(perm.AccessModeWrite))
})
}, reqPackageAccess(perm.AccessModeRead))
})
r.Group("/pypi", func() {
r.Post("/", reqPackageAccess(perm.AccessModeWrite), pypi.UploadPackageFile)
r.Get("/files/{id}/{version}/{filename}", pypi.DownloadPackageFile)
r.Get("/simple/{id}", pypi.PackageMetadata)
}, reqPackageAccess(perm.AccessModeRead))
})
r.Group("/rubygems", func() {
r.Get("/specs.4.8.gz", rubygems.EnumeratePackages)
r.Get("/latest_specs.4.8.gz", rubygems.EnumeratePackagesLatest)
@ -235,7 +233,7 @@ func Routes() *web.Route {
r.Delete("/yank", rubygems.DeletePackage)
}, reqPackageAccess(perm.AccessModeWrite))
})
}, context_service.UserAssignmentWeb(), context.PackageAssignment())
}, context_service.UserAssignmentWeb(), context.PackageAssignment(), reqPackageAccess(perm.AccessModeRead))
return r
}

View file

@ -342,7 +342,8 @@ func uploadFile(ctx *context.Context, fileFilter stringSet, fileKey string) {
Name: rref.Name,
Version: rref.Version,
},
Creator: ctx.Doer,
SemverCompatible: true,
Creator: ctx.Doer,
}
pfci := &packages_service.PackageFileCreationInfo{
PackageFileInfo: packages_service.PackageFileInfo{

View file

@ -24,7 +24,7 @@ import (
// https://www.python.org/dev/peps/pep-0503/#normalized-names
var normalizer = strings.NewReplacer(".", "-", "_", "-")
var nameMatcher = regexp.MustCompile(`\A[a-zA-Z0-9\.\-_]+\z`)
var nameMatcher = regexp.MustCompile(`\A[a-z0-9\.\-_]+\z`)
// https://www.python.org/dev/peps/pep-0440/#appendix-b-parsing-version-strings-with-regular-expressions
var versionMatcher = regexp.MustCompile(`^([1-9][0-9]*!)?(0|[1-9][0-9]*)(\.(0|[1-9][0-9]*))*((a|b|rc)(0|[1-9][0-9]*))?(\.post(0|[1-9][0-9]*))?(\.dev(0|[1-9][0-9]*))?$`)

View file

@ -7,59 +7,59 @@
//
// This documentation describes the Gitea API.
//
// Schemes: http, https
// BasePath: /api/v1
// Version: {{AppVer | JSEscape | Safe}}
// License: MIT http://opensource.org/licenses/MIT
// Schemes: http, https
// BasePath: /api/v1
// Version: {{AppVer | JSEscape | Safe}}
// License: MIT http://opensource.org/licenses/MIT
//
// Consumes:
// - application/json
// - text/plain
// Consumes:
// - application/json
// - text/plain
//
// Produces:
// - application/json
// - text/html
// Produces:
// - application/json
// - text/html
//
// Security:
// - BasicAuth :
// - Token :
// - AccessToken :
// - AuthorizationHeaderToken :
// - SudoParam :
// - SudoHeader :
// - TOTPHeader :
// Security:
// - BasicAuth :
// - Token :
// - AccessToken :
// - AuthorizationHeaderToken :
// - SudoParam :
// - SudoHeader :
// - TOTPHeader :
//
// SecurityDefinitions:
// BasicAuth:
// type: basic
// Token:
// type: apiKey
// name: token
// in: query
// AccessToken:
// type: apiKey
// name: access_token
// in: query
// AuthorizationHeaderToken:
// type: apiKey
// name: Authorization
// in: header
// description: API tokens must be prepended with "token" followed by a space.
// SudoParam:
// type: apiKey
// name: sudo
// in: query
// description: Sudo API request as the user provided as the key. Admin privileges are required.
// SudoHeader:
// type: apiKey
// name: Sudo
// in: header
// description: Sudo API request as the user provided as the key. Admin privileges are required.
// TOTPHeader:
// type: apiKey
// name: X-GITEA-OTP
// in: header
// description: Must be used in combination with BasicAuth if two-factor authentication is enabled.
// SecurityDefinitions:
// BasicAuth:
// type: basic
// Token:
// type: apiKey
// name: token
// in: query
// AccessToken:
// type: apiKey
// name: access_token
// in: query
// AuthorizationHeaderToken:
// type: apiKey
// name: Authorization
// in: header
// description: API tokens must be prepended with "token" followed by a space.
// SudoParam:
// type: apiKey
// name: sudo
// in: query
// description: Sudo API request as the user provided as the key. Admin privileges are required.
// SudoHeader:
// type: apiKey
// name: Sudo
// in: header
// description: Sudo API request as the user provided as the key. Admin privileges are required.
// TOTPHeader:
// type: apiKey
// name: X-GITEA-OTP
// in: header
// description: Must be used in combination with BasicAuth if two-factor authentication is enabled.
//
// swagger:meta
package v1

View file

@ -34,7 +34,7 @@ func GetGitAllRefs(ctx *context.APIContext) {
// required: true
// responses:
// "200":
// # "$ref": "#/responses/Reference" TODO: swagger doesnt support different output formats by ref
// "$ref": "#/responses/Reference"
// "$ref": "#/responses/ReferenceList"
// "404":
// "$ref": "#/responses/notFound"
@ -67,7 +67,7 @@ func GetGitRefs(ctx *context.APIContext) {
// required: true
// responses:
// "200":
// # "$ref": "#/responses/Reference" TODO: swagger doesnt support different output formats by ref
// "$ref": "#/responses/Reference"
// "$ref": "#/responses/ReferenceList"
// "404":
// "$ref": "#/responses/notFound"

View file

@ -566,8 +566,6 @@ func ListMyTrackedTimes(ctx *context.APIContext) {
// swagger:operation GET /user/times user userCurrentTrackedTimes
// ---
// summary: List the current user's tracked times
// produces:
// - application/json
// parameters:
// - name: page
// in: query
@ -577,6 +575,9 @@ func ListMyTrackedTimes(ctx *context.APIContext) {
// in: query
// description: page size of results
// type: integer
// produces:
// - application/json
// parameters:
// - name: since
// in: query
// description: Only show times updated after the given time. This is a timestamp in RFC 3339 format

View file

@ -585,6 +585,7 @@ func Edit(ctx *context.APIContext) {
// description: name of the repo to edit
// type: string
// required: true
// required: true
// - name: body
// in: body
// description: "Properties of a repo that you can edit"

View file

@ -48,6 +48,11 @@ func AddEmail(ctx *context.APIContext) {
// produces:
// - application/json
// parameters:
// - name: options
// in: body
// schema:
// "$ref": "#/definitions/CreateEmailOption"
// parameters:
// - name: body
// in: body
// schema:

View file

@ -588,8 +588,7 @@ func OIDCKeys(ctx *context.Context) {
// AccessTokenOAuth manages all access token requests by the client
func AccessTokenOAuth(ctx *context.Context) {
form := *web.GetForm(ctx).(*forms.AccessTokenForm)
// if there is no ClientID or ClientSecret in the request body, fill these fields by the Authorization header and ensure the provided field matches the Authorization header
if form.ClientID == "" || form.ClientSecret == "" {
if form.ClientID == "" {
authHeader := ctx.Req.Header.Get("Authorization")
authContent := strings.SplitN(authHeader, " ", 2)
if len(authContent) == 2 && authContent[0] == "Basic" {
@ -609,21 +608,7 @@ func AccessTokenOAuth(ctx *context.Context) {
})
return
}
if form.ClientID != "" && form.ClientID != pair[0] {
handleAccessTokenError(ctx, AccessTokenError{
ErrorCode: AccessTokenErrorCodeInvalidRequest,
ErrorDescription: "client_id in request body inconsistent with Authorization header",
})
return
}
form.ClientID = pair[0]
if form.ClientSecret != "" && form.ClientSecret != pair[1] {
handleAccessTokenError(ctx, AccessTokenError{
ErrorCode: AccessTokenErrorCodeInvalidRequest,
ErrorDescription: "client_secret in request body inconsistent with Authorization header",
})
return
}
form.ClientSecret = pair[1]
}
}
@ -701,13 +686,9 @@ func handleAuthorizationCode(ctx *context.Context, form forms.AccessTokenForm, s
return
}
if !app.ValidateClientSecret([]byte(form.ClientSecret)) {
errorDescription := "invalid client secret"
if form.ClientSecret == "" {
errorDescription = "invalid empty client secret"
}
handleAccessTokenError(ctx, AccessTokenError{
ErrorCode: AccessTokenErrorCodeUnauthorizedClient,
ErrorDescription: errorDescription,
ErrorDescription: "client is not authorized",
})
return
}

View file

@ -24,27 +24,27 @@ import (
)
func toBranchLink(act *models.Action) string {
return act.GetRepoAbsoluteLink() + "/src/branch/" + util.PathEscapeSegments(act.GetBranch())
return act.GetRepoLink() + "/src/branch/" + util.PathEscapeSegments(act.GetBranch())
}
func toTagLink(act *models.Action) string {
return act.GetRepoAbsoluteLink() + "/src/tag/" + util.PathEscapeSegments(act.GetTag())
return act.GetRepoLink() + "/src/tag/" + util.PathEscapeSegments(act.GetTag())
}
func toIssueLink(act *models.Action) string {
return act.GetRepoAbsoluteLink() + "/issues/" + url.PathEscape(act.GetIssueInfos()[0])
return act.GetRepoLink() + "/issues/" + url.PathEscape(act.GetIssueInfos()[0])
}
func toPullLink(act *models.Action) string {
return act.GetRepoAbsoluteLink() + "/pulls/" + url.PathEscape(act.GetIssueInfos()[0])
return act.GetRepoLink() + "/pulls/" + url.PathEscape(act.GetIssueInfos()[0])
}
func toSrcLink(act *models.Action) string {
return act.GetRepoAbsoluteLink() + "/src/" + util.PathEscapeSegments(act.GetBranch())
return act.GetRepoLink() + "/src/" + util.PathEscapeSegments(act.GetBranch())
}
func toReleaseLink(act *models.Action) string {
return act.GetRepoAbsoluteLink() + "/releases/tag/" + util.PathEscapeSegments(act.GetBranch())
return act.GetRepoLink() + "/releases/tag/" + util.PathEscapeSegments(act.GetBranch())
}
// renderMarkdown creates a minimal markdown render context from an action.
@ -79,17 +79,17 @@ func feedActionsToFeedItems(ctx *context.Context, actions models.ActionList) (it
title = act.ActUser.DisplayName() + " "
switch act.OpType {
case models.ActionCreateRepo:
title += ctx.TrHTMLEscapeArgs("action.create_repo", act.GetRepoAbsoluteLink(), act.ShortRepoPath())
link.Href = act.GetRepoAbsoluteLink()
title += ctx.TrHTMLEscapeArgs("action.create_repo", act.GetRepoLink(), act.ShortRepoPath())
link.Href = act.GetRepoLink()
case models.ActionRenameRepo:
title += ctx.TrHTMLEscapeArgs("action.rename_repo", act.GetContent(), act.GetRepoAbsoluteLink(), act.ShortRepoPath())
link.Href = act.GetRepoAbsoluteLink()
title += ctx.TrHTMLEscapeArgs("action.rename_repo", act.GetContent(), act.GetRepoLink(), act.ShortRepoPath())
link.Href = act.GetRepoLink()
case models.ActionCommitRepo:
link.Href = toBranchLink(act)
if len(act.Content) != 0 {
title += ctx.TrHTMLEscapeArgs("action.commit_repo", act.GetRepoAbsoluteLink(), link.Href, act.GetBranch(), act.ShortRepoPath())
title += ctx.TrHTMLEscapeArgs("action.commit_repo", act.GetRepoLink(), link.Href, act.GetBranch(), act.ShortRepoPath())
} else {
title += ctx.TrHTMLEscapeArgs("action.create_branch", act.GetRepoAbsoluteLink(), link.Href, act.GetBranch(), act.ShortRepoPath())
title += ctx.TrHTMLEscapeArgs("action.create_branch", act.GetRepoLink(), link.Href, act.GetBranch(), act.ShortRepoPath())
}
case models.ActionCreateIssue:
link.Href = toIssueLink(act)
@ -98,11 +98,11 @@ func feedActionsToFeedItems(ctx *context.Context, actions models.ActionList) (it
link.Href = toPullLink(act)
title += ctx.TrHTMLEscapeArgs("action.create_pull_request", link.Href, act.GetIssueInfos()[0], act.ShortRepoPath())
case models.ActionTransferRepo:
link.Href = act.GetRepoAbsoluteLink()
title += ctx.TrHTMLEscapeArgs("action.transfer_repo", act.GetContent(), act.GetRepoAbsoluteLink(), act.ShortRepoPath())
link.Href = act.GetRepoLink()
title += ctx.TrHTMLEscapeArgs("action.transfer_repo", act.GetContent(), act.GetRepoLink(), act.ShortRepoPath())
case models.ActionPushTag:
link.Href = toTagLink(act)
title += ctx.TrHTMLEscapeArgs("action.push_tag", act.GetRepoAbsoluteLink(), link.Href, act.GetTag(), act.ShortRepoPath())
title += ctx.TrHTMLEscapeArgs("action.push_tag", act.GetRepoLink(), link.Href, act.GetTag(), act.ShortRepoPath())
case models.ActionCommentIssue:
issueLink := toIssueLink(act)
if link.Href == "#" {
@ -140,26 +140,26 @@ func feedActionsToFeedItems(ctx *context.Context, actions models.ActionList) (it
}
title += ctx.TrHTMLEscapeArgs("action.reopen_pull_request", pullLink, act.GetIssueInfos()[0], act.ShortRepoPath())
case models.ActionDeleteTag:
link.Href = act.GetRepoAbsoluteLink()
title += ctx.TrHTMLEscapeArgs("action.delete_tag", act.GetRepoAbsoluteLink(), act.GetTag(), act.ShortRepoPath())
link.Href = act.GetRepoLink()
title += ctx.TrHTMLEscapeArgs("action.delete_tag", act.GetRepoLink(), act.GetTag(), act.ShortRepoPath())
case models.ActionDeleteBranch:
link.Href = act.GetRepoAbsoluteLink()
title += ctx.TrHTMLEscapeArgs("action.delete_branch", act.GetRepoAbsoluteLink(), html.EscapeString(act.GetBranch()), act.ShortRepoPath())
link.Href = act.GetRepoLink()
title += ctx.TrHTMLEscapeArgs("action.delete_branch", act.GetRepoLink(), html.EscapeString(act.GetBranch()), act.ShortRepoPath())
case models.ActionMirrorSyncPush:
srcLink := toSrcLink(act)
if link.Href == "#" {
link.Href = srcLink
}
title += ctx.TrHTMLEscapeArgs("action.mirror_sync_push", act.GetRepoAbsoluteLink(), srcLink, act.GetBranch(), act.ShortRepoPath())
title += ctx.TrHTMLEscapeArgs("action.mirror_sync_push", act.GetRepoLink(), srcLink, act.GetBranch(), act.ShortRepoPath())
case models.ActionMirrorSyncCreate:
srcLink := toSrcLink(act)
if link.Href == "#" {
link.Href = srcLink
}
title += ctx.TrHTMLEscapeArgs("action.mirror_sync_create", act.GetRepoAbsoluteLink(), srcLink, act.GetBranch(), act.ShortRepoPath())
title += ctx.TrHTMLEscapeArgs("action.mirror_sync_create", act.GetRepoLink(), srcLink, act.GetBranch(), act.ShortRepoPath())
case models.ActionMirrorSyncDelete:
link.Href = act.GetRepoAbsoluteLink()
title += ctx.TrHTMLEscapeArgs("action.mirror_sync_delete", act.GetRepoAbsoluteLink(), act.GetBranch(), act.ShortRepoPath())
link.Href = act.GetRepoLink()
title += ctx.TrHTMLEscapeArgs("action.mirror_sync_delete", act.GetRepoLink(), act.GetBranch(), act.ShortRepoPath())
case models.ActionApprovePullRequest:
pullLink := toPullLink(act)
title += ctx.TrHTMLEscapeArgs("action.approve_pull_request", pullLink, act.GetIssueInfos()[0], act.ShortRepoPath())
@ -174,16 +174,16 @@ func feedActionsToFeedItems(ctx *context.Context, actions models.ActionList) (it
if link.Href == "#" {
link.Href = releaseLink
}
title += ctx.TrHTMLEscapeArgs("action.publish_release", act.GetRepoAbsoluteLink(), releaseLink, act.ShortRepoPath(), act.Content)
title += ctx.TrHTMLEscapeArgs("action.publish_release", act.GetRepoLink(), releaseLink, act.ShortRepoPath(), act.Content)
case models.ActionPullReviewDismissed:
pullLink := toPullLink(act)
title += ctx.TrHTMLEscapeArgs("action.review_dismissed", pullLink, act.GetIssueInfos()[0], act.ShortRepoPath(), act.GetIssueInfos()[1])
case models.ActionStarRepo:
link.Href = act.GetRepoAbsoluteLink()
title += ctx.TrHTMLEscapeArgs("action.starred_repo", act.GetRepoAbsoluteLink(), act.GetRepoPath())
link.Href = act.GetRepoLink()
title += ctx.TrHTMLEscapeArgs("action.starred_repo", act.GetRepoLink(), act.GetRepoPath())
case models.ActionWatchRepo:
link.Href = act.GetRepoAbsoluteLink()
title += ctx.TrHTMLEscapeArgs("action.watched_repo", act.GetRepoAbsoluteLink(), act.GetRepoPath())
link.Href = act.GetRepoLink()
title += ctx.TrHTMLEscapeArgs("action.watched_repo", act.GetRepoLink(), act.GetRepoPath())
default:
return nil, fmt.Errorf("unknown action type: %v", act.OpType)
}
@ -193,14 +193,14 @@ func feedActionsToFeedItems(ctx *context.Context, actions models.ActionList) (it
switch act.OpType {
case models.ActionCommitRepo, models.ActionMirrorSyncPush:
push := templates.ActionContent2Commits(act)
repoLink := act.GetRepoAbsoluteLink()
repoLink := act.GetRepoLink()
for _, commit := range push.Commits {
if len(desc) != 0 {
desc += "\n\n"
}
desc += fmt.Sprintf("<a href=\"%s\">%s</a>\n%s",
html.EscapeString(fmt.Sprintf("%s/commit/%s", act.GetRepoAbsoluteLink(), commit.Sha1)),
html.EscapeString(fmt.Sprintf("%s/commit/%s", act.GetRepoLink(), commit.Sha1)),
commit.Sha1,
templates.RenderCommitMessage(ctx, commit.Message, repoLink, nil),
)
@ -209,7 +209,7 @@ func feedActionsToFeedItems(ctx *context.Context, actions models.ActionList) (it
if push.Len > 1 {
link = &feeds.Link{Href: fmt.Sprintf("%s/%s", setting.AppSubURL, push.CompareURL)}
} else if push.Len == 1 {
link = &feeds.Link{Href: fmt.Sprintf("%s/commit/%s", act.GetRepoAbsoluteLink(), push.Commits[0].Sha1)}
link = &feeds.Link{Href: fmt.Sprintf("%s/commit/%s", act.GetRepoLink(), push.Commits[0].Sha1)}
}
case models.ActionCreateIssue, models.ActionCreatePullRequest:

View file

@ -83,7 +83,7 @@ func Commits(ctx *context.Context) {
ctx.Data["CommitCount"] = commitsCount
ctx.Data["RefName"] = ctx.Repo.RefName
pager := context.NewPagination(int(commitsCount), pageSize, page, 5)
pager := context.NewPagination(int(commitsCount), setting.Git.CommitsRangeSize, page, 5)
pager.SetDefaultParams(ctx)
ctx.Data["Page"] = pager

View file

@ -113,17 +113,17 @@ func setCsvCompareContext(ctx *context.Context) {
Error string
}
ctx.Data["CreateCsvDiff"] = func(diffFile *gitdiff.DiffFile, baseBlob, headBlob *git.Blob) CsvDiffResult {
if diffFile == nil {
ctx.Data["CreateCsvDiff"] = func(diffFile *gitdiff.DiffFile, baseCommit, headCommit *git.Commit) CsvDiffResult {
if diffFile == nil || baseCommit == nil || headCommit == nil {
return CsvDiffResult{nil, ""}
}
errTooLarge := errors.New(ctx.Locale.Tr("repo.error.csv.too_large"))
csvReaderFromCommit := func(ctx *markup.RenderContext, blob *git.Blob) (*csv.Reader, io.Closer, error) {
if blob == nil {
// It's ok for blob to be nil (file added or deleted)
return nil, nil, nil
csvReaderFromCommit := func(ctx *markup.RenderContext, c *git.Commit) (*csv.Reader, io.Closer, error) {
blob, err := c.GetBlobByPath(diffFile.Name)
if err != nil {
return nil, nil, err
}
if setting.UI.CSV.MaxFileSize != 0 && setting.UI.CSV.MaxFileSize < blob.Size() {
@ -139,28 +139,28 @@ func setCsvCompareContext(ctx *context.Context) {
return csvReader, reader, err
}
baseReader, baseBlobCloser, err := csvReaderFromCommit(&markup.RenderContext{Ctx: ctx, RelativePath: diffFile.OldName}, baseBlob)
baseReader, baseBlobCloser, err := csvReaderFromCommit(&markup.RenderContext{Ctx: ctx, RelativePath: diffFile.OldName}, baseCommit)
if baseBlobCloser != nil {
defer baseBlobCloser.Close()
}
if err == errTooLarge {
return CsvDiffResult{nil, err.Error()}
}
if err != nil {
if err == errTooLarge {
return CsvDiffResult{nil, err.Error()}
}
log.Error("error whilst creating csv.Reader from file %s in base commit %s in %s: %v", diffFile.Name, baseBlob.ID.String(), ctx.Repo.Repository.Name, err)
return CsvDiffResult{nil, "unable to load file"}
log.Error("CreateCsvDiff error whilst creating baseReader from file %s in commit %s in %s: %v", diffFile.Name, baseCommit.ID.String(), ctx.Repo.Repository.Name, err)
return CsvDiffResult{nil, "unable to load file from base commit"}
}
headReader, headBlobCloser, err := csvReaderFromCommit(&markup.RenderContext{Ctx: ctx, RelativePath: diffFile.Name}, headBlob)
headReader, headBlobCloser, err := csvReaderFromCommit(&markup.RenderContext{Ctx: ctx, RelativePath: diffFile.Name}, headCommit)
if headBlobCloser != nil {
defer headBlobCloser.Close()
}
if err == errTooLarge {
return CsvDiffResult{nil, err.Error()}
}
if err != nil {
if err == errTooLarge {
return CsvDiffResult{nil, err.Error()}
}
log.Error("error whilst creating csv.Reader from file %s in head commit %s in %s: %v", diffFile.Name, headBlob.ID.String(), ctx.Repo.Repository.Name, err)
return CsvDiffResult{nil, "unable to load file"}
log.Error("CreateCsvDiff error whilst creating headReader from file %s in commit %s in %s: %v", diffFile.Name, headCommit.ID.String(), ctx.Repo.Repository.Name, err)
return CsvDiffResult{nil, "unable to load file from head commit"}
}
sections, err := gitdiff.CreateCsvDiff(diffFile, baseReader, headReader)

View file

@ -116,17 +116,9 @@ func releasesOrTags(ctx *context.Context, isTagList bool) {
ctx.Data["CanCreateRelease"] = writeAccess && !ctx.Repo.Repository.IsArchived
opts := models.FindReleasesOptions{
ListOptions: listOptions,
}
if isTagList {
// for the tags list page, show all releases with real tags (having real commit-id),
// the drafts should also be included because a real tag might be used as a draft.
opts.IncludeDrafts = true
opts.IncludeTags = true
opts.HasSha1 = util.OptionalBoolTrue
} else {
// only show draft releases for users who can write, read-only users shouldn't see draft releases.
opts.IncludeDrafts = writeAccess
ListOptions: listOptions,
IncludeDrafts: writeAccess && !isTagList,
IncludeTags: isTagList,
}
releases, err := models.GetReleasesByRepoID(ctx.Repo.Repository.ID, opts)

View file

@ -1448,6 +1448,8 @@ func GetDiff(gitRepo *git.Repository, opts *DiffOptions, files ...string) (*Diff
} else if language, has := attrs["gitlab-language"]; has && language != "unspecified" && language != "" {
diffFile.Language = language
}
} else {
log.Error("Unexpected error: %v", err)
}
}

View file

@ -26,6 +26,7 @@ import (
"code.gitea.io/gitea/modules/structs"
"github.com/google/uuid"
"gopkg.in/yaml.v2"
)

View file

@ -78,9 +78,8 @@ type GiteaDownloader struct {
}
// NewGiteaDownloader creates a gitea Downloader via gitea API
//
// Use either a username/password or personal token. token is preferred
// Note: Public access only allows very basic access
// Use either a username/password or personal token. token is preferred
// Note: Public access only allows very basic access
func NewGiteaDownloader(ctx context.Context, baseURL, repoPath, username, password, token string) (*GiteaDownloader, error) {
giteaClient, err := gitea_sdk.NewClient(
baseURL,

View file

@ -412,10 +412,6 @@ func (g *GiteaLocalUploader) CreateIssues(issues ...*base.Issue) error {
},
}
if is.ForeignReference.ForeignIndex == "0" {
is.ForeignReference.ForeignIndex = strconv.FormatInt(is.Index, 10)
}
if err := g.remapUser(issue, &is); err != nil {
return err
}

View file

@ -71,9 +71,8 @@ type GitlabDownloader struct {
}
// NewGitlabDownloader creates a gitlab Downloader via gitlab API
//
// Use either a username/password, personal token entered into the username field, or anonymous/public access
// Note: Public access only allows very basic access
// Use either a username/password, personal token entered into the username field, or anonymous/public access
// Note: Public access only allows very basic access
func NewGitlabDownloader(ctx context.Context, baseURL, repoPath, username, password, token string) (*GitlabDownloader, error) {
gitlabClient, err := gitlab.NewClient(token, gitlab.WithBaseURL(baseURL), gitlab.WithHTTPClient(NewMigrationHTTPClient()))
// Only use basic auth if token is blank and password is NOT
@ -375,8 +374,7 @@ type gitlabIssueContext struct {
}
// GetIssues returns issues according start and limit
//
// Note: issue label description and colors are not supported by the go-gitlab library at this time
// Note: issue label description and colors are not supported by the go-gitlab library at this time
func (g *GitlabDownloader) GetIssues(page, perPage int) ([]*base.Issue, bool, error) {
state := "all"
sort := "asc"

View file

@ -28,7 +28,6 @@ import (
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/cache"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/notification"
"code.gitea.io/gitea/modules/references"
@ -166,10 +165,9 @@ func Merge(ctx context.Context, pr *issues_model.PullRequest, doer *user_model.U
go AddTestPullRequestTask(doer, pr.BaseRepo.ID, pr.BaseBranch, false, "", "")
}()
// Run the merge in the hammer context to prevent cancellation
hammerCtx := graceful.GetManager().HammerContext()
pr.MergedCommitID, err = rawMerge(hammerCtx, pr, doer, mergeStyle, expectedHeadCommitID, message)
// TODO: make it able to do this in a database session
mergeCtx := context.Background()
pr.MergedCommitID, err = rawMerge(mergeCtx, pr, doer, mergeStyle, expectedHeadCommitID, message)
if err != nil {
return err
}
@ -178,18 +176,18 @@ func Merge(ctx context.Context, pr *issues_model.PullRequest, doer *user_model.U
pr.Merger = doer
pr.MergerID = doer.ID
if _, err := pr.SetMerged(hammerCtx); err != nil {
if _, err := pr.SetMerged(ctx); err != nil {
log.Error("setMerged [%d]: %v", pr.ID, err)
}
if err := pr.LoadIssueCtx(hammerCtx); err != nil {
if err := pr.LoadIssueCtx(ctx); err != nil {
log.Error("loadIssue [%d]: %v", pr.ID, err)
}
if err := pr.Issue.LoadRepo(hammerCtx); err != nil {
if err := pr.Issue.LoadRepo(ctx); err != nil {
log.Error("loadRepo for issue [%d]: %v", pr.ID, err)
}
if err := pr.Issue.Repo.GetOwner(hammerCtx); err != nil {
if err := pr.Issue.Repo.GetOwner(ctx); err != nil {
log.Error("GetOwner for issue repo [%d]: %v", pr.ID, err)
}
@ -199,17 +197,17 @@ func Merge(ctx context.Context, pr *issues_model.PullRequest, doer *user_model.U
cache.Remove(pr.Issue.Repo.GetCommitsCountCacheKey(pr.BaseBranch, true))
// Resolve cross references
refs, err := pr.ResolveCrossReferences(hammerCtx)
refs, err := pr.ResolveCrossReferences(ctx)
if err != nil {
log.Error("ResolveCrossReferences: %v", err)
return nil
}
for _, ref := range refs {
if err = ref.LoadIssueCtx(hammerCtx); err != nil {
if err = ref.LoadIssueCtx(ctx); err != nil {
return err
}
if err = ref.Issue.LoadRepo(hammerCtx); err != nil {
if err = ref.Issue.LoadRepo(ctx); err != nil {
return err
}
close := ref.RefAction == references.XRefActionCloses

View file

@ -157,7 +157,7 @@
<tbody>
{{range .Queue.Workers}}
<tr>
<td>{{.Workers}}{{if .IsFlusher}}<span title="{{$.i18n.Tr "admin.monitor.queue.flush"}}">{{svg "octicon-sync"}}</span>{{end}}</td>
<td>{{.Workers}}{{if .IsFlusher}}<span title="{{.i18n.Tr "admin.monitor.queue.flush"}}">{{svg "octicon-sync"}}</span>{{end}}</td>
<td>{{DateFmtLong .Start}}</td>
<td>{{if .HasTimeout}}{{DateFmtLong .Timeout}}{{else}}-{{end}}</td>
<td>

View file

@ -43,7 +43,7 @@
{{if .PackageDescriptor.Metadata.ImageLayers}}
<h4 class="ui top attached header">{{.i18n.Tr "packages.container.layers"}}</h4>
<div class="ui attached segment">
<table class="ui very basic compact table">
<table id="notice-table" class="ui very basic compact table">
<tbody>
{{range .PackageDescriptor.Metadata.ImageLayers}}
<tr>
@ -57,7 +57,7 @@
{{if .PackageDescriptor.Metadata.Labels}}
<h4 class="ui top attached header">{{.i18n.Tr "packages.container.labels"}}</h4>
<div class="ui attached segment">
<table class="ui very basic compact table container-labels">
<table id="notice-table" class="ui very basic compact table">
<thead>
<tr>
<th>{{.i18n.Tr "packages.container.labels.key"}}</th>

View file

@ -1,11 +1,6 @@
{{/*Golang's template has a bug with string interpolation containing slashes,
the double slash will be treated as a comment there.
But there are also JS lint rules for template that require to use string interpolation in 1.17*/}}
<script>
// synchronously set clone button states and urls here to avoid flickering
// on page load. initRepoCloneLink calls this when proto changes.
// this applies the protocol-dependant clone url to all elements with the
// `js-clone-url` and `js-clone-url-vsc` classes.
// TODO: This localStorage setting should be moved to backend user config
// so it's available during rendering, then this inline script can be removed.
(window.updateCloneStates = function() {
@ -24,9 +19,5 @@ But there are also JS lint rules for template that require to use string interpo
for (const el of document.getElementsByClassName('js-clone-url')) {
el[el.nodeName === 'INPUT' ? 'value' : 'textContent'] = link;
}
const sep = '//';
for (const el of document.getElementsByClassName('js-clone-url-vsc')) {
el.href = `vscode:${sep}vscode.git/clone?url=${encodeURIComponent(link)}`;
}
})();
</script>

View file

@ -57,8 +57,7 @@
{{end}}
</ol>
<div id="diff-file-boxes">
{{range $file := .Diff.Files}}
{{/*notice: the index of Diff.Files should not be used for element ID, because the index will be restarted from 0 when doing load-more for PRs with a lot of files*/}}
{{range $i, $file := .Diff.Files}}
{{$blobBase := call $.GetBlobByPathForCommit $.BaseCommit $file.OldName}}
{{$blobHead := call $.GetBlobByPathForCommit $.HeadCommit $file.Name}}
{{$isImage := or (call $.IsBlobAnImage $blobBase) (call $.IsBlobAnImage $blobHead)}}
@ -94,8 +93,8 @@
<div class="diff-file-header-actions df ac">
{{if $showFileViewToggle}}
<div class="ui compact icon buttons">
<span class="ui tiny basic button tooltip file-view-toggle" data-toggle-selector="#diff-source-{{$file.NameHash}}" data-content="{{$.i18n.Tr "repo.file_view_source"}}" data-position="bottom center">{{svg "octicon-code"}}</span>
<span class="ui tiny basic button tooltip file-view-toggle active" data-toggle-selector="#diff-rendered-{{$file.NameHash}}" data-content="{{$.i18n.Tr "repo.file_view_rendered"}}" data-position="bottom center">{{svg "octicon-file"}}</span>
<span class="ui tiny basic button tooltip file-view-toggle" data-toggle-selector="#diff-source-{{$i}}" data-content="{{$.i18n.Tr "repo.file_view_source"}}" data-position="bottom center">{{svg "octicon-code"}}</span>
<span class="ui tiny basic button tooltip file-view-toggle active" data-toggle-selector="#diff-rendered-{{$i}}" data-content="{{$.i18n.Tr "repo.file_view_rendered"}}" data-position="bottom center">{{svg "octicon-file"}}</span>
</div>
{{end}}
{{if $file.IsProtected}}
@ -116,14 +115,15 @@
{{if $file.HasChangedSinceLastReview}}
<span class="changed-since-last-review unselectable">{{$.i18n.Tr "repo.pulls.has_changed_since_last_review"}}</span>
{{end}}
<label data-link="{{$.Issue.Link}}/viewed-files" data-headcommit="{{$.PullHeadCommitID}}" class="viewed-file-form unselectable{{if $file.IsViewed}} viewed-file-checked-form{{end}}">
<input type="checkbox" name="{{$file.GetDiffFileName}}" autocomplete="off"{{if $file.IsViewed}} checked{{end}}> {{$.i18n.Tr "repo.pulls.has_viewed_file"}}
</label>
<div data-link="{{$.Issue.Link}}/viewed-files" data-headcommit="{{$.PullHeadCommitID}}" class="viewed-file-form unselectable{{if $file.IsViewed}} viewed-file-checked-form{{end}}">
<input type="checkbox" name="{{$file.GetDiffFileName}}" id="viewed-file-checkbox-{{$i}}" autocomplete="off" {{if $file.IsViewed}}checked{{end}}></input>
<label for="viewed-file-checkbox-{{$i}}">{{$.i18n.Tr "repo.pulls.has_viewed_file"}}</label>
</div>
{{end}}
</div>
</h4>
<div class="diff-file-body ui attached unstackable table segment" {{if $file.IsViewed}}data-folded="true"{{end}}>
<div id="diff-source-{{$file.NameHash}}" class="file-body file-code unicode-escaped code-diff{{if $.IsSplitStyle}} code-diff-split{{else}} code-diff-unified{{end}}{{if $showFileViewToggle}} hide{{end}}">
<div id="diff-source-{{$i}}" class="file-body file-code unicode-escaped code-diff{{if $.IsSplitStyle}} code-diff-split{{else}} code-diff-unified{{end}}{{if $showFileViewToggle}} hide{{end}}">
{{if or $file.IsIncomplete $file.IsBin}}
<div class="diff-file-body binary" style="padding: 5px 10px;">
{{if $file.IsIncomplete}}
@ -148,12 +148,12 @@
{{end}}
</div>
{{if $showFileViewToggle}}
<div id="diff-rendered-{{$file.NameHash}}" class="file-body file-code {{if $.IsSplitStyle}} code-diff-split{{else}} code-diff-unified{{end}}">
<div id="diff-rendered-{{$i}}" class="file-body file-code {{if $.IsSplitStyle}} code-diff-split{{else}} code-diff-unified{{end}}">
<table class="chroma w-100">
{{if $isImage}}
{{template "repo/diff/image_diff" dict "file" . "root" $ "blobBase" $blobBase "blobHead" $blobHead}}
{{else}}
{{template "repo/diff/csv_diff" dict "file" . "root" $ "blobBase" $blobBase "blobHead" $blobHead}}
{{template "repo/diff/csv_diff" dict "file" . "root" $}}
{{end}}
</table>
</div>

View file

@ -1,6 +1,6 @@
<tr>
<td>
{{$result := call .root.CreateCsvDiff .file .blobBase .blobHead}}
{{$result := call .root.CreateCsvDiff .file .root.BaseCommit .root.HeadCommit}}
{{if $result.Error}}
<div class="ui center">{{$result.Error}}</div>
{{else if $result.Sections}}

View file

@ -116,19 +116,19 @@
<!-- Only show clone panel in repository home page -->
{{if eq $n 0}}
<div class="ui action tiny input" id="clone-panel">
{{template "repo/clone_buttons" .}}
<button id="download-btn" class="ui basic small compact jump dropdown icon button tooltip" data-content="{{.i18n.Tr "repo.download_archive"}}" data-position="top right">
{{svg "octicon-download"}}
<div class="menu">
{{if not $.DisableDownloadSourceArchives}}
<a class="item archive-link" href="{{$.RepoLink}}/archive/{{PathEscapeSegments $.RefName}}.zip" rel="nofollow">{{svg "octicon-file-zip" 16 "mr-3"}}{{.i18n.Tr "repo.download_zip"}}</a>
<a class="item archive-link" href="{{$.RepoLink}}/archive/{{PathEscapeSegments $.RefName}}.tar.gz" rel="nofollow">{{svg "octicon-file-zip" 16 "mr-3"}}{{.i18n.Tr "repo.download_tar"}}</a>
<a class="item archive-link" href="{{$.RepoLink}}/archive/{{PathEscapeSegments $.RefName}}.bundle" rel="nofollow">{{svg "octicon-package" 16 "mr-3"}}{{.i18n.Tr "repo.download_bundle"}}</a>
{{end}}
<a class="item js-clone-url-vsc" href="vscode://vscode.git/clone?url={{.CloneButtonOriginLink.HTTPS}}">{{svg "gitea-vscode" 16 "mr-3"}}{{.i18n.Tr "repo.clone_in_vsc"}}</a>
</div>
</button>
{{template "repo/clone_script" .}}{{/* the script will update `.js-clone-url` and related elements */}}
{{template "repo/clone_buttons" .}}
{{template "repo/clone_script" .}}
<button id="download-btn" class="ui basic small compact jump dropdown icon button tooltip" data-content="{{.i18n.Tr "repo.download_archive"}}" data-position="top right">
{{svg "octicon-download"}}
<div class="menu">
{{if not $.DisableDownloadSourceArchives}}
<a class="item archive-link" href="{{$.RepoLink}}/archive/{{PathEscapeSegments $.RefName}}.zip" rel="nofollow">{{svg "octicon-file-zip" 16 "mr-3"}}{{.i18n.Tr "repo.download_zip"}}</a>
<a class="item archive-link" href="{{$.RepoLink}}/archive/{{PathEscapeSegments $.RefName}}.tar.gz" rel="nofollow">{{svg "octicon-file-zip" 16 "mr-3"}}{{.i18n.Tr "repo.download_tar"}}</a>
<a class="item archive-link" href="{{$.RepoLink}}/archive/{{PathEscapeSegments $.RefName}}.bundle" rel="nofollow">{{svg "octicon-package" 16 "mr-3"}}{{.i18n.Tr "repo.download_bundle"}}</a>
{{end}}
<a class="item" href="vscode://vscode.git/clone?url={{$.RepoCloneLink.HTTPS}}">{{svg "gitea-vscode" 16 "mr-3"}}{{.i18n.Tr "repo.clone_in_vsc"}}</a>
</div>
</button>
</div>
{{end}}
{{if and (ne $n 0) (not .IsViewFile) (not .IsBlame) }}

View file

@ -77,12 +77,14 @@
<span class="ui green label">{{$.i18n.Tr "repo.release.stable"}}</span>
{{end}}
<span class="tag text blue">
<a class="df ac je" href="{{if not .Sha1}}#{{else}}{{$.RepoLink}}/src/tag/{{.TagName | PathEscapeSegments}}{{end}}" rel="nofollow">{{svg "octicon-tag" 16 "mr-2"}}{{.TagName}}</a>
<a class="df ac je" href="{{if .IsDraft}}#{{else}}{{$.RepoLink}}/src/tag/{{.TagName | PathEscapeSegments}}{{end}}" rel="nofollow">{{svg "octicon-tag" 16 "mr-2"}}{{.TagName}}</a>
</span>
{{if .Sha1}}
{{if not .IsDraft}}
<span class="commit">
<a class="mono" href="{{$.RepoLink}}/src/commit/{{.Sha1}}" rel="nofollow">{{svg "octicon-git-commit" 16 "mr-2"}}{{ShortSha .Sha1}}</a>
</span>
{{end}}
{{if .Sha1 }}
{{template "repo/branch_dropdown" dict "root" $ "release" .}}
{{end}}
{{end}}

View file

@ -12420,18 +12420,6 @@
"summary": "List the current user's tracked times",
"operationId": "userCurrentTrackedTimes",
"parameters": [
{
"type": "integer",
"description": "page number of results to return (1-based)",
"name": "page",
"in": "query"
},
{
"type": "integer",
"description": "page size of results",
"name": "limit",
"in": "query"
},
{
"type": "string",
"format": "date-time",
@ -15631,6 +15619,7 @@
"$ref": "#/definitions/FileCommitResponse"
},
"content": {
"type": "object",
"x-go-name": "Content"
},
"verification": {
@ -18672,6 +18661,7 @@
"x-go-name": "Ignored"
},
"reason": {
"type": "object",
"x-go-name": "Reason"
},
"repository_url": {

View file

@ -33,7 +33,7 @@
</div>
<div class="content">
<strong>{{$provider}}</strong>
{{if $loginSource.IsActive}}<span class="text red">{{$.i18n.Tr "repo.settings.active"}}</span>{{end}}
{{if $loginSource.IsActive}}<span class="text red">{{$.i18n.Tr "settings.active"}}</span>{{end}}
</div>
</div>
{{end}}

View file

@ -1,9 +0,0 @@
.container-labels {
td:nth-child(1) {
vertical-align: top;
}
td:nth-child(2) {
overflow-wrap: anywhere;
}
}

View file

@ -272,22 +272,13 @@ a.blob-excerpt:hover {
}
.viewed-file-form {
display: flex;
align-items: center;
border: 1px none;
padding: 4px 8px;
margin: -8px 0; // just like other buttons in the diff box header
border-radius: .285rem; // just like .ui.tiny.button
font-size: .857rem; // just like .ui.tiny.button
}
.viewed-file-form input {
margin-right: 4px;
margin: 0 3px;
padding: 0 3px;
border-radius: 3px;
}
.viewed-file-checked-form {
background-color: var(--color-primary-light-6);
border: 1px solid var(--color-primary-light-4);
background-color: var(--color-primary-light-4);
}
#viewed-files-summary {

View file

@ -34,6 +34,5 @@
@import "_admin";
@import "_explore";
@import "_review";
@import "_package";
@import "./helpers.less";