Compare commits

..

No commits in common. "4fcf3a3f90ddced158cb31fbb5c1b534c824fc8c" and "2b3f12f6fd12afebb3b8397dc612621df6c730e2" have entirely different histories.

51 changed files with 228 additions and 495 deletions

View File

@ -12,9 +12,6 @@ trigger:
- push - push
- tag - tag
- pull_request - pull_request
paths:
exclude:
- docs/**
volumes: volumes:
- name: deps - name: deps
@ -115,6 +112,7 @@ steps:
image: golang:1.19 # this step is kept as the lowest version of golang that we support image: golang:1.19 # this step is kept as the lowest version of golang that we support
pull: always pull: always
environment: environment:
GO111MODULE: on
GOPROXY: https://goproxy.io GOPROXY: https://goproxy.io
commands: commands:
- go build -o gitea_no_gcc # test if build succeeds without the sqlite tag - go build -o gitea_no_gcc # test if build succeeds without the sqlite tag
@ -126,6 +124,7 @@ steps:
- name: build-backend-arm64 - name: build-backend-arm64
image: golang:1.20 image: golang:1.20
environment: environment:
GO111MODULE: on
GOPROXY: https://goproxy.io GOPROXY: https://goproxy.io
GOOS: linux GOOS: linux
GOARCH: arm64 GOARCH: arm64
@ -141,6 +140,7 @@ steps:
- name: build-backend-windows - name: build-backend-windows
image: golang:1.20 image: golang:1.20
environment: environment:
GO111MODULE: on
GOPROXY: https://goproxy.io GOPROXY: https://goproxy.io
GOOS: windows GOOS: windows
GOARCH: amd64 GOARCH: amd64
@ -155,6 +155,7 @@ steps:
- name: build-backend-386 - name: build-backend-386
image: golang:1.20 image: golang:1.20
environment: environment:
GO111MODULE: on
GOPROXY: https://goproxy.io GOPROXY: https://goproxy.io
GOOS: linux GOOS: linux
GOARCH: 386 GOARCH: 386
@ -182,9 +183,6 @@ trigger:
- push - push
- tag - tag
- pull_request - pull_request
paths:
exclude:
- docs/**
volumes: volumes:
- name: deps - name: deps
@ -412,9 +410,6 @@ trigger:
- push - push
- tag - tag
- pull_request - pull_request
paths:
exclude:
- docs/**
volumes: volumes:
- name: deps - name: deps
@ -522,9 +517,6 @@ depends_on:
trigger: trigger:
event: event:
- pull_request - pull_request
paths:
exclude:
- docs/**
volumes: volumes:
- name: deps - name: deps
@ -704,9 +696,6 @@ trigger:
- "release/*" - "release/*"
event: event:
- push - push
paths:
exclude:
- docs/**
depends_on: depends_on:
- testing-amd64 - testing-amd64
@ -958,9 +947,6 @@ trigger:
- push - push
- tag - tag
- pull_request - pull_request
paths:
include:
- docs/**
steps: steps:
- name: build-docs - name: build-docs
@ -1255,9 +1241,6 @@ depends_on:
trigger: trigger:
ref: ref:
- "refs/pull/**" - "refs/pull/**"
paths:
exclude:
- docs/**
steps: steps:
- name: dryrun - name: dryrun

View File

@ -1,9 +1,9 @@
<!-- start tips --> <!--
Please check the following: Please check the following:
1. Make sure you are targeting the `main` branch, pull requests on release branches are only allowed for backports.
2. Make sure you have read contributing guidelines: https://github.com/go-gitea/gitea/blob/main/CONTRIBUTING.md . 1. Make sure you are targeting the `main` branch, pull requests on release branches are only allowed for bug fixes.
3. Describe what your pull request does and which issue you're targeting (if any). 2. Read contributing guidelines: https://github.com/go-gitea/gitea/blob/main/CONTRIBUTING.md
4. It is recommended to enable "Allow edits by maintainers", so maintainers can help more easily. 3. Describe what your pull request does and which issue you're targeting (if any)
5. Your input here will be included in the commit message when this PR has been merged. If you don't want some content to be included, please separate them with a line like `---`.
6. Delete all these tips before posting. -->
<!-- end tips -->

View File

@ -4,43 +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 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). been added to each release, please refer to the [blog](https://blog.gitea.io).
## [1.18.4](https://github.com/go-gitea/gitea/releases/tag/1.18.4) - 2023-02-20
* SECURITY
* Provide the ability to set password hash algorithm parameters (#22942) (#22943)
* Add command to bulk set must-change-password (#22823) (#22928)
* ENHANCEMENTS
* Use import of OCI structs (#22765) (#22805)
* Fix color of tertiary button on dark theme (#22739) (#22744)
* Link issue and pull requests status change in UI notifications directly to their event in the timelined view. (#22627) (#22642)
* BUGFIXES
* Notify on container image create (#22806) (#22965)
* Fix blame view missing lines (#22826) (#22929)
* Fix incorrect role labels for migrated issues and comments (#22914) (#22923)
* Fix PR file tree folders no longer collapsing (#22864) (#22872)
* Escape filename when assemble URL (#22850) (#22871)
* Fix isAllowed of escapeStreamer (#22814) (#22837)
* Load issue before accessing index in merge message (#22822) (#22830)
* Improve trace logging for pulls and processes (#22633) (#22812)
* Fix restore repo bug, clarify the problem of ForeignIndex (#22776) (#22794)
* Add default user visibility to cli command "admin user create" (#22750) (#22760)
* Escape path for the file list (#22741) (#22757)
* Fix bugs with WebAuthn preventing sign in and registration. (#22651) (#22721)
* Add missing close bracket in imagediff (#22710) (#22712)
* Move code comments to a standalone file and fix the bug when adding a reply to an outdated review appears to not post(#20821) (#22707)
* Fix line spacing for plaintext previews (#22699) (#22701)
* Fix wrong hint when deleting a branch successfully from pull request UI (#22673) (#22698)
* Fix README TOC links (#22577) (#22677)
* Fix missing message in git hook when pull requests disabled on fork (#22625) (#22658)
* Improve checkIfPRContentChanged (#22611) (#22644)
* Prevent duplicate labels when importing more than 99 (#22591) (#22598)
* Don't return duplicated users who can create org repo (#22560) (#22562)
* BUILD
* Upgrade golangcilint to v1.51.0 (#22764)
* MISC
* Use proxy for pull mirror (#22771) (#22772)
* Use `--index-url` in PyPi description (#22620) (#22636)
## [1.18.3](https://github.com/go-gitea/gitea/releases/tag/v1.18.3) - 2023-01-23 ## [1.18.3](https://github.com/go-gitea/gitea/releases/tag/v1.18.3) - 2023-01-23
* SECURITY * SECURITY

View File

@ -47,5 +47,3 @@ Wim <wim@42.be> (@42wim)
Xinyu Zhou <i@sourcehut.net> (@xin-u) Xinyu Zhou <i@sourcehut.net> (@xin-u)
Jason Song <i@wolfogre.com> (@wolfogre) Jason Song <i@wolfogre.com> (@wolfogre)
Yarden Shoham <hrsi88@gmail.com> (@yardenshoham) Yarden Shoham <hrsi88@gmail.com> (@yardenshoham)
Yu Tian <zettat123@gmail.com> (@Zettat123)
Eddie Yang <576951401@qq.com> (@yp05327)

6
go.mod
View File

@ -103,10 +103,10 @@ require (
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20220924101305-151362477c87 github.com/yuin/goldmark-highlighting/v2 v2.0.0-20220924101305-151362477c87
github.com/yuin/goldmark-meta v1.1.0 github.com/yuin/goldmark-meta v1.1.0
golang.org/x/crypto v0.4.0 golang.org/x/crypto v0.4.0
golang.org/x/net v0.7.0 golang.org/x/net v0.4.0
golang.org/x/oauth2 v0.3.0 golang.org/x/oauth2 v0.3.0
golang.org/x/sys v0.5.0 golang.org/x/sys v0.3.0
golang.org/x/text v0.7.0 golang.org/x/text v0.5.0
golang.org/x/tools v0.1.12 golang.org/x/tools v0.1.12
google.golang.org/grpc v1.47.0 google.golang.org/grpc v1.47.0
google.golang.org/protobuf v1.28.1 google.golang.org/protobuf v1.28.1

13
go.sum
View File

@ -1463,8 +1463,8 @@ golang.org/x/net v0.0.0-20220630215102-69896b714898/go.mod h1:XRhObCWvk6IyKnWLug
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -1609,15 +1609,14 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ=
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
golang.org/x/sys v0.5.0/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-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-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY= golang.org/x/term v0.3.0 h1:qoo4akIqOcDME5bhc/NgxUdovd6BSS2uMsVjB56q1xI=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@ -1628,8 +1627,8 @@ 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.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 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-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=

View File

@ -168,23 +168,10 @@ var allAccessTokenScopeBits = map[AccessTokenScope]AccessTokenScopeBitmap{
// Parse parses the scope string into a bitmap, thus removing possible duplicates. // Parse parses the scope string into a bitmap, thus removing possible duplicates.
func (s AccessTokenScope) Parse() (AccessTokenScopeBitmap, error) { func (s AccessTokenScope) Parse() (AccessTokenScopeBitmap, error) {
var bitmap AccessTokenScopeBitmap list := strings.Split(string(s), ",")
// The following is the more performant equivalent of 'for _, v := range strings.Split(remainingScope, ",")' as this is hot code var bitmap AccessTokenScopeBitmap
remainingScopes := string(s) for _, v := range list {
for len(remainingScopes) > 0 {
i := strings.IndexByte(remainingScopes, ',')
var v string
if i < 0 {
v = remainingScopes
remainingScopes = ""
} else if i+1 >= len(remainingScopes) {
v = remainingScopes[:i]
remainingScopes = ""
} else {
v = remainingScopes[:i]
remainingScopes = remainingScopes[i+1:]
}
singleScope := AccessTokenScope(v) singleScope := AccessTokenScope(v)
if singleScope == "" { if singleScope == "" {
continue continue
@ -200,15 +187,9 @@ func (s AccessTokenScope) Parse() (AccessTokenScopeBitmap, error) {
} }
bitmap |= bits bitmap |= bits
} }
return bitmap, nil return bitmap, nil
} }
// StringSlice returns the AccessTokenScope as a []string
func (s AccessTokenScope) StringSlice() []string {
return strings.Split(string(s), ",")
}
// Normalize returns a normalized scope string without any duplicates. // Normalize returns a normalized scope string without any duplicates.
func (s AccessTokenScope) Normalize() (AccessTokenScope, error) { func (s AccessTokenScope) Normalize() (AccessTokenScope, error) {
bitmap, err := s.Parse() bitmap, err := s.Parse()

View File

@ -8,8 +8,8 @@
email: user1@example.com email: user1@example.com
keep_email_private: false keep_email_private: false
email_notifications_preference: enabled email_notifications_preference: enabled
passwd: ZogKvWdyEx:password passwd: e82bc8ae42a53b98c3bd0f941aacc4aa2a264407534b0a11bf270137f67af912f694b67951f92148c45f91717e1478ca7889
passwd_hash_algo: dummy passwd_hash_algo: pbkdf2$50000$50
must_change_password: false must_change_password: false
login_source: 0 login_source: 0
login_name: user1 login_name: user1
@ -45,8 +45,8 @@
email: user2@example.com email: user2@example.com
keep_email_private: true keep_email_private: true
email_notifications_preference: enabled email_notifications_preference: enabled
passwd: ZogKvWdyEx:password passwd: e82bc8ae42a53b98c3bd0f941aacc4aa2a264407534b0a11bf270137f67af912f694b67951f92148c45f91717e1478ca7889
passwd_hash_algo: dummy passwd_hash_algo: pbkdf2$50000$50
must_change_password: false must_change_password: false
login_source: 0 login_source: 0
login_name: user2 login_name: user2
@ -82,8 +82,8 @@
email: user3@example.com email: user3@example.com
keep_email_private: false keep_email_private: false
email_notifications_preference: onmention email_notifications_preference: onmention
passwd: ZogKvWdyEx:password passwd: e82bc8ae42a53b98c3bd0f941aacc4aa2a264407534b0a11bf270137f67af912f694b67951f92148c45f91717e1478ca7889
passwd_hash_algo: dummy passwd_hash_algo: pbkdf2$50000$50
must_change_password: false must_change_password: false
login_source: 0 login_source: 0
login_name: user3 login_name: user3
@ -119,8 +119,8 @@
email: user4@example.com email: user4@example.com
keep_email_private: false keep_email_private: false
email_notifications_preference: onmention email_notifications_preference: onmention
passwd: ZogKvWdyEx:password passwd: e82bc8ae42a53b98c3bd0f941aacc4aa2a264407534b0a11bf270137f67af912f694b67951f92148c45f91717e1478ca7889
passwd_hash_algo: dummy passwd_hash_algo: pbkdf2$50000$50
must_change_password: false must_change_password: false
login_source: 0 login_source: 0
login_name: user4 login_name: user4
@ -156,8 +156,8 @@
email: user5@example.com email: user5@example.com
keep_email_private: false keep_email_private: false
email_notifications_preference: enabled email_notifications_preference: enabled
passwd: ZogKvWdyEx:password passwd: e82bc8ae42a53b98c3bd0f941aacc4aa2a264407534b0a11bf270137f67af912f694b67951f92148c45f91717e1478ca7889
passwd_hash_algo: dummy passwd_hash_algo: pbkdf2$50000$50
must_change_password: false must_change_password: false
login_source: 0 login_source: 0
login_name: user5 login_name: user5
@ -193,8 +193,8 @@
email: user6@example.com email: user6@example.com
keep_email_private: false keep_email_private: false
email_notifications_preference: enabled email_notifications_preference: enabled
passwd: ZogKvWdyEx:password passwd: e82bc8ae42a53b98c3bd0f941aacc4aa2a264407534b0a11bf270137f67af912f694b67951f92148c45f91717e1478ca7889
passwd_hash_algo: dummy passwd_hash_algo: pbkdf2$50000$50
must_change_password: false must_change_password: false
login_source: 0 login_source: 0
login_name: user6 login_name: user6
@ -230,8 +230,8 @@
email: user7@example.com email: user7@example.com
keep_email_private: false keep_email_private: false
email_notifications_preference: disabled email_notifications_preference: disabled
passwd: ZogKvWdyEx:password passwd: e82bc8ae42a53b98c3bd0f941aacc4aa2a264407534b0a11bf270137f67af912f694b67951f92148c45f91717e1478ca7889
passwd_hash_algo: dummy passwd_hash_algo: pbkdf2$50000$50
must_change_password: false must_change_password: false
login_source: 0 login_source: 0
login_name: user7 login_name: user7
@ -267,8 +267,8 @@
email: user8@example.com email: user8@example.com
keep_email_private: false keep_email_private: false
email_notifications_preference: enabled email_notifications_preference: enabled
passwd: ZogKvWdyEx:password passwd: e82bc8ae42a53b98c3bd0f941aacc4aa2a264407534b0a11bf270137f67af912f694b67951f92148c45f91717e1478ca7889
passwd_hash_algo: dummy passwd_hash_algo: pbkdf2$50000$50
must_change_password: false must_change_password: false
login_source: 0 login_source: 0
login_name: user8 login_name: user8
@ -304,8 +304,8 @@
email: user9@example.com email: user9@example.com
keep_email_private: false keep_email_private: false
email_notifications_preference: onmention email_notifications_preference: onmention
passwd: ZogKvWdyEx:password passwd: e82bc8ae42a53b98c3bd0f941aacc4aa2a264407534b0a11bf270137f67af912f694b67951f92148c45f91717e1478ca7889
passwd_hash_algo: dummy passwd_hash_algo: pbkdf2$50000$50
must_change_password: false must_change_password: false
login_source: 0 login_source: 0
login_name: user9 login_name: user9
@ -341,8 +341,8 @@
email: user10@example.com email: user10@example.com
keep_email_private: false keep_email_private: false
email_notifications_preference: enabled email_notifications_preference: enabled
passwd: ZogKvWdyEx:password passwd: e82bc8ae42a53b98c3bd0f941aacc4aa2a264407534b0a11bf270137f67af912f694b67951f92148c45f91717e1478ca7889
passwd_hash_algo: dummy passwd_hash_algo: pbkdf2$50000$50
must_change_password: false must_change_password: false
login_source: 0 login_source: 0
login_name: user10 login_name: user10
@ -378,8 +378,8 @@
email: user11@example.com email: user11@example.com
keep_email_private: false keep_email_private: false
email_notifications_preference: enabled email_notifications_preference: enabled
passwd: ZogKvWdyEx:password passwd: e82bc8ae42a53b98c3bd0f941aacc4aa2a264407534b0a11bf270137f67af912f694b67951f92148c45f91717e1478ca7889
passwd_hash_algo: dummy passwd_hash_algo: pbkdf2$50000$50
must_change_password: false must_change_password: false
login_source: 0 login_source: 0
login_name: user11 login_name: user11
@ -415,8 +415,8 @@
email: user12@example.com email: user12@example.com
keep_email_private: false keep_email_private: false
email_notifications_preference: enabled email_notifications_preference: enabled
passwd: ZogKvWdyEx:password passwd: e82bc8ae42a53b98c3bd0f941aacc4aa2a264407534b0a11bf270137f67af912f694b67951f92148c45f91717e1478ca7889
passwd_hash_algo: dummy passwd_hash_algo: pbkdf2$50000$50
must_change_password: false must_change_password: false
login_source: 0 login_source: 0
login_name: user12 login_name: user12
@ -452,8 +452,8 @@
email: user13@example.com email: user13@example.com
keep_email_private: false keep_email_private: false
email_notifications_preference: enabled email_notifications_preference: enabled
passwd: ZogKvWdyEx:password passwd: e82bc8ae42a53b98c3bd0f941aacc4aa2a264407534b0a11bf270137f67af912f694b67951f92148c45f91717e1478ca7889
passwd_hash_algo: dummy passwd_hash_algo: pbkdf2$50000$50
must_change_password: false must_change_password: false
login_source: 0 login_source: 0
login_name: user13 login_name: user13
@ -489,8 +489,8 @@
email: user14@example.com email: user14@example.com
keep_email_private: false keep_email_private: false
email_notifications_preference: enabled email_notifications_preference: enabled
passwd: ZogKvWdyEx:password passwd: e82bc8ae42a53b98c3bd0f941aacc4aa2a264407534b0a11bf270137f67af912f694b67951f92148c45f91717e1478ca7889
passwd_hash_algo: dummy passwd_hash_algo: pbkdf2$50000$50
must_change_password: false must_change_password: false
login_source: 0 login_source: 0
login_name: user14 login_name: user14
@ -526,8 +526,8 @@
email: user15@example.com email: user15@example.com
keep_email_private: false keep_email_private: false
email_notifications_preference: enabled email_notifications_preference: enabled
passwd: ZogKvWdyEx:password passwd: e82bc8ae42a53b98c3bd0f941aacc4aa2a264407534b0a11bf270137f67af912f694b67951f92148c45f91717e1478ca7889
passwd_hash_algo: dummy passwd_hash_algo: pbkdf2$50000$50
must_change_password: false must_change_password: false
login_source: 0 login_source: 0
login_name: user15 login_name: user15
@ -563,8 +563,8 @@
email: user16@example.com email: user16@example.com
keep_email_private: false keep_email_private: false
email_notifications_preference: enabled email_notifications_preference: enabled
passwd: ZogKvWdyEx:password passwd: e82bc8ae42a53b98c3bd0f941aacc4aa2a264407534b0a11bf270137f67af912f694b67951f92148c45f91717e1478ca7889
passwd_hash_algo: dummy passwd_hash_algo: pbkdf2$50000$50
must_change_password: false must_change_password: false
login_source: 0 login_source: 0
login_name: user16 login_name: user16
@ -600,8 +600,8 @@
email: user17@example.com email: user17@example.com
keep_email_private: false keep_email_private: false
email_notifications_preference: enabled email_notifications_preference: enabled
passwd: ZogKvWdyEx:password passwd: e82bc8ae42a53b98c3bd0f941aacc4aa2a264407534b0a11bf270137f67af912f694b67951f92148c45f91717e1478ca7889
passwd_hash_algo: dummy passwd_hash_algo: pbkdf2$50000$50
must_change_password: false must_change_password: false
login_source: 0 login_source: 0
login_name: user17 login_name: user17
@ -637,8 +637,8 @@
email: user18@example.com email: user18@example.com
keep_email_private: false keep_email_private: false
email_notifications_preference: enabled email_notifications_preference: enabled
passwd: ZogKvWdyEx:password passwd: e82bc8ae42a53b98c3bd0f941aacc4aa2a264407534b0a11bf270137f67af912f694b67951f92148c45f91717e1478ca7889
passwd_hash_algo: dummy passwd_hash_algo: pbkdf2$50000$50
must_change_password: false must_change_password: false
login_source: 0 login_source: 0
login_name: user18 login_name: user18
@ -674,8 +674,8 @@
email: user19@example.com email: user19@example.com
keep_email_private: false keep_email_private: false
email_notifications_preference: enabled email_notifications_preference: enabled
passwd: ZogKvWdyEx:password passwd: e82bc8ae42a53b98c3bd0f941aacc4aa2a264407534b0a11bf270137f67af912f694b67951f92148c45f91717e1478ca7889
passwd_hash_algo: dummy passwd_hash_algo: pbkdf2$50000$50
must_change_password: false must_change_password: false
login_source: 0 login_source: 0
login_name: user19 login_name: user19
@ -711,8 +711,8 @@
email: user20@example.com email: user20@example.com
keep_email_private: false keep_email_private: false
email_notifications_preference: enabled email_notifications_preference: enabled
passwd: ZogKvWdyEx:password passwd: e82bc8ae42a53b98c3bd0f941aacc4aa2a264407534b0a11bf270137f67af912f694b67951f92148c45f91717e1478ca7889
passwd_hash_algo: dummy passwd_hash_algo: pbkdf2$50000$50
must_change_password: false must_change_password: false
login_source: 0 login_source: 0
login_name: user20 login_name: user20
@ -748,8 +748,8 @@
email: user21@example.com email: user21@example.com
keep_email_private: false keep_email_private: false
email_notifications_preference: enabled email_notifications_preference: enabled
passwd: ZogKvWdyEx:password passwd: e82bc8ae42a53b98c3bd0f941aacc4aa2a264407534b0a11bf270137f67af912f694b67951f92148c45f91717e1478ca7889
passwd_hash_algo: dummy passwd_hash_algo: pbkdf2$50000$50
must_change_password: false must_change_password: false
login_source: 0 login_source: 0
login_name: user21 login_name: user21
@ -785,8 +785,8 @@
email: limited_org@example.com email: limited_org@example.com
keep_email_private: false keep_email_private: false
email_notifications_preference: enabled email_notifications_preference: enabled
passwd: ZogKvWdyEx:password passwd: e82bc8ae42a53b98c3bd0f941aacc4aa2a264407534b0a11bf270137f67af912f694b67951f92148c45f91717e1478ca7889
passwd_hash_algo: dummy passwd_hash_algo: pbkdf2$50000$50
must_change_password: false must_change_password: false
login_source: 0 login_source: 0
login_name: limited_org login_name: limited_org
@ -822,8 +822,8 @@
email: privated_org@example.com email: privated_org@example.com
keep_email_private: false keep_email_private: false
email_notifications_preference: enabled email_notifications_preference: enabled
passwd: ZogKvWdyEx:password passwd: e82bc8ae42a53b98c3bd0f941aacc4aa2a264407534b0a11bf270137f67af912f694b67951f92148c45f91717e1478ca7889
passwd_hash_algo: dummy passwd_hash_algo: pbkdf2$50000$50
must_change_password: false must_change_password: false
login_source: 0 login_source: 0
login_name: privated_org login_name: privated_org
@ -859,8 +859,8 @@
email: user24@example.com email: user24@example.com
keep_email_private: true keep_email_private: true
email_notifications_preference: enabled email_notifications_preference: enabled
passwd: ZogKvWdyEx:password passwd: e82bc8ae42a53b98c3bd0f941aacc4aa2a264407534b0a11bf270137f67af912f694b67951f92148c45f91717e1478ca7889
passwd_hash_algo: dummy passwd_hash_algo: pbkdf2$50000$50
must_change_password: false must_change_password: false
login_source: 0 login_source: 0
login_name: user24 login_name: user24
@ -896,8 +896,8 @@
email: org25@example.com email: org25@example.com
keep_email_private: false keep_email_private: false
email_notifications_preference: enabled email_notifications_preference: enabled
passwd: ZogKvWdyEx:password passwd: e82bc8ae42a53b98c3bd0f941aacc4aa2a264407534b0a11bf270137f67af912f694b67951f92148c45f91717e1478ca7889
passwd_hash_algo: dummy passwd_hash_algo: pbkdf2$50000$50
must_change_password: false must_change_password: false
login_source: 0 login_source: 0
login_name: org25 login_name: org25
@ -933,8 +933,8 @@
email: org26@example.com email: org26@example.com
keep_email_private: false keep_email_private: false
email_notifications_preference: onmention email_notifications_preference: onmention
passwd: ZogKvWdyEx:password passwd: e82bc8ae42a53b98c3bd0f941aacc4aa2a264407534b0a11bf270137f67af912f694b67951f92148c45f91717e1478ca7889
passwd_hash_algo: dummy passwd_hash_algo: pbkdf2$50000$50
must_change_password: false must_change_password: false
login_source: 0 login_source: 0
login_name: org26 login_name: org26
@ -970,8 +970,8 @@
email: user27@example.com email: user27@example.com
keep_email_private: false keep_email_private: false
email_notifications_preference: enabled email_notifications_preference: enabled
passwd: ZogKvWdyEx:password passwd: e82bc8ae42a53b98c3bd0f941aacc4aa2a264407534b0a11bf270137f67af912f694b67951f92148c45f91717e1478ca7889
passwd_hash_algo: dummy passwd_hash_algo: pbkdf2$50000$50
must_change_password: false must_change_password: false
login_source: 0 login_source: 0
login_name: user27 login_name: user27
@ -1007,8 +1007,8 @@
email: user28@example.com email: user28@example.com
keep_email_private: true keep_email_private: true
email_notifications_preference: enabled email_notifications_preference: enabled
passwd: ZogKvWdyEx:password passwd: e82bc8ae42a53b98c3bd0f941aacc4aa2a264407534b0a11bf270137f67af912f694b67951f92148c45f91717e1478ca7889
passwd_hash_algo: dummy passwd_hash_algo: pbkdf2$50000$50
must_change_password: false must_change_password: false
login_source: 0 login_source: 0
login_name: user28 login_name: user28
@ -1044,8 +1044,8 @@
email: user29@example.com email: user29@example.com
keep_email_private: false keep_email_private: false
email_notifications_preference: enabled email_notifications_preference: enabled
passwd: ZogKvWdyEx:password passwd: e82bc8ae42a53b98c3bd0f941aacc4aa2a264407534b0a11bf270137f67af912f694b67951f92148c45f91717e1478ca7889
passwd_hash_algo: dummy passwd_hash_algo: pbkdf2$50000$50
must_change_password: false must_change_password: false
login_source: 0 login_source: 0
login_name: user29 login_name: user29
@ -1081,8 +1081,8 @@
email: user30@example.com email: user30@example.com
keep_email_private: false keep_email_private: false
email_notifications_preference: enabled email_notifications_preference: enabled
passwd: ZogKvWdyEx:password passwd: e82bc8ae42a53b98c3bd0f941aacc4aa2a264407534b0a11bf270137f67af912f694b67951f92148c45f91717e1478ca7889
passwd_hash_algo: dummy passwd_hash_algo: pbkdf2$50000$50
must_change_password: false must_change_password: false
login_source: 0 login_source: 0
login_name: user30 login_name: user30
@ -1118,8 +1118,8 @@
email: user31@example.com email: user31@example.com
keep_email_private: false keep_email_private: false
email_notifications_preference: enabled email_notifications_preference: enabled
passwd: ZogKvWdyEx:password passwd: e82bc8ae42a53b98c3bd0f941aacc4aa2a264407534b0a11bf270137f67af912f694b67951f92148c45f91717e1478ca7889
passwd_hash_algo: dummy passwd_hash_algo: pbkdf2$50000$50
must_change_password: false must_change_password: false
login_source: 0 login_source: 0
login_name: user31 login_name: user31
@ -1155,8 +1155,8 @@
email: user32@example.com email: user32@example.com
keep_email_private: false keep_email_private: false
email_notifications_preference: enabled email_notifications_preference: enabled
passwd: ZogKvWdyEx:notpassword passwd: 7d93daa0d1e6f2305cc8fa496847d61dc7320bb16262f9c55dd753480207234cdd96a93194e408341971742f47017
passwd_hash_algo: dummy passwd_hash_algo: argon2
must_change_password: false must_change_password: false
login_source: 0 login_source: 0
login_name: user32 login_name: user32
@ -1192,8 +1192,8 @@
email: user33@example.com email: user33@example.com
keep_email_private: false keep_email_private: false
email_notifications_preference: enabled email_notifications_preference: enabled
passwd: ZogKvWdyEx:password passwd: e82bc8ae42a53b98c3bd0f941aacc4aa2a264407534b0a11bf270137f67af912f694b67951f92148c45f91717e1478ca7889
passwd_hash_algo: dummy passwd_hash_algo: pbkdf2$50000$50
must_change_password: false must_change_password: false
login_source: 0 login_source: 0
login_name: user33 login_name: user33

View File

@ -251,8 +251,7 @@ func (issue *Issue) LoadPoster(ctx context.Context) (err error) {
// LoadPullRequest loads pull request info // LoadPullRequest loads pull request info
func (issue *Issue) LoadPullRequest(ctx context.Context) (err error) { func (issue *Issue) LoadPullRequest(ctx context.Context) (err error) {
if issue.IsPull { if issue.IsPull && issue.PullRequest == nil {
if issue.PullRequest == nil {
issue.PullRequest, err = GetPullRequestByIssueID(ctx, issue.ID) issue.PullRequest, err = GetPullRequestByIssueID(ctx, issue.ID)
if err != nil { if err != nil {
if IsErrPullRequestNotExist(err) { if IsErrPullRequestNotExist(err) {
@ -260,7 +259,6 @@ func (issue *Issue) LoadPullRequest(ctx context.Context) (err error) {
} }
return fmt.Errorf("getPullRequestByIssueID [%d]: %w", issue.ID, err) return fmt.Errorf("getPullRequestByIssueID [%d]: %w", issue.ID, err)
} }
}
issue.PullRequest.Issue = issue issue.PullRequest.Issue = issue
} }
return nil return nil
@ -349,7 +347,7 @@ func (issue *Issue) LoadAttributes(ctx context.Context) (err error) {
return return
} }
if err = issue.LoadProject(ctx); err != nil { if err = issue.loadProject(ctx); err != nil {
return return
} }

View File

@ -13,7 +13,11 @@ import (
) )
// LoadProject load the project the issue was assigned to // LoadProject load the project the issue was assigned to
func (issue *Issue) LoadProject(ctx context.Context) (err error) { func (issue *Issue) LoadProject() (err error) {
return issue.loadProject(db.DefaultContext)
}
func (issue *Issue) loadProject(ctx context.Context) (err error) {
if issue.Project == nil { if issue.Project == nil {
var p project_model.Project var p project_model.Project
if _, err = db.GetEngine(ctx).Table("project"). if _, err = db.GetEngine(ctx).Table("project").

View File

@ -9,8 +9,6 @@ import (
"time" "time"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/modules/auth/password/hash"
"code.gitea.io/gitea/modules/setting"
"github.com/go-testfixtures/testfixtures/v3" "github.com/go-testfixtures/testfixtures/v3"
"xorm.io/xorm" "xorm.io/xorm"
@ -66,11 +64,6 @@ func InitFixtures(opts FixturesOptions, engine ...*xorm.Engine) (err error) {
return err return err
} }
// register the dummy hash algorithm function used in the test fixtures
_ = hash.Register("dummy", hash.NewDummyHasher)
setting.PasswordHashAlgo, _ = hash.SetDefaultPasswordHashAlgorithm("dummy")
return err return err
} }
@ -122,8 +115,5 @@ func LoadFixtures(engine ...*xorm.Engine) error {
} }
} }
} }
_ = hash.Register("dummy", hash.NewDummyHasher)
setting.PasswordHashAlgo, _ = hash.SetDefaultPasswordHashAlgorithm("dummy")
return err return err
} }

View File

@ -13,7 +13,7 @@ import (
) )
func init() { func init() {
MustRegister("argon2", NewArgon2Hasher) Register("argon2", NewArgon2Hasher)
} }
// Argon2Hasher implements PasswordHasher // Argon2Hasher implements PasswordHasher

View File

@ -8,7 +8,7 @@ import (
) )
func init() { func init() {
MustRegister("bcrypt", NewBcryptHasher) Register("bcrypt", NewBcryptHasher)
} }
// BcryptHasher implements PasswordHasher // BcryptHasher implements PasswordHasher

View File

@ -1,33 +0,0 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package hash
import (
"encoding/hex"
)
// DummyHasher implements PasswordHasher and is a dummy hasher that simply
// puts the password in place with its salt
// This SHOULD NOT be used in production and is provided to make the integration
// tests faster only
type DummyHasher struct{}
// HashWithSaltBytes a provided password and salt
func (hasher *DummyHasher) HashWithSaltBytes(password string, salt []byte) string {
if hasher == nil {
return ""
}
if len(salt) == 10 {
return string(salt) + ":" + password
}
return hex.EncodeToString(salt) + ":" + password
}
// NewDummyHasher is a factory method to create a DummyHasher
// Any provided configuration is ignored
func NewDummyHasher(_ string) *DummyHasher {
return &DummyHasher{}
}

View File

@ -1,25 +0,0 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package hash
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestDummyHasher(t *testing.T) {
dummy := &PasswordHashAlgorithm{
PasswordSaltHasher: NewDummyHasher(""),
Specification: "dummy",
}
password, salt := "password", "ZogKvWdyEx"
hash, err := dummy.Hash(password, salt)
assert.Nil(t, err)
assert.Equal(t, hash, salt+":"+password)
assert.True(t, dummy.VerifyPassword(password, hash, salt))
}

View File

@ -83,26 +83,17 @@ var (
availableHasherFactories = map[string]func(string) PasswordSaltHasher{} availableHasherFactories = map[string]func(string) PasswordSaltHasher{}
) )
// MustRegister registers a PasswordSaltHasher with the availableHasherFactories
// Caution: This is not thread safe.
func MustRegister[T PasswordSaltHasher](name string, newFn func(config string) T) {
if err := Register(name, newFn); err != nil {
panic(err)
}
}
// Register registers a PasswordSaltHasher with the availableHasherFactories // Register registers a PasswordSaltHasher with the availableHasherFactories
// Caution: This is not thread safe. // Caution: This is not thread safe.
func Register[T PasswordSaltHasher](name string, newFn func(config string) T) error { func Register[T PasswordSaltHasher](name string, newFn func(config string) T) {
if _, has := availableHasherFactories[name]; has { if _, has := availableHasherFactories[name]; has {
return fmt.Errorf("duplicate registration of password salt hasher: %s", name) panic(fmt.Errorf("duplicate registration of password salt hasher: %s", name))
} }
availableHasherFactories[name] = func(config string) PasswordSaltHasher { availableHasherFactories[name] = func(config string) PasswordSaltHasher {
n := newFn(config) n := newFn(config)
return n return n
} }
return nil
} }
// In early versions of gitea the password hash algorithm field of a user could be // In early versions of gitea the password hash algorithm field of a user could be

View File

@ -19,20 +19,16 @@ func (t testSaltHasher) HashWithSaltBytes(password string, salt []byte) string {
} }
func Test_registerHasher(t *testing.T) { func Test_registerHasher(t *testing.T) {
MustRegister("Test_registerHasher", func(config string) testSaltHasher { Register("Test_registerHasher", func(config string) testSaltHasher {
return testSaltHasher(config) return testSaltHasher(config)
}) })
assert.Panics(t, func() { assert.Panics(t, func() {
MustRegister("Test_registerHasher", func(config string) testSaltHasher { Register("Test_registerHasher", func(config string) testSaltHasher {
return testSaltHasher(config) return testSaltHasher(config)
}) })
}) })
assert.Error(t, Register("Test_registerHasher", func(config string) testSaltHasher {
return testSaltHasher(config)
}))
assert.Equal(t, "password$salt$", assert.Equal(t, "password$salt$",
Parse("Test_registerHasher").PasswordSaltHasher.HashWithSaltBytes("password", []byte("salt"))) Parse("Test_registerHasher").PasswordSaltHasher.HashWithSaltBytes("password", []byte("salt")))

View File

@ -14,7 +14,7 @@ import (
) )
func init() { func init() {
MustRegister("pbkdf2", NewPBKDF2Hasher) Register("pbkdf2", NewPBKDF2Hasher)
} }
// PBKDF2Hasher implements PasswordHasher // PBKDF2Hasher implements PasswordHasher

View File

@ -13,7 +13,7 @@ import (
) )
func init() { func init() {
MustRegister("scrypt", NewScryptHasher) Register("scrypt", NewScryptHasher)
} }
// ScryptHasher implements PasswordHasher // ScryptHasher implements PasswordHasher

View File

@ -6,8 +6,8 @@ package context
import ( import (
"bytes" "bytes"
"context" "context"
"html/template"
"net/http" "net/http"
"text/template"
"time" "time"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"

View File

@ -25,9 +25,9 @@ func mustMapSetting(rootCfg ConfigProvider, sectionName string, setting interfac
} }
} }
func deprecatedSetting(rootCfg ConfigProvider, oldSection, oldKey, newSection, newKey, version string) { func deprecatedSetting(rootCfg ConfigProvider, oldSection, oldKey, newSection, newKey string) {
if rootCfg.Section(oldSection).HasKey(oldKey) { if rootCfg.Section(oldSection).HasKey(oldKey) {
log.Error("Deprecated fallback `[%s]` `%s` present. Use `[%s]` `%s` instead. This fallback will be/has been removed in %s", oldSection, oldKey, newSection, newKey, version) log.Error("Deprecated fallback `[%s]` `%s` present. Use `[%s]` `%s` instead. This fallback will be removed in v1.19.0", oldSection, oldKey, newSection, newKey)
} }
} }

View File

@ -56,13 +56,12 @@ func loadIndexerFrom(rootCfg ConfigProvider) {
Indexer.IssueIndexerName = sec.Key("ISSUE_INDEXER_NAME").MustString(Indexer.IssueIndexerName) Indexer.IssueIndexerName = sec.Key("ISSUE_INDEXER_NAME").MustString(Indexer.IssueIndexerName)
// The following settings are deprecated and can be overridden by settings in [queue] or [queue.issue_indexer] // The following settings are deprecated and can be overridden by settings in [queue] or [queue.issue_indexer]
// DEPRECATED should not be removed because users maybe upgrade from lower version to the latest version // FIXME: DEPRECATED to be removed in v1.18.0
// if these are removed, the warning will not be shown deprecatedSetting(rootCfg, "indexer", "ISSUE_INDEXER_QUEUE_TYPE", "queue.issue_indexer", "TYPE")
deprecatedSetting(rootCfg, "indexer", "ISSUE_INDEXER_QUEUE_TYPE", "queue.issue_indexer", "TYPE", "v1.19.0") deprecatedSetting(rootCfg, "indexer", "ISSUE_INDEXER_QUEUE_DIR", "queue.issue_indexer", "DATADIR")
deprecatedSetting(rootCfg, "indexer", "ISSUE_INDEXER_QUEUE_DIR", "queue.issue_indexer", "DATADIR", "v1.19.0") deprecatedSetting(rootCfg, "indexer", "ISSUE_INDEXER_QUEUE_CONN_STR", "queue.issue_indexer", "CONN_STR")
deprecatedSetting(rootCfg, "indexer", "ISSUE_INDEXER_QUEUE_CONN_STR", "queue.issue_indexer", "CONN_STR", "v1.19.0") deprecatedSetting(rootCfg, "indexer", "ISSUE_INDEXER_QUEUE_BATCH_NUMBER", "queue.issue_indexer", "BATCH_LENGTH")
deprecatedSetting(rootCfg, "indexer", "ISSUE_INDEXER_QUEUE_BATCH_NUMBER", "queue.issue_indexer", "BATCH_LENGTH", "v1.19.0") deprecatedSetting(rootCfg, "indexer", "UPDATE_BUFFER_LEN", "queue.issue_indexer", "LENGTH")
deprecatedSetting(rootCfg, "indexer", "UPDATE_BUFFER_LEN", "queue.issue_indexer", "LENGTH", "v1.19.0")
Indexer.RepoIndexerEnabled = sec.Key("REPO_INDEXER_ENABLED").MustBool(false) Indexer.RepoIndexerEnabled = sec.Key("REPO_INDEXER_ENABLED").MustBool(false)
Indexer.RepoType = sec.Key("REPO_INDEXER_TYPE").MustString("bleve") Indexer.RepoType = sec.Key("REPO_INDEXER_TYPE").MustString("bleve")

View File

@ -35,9 +35,8 @@ func loadLFSFrom(rootCfg ConfigProvider) {
storageType := lfsSec.Key("STORAGE_TYPE").MustString("") storageType := lfsSec.Key("STORAGE_TYPE").MustString("")
// Specifically default PATH to LFS_CONTENT_PATH // Specifically default PATH to LFS_CONTENT_PATH
// DEPRECATED should not be removed because users maybe upgrade from lower version to the latest version // FIXME: DEPRECATED to be removed in v1.18.0
// if these are removed, the warning will not be shown deprecatedSetting(rootCfg, "server", "LFS_CONTENT_PATH", "lfs", "PATH")
deprecatedSetting(rootCfg, "server", "LFS_CONTENT_PATH", "lfs", "PATH", "v1.19.0")
lfsSec.Key("PATH").MustString( lfsSec.Key("PATH").MustString(
sec.Key("LFS_CONTENT_PATH").String()) sec.Key("LFS_CONTENT_PATH").String())

View File

@ -64,16 +64,16 @@ func loadMailerFrom(rootCfg ConfigProvider) {
} }
// Handle Deprecations and map on to new configuration // Handle Deprecations and map on to new configuration
// DEPRECATED should not be removed because users maybe upgrade from lower version to the latest version // FIXME: DEPRECATED to be removed in v1.19.0
// if these are removed, the warning will not be shown deprecatedSetting(rootCfg, "mailer", "MAILER_TYPE", "mailer", "PROTOCOL")
deprecatedSetting(rootCfg, "mailer", "MAILER_TYPE", "mailer", "PROTOCOL", "v1.19.0")
if sec.HasKey("MAILER_TYPE") && !sec.HasKey("PROTOCOL") { if sec.HasKey("MAILER_TYPE") && !sec.HasKey("PROTOCOL") {
if sec.Key("MAILER_TYPE").String() == "sendmail" { if sec.Key("MAILER_TYPE").String() == "sendmail" {
sec.Key("PROTOCOL").MustString("sendmail") sec.Key("PROTOCOL").MustString("sendmail")
} }
} }
deprecatedSetting(rootCfg, "mailer", "HOST", "mailer", "SMTP_ADDR", "v1.19.0") // FIXME: DEPRECATED to be removed in v1.19.0
deprecatedSetting(rootCfg, "mailer", "HOST", "mailer", "SMTP_ADDR")
if sec.HasKey("HOST") && !sec.HasKey("SMTP_ADDR") { if sec.HasKey("HOST") && !sec.HasKey("SMTP_ADDR") {
givenHost := sec.Key("HOST").String() givenHost := sec.Key("HOST").String()
addr, port, err := net.SplitHostPort(givenHost) addr, port, err := net.SplitHostPort(givenHost)
@ -89,7 +89,8 @@ func loadMailerFrom(rootCfg ConfigProvider) {
sec.Key("SMTP_PORT").MustString(port) sec.Key("SMTP_PORT").MustString(port)
} }
deprecatedSetting(rootCfg, "mailer", "IS_TLS_ENABLED", "mailer", "PROTOCOL", "v1.19.0") // FIXME: DEPRECATED to be removed in v1.19.0
deprecatedSetting(rootCfg, "mailer", "IS_TLS_ENABLED", "mailer", "PROTOCOL")
if sec.HasKey("IS_TLS_ENABLED") && !sec.HasKey("PROTOCOL") { if sec.HasKey("IS_TLS_ENABLED") && !sec.HasKey("PROTOCOL") {
if sec.Key("IS_TLS_ENABLED").MustBool() { if sec.Key("IS_TLS_ENABLED").MustBool() {
sec.Key("PROTOCOL").MustString("smtps") sec.Key("PROTOCOL").MustString("smtps")
@ -98,32 +99,38 @@ func loadMailerFrom(rootCfg ConfigProvider) {
} }
} }
deprecatedSetting(rootCfg, "mailer", "DISABLE_HELO", "mailer", "ENABLE_HELO", "v1.19.0") // FIXME: DEPRECATED to be removed in v1.19.0
deprecatedSetting(rootCfg, "mailer", "DISABLE_HELO", "mailer", "ENABLE_HELO")
if sec.HasKey("DISABLE_HELO") && !sec.HasKey("ENABLE_HELO") { if sec.HasKey("DISABLE_HELO") && !sec.HasKey("ENABLE_HELO") {
sec.Key("ENABLE_HELO").MustBool(!sec.Key("DISABLE_HELO").MustBool()) sec.Key("ENABLE_HELO").MustBool(!sec.Key("DISABLE_HELO").MustBool())
} }
deprecatedSetting(rootCfg, "mailer", "SKIP_VERIFY", "mailer", "FORCE_TRUST_SERVER_CERT", "v1.19.0") // FIXME: DEPRECATED to be removed in v1.19.0
deprecatedSetting(rootCfg, "mailer", "SKIP_VERIFY", "mailer", "FORCE_TRUST_SERVER_CERT")
if sec.HasKey("SKIP_VERIFY") && !sec.HasKey("FORCE_TRUST_SERVER_CERT") { if sec.HasKey("SKIP_VERIFY") && !sec.HasKey("FORCE_TRUST_SERVER_CERT") {
sec.Key("FORCE_TRUST_SERVER_CERT").MustBool(sec.Key("SKIP_VERIFY").MustBool()) sec.Key("FORCE_TRUST_SERVER_CERT").MustBool(sec.Key("SKIP_VERIFY").MustBool())
} }
deprecatedSetting(rootCfg, "mailer", "USE_CERTIFICATE", "mailer", "USE_CLIENT_CERT", "v1.19.0") // FIXME: DEPRECATED to be removed in v1.19.0
deprecatedSetting(rootCfg, "mailer", "USE_CERTIFICATE", "mailer", "USE_CLIENT_CERT")
if sec.HasKey("USE_CERTIFICATE") && !sec.HasKey("USE_CLIENT_CERT") { if sec.HasKey("USE_CERTIFICATE") && !sec.HasKey("USE_CLIENT_CERT") {
sec.Key("USE_CLIENT_CERT").MustBool(sec.Key("USE_CERTIFICATE").MustBool()) sec.Key("USE_CLIENT_CERT").MustBool(sec.Key("USE_CERTIFICATE").MustBool())
} }
deprecatedSetting(rootCfg, "mailer", "CERT_FILE", "mailer", "CLIENT_CERT_FILE", "v1.19.0") // FIXME: DEPRECATED to be removed in v1.19.0
deprecatedSetting(rootCfg, "mailer", "CERT_FILE", "mailer", "CLIENT_CERT_FILE")
if sec.HasKey("CERT_FILE") && !sec.HasKey("CLIENT_CERT_FILE") { if sec.HasKey("CERT_FILE") && !sec.HasKey("CLIENT_CERT_FILE") {
sec.Key("CERT_FILE").MustString(sec.Key("CERT_FILE").String()) sec.Key("CERT_FILE").MustString(sec.Key("CERT_FILE").String())
} }
deprecatedSetting(rootCfg, "mailer", "KEY_FILE", "mailer", "CLIENT_KEY_FILE", "v1.19.0") // FIXME: DEPRECATED to be removed in v1.19.0
deprecatedSetting(rootCfg, "mailer", "KEY_FILE", "mailer", "CLIENT_KEY_FILE")
if sec.HasKey("KEY_FILE") && !sec.HasKey("CLIENT_KEY_FILE") { if sec.HasKey("KEY_FILE") && !sec.HasKey("CLIENT_KEY_FILE") {
sec.Key("KEY_FILE").MustString(sec.Key("KEY_FILE").String()) sec.Key("KEY_FILE").MustString(sec.Key("KEY_FILE").String())
} }
deprecatedSetting(rootCfg, "mailer", "ENABLE_HTML_ALTERNATIVE", "mailer", "SEND_AS_PLAIN_TEXT", "v1.19.0") // FIXME: DEPRECATED to be removed in v1.19.0
deprecatedSetting(rootCfg, "mailer", "ENABLE_HTML_ALTERNATIVE", "mailer", "SEND_AS_PLAIN_TEXT")
if sec.HasKey("ENABLE_HTML_ALTERNATIVE") && !sec.HasKey("SEND_AS_PLAIN_TEXT") { if sec.HasKey("ENABLE_HTML_ALTERNATIVE") && !sec.HasKey("SEND_AS_PLAIN_TEXT") {
sec.Key("SEND_AS_PLAIN_TEXT").MustBool(!sec.Key("ENABLE_HTML_ALTERNATIVE").MustBool(false)) sec.Key("SEND_AS_PLAIN_TEXT").MustBool(!sec.Key("ENABLE_HTML_ALTERNATIVE").MustBool(false))
} }

View File

@ -27,9 +27,8 @@ var Mirror = struct {
func loadMirrorFrom(rootCfg ConfigProvider) { func loadMirrorFrom(rootCfg ConfigProvider) {
// Handle old configuration through `[repository]` `DISABLE_MIRRORS` // Handle old configuration through `[repository]` `DISABLE_MIRRORS`
// - please note this was badly named and only disabled the creation of new pull mirrors // - please note this was badly named and only disabled the creation of new pull mirrors
// DEPRECATED should not be removed because users maybe upgrade from lower version to the latest version // FIXME: DEPRECATED to be removed in v1.18.0
// if these are removed, the warning will not be shown deprecatedSetting(rootCfg, "repository", "DISABLE_MIRRORS", "mirror", "ENABLED")
deprecatedSetting(rootCfg, "repository", "DISABLE_MIRRORS", "mirror", "ENABLED", "v1.19.0")
if rootCfg.Section("repository").Key("DISABLE_MIRRORS").MustBool(false) { if rootCfg.Section("repository").Key("DISABLE_MIRRORS").MustBool(false) {
Mirror.DisableNewPull = true Mirror.DisableNewPull = true
} }

View File

@ -178,40 +178,38 @@ func loadServerFrom(rootCfg ConfigProvider) {
switch protocolCfg { switch protocolCfg {
case "https": case "https":
Protocol = HTTPS Protocol = HTTPS
// FIXME: DEPRECATED to be removed in v1.18.0
// DEPRECATED should not be removed because users maybe upgrade from lower version to the latest version
// if these are removed, the warning will not be shown
if sec.HasKey("ENABLE_ACME") { if sec.HasKey("ENABLE_ACME") {
EnableAcme = sec.Key("ENABLE_ACME").MustBool(false) EnableAcme = sec.Key("ENABLE_ACME").MustBool(false)
} else { } else {
deprecatedSetting(rootCfg, "server", "ENABLE_LETSENCRYPT", "server", "ENABLE_ACME", "v1.19.0") deprecatedSetting(rootCfg, "server", "ENABLE_LETSENCRYPT", "server", "ENABLE_ACME")
EnableAcme = sec.Key("ENABLE_LETSENCRYPT").MustBool(false) EnableAcme = sec.Key("ENABLE_LETSENCRYPT").MustBool(false)
} }
if EnableAcme { if EnableAcme {
AcmeURL = sec.Key("ACME_URL").MustString("") AcmeURL = sec.Key("ACME_URL").MustString("")
AcmeCARoot = sec.Key("ACME_CA_ROOT").MustString("") AcmeCARoot = sec.Key("ACME_CA_ROOT").MustString("")
// FIXME: DEPRECATED to be removed in v1.18.0
if sec.HasKey("ACME_ACCEPTTOS") { if sec.HasKey("ACME_ACCEPTTOS") {
AcmeTOS = sec.Key("ACME_ACCEPTTOS").MustBool(false) AcmeTOS = sec.Key("ACME_ACCEPTTOS").MustBool(false)
} else { } else {
deprecatedSetting(rootCfg, "server", "LETSENCRYPT_ACCEPTTOS", "server", "ACME_ACCEPTTOS", "v1.19.0") deprecatedSetting(rootCfg, "server", "LETSENCRYPT_ACCEPTTOS", "server", "ACME_ACCEPTTOS")
AcmeTOS = sec.Key("LETSENCRYPT_ACCEPTTOS").MustBool(false) AcmeTOS = sec.Key("LETSENCRYPT_ACCEPTTOS").MustBool(false)
} }
if !AcmeTOS { if !AcmeTOS {
log.Fatal("ACME TOS is not accepted (ACME_ACCEPTTOS).") log.Fatal("ACME TOS is not accepted (ACME_ACCEPTTOS).")
} }
// FIXME: DEPRECATED to be removed in v1.18.0
if sec.HasKey("ACME_DIRECTORY") { if sec.HasKey("ACME_DIRECTORY") {
AcmeLiveDirectory = sec.Key("ACME_DIRECTORY").MustString("https") AcmeLiveDirectory = sec.Key("ACME_DIRECTORY").MustString("https")
} else { } else {
deprecatedSetting(rootCfg, "server", "LETSENCRYPT_DIRECTORY", "server", "ACME_DIRECTORY", "v1.19.0") deprecatedSetting(rootCfg, "server", "LETSENCRYPT_DIRECTORY", "server", "ACME_DIRECTORY")
AcmeLiveDirectory = sec.Key("LETSENCRYPT_DIRECTORY").MustString("https") AcmeLiveDirectory = sec.Key("LETSENCRYPT_DIRECTORY").MustString("https")
} }
// FIXME: DEPRECATED to be removed in v1.18.0
if sec.HasKey("ACME_EMAIL") { if sec.HasKey("ACME_EMAIL") {
AcmeEmail = sec.Key("ACME_EMAIL").MustString("") AcmeEmail = sec.Key("ACME_EMAIL").MustString("")
} else { } else {
deprecatedSetting(rootCfg, "server", "LETSENCRYPT_EMAIL", "server", "ACME_EMAIL", "v1.19.0") deprecatedSetting(rootCfg, "server", "LETSENCRYPT_EMAIL", "server", "ACME_EMAIL")
AcmeEmail = sec.Key("LETSENCRYPT_EMAIL").MustString("") AcmeEmail = sec.Key("LETSENCRYPT_EMAIL").MustString("")
} }
} else { } else {

View File

@ -16,7 +16,6 @@ import (
"strings" "strings"
"time" "time"
"code.gitea.io/gitea/modules/auth/password/hash"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/user" "code.gitea.io/gitea/modules/user"
"code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/modules/util"
@ -233,10 +232,6 @@ func InitProviderAndLoadCommonSettingsForTest(extraConfigs ...string) {
if err := PrepareAppDataPath(); err != nil { if err := PrepareAppDataPath(); err != nil {
log.Fatal("Can not prepare APP_DATA_PATH: %v", err) log.Fatal("Can not prepare APP_DATA_PATH: %v", err)
} }
// register the dummy hash algorithm function used in the test fixtures
_ = hash.Register("dummy", hash.NewDummyHasher)
PasswordHashAlgo, _ = hash.SetDefaultPasswordHashAlgorithm("dummy")
} }
// newFileProviderFromConf initializes configuration context. // newFileProviderFromConf initializes configuration context.

View File

@ -3,16 +3,15 @@
package setting package setting
// DEPRECATED should not be removed because users maybe upgrade from lower version to the latest version // FIXME: DEPRECATED to be removed in v1.18.0
// if these are removed, the warning will not be shown
// - will need to set default for [queue.task] LENGTH to 1000 though // - will need to set default for [queue.task] LENGTH to 1000 though
func loadTaskFrom(rootCfg ConfigProvider) { func loadTaskFrom(rootCfg ConfigProvider) {
taskSec := rootCfg.Section("task") taskSec := rootCfg.Section("task")
queueTaskSec := rootCfg.Section("queue.task") queueTaskSec := rootCfg.Section("queue.task")
deprecatedSetting(rootCfg, "task", "QUEUE_TYPE", "queue.task", "TYPE", "v1.19.0") deprecatedSetting(rootCfg, "task", "QUEUE_TYPE", "queue.task", "TYPE")
deprecatedSetting(rootCfg, "task", "QUEUE_CONN_STR", "queue.task", "CONN_STR", "v1.19.0") deprecatedSetting(rootCfg, "task", "QUEUE_CONN_STR", "queue.task", "CONN_STR")
deprecatedSetting(rootCfg, "task", "QUEUE_LENGTH", "queue.task", "LENGTH", "v1.19.0") deprecatedSetting(rootCfg, "task", "QUEUE_LENGTH", "queue.task", "LENGTH")
switch taskSec.Key("QUEUE_TYPE").MustString("channel") { switch taskSec.Key("QUEUE_TYPE").MustString("channel") {
case "channel": case "channel":

View File

@ -15,7 +15,6 @@ type AccessToken struct {
Name string `json:"name"` Name string `json:"name"`
Token string `json:"sha1"` Token string `json:"sha1"`
TokenLastEight string `json:"token_last_eight"` TokenLastEight string `json:"token_last_eight"`
Scopes []string `json:"scopes"`
} }
// AccessTokenList represents a list of API access token. // AccessTokenList represents a list of API access token.
@ -23,10 +22,9 @@ type AccessToken struct {
type AccessTokenList []*AccessToken type AccessTokenList []*AccessToken
// CreateAccessTokenOption options when create access token // CreateAccessTokenOption options when create access token
// swagger:parameters userCreateToken
type CreateAccessTokenOption struct { type CreateAccessTokenOption struct {
// required: true
Name string `json:"name" binding:"Required"` Name string `json:"name" binding:"Required"`
Scopes []string `json:"scopes"`
} }
// CreateOAuth2ApplicationOptions holds options to create an oauth2 application // CreateOAuth2ApplicationOptions holds options to create an oauth2 application

View File

@ -757,7 +757,6 @@ access_token_deletion_confirm_action = Delete
access_token_deletion_desc = Deleting a token will revoke access to your account for applications using it. This cannot be undone. Continue? access_token_deletion_desc = Deleting a token will revoke access to your account for applications using it. This cannot be undone. Continue?
delete_token_success = The token has been deleted. Applications using it no longer have access to your account. delete_token_success = The token has been deleted. Applications using it no longer have access to your account.
select_scopes = Select scopes select_scopes = Select scopes
scopes_list = Scopes:
manage_oauth2_applications = Manage OAuth2 Applications manage_oauth2_applications = Manage OAuth2 Applications
edit_oauth2_application = Edit OAuth2 Application edit_oauth2_application = Edit OAuth2 Application
@ -2153,7 +2152,6 @@ settings.choose_branch = Choose a branch…
settings.no_protected_branch = There are no protected branches. settings.no_protected_branch = There are no protected branches.
settings.edit_protected_branch = Edit settings.edit_protected_branch = Edit
settings.protected_branch_required_rule_name = Required rule name settings.protected_branch_required_rule_name = Required rule name
settings.protected_branch_duplicate_rule_name = Duplicate rule name
settings.protected_branch_required_approvals_min = Required approvals cannot be negative. settings.protected_branch_required_approvals_min = Required approvals cannot be negative.
settings.tags = Tags settings.tags = Tags
settings.tags.protection = Tag Protection settings.tags.protection = Tag Protection

View File

@ -1420,9 +1420,8 @@ func GetPullRequestFiles(ctx *context.APIContext) {
startCommitID := prInfo.MergeBase startCommitID := prInfo.MergeBase
endCommitID := headCommitID endCommitID := headCommitID
maxLines := setting.Git.MaxGitDiffLines maxLines, maxFiles := setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffFiles
// FIXME: If there are too many files in the repo, may cause some unpredictable issues.
diff, err := gitdiff.GetDiff(baseGitRepo, diff, err := gitdiff.GetDiff(baseGitRepo,
&gitdiff.DiffOptions{ &gitdiff.DiffOptions{
BeforeCommitID: startCommitID, BeforeCommitID: startCommitID,
@ -1430,7 +1429,7 @@ func GetPullRequestFiles(ctx *context.APIContext) {
SkipTo: ctx.FormString("skip-to"), SkipTo: ctx.FormString("skip-to"),
MaxLines: maxLines, MaxLines: maxLines,
MaxLineCharacters: setting.Git.MaxGitDiffLineCharacters, MaxLineCharacters: setting.Git.MaxGitDiffLineCharacters,
MaxFiles: -1, // GetDiff() will return all files MaxFiles: maxFiles,
WhitespaceBehavior: gitdiff.GetWhitespaceFlag(ctx.FormString("whitespace")), WhitespaceBehavior: gitdiff.GetWhitespaceFlag(ctx.FormString("whitespace")),
}) })
if err != nil { if err != nil {
@ -1453,7 +1452,6 @@ func GetPullRequestFiles(ctx *context.APIContext) {
if lenFiles < 0 { if lenFiles < 0 {
lenFiles = 0 lenFiles = 0
} }
apiFiles := make([]*api.ChangedFile, 0, lenFiles) apiFiles := make([]*api.ChangedFile, 0, lenFiles)
for i := start; i < end; i++ { for i := start; i < end; i++ {
apiFiles = append(apiFiles, convert.ToChangedFile(diff.Files[i], pr.HeadRepo, endCommitID)) apiFiles = append(apiFiles, convert.ToChangedFile(diff.Files[i], pr.HeadRepo, endCommitID))

View File

@ -9,7 +9,6 @@ import (
"fmt" "fmt"
"net/http" "net/http"
"strconv" "strconv"
"strings"
auth_model "code.gitea.io/gitea/models/auth" auth_model "code.gitea.io/gitea/models/auth"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
@ -63,7 +62,6 @@ func ListAccessTokens(ctx *context.APIContext) {
ID: tokens[i].ID, ID: tokens[i].ID,
Name: tokens[i].Name, Name: tokens[i].Name,
TokenLastEight: tokens[i].TokenLastEight, TokenLastEight: tokens[i].TokenLastEight,
Scopes: tokens[i].Scope.StringSlice(),
} }
} }
@ -84,9 +82,9 @@ func CreateAccessToken(ctx *context.APIContext) {
// - name: username // - name: username
// in: path // in: path
// description: username of user // description: username of user
// required: true
// type: string // type: string
// - name: body // required: true
// - name: userCreateToken
// in: body // in: body
// schema: // schema:
// "$ref": "#/definitions/CreateAccessTokenOption" // "$ref": "#/definitions/CreateAccessTokenOption"
@ -113,13 +111,6 @@ func CreateAccessToken(ctx *context.APIContext) {
return return
} }
scope, err := auth_model.AccessTokenScope(strings.Join(form.Scopes, ",")).Normalize()
if err != nil {
ctx.Error(http.StatusBadRequest, "AccessTokenScope.Normalize", fmt.Errorf("invalid access token scope provided: %w", err))
return
}
t.Scope = scope
if err := auth_model.NewAccessToken(t); err != nil { if err := auth_model.NewAccessToken(t); err != nil {
ctx.Error(http.StatusInternalServerError, "NewAccessToken", err) ctx.Error(http.StatusInternalServerError, "NewAccessToken", err)
return return

View File

@ -166,37 +166,11 @@ func SettingsProtectedBranchPost(ctx *context.Context) {
} }
var err error var err error
if f.RuleID > 0 {
// If the RuleID isn't 0, it must be an edit operation. So we get rule by id.
protectBranch, err = git_model.GetProtectedBranchRuleByID(ctx, ctx.Repo.Repository.ID, f.RuleID)
if err != nil {
ctx.ServerError("GetProtectBranchOfRepoByID", err)
return
}
if protectBranch != nil && protectBranch.RuleName != f.RuleName {
// RuleName changed. We need to check if there is a rule with the same name.
// If a rule with the same name exists, an error should be returned.
sameNameProtectBranch, err := git_model.GetProtectedBranchRuleByName(ctx, ctx.Repo.Repository.ID, f.RuleName)
if err != nil {
ctx.ServerError("GetProtectBranchOfRepoByName", err)
return
}
if sameNameProtectBranch != nil {
ctx.Flash.Error(ctx.Tr("repo.settings.protected_branch_duplicate_rule_name"))
ctx.Redirect(fmt.Sprintf("%s/settings/branches/edit?rule_name=%s", ctx.Repo.RepoLink, protectBranch.RuleName))
return
}
}
} else {
// FIXME: If a new ProtectBranch has a duplicate RuleName, an error should be returned.
// Currently, if a new ProtectBranch with a duplicate RuleName is created, the existing ProtectBranch will be updated.
// But we cannot modify this logic now because many unit tests rely on it.
protectBranch, err = git_model.GetProtectedBranchRuleByName(ctx, ctx.Repo.Repository.ID, f.RuleName) protectBranch, err = git_model.GetProtectedBranchRuleByName(ctx, ctx.Repo.Repository.ID, f.RuleName)
if err != nil { if err != nil {
ctx.ServerError("GetProtectBranchOfRepoByName", err) ctx.ServerError("GetProtectBranchOfRepoByName", err)
return return
} }
}
if protectBranch == nil { if protectBranch == nil {
// No options found, create defaults. // No options found, create defaults.
protectBranch = &git_model.ProtectedBranch{ protectBranch = &git_model.ProtectedBranch{

View File

@ -190,7 +190,6 @@ func (f *RepoSettingForm) Validate(req *http.Request, errs binding.Errors) bindi
// ProtectBranchForm form for changing protected branch settings // ProtectBranchForm form for changing protected branch settings
type ProtectBranchForm struct { type ProtectBranchForm struct {
RuleName string `binding:"Required"` RuleName string `binding:"Required"`
RuleID int64
EnablePush string EnablePush string
WhitelistUsers string WhitelistUsers string
WhitelistTeams string WhitelistTeams string

View File

@ -150,6 +150,7 @@ func (m *webhookNotifier) NotifyIssueChangeAssignee(ctx context.Context, doer *u
log.Error("LoadPullRequest failed: %v", err) log.Error("LoadPullRequest failed: %v", err)
return return
} }
issue.PullRequest.Issue = issue
apiPullRequest := &api.PullRequestPayload{ apiPullRequest := &api.PullRequestPayload{
Index: issue.Index, Index: issue.Index,
PullRequest: convert.ToAPIPullRequest(ctx, issue.PullRequest, nil), PullRequest: convert.ToAPIPullRequest(ctx, issue.PullRequest, nil),
@ -195,6 +196,7 @@ func (m *webhookNotifier) NotifyIssueChangeTitle(ctx context.Context, doer *user
log.Error("LoadPullRequest failed: %v", err) log.Error("LoadPullRequest failed: %v", err)
return return
} }
issue.PullRequest.Issue = issue
err = PrepareWebhooks(ctx, EventSource{Repository: issue.Repo}, webhook_module.HookEventPullRequest, &api.PullRequestPayload{ err = PrepareWebhooks(ctx, EventSource{Repository: issue.Repo}, webhook_module.HookEventPullRequest, &api.PullRequestPayload{
Action: api.HookIssueEdited, Action: api.HookIssueEdited,
Index: issue.Index, Index: issue.Index,
@ -326,10 +328,7 @@ func (m *webhookNotifier) NotifyIssueChangeContent(ctx context.Context, doer *us
mode, _ := access_model.AccessLevel(ctx, issue.Poster, issue.Repo) mode, _ := access_model.AccessLevel(ctx, issue.Poster, issue.Repo)
var err error var err error
if issue.IsPull { if issue.IsPull {
if err := issue.LoadPullRequest(ctx); err != nil { issue.PullRequest.Issue = issue
log.Error("LoadPullRequest: %v", err)
return
}
err = PrepareWebhooks(ctx, EventSource{Repository: issue.Repo}, webhook_module.HookEventPullRequest, &api.PullRequestPayload{ err = PrepareWebhooks(ctx, EventSource{Repository: issue.Repo}, webhook_module.HookEventPullRequest, &api.PullRequestPayload{
Action: api.HookIssueEdited, Action: api.HookIssueEdited,
Index: issue.Index, Index: issue.Index,

View File

@ -39,7 +39,6 @@
</div> </div>
</div> </div>
<div class="ui two wide column center"> <div class="ui two wide column center">
{{if $.IsOrganizationOwner}}
<div class="meta"> <div class="meta">
{{$.locale.Tr "admin.users.2fa"}} {{$.locale.Tr "admin.users.2fa"}}
</div> </div>
@ -52,7 +51,6 @@
{{end}} {{end}}
</strong> </strong>
</div> </div>
{{end}}
</div> </div>
{{end}} {{end}}
<div class="ui three wide column"> <div class="ui three wide column">

View File

@ -58,7 +58,7 @@
</thead> </thead>
<tbody> <tbody>
{{range $t, $unit := $.Units}} {{range $t, $unit := $.Units}}
{{if (not $unit.Type.UnitGlobalDisabled)}} {{if and (lt $unit.MaxPerm 2) (not $unit.Type.UnitGlobalDisabled)}}
<tr> <tr>
<td><strong>{{$.locale.Tr $unit.NameKey}}</strong></td> <td><strong>{{$.locale.Tr $unit.NameKey}}</strong></td>
<td>{{if eq ($.Team.UnitAccessMode $.Context $unit.Type) 0 -}} <td>{{if eq ($.Team.UnitAccessMode $.Context $unit.Type) 0 -}}

View File

@ -17,7 +17,7 @@
{{$class = (printf "%s%s" $class " isWarning")}} {{$class = (printf "%s%s" $class " isWarning")}}
{{end}} {{end}}
{{end}} {{end}}
<div class="ui top attached header clearing segment gt-relative commit-header {{$class}}"> <div class="ui top attached header clearing segment gt-pr commit-header {{$class}}">
<div class="gt-df gt-mb-4 gt-fw"> <div class="gt-df gt-mb-4 gt-fw">
<h3 class="gt-mb-0 gt-f1"><span class="commit-summary" title="{{.Commit.Summary}}">{{RenderCommitMessage $.Context .Commit.Message $.RepoLink $.Repository.ComposeMetas}}</span>{{template "repo/commit_statuses" dict "Status" .CommitStatus "Statuses" .CommitStatuses "root" $}}</h3> <h3 class="gt-mb-0 gt-f1"><span class="commit-summary" title="{{.Commit.Summary}}">{{RenderCommitMessage $.Context .Commit.Message $.RepoLink $.Repository.ComposeMetas}}</span>{{template "repo/commit_statuses" dict "Status" .CommitStatus "Statuses" .CommitStatuses "root" $}}</h3>
{{if not $.PageIsWiki}} {{if not $.PageIsWiki}}

View File

@ -1,14 +1,6 @@
{{if .Statuses}} {{if eq (len .Statuses) 1}}{{$status := index .Statuses 0}}{{if $status.TargetURL}}<a class="ui link commit-statuses-trigger gt-vm" href="{{$status.TargetURL}}">{{template "repo/commit_status" .Status}}</a>{{end}}{{end}}
{{if and (eq (len .Statuses) 1) .Status.TargetURL}} <div class="ui commit-statuses-popup commit-statuses tippy-target">
<a class="gt-vm gt-tdn" data-tippy="commit-statuses" href="{{.Status.TargetURL}}"> <div class="ui relaxed list divided">
{{template "repo/commit_status" .Status}}
</a>
{{else}}
<span class="gt-vm" data-tippy="commit-statuses" tabindex="0">
{{template "repo/commit_status" .Status}}
</span>
{{end}}
<div class="tippy-target ui relaxed list divided">
{{range .Statuses}} {{range .Statuses}}
<div class="ui item singular-status gt-df"> <div class="ui item singular-status gt-df">
{{template "repo/commit_status" .}} {{template "repo/commit_status" .}}
@ -19,4 +11,4 @@
</div> </div>
{{end}} {{end}}
</div> </div>
{{end}} </div>

View File

@ -61,7 +61,7 @@
{{$.locale.Tr "repo.pulls.title_desc" .NumCommits $headHref $baseHref | Safe}} {{$.locale.Tr "repo.pulls.title_desc" .NumCommits $headHref $baseHref | Safe}}
</span> </span>
{{end}} {{end}}
<span id="pull-desc-edit" class="gt-hidden"> <span id="pull-desc-edit gt-hidden">
<div class="ui floating filter dropdown"> <div class="ui floating filter dropdown">
<div class="ui basic small button"> <div class="ui basic small button">
<span class="text">{{.locale.Tr "repo.pulls.compare_compare"}}: {{$.HeadTarget}}</span> <span class="text">{{.locale.Tr "repo.pulls.compare_compare"}}: {{$.HeadTarget}}</span>

View File

@ -14084,13 +14084,14 @@
"parameters": [ "parameters": [
{ {
"type": "string", "type": "string",
"x-go-name": "Name",
"description": "username of user", "description": "username of user",
"name": "username", "name": "username",
"in": "path", "in": "path",
"required": true "required": true
}, },
{ {
"name": "body", "name": "userCreateToken",
"in": "body", "in": "body",
"schema": { "schema": {
"$ref": "#/definitions/CreateAccessTokenOption" "$ref": "#/definitions/CreateAccessTokenOption"
@ -14193,13 +14194,6 @@
"type": "string", "type": "string",
"x-go-name": "Name" "x-go-name": "Name"
}, },
"scopes": {
"type": "array",
"items": {
"type": "string"
},
"x-go-name": "Scopes"
},
"sha1": { "sha1": {
"type": "string", "type": "string",
"x-go-name": "Token" "x-go-name": "Token"
@ -14931,20 +14925,10 @@
"CreateAccessTokenOption": { "CreateAccessTokenOption": {
"description": "CreateAccessTokenOption options when create access token", "description": "CreateAccessTokenOption options when create access token",
"type": "object", "type": "object",
"required": [
"name"
],
"properties": { "properties": {
"name": { "name": {
"type": "string", "type": "string",
"x-go-name": "Name" "x-go-name": "Name"
},
"scopes": {
"type": "array",
"items": {
"type": "string"
},
"x-go-name": "Scopes"
} }
}, },
"x-go-package": "code.gitea.io/gitea/modules/structs" "x-go-package": "code.gitea.io/gitea/modules/structs"

View File

@ -21,14 +21,7 @@
</div> </div>
<i class="icon tooltip{{if .HasRecentActivity}} green{{end}}" {{if .HasRecentActivity}}data-content="{{$.locale.Tr "settings.token_state_desc"}}"{{end}}>{{svg "fontawesome-send" 36}}</i> <i class="icon tooltip{{if .HasRecentActivity}} green{{end}}" {{if .HasRecentActivity}}data-content="{{$.locale.Tr "settings.token_state_desc"}}"{{end}}>{{svg "fontawesome-send" 36}}</i>
<div class="content"> <div class="content">
<details><summary><strong>{{.Name}}</strong></summary> <strong>{{.Name}}</strong>
<p class="gt-my-2">{{$.locale.Tr "settings.scopes_list"}}</p>
<ul class="gt-my-2">
{{range .Scope.StringSlice}}
<li>{{.}}</li>
{{end}}
</ul>
</details>
<div class="activity meta"> <div class="activity meta">
<i>{{$.locale.Tr "settings.add_on"}} <span><time data-format="short-date" datetime="{{.CreatedUnix.FormatLong}}">{{.CreatedUnix.FormatShort}}</time></span> — {{svg "octicon-info"}} {{if .HasUsed}}{{$.locale.Tr "settings.last_used"}} <span {{if .HasRecentActivity}}class="green"{{end}}><time data-format="short-date" datetime="{{.UpdatedUnix.FormatLong}}">{{.UpdatedUnix.FormatShort}}</time></span>{{else}}{{$.locale.Tr "settings.no_activity"}}{{end}}</i> <i>{{$.locale.Tr "settings.add_on"}} <span><time data-format="short-date" datetime="{{.CreatedUnix.FormatLong}}">{{.CreatedUnix.FormatShort}}</time></span> — {{svg "octicon-info"}} {{if .HasUsed}}{{$.locale.Tr "settings.last_used"}} <span {{if .HasRecentActivity}}class="green"{{end}}><time data-format="short-date" datetime="{{.UpdatedUnix.FormatLong}}">{{.UpdatedUnix.FormatShort}}</time></span>{{else}}{{$.locale.Tr "settings.no_activity"}}{{end}}</i>
</div> </div>

View File

@ -630,17 +630,8 @@ func doAutoPRMerge(baseCtx *APITestContext, dstPath string) func(t *testing.T) {
commitID := path.Base(commitURL) commitID := path.Base(commitURL)
addCommitStatus := func(status api.CommitStatusState) func(*testing.T) {
return doAPICreateCommitStatus(ctx, commitID, api.CreateStatusOption{
State: status,
TargetURL: "http://test.ci/",
Description: "",
Context: "testci",
})
}
// Call API to add Pending status for commit // Call API to add Pending status for commit
t.Run("CreateStatus", addCommitStatus(api.CommitStatusPending)) t.Run("CreateStatus", doAPICreateCommitStatus(ctx, commitID, api.CommitStatusPending))
// Cancel not existing auto merge // Cancel not existing auto merge
ctx.ExpectedCode = http.StatusNotFound ctx.ExpectedCode = http.StatusNotFound
@ -669,7 +660,7 @@ func doAutoPRMerge(baseCtx *APITestContext, dstPath string) func(t *testing.T) {
assert.False(t, pr.HasMerged) assert.False(t, pr.HasMerged)
// Call API to add Failure status for commit // Call API to add Failure status for commit
t.Run("CreateStatus", addCommitStatus(api.CommitStatusFailure)) t.Run("CreateStatus", doAPICreateCommitStatus(ctx, commitID, api.CommitStatusFailure))
// Check pr status // Check pr status
pr, err = doAPIGetPullRequest(ctx, baseCtx.Username, baseCtx.Reponame, pr.Index)(t) pr, err = doAPIGetPullRequest(ctx, baseCtx.Username, baseCtx.Reponame, pr.Index)(t)
@ -677,7 +668,7 @@ func doAutoPRMerge(baseCtx *APITestContext, dstPath string) func(t *testing.T) {
assert.False(t, pr.HasMerged) assert.False(t, pr.HasMerged)
// Call API to add Success status for commit // Call API to add Success status for commit
t.Run("CreateStatus", addCommitStatus(api.CommitStatusSuccess)) t.Run("CreateStatus", doAPICreateCommitStatus(ctx, commitID, api.CommitStatusSuccess))
// wait to let gitea merge stuff // wait to let gitea merge stuff
time.Sleep(time.Second) time.Sleep(time.Second)

View File

@ -70,12 +70,7 @@ func TestPullCreate_CommitStatus(t *testing.T) {
for _, status := range statusList { for _, status := range statusList {
// Call API to add status for commit // Call API to add status for commit
t.Run("CreateStatus", doAPICreateCommitStatus(testCtx, commitID, api.CreateStatusOption{ t.Run("CreateStatus", doAPICreateCommitStatus(testCtx, commitID, status))
State: status,
TargetURL: "http://test.ci/",
Description: "",
Context: "testci",
}))
req = NewRequestf(t, "GET", "/user1/repo1/pulls/1/commits") req = NewRequestf(t, "GET", "/user1/repo1/pulls/1/commits")
resp = session.MakeRequest(t, req, http.StatusOK) resp = session.MakeRequest(t, req, http.StatusOK)
@ -93,13 +88,15 @@ func TestPullCreate_CommitStatus(t *testing.T) {
}) })
} }
func doAPICreateCommitStatus(ctx APITestContext, commitID string, data api.CreateStatusOption) func(*testing.T) { func doAPICreateCommitStatus(ctx APITestContext, commitID string, status api.CommitStatusState) func(*testing.T) {
return func(t *testing.T) { return func(t *testing.T) {
req := NewRequestWithJSON( req := NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/statuses/%s?token=%s", ctx.Username, ctx.Reponame, commitID, ctx.Token),
t, api.CreateStatusOption{
http.MethodPost, State: status,
fmt.Sprintf("/api/v1/repos/%s/%s/statuses/%s?token=%s", ctx.Username, ctx.Reponame, commitID, ctx.Token), TargetURL: "http://test.ci/",
data, Description: "",
Context: "testci",
},
) )
if ctx.ExpectedCode != 0 { if ctx.ExpectedCode != 0 {
ctx.Session.MakeRequest(t, req, ctx.ExpectedCode) ctx.Session.MakeRequest(t, req, ctx.ExpectedCode)

View File

@ -52,19 +52,14 @@ func doTestRepoCommitWithStatus(t *testing.T, state string, classes ...string) {
// Call API to add status for commit // Call API to add status for commit
ctx := NewAPITestContext(t, "user2", "repo1", auth_model.AccessTokenScopeRepo) ctx := NewAPITestContext(t, "user2", "repo1", auth_model.AccessTokenScopeRepo)
t.Run("CreateStatus", doAPICreateCommitStatus(ctx, path.Base(commitURL), api.CreateStatusOption{ t.Run("CreateStatus", doAPICreateCommitStatus(ctx, path.Base(commitURL), api.CommitStatusState(state)))
State: api.CommitStatusState(state),
TargetURL: "http://test.ci/",
Description: "",
Context: "testci",
}))
req = NewRequest(t, "GET", "/user2/repo1/commits/branch/master") req = NewRequest(t, "GET", "/user2/repo1/commits/branch/master")
resp = session.MakeRequest(t, req, http.StatusOK) resp = session.MakeRequest(t, req, http.StatusOK)
doc = NewHTMLParser(t, resp.Body) doc = NewHTMLParser(t, resp.Body)
// Check if commit status is displayed in message column (.tippy-target to ignore the tippy trigger) // Check if commit status is displayed in message column
sel := doc.doc.Find("#commits-table tbody tr td.message .tippy-target .commit-status") sel := doc.doc.Find("#commits-table tbody tr td.message a.commit-statuses-trigger .commit-status")
assert.Equal(t, 1, sel.Length()) assert.Equal(t, 1, sel.Length())
for _, class := range classes { for _, class := range classes {
assert.True(t, sel.HasClass(class)) assert.True(t, sel.HasClass(class))
@ -150,12 +145,7 @@ func TestRepoCommitsStatusParallel(t *testing.T) {
go func(parentT *testing.T, i int) { go func(parentT *testing.T, i int) {
parentT.Run(fmt.Sprintf("ParallelCreateStatus_%d", i), func(t *testing.T) { parentT.Run(fmt.Sprintf("ParallelCreateStatus_%d", i), func(t *testing.T) {
ctx := NewAPITestContext(t, "user2", "repo1", auth_model.AccessTokenScopeRepoStatus) ctx := NewAPITestContext(t, "user2", "repo1", auth_model.AccessTokenScopeRepoStatus)
runBody := doAPICreateCommitStatus(ctx, path.Base(commitURL), api.CreateStatusOption{ runBody := doAPICreateCommitStatus(ctx, path.Base(commitURL), api.CommitStatusState("pending"))
State: api.CommitStatusPending,
TargetURL: "http://test.ci/",
Description: "",
Context: "testci",
})
runBody(t) runBody(t)
wg.Done() wg.Done()
}) })
@ -163,43 +153,3 @@ func TestRepoCommitsStatusParallel(t *testing.T) {
} }
wg.Wait() wg.Wait()
} }
func TestRepoCommitsStatusMultiple(t *testing.T) {
defer tests.PrepareTestEnv(t)()
session := loginUser(t, "user2")
// Request repository commits page
req := NewRequest(t, "GET", "/user2/repo1/commits/branch/master")
resp := session.MakeRequest(t, req, http.StatusOK)
doc := NewHTMLParser(t, resp.Body)
// Get first commit URL
commitURL, exists := doc.doc.Find("#commits-table tbody tr td.sha a").Attr("href")
assert.True(t, exists)
assert.NotEmpty(t, commitURL)
// Call API to add status for commit
ctx := NewAPITestContext(t, "user2", "repo1", auth_model.AccessTokenScopeRepo)
t.Run("CreateStatus", doAPICreateCommitStatus(ctx, path.Base(commitURL), api.CreateStatusOption{
State: api.CommitStatusSuccess,
TargetURL: "http://test.ci/",
Description: "",
Context: "testci",
}))
t.Run("CreateStatus", doAPICreateCommitStatus(ctx, path.Base(commitURL), api.CreateStatusOption{
State: api.CommitStatusSuccess,
TargetURL: "http://test.ci/",
Description: "",
Context: "other_context",
}))
req = NewRequest(t, "GET", "/user2/repo1/commits/branch/master")
resp = session.MakeRequest(t, req, http.StatusOK)
doc = NewHTMLParser(t, resp.Body)
// Check that the data-tippy="commit-statuses" (for trigger) and commit-status (svg) are present
sel := doc.doc.Find("#commits-table tbody tr td.message [data-tippy=\"commit-statuses\"] .commit-status")
assert.Equal(t, 1, sel.Length())
}

View File

@ -58,7 +58,7 @@ export function initRepoCommitLastCommitLoader() {
} }
export function initCommitStatuses() { export function initCommitStatuses() {
$('[data-tippy="commit-statuses"]').each(function () { $('.commit-statuses-trigger').each(function () {
const top = $('.repository.file.list').length > 0 || $('.repository.diff').length > 0; const top = $('.repository.file.list').length > 0 || $('.repository.diff').length > 0;
createTippy(this, { createTippy(this, {

View File

@ -552,6 +552,8 @@ export function initRepoIssueReferenceIssue() {
// Reference issue // Reference issue
$(document).on('click', '.reference-issue', function (event) { $(document).on('click', '.reference-issue', function (event) {
const $this = $(this); const $this = $(this);
$this.closest('.dropdown').find('.menu').toggle('visible'); // eslint-disable-line
const content = $(`#${$this.data('target')}`).text(); const content = $(`#${$this.data('target')}`).text();
const poster = $this.data('poster-username'); const poster = $this.data('poster-username');
const reference = $this.data('reference'); const reference = $this.data('reference');

View File

@ -291,6 +291,7 @@ export function initRepoCommentForm() {
async function onEditContent(event) { async function onEditContent(event) {
event.preventDefault(); event.preventDefault();
$(this).closest('.dropdown').find('.menu').toggle('visible'); // eslint-disable-line
const $segment = $(this).closest('.header').next(); const $segment = $(this).closest('.header').next();
const $editContentZone = $segment.find('.edit-content-zone'); const $editContentZone = $segment.find('.edit-content-zone');
const $renderContent = $segment.find('.render-content'); const $renderContent = $segment.find('.render-content');
@ -583,6 +584,7 @@ function initRepoIssueCommentEdit() {
// Quote reply // Quote reply
$(document).on('click', '.quote-reply', function (event) { $(document).on('click', '.quote-reply', function (event) {
$(this).closest('.dropdown').find('.menu').toggle('visible'); // eslint-disable-line
const target = $(this).data('target'); const target = $(this).data('target');
const quote = $(`#${target}`).text().replace(/\n/g, '\n> '); const quote = $(`#${target}`).text().replace(/\n/g, '\n> ');
const content = `> ${quote}\n\n`; const content = `> ${quote}\n\n`;

View File

@ -340,7 +340,8 @@ a.label,
.ui.search .results a, .ui.search .results a,
.ui .menu a, .ui .menu a,
.ui.cards a.card, .ui.cards a.card,
.issue-keyword a { .issue-keyword a,
a.commit-statuses-trigger {
text-decoration: none !important; text-decoration: none !important;
} }

View File

@ -1,4 +1,28 @@
.repository { .repository {
.popup.commit-statuses {
// we had better limit the max size of the popup, and add scroll bars if the content size is too large.
// otherwise some part of the popup will be hidden by viewport boundary
max-height: 45vh;
max-width: 60vw;
&.ui.right {
// Override `.ui.attached.header .right:not(.dropdown) height: 30px;` which would otherwise lead to
// the status popup box having its height fixed at 30px. See https://github.com/go-gitea/gitea/issues/18498
height: auto;
}
overflow: auto;
padding: 0;
.list {
padding: .8em; // to make the scrollbar align to the border, we move the padding from outer `.popup` to this inside `.list`
> .item {
line-height: 2;
}
}
}
.repo-header { .repo-header {
.ui.compact.menu { .ui.compact.menu {
margin-left: 1rem; margin-left: 1rem;

View File

@ -2,6 +2,7 @@
.gt-di { display: inline !important; } .gt-di { display: inline !important; }
.gt-dif { display: inline-flex !important; } .gt-dif { display: inline-flex !important; }
.gt-dib { display: inline-block !important; } .gt-dib { display: inline-block !important; }
.gt-pr { position: relative !important; }
.gt-ac { align-items: center !important; } .gt-ac { align-items: center !important; }
.gt-tc { text-align: center !important; } .gt-tc { text-align: center !important; }
.gt-tl { text-align: left !important; } .gt-tl { text-align: left !important; }