Compare commits

..

1 Commits

Author SHA1 Message Date
Jimmy Praet 8df3d6575a Change @every 24h default schedules to @midnight (#16431) 2021-07-15 11:55:48 -04:00
101 changed files with 451 additions and 5665 deletions
+9 -9
View File
@@ -15,12 +15,12 @@ trigger:
steps:
- name: deps-frontend
pull: always
image: node:14
image: node:16
commands:
- make node_modules
- name: lint-frontend
image: node:14
image: node:16
commands:
- make lint-frontend
depends_on: [deps-frontend]
@@ -58,7 +58,7 @@ steps:
TAGS: bindata gogit sqlite sqlite_unlock_notify
- name: checks-frontend
image: node:14
image: node:16
commands:
- make checks-frontend
depends_on: [deps-frontend]
@@ -71,20 +71,20 @@ steps:
depends_on: [lint-backend]
- name: test-frontend
image: node:14
image: node:16
commands:
- make test-frontend
depends_on: [lint-frontend]
- name: build-frontend
image: node:14
image: node:16
commands:
- make frontend
depends_on: [test-frontend]
- name: build-backend-no-gcc
pull: always
image: golang:1.15 # this step is kept as the lowest version of golang that we support
image: golang:1.14 # this step is kept as the lowest version of golang that we support
environment:
GO111MODULE: on
GOPROXY: off
@@ -404,7 +404,7 @@ steps:
- name: update
pull: default
image: alpine:3.13
image: alpine:3.14
commands:
- ./build/update-locales.sh
@@ -503,7 +503,7 @@ steps:
pull: always
image: techknowlogick/xgo:go-1.16.x
commands:
- curl -sL https://deb.nodesource.com/setup_14.x | bash - && apt-get install -y nodejs
- curl -sL https://deb.nodesource.com/setup_16.x | bash - && apt-get install -y nodejs
- export PATH=$PATH:$GOPATH/bin
- make release
environment:
@@ -599,7 +599,7 @@ steps:
pull: always
image: techknowlogick/xgo:go-1.16.x
commands:
- curl -sL https://deb.nodesource.com/setup_14.x | bash - && apt-get install -y nodejs
- curl -sL https://deb.nodesource.com/setup_16.x | bash - && apt-get install -y nodejs
- export PATH=$PATH:$GOPATH/bin
- make release
environment:
-1
View File
@@ -2,7 +2,6 @@ root: true
reportUnusedDisableDirectives: true
ignorePatterns:
- /web_src/js/vendor
- /templates/base/head.tmpl
- /templates/repo/activity.tmpl
- /templates/repo/view_file.tmpl
-66
View File
@@ -4,50 +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.15.0-rc3](https://github.com/go-gitea/gitea/releases/tag/v1.15.0-rc3) - 2021-08-06
* BREAKING
* Upgrade to the latest version of golang-jwt and increase minimum go to 1.15 (#16590) (#16606)
* SECURITY
* Upgrade to the latest version of golang-jwt and increase minimum go to 1.15 (#16590) (#16606)
* Correctly create of git-daemon-export-ok files (#16508) (#16514)
* Don't show private user's repo in explore view (#16550) (#16554)
* Update node tar dependency to 6.1.6 (#16622) (#16623)
* API
* Swagger AccessToken fixes (#16574) (#16597)
* Set AllowedHeaders on API CORS handler (#16524) (#16618)
* BUGFIXES
* Restore Accessibility for Dropdown (#16576) (#16617)
* Pass down SignedUserName down to AccessLogger context (#16605) (#16616)
* Fix table alignment in markdown (#16596) (#16602)
* Fix 500 on first wiki page (#16586) (#16598)
* Lock goth/gothic and Re-attempt OAuth2 registration on login if registration failed at startup (#16564) (#16570)
* Upgrade levelqueue to v0.4.0 (#16560) (#16561)
* Handle too long PR titles correctly (#16517) (#16549)
* Fix data race in bleve indexer (#16474) (#16509)
* Restore CORS on git smart http protocol (#16496) (#16506)
* Fix race in log (#16490) (#16505)
* Fix prepareWikiFileName to respect existing unescaped files (#16487) (#16498)
* Make cancel from CatFileBatch and CatFileBatchCheck wait for the command to end (#16479) (#16480)
* Update notification table with only latest data (#16445) (#16469)
* Revert to use alpine 3.13 (#16451) (#16452)
* Fix crash following ldap authentication update (#16447) (#16448)
* Fix direct creation of external users on admin page (partial #16612) (#16613)
* Prevent 500 on draft releases without tag (#16634) (#16636)
## [1.15.0-rc2](https://github.com/go-gitea/gitea/releases/tag/v1.15.0-rc2) - 2021-07-22
* BUGFIXES
* Restore creation of git-daemon-export-ok files (#16508) (#16514)
* Fix data race in bleve indexer (#16474) (#16509)
* Restore CORS on git smart http protocol (#16496) (#16506)
* Fix race in log (#16490) (#16505)
* Fix prepareWikiFileName to respect existing unescaped files (#16487) (#16498)
* Make cancel from CatFileBatch and CatFileBatchCheck wait for the command to end (#16479) (#16480)
* Update notification table with only latest data (#16445) (#16469)
* Revert to use alpine 3.13 to fix multiple seccomp related issues with Docker <20 (#16451) (#16452)
* Fix crash following ldap authentication update (#16447) (#16448)
## [1.15.0-rc1](https://github.com/go-gitea/gitea/releases/tag/v1.15.0-rc1) - 2021-07-15
* BREAKING
@@ -260,28 +216,6 @@ been added to each release, please refer to the [blog](https://blog.gitea.io).
* Remove utf8 option from installation page (#16126)
* Use Wants= over Requires= in systemd file (#15897)
## [1.14.6](https://github.com/go-gitea/gitea/releases/tag/v1.14.6) - 2021-08-04
* SECURITY
* Bump github.com/markbates/goth from v1.67.1 to v1.68.0 (#16538) (#16540)
* Switch to maintained JWT lib (#16532) (#16535)
* Upgrade to latest version of golang-jwt (as forked for 1.14) (#16590) (#16607)
* BUGFIXES
* Add basic edit ldap auth test & actually fix #16252 (#16465) (#16495)
* Make cancel from CatFileBatch and CatFileBatchCheck wait for the command to end (#16479) (#16481)
## [1.14.5](https://github.com/go-gitea/gitea/releases/tag/v1.14.5) - 2021-07-16
* SECURITY
* Hide mirror passwords on repo settings page (#16022) (#16355)
* Update bluemonday to v1.0.15 (#16379) (#16380)
* BUGFIXES
* Retry rename on lock induced failures (#16435) (#16439)
* Validate issue index before querying DB (#16406) (#16410)
* Fix crash following ldap authentication update (#16447) (#16449)
* ENHANCEMENTS
* Redirect on bad CSRF instead of presenting bad page (#14937) (#16378)
## [1.14.4](https://github.com/go-gitea/gitea/releases/tag/v1.14.4) - 2021-07-06
* BUGFIXES
+2 -2
View File
@@ -1,7 +1,7 @@
###################################
#Build stage
FROM golang:1.16-alpine3.13 AS build-env
FROM golang:1.16-alpine3.14 AS build-env
ARG GOPROXY
ENV GOPROXY ${GOPROXY:-direct}
@@ -25,7 +25,7 @@ RUN if [ -n "${GITEA_VERSION}" ]; then git checkout "${GITEA_VERSION}"; fi \
# Begin env-to-ini build
RUN go build contrib/environment-to-ini/environment-to-ini.go
FROM alpine:3.13
FROM alpine:3.14
LABEL maintainer="maintainers@gitea.io"
EXPOSE 22 3000
+2 -2
View File
@@ -1,7 +1,7 @@
###################################
#Build stage
FROM golang:1.16-alpine3.13 AS build-env
FROM golang:1.16-alpine3.14 AS build-env
ARG GOPROXY
ENV GOPROXY ${GOPROXY:-direct}
@@ -25,7 +25,7 @@ RUN if [ -n "${GITEA_VERSION}" ]; then git checkout "${GITEA_VERSION}"; fi \
# Begin env-to-ini build
RUN go build contrib/environment-to-ini/environment-to-ini.go
FROM alpine:3.13
FROM alpine:3.14
LABEL maintainer="maintainers@gitea.io"
EXPOSE 2222 3000
+2 -3
View File
@@ -25,7 +25,7 @@ HAS_GO = $(shell hash $(GO) > /dev/null 2>&1 && echo "GO" || echo "NOGO" )
COMMA := ,
XGO_VERSION := go-1.16.x
MIN_GO_VERSION := 001015000
MIN_GO_VERSION := 001014000
MIN_NODE_VERSION := 012017000
DOCKER_IMAGE ?= gitea/gitea
@@ -200,7 +200,7 @@ help:
go-check:
$(eval GO_VERSION := $(shell printf "%03d%03d%03d" $(shell $(GO) version | grep -Eo '[0-9]+\.[0-9.]+' | tr '.' ' ');))
@if [ "$(GO_VERSION)" -lt "$(MIN_GO_VERSION)" ]; then \
echo "Gitea requires Go 1.15 or greater to build. You can get it at https://golang.org/dl/"; \
echo "Gitea requires Go 1.14 or greater to build. You can get it at https://golang.org/dl/"; \
exit 1; \
fi
@@ -699,7 +699,6 @@ fomantic:
cd $(FOMANTIC_WORK_DIR) && npm install --no-save
cp -f $(FOMANTIC_WORK_DIR)/theme.config.less $(FOMANTIC_WORK_DIR)/node_modules/fomantic-ui/src/theme.config
cp -rf $(FOMANTIC_WORK_DIR)/_site $(FOMANTIC_WORK_DIR)/node_modules/fomantic-ui/src/
cp -f web_src/js/vendor/dropdown.js $(FOMANTIC_WORK_DIR)/node_modules/fomantic-ui/src/definitions/modules
cd $(FOMANTIC_WORK_DIR) && npx gulp -f node_modules/fomantic-ui/gulpfile.js build
.PHONY: webpack
+1 -1
View File
@@ -23,7 +23,7 @@ import (
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/services/lfs"
"github.com/golang-jwt/jwt"
"github.com/dgrijalva/jwt-go"
jsoniter "github.com/json-iterator/go"
"github.com/kballard/go-shellquote"
"github.com/urfave/cli"
+7 -7
View File
@@ -1671,7 +1671,7 @@ PATH =
;; Notice if not success
;NO_SUCCESS_NOTICE = false
;; Time interval for job to run
;SCHEDULE = @every 24h
;SCHEDULE = @midnight
;; Archives created more than OLDER_THAN ago are subject to deletion
;OLDER_THAN = 24h
@@ -1697,7 +1697,7 @@ PATH =
;[cron.repo_health_check]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;SCHEDULE = @every 24h
;SCHEDULE = @midnight
;; Enable running Repository health check task periodically.
;ENABLED = true
;; Run Repository health check task when Gitea starts.
@@ -1722,7 +1722,7 @@ PATH =
;RUN_AT_START = true
;; Notice if not success
;NO_SUCCESS_NOTICE = false
;SCHEDULE = @every 24h
;SCHEDULE = @midnight
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -1736,7 +1736,7 @@ PATH =
;; Notice if not success
;NO_SUCCESS_NOTICE = false
;; Interval as a duration between each synchronization. (default every 24h)
;SCHEDULE = @every 24h
;SCHEDULE = @midnight
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -1751,7 +1751,7 @@ PATH =
;; Notice if not success
;NO_SUCCESS_NOTICE = false
;; Interval as a duration between each synchronization (default every 24h)
;SCHEDULE = @every 24h
;SCHEDULE = @midnight
;; Create new users, update existing user data and disable users that are not in external source anymore (default)
;; or only create new users if UPDATE_EXISTING is set to false
;UPDATE_EXISTING = true
@@ -1769,7 +1769,7 @@ PATH =
;; Notice if not success
;NO_SUCCESS_NOTICE = false
;; Interval as a duration between each synchronization (default every 24h)
;SCHEDULE = @every 24h
;SCHEDULE = @midnight
;; deleted branches than OLDER_THAN ago are subject to deletion
;OLDER_THAN = 24h
@@ -1785,7 +1785,7 @@ PATH =
;; Whether to always run at start up time (if ENABLED)
;RUN_AT_START = false
;; Time interval for job to run
;SCHEDULE = @every 24h
;SCHEDULE = @midnight
;; OlderThan or PerWebhook. How the records are removed, either by age (i.e. how long ago hook_task record was delivered) or by the number to keep per webhook (i.e. keep most recent x deliveries per webhook).
;CLEANUP_TYPE = OlderThan
;; If CLEANUP_TYPE is set to OlderThan, then any delivered hook_task records older than this expression will be deleted.
+2 -2
View File
@@ -18,8 +18,8 @@ params:
description: Git with a cup of tea
author: The Gitea Authors
website: https://docs.gitea.io
version: 1.14.6
minGoVersion: 1.15
version: 1.14.4
minGoVersion: 1.14
goVersion: 1.16
minNodeVersion: 12.17
@@ -32,7 +32,7 @@ You absolutely must not place a general ToS or privacy statement that implies th
Create or append to `/path/to/custom/templates/custom/extra_links_footer.tmpl`:
```go
<a class="item" href="{{AppSubUrl}}/assets/privacy.html">Privacy Policy</a>
<a class="item" href="{{AppSubUrl}}/privacy.html">Privacy Policy</a>
```
Restart Gitea to see the changes.
@@ -740,7 +740,7 @@ NB: You must have `DISABLE_ROUTER_LOG` set to `false` for this option to take ef
- `ENABLED`: **true**: Enable service.
- `RUN_AT_START`: **true**: Run tasks at start up time (if ENABLED).
- `SCHEDULE`: **@every 24h**: Cron syntax for scheduling repository archive cleanup, e.g. `@every 1h`.
- `SCHEDULE`: **@midnight**: Cron syntax for scheduling repository archive cleanup, e.g. `@every 1h`.
- `OLDER_THAN`: **24h**: Archives created more than `OLDER_THAN` ago are subject to deletion, e.g. `12h`.
#### Cron - Update Mirrors (`cron.update_mirrors`)
@@ -750,31 +750,31 @@ NB: You must have `DISABLE_ROUTER_LOG` set to `false` for this option to take ef
#### Cron - Repository Health Check (`cron.repo_health_check`)
- `SCHEDULE`: **@every 24h**: Cron syntax for scheduling repository health check.
- `SCHEDULE`: **@midnight**: Cron syntax for scheduling repository health check.
- `TIMEOUT`: **60s**: Time duration syntax for health check execution timeout.
- `ARGS`: **\<empty\>**: Arguments for command `git fsck`, e.g. `--unreachable --tags`. See more on http://git-scm.com/docs/git-fsck
#### Cron - Repository Statistics Check (`cron.check_repo_stats`)
- `RUN_AT_START`: **true**: Run repository statistics check at start time.
- `SCHEDULE`: **@every 24h**: Cron syntax for scheduling repository statistics check.
- `SCHEDULE`: **@midnight**: Cron syntax for scheduling repository statistics check.
### Cron - Cleanup hook_task Table (`cron.cleanup_hook_task_table`)
- `ENABLED`: **true**: Enable cleanup hook_task job.
- `RUN_AT_START`: **false**: Run cleanup hook_task at start time (if ENABLED).
- `SCHEDULE`: **@every 24h**: Cron syntax for cleaning hook_task table.
- `SCHEDULE`: **@midnight**: Cron syntax for cleaning hook_task table.
- `CLEANUP_TYPE` **OlderThan** OlderThan or PerWebhook Method to cleanup hook_task, either by age (i.e. how long ago hook_task record was delivered) or by the number to keep per webhook (i.e. keep most recent x deliveries per webhook).
- `OLDER_THAN`: **168h**: If CLEANUP_TYPE is set to OlderThan, then any delivered hook_task records older than this expression will be deleted.
- `NUMBER_TO_KEEP`: **10**: If CLEANUP_TYPE is set to PerWebhook, this is number of hook_task records to keep for a webhook (i.e. keep the most recent x deliveries).
#### Cron - Update Migration Poster ID (`cron.update_migration_poster_id`)
- `SCHEDULE`: **@every 24h** : Interval as a duration between each synchronization, it will always attempt synchronization when the instance starts.
- `SCHEDULE`: **@midnight** : Interval as a duration between each synchronization, it will always attempt synchronization when the instance starts.
#### Cron - Sync External Users (`cron.sync_external_users`)
- `SCHEDULE`: **@every 24h** : Interval as a duration between each synchronization, it will always attempt synchronization when the instance starts.
- `SCHEDULE`: **@midnight** : Interval as a duration between each synchronization, it will always attempt synchronization when the instance starts.
- `UPDATE_EXISTING`: **true**: Create new users, update existing user data and disable users that are not in external source anymore (default) or only create new users if UPDATE_EXISTING is set to false.
### Extended cron tasks (not enabled by default)
@@ -257,18 +257,18 @@ test01.xls: application/vnd.ms-excel; charset=binary
### Cron - Repository Health Check (`cron.repo_health_check`)
- `SCHEDULE`: 仓库健康监测的Cron语法,比如:`@every 24h`
- `SCHEDULE`: 仓库健康监测的Cron语法,比如:`@midnight`
- `TIMEOUT`: 仓库健康监测的超时时间,比如:`60s`.
- `ARGS`: 执行 `git fsck` 命令的参数,比如:`--unreachable --tags`
### Cron - Repository Statistics Check (`cron.check_repo_stats`)
- `RUN_AT_START`: 是否启动时自动运行仓库统计。
- `SCHEDULE`: 仓库统计时的Cron 语法,比如:`@every 24h`.
- `SCHEDULE`: 仓库统计时的Cron 语法,比如:`@midnight`.
### Cron - Update Migration Poster ID (`cron.update_migration_poster_id`)
- `SCHEDULE`: **@every 24h** : 每次同步的间隔时间。此任务总是在启动时自动进行。
- `SCHEDULE`: **@midnight** : 每次同步的间隔时间。此任务总是在启动时自动进行。
## Git (`git`)
@@ -102,7 +102,7 @@ For instance, let's say you are in Germany and must add the famously legally-req
just place it under your "$GITEA_CUSTOM/public/" directory (for instance `$GITEA_CUSTOM/public/impressum.html`) and put a link to it in either `$GITEA_CUSTOM/templates/custom/extra_links.tmpl` or `$GITEA_CUSTOM/templates/custom/extra_links_footer.tmpl`.
To match the current style, the link should have the class name "item", and you can use `{{AppSubUrl}}` to get the base URL:
`<a class="item" href="{{AppSubUrl}}/assets/impressum.html">Impressum</a>`
`<a class="item" href="{{AppSubUrl}}/impressum.html">Impressum</a>`
For more information, see [Adding Legal Pages](https://docs.gitea.io/en-us/adding-legal-pages).
@@ -174,13 +174,13 @@ You can display STL file directly in Gitea by adding:
if ($('.view-raw>a[href$=".stl" i]').length) {
$("body").append(
'<link href="/assets/Madeleine.js/src/css/Madeleine.css" rel="stylesheet">'
'<link href="/Madeleine.js/src/css/Madeleine.css" rel="stylesheet">'
);
Promise.all([
lS("/assets/Madeleine.js/src/lib/stats.js"),
lS("/assets/Madeleine.js/src/lib/detector.js"),
lS("/assets/Madeleine.js/src/lib/three.min.js"),
lS("/assets/Madeleine.js/src/Madeleine.js"),
lS("/Madeleine.js/src/lib/stats.js"),
lS("/Madeleine.js/src/lib/detector.js"),
lS("/Madeleine.js/src/lib/three.min.js"),
lS("/Madeleine.js/src/Madeleine.js"),
]).then(function () {
$(".view-raw")
.attr("id", "view-raw")
@@ -188,7 +188,7 @@ You can display STL file directly in Gitea by adding:
new Madeleine({
target: "view-raw",
data: $('.view-raw>a[href$=".stl" i]').attr("href"),
path: "/assets/Madeleine.js/src",
path: "/Madeleine.js/src",
});
$('.view-raw>a[href$=".stl"]').remove();
});
@@ -61,7 +61,7 @@ Gitea 引用 `custom` 目录中的自定义配置文件来覆盖配置、模板
"custom/public/"目录下(比如 `custom/public/impressum.html`)并且将它与 `custom/templates/custom/extra_links.tmpl` 链接起来即可。
这个链接应当使用一个名为“item”的 class 来匹配当前样式,您可以使用 `{{AppSubUrl}}` 来获取 base URL:
`<a class="item" href="{{AppSubUrl}}/assets/impressum.html">Impressum</a>`
`<a class="item" href="{{AppSubUrl}}/impressum.html">Impressum</a>`
同理,您可以将页签添加到 `extra_tabs.tmpl` 中,使用同样的方式来添加页签。它的具体样式需要与
`templates/repo/header.tmpl` 中已有的其他选项卡的样式匹配
@@ -164,5 +164,5 @@ And so you could write some CSS:
Add your stylesheet to your custom directory e.g `custom/public/css/my-style-XXXXX.css` and import it using a custom header file `custom/templates/custom/header.tmpl`:
```html
<link type="text/css" href="{{AppSubUrl}}/assets/css/my-style-XXXXX.css" />
<link type="text/css" href="{{AppSubUrl}}/css/my-style-XXXXX.css" />
```
+3 -5
View File
@@ -10,7 +10,7 @@ require (
gitea.com/go-chi/cache v0.0.0-20210110083709-82c4c9ce2d5e
gitea.com/go-chi/captcha v0.0.0-20210110083842-e7696c336a1e
gitea.com/go-chi/session v0.0.0-20210108030337-0cb48c5ba8ee
gitea.com/lunny/levelqueue v0.4.0
gitea.com/lunny/levelqueue v0.3.0
github.com/Microsoft/go-winio v0.5.0 // indirect
github.com/NYTimes/gziphandler v1.1.1
github.com/ProtonMail/go-crypto v0.0.0-20210705153151-cc34b1f6908b // indirect
@@ -28,6 +28,7 @@ require (
github.com/couchbase/gomemcached v0.1.2 // indirect
github.com/couchbase/goutils v0.0.0-20210118111533-e33d3ffb5401 // indirect
github.com/denisenkom/go-mssqldb v0.10.0
github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/djherbis/buffer v1.2.0
github.com/djherbis/nio/v3 v3.0.1
github.com/dustin/go-humanize v1.0.0
@@ -50,7 +51,6 @@ require (
github.com/gogs/chardet v0.0.0-20191104214054-4b6791f73a28
github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14
github.com/gogs/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85
github.com/golang-jwt/jwt v3.2.2+incompatible
github.com/golang/snappy v0.0.4 // indirect
github.com/google/go-github/v32 v32.1.0
github.com/google/go-querystring v1.1.0 // indirect
@@ -75,7 +75,7 @@ require (
github.com/lafriks/xormstore v1.4.0
github.com/lib/pq v1.10.2
github.com/lunny/dingtalk_webhook v0.0.0-20171025031554-e3534c89ef96
github.com/markbates/goth v1.68.0
github.com/markbates/goth v1.67.1
github.com/mattn/go-isatty v0.0.13
github.com/mattn/go-runewidth v0.0.13 // indirect
github.com/mattn/go-sqlite3 v1.14.7
@@ -143,5 +143,3 @@ require (
)
replace github.com/hashicorp/go-version => github.com/6543/go-version v1.3.1
replace github.com/golang-jwt/jwt v3.2.1+incompatible => github.com/golang-jwt/jwt v3.2.2+incompatible
+5 -6
View File
@@ -49,8 +49,8 @@ gitea.com/go-chi/captcha v0.0.0-20210110083842-e7696c336a1e h1:YjaQU6XFicdhPN+Ml
gitea.com/go-chi/captcha v0.0.0-20210110083842-e7696c336a1e/go.mod h1:nfA7JaGv3hbGQ1ktdhAsZhdS84qKffI8NMlHr+Opsog=
gitea.com/go-chi/session v0.0.0-20210108030337-0cb48c5ba8ee h1:9U6HuKUBt/cGK6T/64dEuz0r7Yp97WAAEJvXHDlY3ws=
gitea.com/go-chi/session v0.0.0-20210108030337-0cb48c5ba8ee/go.mod h1:Ozg8IchVNb/Udg+ui39iHRYqVHSvf3C99ixdpLR8Vu0=
gitea.com/lunny/levelqueue v0.4.0 h1:v+bCR1lwLTBpZMshguWNhGIFLkUj+R04pgaU3TcJFS8=
gitea.com/lunny/levelqueue v0.4.0/go.mod h1:HBqmLbz56JWpfEGG0prskAV97ATNRoj5LDmPicD22hU=
gitea.com/lunny/levelqueue v0.3.0 h1:MHn1GuSZkxvVEDMyAPqlc7A3cOW+q8RcGhRgH/xtm6I=
gitea.com/lunny/levelqueue v0.3.0/go.mod h1:HBqmLbz56JWpfEGG0prskAV97ATNRoj5LDmPicD22hU=
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s=
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU=
github.com/6543/go-version v1.3.1 h1:HvOp+Telns7HWJ2Xo/05YXQSB2bE0WmVgbHqwMPZT4U=
@@ -241,6 +241,7 @@ github.com/denisenkom/go-mssqldb v0.0.0-20200428022330-06a60b6afbbc/go.mod h1:xb
github.com/denisenkom/go-mssqldb v0.9.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
github.com/denisenkom/go-mssqldb v0.10.0 h1:QykgLZBorFE95+gO3u9esLd0BmbvpWp0/waNNZfHBM8=
github.com/denisenkom/go-mssqldb v0.10.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
@@ -475,8 +476,6 @@ github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14 h1:yXtpJr/LV6PFu4nTLgfjQ
github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14/go.mod h1:jPoNZLWDAqA5N3G5amEoiNbhVrmM+ZQEcnQvNQ2KaZk=
github.com/gogs/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85 h1:UjoPNDAQ5JPCjlxoJd6K8ALZqSDDhk2ymieAZOVaDg0=
github.com/gogs/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85/go.mod h1:fR6z1Ie6rtF7kl/vBYMfgD5/G5B1blui7z426/sj2DU=
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
@@ -763,8 +762,8 @@ github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJ
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/markbates/going v1.0.0/go.mod h1:I6mnB4BPnEeqo85ynXIx1ZFLLbtiLHNXVgWeFO9OGOA=
github.com/markbates/goth v1.68.0 h1:90sKvjRAKHcl9V2uC9x/PJXeD78cFPiBsyP1xVhoQfA=
github.com/markbates/goth v1.68.0/go.mod h1:V2VcDMzDiMHW+YmqYl7i0cMiAUeCkAe4QE6jRKBhXZw=
github.com/markbates/goth v1.67.1 h1:gU5B0pzHVyhnJPwGynfFnkfvaQ39C1Sy+ewdl+bhAOw=
github.com/markbates/goth v1.67.1/go.mod h1:EyLFHGU5ySr2GXRDyJH5nu2dA7parbC8QwIYW/rGcWg=
github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE=
github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A=
-54
View File
@@ -144,60 +144,6 @@ func TestLDAPUserSignin(t *testing.T) {
assert.Equal(t, u.Email, htmlDoc.Find(`label[for="email"]`).Siblings().First().Text())
}
func TestLDAPAuthChange(t *testing.T) {
defer prepareTestEnv(t)()
addAuthSourceLDAP(t, "")
session := loginUser(t, "user1")
req := NewRequest(t, "GET", "/admin/auths")
resp := session.MakeRequest(t, req, http.StatusOK)
doc := NewHTMLParser(t, resp.Body)
href, exists := doc.Find("table.table td a").Attr("href")
if !exists {
assert.True(t, exists, "No authentication source found")
return
}
req = NewRequest(t, "GET", href)
resp = session.MakeRequest(t, req, http.StatusOK)
doc = NewHTMLParser(t, resp.Body)
csrf := doc.GetCSRF()
host, _ := doc.Find(`input[name="host"]`).Attr("value")
assert.Equal(t, host, getLDAPServerHost())
binddn, _ := doc.Find(`input[name="bind_dn"]`).Attr("value")
assert.Equal(t, binddn, "uid=gitea,ou=service,dc=planetexpress,dc=com")
req = NewRequestWithValues(t, "POST", href, map[string]string{
"_csrf": csrf,
"type": "2",
"name": "ldap",
"host": getLDAPServerHost(),
"port": "389",
"bind_dn": "uid=gitea,ou=service,dc=planetexpress,dc=com",
"bind_password": "password",
"user_base": "ou=people,dc=planetexpress,dc=com",
"filter": "(&(objectClass=inetOrgPerson)(memberOf=cn=git,ou=people,dc=planetexpress,dc=com)(uid=%s))",
"admin_filter": "(memberOf=cn=admin_staff,ou=people,dc=planetexpress,dc=com)",
"restricted_filter": "(uid=leela)",
"attribute_username": "uid",
"attribute_name": "givenName",
"attribute_surname": "sn",
"attribute_mail": "mail",
"attribute_ssh_public_key": "",
"is_sync_enabled": "on",
"is_active": "on",
})
session.MakeRequest(t, req, http.StatusFound)
req = NewRequest(t, "GET", href)
resp = session.MakeRequest(t, req, http.StatusOK)
doc = NewHTMLParser(t, resp.Body)
host, _ = doc.Find(`input[name="host"]`).Attr("value")
assert.Equal(t, host, getLDAPServerHost())
binddn, _ = doc.Find(`input[name="bind_dn"]`).Attr("value")
assert.Equal(t, binddn, "uid=gitea,ou=service,dc=planetexpress,dc=com")
}
func TestLDAPUserSync(t *testing.T) {
if skipLDAPTests() {
t.Skip()
@@ -1 +1 @@
0dca5bd9b5d7ef937710e056f575e86c0184ba85
423313fbd38093bb10d0c8387db9105409c6f196
+1 -1
View File
@@ -160,7 +160,7 @@ func getLatestCommitStatus(e Engine, repoID int64, sha string, listOptions ListO
if len(ids) == 0 {
return statuses, nil
}
return statuses, e.In("id", ids).Find(&statuses)
return statuses, x.In("id", ids).Find(&statuses)
}
// FindRepoRecentCommitStatusContexts returns repository's recent commit status contexts
+15 -45
View File
@@ -9,8 +9,6 @@ import (
"time"
"code.gitea.io/gitea/modules/timeutil"
"xorm.io/xorm"
)
// Stopwatch represents a stopwatch for time tracking.
@@ -63,12 +61,8 @@ func StopwatchExists(userID, issueID int64) bool {
// HasUserStopwatch returns true if the user has a stopwatch
func HasUserStopwatch(userID int64) (exists bool, sw *Stopwatch, err error) {
return hasUserStopwatch(x, userID)
}
func hasUserStopwatch(e Engine, userID int64) (exists bool, sw *Stopwatch, err error) {
sw = new(Stopwatch)
exists, err = e.
exists, err = x.
Where("user_id = ?", userID).
Get(sw)
return
@@ -76,23 +70,11 @@ func hasUserStopwatch(e Engine, userID int64) (exists bool, sw *Stopwatch, err e
// CreateOrStopIssueStopwatch will create or remove a stopwatch and will log it into issue's timeline.
func CreateOrStopIssueStopwatch(user *User, issue *Issue) error {
sess := x.NewSession()
defer sess.Close()
if err := sess.Begin(); err != nil {
return err
}
if err := createOrStopIssueStopwatch(sess, user, issue); err != nil {
return err
}
return sess.Commit()
}
func createOrStopIssueStopwatch(e *xorm.Session, user *User, issue *Issue) error {
sw, exists, err := getStopwatch(e, user.ID, issue.ID)
sw, exists, err := getStopwatch(x, user.ID, issue.ID)
if err != nil {
return err
}
if err := issue.loadRepo(e); err != nil {
if err := issue.loadRepo(x); err != nil {
return err
}
@@ -108,11 +90,11 @@ func createOrStopIssueStopwatch(e *xorm.Session, user *User, issue *Issue) error
Time: timediff,
}
if _, err := e.Insert(tt); err != nil {
if _, err := x.Insert(tt); err != nil {
return err
}
if _, err := createComment(e, &CreateCommentOptions{
if _, err := CreateComment(&CreateCommentOptions{
Doer: user,
Issue: issue,
Repo: issue.Repo,
@@ -122,21 +104,21 @@ func createOrStopIssueStopwatch(e *xorm.Session, user *User, issue *Issue) error
}); err != nil {
return err
}
if _, err := e.Delete(sw); err != nil {
if _, err := x.Delete(sw); err != nil {
return err
}
} else {
// if another stopwatch is running: stop it
exists, sw, err := hasUserStopwatch(e, user.ID)
exists, sw, err := HasUserStopwatch(user.ID)
if err != nil {
return err
}
if exists {
issue, err := getIssueByID(e, sw.IssueID)
issue, err := getIssueByID(x, sw.IssueID)
if err != nil {
return err
}
if err := createOrStopIssueStopwatch(e, user, issue); err != nil {
if err := CreateOrStopIssueStopwatch(user, issue); err != nil {
return err
}
}
@@ -147,11 +129,11 @@ func createOrStopIssueStopwatch(e *xorm.Session, user *User, issue *Issue) error
IssueID: issue.ID,
}
if _, err := e.Insert(sw); err != nil {
if _, err := x.Insert(sw); err != nil {
return err
}
if _, err := createComment(e, &CreateCommentOptions{
if _, err := CreateComment(&CreateCommentOptions{
Doer: user,
Issue: issue,
Repo: issue.Repo,
@@ -165,33 +147,21 @@ func createOrStopIssueStopwatch(e *xorm.Session, user *User, issue *Issue) error
// CancelStopwatch removes the given stopwatch and logs it into issue's timeline.
func CancelStopwatch(user *User, issue *Issue) error {
sess := x.NewSession()
defer sess.Close()
if err := sess.Begin(); err != nil {
return err
}
if err := cancelStopwatch(sess, user, issue); err != nil {
return err
}
return sess.Commit()
}
func cancelStopwatch(e *xorm.Session, user *User, issue *Issue) error {
sw, exists, err := getStopwatch(e, user.ID, issue.ID)
sw, exists, err := getStopwatch(x, user.ID, issue.ID)
if err != nil {
return err
}
if exists {
if _, err := e.Delete(sw); err != nil {
if _, err := x.Delete(sw); err != nil {
return err
}
if err := issue.loadRepo(e); err != nil {
if err := issue.loadRepo(x); err != nil {
return err
}
if _, err := createComment(e, &CreateCommentOptions{
if _, err := CreateComment(&CreateCommentOptions{
Doer: user,
Issue: issue,
Repo: issue.Repo,
+10 -30
View File
@@ -7,7 +7,6 @@ package models
import (
"crypto/tls"
"encoding/binary"
"errors"
"fmt"
"net/smtp"
@@ -71,32 +70,13 @@ var (
_ convert.Conversion = &SSPIConfig{}
)
// jsonUnmarshalHandleDoubleEncode - due to a bug in xorm (see https://gitea.com/xorm/xorm/pulls/1957) - it's
// possible that a Blob may be double encoded or gain an unwanted prefix of 0xff 0xfe.
func jsonUnmarshalHandleDoubleEncode(bs []byte, v interface{}) error {
// jsonUnmarshalIgnoreErroneousBOM - due to a bug in xorm (see https://gitea.com/xorm/xorm/pulls/1957) - it's
// possible that a Blob may gain an unwanted prefix of 0xff 0xfe.
func jsonUnmarshalIgnoreErroneousBOM(bs []byte, v interface{}) error {
json := jsoniter.ConfigCompatibleWithStandardLibrary
err := json.Unmarshal(bs, v)
if err != nil {
ok := true
rs := []byte{}
temp := make([]byte, 2)
for _, rn := range string(bs) {
if rn > 0xffff {
ok = false
break
}
binary.LittleEndian.PutUint16(temp, uint16(rn))
rs = append(rs, temp...)
}
if ok {
if rs[0] == 0xff && rs[1] == 0xfe {
rs = rs[2:]
}
err = json.Unmarshal(rs, v)
}
}
err := json.Unmarshal(bs, &v)
if err != nil && len(bs) > 2 && bs[0] == 0xff && bs[1] == 0xfe {
err = json.Unmarshal(bs[2:], v)
err = json.Unmarshal(bs[2:], &v)
}
return err
}
@@ -108,7 +88,7 @@ type LDAPConfig struct {
// FromDB fills up a LDAPConfig from serialized format.
func (cfg *LDAPConfig) FromDB(bs []byte) error {
err := jsonUnmarshalHandleDoubleEncode(bs, &cfg)
err := jsonUnmarshalIgnoreErroneousBOM(bs, &cfg)
if err != nil {
return err
}
@@ -149,7 +129,7 @@ type SMTPConfig struct {
// FromDB fills up an SMTPConfig from serialized format.
func (cfg *SMTPConfig) FromDB(bs []byte) error {
return jsonUnmarshalHandleDoubleEncode(bs, cfg)
return jsonUnmarshalIgnoreErroneousBOM(bs, cfg)
}
// ToDB exports an SMTPConfig to a serialized format.
@@ -166,7 +146,7 @@ type PAMConfig struct {
// FromDB fills up a PAMConfig from serialized format.
func (cfg *PAMConfig) FromDB(bs []byte) error {
return jsonUnmarshalHandleDoubleEncode(bs, cfg)
return jsonUnmarshalIgnoreErroneousBOM(bs, cfg)
}
// ToDB exports a PAMConfig to a serialized format.
@@ -187,7 +167,7 @@ type OAuth2Config struct {
// FromDB fills up an OAuth2Config from serialized format.
func (cfg *OAuth2Config) FromDB(bs []byte) error {
return jsonUnmarshalHandleDoubleEncode(bs, cfg)
return jsonUnmarshalIgnoreErroneousBOM(bs, cfg)
}
// ToDB exports an SMTPConfig to a serialized format.
@@ -207,7 +187,7 @@ type SSPIConfig struct {
// FromDB fills up an SSPIConfig from serialized format.
func (cfg *SSPIConfig) FromDB(bs []byte) error {
return jsonUnmarshalHandleDoubleEncode(bs, cfg)
return jsonUnmarshalIgnoreErroneousBOM(bs, cfg)
}
// ToDB exports an SSPIConfig to a serialized format.
+5
View File
@@ -155,6 +155,11 @@ func initOAuth2LoginSources() error {
err := oauth2.RegisterProvider(source.Name, oAuth2Config.Provider, oAuth2Config.ClientID, oAuth2Config.ClientSecret, oAuth2Config.OpenIDConnectAutoDiscoveryURL, oAuth2Config.CustomURLMapping)
if err != nil {
log.Critical("Unable to register source: %s due to Error: %v. This source will be disabled.", source.Name, err)
source.IsActived = false
if err = UpdateSource(source); err != nil {
log.Critical("Unable to update source %s to disable it. Error: %v", err)
return err
}
}
}
return nil
+1 -1
View File
@@ -17,7 +17,7 @@ import (
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util"
"github.com/golang-jwt/jwt"
"github.com/dgrijalva/jwt-go"
uuid "github.com/google/uuid"
"golang.org/x/crypto/bcrypt"
"xorm.io/xorm"
+3 -14
View File
@@ -1125,7 +1125,7 @@ func CreateRepository(ctx DBContext, doer, u *User, repo *Repository, overwriteO
// Give access to all members in teams with access to all repositories.
if u.IsOrganization() {
if err := u.getTeams(ctx.e); err != nil {
if err := u.GetTeams(&SearchTeamOptions{}); err != nil {
return fmt.Errorf("GetTeams: %v", err)
}
for _, t := range u.Teams {
@@ -1152,16 +1152,6 @@ func CreateRepository(ctx DBContext, doer, u *User, repo *Repository, overwriteO
return fmt.Errorf("recalculateAccesses: %v", err)
}
if u.Visibility == api.VisibleTypePublic && !repo.IsPrivate {
// Create/Remove git-daemon-export-ok for git-daemon...
daemonExportFile := path.Join(repo.RepoPath(), `git-daemon-export-ok`)
if f, err := os.Create(daemonExportFile); err != nil {
log.Error("Failed to create %s: %v", daemonExportFile, err)
} else {
f.Close()
}
}
if setting.Service.AutoWatchNewRepos {
if err = watchRepo(ctx.e, doer.ID, repo.ID, true); err != nil {
return fmt.Errorf("watchRepo: %v", err)
@@ -1320,16 +1310,15 @@ func updateRepository(e Engine, repo *Repository, visibilityChanged bool) (err e
// Create/Remove git-daemon-export-ok for git-daemon...
daemonExportFile := path.Join(repo.RepoPath(), `git-daemon-export-ok`)
isExist, err := util.IsExist(daemonExportFile)
isPublic := !repo.IsPrivate && repo.Owner.Visibility == api.VisibleTypePublic
if err != nil {
log.Error("Unable to check if %s exists. Error: %v", daemonExportFile, err)
return err
}
if !isPublic && isExist {
if repo.IsPrivate && isExist {
if err = util.Remove(daemonExportFile); err != nil {
log.Error("Failed to remove %s: %v", daemonExportFile, err)
}
} else if isPublic && !isExist {
} else if !repo.IsPrivate && !isExist {
if f, err := os.Create(daemonExportFile); err != nil {
log.Error("Failed to create %s: %v", daemonExportFile, err)
} else {
+5 -3
View File
@@ -217,14 +217,16 @@ func SearchRepositoryCondition(opts *SearchRepoOptions) builder.Cond {
cond = cond.And(accessibleRepositoryCondition(opts.Actor))
}
} else {
// Not looking at private organisations and users
// Not looking at private organisations
// We should be able to see all non-private repositories that
// isn't in a private or limited organisation.
cond = cond.And(
builder.Eq{"is_private": false},
builder.NotIn("owner_id", builder.Select("id").From("`user`").Where(
builder.Or(builder.Eq{"visibility": structs.VisibleTypeLimited}, builder.Eq{"visibility": structs.VisibleTypePrivate}),
)))
builder.And(
builder.Eq{"type": UserTypeOrganization},
builder.Or(builder.Eq{"visibility": structs.VisibleTypeLimited}, builder.Eq{"visibility": structs.VisibleTypePrivate}),
))))
}
if opts.IsPrivate != util.OptionalBoolNone {
+5 -5
View File
@@ -28,7 +28,7 @@ type UnitConfig struct{}
// FromDB fills up a UnitConfig from serialized format.
func (cfg *UnitConfig) FromDB(bs []byte) error {
return jsonUnmarshalHandleDoubleEncode(bs, &cfg)
return jsonUnmarshalIgnoreErroneousBOM(bs, &cfg)
}
// ToDB exports a UnitConfig to a serialized format.
@@ -44,7 +44,7 @@ type ExternalWikiConfig struct {
// FromDB fills up a ExternalWikiConfig from serialized format.
func (cfg *ExternalWikiConfig) FromDB(bs []byte) error {
return jsonUnmarshalHandleDoubleEncode(bs, &cfg)
return jsonUnmarshalIgnoreErroneousBOM(bs, &cfg)
}
// ToDB exports a ExternalWikiConfig to a serialized format.
@@ -62,7 +62,7 @@ type ExternalTrackerConfig struct {
// FromDB fills up a ExternalTrackerConfig from serialized format.
func (cfg *ExternalTrackerConfig) FromDB(bs []byte) error {
return jsonUnmarshalHandleDoubleEncode(bs, &cfg)
return jsonUnmarshalIgnoreErroneousBOM(bs, &cfg)
}
// ToDB exports a ExternalTrackerConfig to a serialized format.
@@ -80,7 +80,7 @@ type IssuesConfig struct {
// FromDB fills up a IssuesConfig from serialized format.
func (cfg *IssuesConfig) FromDB(bs []byte) error {
return jsonUnmarshalHandleDoubleEncode(bs, &cfg)
return jsonUnmarshalIgnoreErroneousBOM(bs, &cfg)
}
// ToDB exports a IssuesConfig to a serialized format.
@@ -104,7 +104,7 @@ type PullRequestsConfig struct {
// FromDB fills up a PullRequestsConfig from serialized format.
func (cfg *PullRequestsConfig) FromDB(bs []byte) error {
return jsonUnmarshalHandleDoubleEncode(bs, &cfg)
return jsonUnmarshalIgnoreErroneousBOM(bs, &cfg)
}
// ToDB exports a PullRequestsConfig to a serialized format.
+1 -1
View File
@@ -25,7 +25,7 @@ import (
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"
"github.com/golang-jwt/jwt"
"github.com/dgrijalva/jwt-go"
ini "gopkg.in/ini.v1"
)
-21
View File
@@ -7,7 +7,6 @@ package oauth2
import (
"net/http"
"net/url"
"sync"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
@@ -35,7 +34,6 @@ import (
var (
sessionUsersStoreKey = "gitea-oauth2-sessions"
providerHeaderKey = "gitea-oauth2-provider"
gothRWMutex = sync.RWMutex{}
)
// CustomURLMapping describes the urls values to use when customizing OAuth2 provider URLs
@@ -62,10 +60,6 @@ func Init(x *xorm.Engine) error {
// Note, when using the FilesystemStore only the session.ID is written to a browser cookie, so this is explicit for the storage on disk
store.MaxLength(setting.OAuth2.MaxTokenLength)
gothRWMutex.Lock()
defer gothRWMutex.Unlock()
gothic.Store = store
gothic.SetState = func(req *http.Request) string {
@@ -88,9 +82,6 @@ func Auth(provider string, request *http.Request, response http.ResponseWriter)
// normally the gothic library will write some custom stuff to the response instead of our own nice error page
//gothic.BeginAuthHandler(response, request)
gothRWMutex.RLock()
defer gothRWMutex.RUnlock()
url, err := gothic.GetAuthURL(response, request)
if err == nil {
http.Redirect(response, request, url, http.StatusTemporaryRedirect)
@@ -104,9 +95,6 @@ func ProviderCallback(provider string, request *http.Request, response http.Resp
// not sure if goth is thread safe (?) when using multiple providers
request.Header.Set(providerHeaderKey, provider)
gothRWMutex.RLock()
defer gothRWMutex.RUnlock()
user, err := gothic.CompleteUserAuth(response, request)
if err != nil {
return user, err
@@ -120,9 +108,6 @@ func RegisterProvider(providerName, providerType, clientID, clientSecret, openID
provider, err := createProvider(providerName, providerType, clientID, clientSecret, openIDConnectAutoDiscoveryURL, customURLMapping)
if err == nil && provider != nil {
gothRWMutex.Lock()
defer gothRWMutex.Unlock()
goth.UseProviders(provider)
}
@@ -131,17 +116,11 @@ func RegisterProvider(providerName, providerType, clientID, clientSecret, openID
// RemoveProvider removes the given OAuth2 provider from the goth lib
func RemoveProvider(providerName string) {
gothRWMutex.Lock()
defer gothRWMutex.Unlock()
delete(goth.GetProviders(), providerName)
}
// ClearProviders clears all OAuth2 providers from the goth lib
func ClearProviders() {
gothRWMutex.Lock()
defer gothRWMutex.Unlock()
goth.ClearProviders()
}
+4 -6
View File
@@ -6,7 +6,6 @@ package context
import (
"bytes"
"context"
"html/template"
"net/http"
"time"
@@ -23,8 +22,6 @@ type routerLoggerOptions struct {
Ctx map[string]interface{}
}
var signedUserNameStringPointerKey interface{} = "signedUserNameStringPointerKey"
// AccessLogger returns a middleware to log access logger
func AccessLogger() func(http.Handler) http.Handler {
logger := log.GetLogger("access")
@@ -32,10 +29,11 @@ func AccessLogger() func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
start := time.Now()
next.ServeHTTP(w, req)
identity := "-"
r := req.WithContext(context.WithValue(req.Context(), signedUserNameStringPointerKey, &identity))
next.ServeHTTP(w, r)
if val := SignedUserName(req); val != "" {
identity = val
}
rw := w.(ResponseWriter)
buf := bytes.NewBuffer([]byte{})
-11
View File
@@ -275,17 +275,6 @@ func APIContexter() func(http.Handler) http.Handler {
ctx.Data["CsrfToken"] = html.EscapeString(ctx.csrf.GetToken())
next.ServeHTTP(ctx.Resp, ctx.Req)
// Handle adding signedUserName to the context for the AccessLogger
usernameInterface := ctx.Data["SignedUserName"]
identityPtrInterface := ctx.Req.Context().Value(signedUserNameStringPointerKey)
if usernameInterface != nil && identityPtrInterface != nil {
username := usernameInterface.(string)
identityPtr := identityPtrInterface.(*string)
if identityPtr != nil && username != "" {
*identityPtr = username
}
}
})
}
}
-11
View File
@@ -774,17 +774,6 @@ func Contexter() func(next http.Handler) http.Handler {
}
next.ServeHTTP(ctx.Resp, ctx.Req)
// Handle adding signedUserName to the context for the AccessLogger
usernameInterface := ctx.Data["SignedUserName"]
identityPtrInterface := ctx.Req.Context().Value(signedUserNameStringPointerKey)
if usernameInterface != nil && identityPtrInterface != nil {
username := usernameInterface.(string)
identityPtr := identityPtrInterface.(*string)
if identityPtr != nil && username != "" {
*identityPtr = username
}
}
})
}
}
+7 -7
View File
@@ -36,7 +36,7 @@ func registerRepoHealthCheck() {
BaseConfig: BaseConfig{
Enabled: true,
RunAtStart: false,
Schedule: "@every 24h",
Schedule: "@midnight",
},
Timeout: 60 * time.Second,
Args: []string{},
@@ -50,7 +50,7 @@ func registerCheckRepoStats() {
RegisterTaskFatal("check_repo_stats", &BaseConfig{
Enabled: true,
RunAtStart: true,
Schedule: "@every 24h",
Schedule: "@midnight",
}, func(ctx context.Context, _ *models.User, _ Config) error {
return models.CheckRepoStats(ctx)
})
@@ -61,7 +61,7 @@ func registerArchiveCleanup() {
BaseConfig: BaseConfig{
Enabled: true,
RunAtStart: true,
Schedule: "@every 24h",
Schedule: "@midnight",
},
OlderThan: 24 * time.Hour,
}, func(ctx context.Context, _ *models.User, config Config) error {
@@ -75,7 +75,7 @@ func registerSyncExternalUsers() {
BaseConfig: BaseConfig{
Enabled: true,
RunAtStart: false,
Schedule: "@every 24h",
Schedule: "@midnight",
},
UpdateExisting: true,
}, func(ctx context.Context, _ *models.User, config Config) error {
@@ -89,7 +89,7 @@ func registerDeletedBranchesCleanup() {
BaseConfig: BaseConfig{
Enabled: true,
RunAtStart: true,
Schedule: "@every 24h",
Schedule: "@midnight",
},
OlderThan: 24 * time.Hour,
}, func(ctx context.Context, _ *models.User, config Config) error {
@@ -103,7 +103,7 @@ func registerUpdateMigrationPosterID() {
RegisterTaskFatal("update_migration_poster_id", &BaseConfig{
Enabled: true,
RunAtStart: true,
Schedule: "@every 24h",
Schedule: "@midnight",
}, func(ctx context.Context, _ *models.User, _ Config) error {
return migrations.UpdateMigrationPosterID(ctx)
})
@@ -114,7 +114,7 @@ func registerCleanupHookTaskTable() {
BaseConfig: BaseConfig{
Enabled: true,
RunAtStart: false,
Schedule: "@every 24h",
Schedule: "@midnight",
},
CleanupType: "OlderThan",
OlderThan: 168 * time.Hour,
-73
View File
@@ -6,9 +6,7 @@ package doctor
import (
"fmt"
"os"
"os/exec"
"path"
"strings"
"code.gitea.io/gitea/models"
@@ -16,9 +14,6 @@ import (
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/repository"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util"
lru "github.com/hashicorp/golang-lru"
"xorm.io/builder"
)
@@ -80,7 +75,6 @@ func checkUserStarNum(logger log.Logger, autofix bool) error {
func checkEnablePushOptions(logger log.Logger, autofix bool) error {
numRepos := 0
numNeedUpdate := 0
if err := iterateRepositories(func(repo *models.Repository) error {
numRepos++
r, err := git.OpenRepository(repo.RepoPath())
@@ -120,66 +114,6 @@ func checkEnablePushOptions(logger log.Logger, autofix bool) error {
return nil
}
func checkDaemonExport(logger log.Logger, autofix bool) error {
numRepos := 0
numNeedUpdate := 0
cache, err := lru.New(512)
if err != nil {
logger.Critical("Unable to create cache: %v", err)
return err
}
if err := iterateRepositories(func(repo *models.Repository) error {
numRepos++
if owner, has := cache.Get(repo.OwnerID); has {
repo.Owner = owner.(*models.User)
} else {
if err := repo.GetOwner(); err != nil {
return err
}
cache.Add(repo.OwnerID, repo.Owner)
}
// Create/Remove git-daemon-export-ok for git-daemon...
daemonExportFile := path.Join(repo.RepoPath(), `git-daemon-export-ok`)
isExist, err := util.IsExist(daemonExportFile)
if err != nil {
log.Error("Unable to check if %s exists. Error: %v", daemonExportFile, err)
return err
}
isPublic := !repo.IsPrivate && repo.Owner.Visibility == structs.VisibleTypePublic
if isPublic != isExist {
numNeedUpdate++
if autofix {
if !isPublic && isExist {
if err = util.Remove(daemonExportFile); err != nil {
log.Error("Failed to remove %s: %v", daemonExportFile, err)
}
} else if isPublic && !isExist {
if f, err := os.Create(daemonExportFile); err != nil {
log.Error("Failed to create %s: %v", daemonExportFile, err)
} else {
f.Close()
}
}
}
}
return nil
}); err != nil {
logger.Critical("Unable to checkDaemonExport: %v", err)
return err
}
if autofix {
logger.Info("Updated git-daemon-export-ok files for %d of %d repositories.", numNeedUpdate, numRepos)
} else {
logger.Info("Checked %d repositories, %d need updates.", numRepos, numNeedUpdate)
}
return nil
}
func init() {
Register(&Check{
Title: "Check if SCRIPT_TYPE is available",
@@ -209,11 +143,4 @@ func init() {
Run: checkEnablePushOptions,
Priority: 7,
})
Register(&Check{
Title: "Check git-daemon-export-ok files",
Name: "check-git-daemon-export-ok",
IsDefault: false,
Run: checkDaemonExport,
Priority: 8,
})
}
+1 -2
View File
@@ -12,8 +12,7 @@ import (
"time"
"code.gitea.io/gitea/modules/util"
"github.com/golang-jwt/jwt"
"github.com/dgrijalva/jwt-go"
)
// NewInternalToken generate a new value intended to be used by INTERNAL_TOKEN.
+2 -13
View File
@@ -7,7 +7,6 @@ package git
import (
"bufio"
"bytes"
"context"
"io"
"math"
"strconv"
@@ -29,20 +28,16 @@ type WriteCloserError interface {
func CatFileBatchCheck(repoPath string) (WriteCloserError, *bufio.Reader, func()) {
batchStdinReader, batchStdinWriter := io.Pipe()
batchStdoutReader, batchStdoutWriter := io.Pipe()
ctx, ctxCancel := context.WithCancel(DefaultContext)
closed := make(chan struct{})
cancel := func() {
_ = batchStdinReader.Close()
_ = batchStdinWriter.Close()
_ = batchStdoutReader.Close()
_ = batchStdoutWriter.Close()
ctxCancel()
<-closed
}
go func() {
stderr := strings.Builder{}
err := NewCommandContext(ctx, "cat-file", "--batch-check").RunInDirFullPipeline(repoPath, batchStdoutWriter, &stderr, batchStdinReader)
err := NewCommand("cat-file", "--batch-check").RunInDirFullPipeline(repoPath, batchStdoutWriter, &stderr, batchStdinReader)
if err != nil {
_ = batchStdoutWriter.CloseWithError(ConcatenateError(err, (&stderr).String()))
_ = batchStdinReader.CloseWithError(ConcatenateError(err, (&stderr).String()))
@@ -50,7 +45,6 @@ func CatFileBatchCheck(repoPath string) (WriteCloserError, *bufio.Reader, func()
_ = batchStdoutWriter.Close()
_ = batchStdinReader.Close()
}
close(closed)
}()
// For simplicities sake we'll use a buffered reader to read from the cat-file --batch-check
@@ -65,20 +59,16 @@ func CatFileBatch(repoPath string) (WriteCloserError, *bufio.Reader, func()) {
// so let's create a batch stdin and stdout
batchStdinReader, batchStdinWriter := io.Pipe()
batchStdoutReader, batchStdoutWriter := nio.Pipe(buffer.New(32 * 1024))
ctx, ctxCancel := context.WithCancel(DefaultContext)
closed := make(chan struct{})
cancel := func() {
_ = batchStdinReader.Close()
_ = batchStdinWriter.Close()
_ = batchStdoutReader.Close()
_ = batchStdoutWriter.Close()
ctxCancel()
<-closed
}
go func() {
stderr := strings.Builder{}
err := NewCommandContext(ctx, "cat-file", "--batch").RunInDirFullPipeline(repoPath, batchStdoutWriter, &stderr, batchStdinReader)
err := NewCommand("cat-file", "--batch").RunInDirFullPipeline(repoPath, batchStdoutWriter, &stderr, batchStdinReader)
if err != nil {
_ = batchStdoutWriter.CloseWithError(ConcatenateError(err, (&stderr).String()))
_ = batchStdinReader.CloseWithError(ConcatenateError(err, (&stderr).String()))
@@ -86,7 +76,6 @@ func CatFileBatch(repoPath string) (WriteCloserError, *bufio.Reader, func()) {
_ = batchStdoutWriter.Close()
_ = batchStdinReader.Close()
}
close(closed)
}()
// For simplicities sake we'll us a buffered reader to read from the cat-file --batch
-21
View File
@@ -6,7 +6,6 @@
package git
import (
"bytes"
"strings"
)
@@ -46,23 +45,3 @@ func (t *Tree) SubTree(rpath string) (*Tree, error) {
}
return g, nil
}
// LsTree checks if the given filenames are in the tree
func (repo *Repository) LsTree(ref string, filenames ...string) ([]string, error) {
cmd := NewCommand("ls-tree", "-z", "--name-only", "--", ref)
for _, arg := range filenames {
if arg != "" {
cmd.AddArguments(arg)
}
}
res, err := cmd.RunInDirBytes(repo.Path)
if err != nil {
return nil, err
}
filelist := make([]string, 0, len(filenames))
for _, line := range bytes.Split(res, []byte{'\000'}) {
filelist = append(filelist, string(line))
}
return filelist, err
}
-59
View File
@@ -1,59 +0,0 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package bleve
import (
"github.com/blevesearch/bleve/v2"
)
// FlushingBatch is a batch of operations that automatically flushes to the
// underlying index once it reaches a certain size.
type FlushingBatch struct {
maxBatchSize int
batch *bleve.Batch
index bleve.Index
}
// NewFlushingBatch creates a new flushing batch for the specified index. Once
// the number of operations in the batch reaches the specified limit, the batch
// automatically flushes its operations to the index.
func NewFlushingBatch(index bleve.Index, maxBatchSize int) *FlushingBatch {
return &FlushingBatch{
maxBatchSize: maxBatchSize,
batch: index.NewBatch(),
index: index,
}
}
// Index add a new index to batch
func (b *FlushingBatch) Index(id string, data interface{}) error {
if err := b.batch.Index(id, data); err != nil {
return err
}
return b.flushIfFull()
}
// Delete add a delete index to batch
func (b *FlushingBatch) Delete(id string) error {
b.batch.Delete(id)
return b.flushIfFull()
}
func (b *FlushingBatch) flushIfFull() error {
if b.batch.Size() < b.maxBatchSize {
return nil
}
return b.Flush()
}
// Flush submit the batch and create a new one
func (b *FlushingBatch) Flush() error {
err := b.index.Batch(b.batch)
if err != nil {
return err
}
b.batch = b.index.NewBatch()
return nil
}
+4 -6
View File
@@ -18,7 +18,6 @@ import (
"code.gitea.io/gitea/modules/analyze"
"code.gitea.io/gitea/modules/charset"
"code.gitea.io/gitea/modules/git"
gitea_bleve "code.gitea.io/gitea/modules/indexer/bleve"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/timeutil"
@@ -177,8 +176,7 @@ func NewBleveIndexer(indexDir string) (*BleveIndexer, bool, error) {
return indexer, created, err
}
func (b *BleveIndexer) addUpdate(batchWriter git.WriteCloserError, batchReader *bufio.Reader, commitSha string,
update fileUpdate, repo *models.Repository, batch *gitea_bleve.FlushingBatch) error {
func (b *BleveIndexer) addUpdate(batchWriter git.WriteCloserError, batchReader *bufio.Reader, commitSha string, update fileUpdate, repo *models.Repository, batch rupture.FlushingBatch) error {
// Ignore vendored files in code search
if setting.Indexer.ExcludeVendored && analyze.IsVendor(update.Filename) {
return nil
@@ -231,7 +229,7 @@ func (b *BleveIndexer) addUpdate(batchWriter git.WriteCloserError, batchReader *
})
}
func (b *BleveIndexer) addDelete(filename string, repo *models.Repository, batch *gitea_bleve.FlushingBatch) error {
func (b *BleveIndexer) addDelete(filename string, repo *models.Repository, batch rupture.FlushingBatch) error {
id := filenameIndexerID(repo.ID, filename)
return batch.Delete(id)
}
@@ -269,7 +267,7 @@ func (b *BleveIndexer) Close() {
// Index indexes the data
func (b *BleveIndexer) Index(repo *models.Repository, sha string, changes *repoChanges) error {
batch := gitea_bleve.NewFlushingBatch(b.indexer, maxBatchSize)
batch := rupture.NewFlushingBatch(b.indexer, maxBatchSize)
if len(changes.Updates) > 0 {
batchWriter, batchReader, cancel := git.CatFileBatch(repo.RepoPath())
@@ -298,7 +296,7 @@ func (b *BleveIndexer) Delete(repoID int64) error {
if err != nil {
return err
}
batch := gitea_bleve.NewFlushingBatch(b.indexer, maxBatchSize)
batch := rupture.NewFlushingBatch(b.indexer, maxBatchSize)
for _, hit := range result.Hits {
if err = batch.Delete(hit.ID); err != nil {
return err
+2 -4
View File
@@ -9,10 +9,8 @@ import (
"os"
"strconv"
gitea_bleve "code.gitea.io/gitea/modules/indexer/bleve"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/util"
"github.com/blevesearch/bleve/v2"
"github.com/blevesearch/bleve/v2/analysis/analyzer/custom"
"github.com/blevesearch/bleve/v2/analysis/token/lowercase"
@@ -199,7 +197,7 @@ func (b *BleveIndexer) Close() {
// Index will save the index data
func (b *BleveIndexer) Index(issues []*IndexerData) error {
batch := gitea_bleve.NewFlushingBatch(b.indexer, maxBatchSize)
batch := rupture.NewFlushingBatch(b.indexer, maxBatchSize)
for _, issue := range issues {
if err := batch.Index(indexerID(issue.ID), struct {
RepoID int64
@@ -220,7 +218,7 @@ func (b *BleveIndexer) Index(issues []*IndexerData) error {
// Delete deletes indexes by ids
func (b *BleveIndexer) Delete(ids ...int64) error {
batch := gitea_bleve.NewFlushingBatch(b.indexer, maxBatchSize)
batch := rupture.NewFlushingBatch(b.indexer, maxBatchSize)
for _, id := range ids {
if err := batch.Delete(indexerID(id)); err != nil {
return err
+26 -30
View File
@@ -143,7 +143,7 @@ type MultiChannelledLog struct {
name string
bufferLength int64
queue chan *Event
rwmutex sync.RWMutex
mutex sync.Mutex
loggers map[string]EventLogger
flush chan bool
close chan bool
@@ -173,10 +173,10 @@ func NewMultiChannelledLog(name string, bufferLength int64) *MultiChannelledLog
// AddLogger adds a logger to this MultiChannelledLog
func (m *MultiChannelledLog) AddLogger(logger EventLogger) error {
m.rwmutex.Lock()
m.mutex.Lock()
name := logger.GetName()
if _, has := m.loggers[name]; has {
m.rwmutex.Unlock()
m.mutex.Unlock()
return ErrDuplicateName{name}
}
m.loggers[name] = logger
@@ -186,7 +186,7 @@ func (m *MultiChannelledLog) AddLogger(logger EventLogger) error {
if logger.GetStacktraceLevel() < m.stacktraceLevel {
m.stacktraceLevel = logger.GetStacktraceLevel()
}
m.rwmutex.Unlock()
m.mutex.Unlock()
go m.Start()
return nil
}
@@ -195,15 +195,15 @@ func (m *MultiChannelledLog) AddLogger(logger EventLogger) error {
// NB: If you delete the last sublogger this logger will simply drop
// log events
func (m *MultiChannelledLog) DelLogger(name string) bool {
m.rwmutex.Lock()
m.mutex.Lock()
logger, has := m.loggers[name]
if !has {
m.rwmutex.Unlock()
m.mutex.Unlock()
return false
}
delete(m.loggers, name)
m.internalResetLevel()
m.rwmutex.Unlock()
m.mutex.Unlock()
logger.Flush()
logger.Close()
return true
@@ -211,15 +211,15 @@ func (m *MultiChannelledLog) DelLogger(name string) bool {
// GetEventLogger returns a sub logger from this MultiChannelledLog
func (m *MultiChannelledLog) GetEventLogger(name string) EventLogger {
m.rwmutex.RLock()
defer m.rwmutex.RUnlock()
m.mutex.Lock()
defer m.mutex.Unlock()
return m.loggers[name]
}
// GetEventLoggerNames returns a list of names
func (m *MultiChannelledLog) GetEventLoggerNames() []string {
m.rwmutex.RLock()
defer m.rwmutex.RUnlock()
m.mutex.Lock()
defer m.mutex.Unlock()
var keys []string
for k := range m.loggers {
keys = append(keys, k)
@@ -228,12 +228,12 @@ func (m *MultiChannelledLog) GetEventLoggerNames() []string {
}
func (m *MultiChannelledLog) closeLoggers() {
m.rwmutex.Lock()
m.mutex.Lock()
for _, logger := range m.loggers {
logger.Flush()
logger.Close()
}
m.rwmutex.Unlock()
m.mutex.Unlock()
m.closed <- true
}
@@ -249,8 +249,8 @@ func (m *MultiChannelledLog) Resume() {
// ReleaseReopen causes this logger to tell its subloggers to release and reopen
func (m *MultiChannelledLog) ReleaseReopen() error {
m.rwmutex.Lock()
defer m.rwmutex.Unlock()
m.mutex.Lock()
defer m.mutex.Unlock()
var accumulatedErr error
for _, logger := range m.loggers {
if err := logger.ReleaseReopen(); err != nil {
@@ -266,13 +266,13 @@ func (m *MultiChannelledLog) ReleaseReopen() error {
// Start processing the MultiChannelledLog
func (m *MultiChannelledLog) Start() {
m.rwmutex.Lock()
m.mutex.Lock()
if m.started {
m.rwmutex.Unlock()
m.mutex.Unlock()
return
}
m.started = true
m.rwmutex.Unlock()
m.mutex.Unlock()
paused := false
for {
if paused {
@@ -286,11 +286,11 @@ func (m *MultiChannelledLog) Start() {
m.closeLoggers()
return
}
m.rwmutex.RLock()
m.mutex.Lock()
for _, logger := range m.loggers {
logger.Flush()
}
m.rwmutex.RUnlock()
m.mutex.Unlock()
case <-m.close:
m.closeLoggers()
return
@@ -307,24 +307,24 @@ func (m *MultiChannelledLog) Start() {
m.closeLoggers()
return
}
m.rwmutex.RLock()
m.mutex.Lock()
for _, logger := range m.loggers {
err := logger.LogEvent(event)
if err != nil {
fmt.Println(err)
}
}
m.rwmutex.RUnlock()
m.mutex.Unlock()
case _, ok := <-m.flush:
if !ok {
m.closeLoggers()
return
}
m.rwmutex.RLock()
m.mutex.Lock()
for _, logger := range m.loggers {
logger.Flush()
}
m.rwmutex.RUnlock()
m.mutex.Unlock()
case <-m.close:
m.closeLoggers()
return
@@ -359,15 +359,11 @@ func (m *MultiChannelledLog) Flush() {
// GetLevel gets the level of this MultiChannelledLog
func (m *MultiChannelledLog) GetLevel() Level {
m.rwmutex.RLock()
defer m.rwmutex.RUnlock()
return m.level
}
// GetStacktraceLevel gets the level of this MultiChannelledLog
func (m *MultiChannelledLog) GetStacktraceLevel() Level {
m.rwmutex.RLock()
defer m.rwmutex.RUnlock()
return m.stacktraceLevel
}
@@ -388,8 +384,8 @@ func (m *MultiChannelledLog) internalResetLevel() Level {
// ResetLevel will reset the level of this MultiChannelledLog
func (m *MultiChannelledLog) ResetLevel() Level {
m.rwmutex.Lock()
defer m.rwmutex.Unlock()
m.mutex.Lock()
defer m.mutex.Unlock()
return m.internalResetLevel()
}
+1 -3
View File
@@ -87,9 +87,7 @@ func newParserContext(ctx *markup.RenderContext) parser.Context {
func actualRender(ctx *markup.RenderContext, input io.Reader, output io.Writer) error {
once.Do(func() {
converter = goldmark.New(
goldmark.WithExtensions(
extension.NewTable(
extension.WithTableCellAlignMethod(extension.TableCellAlignAttribute)),
goldmark.WithExtensions(extension.Table,
extension.Strikethrough,
extension.TaskList,
extension.DefinitionList,
+1
View File
@@ -15,6 +15,7 @@ import (
func TestPersistableChannelQueue(t *testing.T) {
handleChan := make(chan *testData)
handle := func(data ...Data) {
assert.True(t, len(data) == 2)
for _, datum := range data {
testDatum := datum.(*testData)
handleChan <- testDatum
+1 -22
View File
@@ -6,13 +6,10 @@ package util
import (
"os"
"runtime"
"syscall"
"time"
)
const windowsSharingViolationError syscall.Errno = 32
// Remove removes the named file or (empty) directory with at most 5 attempts.
func Remove(name string) error {
var err error
@@ -28,12 +25,6 @@ func Remove(name string) error {
continue
}
if unwrapped == windowsSharingViolationError && runtime.GOOS == "windows" {
// try again
<-time.After(100 * time.Millisecond)
continue
}
if unwrapped == syscall.ENOENT {
// it's already gone
return nil
@@ -57,12 +48,6 @@ func RemoveAll(name string) error {
continue
}
if unwrapped == windowsSharingViolationError && runtime.GOOS == "windows" {
// try again
<-time.After(100 * time.Millisecond)
continue
}
if unwrapped == syscall.ENOENT {
// it's already gone
return nil
@@ -79,19 +64,13 @@ func Rename(oldpath, newpath string) error {
if err == nil {
break
}
unwrapped := err.(*os.LinkError).Err
unwrapped := err.(*os.PathError).Err
if unwrapped == syscall.EBUSY || unwrapped == syscall.ENOTEMPTY || unwrapped == syscall.EPERM || unwrapped == syscall.EMFILE || unwrapped == syscall.ENFILE {
// try again
<-time.After(100 * time.Millisecond)
continue
}
if unwrapped == windowsSharingViolationError && runtime.GOOS == "windows" {
// try again
<-time.After(100 * time.Millisecond)
continue
}
if i == 0 && os.IsNotExist(err) {
return err
}
-35
View File
@@ -1,35 +0,0 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package util
import "unicode/utf8"
// SplitStringAtByteN splits a string at byte n accounting for rune boundaries. (Combining characters are not accounted for.)
func SplitStringAtByteN(input string, n int) (left, right string) {
if len(input) <= n {
left = input
return
}
if !utf8.ValidString(input) {
left = input[:n-3] + "..."
right = "..." + input[n-3:]
return
}
// in UTF8 "…" is 3 bytes so doesn't really gain us anything...
end := 0
for end <= n-3 {
_, size := utf8.DecodeRuneInString(input[end:])
if end+size > n-3 {
break
}
end += size
}
left = input[:end] + "…"
right = "…" + input[end:]
return
}
-20
View File
@@ -269,26 +269,6 @@ func (r *Route) Get(pattern string, h ...interface{}) {
r.R.Get(r.getPattern(pattern), Wrap(middlewares...))
}
// Options delegate options method
func (r *Route) Options(pattern string, h ...interface{}) {
var middlewares = r.getMiddlewares(h)
r.R.Options(r.getPattern(pattern), Wrap(middlewares...))
}
// GetOptions delegate get and options method
func (r *Route) GetOptions(pattern string, h ...interface{}) {
var middlewares = r.getMiddlewares(h)
r.R.Get(r.getPattern(pattern), Wrap(middlewares...))
r.R.Options(r.getPattern(pattern), Wrap(middlewares...))
}
// PostOptions delegate post and options method
func (r *Route) PostOptions(pattern string, h ...interface{}) {
var middlewares = r.getMiddlewares(h)
r.R.Post(r.getPattern(pattern), Wrap(middlewares...))
r.R.Options(r.getPattern(pattern), Wrap(middlewares...))
}
// Head delegate head method
func (r *Route) Head(pattern string, h ...interface{}) {
var middlewares = r.getMiddlewares(h)
+6 -6
View File
@@ -12076,9 +12076,9 @@
}
},
"node_modules/tar": {
"version": "6.1.6",
"resolved": "https://registry.npmjs.org/tar/-/tar-6.1.6.tgz",
"integrity": "sha512-oaWyu5dQbHaYcyZCTfyPpC+VmI62/OM2RTUYavTk1MDr1cwW5Boi3baeYQKiZbY2uSQJGr+iMOzb/JFxLrft+g==",
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz",
"integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==",
"dev": true,
"dependencies": {
"chownr": "^2.0.0",
@@ -23018,9 +23018,9 @@
"integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw=="
},
"tar": {
"version": "6.1.6",
"resolved": "https://registry.npmjs.org/tar/-/tar-6.1.6.tgz",
"integrity": "sha512-oaWyu5dQbHaYcyZCTfyPpC+VmI62/OM2RTUYavTk1MDr1cwW5Boi3baeYQKiZbY2uSQJGr+iMOzb/JFxLrft+g==",
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz",
"integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==",
"dev": true,
"requires": {
"chownr": "^2.0.0",
-1
View File
@@ -569,7 +569,6 @@ func Routes() *web.Route {
//setting.CORSConfig.AllowSubdomain // FIXME: the cors middleware needs allowSubdomain option
AllowedMethods: setting.CORSConfig.Methods,
AllowCredentials: setting.CORSConfig.AllowCredentials,
AllowedHeaders: []string{"Authorization", "X-CSRFToken", "X-Gitea-OTP"},
MaxAge: int(setting.CORSConfig.MaxAge.Seconds()),
}))
}
-1
View File
@@ -1254,6 +1254,5 @@ func GetPullRequestCommits(ctx *context.APIContext) {
ctx.Header().Set("X-Total-Count", fmt.Sprintf("%d", totalNumberOfCommits))
ctx.Header().Set("X-PageCount", strconv.Itoa(totalNumberOfPages))
ctx.Header().Set("X-HasMore", strconv.FormatBool(listOptions.Page < totalNumberOfPages))
ctx.Header().Set("Access-Control-Expose-Headers", "X-Total-Count, X-PerPage, X-Total, X-PageCount, X-HasMore, Link")
ctx.JSON(http.StatusOK, &apiCommits)
}
-7
View File
@@ -14,10 +14,3 @@ type swaggerResponseOAuth2Application struct {
// in:body
Body api.OAuth2Application `json:"body"`
}
// AccessToken represents an API access token.
// swagger:response AccessToken
type swaggerResponseAccessToken struct {
// in:body
Body api.AccessToken `json:"body"`
}
-3
View File
@@ -164,9 +164,6 @@ type swaggerParameterBodies struct {
// in:body
CreateTagOption api.CreateTagOption
// in:body
CreateAccessTokenOption api.CreateAccessTokenOption
// in:body
UserSettingsOptions api.UserSettingsOptions
}
+7 -2
View File
@@ -76,10 +76,15 @@ func CreateAccessToken(ctx *context.APIContext) {
// description: username of user
// type: string
// required: true
// - name: userCreateToken
// - name: accessToken
// in: body
// schema:
// "$ref": "#/definitions/CreateAccessTokenOption"
// type: object
// required:
// - name
// properties:
// name:
// type: string
// responses:
// "201":
// "$ref": "#/responses/AccessToken"
-13
View File
@@ -24,7 +24,6 @@ import (
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/upload"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/services/gitdiff"
)
@@ -568,18 +567,6 @@ func PrepareCompareDiff(
} else {
title = headBranch
}
if len(title) > 255 {
var trailer string
title, trailer = util.SplitStringAtByteN(title, 255)
if len(trailer) > 0 {
if ctx.Data["content"] != nil {
ctx.Data["content"] = fmt.Sprintf("%s\n\n%s", trailer, ctx.Data["content"])
} else {
ctx.Data["content"] = trailer + "\n"
}
}
}
ctx.Data["title"] = title
ctx.Data["Username"] = headUser.Name
ctx.Data["Reponame"] = headRepo.Name
-12
View File
@@ -1001,14 +1001,10 @@ func CompareAndPullRequestPost(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("repo.pulls.compare_changes")
ctx.Data["PageIsComparePull"] = true
ctx.Data["IsDiffCompare"] = true
ctx.Data["IsRepoToolbarCommits"] = true
ctx.Data["RequireTribute"] = true
ctx.Data["RequireSimpleMDE"] = true
ctx.Data["RequireHighlightJS"] = true
ctx.Data["PullRequestWorkInProgressPrefixes"] = setting.Repository.PullRequest.WorkInProgressPrefixes
ctx.Data["IsAttachmentEnabled"] = setting.Attachment.Enabled
upload.AddUploadContext(ctx, "comment")
ctx.Data["HasIssuesOrPullsWritePermission"] = ctx.Repo.CanWrite(models.UnitTypePullRequests)
var (
repo = ctx.Repo.Repository
@@ -1041,14 +1037,6 @@ func CompareAndPullRequestPost(ctx *context.Context) {
return
}
if len(form.Title) > 255 {
var trailer string
form.Title, trailer = util.SplitStringAtByteN(form.Title, 255)
form.Content = trailer + "\n\n" + form.Content
}
middleware.AssignForm(form, ctx.Data)
ctx.HTML(http.StatusOK, tplCompareDiff)
return
}
+2 -2
View File
@@ -81,7 +81,7 @@ func TestWiki(t *testing.T) {
Wiki(ctx)
assert.EqualValues(t, http.StatusOK, ctx.Resp.Status())
assert.EqualValues(t, "Home", ctx.Data["Title"])
assertPagesMetas(t, []string{"Home", "Page With Image", "Page With Spaced Name", "Unescaped File"}, ctx.Data["Pages"])
assertPagesMetas(t, []string{"Home", "Page With Image", "Page With Spaced Name"}, ctx.Data["Pages"])
}
func TestWikiPages(t *testing.T) {
@@ -91,7 +91,7 @@ func TestWikiPages(t *testing.T) {
test.LoadRepo(t, ctx, 1)
WikiPages(ctx)
assert.EqualValues(t, http.StatusOK, ctx.Resp.Status())
assertPagesMetas(t, []string{"Home", "Page With Image", "Page With Spaced Name", "Unescaped File"}, ctx.Data["Pages"])
assertPagesMetas(t, []string{"Home", "Page With Image", "Page With Spaced Name"}, ctx.Data["Pages"])
}
func TestNewWiki(t *testing.T) {
-2
View File
@@ -50,7 +50,6 @@ func Notifications(c *context.Context) {
return
}
if c.QueryBool("div-only") {
c.Data["SequenceNumber"] = c.Query("sequence-number")
c.HTML(http.StatusOK, tplNotificationDiv)
return
}
@@ -176,7 +175,6 @@ func NotificationStatusPost(c *context.Context) {
return
}
c.Data["Link"] = setting.AppURL + "notifications"
c.Data["SequenceNumber"] = c.Req.PostFormValue("sequence-number")
c.HTML(http.StatusOK, tplNotificationDiv)
}
+1 -1
View File
@@ -24,7 +24,7 @@ import (
"code.gitea.io/gitea/services/forms"
"gitea.com/go-chi/binding"
"github.com/golang-jwt/jwt"
"github.com/dgrijalva/jwt-go"
jsoniter "github.com/json-iterator/go"
)
+12 -17
View File
@@ -822,13 +822,8 @@ func RegisterRoutes(m *web.Route) {
}
ctx.Data["CommitsCount"] = ctx.Repo.CommitsCount
})
}, ignSignIn, context.RepoAssignment, context.UnitTypes(), reqRepoReleaseReader)
// to maintain compatibility with old attachments
m.Group("/{username}/{reponame}", func() {
m.Get("/attachments/{uuid}", repo.GetAttachment)
}, ignSignIn, context.RepoAssignment, context.UnitTypes())
}, ignSignIn, context.RepoAssignment, context.UnitTypes(), reqRepoReleaseReader)
m.Group("/{username}/{reponame}", func() {
m.Post("/topics", repo.TopicsPost)
@@ -1011,17 +1006,17 @@ func RegisterRoutes(m *web.Route) {
}, ignSignInAndCsrf, lfsServerEnabled)
m.Group("", func() {
m.PostOptions("/git-upload-pack", repo.ServiceUploadPack)
m.PostOptions("/git-receive-pack", repo.ServiceReceivePack)
m.GetOptions("/info/refs", repo.GetInfoRefs)
m.GetOptions("/HEAD", repo.GetTextFile("HEAD"))
m.GetOptions("/objects/info/alternates", repo.GetTextFile("objects/info/alternates"))
m.GetOptions("/objects/info/http-alternates", repo.GetTextFile("objects/info/http-alternates"))
m.GetOptions("/objects/info/packs", repo.GetInfoPacks)
m.GetOptions("/objects/info/{file:[^/]*}", repo.GetTextFile(""))
m.GetOptions("/objects/{head:[0-9a-f]{2}}/{hash:[0-9a-f]{38}}", repo.GetLooseObject)
m.GetOptions("/objects/pack/pack-{file:[0-9a-f]{40}}.pack", repo.GetPackFile)
m.GetOptions("/objects/pack/pack-{file:[0-9a-f]{40}}.idx", repo.GetIdxFile)
m.Post("/git-upload-pack", repo.ServiceUploadPack)
m.Post("/git-receive-pack", repo.ServiceReceivePack)
m.Get("/info/refs", repo.GetInfoRefs)
m.Get("/HEAD", repo.GetTextFile("HEAD"))
m.Get("/objects/info/alternates", repo.GetTextFile("objects/info/alternates"))
m.Get("/objects/info/http-alternates", repo.GetTextFile("objects/info/http-alternates"))
m.Get("/objects/info/packs", repo.GetInfoPacks)
m.Get("/objects/info/{file:[^/]*}", repo.GetTextFile(""))
m.Get("/objects/{head:[0-9a-f]{2}}/{hash:[0-9a-f]{38}}", repo.GetLooseObject)
m.Get("/objects/pack/pack-{file:[0-9a-f]{40}}.pack", repo.GetPackFile)
m.Get("/objects/pack/pack-{file:[0-9a-f]{40}}.idx", repo.GetIdxFile)
}, ignSignInAndCsrf)
m.Head("/tasks/trigger", repo.TriggerTask)
+1 -1
View File
@@ -21,7 +21,7 @@ import (
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"github.com/golang-jwt/jwt"
"github.com/dgrijalva/jwt-go"
jsoniter "github.com/json-iterator/go"
)
+9 -7
View File
@@ -88,11 +88,8 @@ func prepareWikiFileName(gitRepo *git.Repository, wikiName string) (bool, string
escaped := NameToFilename(wikiName)
// Look for both files
filesInIndex, err := gitRepo.LsTree("master", unescaped, escaped)
filesInIndex, err := gitRepo.LsFiles(unescaped, escaped)
if err != nil {
if strings.Contains(err.Error(), "Not a valid object name master") {
return false, escaped, nil
}
log.Error("%v", err)
return false, escaped, err
}
@@ -311,9 +308,14 @@ func DeleteWikiPage(doer *models.User, repo *models.Repository, wikiName string)
return fmt.Errorf("Unable to read HEAD tree to index in: %s %v", basePath, err)
}
found, wikiPath, err := prepareWikiFileName(gitRepo, wikiName)
if err != nil {
return err
wikiPath := NameToFilename(wikiName)
filesInIndex, err := gitRepo.LsFiles(wikiPath)
found := false
for _, file := range filesInIndex {
if file == wikiPath {
found = true
break
}
}
if found {
err := gitRepo.RemoveFilesFromIndex(wikiPath)
-80
View File
@@ -5,15 +5,11 @@
package wiki
import (
"io/ioutil"
"os"
"path/filepath"
"testing"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/util"
"github.com/stretchr/testify/assert"
)
@@ -214,79 +210,3 @@ func TestRepository_DeleteWikiPage(t *testing.T) {
_, err = masterTree.GetTreeEntryByPath(wikiPath)
assert.Error(t, err)
}
func TestPrepareWikiFileName(t *testing.T) {
models.PrepareTestEnv(t)
repo := models.AssertExistsAndLoadBean(t, &models.Repository{ID: 1}).(*models.Repository)
gitRepo, err := git.OpenRepository(repo.WikiPath())
defer gitRepo.Close()
assert.NoError(t, err)
tests := []struct {
name string
arg string
existence bool
wikiPath string
wantErr bool
}{{
name: "add suffix",
arg: "Home",
existence: true,
wikiPath: "Home.md",
wantErr: false,
}, {
name: "test special chars",
arg: "home of and & or wiki page!",
existence: false,
wikiPath: "home-of-and-%26-or-wiki-page%21.md",
wantErr: false,
}, {
name: "fount unescaped cases",
arg: "Unescaped File",
existence: true,
wikiPath: "Unescaped File.md",
wantErr: false,
}}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
existence, newWikiPath, err := prepareWikiFileName(gitRepo, tt.arg)
if (err != nil) != tt.wantErr {
assert.NoError(t, err)
return
}
if existence != tt.existence {
if existence {
t.Errorf("expect to find no escaped file but we detect one")
} else {
t.Errorf("expect to find an escaped file but we could not detect one")
}
}
assert.Equal(t, tt.wikiPath, newWikiPath)
})
}
}
func TestPrepareWikiFileName_FirstPage(t *testing.T) {
models.PrepareTestEnv(t)
// Now create a temporaryDirectory
tmpDir, err := ioutil.TempDir("", "empty-wiki")
assert.NoError(t, err)
defer func() {
if _, err := os.Stat(tmpDir); !os.IsNotExist(err) {
_ = util.RemoveAll(tmpDir)
}
}()
err = git.InitRepository(tmpDir, true)
assert.NoError(t, err)
gitRepo, err := git.OpenRepository(tmpDir)
defer gitRepo.Close()
assert.NoError(t, err)
existence, newWikiPath, err := prepareWikiFileName(gitRepo, "Home")
assert.False(t, existence)
assert.NoError(t, err)
assert.Equal(t, "Home.md", newWikiPath)
}
+4 -4
View File
@@ -176,10 +176,10 @@
{{if .IsNothingToCompare}}
{{if and $.IsSigned $.AllowEmptyPr (not .Repository.IsArchived) }}
<div class="ui segment">{{.i18n.Tr "repo.pulls.nothing_to_compare_and_allow_empty_pr"}}</div>
<div class="ui info message show-form-container" {{if .Flash}}style="display: none"{{end}}>
<div class="ui info message show-form-container">
<button class="ui button green show-form">{{.i18n.Tr "repo.pulls.new"}}</button>
</div>
<div class="pullrequest-form" {{if not .Flash}}style="display: none"{{end}}>
<div class="pullrequest-form" style="display: none">
{{template "repo/issue/new_form" .}}
</div>
{{else}}
@@ -192,7 +192,7 @@
</div>
{{else}}
{{if and $.IsSigned (not .Repository.IsArchived)}}
<div class="ui info message show-form-container" {{if .Flash}}style="display: none"{{end}}>
<div class="ui info message show-form-container">
<button class="ui button green show-form">{{.i18n.Tr "repo.pulls.new"}}</button>
</div>
{{else if .Repository.IsArchived}}
@@ -201,7 +201,7 @@
</div>
{{end}}
{{if $.IsSigned}}
<div class="pullrequest-form" {{if not .Flash}}style="display: none"{{end}}>
<div class="pullrequest-form" style="display: none">
{{template "repo/issue/new_form" .}}
</div>
{{end}}
+1 -3
View File
@@ -82,9 +82,7 @@
<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}}
{{template "repo/branch_dropdown" dict "root" $ "release" .}}
{{end}}
</div>
<div class="ui twelve wide column detail">
+24 -15
View File
@@ -11917,10 +11917,18 @@
"required": true
},
{
"name": "userCreateToken",
"name": "accessToken",
"in": "body",
"schema": {
"$ref": "#/definitions/CreateAccessTokenOption"
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string"
}
}
}
}
],
@@ -12646,17 +12654,6 @@
},
"x-go-package": "code.gitea.io/gitea/modules/structs"
},
"CreateAccessTokenOption": {
"description": "CreateAccessTokenOption options when create access token",
"type": "object",
"properties": {
"name": {
"type": "string",
"x-go-name": "Name"
}
},
"x-go-package": "code.gitea.io/gitea/modules/structs"
},
"CreateBranchProtectionOption": {
"description": "CreateBranchProtectionOption options for creating a branch protection",
"type": "object",
@@ -17047,8 +17044,20 @@
"responses": {
"AccessToken": {
"description": "AccessToken represents an API access token.",
"schema": {
"$ref": "#/definitions/AccessToken"
"headers": {
"id": {
"type": "integer",
"format": "int64"
},
"name": {
"type": "string"
},
"sha1": {
"type": "string"
},
"token_last_eight": {
"type": "string"
}
}
},
"AccessTokenList": {
@@ -1,4 +1,4 @@
<div class="page-content user notification" id="notification_div" data-params="{{.Page.GetParams}}" data-sequence-number="{{.SequenceNumber}}">
<div class="page-content user notification" id="notification_div" data-params="{{.Page.GetParams}}">
<div class="ui container">
<h1 class="ui dividing header">{{.i18n.Tr "notification.notifications"}}</h1>
<div class="ui top attached tabular menu">
-5
View File
@@ -295,11 +295,6 @@ func (queue *Queue) LHandle(h func([]byte) error) error {
// Close closes the queue (and the underlying db is set to closeUnderlyingDB)
func (queue *Queue) Close() error {
queue.highLock.Lock()
queue.lowLock.Lock()
defer queue.highLock.Unlock()
defer queue.lowLock.Unlock()
if !queue.closeUnderlyingDB {
queue.db = nil
return nil
-2
View File
@@ -107,8 +107,6 @@ func (set *Set) Remove(value []byte) (bool, error) {
// Close closes the set (and the underlying db if set to closeUnderlyingDB)
func (set *Set) Close() error {
set.lock.Lock()
defer set.lock.Unlock()
if !set.closeUnderlyingDB {
set.db = nil
return nil
-2
View File
@@ -181,8 +181,6 @@ func (queue *UniqueQueue) Len() int64 {
func (queue *UniqueQueue) Close() error {
_ = queue.q.Close()
_ = queue.set.Close()
queue.set.lock.Lock()
defer queue.set.lock.Unlock()
if !queue.closeUnderlyingDB {
queue.db = nil
return nil
@@ -1,4 +1,4 @@
.DS_Store
bin
.idea/
+13
View File
@@ -0,0 +1,13 @@
language: go
script:
- go vet ./...
- go test -v ./...
go:
- 1.3
- 1.4
- 1.5
- 1.6
- 1.7
- tip
@@ -1,5 +1,4 @@
Copyright (c) 2012 Dave Grijalva
Copyright (c) 2021 golang-jwt maintainers
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+97
View File
@@ -0,0 +1,97 @@
## Migration Guide from v2 -> v3
Version 3 adds several new, frequently requested features. To do so, it introduces a few breaking changes. We've worked to keep these as minimal as possible. This guide explains the breaking changes and how you can quickly update your code.
### `Token.Claims` is now an interface type
The most requested feature from the 2.0 verison of this library was the ability to provide a custom type to the JSON parser for claims. This was implemented by introducing a new interface, `Claims`, to replace `map[string]interface{}`. We also included two concrete implementations of `Claims`: `MapClaims` and `StandardClaims`.
`MapClaims` is an alias for `map[string]interface{}` with built in validation behavior. It is the default claims type when using `Parse`. The usage is unchanged except you must type cast the claims property.
The old example for parsing a token looked like this..
```go
if token, err := jwt.Parse(tokenString, keyLookupFunc); err == nil {
fmt.Printf("Token for user %v expires %v", token.Claims["user"], token.Claims["exp"])
}
```
is now directly mapped to...
```go
if token, err := jwt.Parse(tokenString, keyLookupFunc); err == nil {
claims := token.Claims.(jwt.MapClaims)
fmt.Printf("Token for user %v expires %v", claims["user"], claims["exp"])
}
```
`StandardClaims` is designed to be embedded in your custom type. You can supply a custom claims type with the new `ParseWithClaims` function. Here's an example of using a custom claims type.
```go
type MyCustomClaims struct {
User string
*StandardClaims
}
if token, err := jwt.ParseWithClaims(tokenString, &MyCustomClaims{}, keyLookupFunc); err == nil {
claims := token.Claims.(*MyCustomClaims)
fmt.Printf("Token for user %v expires %v", claims.User, claims.StandardClaims.ExpiresAt)
}
```
### `ParseFromRequest` has been moved
To keep this library focused on the tokens without becoming overburdened with complex request processing logic, `ParseFromRequest` and its new companion `ParseFromRequestWithClaims` have been moved to a subpackage, `request`. The method signatues have also been augmented to receive a new argument: `Extractor`.
`Extractors` do the work of picking the token string out of a request. The interface is simple and composable.
This simple parsing example:
```go
if token, err := jwt.ParseFromRequest(tokenString, req, keyLookupFunc); err == nil {
fmt.Printf("Token for user %v expires %v", token.Claims["user"], token.Claims["exp"])
}
```
is directly mapped to:
```go
if token, err := request.ParseFromRequest(req, request.OAuth2Extractor, keyLookupFunc); err == nil {
claims := token.Claims.(jwt.MapClaims)
fmt.Printf("Token for user %v expires %v", claims["user"], claims["exp"])
}
```
There are several concrete `Extractor` types provided for your convenience:
* `HeaderExtractor` will search a list of headers until one contains content.
* `ArgumentExtractor` will search a list of keys in request query and form arguments until one contains content.
* `MultiExtractor` will try a list of `Extractors` in order until one returns content.
* `AuthorizationHeaderExtractor` will look in the `Authorization` header for a `Bearer` token.
* `OAuth2Extractor` searches the places an OAuth2 token would be specified (per the spec): `Authorization` header and `access_token` argument
* `PostExtractionFilter` wraps an `Extractor`, allowing you to process the content before it's parsed. A simple example is stripping the `Bearer ` text from a header
### RSA signing methods no longer accept `[]byte` keys
Due to a [critical vulnerability](https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/), we've decided the convenience of accepting `[]byte` instead of `rsa.PublicKey` or `rsa.PrivateKey` isn't worth the risk of misuse.
To replace this behavior, we've added two helper methods: `ParseRSAPrivateKeyFromPEM(key []byte) (*rsa.PrivateKey, error)` and `ParseRSAPublicKeyFromPEM(key []byte) (*rsa.PublicKey, error)`. These are just simple helpers for unpacking PEM encoded PKCS1 and PKCS8 keys. If your keys are encoded any other way, all you need to do is convert them to the `crypto/rsa` package's types.
```go
func keyLookupFunc(*Token) (interface{}, error) {
// Don't forget to validate the alg is what you expect:
if _, ok := token.Method.(*jwt.SigningMethodRSA); !ok {
return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
}
// Look up key
key, err := lookupPublicKey(token.Header["kid"])
if err != nil {
return nil, err
}
// Unpack key from PEM encoded PKCS8
return jwt.ParseRSAPublicKeyFromPEM(key)
}
```
@@ -1,34 +1,25 @@
# jwt-go
[![build](https://github.com/golang-jwt/jwt/actions/workflows/build.yml/badge.svg)](https://github.com/golang-jwt/jwt/actions/workflows/build.yml)
[![Go Reference](https://pkg.go.dev/badge/github.com/golang-jwt/jwt.svg)](https://pkg.go.dev/github.com/golang-jwt/jwt)
[![Build Status](https://travis-ci.org/dgrijalva/jwt-go.svg?branch=master)](https://travis-ci.org/dgrijalva/jwt-go)
[![GoDoc](https://godoc.org/github.com/dgrijalva/jwt-go?status.svg)](https://godoc.org/github.com/dgrijalva/jwt-go)
A [go](http://www.golang.org) (or 'golang' for search engine friendliness) implementation of [JSON Web Tokens](https://datatracker.ietf.org/doc/html/rfc7519).
A [go](http://www.golang.org) (or 'golang' for search engine friendliness) implementation of [JSON Web Tokens](http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html)
**IMPORT PATH CHANGE:** Starting from [v3.2.1](https://github.com/golang-jwt/jwt/releases/tag/v3.2.1), the import path has changed from `github.com/dgrijalva/jwt-go` to `github.com/golang-jwt/jwt`. After the original author of the library suggested migrating the maintenance of `jwt-go`, a dedicated team of open source maintainers decided to clone the existing library into this repository. See [dgrijalva/jwt-go#462](https://github.com/dgrijalva/jwt-go/issues/462) for a detailed discussion on this topic.
**NEW VERSION COMING:** There have been a lot of improvements suggested since the version 3.0.0 released in 2016. I'm working now on cutting two different releases: 3.2.0 will contain any non-breaking changes or enhancements. 4.0.0 will follow shortly which will include breaking changes. See the 4.0.0 milestone to get an idea of what's coming. If you have other ideas, or would like to participate in 4.0.0, now's the time. If you depend on this library and don't want to be interrupted, I recommend you use your dependency mangement tool to pin to version 3.
Future releases will be using the `github.com/golang-jwt/jwt` import path and continue the existing versioning scheme of `v3.x.x+incompatible`. Backwards-compatible patches and fixes will be done on the `v3` release branch, where as new build-breaking features will be developed in a `v4` release, possibly including a SIV-style import path.
**SECURITY NOTICE:** Some older versions of Go have a security issue in the cryotp/elliptic. Recommendation is to upgrade to at least 1.8.3. See issue #216 for more detail.
**SECURITY NOTICE:** Some older versions of Go have a security issue in the crypto/elliptic. Recommendation is to upgrade to at least 1.15 See issue [dgrijalva/jwt-go#216](https://github.com/dgrijalva/jwt-go/issues/216) for more detail.
**SECURITY NOTICE:** It's important that you [validate the `alg` presented is what you expect](https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/). This library attempts to make it easy to do the right thing by requiring key types match the expected alg, but you should take the extra step to verify it in your usage. See the examples provided.
### Supported Go versions
Our support of Go versions is aligned with Go's [version release policy](https://golang.org/doc/devel/release#policy).
So we will support a major version of Go until there are two newer major releases.
We no longer support building jwt-go with unsupported Go versions, as these contain security vulnerabilities
which will not be fixed.
**SECURITY NOTICE:** It's important that you [validate the `alg` presented is what you expect](https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/). This library attempts to make it easy to do the right thing by requiring key types match the expected alg, but you should take the extra step to verify it in your usage. See the examples provided.
## What the heck is a JWT?
JWT.io has [a great introduction](https://jwt.io/introduction) to JSON Web Tokens.
In short, it's a signed JSON object that does something useful (for example, authentication). It's commonly used for `Bearer` tokens in Oauth 2. A token is made of three parts, separated by `.`'s. The first two parts are JSON objects, that have been [base64url](https://datatracker.ietf.org/doc/html/rfc4648) encoded. The last part is the signature, encoded the same way.
In short, it's a signed JSON object that does something useful (for example, authentication). It's commonly used for `Bearer` tokens in Oauth 2. A token is made of three parts, separated by `.`'s. The first two parts are JSON objects, that have been [base64url](http://tools.ietf.org/html/rfc4648) encoded. The last part is the signature, encoded the same way.
The first part is called the header. It contains the necessary information for verifying the last part, the signature. For example, which encryption method was used for signing and what key was used.
The part in the middle is the interesting bit. It's called the Claims and contains the actual stuff you care about. Refer to [RFC 7519](https://datatracker.ietf.org/doc/html/rfc7519) for information about reserved keys and the proper way to add your own.
The part in the middle is the interesting bit. It's called the Claims and contains the actual stuff you care about. Refer to [the RFC](http://self-issued.info/docs/draft-jones-json-web-token.html) for information about reserved keys and the proper way to add your own.
## What's in the box?
@@ -36,31 +27,31 @@ This library supports the parsing and verification as well as the generation and
## Examples
See [the project documentation](https://pkg.go.dev/github.com/golang-jwt/jwt) for examples of usage:
See [the project documentation](https://godoc.org/github.com/dgrijalva/jwt-go) for examples of usage:
* [Simple example of parsing and validating a token](https://pkg.go.dev/github.com/golang-jwt/jwt#example-Parse-Hmac)
* [Simple example of building and signing a token](https://pkg.go.dev/github.com/golang-jwt/jwt#example-New-Hmac)
* [Directory of Examples](https://pkg.go.dev/github.com/golang-jwt/jwt#pkg-examples)
* [Simple example of parsing and validating a token](https://godoc.org/github.com/dgrijalva/jwt-go#example-Parse--Hmac)
* [Simple example of building and signing a token](https://godoc.org/github.com/dgrijalva/jwt-go#example-New--Hmac)
* [Directory of Examples](https://godoc.org/github.com/dgrijalva/jwt-go#pkg-examples)
## Extensions
This library publishes all the necessary components for adding your own signing methods. Simply implement the `SigningMethod` interface and register a factory method using `RegisterSigningMethod`.
Here's an example of an extension that integrates with multiple Google Cloud Platform signing tools (AppEngine, IAM API, Cloud KMS): https://github.com/someone1/gcp-jwt-go
Here's an example of an extension that integrates with the Google App Engine signing tools: https://github.com/someone1/gcp-jwt-go
## Compliance
This library was last reviewed to comply with [RTF 7519](https://datatracker.ietf.org/doc/html/rfc7519) dated May 2015 with a few notable differences:
This library was last reviewed to comply with [RTF 7519](http://www.rfc-editor.org/info/rfc7519) dated May 2015 with a few notable differences:
* In order to protect against accidental use of [Unsecured JWTs](https://datatracker.ietf.org/doc/html/rfc7519#section-6), tokens using `alg=none` will only be accepted if the constant `jwt.UnsafeAllowNoneSignatureType` is provided as the key.
* In order to protect against accidental use of [Unsecured JWTs](http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html#UnsecuredJWT), tokens using `alg=none` will only be accepted if the constant `jwt.UnsafeAllowNoneSignatureType` is provided as the key.
## Project Status & Versioning
This library is considered production ready. Feedback and feature requests are appreciated. The API should be considered stable. There should be very few backwards-incompatible changes outside of major version updates (and only with good reason).
This project uses [Semantic Versioning 2.0.0](http://semver.org). Accepted pull requests will land on `main`. Periodically, versions will be tagged from `main`. You can find all the releases on [the project releases page](https://github.com/golang-jwt/jwt/releases).
This project uses [Semantic Versioning 2.0.0](http://semver.org). Accepted pull requests will land on `master`. Periodically, versions will be tagged from `master`. You can find all the releases on [the project releases page](https://github.com/dgrijalva/jwt-go/releases).
While we try to make it obvious when we make breaking changes, there isn't a great mechanism for pushing announcements out to users. You may want to use this alternative package include: `gopkg.in/golang-jwt/jwt.v3`. It will do the right thing WRT semantic versioning.
While we try to make it obvious when we make breaking changes, there isn't a great mechanism for pushing announcements out to users. You may want to use this alternative package include: `gopkg.in/dgrijalva/jwt-go.v3`. It will do the right thing WRT semantic versioning.
**BREAKING CHANGES:***
* Version 3.0.0 includes _a lot_ of changes from the 2.x line, including a few that break the API. We've tried to break as few things as possible, so there should just be a few type signature changes. A full list of breaking changes is available in `VERSION_HISTORY.md`. See `MIGRATION_GUIDE.md` for more information on updating your code.
@@ -88,9 +79,9 @@ Asymmetric signing methods, such as RSA, use different keys for signing and veri
Each signing method expects a different object type for its signing keys. See the package documentation for details. Here are the most common ones:
* The [HMAC signing method](https://pkg.go.dev/github.com/golang-jwt/jwt#SigningMethodHMAC) (`HS256`,`HS384`,`HS512`) expect `[]byte` values for signing and validation
* The [RSA signing method](https://pkg.go.dev/github.com/golang-jwt/jwt#SigningMethodRSA) (`RS256`,`RS384`,`RS512`) expect `*rsa.PrivateKey` for signing and `*rsa.PublicKey` for validation
* The [ECDSA signing method](https://pkg.go.dev/github.com/golang-jwt/jwt#SigningMethodECDSA) (`ES256`,`ES384`,`ES512`) expect `*ecdsa.PrivateKey` for signing and `*ecdsa.PublicKey` for validation
* The [HMAC signing method](https://godoc.org/github.com/dgrijalva/jwt-go#SigningMethodHMAC) (`HS256`,`HS384`,`HS512`) expect `[]byte` values for signing and validation
* The [RSA signing method](https://godoc.org/github.com/dgrijalva/jwt-go#SigningMethodRSA) (`RS256`,`RS384`,`RS512`) expect `*rsa.PrivateKey` for signing and `*rsa.PublicKey` for validation
* The [ECDSA signing method](https://godoc.org/github.com/dgrijalva/jwt-go#SigningMethodECDSA) (`ES256`,`ES384`,`ES512`) expect `*ecdsa.PrivateKey` for signing and `*ecdsa.PublicKey` for validation
### JWT and OAuth
@@ -102,12 +93,8 @@ Without going too far down the rabbit hole, here's a description of the interact
* OAuth defines several options for passing around authentication data. One popular method is called a "bearer token". A bearer token is simply a string that _should_ only be held by an authenticated user. Thus, simply presenting this token proves your identity. You can probably derive from here why a JWT might make a good bearer token.
* Because bearer tokens are used for authentication, it's important they're kept secret. This is why transactions that use bearer tokens typically happen over SSL.
### Troubleshooting
This library uses descriptive error messages whenever possible. If you are not getting the expected result, have a look at the errors. The most common place people get stuck is providing the correct type of key to the parser. See the above section on signing methods and key types.
## More
Documentation can be found [on pkg.go.dev](https://pkg.go.dev/github.com/golang-jwt/jwt).
Documentation can be found [on godoc.org](http://godoc.org/github.com/dgrijalva/jwt-go).
The command line utility included in this project (cmd/jwt) provides a straightforward example of token creation and parsing as well as a useful tool for debugging your own integration. You'll also find several implementation examples in the documentation.
@@ -1,18 +1,5 @@
## `jwt-go` Version History
#### 3.2.2
* Starting from this release, we are adopting the policy to support the most 2 recent versions of Go currently available. By the time of this release, this is Go 1.15 and 1.16 ([#28](https://github.com/golang-jwt/jwt/pull/28)).
* Fixed a potential issue that could occur when the verification of `exp`, `iat` or `nbf` was not required and contained invalid contents, i.e. non-numeric/date. Thanks for @thaJeztah for making us aware of that and @giorgos-f3 for originally reporting it to the formtech fork ([#40](https://github.com/golang-jwt/jwt/pull/40)).
* Added support for EdDSA / ED25519 ([#36](https://github.com/golang-jwt/jwt/pull/36)).
* Optimized allocations ([#33](https://github.com/golang-jwt/jwt/pull/33)).
#### 3.2.1
* **Import Path Change**: See MIGRATION_GUIDE.md for tips on updating your code
* Changed the import path from `github.com/dgrijalva/jwt-go` to `github.com/golang-jwt/jwt`
* Fixed type confusing issue between `string` and `[]string` in `VerifyAudience` ([#12](https://github.com/golang-jwt/jwt/pull/12)). This fixes CVE-2020-26160
#### 3.2.0
* Added method `ParseUnverified` to allow users to split up the tasks of parsing and validation
@@ -128,4 +115,4 @@ It is likely the only integration change required here will be to change `func(t
* First versioned release
* API stabilized
* Supports creating, signing, parsing, and validating JWT tokens
* Supports RS256 and HS256 signing methods
* Supports RS256 and HS256 signing methods
@@ -35,18 +35,18 @@ func (c StandardClaims) Valid() error {
// The claims below are optional, by default, so if they are set to the
// default value in Go, let's not fail the verification for them.
if !c.VerifyExpiresAt(now, false) {
if c.VerifyExpiresAt(now, false) == false {
delta := time.Unix(now, 0).Sub(time.Unix(c.ExpiresAt, 0))
vErr.Inner = fmt.Errorf("token is expired by %v", delta)
vErr.Errors |= ValidationErrorExpired
}
if !c.VerifyIssuedAt(now, false) {
if c.VerifyIssuedAt(now, false) == false {
vErr.Inner = fmt.Errorf("Token used before issued")
vErr.Errors |= ValidationErrorIssuedAt
}
if !c.VerifyNotBefore(now, false) {
if c.VerifyNotBefore(now, false) == false {
vErr.Inner = fmt.Errorf("token is not valid yet")
vErr.Errors |= ValidationErrorNotValidYet
}
@@ -61,7 +61,7 @@ func (c StandardClaims) Valid() error {
// Compares the aud claim against cmp.
// If required is false, this method will return true if the value matches or is unset
func (c *StandardClaims) VerifyAudience(cmp string, req bool) bool {
return verifyAud([]string{c.Audience}, cmp, req)
return verifyAud(c.Audience, cmp, req)
}
// Compares the exp claim against cmp.
@@ -90,27 +90,15 @@ func (c *StandardClaims) VerifyNotBefore(cmp int64, req bool) bool {
// ----- helpers
func verifyAud(aud []string, cmp string, required bool) bool {
if len(aud) == 0 {
func verifyAud(aud string, cmp string, required bool) bool {
if aud == "" {
return !required
}
// use a var here to keep constant time compare when looping over a number of claims
result := false
var stringClaims string
for _, a := range aud {
if subtle.ConstantTimeCompare([]byte(a), []byte(cmp)) != 0 {
result = true
}
stringClaims = stringClaims + a
if subtle.ConstantTimeCompare([]byte(aud), []byte(cmp)) != 0 {
return true
} else {
return false
}
// case where "" is sent in one or many aud claims
if len(stringClaims) == 0 {
return !required
}
return result
}
func verifyExp(exp int64, now int64, required bool) bool {
@@ -88,11 +88,11 @@ func (m *SigningMethodECDSA) Verify(signingString, signature string, key interfa
hasher.Write([]byte(signingString))
// Verify the signature
if verifystatus := ecdsa.Verify(ecdsaKey, hasher.Sum(nil), r, s); verifystatus {
if verifystatus := ecdsa.Verify(ecdsaKey, hasher.Sum(nil), r, s); verifystatus == true {
return nil
} else {
return ErrECDSAVerification
}
return ErrECDSAVerification
}
// Implements the Sign method from SigningMethod
@@ -128,12 +128,18 @@ func (m *SigningMethodECDSA) Sign(signingString string, key interface{}) (string
keyBytes += 1
}
// We serialize the outputs (r and s) into big-endian byte arrays
// padded with zeros on the left to make sure the sizes work out.
// Output must be 2*keyBytes long.
out := make([]byte, 2*keyBytes)
r.FillBytes(out[0:keyBytes]) // r is assigned to the first half of output.
s.FillBytes(out[keyBytes:]) // s is assigned to the second half of output.
// We serialize the outpus (r and s) into big-endian byte arrays and pad
// them with zeros on the left to make sure the sizes work out. Both arrays
// must be keyBytes long, and the output must be 2*keyBytes long.
rBytes := r.Bytes()
rBytesPadded := make([]byte, keyBytes)
copy(rBytesPadded[keyBytes-len(rBytes):], rBytes)
sBytes := s.Bytes()
sBytesPadded := make([]byte, keyBytes)
copy(sBytesPadded[keyBytes-len(sBytes):], sBytes)
out := append(rBytesPadded, sBytesPadded...)
return EncodeSegment(out), nil
} else {
@@ -25,9 +25,7 @@ func ParseECPrivateKeyFromPEM(key []byte) (*ecdsa.PrivateKey, error) {
// Parse the key
var parsedKey interface{}
if parsedKey, err = x509.ParseECPrivateKey(block.Bytes); err != nil {
if parsedKey, err = x509.ParsePKCS8PrivateKey(block.Bytes); err != nil {
return nil, err
}
return nil, err
}
var pkey *ecdsa.PrivateKey
@@ -10,59 +10,37 @@ import (
// This is the default claims type if you don't supply one
type MapClaims map[string]interface{}
// VerifyAudience Compares the aud claim against cmp.
// Compares the aud claim against cmp.
// If required is false, this method will return true if the value matches or is unset
func (m MapClaims) VerifyAudience(cmp string, req bool) bool {
var aud []string
switch v := m["aud"].(type) {
case string:
aud = append(aud, v)
case []string:
aud = v
case []interface{}:
for _, a := range v {
vs, ok := a.(string)
if !ok {
return false
}
aud = append(aud, vs)
}
}
aud, _ := m["aud"].(string)
return verifyAud(aud, cmp, req)
}
// Compares the exp claim against cmp.
// If required is false, this method will return true if the value matches or is unset
func (m MapClaims) VerifyExpiresAt(cmp int64, req bool) bool {
exp, ok := m["exp"]
if !ok {
return !req
}
switch expType := exp.(type) {
switch exp := m["exp"].(type) {
case float64:
return verifyExp(int64(expType), cmp, req)
return verifyExp(int64(exp), cmp, req)
case json.Number:
v, _ := expType.Int64()
v, _ := exp.Int64()
return verifyExp(v, cmp, req)
}
return false
return req == false
}
// Compares the iat claim against cmp.
// If required is false, this method will return true if the value matches or is unset
func (m MapClaims) VerifyIssuedAt(cmp int64, req bool) bool {
iat, ok := m["iat"]
if !ok {
return !req
}
switch iatType := iat.(type) {
switch iat := m["iat"].(type) {
case float64:
return verifyIat(int64(iatType), cmp, req)
return verifyIat(int64(iat), cmp, req)
case json.Number:
v, _ := iatType.Int64()
v, _ := iat.Int64()
return verifyIat(v, cmp, req)
}
return false
return req == false
}
// Compares the iss claim against cmp.
@@ -75,18 +53,14 @@ func (m MapClaims) VerifyIssuer(cmp string, req bool) bool {
// Compares the nbf claim against cmp.
// If required is false, this method will return true if the value matches or is unset
func (m MapClaims) VerifyNotBefore(cmp int64, req bool) bool {
nbf, ok := m["nbf"]
if !ok {
return !req
}
switch nbfType := nbf.(type) {
switch nbf := m["nbf"].(type) {
case float64:
return verifyNbf(int64(nbfType), cmp, req)
return verifyNbf(int64(nbf), cmp, req)
case json.Number:
v, _ := nbfType.Int64()
v, _ := nbf.Int64()
return verifyNbf(v, cmp, req)
}
return false
return req == false
}
// Validates time based claims "exp, iat, nbf".
@@ -97,17 +71,17 @@ func (m MapClaims) Valid() error {
vErr := new(ValidationError)
now := TimeFunc().Unix()
if !m.VerifyExpiresAt(now, false) {
if m.VerifyExpiresAt(now, false) == false {
vErr.Inner = errors.New("Token is expired")
vErr.Errors |= ValidationErrorExpired
}
if !m.VerifyIssuedAt(now, false) {
if m.VerifyIssuedAt(now, false) == false {
vErr.Inner = errors.New("Token used before issued")
vErr.Errors |= ValidationErrorIssuedAt
}
if !m.VerifyNotBefore(now, false) {
if m.VerifyNotBefore(now, false) == false {
vErr.Inner = errors.New("Token is not valid yet")
vErr.Errors |= ValidationErrorNotValidYet
}
@@ -12,14 +12,9 @@ import (
type SigningMethodRSAPSS struct {
*SigningMethodRSA
Options *rsa.PSSOptions
// VerifyOptions is optional. If set overrides Options for rsa.VerifyPPS.
// Used to accept tokens signed with rsa.PSSSaltLengthAuto, what doesn't follow
// https://tools.ietf.org/html/rfc7518#section-3.5 but was used previously.
// See https://github.com/dgrijalva/jwt-go/issues/285#issuecomment-437451244 for details.
VerifyOptions *rsa.PSSOptions
}
// Specific instances for RS/PS and company.
// Specific instances for RS/PS and company
var (
SigningMethodPS256 *SigningMethodRSAPSS
SigningMethodPS384 *SigningMethodRSAPSS
@@ -29,15 +24,13 @@ var (
func init() {
// PS256
SigningMethodPS256 = &SigningMethodRSAPSS{
SigningMethodRSA: &SigningMethodRSA{
&SigningMethodRSA{
Name: "PS256",
Hash: crypto.SHA256,
},
Options: &rsa.PSSOptions{
SaltLength: rsa.PSSSaltLengthEqualsHash,
},
VerifyOptions: &rsa.PSSOptions{
&rsa.PSSOptions{
SaltLength: rsa.PSSSaltLengthAuto,
Hash: crypto.SHA256,
},
}
RegisterSigningMethod(SigningMethodPS256.Alg(), func() SigningMethod {
@@ -46,15 +39,13 @@ func init() {
// PS384
SigningMethodPS384 = &SigningMethodRSAPSS{
SigningMethodRSA: &SigningMethodRSA{
&SigningMethodRSA{
Name: "PS384",
Hash: crypto.SHA384,
},
Options: &rsa.PSSOptions{
SaltLength: rsa.PSSSaltLengthEqualsHash,
},
VerifyOptions: &rsa.PSSOptions{
&rsa.PSSOptions{
SaltLength: rsa.PSSSaltLengthAuto,
Hash: crypto.SHA384,
},
}
RegisterSigningMethod(SigningMethodPS384.Alg(), func() SigningMethod {
@@ -63,15 +54,13 @@ func init() {
// PS512
SigningMethodPS512 = &SigningMethodRSAPSS{
SigningMethodRSA: &SigningMethodRSA{
&SigningMethodRSA{
Name: "PS512",
Hash: crypto.SHA512,
},
Options: &rsa.PSSOptions{
SaltLength: rsa.PSSSaltLengthEqualsHash,
},
VerifyOptions: &rsa.PSSOptions{
&rsa.PSSOptions{
SaltLength: rsa.PSSSaltLengthAuto,
Hash: crypto.SHA512,
},
}
RegisterSigningMethod(SigningMethodPS512.Alg(), func() SigningMethod {
@@ -105,12 +94,7 @@ func (m *SigningMethodRSAPSS) Verify(signingString, signature string, key interf
hasher := m.Hash.New()
hasher.Write([]byte(signingString))
opts := m.Options
if m.VerifyOptions != nil {
opts = m.VerifyOptions
}
return rsa.VerifyPSS(rsaKey, m.Hash, hasher.Sum(nil), sig, opts)
return rsa.VerifyPSS(rsaKey, m.Hash, hasher.Sum(nil), sig, m.Options)
}
// Implements the Sign method from SigningMethod
@@ -8,7 +8,7 @@ import (
)
var (
ErrKeyMustBePEMEncoded = errors.New("Invalid Key: Key must be a PEM encoded PKCS1 or PKCS8 key")
ErrKeyMustBePEMEncoded = errors.New("Invalid Key: Key must be PEM encoded PKCS1 or PKCS8 private key")
ErrNotRSAPrivateKey = errors.New("Key is not a valid RSA private key")
ErrNotRSAPublicKey = errors.New("Key is not a valid RSA public key")
)
@@ -65,7 +65,7 @@ func (t *Token) SignedString(key interface{}) (string, error) {
func (t *Token) SigningString() (string, error) {
var err error
parts := make([]string, 2)
for i := range parts {
for i, _ := range parts {
var jsonValue []byte
if i == 0 {
if jsonValue, err = json.Marshal(t.Header); err != nil {
@@ -95,10 +95,14 @@ func ParseWithClaims(tokenString string, claims Claims, keyFunc Keyfunc) (*Token
// Encode JWT specific base64url encoding with padding stripped
func EncodeSegment(seg []byte) string {
return base64.RawURLEncoding.EncodeToString(seg)
return strings.TrimRight(base64.URLEncoding.EncodeToString(seg), "=")
}
// Decode JWT specific base64url encoding with padding stripped
func DecodeSegment(seg string) ([]byte, error) {
return base64.RawURLEncoding.DecodeString(seg)
if l := len(seg) % 4; l > 0 {
seg += strings.Repeat("=", 4-l)
}
return base64.URLEncoding.DecodeString(seg)
}
-22
View File
@@ -1,22 +0,0 @@
## Migration Guide (v3.2.1)
Starting from [v3.2.1](https://github.com/golang-jwt/jwt/releases/tag/v3.2.1]), the import path has changed from `github.com/dgrijalva/jwt-go` to `github.com/golang-jwt/jwt`. Future releases will be using the `github.com/golang-jwt/jwt` import path and continue the existing versioning scheme of `v3.x.x+incompatible`. Backwards-compatible patches and fixes will be done on the `v3` release branch, where as new build-breaking features will be developed in a `v4` release, possibly including a SIV-style import path.
### go.mod replacement
In a first step, the easiest way is to use `go mod edit` to issue a replacement.
```
go mod edit -replace github.com/dgrijalva/jwt-go=github.com/golang-jwt/jwt@v3.2.1+incompatible
go mod tidy
```
This will still keep the old import path in your code but replace it with the new package and also introduce a new indirect dependency to `github.com/golang-jwt/jwt`. Try to compile your project; it should still work.
### Cleanup
If your code still consistently builds, you can replace all occurences of `github.com/dgrijalva/jwt-go` with `github.com/golang-jwt/jwt`, either manually or by using tools such as `sed`. Finally, the `replace` directive in the `go.mod` file can be removed.
## Older releases (before v3.2.0)
The original migration guide for older releases can be found at https://github.com/dgrijalva/jwt-go/blob/master/MIGRATION_GUIDE.md.
-81
View File
@@ -1,81 +0,0 @@
package jwt
import (
"errors"
"crypto/ed25519"
)
var (
ErrEd25519Verification = errors.New("ed25519: verification error")
)
// Implements the EdDSA family
// Expects ed25519.PrivateKey for signing and ed25519.PublicKey for verification
type SigningMethodEd25519 struct{}
// Specific instance for EdDSA
var (
SigningMethodEdDSA *SigningMethodEd25519
)
func init() {
SigningMethodEdDSA = &SigningMethodEd25519{}
RegisterSigningMethod(SigningMethodEdDSA.Alg(), func() SigningMethod {
return SigningMethodEdDSA
})
}
func (m *SigningMethodEd25519) Alg() string {
return "EdDSA"
}
// Implements the Verify method from SigningMethod
// For this verify method, key must be an ed25519.PublicKey
func (m *SigningMethodEd25519) Verify(signingString, signature string, key interface{}) error {
var err error
var ed25519Key ed25519.PublicKey
var ok bool
if ed25519Key, ok = key.(ed25519.PublicKey); !ok {
return ErrInvalidKeyType
}
if len(ed25519Key) != ed25519.PublicKeySize {
return ErrInvalidKey
}
// Decode the signature
var sig []byte
if sig, err = DecodeSegment(signature); err != nil {
return err
}
// Verify the signature
if !ed25519.Verify(ed25519Key, []byte(signingString), sig) {
return ErrEd25519Verification
}
return nil
}
// Implements the Sign method from SigningMethod
// For this signing method, key must be an ed25519.PrivateKey
func (m *SigningMethodEd25519) Sign(signingString string, key interface{}) (string, error) {
var ed25519Key ed25519.PrivateKey
var ok bool
if ed25519Key, ok = key.(ed25519.PrivateKey); !ok {
return "", ErrInvalidKeyType
}
// ed25519.Sign panics if private key not equal to ed25519.PrivateKeySize
// this allows to avoid recover usage
if len(ed25519Key) != ed25519.PrivateKeySize {
return "", ErrInvalidKey
}
// Sign the string and return the encoded result
sig := ed25519.Sign(ed25519Key, []byte(signingString))
return EncodeSegment(sig), nil
}
-64
View File
@@ -1,64 +0,0 @@
package jwt
import (
"crypto"
"crypto/ed25519"
"crypto/x509"
"encoding/pem"
"errors"
)
var (
ErrNotEdPrivateKey = errors.New("Key is not a valid Ed25519 private key")
ErrNotEdPublicKey = errors.New("Key is not a valid Ed25519 public key")
)
// Parse PEM-encoded Edwards curve private key
func ParseEdPrivateKeyFromPEM(key []byte) (crypto.PrivateKey, error) {
var err error
// Parse PEM block
var block *pem.Block
if block, _ = pem.Decode(key); block == nil {
return nil, ErrKeyMustBePEMEncoded
}
// Parse the key
var parsedKey interface{}
if parsedKey, err = x509.ParsePKCS8PrivateKey(block.Bytes); err != nil {
return nil, err
}
var pkey ed25519.PrivateKey
var ok bool
if pkey, ok = parsedKey.(ed25519.PrivateKey); !ok {
return nil, ErrNotEdPrivateKey
}
return pkey, nil
}
// Parse PEM-encoded Edwards curve public key
func ParseEdPublicKeyFromPEM(key []byte) (crypto.PublicKey, error) {
var err error
// Parse PEM block
var block *pem.Block
if block, _ = pem.Decode(key); block == nil {
return nil, ErrKeyMustBePEMEncoded
}
// Parse the key
var parsedKey interface{}
if parsedKey, err = x509.ParsePKIXPublicKey(block.Bytes); err != nil {
return nil, err
}
var pkey ed25519.PublicKey
var ok bool
if pkey, ok = parsedKey.(ed25519.PublicKey); !ok {
return nil, ErrNotEdPublicKey
}
return pkey, nil
}
+2 -1
View File
@@ -5,7 +5,7 @@ go 1.15
require (
cloud.google.com/go v0.67.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/golang-jwt/jwt v3.2.1+incompatible
github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/gorilla/mux v1.6.2
github.com/gorilla/pat v0.0.0-20180118222023-199c85a7f6d1
github.com/gorilla/sessions v1.1.1
@@ -14,6 +14,7 @@ require (
github.com/markbates/going v1.0.0
github.com/mrjones/oauth v0.0.0-20180629183705-f4e24b6d100c
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/stretchr/testify v1.4.0
golang.org/x/net v0.0.0-20200930145003-4acb6c075d10 // indirect
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43
+19 -4
View File
@@ -1,4 +1,6 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.30.0 h1:xKvyLgk56d0nksWq49J0UyGEeUIicTl4+UBiX1NPX9g=
cloud.google.com/go v0.30.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
@@ -12,8 +14,8 @@ cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bP
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
cloud.google.com/go v0.63.0/go.mod h1:GmezbQc7T2snqkEXWfZ0sy0VfkB/ivI2DdtJL2DEmlg=
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
cloud.google.com/go v0.67.0 h1:YIkzmqUfVGiGPpT98L8sVvUIkDno6UlrDxw4NR6z5ak=
cloud.google.com/go v0.67.0/go.mod h1:YNan/mUhNZFrYUor0vqrsQ0Ffl7Xtm/ACOy/vsTS858=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
@@ -41,9 +43,12 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5P
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/damonkeys/goth v1.64.2 h1:I2cB72NAa1tJBI1TcLYn7H6hBeHpwm5y8Ew+VeSZXPg=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
@@ -51,8 +56,6 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/golang-jwt/jwt v3.2.1+incompatible h1:73Z+4BJcrTC+KczS6WvTPvRGOp1WmfEP4Q1lOd9Z/+c=
github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
@@ -64,6 +67,7 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@@ -129,6 +133,8 @@ github.com/lestrrat-go/jwx v0.9.0 h1:Fnd0EWzTm0kFrBPzE/PEPp9nzllES5buMkksPMjEKpM
github.com/lestrrat-go/jwx v0.9.0/go.mod h1:iEoxlYfZjvoGpuWwxUz+eR5e6KTJGsaRcy/YNA/UnBk=
github.com/markbates/going v1.0.0 h1:DQw0ZP7NbNlFGcKbcE/IVSOAFzScxRtLpd0rLMzLhq0=
github.com/markbates/going v1.0.0/go.mod h1:I6mnB4BPnEeqo85ynXIx1ZFLLbtiLHNXVgWeFO9OGOA=
github.com/markbates/goth v1.65.0 h1:IbXpMneUhqbxgJ8JP1Ghl8ghlAaVX66jWDAapU1KxqU=
github.com/markbates/goth v1.65.0/go.mod h1:65frybxoeSCfORin51KOKqAKbIh7wREIDvdCkdWj//4=
github.com/mrjones/oauth v0.0.0-20180629183705-f4e24b6d100c h1:3wkDRdxK92dF+c1ke2dtj7ZzemFWBHB9plnJOtlwdFA=
github.com/mrjones/oauth v0.0.0-20180629183705-f4e24b6d100c/go.mod h1:skjdDftzkFALcuGzYSklqYd8gvat6F1gZJ4YPVbkZpM=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
@@ -137,8 +143,10 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
@@ -184,6 +192,7 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225 h1:kNX+jCowfMYzvlSvJu5pQWEmyWFrBXJ3PBy10xKMXK8=
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-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -209,10 +218,13 @@ golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200927032502-5d4f70055728/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200930145003-4acb6c075d10 h1:YfxMZzv3PjGonQYNUaeU2+DhAdqOxerQ30JFB6WgAXo=
golang.org/x/net v0.0.0-20200930145003-4acb6c075d10/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/oauth2 v0.0.0-20180620175406-ef147856a6dd h1:QQhib242ErYDSMitlBm8V7wYCm/1a25hV8qMadIKLPA=
golang.org/x/oauth2 v0.0.0-20180620175406-ef147856a6dd/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-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -220,6 +232,7 @@ golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4Iltr
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43 h1:ld7aEMNHoBnnDAX15v1T6z31v8HwR2A9FYOuAhWqkwc=
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -301,6 +314,7 @@ golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roY
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200806022845-90696ccdc692/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
golang.org/x/tools v0.0.0-20200929161345-d7fc70abf50f/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
@@ -361,6 +375,7 @@ google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEY
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200806141610-86f49bd18e98/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200929141702-51c3e5b607fe/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
@@ -8,7 +8,6 @@ import (
"fmt"
"io/ioutil"
"net/http"
"net/url"
"strings"
"time"
@@ -83,22 +82,6 @@ type OpenIDConfig struct {
Issuer string `json:"issuer"`
}
type RefreshTokenResponse struct {
AccessToken string `json:"access_token"`
// The OpenID spec defines the ID token as an optional response field in the
// refresh token flow. As a result, a new ID token may not be returned in a successful
// response.
// See more: https://openid.net/specs/openid-connect-core-1_0.html#RefreshingAccessToken
IdToken string `json:"id_token, omitempty"`
// The OAuth spec defines the refresh token as an optional response field in the
// refresh token flow. As a result, a new refresh token may not be returned in a successful
// response.
//See more: https://www.oauth.com/oauth2-servers/making-authenticated-requests/refreshing-an-access-token/
RefreshToken string `json:"refresh_token,omitempty"`
}
// New creates a new OpenID Connect provider, and sets up important connection details.
// You should always call `openidConnect.New` to get a new Provider. Never try to create
// one manually.
@@ -219,49 +202,6 @@ func (p *Provider) RefreshToken(refreshToken string) (*oauth2.Token, error) {
return newToken, err
}
// The ID token is a fundamental part of the OpenID connect refresh token flow but is not part of the OAuth flow.
// The existing RefreshToken function leverages the OAuth library's refresh token mechanism, ignoring the refreshed
// ID token. As a result, a new function needs to be exposed (rather than changing the existing function, for backwards
// compatibility purposes) that also returns the id_token in the OpenID refresh token flow API response
// Learn more about ID tokens: https://openid.net/specs/openid-connect-core-1_0.html#IDToken
func (p *Provider) RefreshTokenWithIDToken(refreshToken string) (*RefreshTokenResponse, error) {
urlValues := url.Values{
"grant_type": {"refresh_token"},
"refresh_token": {refreshToken},
"client_id": {p.ClientKey},
"client_secret": {p.Secret},
}
req, err := http.NewRequest("POST", p.OpenIDConfig.TokenEndpoint, strings.NewReader(urlValues.Encode()))
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
resp, err := p.Client().Do(req)
if err != nil {
return nil, err
}
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("Non-200 response from RefreshToken: %d, WWW-Authenticate=%s", resp.StatusCode, resp.Header.Get("WWW-Authenticate"))
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
resp.Body.Close()
refreshTokenResponse := &RefreshTokenResponse{}
err = json.Unmarshal(body, refreshTokenResponse)
if err != nil {
return nil, err
}
return refreshTokenResponse, nil
}
// validate according to standard, returns expiry
// http://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation
func (p *Provider) validateClaims(claims map[string]interface{}) (time.Time, error) {
+5 -6
View File
@@ -25,7 +25,7 @@ gitea.com/go-chi/session/couchbase
gitea.com/go-chi/session/memcache
gitea.com/go-chi/session/mysql
gitea.com/go-chi/session/postgres
# gitea.com/lunny/levelqueue v0.4.0
# gitea.com/lunny/levelqueue v0.3.0
## explicit
gitea.com/lunny/levelqueue
# github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c
@@ -225,6 +225,9 @@ github.com/denisenkom/go-mssqldb
github.com/denisenkom/go-mssqldb/internal/cp
github.com/denisenkom/go-mssqldb/internal/decimal
github.com/denisenkom/go-mssqldb/internal/querytext
# github.com/dgrijalva/jwt-go v3.2.0+incompatible
## explicit
github.com/dgrijalva/jwt-go
# github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f
github.com/dgryski/go-rendezvous
# github.com/djherbis/buffer v1.2.0
@@ -428,9 +431,6 @@ github.com/gogs/cron
# github.com/gogs/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85
## explicit
github.com/gogs/go-gogs-client
# github.com/golang-jwt/jwt v3.2.2+incompatible
## explicit
github.com/golang-jwt/jwt
# github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe
github.com/golang-sql/civil
# github.com/golang/protobuf v1.5.2
@@ -570,7 +570,7 @@ github.com/mailru/easyjson
github.com/mailru/easyjson/buffer
github.com/mailru/easyjson/jlexer
github.com/mailru/easyjson/jwriter
# github.com/markbates/goth v1.68.0
# github.com/markbates/goth v1.67.1
## explicit
github.com/markbates/goth
github.com/markbates/goth/gothic
@@ -1053,4 +1053,3 @@ xorm.io/xorm/names
xorm.io/xorm/schemas
xorm.io/xorm/tags
# github.com/hashicorp/go-version => github.com/6543/go-version v1.3.1
# github.com/golang-jwt/jwt v3.2.1+incompatible => github.com/golang-jwt/jwt v3.2.2+incompatible
+2 -2
View File
@@ -30873,7 +30873,7 @@ ol.ui.suffixed.list li:before,
List
---------------*/
/* Menu divider shouldnt apply */
/* Menu divider shouldn't apply */
.ui.menu .list .item:before {
background: none !important;
@@ -31802,7 +31802,7 @@ Floated Menu / Item
opacity: 1;
}
/* Icon Gylph */
/* Icon Glyph */
.ui.icon.menu i.icon:before {
opacity: 1;
+8 -108
View File
@@ -142,7 +142,7 @@ $.api = $.fn.api = function(parameters) {
response = JSON.parse(response);
}
catch(e) {
// isnt json string
// isn't json string
}
}
return response;
@@ -2220,7 +2220,7 @@ $.fn.dimmer = function(parameters) {
event: {
click: function(event) {
module.verbose('Determining if event occured on dimmer', event);
module.verbose('Determining if event occurred on dimmer', event);
if( $dimmer.find(event.target).length === 0 || $(event.target).is(selector.content) ) {
module.hide();
event.stopImmediatePropagation();
@@ -2827,13 +2827,6 @@ $.fn.dimmer.settings = {
*
*/
/*
* Copyright 2019 The Gitea Authors
* Released under the MIT license
* http://opensource.org/licenses/MIT
* This version has been modified by Gitea to improve accessibility.
*/
;(function ($, window, document, undefined) {
'use strict';
@@ -2867,7 +2860,6 @@ $.fn.dropdown = function(parameters) {
query = arguments[0],
methodInvoked = (typeof query == 'string'),
queryArguments = [].slice.call(arguments, 1),
lastAriaID = 1,
returnedValue
;
@@ -2960,8 +2952,6 @@ $.fn.dropdown = function(parameters) {
module.observeChanges();
module.instantiate();
module.aria.setup();
}
},
@@ -3162,86 +3152,6 @@ $.fn.dropdown = function(parameters) {
}
},
aria: {
setup: function() {
var role = module.aria.guessRole();
if( role !== 'menu' ) {
return;
}
$module.attr('aria-busy', 'true');
$module.attr('role', 'menu');
$module.attr('aria-haspopup', 'menu');
$module.attr('aria-expanded', 'false');
$menu.find('.divider').attr('role', 'separator');
$item.attr('role', 'menuitem');
$item.each(function (index, item) {
if( !item.id ) {
item.id = module.aria.nextID('menuitem');
}
});
$text = $module
.find('> .text')
.eq(0)
;
if( $module.data('content') ) {
$text.attr('aria-hidden');
$module.attr('aria-label', $module.data('content'));
}
else {
$text.attr('id', module.aria.nextID('menutext'));
$module.attr('aria-labelledby', $text.attr('id'));
}
$module.attr('aria-busy', 'false');
},
nextID: function(prefix) {
var nextID;
do {
nextID = prefix + '_' + lastAriaID++;
} while( document.getElementById(nextID) );
return nextID;
},
setExpanded: function(expanded) {
if( $module.attr('aria-haspopup') ) {
$module.attr('aria-expanded', expanded);
}
},
refreshDescendant: function() {
if( $module.attr('aria-haspopup') !== 'menu' ) {
return;
}
var
$currentlySelected = $item.not(selector.unselectable).filter('.' + className.selected).eq(0),
$activeItem = $menu.children('.' + className.active).eq(0),
$selectedItem = ($currentlySelected.length > 0)
? $currentlySelected
: $activeItem
;
if( $selectedItem ) {
$module.attr('aria-activedescendant', $selectedItem.attr('id'));
}
else {
module.aria.removeDescendant();
}
},
removeDescendant: function() {
if( $module.attr('aria-haspopup') == 'menu' ) {
$module.removeAttr('aria-activedescendant');
}
},
guessRole: function() {
var
isIcon = $module.hasClass('icon'),
hasSearch = module.has.search(),
hasInput = ($input.length > 0),
isMultiple = module.is.multiple()
;
if ( !isIcon && !hasSearch && !hasInput && !isMultiple ) {
return 'menu';
}
return 'unknown';
}
},
setup: {
api: function() {
var
@@ -3288,7 +3198,6 @@ $.fn.dropdown = function(parameters) {
if(settings.allowTab) {
module.set.tabbable();
}
$item.attr('tabindex', '-1');
},
select: function() {
var
@@ -3435,8 +3344,6 @@ $.fn.dropdown = function(parameters) {
return true;
}
if(settings.onShow.call(element) !== false) {
module.aria.setExpanded(true);
module.aria.refreshDescendant();
module.animate.show(function() {
if( module.can.click() ) {
module.bind.intent();
@@ -3459,11 +3366,9 @@ $.fn.dropdown = function(parameters) {
if( module.is.active() && !module.is.animatingOutward() ) {
module.debug('Hiding dropdown');
if(settings.onHide.call(element) !== false) {
module.aria.setExpanded(false);
module.aria.removeDescendant();
module.animate.hide(function() {
module.remove.visible();
// hidding search focus
// hiding search focus
if ( module.is.focusedOnSearch() && preventBlur !== true ) {
$search.blur();
}
@@ -4414,7 +4319,7 @@ $.fn.dropdown = function(parameters) {
// allow selection with menu closed
if(isAdditionWithoutMenu) {
module.verbose('Selecting item from keyboard shortcut', $selectedItem);
$selectedItem[0].click();
module.event.item.click.call($selectedItem, event);
if(module.is.searchSelection()) {
module.remove.searchTerm();
}
@@ -4434,7 +4339,7 @@ $.fn.dropdown = function(parameters) {
}
else if(selectedIsSelectable) {
module.verbose('Selecting item from keyboard shortcut', $selectedItem);
$selectedItem[0].click();
module.event.item.click.call($selectedItem, event);
if(module.is.searchSelection()) {
module.remove.searchTerm();
if(module.is.multiple()) {
@@ -4462,7 +4367,6 @@ $.fn.dropdown = function(parameters) {
.closest(selector.item)
.addClass(className.selected)
;
module.aria.refreshDescendant();
event.preventDefault();
}
}
@@ -4479,7 +4383,6 @@ $.fn.dropdown = function(parameters) {
.find(selector.item).eq(0)
.addClass(className.selected)
;
module.aria.refreshDescendant();
event.preventDefault();
}
}
@@ -4504,7 +4407,6 @@ $.fn.dropdown = function(parameters) {
$nextItem
.addClass(className.selected)
;
module.aria.refreshDescendant();
module.set.scrollPosition($nextItem);
if(settings.selectOnKeydown && module.is.single()) {
module.set.selectedItem($nextItem);
@@ -4532,7 +4434,6 @@ $.fn.dropdown = function(parameters) {
$nextItem
.addClass(className.selected)
;
module.aria.refreshDescendant();
module.set.scrollPosition($nextItem);
if(settings.selectOnKeydown && module.is.single()) {
module.set.selectedItem($nextItem);
@@ -5502,7 +5403,6 @@ $.fn.dropdown = function(parameters) {
module.set.scrollPosition($nextValue);
$selectedItem.removeClass(className.selected);
$nextValue.addClass(className.selected);
module.aria.refreshDescendant();
if(settings.selectOnKeydown && module.is.single()) {
module.set.selectedItem($nextValue);
}
@@ -12037,7 +11937,7 @@ $.fn.progress = function(parameters) {
*
* @param min A minimum value within multiple values
* @param total A total amount of multiple values
* @returns {number} A precison. Could be 1, 10, 100, ... 1e+10.
* @returns {number} A precision. Could be 1, 10, 100, ... 1e+10.
*/
derivePrecision: function(min, total) {
var precisionPower = 0
@@ -12937,7 +12837,7 @@ $.fn.progress.settings = {
nonNumeric : 'Progress value is non numeric',
tooHigh : 'Value specified is above 100%',
tooLow : 'Value specified is below 0%',
sumExceedsTotal : 'Sum of multple values exceed total',
sumExceedsTotal : 'Sum of multiple values exceed total',
},
regExp: {
@@ -18176,7 +18076,7 @@ $.fn.transition.settings = {
// possible errors
error: {
noAnimation : 'Element is no longer attached to DOM. Unable to animate. Use silent setting to surpress this warning in production.',
noAnimation : 'Element is no longer attached to DOM. Unable to animate. Use silent setting to suppress this warning in production.',
repeated : 'That animation is already occurring, cancelling repeated animation',
method : 'The method you called is not defined',
support : 'This browser does not support CSS animations'
+4 -12
View File
@@ -1,7 +1,5 @@
const {AppSubUrl, csrf, NotificationSettings} = window.config;
let notificationSequenceNumber = 0;
export function initNotificationsTable() {
$('#notification_table .button').on('click', async function () {
const data = await updateNotification(
@@ -12,10 +10,8 @@ export function initNotificationsTable() {
$(this).data('notification-id'),
);
if ($(data).data('sequence-number') === notificationSequenceNumber) {
$('#notification_div').replaceWith(data);
initNotificationsTable();
}
$('#notification_div').replaceWith(data);
initNotificationsTable();
await updateNotificationCount();
return false;
@@ -143,13 +139,10 @@ async function updateNotificationTable() {
url: `${AppSubUrl}/notifications?${notificationDiv.data('params')}`,
data: {
'div-only': true,
'sequence-number': ++notificationSequenceNumber,
}
});
if ($(data).data('sequence-number') === notificationSequenceNumber) {
notificationDiv.replaceWith(data);
initNotificationsTable();
}
notificationDiv.replaceWith(data);
initNotificationsTable();
}
}
@@ -189,7 +182,6 @@ async function updateNotification(url, status, page, q, notificationID) {
page,
q,
noredirect: true,
'sequence-number': ++notificationSequenceNumber,
},
});
}

Some files were not shown because too many files have changed in this diff Show More