mirror of
https://github.com/gogs/gogs.git
synced 2026-02-28 09:10:57 +01:00
Compare commits
44 Commits
v0.14.1-rc
...
v0.12.7-rc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d06ba7e527 | ||
|
|
b0a902dcca | ||
|
|
bc77440b30 | ||
|
|
2a8f561c64 | ||
|
|
8a046c22a8 | ||
|
|
26395294bd | ||
|
|
c91365774b | ||
|
|
dff067ac28 | ||
|
|
45fdfecf64 | ||
|
|
1bf5d89386 | ||
|
|
670cbccf98 | ||
|
|
4e10265568 | ||
|
|
640e2f62e0 | ||
|
|
eddae31ada | ||
|
|
0fef3c9082 | ||
|
|
5aca56d2dd | ||
|
|
e309bc8324 | ||
|
|
64102be2c9 | ||
|
|
91f2cde5e9 | ||
|
|
b3541030c3 | ||
|
|
bc8b8c3767 | ||
|
|
d4ae178b72 | ||
|
|
fa1d9174ad | ||
|
|
2210ab7a42 | ||
|
|
01a2c68abb | ||
|
|
2626bcf94f | ||
|
|
5a04c47cf0 | ||
|
|
ec84506da4 | ||
|
|
eb3386c4aa | ||
|
|
f0e3cd90f8 | ||
|
|
fbe34c8c61 | ||
|
|
e6b4c467e8 | ||
|
|
6b6bfe8bb0 | ||
|
|
253b2bef4c | ||
|
|
1a051ae5f8 | ||
|
|
ca54cbd055 | ||
|
|
9044afa40f | ||
|
|
672625b55c | ||
|
|
98c65f319f | ||
|
|
43fc826085 | ||
|
|
d7a6bb8bcb | ||
|
|
db037495de | ||
|
|
39bdd5c2cd | ||
|
|
f17e7d5a2c |
212
.github/workflows/docker.yml
vendored
Normal file
212
.github/workflows/docker.yml
vendored
Normal file
@@ -0,0 +1,212 @@
|
||||
name: Docker
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
paths:
|
||||
- 'Dockerfile'
|
||||
- 'docker/**'
|
||||
- '.github/workflows/docker.yml'
|
||||
release:
|
||||
types: [ published ]
|
||||
|
||||
jobs:
|
||||
buildx:
|
||||
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: write
|
||||
contents: read
|
||||
packages: write
|
||||
steps:
|
||||
- name: Canel previous runs
|
||||
uses: styfle/cancel-workflow-action@0.9.1
|
||||
with:
|
||||
all_but_latest: true
|
||||
access_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
- name: Set up Docker Buildx
|
||||
id: buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
with:
|
||||
config-inline: |
|
||||
[worker.oci]
|
||||
max-parallelism = 2
|
||||
- name: Inspect builder
|
||||
run: |
|
||||
echo "Name: ${{ steps.buildx.outputs.name }}"
|
||||
echo "Endpoint: ${{ steps.buildx.outputs.endpoint }}"
|
||||
echo "Status: ${{ steps.buildx.outputs.status }}"
|
||||
echo "Flags: ${{ steps.buildx.outputs.flags }}"
|
||||
echo "Platforms: ${{ steps.buildx.outputs.platforms }}"
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
- name: Login to GitHub Container registry
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Build and push images
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
||||
push: true
|
||||
tags: |
|
||||
gogs/gogs:latest
|
||||
ghcr.io/gogs/gogs:latest
|
||||
- name: Send email on failure
|
||||
uses: dawidd6/action-send-mail@v3
|
||||
if: ${{ failure() }}
|
||||
with:
|
||||
server_address: smtp.mailgun.org
|
||||
server_port: 465
|
||||
username: ${{ secrets.SMTP_USERNAME }}
|
||||
password: ${{ secrets.SMTP_PASSWORD }}
|
||||
subject: GitHub Actions (${{ github.repository }}) job result
|
||||
to: github-actions-8ce6454@unknwon.io
|
||||
from: GitHub Actions (${{ github.repository }})
|
||||
reply_to: noreply@unknwon.io
|
||||
body: |
|
||||
The job "${{ github.job }}" of ${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }} completed with "${{ job.status }}".
|
||||
|
||||
View the job run at: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||||
|
||||
buildx-pull-request:
|
||||
if: ${{ github.event_name == 'pull_request' && github.repository == 'gogs/gogs' }}
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
- name: Set up Docker Buildx
|
||||
id: buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
with:
|
||||
config-inline: |
|
||||
[worker.oci]
|
||||
max-parallelism = 2
|
||||
- name: Inspect builder
|
||||
run: |
|
||||
echo "Name: ${{ steps.buildx.outputs.name }}"
|
||||
echo "Endpoint: ${{ steps.buildx.outputs.endpoint }}"
|
||||
echo "Status: ${{ steps.buildx.outputs.status }}"
|
||||
echo "Flags: ${{ steps.buildx.outputs.flags }}"
|
||||
echo "Platforms: ${{ steps.buildx.outputs.platforms }}"
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
- name: Compute short commit SHA
|
||||
uses: benjlevesque/short-sha@v1.2
|
||||
- name: Build and push images
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64
|
||||
push: true
|
||||
tags: |
|
||||
gogs/gogs:commit-${{ env.SHA }}
|
||||
|
||||
buildx-pull-request-fork:
|
||||
if: ${{ github.event_name == 'pull_request' && github.repository != 'gogs/gogs' }}
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
- name: Set up Docker Buildx
|
||||
id: buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
with:
|
||||
config-inline: |
|
||||
[worker.oci]
|
||||
max-parallelism = 2
|
||||
- name: Inspect builder
|
||||
run: |
|
||||
echo "Name: ${{ steps.buildx.outputs.name }}"
|
||||
echo "Endpoint: ${{ steps.buildx.outputs.endpoint }}"
|
||||
echo "Status: ${{ steps.buildx.outputs.status }}"
|
||||
echo "Flags: ${{ steps.buildx.outputs.flags }}"
|
||||
echo "Platforms: ${{ steps.buildx.outputs.platforms }}"
|
||||
- name: Build images
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64
|
||||
|
||||
buildx-release:
|
||||
if: ${{ github.event_name == 'release' }}
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: write
|
||||
contents: read
|
||||
packages: write
|
||||
steps:
|
||||
- name: Compute image tag name
|
||||
run: echo "IMAGE_TAG=$(echo $GITHUB_REF_NAME | cut -c 2-)" >> $GITHUB_ENV
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
- name: Set up Docker Buildx
|
||||
id: buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
with:
|
||||
config-inline: |
|
||||
[worker.oci]
|
||||
max-parallelism = 2
|
||||
- name: Inspect builder
|
||||
run: |
|
||||
echo "Name: ${{ steps.buildx.outputs.name }}"
|
||||
echo "Endpoint: ${{ steps.buildx.outputs.endpoint }}"
|
||||
echo "Status: ${{ steps.buildx.outputs.status }}"
|
||||
echo "Flags: ${{ steps.buildx.outputs.flags }}"
|
||||
echo "Platforms: ${{ steps.buildx.outputs.platforms }}"
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
- name: Login to GitHub Container registry
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Build and push images
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
||||
push: true
|
||||
tags: |
|
||||
gogs/gogs:${{ env.IMAGE_TAG }}
|
||||
ghcr.io/gogs/gogs:${{ env.IMAGE_TAG }}
|
||||
- name: Send email on failure
|
||||
uses: dawidd6/action-send-mail@v3
|
||||
if: ${{ failure() }}
|
||||
with:
|
||||
server_address: smtp.mailgun.org
|
||||
server_port: 465
|
||||
username: ${{ secrets.SMTP_USERNAME }}
|
||||
password: ${{ secrets.SMTP_PASSWORD }}
|
||||
subject: GitHub Actions (${{ github.repository }}) job result
|
||||
to: github-actions-8ce6454@unknwon.io
|
||||
from: GitHub Actions (${{ github.repository }})
|
||||
reply_to: noreply@unknwon.io
|
||||
body: |
|
||||
The job "${{ github.job }}" of ${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }} completed with "${{ job.status }}".
|
||||
|
||||
View the job run at: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||||
70
.github/workflows/go.yml
vendored
70
.github/workflows/go.yml
vendored
@@ -1,8 +1,20 @@
|
||||
name: Go
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
branches:
|
||||
- main
|
||||
- 'release/**'
|
||||
paths:
|
||||
- '**.go'
|
||||
- 'go.mod'
|
||||
- '.golangci.yml'
|
||||
- '.github/workflows/go.yml'
|
||||
pull_request:
|
||||
paths:
|
||||
- '**.go'
|
||||
- 'go.mod'
|
||||
- '.golangci.yml'
|
||||
- '.github/workflows/go.yml'
|
||||
env:
|
||||
GOPROXY: "https://proxy.golang.org"
|
||||
|
||||
@@ -11,38 +23,66 @@ jobs:
|
||||
name: Lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
- name: Run golangci-lint
|
||||
uses: actions-contrib/golangci-lint@v1
|
||||
uses: golangci/golangci-lint-action@v2
|
||||
with:
|
||||
args: 'run --timeout=30m'
|
||||
version: latest
|
||||
args: --timeout=30m
|
||||
- name: Install Task
|
||||
uses: arduino/setup-task@v1
|
||||
- name: Install go-bindata
|
||||
shell: bash
|
||||
run: |
|
||||
curl --silent --location --output /usr/local/bin/go-bindata https://github.com/kevinburke/go-bindata/releases/download/v3.23.0/go-bindata-linux-amd64
|
||||
chmod +x /usr/local/bin/go-bindata
|
||||
- name: Check Go module tidiness
|
||||
shell: bash
|
||||
run: |
|
||||
go mod tidy
|
||||
STATUS=$(git status --porcelain)
|
||||
if [ ! -z "$STATUS" ]; then
|
||||
echo "Unstaged files:"
|
||||
echo $STATUS
|
||||
echo "Run 'go mod tidy' and commit them"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
test:
|
||||
name: Test
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.14.x]
|
||||
platform: [ubuntu-latest, macos-latest, windows-latest]
|
||||
go-version: [ 1.14.x, 1.15.x, 1.16.x, 1.17.x, 1.18.x ]
|
||||
platform: [ ubuntu-latest, macos-latest, windows-latest ]
|
||||
runs-on: ${{ matrix.platform }}
|
||||
steps:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v1
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: ${{ matrix.go-version }}
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
- name: Run unit tests
|
||||
- name: Run tests with coverage
|
||||
run: go test -v -race -coverprofile=coverage -covermode=atomic ./...
|
||||
- name: Upload coverage report to Codecov
|
||||
uses: codecov/codecov-action@v1.0.6
|
||||
uses: codecov/codecov-action@v1.5.0
|
||||
with:
|
||||
file: ./coverage
|
||||
flags: unittests
|
||||
- name: Cache downloaded modules
|
||||
uses: actions/cache@v1
|
||||
- name: Send email on failure
|
||||
uses: dawidd6/action-send-mail@v3
|
||||
if: ${{ failure() && github.event_name == 'push' && github.ref == 'refs/heads/main' }}
|
||||
with:
|
||||
path: ~/go/pkg/mod
|
||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-go-
|
||||
server_address: smtp.mailgun.org
|
||||
server_port: 465
|
||||
username: ${{ secrets.SMTP_USERNAME }}
|
||||
password: ${{ secrets.SMTP_PASSWORD }}
|
||||
subject: GitHub Actions (${{ github.repository }}) job result
|
||||
to: github-actions-8ce6454@unknwon.io
|
||||
from: GitHub Actions (${{ github.repository }})
|
||||
reply_to: noreply@unknwon.io
|
||||
body: |
|
||||
The job "${{ github.job }}" of ${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }} completed with "${{ job.status }}".
|
||||
|
||||
View the job run at: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||||
|
||||
12
.github/workflows/lsif.yml
vendored
12
.github/workflows/lsif.yml
vendored
@@ -1,11 +1,19 @@
|
||||
name: LSIF
|
||||
on: [push]
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- '**.go'
|
||||
- 'go.mod'
|
||||
- '.github/workflows/lsif.yml'
|
||||
env:
|
||||
GOPROXY: "https://proxy.golang.org"
|
||||
|
||||
jobs:
|
||||
lsif-go:
|
||||
if: github.repository == 'gogs/gogs'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/checkout@v2
|
||||
- name: Generate LSIF data
|
||||
uses: sourcegraph/lsif-go-action@master
|
||||
- name: Upload LSIF data to sourcegraph.com
|
||||
|
||||
5
.github/workflows/shell.yml
vendored
5
.github/workflows/shell.yml
vendored
@@ -1,13 +1,14 @@
|
||||
name: Shell
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
shellcheck:
|
||||
name: Shellcheck
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- uses: actions/checkout@v2
|
||||
- name: Run ShellCheck
|
||||
uses: ludeeus/action-shellcheck@master
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -16,3 +16,4 @@ output*
|
||||
*.sublime-project
|
||||
*.sublime-workspace
|
||||
/release
|
||||
.task
|
||||
|
||||
26
.golangci.yml
Normal file
26
.golangci.yml
Normal file
@@ -0,0 +1,26 @@
|
||||
linters-settings:
|
||||
staticcheck:
|
||||
checks: [
|
||||
"all",
|
||||
"-SA1019" # There are valid use cases of strings.Title
|
||||
]
|
||||
nakedret:
|
||||
max-func-lines: 0 # Disallow any unnamed return statement
|
||||
|
||||
linters:
|
||||
enable:
|
||||
- deadcode
|
||||
- errcheck
|
||||
- gosimple
|
||||
- govet
|
||||
- ineffassign
|
||||
- staticcheck
|
||||
- structcheck
|
||||
- typecheck
|
||||
- unused
|
||||
- varcheck
|
||||
- nakedret
|
||||
- gofmt
|
||||
- rowserrcheck
|
||||
- unconvert
|
||||
- goimports
|
||||
68
CHANGELOG.md
68
CHANGELOG.md
@@ -2,13 +2,76 @@
|
||||
|
||||
All notable changes to Gogs are documented in this file.
|
||||
|
||||
## 0.13.0+dev (`master`)
|
||||
## 0.13.0+dev (`main`)
|
||||
|
||||
### Added
|
||||
|
||||
- An unlisted option is added when create or migrate a repository. Unlisted repositories are public but not being listed for users without direct access in the UI. [#5733](https://github.com/gogs/gogs/issues/5733)
|
||||
- New configuration option `[git.timeout] DIFF` for customizing operation timeout of `git diff`. [#6315](https://github.com/gogs/gogs/issues/6315)
|
||||
- New configuration option `[server] SSH_SERVER_MACS` for setting list of accepted MACs for connections to builtin SSH server. [#6434](https://github.com/gogs/gogs/issues/6434)
|
||||
- Support specifying custom schema for PostgreSQL. [#6695](https://github.com/gogs/gogs/pull/6695)
|
||||
- New languages support: Mongolian. [#6510](https://github.com/gogs/gogs/pull/6510)
|
||||
|
||||
### Changed
|
||||
|
||||
- The default branch has been changed to `main`. [#6285](https://github.com/gogs/gogs/pull/6285)
|
||||
- MSSQL as database backend is deprecated, installation page no longer shows it as an option. Existing installations and manually craft configuration file continue to work. [#6295](https://github.com/gogs/gogs/pull/6295)
|
||||
- Use [Task](https://github.com/go-task/task) as the default build tool for development. [#6297](https://github.com/gogs/gogs/pull/6297)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Add `X-Frame-Options` header to prevent Clickjacking. [#6409](https://github.com/gogs/gogs/issues/6409)
|
||||
- _Regression:_ Fixed smart links for issues stops rendering. [#6506](https://github.com/gogs/gogs/issues/6506)
|
||||
- _Security:_ Potential SSRF attack by CRLF injection via repository migration. [#6413](https://github.com/gogs/gogs/issues/6413)
|
||||
|
||||
### Removed
|
||||
|
||||
- ⚠️ Migrations before 0.12 are removed, installations not on 0.12 should upgrade to it to run the migrations and then upgrade to 0.13.
|
||||
- Configuration section `[mailer]` is no longer used, please use `[email]`.
|
||||
- Configuration section `[service]` is no longer used, please use `[auth]`.
|
||||
- Configuration option `APP_NAME` is no longer used, please use `BRAND_NAME`.
|
||||
- Configuration option `[security] REVERSE_PROXY_AUTHENTICATION_USER` is no longer used, please use `[auth] REVERSE_PROXY_AUTHENTICATION_HEADER`.
|
||||
- Configuration option `[auth] ACTIVE_CODE_LIVE_MINUTES` is no longer used, please use `[auth] ACTIVATE_CODE_LIVES`.
|
||||
- Configuration option `[auth] RESET_PASSWD_CODE_LIVE_MINUTES` is no longer used, please use `[auth] RESET_PASSWORD_CODE_LIVES`.
|
||||
- Configuration option `[auth] ENABLE_CAPTCHA` is no longer used, please use `[auth] ENABLE_REGISTRATION_CAPTCHA`.
|
||||
- Configuration option `[auth] ENABLE_NOTIFY_MAIL` is no longer used, please use `[user] ENABLE_EMAIL_NOTIFICATION`.
|
||||
- Configuration option `[auth] REGISTER_EMAIL_CONFIRM` is no longer used, please use `[auth] REQUIRE_EMAIL_CONFIRMATION`.
|
||||
- Configuration option `[session] GC_INTERVAL_TIME` is no longer used, please use `[session] GC_INTERVAL`.
|
||||
- Configuration option `[session] SESSION_LIFE_TIME` is no longer used, please use `[session] MAX_LIFE_TIME`.
|
||||
- Configuration option `[server] ROOT_URL` is no longer used, please use `[server] EXTERNAL_URL`.
|
||||
- Configuration option `[server] LANDING_PAGE` is no longer used, please use `[server] LANDING_URL`.
|
||||
- Configuration option `[database] DB_TYPE` is no longer used, please use `[database] TYPE`.
|
||||
- Configuration option `[database] PASSWD` is no longer used, please use `[database] PASSWORD`.
|
||||
|
||||
## 0.12.3
|
||||
|
||||
### Fixed
|
||||
|
||||
- _Regression:_ When running Gogs on Windows, push commits no longer fail on a daily basis with the error "pre-receive hook declined". [#6316](https://github.com/gogs/gogs/issues/6316)
|
||||
- Auto-linked commit SHAs now have correct links. [#6300](https://github.com/gogs/gogs/issues/6300)
|
||||
- Git LFS client (with version >= 2.5.0) wasn't able to upload files with known format (e.g. PNG, JPEG), and the server is expecting the HTTP Header `Content-Type` to be `application/octet-stream`. The server now tells the LFS client to always use `Content-Type: application/octet-stream` when upload files.
|
||||
|
||||
## 0.12.2
|
||||
|
||||
### Fixed
|
||||
|
||||
- _Regression:_ Pages are correctly rendered when requesting `?go-get=1` for subdirectories. [#6314](https://github.com/gogs/gogs/issues/6314)
|
||||
- _Regression:_ Submodule with a relative path is linked correctly. [#6319](https://github.com/gogs/gogs/issues/6319)
|
||||
- Backup can be processed when `--target` is specified on Windows. [#6339](https://github.com/gogs/gogs/issues/6339)
|
||||
- Commit message contains keywords look like an issue reference no longer fails the push entirely. [#6289](https://github.com/gogs/gogs/issues/6289)
|
||||
|
||||
## 0.12.1
|
||||
|
||||
### Fixed
|
||||
|
||||
- The `updated_at` field is now correctly updated when updates an issue. [#6209](https://github.com/gogs/gogs/issues/6209)
|
||||
- Fixed a regression which created `login_source.cfg` column to have `VARCHAR(255)` instead of `TEXT` in MySQL. [#6280](https://github.com/gogs/gogs/issues/6280)
|
||||
|
||||
## 0.12.0
|
||||
|
||||
### Added
|
||||
|
||||
- Support for Git LFS, you can read documentation for both [user](https://github.com/gogs/gogs/blob/master/docs/user/lfs.md) and [admin](https://github.com/gogs/gogs/blob/master/docs/admin/lfs.md). [#1322](https://github.com/gogs/gogs/issues/1322)
|
||||
- Support for Git LFS, you can read documentation for both [user](https://github.com/gogs/gogs/blob/main/docs/user/lfs.md) and [admin](https://github.com/gogs/gogs/blob/main/docs/admin/lfs.md). [#1322](https://github.com/gogs/gogs/issues/1322)
|
||||
- Allow admin to remove observers from the repository. [#5803](https://github.com/gogs/gogs/pull/5803)
|
||||
- Use `Last-Modified` HTTP header for raw files. [#5811](https://github.com/gogs/gogs/issues/5811)
|
||||
- Support syntax highlighting for SAS code files (i.e. `.r`, `.sas`, `.tex`, `.yaml`). [#5856](https://github.com/gogs/gogs/pull/5856)
|
||||
@@ -34,6 +97,7 @@ All notable changes to Gogs are documented in this file.
|
||||
- Configuration section `[service]` is deprecated and will end support in 0.13.0, please start using `[auth]`.
|
||||
- Configuration option `[auth] ACTIVE_CODE_LIVE_MINUTES` is deprecated and will end support in 0.13.0, please start using `[auth] ACTIVATE_CODE_LIVES`.
|
||||
- Configuration option `[auth] RESET_PASSWD_CODE_LIVE_MINUTES` is deprecated and will end support in 0.13.0, please start using `[auth] RESET_PASSWORD_CODE_LIVES`.
|
||||
- Configuration option `[auth] REGISTER_EMAIL_CONFIRM` is deprecated and will end support in 0.13.0, please start using `[auth] REQUIRE_EMAIL_CONFIRMATION`.
|
||||
- Configuration option `[auth] ENABLE_CAPTCHA` is deprecated and will end support in 0.13.0, please start using `[auth] ENABLE_REGISTRATION_CAPTCHA`.
|
||||
- Configuration option `[auth] ENABLE_NOTIFY_MAIL` is deprecated and will end support in 0.13.0, please start using `[user] ENABLE_EMAIL_NOTIFICATION`.
|
||||
- Configuration option `[session] GC_INTERVAL_TIME` is deprecated and will end support in 0.13.0, please start using `[session] GC_INTERVAL`.
|
||||
|
||||
21
Dockerfile
21
Dockerfile
@@ -1,4 +1,4 @@
|
||||
FROM golang:alpine3.11 AS binarybuilder
|
||||
FROM golang:alpine3.14 AS binarybuilder
|
||||
RUN apk --no-cache --no-progress add --virtual \
|
||||
build-deps \
|
||||
build-base \
|
||||
@@ -7,11 +7,18 @@ RUN apk --no-cache --no-progress add --virtual \
|
||||
|
||||
WORKDIR /gogs.io/gogs
|
||||
COPY . .
|
||||
RUN make build-no-gen TAGS="cert pam"
|
||||
RUN make build TAGS="cert pam"
|
||||
|
||||
FROM alpine:3.11
|
||||
ADD https://github.com/tianon/gosu/releases/download/1.11/gosu-amd64 /usr/sbin/gosu
|
||||
RUN chmod +x /usr/sbin/gosu \
|
||||
FROM alpine:3.14
|
||||
RUN if [ `uname -m` == "aarch64" ] ; then \
|
||||
export arch="arm64" ; \
|
||||
elif [ `uname -m` == "armv7l" ] ; then \
|
||||
export arch="armhf"; \
|
||||
else \
|
||||
export arch="amd64" ; \
|
||||
fi \
|
||||
&& wget https://github.com/tianon/gosu/releases/download/1.11/gosu-$arch -O /usr/sbin/gosu \
|
||||
&& chmod +x /usr/sbin/gosu \
|
||||
&& echo http://dl-2.alpinelinux.org/alpine/edge/community/ >> /etc/apk/repositories \
|
||||
&& apk --no-cache --no-progress add \
|
||||
bash \
|
||||
@@ -28,7 +35,7 @@ RUN chmod +x /usr/sbin/gosu \
|
||||
|
||||
ENV GOGS_CUSTOM /data/gogs
|
||||
|
||||
# Configure LibC Name Service
|
||||
# Configure LibC Name Service
|
||||
COPY docker/nsswitch.conf /etc/nsswitch.conf
|
||||
|
||||
WORKDIR /app/gogs
|
||||
@@ -37,7 +44,7 @@ COPY --from=binarybuilder /gogs.io/gogs/gogs .
|
||||
|
||||
RUN ./docker/finalize.sh
|
||||
|
||||
# Configure Docker Container
|
||||
# Configure Docker Container
|
||||
VOLUME ["/data", "/backup"]
|
||||
EXPOSE 22 3000
|
||||
ENTRYPOINT ["/app/gogs/docker/start.sh"]
|
||||
|
||||
21
Makefile
21
Makefile
@@ -5,8 +5,6 @@ CONF_FILES := $(shell find conf | sed 's/ /\\ /g')
|
||||
TEMPLATES_FILES := $(shell find templates | sed 's/ /\\ /g')
|
||||
PUBLIC_FILES := $(shell find public | sed 's/ /\\ /g')
|
||||
LESS_FILES := $(wildcard public/less/*.less)
|
||||
ASSETS_GENERATED := internal/assets/conf/conf_gen.go internal/assets/templates/templates_gen.go internal/assets/public/public_gen.go
|
||||
GENERATED := $(ASSETS_GENERATED) public/css/gogs.min.css
|
||||
|
||||
TAGS = ""
|
||||
BUILD_FLAGS = "-v"
|
||||
@@ -28,10 +26,7 @@ dist: release
|
||||
web: build
|
||||
./gogs web
|
||||
|
||||
build: $(GENERATED)
|
||||
go build $(BUILD_FLAGS) -ldflags '$(LDFLAGS)' -tags '$(TAGS)' -trimpath -o gogs
|
||||
|
||||
build-no-gen:
|
||||
build:
|
||||
go build $(BUILD_FLAGS) -ldflags '$(LDFLAGS)' -tags '$(TAGS)' -trimpath -o gogs
|
||||
|
||||
pack:
|
||||
@@ -42,22 +37,10 @@ pack:
|
||||
|
||||
release: build pack
|
||||
|
||||
generate: clean $(ASSETS_GENERATED)
|
||||
|
||||
internal/assets/conf/conf_gen.go: $(CONF_FILES)
|
||||
-rm -f $@
|
||||
generate: clean
|
||||
go generate internal/assets/conf/conf.go
|
||||
gofmt -s -w $@
|
||||
|
||||
internal/assets/templates/templates_gen.go: $(TEMPLATES_FILES)
|
||||
-rm -f $@
|
||||
go generate internal/assets/templates/templates.go
|
||||
gofmt -s -w $@
|
||||
|
||||
internal/assets/public/public_gen.go: $(PUBLIC_FILES)
|
||||
-rm -f $@
|
||||
go generate internal/assets/public/public.go
|
||||
gofmt -s -w $@
|
||||
|
||||
less: clean public/css/gogs.min.css
|
||||
|
||||
|
||||
91
Taskfile.yml
Normal file
91
Taskfile.yml
Normal file
@@ -0,0 +1,91 @@
|
||||
version: '3'
|
||||
|
||||
vars:
|
||||
BINARY_EXT:
|
||||
sh: echo '{{if eq OS "windows"}}.exe{{end}}'
|
||||
|
||||
tasks:
|
||||
web:
|
||||
desc: Build the binary and start the web server.
|
||||
deps: [build]
|
||||
cmds:
|
||||
- ./gogs web
|
||||
|
||||
build:
|
||||
desc: Build the binary.
|
||||
cmds:
|
||||
- go build -v
|
||||
-ldflags '
|
||||
-X "{{.PKG_PATH}}.BuildTime={{.BUILD_TIME}}"
|
||||
-X "{{.PKG_PATH}}.BuildCommit={{.BUILD_COMMIT}}"
|
||||
'
|
||||
-tags '{{.TAGS}}'
|
||||
-trimpath -o gogs{{.BINARY_EXT}}
|
||||
vars:
|
||||
PKG_PATH: gogs.io/gogs/internal/conf
|
||||
BUILD_TIME:
|
||||
sh: date -u '+%Y-%m-%d %I:%M:%S %Z'
|
||||
BUILD_COMMIT:
|
||||
sh: git rev-parse HEAD
|
||||
sources:
|
||||
- gogs.go
|
||||
- internal/**/*.go
|
||||
|
||||
generate-bindata:
|
||||
desc: Generate bindata for all assets.
|
||||
deps: [clean]
|
||||
cmds:
|
||||
- go generate internal/assets/conf/conf.go
|
||||
- go generate internal/assets/templates/templates.go
|
||||
- go generate internal/assets/public/public.go
|
||||
|
||||
generate-schemadoc:
|
||||
desc: Generate database schema documentation.
|
||||
cmds:
|
||||
- go generate ./internal/db/schemadoc
|
||||
|
||||
generate:
|
||||
desc: Run all go:generate commands.
|
||||
deps: [generate-bindata, generate-schemadoc]
|
||||
|
||||
test:
|
||||
desc: Run all tests.
|
||||
cmds:
|
||||
- go test -cover -race ./...
|
||||
|
||||
clean:
|
||||
desc: Cleans up system meta files for code generation.
|
||||
cmds:
|
||||
- find . -name "*.DS_Store" -type f -delete
|
||||
|
||||
release:
|
||||
desc: Build the binary and pack resources to a ZIP file.
|
||||
deps: [build]
|
||||
cmds:
|
||||
- rm -rf {{.RELEASE_GOGS}}
|
||||
- mkdir -p {{.RELEASE_GOGS}}
|
||||
- cp -r gogs{{.BINARY_EXT}} LICENSE README.md README_ZH.md scripts {{.RELEASE_GOGS}}
|
||||
- cd {{.RELEASE_ROOT}} && zip -r gogs.$(NOW).zip "gogs"
|
||||
vars:
|
||||
RELEASE_ROOT: release
|
||||
RELEASE_GOGS: release/gogs
|
||||
|
||||
less:
|
||||
desc: Generate CSS from LESS files.
|
||||
cmds:
|
||||
- lessc --clean-css --source-map "public/less/gogs.less" public/css/gogs.min.css
|
||||
|
||||
fixme:
|
||||
desc: Show all occurrences of "FIXME".
|
||||
cmds:
|
||||
- grep -rnw "FIXME" internal
|
||||
|
||||
todo:
|
||||
desc: Show all occurrences of "TODO".
|
||||
cmds:
|
||||
- grep -rnw "TODO" internal
|
||||
|
||||
legacy:
|
||||
desc: Identify legacy and deprecated lines.
|
||||
cmds:
|
||||
- grep -rnw "\(LEGACY\|Deprecated\)" internal
|
||||
@@ -169,6 +169,8 @@ COOKIE_SECURE = false
|
||||
ENABLE_LOGIN_STATUS_COOKIE = false
|
||||
; The cookie name to store user login status.
|
||||
LOGIN_STATUS_COOKIE_NAME = login_status
|
||||
; A comma separated list of hostnames that are explicitly allowed to be accessed within the local network.
|
||||
LOCAL_NETWORK_ALLOWLIST =
|
||||
|
||||
[email]
|
||||
; Whether to enable the email service.
|
||||
|
||||
@@ -1242,6 +1242,7 @@ config.security.cookie_secure = Enable secure cookie
|
||||
config.security.reverse_proxy_auth_user = Reverse proxy authentication header
|
||||
config.security.enable_login_status_cookie = Enable login status cookie
|
||||
config.security.login_status_cookie_name = Login status cookie
|
||||
config.security.local_network_allowlist = Local network allowlist
|
||||
|
||||
config.email_config = Email configuration
|
||||
config.email.enabled = Enabled
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
FROM arm64v8/golang:1.14-alpine3.11 AS binarybuilder
|
||||
RUN apk --no-cache --no-progress add --virtual \
|
||||
build-deps \
|
||||
build-base \
|
||||
git \
|
||||
linux-pam-dev
|
||||
|
||||
WORKDIR /gogs.io/gogs
|
||||
COPY . .
|
||||
RUN make build-no-gen TAGS="cert pam"
|
||||
|
||||
FROM arm64v8/alpine:3.11
|
||||
ADD https://github.com/tianon/gosu/releases/download/1.11/gosu-arm64 /usr/sbin/gosu
|
||||
RUN chmod +x /usr/sbin/gosu \
|
||||
&& echo http://dl-2.alpinelinux.org/alpine/edge/community/ >> /etc/apk/repositories \
|
||||
&& apk --no-cache --no-progress add \
|
||||
bash \
|
||||
ca-certificates \
|
||||
curl \
|
||||
git \
|
||||
linux-pam \
|
||||
openssh \
|
||||
s6 \
|
||||
shadow \
|
||||
socat \
|
||||
tzdata \
|
||||
rsync
|
||||
|
||||
ENV GOGS_CUSTOM /data/gogs
|
||||
|
||||
# Configure LibC Name Service
|
||||
COPY docker/nsswitch.conf /etc/nsswitch.conf
|
||||
|
||||
WORKDIR /app/gogs
|
||||
COPY docker ./docker
|
||||
COPY --from=binarybuilder /gogs.io/gogs/gogs .
|
||||
|
||||
RUN ./docker/finalize.sh
|
||||
|
||||
# Configure Docker Container
|
||||
VOLUME ["/data", "/backup"]
|
||||
EXPOSE 22 3000
|
||||
ENTRYPOINT ["/app/gogs/docker/start.sh"]
|
||||
CMD ["/bin/s6-svscan", "/app/gogs/docker/s6/"]
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM arm32v7/golang:1.14-alpine3.11 AS binarybuilder
|
||||
FROM arm32v7/golang:1.14-alpine3.14 AS binarybuilder
|
||||
RUN apk --no-cache --no-progress add --virtual \
|
||||
build-deps \
|
||||
build-base \
|
||||
@@ -7,11 +7,11 @@ RUN apk --no-cache --no-progress add --virtual \
|
||||
|
||||
WORKDIR /gogs.io/gogs
|
||||
COPY . .
|
||||
RUN make build-no-gen TAGS="cert pam"
|
||||
RUN make build TAGS="cert pam"
|
||||
|
||||
FROM arm32v7/alpine:3.11
|
||||
ADD https://github.com/tianon/gosu/releases/download/1.12/gosu-armhf /usr/sbin/gosu
|
||||
RUN chmod +x /usr/sbin/gosu \
|
||||
FROM arm32v7/alpine:3.14
|
||||
RUN wget https://github.com/tianon/gosu/releases/download/1.12/gosu-armhf -O /usr/sbin/gosu \
|
||||
&& chmod +x /usr/sbin/gosu \
|
||||
&& echo http://dl-2.alpinelinux.org/alpine/edge/community/ >> /etc/apk/repositories \
|
||||
&& apk --no-cache --no-progress add \
|
||||
bash \
|
||||
@@ -28,7 +28,7 @@ RUN chmod +x /usr/sbin/gosu \
|
||||
|
||||
ENV GOGS_CUSTOM /data/gogs
|
||||
|
||||
# Configure LibC Name Service
|
||||
# Configure LibC Name Service
|
||||
COPY docker/nsswitch.conf /etc/nsswitch.conf
|
||||
|
||||
WORKDIR /app/gogs
|
||||
@@ -37,8 +37,9 @@ COPY --from=binarybuilder /gogs.io/gogs/gogs .
|
||||
|
||||
RUN ./docker/finalize.sh
|
||||
|
||||
# Configure Docker Container
|
||||
# Configure Docker Container
|
||||
VOLUME ["/data", "/backup"]
|
||||
EXPOSE 22 3000
|
||||
HEALTHCHECK CMD (nc -z -w 3 localhost 22 && curl -o /dev/null -sS http://localhost:3000/healthcheck) || exit 1
|
||||
ENTRYPOINT ["/app/gogs/docker/start.sh"]
|
||||
CMD ["/bin/s6-svscan", "/app/gogs/docker/s6/"]
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Docker for Gogs
|
||||
|
||||
 
|
||||

|
||||
|
||||
Visit [Docker Hub](https://hub.docker.com/u/gogs) see all available images and tags.
|
||||
Visit [Docker Hub](https://hub.docker.com/u/gogs) or [GitHub Container registry](https://github.com/gogs/gogs/pkgs/container/gogs) to see all available images and tags.
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -18,13 +18,13 @@ $ docker pull gogs/gogs
|
||||
$ mkdir -p /var/gogs
|
||||
|
||||
# Use `docker run` for the first time.
|
||||
$ docker run --name=gogs -p 10022:22 -p 10080:3000 -v /var/gogs:/data gogs/gogs
|
||||
$ docker run --name=gogs -p 10022:22 -p 10880:3000 -v /var/gogs:/data gogs/gogs
|
||||
|
||||
# Use `docker start` if you have stopped it.
|
||||
$ docker start gogs
|
||||
```
|
||||
|
||||
Note: It is important to map the Gogs ssh service from the container to the host and set the appropriate SSH Port and URI settings when setting up Gogs for the first time. To access and clone Gogs Git repositories with the above configuration you would use: `git clone ssh://git@hostname:10022/username/myrepo.git` for example.
|
||||
Note: It is important to map the SSH service from the container to the host and set the appropriate SSH Port and URI settings when setting up Gogs for the first time. To access and clone Git repositories with the above configuration you would use: `git clone ssh://git@hostname:10022/username/myrepo.git` for example.
|
||||
|
||||
Files will be store in local path `/var/gogs` in my case.
|
||||
|
||||
@@ -40,50 +40,38 @@ Directory `/var/gogs` keeps Git repositories and Gogs data:
|
||||
|-- data
|
||||
|-- log
|
||||
|
||||
#### Custom Directory
|
||||
#### Custom directory
|
||||
|
||||
The "custom" directory may not be obvious in Docker environment. The `/var/gogs/gogs` (in the host) and `/data/gogs` (in the container) is already the "custom" directory and you do not need to create another layer but directly edit corresponding files under this directory.
|
||||
|
||||
### Volume With Data Container
|
||||
|
||||
If you're more comfortable with mounting data to a data container, the commands you execute at the first time will look like as follows:
|
||||
|
||||
```sh
|
||||
# Create data container
|
||||
docker run --name=gogs-data --entrypoint /bin/true gogs/gogs
|
||||
|
||||
# Use `docker run` for the first time.
|
||||
docker run --name=gogs --volumes-from gogs-data -p 10022:22 -p 10080:3000 gogs/gogs
|
||||
```
|
||||
|
||||
#### Using Docker 1.9 Volume Command
|
||||
#### Using Docker volumes
|
||||
|
||||
```sh
|
||||
# Create docker volume.
|
||||
$ docker volume create --name gogs-data
|
||||
|
||||
# Use `docker run` for the first time.
|
||||
$ docker run --name=gogs -p 10022:22 -p 10080:3000 -v gogs-data:/data gogs/gogs
|
||||
$ docker run --name=gogs -p 10022:22 -p 10880:3000 -v gogs-data:/data gogs/gogs
|
||||
```
|
||||
|
||||
## Settings
|
||||
|
||||
### Application
|
||||
|
||||
Most of settings are obvious and easy to understand, but there are some settings can be confusing by running Gogs inside Docker:
|
||||
Most of the settings are obvious and easy to understand, but there are some settings can be confusing by running Gogs inside Docker:
|
||||
|
||||
- **Repository Root Path**: keep it as default value `/home/git/gogs-repositories` because `start.sh` already made a symbolic link for you.
|
||||
- **Run User**: keep it as default value `git` because `finalize.sh` already setup a user with name `git`.
|
||||
- **Domain**: fill in with Docker container IP (e.g. `192.168.99.100`). But if you want to access your Gogs instance from a different physical machine, please fill in with the hostname or IP address of the Docker host machine.
|
||||
- **SSH Port**: Use the exposed port from Docker container. For example, your SSH server listens on `22` inside Docker, **but** you expose it by `10022:22`, then use `10022` for this value. **Builtin SSH server is not recommended inside Docker Container**
|
||||
- **HTTP Port**: Use port you want Gogs to listen on inside Docker container. For example, your Gogs listens on `3000` inside Docker, **and** you expose it by `10080:3000`, but you still use `3000` for this value.
|
||||
- **Application URL**: Use combination of **Domain** and **exposed HTTP Port** values (e.g. `http://192.168.99.100:10080/`).
|
||||
- **HTTP Port**: Use port you want Gogs to listen on inside Docker container. For example, your Gogs listens on `3000` inside Docker, **and** you expose it by `10880:3000`, but you still use `3000` for this value.
|
||||
- **Application URL**: Use combination of **Domain** and **exposed HTTP Port** values (e.g. `http://192.168.99.100:10880/`).
|
||||
|
||||
Full documentation of application settings can be found [here](https://github.com/gogs/gogs/blob/master/conf/app.ini).
|
||||
Full documentation of application settings can be found [here](https://github.com/gogs/gogs/blob/main/conf/app.ini).
|
||||
|
||||
### Container Options
|
||||
### Container options
|
||||
|
||||
This container have some options available via environment variables, these options are opt-in features that can help the administration of this container:
|
||||
This container has some options available via environment variables, these options are opt-in features that can help the administration of this container:
|
||||
|
||||
- **SOCAT_LINK**:
|
||||
- <u>Possible value:</u>
|
||||
@@ -135,7 +123,8 @@ This container have some options available via environment variables, these opti
|
||||
Used by backup system. If defined, supplies `--exclude-repos` argument to `gogs backup`.\
|
||||
See: [Backup System](#backup-system)
|
||||
|
||||
## Backup System
|
||||
## Backup system
|
||||
|
||||
Automated backups with retention policy:
|
||||
|
||||
- `BACKUP_INTERVAL` controls how often the backup job runs and supports interval in hours (h), days (d), and months (M), eg. `3h`, `7d`, `3M`. The lowest possible value is one hour (`1h`).
|
||||
@@ -152,10 +141,10 @@ Steps to upgrade Gogs with Docker:
|
||||
- `docker rm gogs`
|
||||
- Finally, create a container for the first time and don't forget to do the same for the volume and port mapping.
|
||||
|
||||
## Known Issues
|
||||
## Known issues
|
||||
|
||||
- The docker container cannot currently be built on Raspberry 1 (armv6l) as our base image `alpine` does not have a `go` package available for this platform.
|
||||
|
||||
## Useful Links
|
||||
## Useful links
|
||||
|
||||
- [Share port 22 between Gogs inside Docker & the local system](http://www.ateijelo.com/blog/2016/07/09/share-port-22-between-docker-gogs-ssh-and-local-system)
|
||||
|
||||
@@ -30,7 +30,9 @@ parse_generate_cron_expression() {
|
||||
CRON_EXPR_DAYS="*"
|
||||
CRON_EXPR_MONTHS="*"
|
||||
|
||||
# shellcheck disable=SC2001
|
||||
TIME_INTERVAL=$(echo "${BACKUP_INTERVAL}" | sed -e 's/[hdM]$//')
|
||||
# shellcheck disable=SC2001
|
||||
TIME_UNIT=$(echo "${BACKUP_INTERVAL}" | sed -e 's/^[0-9]\+//')
|
||||
|
||||
if [ "${TIME_UNIT}" = "h" ]; then
|
||||
@@ -74,7 +76,9 @@ parse_generate_cron_expression() {
|
||||
parse_generate_retention_expression() {
|
||||
FIND_TIME_EXPR='mtime'
|
||||
|
||||
# shellcheck disable=SC2001
|
||||
TIME_INTERVAL=$(echo "${BACKUP_RETENTION}" | sed -e 's/[mhdM]$//')
|
||||
# shellcheck disable=SC2001
|
||||
TIME_UNIT=$(echo "${BACKUP_RETENTION}" | sed -e 's/^[0-9]\+//')
|
||||
|
||||
if [ "${TIME_UNIT}" = "m" ]; then
|
||||
|
||||
@@ -17,10 +17,11 @@ main() {
|
||||
fi
|
||||
|
||||
if [ ! -d "${BACKUP_PATH}" ]; then
|
||||
echo "Error: BACKUP_PATH does't exist or is not a directory" 1>&2
|
||||
echo "Error: BACKUP_PATH doesn't exist or is not a directory" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# shellcheck disable=SC2086
|
||||
find "${BACKUP_PATH}/" -type f -name "gogs-backup-*.zip" -${FIND_EXPRESSION} -print -exec rm "{}" +
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Cleanup SOCAT services and s6 event folder
|
||||
rm -rf $(find /app/gogs/docker/s6/ -name 'event')
|
||||
rm -rf "$(find /app/gogs/docker/s6/ -name 'event')"
|
||||
rm -rf /app/gogs/docker/s6/SOCAT_*
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
# The default configuration is also calling all the scripts in /etc/periodic/${period}
|
||||
|
||||
if test -f ./setup; then
|
||||
# shellcheck disable=SC2039,SC1091,SC3046
|
||||
source ./setup
|
||||
fi
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
#!/bin/sh
|
||||
|
||||
if test -f ./setup; then
|
||||
# shellcheck disable=SC2039,SC1091,SC3046
|
||||
source ./setup
|
||||
fi
|
||||
|
||||
exec gosu $USER /app/gogs/gogs web
|
||||
exec gosu "$USER" /app/gogs/gogs web
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
#!/bin/sh
|
||||
|
||||
if ! test -d ~git/.ssh; then
|
||||
gosu $USER mkdir -p ~git/.ssh
|
||||
gosu "$USER" mkdir -p ~git/.ssh
|
||||
chmod 700 ~git/.ssh
|
||||
fi
|
||||
|
||||
if ! test -f ~git/.ssh/environment; then
|
||||
gosu $USER echo "GOGS_CUSTOM=${GOGS_CUSTOM}" > ~git/.ssh/environment
|
||||
gosu "$USER" echo "GOGS_CUSTOM=${GOGS_CUSTOM}" > ~git/.ssh/environment
|
||||
chmod 600 ~git/.ssh/environment
|
||||
fi
|
||||
|
||||
cd /app/gogs
|
||||
cd /app/gogs || exit 1
|
||||
|
||||
# Link volumed data with app data
|
||||
ln -sfn /data/gogs/log ./log
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
if test -f ./setup; then
|
||||
# shellcheck disable=SC2039,SC1091,SC3046
|
||||
source ./setup
|
||||
fi
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Check if host keys are present, else create them
|
||||
# Check if host keys are present, else create them
|
||||
if ! test -f /data/ssh/ssh_host_rsa_key; then
|
||||
ssh-keygen -q -f /data/ssh/ssh_host_rsa_key -N '' -t rsa
|
||||
fi
|
||||
@@ -17,7 +17,7 @@ if ! test -f /data/ssh/ssh_host_ed25519_key; then
|
||||
ssh-keygen -q -f /data/ssh/ssh_host_ed25519_key -N '' -t ed25519
|
||||
fi
|
||||
|
||||
# Set correct right to ssh keys
|
||||
# Set correct right to ssh keys
|
||||
chown -R root:root /data/ssh/*
|
||||
chmod 0700 /data/ssh
|
||||
chmod 0600 /data/ssh/*
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
if test -f ./setup; then
|
||||
# shellcheck disable=SC2039,SC1091,SC3046
|
||||
source ./setup
|
||||
fi
|
||||
|
||||
|
||||
@@ -3,17 +3,18 @@
|
||||
create_socat_links() {
|
||||
# Bind linked docker container to localhost socket using socat
|
||||
USED_PORT="3000:22"
|
||||
while read NAME ADDR PORT; do
|
||||
while read -r NAME ADDR PORT; do
|
||||
if test -z "$NAME$ADDR$PORT"; then
|
||||
continue
|
||||
elif echo $USED_PORT | grep -E "(^|:)$PORT($|:)" > /dev/null; then
|
||||
echo "init:socat | Can't bind linked container ${NAME} to localhost, port ${PORT} already in use" 1>&2
|
||||
else
|
||||
SERV_FOLDER=/app/gogs/docker/s6/SOCAT_${NAME}_${PORT}
|
||||
mkdir -p ${SERV_FOLDER}
|
||||
mkdir -p "${SERV_FOLDER}"
|
||||
CMD="socat -ls TCP4-LISTEN:${PORT},fork,reuseaddr TCP4:${ADDR}:${PORT}"
|
||||
echo -e "#!/bin/sh\nexec $CMD" > ${SERV_FOLDER}/run
|
||||
chmod +x ${SERV_FOLDER}/run
|
||||
# shellcheck disable=SC2039,SC3037
|
||||
echo -e "#!/bin/sh\nexec $CMD" > "${SERV_FOLDER}"/run
|
||||
chmod +x "${SERV_FOLDER}"/run
|
||||
USED_PORT="${USED_PORT}:${PORT}"
|
||||
echo "init:socat | Linked container ${NAME} will be binded to localhost on port ${PORT}" 1>&2
|
||||
fi
|
||||
@@ -23,20 +24,24 @@ EOT
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
# Cleanup SOCAT services and s6 event folder
|
||||
# Cleanup SOCAT services and s6 event folder
|
||||
# On start and on shutdown in case container has been killed
|
||||
rm -rf $(find /app/gogs/docker/s6/ -name 'event')
|
||||
rm -rf "$(find /app/gogs/docker/s6/ -name 'event')"
|
||||
rm -rf /app/gogs/docker/s6/SOCAT_*
|
||||
}
|
||||
|
||||
create_volume_subfolder() {
|
||||
# Modify the owner of /data dir, make $USER(git) user have permission to create sub-dir in /data.
|
||||
chown -R $USER:$USER /data
|
||||
# only change ownership if needed, if using an nfs mount this could be expensive
|
||||
if [ "$USER:$USER" != "$(stat /data -c '%U:%G')" ]
|
||||
then
|
||||
# Modify the owner of /data dir, make $USER(git) user have permission to create sub-dir in /data.
|
||||
chown -R "$USER:$USER" /data
|
||||
fi
|
||||
|
||||
# Create VOLUME subfolder
|
||||
for f in /data/gogs/data /data/gogs/conf /data/gogs/log /data/git /data/ssh; do
|
||||
if ! test -d $f; then
|
||||
gosu $USER mkdir -p $f
|
||||
gosu "$USER" mkdir -p $f
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -54,19 +59,19 @@ cleanup
|
||||
create_volume_subfolder
|
||||
|
||||
LINK=$(echo "$SOCAT_LINK" | tr '[:upper:]' '[:lower:]')
|
||||
if [ "$LINK" = "false" -o "$LINK" = "0" ]; then
|
||||
if [ "$LINK" = "false" ] || [ "$LINK" = "0" ]; then
|
||||
echo "init:socat | Will not try to create socat links as requested" 1>&2
|
||||
else
|
||||
create_socat_links
|
||||
fi
|
||||
|
||||
CROND=$(echo "$RUN_CROND" | tr '[:upper:]' '[:lower:]')
|
||||
if [ "$CROND" = "true" -o "$CROND" = "1" ]; then
|
||||
if [ "$CROND" = "true" ] || [ "$CROND" = "1" ]; then
|
||||
echo "init:crond | Cron Daemon (crond) will be run as requested by s6" 1>&2
|
||||
rm -f /app/gogs/docker/s6/crond/down
|
||||
/bin/sh /app/gogs/docker/runtime/backup-init.sh "${PUID}"
|
||||
else
|
||||
# Tell s6 not to run the crond service
|
||||
# Tell s6 not to run the crond service
|
||||
touch /app/gogs/docker/s6/crond/down
|
||||
fi
|
||||
|
||||
|
||||
@@ -153,6 +153,8 @@ You would have to re-run this command after changing Go files, or any file under
|
||||
When you are actively working on HTML templates and static files during development, you may want to enable the following configuration to avoid recompiling and restarting Gogs every time you make a change to files under `template/` and `public/` directories:
|
||||
|
||||
```ini
|
||||
RUN_MODE = dev
|
||||
|
||||
[server]
|
||||
LOAD_ASSETS_FROM_DISK = true
|
||||
```
|
||||
|
||||
11
go.mod
11
go.mod
@@ -28,7 +28,7 @@ require (
|
||||
github.com/issue9/identicon v1.0.1
|
||||
github.com/jaytaylor/html2text v0.0.0-20190408195923-01ec452cbe43
|
||||
github.com/jinzhu/gorm v1.9.12
|
||||
github.com/json-iterator/go v1.1.10
|
||||
github.com/json-iterator/go v1.1.12
|
||||
github.com/klauspost/compress v1.8.6 // indirect
|
||||
github.com/klauspost/cpuid v1.2.1 // indirect
|
||||
github.com/lib/pq v1.3.0 // indirect
|
||||
@@ -51,14 +51,15 @@ require (
|
||||
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf // indirect
|
||||
github.com/stretchr/testify v1.6.1
|
||||
github.com/t-tiger/gorm-bulk-insert v1.3.0
|
||||
github.com/unknwon/cae v1.0.0
|
||||
github.com/unknwon/cae v1.0.2
|
||||
github.com/unknwon/com v1.0.1
|
||||
github.com/unknwon/i18n v0.0.0-20190805065654-5c6446a380b6
|
||||
github.com/unknwon/paginater v0.0.0-20170405233947-45e5d631308e
|
||||
github.com/urfave/cli v1.22.4
|
||||
golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975
|
||||
golang.org/x/net v0.0.0-20191014212845-da9a3fd4c582
|
||||
golang.org/x/text v0.3.3
|
||||
golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2
|
||||
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 // indirect
|
||||
golang.org/x/text v0.3.6
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
||||
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d // indirect
|
||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
|
||||
|
||||
66
go.sum
66
go.sum
@@ -17,6 +17,7 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY=
|
||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc h1:biVzkmvwrH8WK8raXaxBx6fRVTlJILwEwQGL1I/ByEI=
|
||||
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
|
||||
@@ -47,6 +48,7 @@ github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFP
|
||||
github.com/editorconfig/editorconfig-core-go/v2 v2.3.2 h1:j9GLz0kWF9+1T3IX0MOhhvzLtqhFOvIKLhZFxtY95Qc=
|
||||
github.com/editorconfig/editorconfig-core-go/v2 v2.3.2/go.mod h1:+u4rFiKVvlbukHyJM76GYXqQcnHScxvQCuKpMLRtJVw=
|
||||
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DPaBjB8zlTR87/ElzFsnQfuHnVUVqpZZIcV5Y=
|
||||
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s=
|
||||
@@ -78,6 +80,7 @@ github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG
|
||||
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
|
||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:9wScpmSP5A3Bk8V3XHWUcJmYTh+ZnlHVyc+A4oZYS3Y=
|
||||
github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:56xuuqnHyryaerycW3BfssRdxQstACi0Epw/yC5E2xM=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
@@ -85,14 +88,13 @@ github.com/gogs/chardet v0.0.0-20150115103509-2404f7772561 h1:aBzukfDxQlCTVS0NBU
|
||||
github.com/gogs/chardet v0.0.0-20150115103509-2404f7772561/go.mod h1:Pcatq5tYkCW2Q6yrR2VRHlbHpZ/R4/7qyL1TCF7vl14=
|
||||
github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14 h1:yXtpJr/LV6PFu4nTLgfjQdcMdzjbqqXMEnHfq0Or6p8=
|
||||
github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14/go.mod h1:jPoNZLWDAqA5N3G5amEoiNbhVrmM+ZQEcnQvNQ2KaZk=
|
||||
github.com/gogs/git-module v1.1.1 h1:/taoHtOHLorlmQJ7zLBQvJGGgM9LRIoGGH1et4Upzvo=
|
||||
github.com/gogs/git-module v1.1.1/go.mod h1:oN37FFStFjdnTJXsSbhIHKJXh2YeDsEcXPATVz/oeuQ=
|
||||
github.com/gogs/git-module v1.1.2 h1:30jO+rKEmCDk/O6Mnl7MVrw6rI1qLDByXpkRB+bpYwM=
|
||||
github.com/gogs/git-module v1.1.2/go.mod h1:oN37FFStFjdnTJXsSbhIHKJXh2YeDsEcXPATVz/oeuQ=
|
||||
github.com/gogs/go-gogs-client v0.0.0-20200128182646-c69cb7680fd4 h1:C7NryI/RQhsIWwC2bHN601P1wJKeuQ6U/UCOYTn3Cic=
|
||||
github.com/gogs/go-gogs-client v0.0.0-20200128182646-c69cb7680fd4/go.mod h1:fR6z1Ie6rtF7kl/vBYMfgD5/G5B1blui7z426/sj2DU=
|
||||
github.com/gogs/go-libravatar v0.0.0-20191106065024-33a75213d0a0 h1:K02vod+sn3M1OOkdqi2tPxN2+xESK4qyITVQ3JkGEv4=
|
||||
github.com/gogs/go-libravatar v0.0.0-20191106065024-33a75213d0a0/go.mod h1:Zas3BtO88pk1cwUfEYlvnl/CRwh0ybDxRWSwRjG8I3w=
|
||||
github.com/gogs/minwinsvc v0.0.0-20170301035411-95be6356811a h1:8DZwxETOVWIinYxDK+i6L+rMb7eGATGaakD6ZucfHVk=
|
||||
github.com/gogs/minwinsvc v0.0.0-20170301035411-95be6356811a/go.mod h1:TUIZ+29jodWQ8Gk6Pvtg4E09aMsc3C/VLZiVYfUhWQU=
|
||||
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=
|
||||
@@ -114,6 +116,7 @@ github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Z
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY=
|
||||
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
|
||||
@@ -125,6 +128,7 @@ github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OI
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRidnzC1Oq86fpX1q/iEv2KJdrCtttYjT4=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||
github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY=
|
||||
@@ -132,6 +136,7 @@ github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl
|
||||
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/issue9/assert v1.3.1 h1:L8pRpbnzMIPFJqrMKR/oG03uWrtVeZyYBpI2U2Jx1JE=
|
||||
github.com/issue9/assert v1.3.1/go.mod h1:9Ger+iz8X7r1zMYYwEhh++2wMGWcNN2oVI+zIQXxcio=
|
||||
github.com/issue9/identicon v1.0.1 h1:pCDfjMDM6xWK0Chxo8Lif+ST/nOEtmXgMITgV1YA9Og=
|
||||
github.com/issue9/identicon v1.0.1/go.mod h1:UKNVkUFI68RPz/RlLhsAr1aX6bBSaYEWRHVfdjrMUmk=
|
||||
@@ -142,14 +147,15 @@ github.com/jinzhu/gorm v1.9.12 h1:Drgk1clyWT9t9ERbzHza6Mj/8FY/CqMyVzOiHviMo6Q=
|
||||
github.com/jinzhu/gorm v1.9.12/go.mod h1:vhTjlKSJUTWNtcbQtrMBFCxy7eXTzeCAzfL5fBZT/Qs=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.0.1 h1:HjfetcXq097iXP0uoPCdnM4Efp5/9MsM0/M+XOTeR3M=
|
||||
github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns=
|
||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
@@ -159,8 +165,10 @@ github.com/klauspost/cpuid v1.2.1 h1:vJi+O/nMdFt0vqm8NZBI6wzALWdA2X+egi0ogNyrC/w
|
||||
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
@@ -188,16 +196,15 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5
|
||||
github.com/mcuadros/go-version v0.0.0-20190308113854-92cdf37c5b75/go.mod h1:76rfSfYPWj01Z85hUf/ituArm797mNKcvINh1OlsZKo=
|
||||
github.com/mcuadros/go-version v0.0.0-20190830083331-035f6764e8d2 h1:YocNLcTBdEdvY3iDK6jfWXvEaM5OCKkjxPKoJRdB3Gg=
|
||||
github.com/mcuadros/go-version v0.0.0-20190830083331-035f6764e8d2/go.mod h1:76rfSfYPWj01Z85hUf/ituArm797mNKcvINh1OlsZKo=
|
||||
github.com/microcosm-cc/bluemonday v1.0.2 h1:5lPfLTTAvAbtS0VqT+94yOtFnGfUWYyx0+iToC3Os3s=
|
||||
github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc=
|
||||
github.com/microcosm-cc/bluemonday v1.0.4 h1:p0L+CTpo/PLFdkoPcJemLXG+fpMD7pYOoDEq1axMbGg=
|
||||
github.com/microcosm-cc/bluemonday v1.0.4/go.mod h1:8iwZnFn2CDDNZ0r6UXhF4xawGvzaqzCRa1n3/lO3W2w=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/msteinert/pam v0.0.0-20190215180659-f29b9f28d6f9 h1:ZivaaKmjs9q90zi6I4gTLW6tbVGtlBjellr3hMYaly0=
|
||||
github.com/msteinert/pam v0.0.0-20190215180659-f29b9f28d6f9/go.mod h1:np1wUFZ6tyoke22qDJZY40URn9Ae51gX7ljIWXN5TJs=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
@@ -247,6 +254,7 @@ github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNue
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca h1:NugYot0LIVPxTvN8n+Kvkn6TrbMyxQiuvKdEwFdR9vI=
|
||||
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU=
|
||||
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
|
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
@@ -262,28 +270,27 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/assertions v1.0.1 h1:voD4ITNjPL5jjBfgR/r8fPIIBrliWrWHeiJApdr3r4w=
|
||||
github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM=
|
||||
github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s=
|
||||
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
|
||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf h1:pvbZ0lM0XWPBqUKqFU8cmavspvIl9nulOYwdy6IFRRo=
|
||||
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf/go.mod h1:RJID2RhlZKId02nZ62WenDCkgHFerpIOmW0iT7GKmXM=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.6.0 h1:jlIyCplCJFULU/01vCkhKuTyc3OorI3bJFuw6obfgho=
|
||||
github.com/stretchr/testify v1.6.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
||||
github.com/t-tiger/gorm-bulk-insert v1.3.0 h1:9k7BaVEhw/3fsvh6GTOBwJ2RXk3asc5xs5m6hwozq20=
|
||||
github.com/t-tiger/gorm-bulk-insert v1.3.0/go.mod h1:ruDlk8xDl+8sX4bA7PQuYly9YEb3pbp1eP2LCyeRrFY=
|
||||
github.com/unknwon/cae v1.0.0 h1:i39lOFaBXZxhGjQOy/RNbi8uzettCs6OQxpR0xXohGU=
|
||||
github.com/unknwon/cae v1.0.0/go.mod h1:QaSeRctcea9fK6piJpAMCCPKxzJ01+xFcr2k1m3WRPU=
|
||||
github.com/unknwon/cae v1.0.2 h1:3L8/RCN1ARvD5quyNjU30EdvYkFbxBfnRcIBXugpHlg=
|
||||
github.com/unknwon/cae v1.0.2/go.mod h1:HqpmD2fVq9G1oGEXrXzbgIp51uJ29Hshv41n9ljm+AA=
|
||||
github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM=
|
||||
github.com/unknwon/com v1.0.1 h1:3d1LTxD+Lnf3soQiD4Cp/0BRB+Rsa/+RTvz8GMMzIXs=
|
||||
github.com/unknwon/com v1.0.1/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM=
|
||||
@@ -293,6 +300,7 @@ github.com/unknwon/paginater v0.0.0-20170405233947-45e5d631308e h1:Qf3QQl/zmEbWD
|
||||
github.com/unknwon/paginater v0.0.0-20170405233947-45e5d631308e/go.mod h1:TBwoao3Q4Eb/cp+dHbXDfRTrZSsj/k7kLr2j1oWRWC0=
|
||||
github.com/urfave/cli v1.22.4 h1:u7tSpNPPswAFymm8IehJhy4uJMlUuU/GmqSkvJ1InXA=
|
||||
github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs=
|
||||
github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
|
||||
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
@@ -302,8 +310,8 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U
|
||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975 h1:/Tl7pH94bvbAAHBdZJT947M/+gp0+CqQXDtMRC0fseo=
|
||||
golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29 h1:tkVvjkPTB7pnW3jnid7kNyAMPVWllTNOf/qKDze4p9o=
|
||||
golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
@@ -324,8 +332,8 @@ golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR
|
||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191014212845-da9a3fd4c582 h1:p9xBe/w/OzkeYVKm234g55gMdD1nSIooTir5kV11kfA=
|
||||
golang.org/x/net v0.0.0-20191014212845-da9a3fd4c582/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
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/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@@ -333,6 +341,7 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@@ -349,14 +358,19 @@ golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f h1:gWF768j/LaZugp8dyS4UwsslYCYz9XgFxvlgsn0n9H8=
|
||||
golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 h1:XfKQ4OlFl8okEOr5UvAqFRVj8pY/4yfcXrddB8qAbU0=
|
||||
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
@@ -370,6 +384,7 @@ golang.org/x/tools v0.0.0-20190805222050-c5a2fd39b72a/go.mod h1:jcCCGcm9btYwXyDq
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
@@ -388,6 +403,7 @@ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miE
|
||||
google.golang.org/protobuf v1.21.0 h1:qdOKuR/EIArgaWNjetjgTzgVTAZ+S/WXVrq9HW9zimw=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
|
||||
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d h1:TxyelI5cVkbREznMhfzycHdkp5cLA7DpE+GKjSslYhM=
|
||||
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw=
|
||||
@@ -395,12 +411,12 @@ gopkg.in/bufio.v1 v1.0.0-20140618132640-567b2bfa514e h1:wGA78yza6bu/mWcc4QfBuIEH
|
||||
gopkg.in/bufio.v1 v1.0.0-20140618132640-567b2bfa514e/go.mod h1:xsQCaysVCudhrYTfzYWe577fCe7Ceci+6qjO2Rdc0Z4=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AWRXxgwEyPp2z+p0+hgMuE=
|
||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw=
|
||||
gopkg.in/ini.v1 v1.46.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.55.0 h1:E8yzL5unfpW3M6fz/eB7Cb5MQAYSZ7GKo4Qth+N2sgQ=
|
||||
gopkg.in/ini.v1 v1.55.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.56.0 h1:DPMeDvGTM54DXbPkVIZsp19fp/I2K7zwA/itHYHKo8Y=
|
||||
gopkg.in/ini.v1 v1.56.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
@@ -408,10 +424,6 @@ gopkg.in/ldap.v2 v2.5.1 h1:wiu0okdNfjlBzg6UWvd1Hn8Y+Ux17/u/4nlk4CQr6tU=
|
||||
gopkg.in/ldap.v2 v2.5.1/go.mod h1:oI0cpe/D7HRtBQl8aTg+ZmzFUAvu4lsv3eLXMLGFxWk=
|
||||
gopkg.in/macaron.v1 v1.3.4/go.mod h1:/RoHTdC8ALpyJ3+QR36mKjwnT1F1dyYtsGM9Ate6ZFI=
|
||||
gopkg.in/macaron.v1 v1.3.5/go.mod h1:uMZCFccv9yr5TipIalVOyAyZQuOH3OkmXvgcWwhJuP4=
|
||||
gopkg.in/macaron.v1 v1.3.6 h1:mHw5qRGj2f86sCjBV/S5OOPvPbiZpu0OEs1F5l66fYI=
|
||||
gopkg.in/macaron.v1 v1.3.6/go.mod h1:uMZCFccv9yr5TipIalVOyAyZQuOH3OkmXvgcWwhJuP4=
|
||||
gopkg.in/macaron.v1 v1.3.8 h1:45bQT4dDF+5SLd75qlj+dulQsuFQ9aFyLlvZX6YUJWE=
|
||||
gopkg.in/macaron.v1 v1.3.8/go.mod h1:uMZCFccv9yr5TipIalVOyAyZQuOH3OkmXvgcWwhJuP4=
|
||||
gopkg.in/macaron.v1 v1.3.9 h1:Dw+DDRYdXgQyEsPlfAfKz+UA5qVUrH3KPD7JhmZ9MFc=
|
||||
gopkg.in/macaron.v1 v1.3.9/go.mod h1:uMZCFccv9yr5TipIalVOyAyZQuOH3OkmXvgcWwhJuP4=
|
||||
gopkg.in/redis.v2 v2.3.2 h1:GPVIIB/JnL1wvfULefy3qXmPu1nfNu2d0yA09FHgwfs=
|
||||
|
||||
3
gogs.go
3
gogs.go
@@ -1,3 +1,4 @@
|
||||
//go:build go1.14
|
||||
// +build go1.14
|
||||
|
||||
// Copyright 2014 The Gogs Authors. All rights reserved.
|
||||
@@ -18,7 +19,7 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
conf.App.Version = "0.12.0+dev"
|
||||
conf.App.Version = "0.12.7"
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -27,9 +27,9 @@ func PAMAuth(serviceName, userName, passwd string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = t.Authenticate(0); err != nil {
|
||||
err = t.Authenticate(0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return t.AcctMgmt(0)
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build !pam
|
||||
// +build !pam
|
||||
|
||||
// Copyright 2014 The Gogs Authors. All rights reserved.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//go:build !cert
|
||||
// +build !cert
|
||||
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
|
||||
@@ -66,7 +66,7 @@ func runHookPreReceive(c *cli.Context) error {
|
||||
if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
|
||||
return nil
|
||||
}
|
||||
setup(c, "hooks/pre-receive.log", true)
|
||||
setup(c, "pre-receive.log", true)
|
||||
|
||||
isWiki := strings.Contains(os.Getenv(db.ENV_REPO_CUSTOM_HOOKS_PATH), ".wiki.git/")
|
||||
|
||||
@@ -159,7 +159,7 @@ func runHookUpdate(c *cli.Context) error {
|
||||
if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
|
||||
return nil
|
||||
}
|
||||
setup(c, "hooks/update.log", false)
|
||||
setup(c, "update.log", false)
|
||||
|
||||
args := c.Args()
|
||||
if len(args) != 3 {
|
||||
@@ -193,7 +193,7 @@ func runHookPostReceive(c *cli.Context) error {
|
||||
if len(os.Getenv("SSH_ORIGINAL_COMMAND")) == 0 {
|
||||
return nil
|
||||
}
|
||||
setup(c, "hooks/post-receive.log", true)
|
||||
setup(c, "post-receive.log", true)
|
||||
|
||||
// Post-receive hook does more than just gather Git information,
|
||||
// so we need to setup additional services for email notifications.
|
||||
|
||||
@@ -38,7 +38,7 @@ var Serv = cli.Command{
|
||||
// logs error message on the server side. When not in "prod" mode,
|
||||
// error message is also printed to the client for easier debugging.
|
||||
func fail(userMessage, errMessage string, args ...interface{}) {
|
||||
fmt.Fprintln(os.Stderr, "Gogs:", userMessage)
|
||||
_, _ = fmt.Fprintln(os.Stderr, "Gogs:", userMessage)
|
||||
|
||||
if len(errMessage) > 0 {
|
||||
if !conf.IsProdMode() {
|
||||
@@ -47,10 +47,11 @@ func fail(userMessage, errMessage string, args ...interface{}) {
|
||||
log.Error(errMessage, args...)
|
||||
}
|
||||
|
||||
log.Stop()
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func setup(c *cli.Context, logPath string, connectDB bool) {
|
||||
func setup(c *cli.Context, logFile string, connectDB bool) {
|
||||
conf.HookMode = true
|
||||
|
||||
var customConf string
|
||||
@@ -73,7 +74,7 @@ func setup(c *cli.Context, logPath string, connectDB bool) {
|
||||
|
||||
err = log.NewFile(log.FileConfig{
|
||||
Level: level,
|
||||
Filename: filepath.Join(conf.Log.RootPath, logPath),
|
||||
Filename: filepath.Join(conf.Log.RootPath, "hooks", logFile),
|
||||
FileRotationConfig: log.FileRotationConfig{
|
||||
Rotate: true,
|
||||
Daily: true,
|
||||
|
||||
@@ -314,6 +314,7 @@ func runWeb(c *cli.Context) error {
|
||||
}
|
||||
defer fr.Close()
|
||||
|
||||
c.Header().Set("Content-Security-Policy", "default-src 'none'; style-src 'unsafe-inline'; sandbox")
|
||||
c.Header().Set("Cache-Control", "public,max-age=86400")
|
||||
c.Header().Set("Content-Disposition", fmt.Sprintf(`inline; filename="%s"`, attach.Name))
|
||||
|
||||
@@ -611,7 +612,7 @@ func runWeb(c *cli.Context) error {
|
||||
m.Get("/compare/:before([a-z0-9]{40})\\.\\.\\.:after([a-z0-9]{40})", repo.MustBeNotBare, context.RepoRef(), repo.CompareDiff)
|
||||
}, ignSignIn, context.RepoAssignment())
|
||||
m.Group("/:username/:reponame", func() {
|
||||
m.Get("", repo.Home)
|
||||
m.Get("", context.ServeGoGet(), repo.Home)
|
||||
m.Get("/stars", repo.Stars)
|
||||
m.Get("/watchers", repo.Watchers)
|
||||
}, ignSignIn, context.RepoAssignment(), context.RepoRef())
|
||||
@@ -659,7 +660,7 @@ func runWeb(c *cli.Context) error {
|
||||
lfs.RegisterRoutes(m.Router)
|
||||
})
|
||||
|
||||
m.Route("/*", "GET,POST,OPTIONS", repo.HTTPContexter(), repo.HTTP)
|
||||
m.Route("/*", "GET,POST,OPTIONS", context.ServeGoGet(), repo.HTTPContexter(), repo.HTTP)
|
||||
})
|
||||
|
||||
// ***************************
|
||||
|
||||
@@ -103,6 +103,7 @@ var (
|
||||
CookieSecure bool
|
||||
EnableLoginStatusCookie bool
|
||||
LoginStatusCookieName string
|
||||
LocalNetworkAllowlist []string `delim:","`
|
||||
|
||||
// Deprecated: Use Auth.ReverseProxyAuthenticationHeader instead, will be removed in 0.13.
|
||||
ReverseProxyAuthenticationUser string
|
||||
|
||||
1
internal/conf/testdata/TestInit.golden.ini
vendored
1
internal/conf/testdata/TestInit.golden.ini
vendored
@@ -80,6 +80,7 @@ COOKIE_USERNAME=gogs_awesome
|
||||
COOKIE_SECURE=false
|
||||
ENABLE_LOGIN_STATUS_COOKIE=false
|
||||
LOGIN_STATUS_COOKIE_NAME=login_status
|
||||
LOCAL_NETWORK_ALLOWLIST=
|
||||
REVERSE_PROXY_AUTHENTICATION_USER=
|
||||
|
||||
[email]
|
||||
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"path"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -16,7 +15,6 @@ import (
|
||||
"github.com/go-macaron/csrf"
|
||||
"github.com/go-macaron/i18n"
|
||||
"github.com/go-macaron/session"
|
||||
"github.com/unknwon/com"
|
||||
"gopkg.in/macaron.v1"
|
||||
log "unknwon.dev/clog/v2"
|
||||
|
||||
@@ -249,55 +247,9 @@ func Contexter() macaron.Handler {
|
||||
c.Data["Link"] = template.EscapePound(c.Link)
|
||||
c.Data["PageStartTime"] = time.Now()
|
||||
|
||||
// Quick responses appropriate go-get meta with status 200
|
||||
// regardless of if user have access to the repository,
|
||||
// or the repository does not exist at all.
|
||||
// This is particular a workaround for "go get" command which does not respect
|
||||
// .netrc file.
|
||||
if c.Query("go-get") == "1" {
|
||||
ownerName := c.Params(":username")
|
||||
repoName := c.Params(":reponame")
|
||||
branchName := "master"
|
||||
|
||||
owner, err := db.GetUserByName(ownerName)
|
||||
if err != nil {
|
||||
c.NotFoundOrError(err, "get user by name")
|
||||
return
|
||||
}
|
||||
|
||||
repo, err := db.GetRepositoryByName(owner.ID, repoName)
|
||||
if err == nil && len(repo.DefaultBranch) > 0 {
|
||||
branchName = repo.DefaultBranch
|
||||
}
|
||||
|
||||
prefix := conf.Server.ExternalURL + path.Join(ownerName, repoName, "src", branchName)
|
||||
insecureFlag := ""
|
||||
if !strings.HasPrefix(conf.Server.ExternalURL, "https://") {
|
||||
insecureFlag = "--insecure "
|
||||
}
|
||||
c.PlainText(http.StatusOK, com.Expand(`<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="go-import" content="{GoGetImport} git {CloneLink}">
|
||||
<meta name="go-source" content="{GoGetImport} _ {GoDocDirectory} {GoDocFile}">
|
||||
</head>
|
||||
<body>
|
||||
go get {InsecureFlag}{GoGetImport}
|
||||
</body>
|
||||
</html>
|
||||
`, map[string]string{
|
||||
"GoGetImport": path.Join(conf.Server.URL.Host, conf.Server.Subpath, ownerName, repoName),
|
||||
"CloneLink": db.ComposeHTTPSCloneURL(ownerName, repoName),
|
||||
"GoDocDirectory": prefix + "{/dir}",
|
||||
"GoDocFile": prefix + "{/dir}/{file}#L{line}",
|
||||
"InsecureFlag": insecureFlag,
|
||||
}))
|
||||
return
|
||||
}
|
||||
|
||||
if len(conf.HTTP.AccessControlAllowOrigin) > 0 {
|
||||
c.Header().Set("Access-Control-Allow-Origin", conf.HTTP.AccessControlAllowOrigin)
|
||||
c.Header().Set("'Access-Control-Allow-Credentials' ", "true")
|
||||
c.Header().Set("Access-Control-Allow-Credentials", "true")
|
||||
c.Header().Set("Access-Control-Max-Age", "3600")
|
||||
c.Header().Set("Access-Control-Allow-Headers", "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With")
|
||||
}
|
||||
@@ -338,6 +290,7 @@ func Contexter() macaron.Handler {
|
||||
// 🚨 SECURITY: Prevent MIME type sniffing in some browsers,
|
||||
// see https://github.com/gogs/gogs/issues/5397 for details.
|
||||
c.Header().Set("X-Content-Type-Options", "nosniff")
|
||||
c.Header().Set("X-Frame-Options", "DENY")
|
||||
|
||||
ctx.Map(c)
|
||||
}
|
||||
|
||||
62
internal/context/go_get.go
Normal file
62
internal/context/go_get.go
Normal file
@@ -0,0 +1,62 @@
|
||||
package context
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/unknwon/com"
|
||||
"gopkg.in/macaron.v1"
|
||||
|
||||
"gogs.io/gogs/internal/conf"
|
||||
"gogs.io/gogs/internal/db"
|
||||
)
|
||||
|
||||
// ServeGoGet does quick responses for appropriate go-get meta with status OK
|
||||
// regardless of whether the user has access to the repository, or the repository
|
||||
// does exist at all. This is particular a workaround for "go get" command which
|
||||
// does not respect .netrc file.
|
||||
func ServeGoGet() macaron.Handler {
|
||||
return func(c *macaron.Context) {
|
||||
if c.Query("go-get") != "1" {
|
||||
return
|
||||
}
|
||||
|
||||
ownerName := c.Params(":username")
|
||||
repoName := c.Params(":reponame")
|
||||
branchName := "master"
|
||||
|
||||
owner, err := db.Users.GetByUsername(ownerName)
|
||||
if err == nil {
|
||||
repo, err := db.Repos.GetByName(owner.ID, repoName)
|
||||
if err == nil && repo.DefaultBranch != "" {
|
||||
branchName = repo.DefaultBranch
|
||||
}
|
||||
}
|
||||
|
||||
prefix := conf.Server.ExternalURL + path.Join(ownerName, repoName, "src", branchName)
|
||||
insecureFlag := ""
|
||||
if !strings.HasPrefix(conf.Server.ExternalURL, "https://") {
|
||||
insecureFlag = "--insecure "
|
||||
}
|
||||
c.PlainText(http.StatusOK, []byte(com.Expand(`<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="go-import" content="{GoGetImport} git {CloneLink}">
|
||||
<meta name="go-source" content="{GoGetImport} _ {GoDocDirectory} {GoDocFile}">
|
||||
</head>
|
||||
<body>
|
||||
go get {InsecureFlag}{GoGetImport}
|
||||
</body>
|
||||
</html>
|
||||
`,
|
||||
map[string]string{
|
||||
"GoGetImport": path.Join(conf.Server.URL.Host, conf.Server.Subpath, ownerName, repoName),
|
||||
"CloneLink": db.ComposeHTTPSCloneURL(ownerName, repoName),
|
||||
"GoDocDirectory": prefix + "{/dir}",
|
||||
"GoDocFile": prefix + "{/dir}/{file}#L{line}",
|
||||
"InsecureFlag": insecureFlag,
|
||||
},
|
||||
)))
|
||||
}
|
||||
}
|
||||
@@ -11,8 +11,8 @@ import (
|
||||
|
||||
"github.com/gogs/cron"
|
||||
|
||||
"gogs.io/gogs/internal/db"
|
||||
"gogs.io/gogs/internal/conf"
|
||||
"gogs.io/gogs/internal/db"
|
||||
)
|
||||
|
||||
var c = cron.New()
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
"time"
|
||||
"unicode"
|
||||
|
||||
"github.com/json-iterator/go"
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
"github.com/unknwon/com"
|
||||
log "unknwon.dev/clog/v2"
|
||||
"xorm.io/xorm"
|
||||
@@ -57,9 +57,9 @@ var (
|
||||
IssueCloseKeywords = []string{"close", "closes", "closed", "fix", "fixes", "fixed", "resolve", "resolves", "resolved"}
|
||||
IssueReopenKeywords = []string{"reopen", "reopens", "reopened"}
|
||||
|
||||
IssueCloseKeywordsPat = lazyregexp.New(assembleKeywordsPattern(IssueCloseKeywords))
|
||||
IssueReopenKeywordsPat = lazyregexp.New(assembleKeywordsPattern(IssueReopenKeywords))
|
||||
IssueReferenceKeywordsPat = lazyregexp.New(`(?i)(?:)(^| )\S+`)
|
||||
IssueCloseKeywordsPat = lazyregexp.New(assembleKeywordsPattern(IssueCloseKeywords))
|
||||
IssueReopenKeywordsPat = lazyregexp.New(assembleKeywordsPattern(IssueReopenKeywords))
|
||||
issueReferencePattern = lazyregexp.New(`(?i)(?:)(^| )\S*#\d+`)
|
||||
)
|
||||
|
||||
func assembleKeywordsPattern(words []string) string {
|
||||
@@ -321,8 +321,8 @@ func UpdateIssuesCommit(doer *User, repo *Repository, commits []*PushCommit) err
|
||||
c := commits[i]
|
||||
|
||||
refMarked := make(map[int64]bool)
|
||||
for _, ref := range IssueReferenceKeywordsPat.FindAllString(c.Message, -1) {
|
||||
ref = ref[strings.IndexByte(ref, byte(' '))+1:]
|
||||
for _, ref := range issueReferencePattern.FindAllString(c.Message, -1) {
|
||||
ref = strings.TrimSpace(ref)
|
||||
ref = strings.TrimRightFunc(ref, issueIndexTrimRight)
|
||||
|
||||
if len(ref) == 0 {
|
||||
@@ -455,7 +455,7 @@ type CommitRepoActionOptions struct {
|
||||
Commits *PushCommits
|
||||
}
|
||||
|
||||
// CommitRepoAction adds new commit actio to the repository, and prepare corresponding webhooks.
|
||||
// CommitRepoAction adds new commit action to the repository, and prepare corresponding webhooks.
|
||||
func CommitRepoAction(opts CommitRepoActionOptions) error {
|
||||
pusher, err := GetUserByName(opts.PusherName)
|
||||
if err != nil {
|
||||
|
||||
41
internal/db/action_test.go
Normal file
41
internal/db/action_test.go
Normal file
@@ -0,0 +1,41 @@
|
||||
// Copyright 2020 The Gogs 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 db
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test_issueReferencePattern(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
message string
|
||||
expStrings []string
|
||||
}{
|
||||
{
|
||||
name: "no match",
|
||||
message: "Hello world!",
|
||||
expStrings: nil,
|
||||
},
|
||||
{
|
||||
name: "contains issue numbers",
|
||||
message: "#123 is fixed, and #456 is WIP",
|
||||
expStrings: []string{"#123", " #456"},
|
||||
},
|
||||
{
|
||||
name: "contains full issue references",
|
||||
message: "#123 is fixed, and user/repo#456 is WIP",
|
||||
expStrings: []string{"#123", " user/repo#456"},
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
strs := issueReferencePattern.FindAllString(test.message, -1)
|
||||
assert.Equal(t, test.expStrings, strs)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -87,7 +87,7 @@ func dumpTable(db *gorm.DB, table interface{}, w io.Writer) error {
|
||||
return errors.Wrap(err, "encode JSON")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return rows.Err()
|
||||
}
|
||||
|
||||
func dumpLegacyTables(dirPath string, verbose bool) error {
|
||||
|
||||
@@ -128,7 +128,7 @@ var tables = []interface{}{
|
||||
new(LFSObject), new(LoginSource),
|
||||
}
|
||||
|
||||
func Init() (*gorm.DB, error) {
|
||||
func Init(w io.Writer) (*gorm.DB, error) {
|
||||
db, err := openDB(conf.Database)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "open database")
|
||||
@@ -138,10 +138,6 @@ func Init() (*gorm.DB, error) {
|
||||
db.DB().SetMaxIdleConns(conf.Database.MaxIdleConns)
|
||||
db.DB().SetConnMaxLifetime(time.Minute)
|
||||
|
||||
w, err := getLogWriter()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "get log writer")
|
||||
}
|
||||
db.SetLogger(&dbutil.Writer{Writer: w})
|
||||
if !conf.IsProdMode() {
|
||||
db = db.LogMode(true)
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
// Copyright 2017 The Gogs 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 errors
|
||||
|
||||
import "fmt"
|
||||
|
||||
type InvalidIssueReference struct {
|
||||
Ref string
|
||||
}
|
||||
|
||||
func IsInvalidIssueReference(err error) bool {
|
||||
_, ok := err.(InvalidIssueReference)
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err InvalidIssueReference) Error() string {
|
||||
return fmt.Sprintf("invalid issue reference [ref: %s]", err.Ref)
|
||||
}
|
||||
@@ -408,6 +408,7 @@ func (issue *Issue) ReadBy(uid int64) error {
|
||||
}
|
||||
|
||||
func updateIssueCols(e Engine, issue *Issue, cols ...string) error {
|
||||
cols = append(cols, "updated_unix")
|
||||
_, err := e.ID(issue.ID).Cols(cols...).Update(issue)
|
||||
return err
|
||||
}
|
||||
@@ -816,12 +817,11 @@ func (ErrIssueNotExist) NotFound() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// GetIssueByRef returns an Issue specified by a GFM reference.
|
||||
// See https://help.github.com/articles/writing-on-github#references for more information on the syntax.
|
||||
// GetIssueByRef returns an Issue specified by a GFM reference, e.g. owner/repo#123.
|
||||
func GetIssueByRef(ref string) (*Issue, error) {
|
||||
n := strings.IndexByte(ref, byte('#'))
|
||||
if n == -1 {
|
||||
return nil, errors.InvalidIssueReference{Ref: ref}
|
||||
return nil, ErrIssueNotExist{args: map[string]interface{}{"ref": ref}}
|
||||
}
|
||||
|
||||
index := com.StrTo(ref[n+1:]).MustInt64()
|
||||
|
||||
@@ -51,7 +51,7 @@ type LoginSource struct {
|
||||
IsActived bool `xorm:"NOT NULL DEFAULT false" gorm:"NOT NULL"`
|
||||
IsDefault bool `xorm:"DEFAULT false"`
|
||||
Config interface{} `xorm:"-" gorm:"-"`
|
||||
RawConfig string `xorm:"TEXT cfg" gorm:"COLUMN:cfg"`
|
||||
RawConfig string `xorm:"TEXT cfg" gorm:"COLUMN:cfg;TYPE:TEXT"`
|
||||
|
||||
Created time.Time `xorm:"-" gorm:"-" json:"-"`
|
||||
CreatedUnix int64
|
||||
|
||||
@@ -8,9 +8,9 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
"github.com/unknwon/com"
|
||||
"xorm.io/xorm"
|
||||
"github.com/json-iterator/go"
|
||||
)
|
||||
|
||||
func ldapUseSSLToSecurityProtocol(x *xorm.Engine) error {
|
||||
|
||||
@@ -20,15 +20,15 @@ func updateRepositoryDescriptionField(x *xorm.Engine) error {
|
||||
return nil
|
||||
}
|
||||
switch {
|
||||
case conf.UseMySQL:
|
||||
_, err = x.Exec("ALTER TABLE `repository` MODIFY `description` VARCHAR(512);")
|
||||
case conf.UseMSSQL:
|
||||
_, err = x.Exec("ALTER TABLE `repository` ALTER COLUMN `description` VARCHAR(512);")
|
||||
case conf.UsePostgreSQL:
|
||||
_, err = x.Exec("ALTER TABLE `repository` ALTER COLUMN `description` TYPE VARCHAR(512);")
|
||||
case conf.UseSQLite3:
|
||||
// Sqlite3 uses TEXT type by default for any string type field.
|
||||
// Keep this comment to mention that we don't missed any option.
|
||||
case conf.UseMySQL:
|
||||
_, err = x.Exec("ALTER TABLE `repository` MODIFY `description` VARCHAR(512);")
|
||||
case conf.UseMSSQL:
|
||||
_, err = x.Exec("ALTER TABLE `repository` ALTER COLUMN `description` VARCHAR(512);")
|
||||
case conf.UsePostgreSQL:
|
||||
_, err = x.Exec("ALTER TABLE `repository` ALTER COLUMN `description` TYPE VARCHAR(512);")
|
||||
case conf.UseSQLite3:
|
||||
// Sqlite3 uses TEXT type by default for any string type field.
|
||||
// Keep this comment to mention that we don't missed any option.
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -7,13 +7,16 @@ package db
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/jinzhu/gorm"
|
||||
"github.com/pkg/errors"
|
||||
log "unknwon.dev/clog/v2"
|
||||
"xorm.io/core"
|
||||
"xorm.io/xorm"
|
||||
@@ -130,16 +133,21 @@ func SetEngine() (*gorm.DB, error) {
|
||||
|
||||
x.SetMapper(core.GonicMapper{})
|
||||
|
||||
// WARNING: for serv command, MUST remove the output to os.stdout,
|
||||
// so use log file to instead print to stdout.
|
||||
var logPath string
|
||||
if conf.HookMode {
|
||||
logPath = filepath.Join(conf.Log.RootPath, "hooks", "xorm.log")
|
||||
} else {
|
||||
logPath = filepath.Join(conf.Log.RootPath, "xorm.log")
|
||||
}
|
||||
sec := conf.File.Section("log.xorm")
|
||||
logger, err := log.NewFileWriter(path.Join(conf.Log.RootPath, "xorm.log"),
|
||||
fileWriter, err := log.NewFileWriter(logPath,
|
||||
log.FileRotationConfig{
|
||||
Rotate: sec.Key("ROTATE").MustBool(true),
|
||||
Daily: sec.Key("ROTATE_DAILY").MustBool(true),
|
||||
MaxSize: sec.Key("MAX_SIZE").MustInt64(100) * 1024 * 1024,
|
||||
MaxDays: sec.Key("MAX_DAYS").MustInt64(3),
|
||||
})
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("create 'xorm.log': %v", err)
|
||||
}
|
||||
@@ -149,12 +157,22 @@ func SetEngine() (*gorm.DB, error) {
|
||||
x.SetConnMaxLifetime(time.Second)
|
||||
|
||||
if conf.IsProdMode() {
|
||||
x.SetLogger(xorm.NewSimpleLogger3(logger, xorm.DEFAULT_LOG_PREFIX, xorm.DEFAULT_LOG_FLAG, core.LOG_WARNING))
|
||||
x.SetLogger(xorm.NewSimpleLogger3(fileWriter, xorm.DEFAULT_LOG_PREFIX, xorm.DEFAULT_LOG_FLAG, core.LOG_WARNING))
|
||||
} else {
|
||||
x.SetLogger(xorm.NewSimpleLogger(logger))
|
||||
x.SetLogger(xorm.NewSimpleLogger(fileWriter))
|
||||
}
|
||||
x.ShowSQL(true)
|
||||
return Init()
|
||||
|
||||
var w io.Writer
|
||||
if conf.HookMode {
|
||||
w = fileWriter
|
||||
} else {
|
||||
w, err = getLogWriter()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "get log writer")
|
||||
}
|
||||
}
|
||||
return Init(w)
|
||||
}
|
||||
|
||||
func NewEngine() (err error) {
|
||||
@@ -206,7 +224,7 @@ func GetStatistic() (stats Statistic) {
|
||||
stats.Counter.HookTask, _ = x.Count(new(HookTask))
|
||||
stats.Counter.Team, _ = x.Count(new(Team))
|
||||
stats.Counter.Attachment, _ = x.Count(new(Attachment))
|
||||
return
|
||||
return stats
|
||||
}
|
||||
|
||||
func Ping() error {
|
||||
|
||||
@@ -6,7 +6,7 @@ package db
|
||||
|
||||
import (
|
||||
"github.com/jinzhu/gorm"
|
||||
"github.com/t-tiger/gorm-bulk-insert"
|
||||
gormbulk "github.com/t-tiger/gorm-bulk-insert"
|
||||
log "unknwon.dev/clog/v2"
|
||||
)
|
||||
|
||||
|
||||
@@ -426,24 +426,29 @@ func (repo *Repository) UpdateSize() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ComposeMetas composes a map of metas for rendering external issue tracker URL.
|
||||
// ComposeMetas composes a map of metas for rendering SHA1 URL and external issue tracker URL.
|
||||
func (repo *Repository) ComposeMetas() map[string]string {
|
||||
if !repo.EnableExternalTracker {
|
||||
return nil
|
||||
} else if repo.ExternalMetas == nil {
|
||||
repo.ExternalMetas = map[string]string{
|
||||
"format": repo.ExternalTrackerFormat,
|
||||
"user": repo.MustOwner().Name,
|
||||
"repo": repo.Name,
|
||||
}
|
||||
if repo.ExternalMetas != nil {
|
||||
return repo.ExternalMetas
|
||||
}
|
||||
|
||||
repo.ExternalMetas = map[string]string{
|
||||
"repoLink": repo.Link(),
|
||||
}
|
||||
|
||||
if repo.EnableExternalTracker {
|
||||
repo.ExternalMetas["user"] = repo.MustOwner().Name
|
||||
repo.ExternalMetas["repo"] = repo.Name
|
||||
repo.ExternalMetas["format"] = repo.ExternalTrackerFormat
|
||||
|
||||
switch repo.ExternalTrackerStyle {
|
||||
case markup.ISSUE_NAME_STYLE_ALPHANUMERIC:
|
||||
repo.ExternalMetas["style"] = markup.ISSUE_NAME_STYLE_ALPHANUMERIC
|
||||
default:
|
||||
repo.ExternalMetas["style"] = markup.ISSUE_NAME_STYLE_NUMERIC
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return repo.ExternalMetas
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
gouuid "github.com/satori/go.uuid"
|
||||
"github.com/unknwon/com"
|
||||
|
||||
@@ -23,9 +24,10 @@ import (
|
||||
|
||||
"gogs.io/gogs/internal/conf"
|
||||
"gogs.io/gogs/internal/cryptoutil"
|
||||
"gogs.io/gogs/internal/db/errors"
|
||||
dberrors "gogs.io/gogs/internal/db/errors"
|
||||
"gogs.io/gogs/internal/gitutil"
|
||||
"gogs.io/gogs/internal/osutil"
|
||||
"gogs.io/gogs/internal/pathutil"
|
||||
"gogs.io/gogs/internal/process"
|
||||
"gogs.io/gogs/internal/tool"
|
||||
)
|
||||
@@ -134,7 +136,7 @@ func (repo *Repository) UpdateRepoFile(doer *User, opts UpdateRepoFileOptions) (
|
||||
if opts.OldBranch != opts.NewBranch {
|
||||
// Directly return error if new branch already exists in the server
|
||||
if git.RepoHasBranch(repoPath, opts.NewBranch) {
|
||||
return errors.BranchAlreadyExists{Name: opts.NewBranch}
|
||||
return dberrors.BranchAlreadyExists{Name: opts.NewBranch}
|
||||
}
|
||||
|
||||
// Otherwise, delete branch from local copy in case out of sync
|
||||
@@ -449,11 +451,16 @@ func isRepositoryGitPath(path string) bool {
|
||||
return strings.HasSuffix(path, ".git") || strings.Contains(path, ".git"+string(os.PathSeparator))
|
||||
}
|
||||
|
||||
func (repo *Repository) UploadRepoFiles(doer *User, opts UploadRepoFileOptions) (err error) {
|
||||
func (repo *Repository) UploadRepoFiles(doer *User, opts UploadRepoFileOptions) error {
|
||||
if len(opts.Files) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Prevent uploading files into the ".git" directory
|
||||
if isRepositoryGitPath(opts.TreePath) {
|
||||
return errors.Errorf("bad tree path %q", opts.TreePath)
|
||||
}
|
||||
|
||||
uploads, err := GetUploadsByUUIDs(opts.Files)
|
||||
if err != nil {
|
||||
return fmt.Errorf("get uploads by UUIDs[%v]: %v", opts.Files, err)
|
||||
@@ -487,7 +494,9 @@ func (repo *Repository) UploadRepoFiles(doer *User, opts UploadRepoFileOptions)
|
||||
continue
|
||||
}
|
||||
|
||||
// Prevent copying files into .git directory, see https://gogs.io/gogs/issues/5558.
|
||||
upload.Name = pathutil.Clean(upload.Name)
|
||||
|
||||
// Prevent uploading files into the ".git" directory
|
||||
if isRepositoryGitPath(upload.Name) {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -19,14 +19,19 @@ func TestRepository_ComposeMetas(t *testing.T) {
|
||||
|
||||
t.Run("no external tracker is configured", func(t *testing.T) {
|
||||
repo.EnableExternalTracker = false
|
||||
assert.Equal(t, map[string]string(nil), repo.ComposeMetas())
|
||||
|
||||
// Should be nil even if other settings are present
|
||||
repo.ExternalTrackerStyle = markup.ISSUE_NAME_STYLE_NUMERIC
|
||||
assert.Equal(t, map[string]string(nil), repo.ComposeMetas())
|
||||
metas := repo.ComposeMetas()
|
||||
assert.Equal(t, metas["repoLink"], repo.Link())
|
||||
|
||||
// Should no format and style if no external tracker is configured
|
||||
_, ok := metas["format"]
|
||||
assert.False(t, ok)
|
||||
_, ok = metas["style"]
|
||||
assert.False(t, ok)
|
||||
})
|
||||
|
||||
t.Run("an external issue tracker is configured", func(t *testing.T) {
|
||||
repo.ExternalMetas = nil
|
||||
repo.EnableExternalTracker = true
|
||||
|
||||
// Default to numeric issue style
|
||||
|
||||
@@ -221,7 +221,7 @@ func SSHKeyGenParsePublicKey(key string) (string, int, error) {
|
||||
func SSHNativeParsePublicKey(keyLine string) (string, int, error) {
|
||||
fields := strings.Fields(keyLine)
|
||||
if len(fields) < 2 {
|
||||
return "", 0, fmt.Errorf("not enough fields in public key line: %s", string(keyLine))
|
||||
return "", 0, fmt.Errorf("not enough fields in public key line: %s", keyLine)
|
||||
}
|
||||
|
||||
raw, err := base64.StdEncoding.DecodeString(fields[1])
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
|
||||
"github.com/jinzhu/gorm"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/t-tiger/gorm-bulk-insert"
|
||||
gormbulk "github.com/t-tiger/gorm-bulk-insert"
|
||||
log "unknwon.dev/clog/v2"
|
||||
|
||||
"gogs.io/gogs/internal/cryptoutil"
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/json-iterator/go"
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
gouuid "github.com/satori/go.uuid"
|
||||
log "unknwon.dev/clog/v2"
|
||||
"xorm.io/xorm"
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/json-iterator/go"
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
|
||||
"github.com/gogs/git-module"
|
||||
api "github.com/gogs/go-gogs-client"
|
||||
@@ -18,7 +18,7 @@ const (
|
||||
DingtalkNotificationTitle = "Gogs Notification"
|
||||
)
|
||||
|
||||
//Refer: https://open-doc.dingtalk.com/docs/doc.htm?treeId=257&articleId=105735&docType=1
|
||||
// Refer: https://open-doc.dingtalk.com/docs/doc.htm?treeId=257&articleId=105735&docType=1
|
||||
type DingtalkActionCard struct {
|
||||
Title string `json:"title"`
|
||||
Text string `json:"text"`
|
||||
@@ -28,13 +28,13 @@ type DingtalkActionCard struct {
|
||||
SingleURL string `json:"singleURL"`
|
||||
}
|
||||
|
||||
//Refer: https://open-doc.dingtalk.com/docs/doc.htm?treeId=257&articleId=105735&docType=1
|
||||
// Refer: https://open-doc.dingtalk.com/docs/doc.htm?treeId=257&articleId=105735&docType=1
|
||||
type DingtalkAtObject struct {
|
||||
AtMobiles []string `json:"atMobiles"`
|
||||
IsAtAll bool `json:"isAtAll"`
|
||||
}
|
||||
|
||||
//Refer: https://open-doc.dingtalk.com/docs/doc.htm?treeId=257&articleId=105735&docType=1
|
||||
// Refer: https://open-doc.dingtalk.com/docs/doc.htm?treeId=257&articleId=105735&docType=1
|
||||
type DingtalkPayload struct {
|
||||
MsgType string `json:"msgtype"`
|
||||
At DingtalkAtObject `json:"at"`
|
||||
@@ -57,7 +57,7 @@ func NewDingtalkActionCard(singleTitle, singleURL string) DingtalkActionCard {
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: add content
|
||||
// TODO: add content
|
||||
func GetDingtalkPayload(p api.Payloader, event HookEventType) (payload *DingtalkPayload, err error) {
|
||||
switch event {
|
||||
case HOOK_EVENT_CREATE:
|
||||
@@ -255,7 +255,7 @@ func getDingtalkReleasePayload(p *api.ReleasePayload) (*DingtalkPayload, error)
|
||||
return &DingtalkPayload{MsgType: "actionCard", ActionCard: actionCard}, nil
|
||||
}
|
||||
|
||||
//Format link addr and title into markdown style
|
||||
// Format link addr and title into markdown style
|
||||
func MarkdownLinkFormatter(link, text string) string {
|
||||
return "[" + text + "](" + link + ")"
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/json-iterator/go"
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
|
||||
"github.com/gogs/git-module"
|
||||
api "github.com/gogs/go-gogs-client"
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/json-iterator/go"
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
|
||||
"github.com/gogs/git-module"
|
||||
api "github.com/gogs/go-gogs-client"
|
||||
|
||||
@@ -12,7 +12,9 @@ import (
|
||||
"github.com/unknwon/com"
|
||||
"gopkg.in/macaron.v1"
|
||||
|
||||
"gogs.io/gogs/internal/conf"
|
||||
"gogs.io/gogs/internal/db"
|
||||
"gogs.io/gogs/internal/netutil"
|
||||
)
|
||||
|
||||
// _______________________________________ _________.______________________ _______________.___.
|
||||
@@ -67,9 +69,18 @@ func (f MigrateRepo) ParseRemoteAddr(user *db.User) (string, error) {
|
||||
if err != nil {
|
||||
return "", db.ErrInvalidCloneAddr{IsURLError: true}
|
||||
}
|
||||
|
||||
if netutil.IsLocalHostname(u.Hostname(), conf.Security.LocalNetworkAllowlist) {
|
||||
return "", db.ErrInvalidCloneAddr{IsURLError: true}
|
||||
}
|
||||
|
||||
if len(f.AuthUsername)+len(f.AuthPassword) > 0 {
|
||||
u.User = url.UserPassword(f.AuthUsername, f.AuthPassword)
|
||||
}
|
||||
// To prevent CRLF injection in git protocol, see https://github.com/gogs/gogs/issues/6413
|
||||
if u.Scheme == "git" && (strings.Contains(remoteAddr, "%0d") || strings.Contains(remoteAddr, "%0a")) {
|
||||
return "", db.ErrInvalidCloneAddr{IsURLError: true}
|
||||
}
|
||||
remoteAddr = u.String()
|
||||
} else if !user.CanImportLocal() {
|
||||
return "", db.ErrInvalidCloneAddr{IsPermissionDenied: true}
|
||||
|
||||
@@ -17,10 +17,21 @@ import (
|
||||
var scpSyntax = lazyregexp.New(`^([a-zA-Z0-9_]+@)?([a-zA-Z0-9._-]+):(.*)$`)
|
||||
|
||||
// InferSubmoduleURL returns the inferred external URL of the submodule at best effort.
|
||||
func InferSubmoduleURL(mod *git.Submodule) string {
|
||||
// The `baseURL` should be the URL of the current repository. If the submodule URL looks
|
||||
// like a relative path, it assumes that the submodule is another repository on the same
|
||||
// Gogs instance by appending it to the `baseURL` with the commit.
|
||||
func InferSubmoduleURL(baseURL string, mod *git.Submodule) string {
|
||||
if !strings.HasSuffix(baseURL, "/") {
|
||||
baseURL += "/"
|
||||
}
|
||||
|
||||
raw := strings.TrimSuffix(mod.URL, "/")
|
||||
raw = strings.TrimSuffix(raw, ".git")
|
||||
|
||||
if strings.HasPrefix(raw, "../") {
|
||||
return fmt.Sprintf("%s%s/commit/%s", baseURL, raw, mod.Commit)
|
||||
}
|
||||
|
||||
parsed, err := url.Parse(raw)
|
||||
if err != nil {
|
||||
// Try parse as SCP syntax again
|
||||
|
||||
@@ -41,6 +41,14 @@ func TestInferSubmoduleURL(t *testing.T) {
|
||||
},
|
||||
expURL: "http://github.com/gogs/docs-api/commit/6b08f76a5313fa3d26859515b30aa17a5faa2807",
|
||||
},
|
||||
{
|
||||
name: "relative path",
|
||||
submodule: &git.Submodule{
|
||||
URL: "../repo2.git",
|
||||
Commit: "6b08f76a5313fa3d26859515b30aa17a5faa2807",
|
||||
},
|
||||
expURL: "https://gogs.example.com/user/repo/../repo2/commit/6b08f76a5313fa3d26859515b30aa17a5faa2807",
|
||||
},
|
||||
{
|
||||
name: "bad URL",
|
||||
submodule: &git.Submodule{
|
||||
@@ -52,7 +60,7 @@ func TestInferSubmoduleURL(t *testing.T) {
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
assert.Equal(t, test.expURL, InferSubmoduleURL(test.submodule))
|
||||
assert.Equal(t, test.expURL, InferSubmoduleURL("https://gogs.example.com/user/repo", test.submodule))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/json-iterator/go"
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
)
|
||||
|
||||
var defaultSetting = Settings{false, "GogsServer", 60 * time.Second, 60 * time.Second, nil, nil, nil, false}
|
||||
@@ -270,7 +270,7 @@ func (r *Request) getResponse() (*http.Response, error) {
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
//iocopy
|
||||
// iocopy
|
||||
_, err = io.Copy(fileWriter, fh)
|
||||
_ = fh.Close()
|
||||
if err != nil {
|
||||
|
||||
@@ -101,7 +101,7 @@ func RenderIssueIndexPattern(rawBytes []byte, urlPrefix string, metas map[string
|
||||
m = m[1:]
|
||||
}
|
||||
var link string
|
||||
if metas == nil {
|
||||
if metas == nil || metas["format"] == "" {
|
||||
link = fmt.Sprintf(`<a href="%s/issues/%s">%s</a>`, urlPrefix, m[1:], m)
|
||||
} else {
|
||||
// Support for external issue tracker
|
||||
@@ -145,7 +145,8 @@ func RenderSha1CurrentPattern(rawBytes []byte, urlPrefix string) []byte {
|
||||
if com.StrTo(m).MustInt() > 0 {
|
||||
return m
|
||||
}
|
||||
return fmt.Sprintf(`<a href="%s/commit/%s"><code>%s</code></a>`, urlPrefix, m, tool.ShortSHA1(string(m)))
|
||||
|
||||
return fmt.Sprintf(`<a href="%s/commit/%s"><code>%s</code></a>`, urlPrefix, m, tool.ShortSHA1(m))
|
||||
}))
|
||||
}
|
||||
|
||||
@@ -160,7 +161,7 @@ func RenderSpecialLink(rawBytes []byte, urlPrefix string, metas map[string]strin
|
||||
|
||||
rawBytes = RenderIssueIndexPattern(rawBytes, urlPrefix, metas)
|
||||
rawBytes = RenderCrossReferenceIssueIndexPattern(rawBytes, urlPrefix, metas)
|
||||
rawBytes = RenderSha1CurrentPattern(rawBytes, urlPrefix)
|
||||
rawBytes = RenderSha1CurrentPattern(rawBytes, metas["repoLink"])
|
||||
return rawBytes
|
||||
}
|
||||
|
||||
@@ -215,7 +216,7 @@ func wrapImgWithLink(urlPrefix string, buf *bytes.Buffer, token html.Token) {
|
||||
buf.WriteString(`">`)
|
||||
|
||||
if needPrepend {
|
||||
src = strings.Replace(urlPrefix+string(src), " ", "%20", -1)
|
||||
src = strings.Replace(urlPrefix+src, " ", "%20", -1)
|
||||
buf.WriteString(`<img src="`)
|
||||
buf.WriteString(src)
|
||||
buf.WriteString(`"`)
|
||||
|
||||
@@ -215,3 +215,41 @@ func Test_RenderIssueIndexPattern(t *testing.T) {
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestRenderSha1CurrentPattern(t *testing.T) {
|
||||
metas := map[string]string{
|
||||
"repoLink": "/someuser/somerepo",
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
desc string
|
||||
input string
|
||||
prefix string
|
||||
expVal string
|
||||
}{
|
||||
{
|
||||
desc: "Full SHA (40 symbols)",
|
||||
input: "ad8ced4f57d9068cb2874557245be3c7f341149d",
|
||||
prefix: metas["repoLink"],
|
||||
expVal: `<a href="/someuser/somerepo/commit/ad8ced4f57d9068cb2874557245be3c7f341149d"><code>ad8ced4f57</code></a>`,
|
||||
},
|
||||
{
|
||||
desc: "Short SHA (8 symbols)",
|
||||
input: "ad8ced4f",
|
||||
prefix: metas["repoLink"],
|
||||
expVal: `<a href="/someuser/somerepo/commit/ad8ced4f"><code>ad8ced4f</code></a>`,
|
||||
},
|
||||
{
|
||||
desc: "9 digits",
|
||||
input: "123456789",
|
||||
prefix: metas["repoLink"],
|
||||
expVal: "123456789",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
assert.Equal(t, test.expVal, string(RenderSha1CurrentPattern([]byte(test.input), test.prefix)))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,8 +9,8 @@ import (
|
||||
|
||||
"github.com/microcosm-cc/bluemonday"
|
||||
|
||||
"gogs.io/gogs/internal/lazyregexp"
|
||||
"gogs.io/gogs/internal/conf"
|
||||
"gogs.io/gogs/internal/lazyregexp"
|
||||
)
|
||||
|
||||
// Sanitizer is a protection wrapper of *bluemonday.Policy which does not allow
|
||||
|
||||
71
internal/netutil/netutil.go
Normal file
71
internal/netutil/netutil.go
Normal file
@@ -0,0 +1,71 @@
|
||||
// Copyright 2022 The Gogs 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 netutil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
)
|
||||
|
||||
var localCIDRs []*net.IPNet
|
||||
|
||||
func init() {
|
||||
// Parsing hardcoded CIDR strings should never fail, if in case it does, let's
|
||||
// fail it at start.
|
||||
rawCIDRs := []string{
|
||||
// https://datatracker.ietf.org/doc/html/rfc5735:
|
||||
"127.0.0.0/8", // Loopback
|
||||
"0.0.0.0/8", // "This" network
|
||||
"100.64.0.0/10", // Shared address space
|
||||
"169.254.0.0/16", // Link local
|
||||
"172.16.0.0/12", // Private-use networks
|
||||
"192.0.0.0/24", // IETF Protocol assignments
|
||||
"192.0.2.0/24", // TEST-NET-1
|
||||
"192.88.99.0/24", // 6to4 Relay anycast
|
||||
"192.168.0.0/16", // Private-use networks
|
||||
"198.18.0.0/15", // Network interconnect
|
||||
"198.51.100.0/24", // TEST-NET-2
|
||||
"203.0.113.0/24", // TEST-NET-3
|
||||
"255.255.255.255/32", // Limited broadcast
|
||||
|
||||
// https://datatracker.ietf.org/doc/html/rfc1918:
|
||||
"10.0.0.0/8", // Private-use networks
|
||||
|
||||
// https://datatracker.ietf.org/doc/html/rfc6890:
|
||||
"::1/128", // Loopback
|
||||
"FC00::/7", // Unique local address
|
||||
"FE80::/10", // Multicast address
|
||||
}
|
||||
for _, raw := range rawCIDRs {
|
||||
_, cidr, err := net.ParseCIDR(raw)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("parse CIDR %q: %v", raw, err))
|
||||
}
|
||||
localCIDRs = append(localCIDRs, cidr)
|
||||
}
|
||||
}
|
||||
|
||||
// IsLocalHostname returns true if given hostname is resolved to local network
|
||||
// address, except exempted from the allowlist.
|
||||
func IsLocalHostname(hostname string, allowlist []string) bool {
|
||||
for _, allow := range allowlist {
|
||||
if hostname == allow {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
ips, err := net.LookupIP(hostname)
|
||||
if err != nil {
|
||||
return true
|
||||
}
|
||||
for _, ip := range ips {
|
||||
for _, cidr := range localCIDRs {
|
||||
if cidr.Contains(ip) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
40
internal/netutil/netutil_test.go
Normal file
40
internal/netutil/netutil_test.go
Normal file
@@ -0,0 +1,40 @@
|
||||
// Copyright 2022 The Gogs 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 netutil
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestIsLocalHostname(t *testing.T) {
|
||||
tests := []struct {
|
||||
hostname string
|
||||
allowlist []string
|
||||
want bool
|
||||
}{
|
||||
{hostname: "localhost", want: true},
|
||||
{hostname: "127.0.0.1", want: true},
|
||||
{hostname: "::1", want: true},
|
||||
{hostname: "0:0:0:0:0:0:0:1", want: true},
|
||||
{hostname: "fuf.me", want: true},
|
||||
{hostname: "127.0.0.95", want: true},
|
||||
{hostname: "0.0.0.0", want: true},
|
||||
{hostname: "192.168.123.45", want: true},
|
||||
|
||||
{hostname: "gogs.io", want: false},
|
||||
{hostname: "google.com", want: false},
|
||||
{hostname: "165.232.140.255", want: false},
|
||||
|
||||
{hostname: "192.168.123.45", allowlist: []string{"10.0.0.17"}, want: true},
|
||||
{hostname: "gogs.local", allowlist: []string{"gogs.local"}, want: false},
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run("", func(t *testing.T) {
|
||||
assert.Equal(t, test.want, IsLocalHostname(test.hostname, test.allowlist))
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/json-iterator/go"
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
|
||||
"gogs.io/gogs/internal/conf"
|
||||
"gogs.io/gogs/internal/context"
|
||||
|
||||
@@ -64,7 +64,7 @@ func DeleteNotices(c *context.Context) {
|
||||
|
||||
func EmptyNotices(c *context.Context) {
|
||||
if err := db.DeleteNotices(0, 0); err != nil {
|
||||
c.Error(err,"delete notices")
|
||||
c.Error(err, "delete notices")
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"gogs.io/gogs/internal/conf"
|
||||
"gogs.io/gogs/internal/context"
|
||||
"gogs.io/gogs/internal/db"
|
||||
"gogs.io/gogs/internal/route"
|
||||
"gogs.io/gogs/internal/conf"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -25,7 +25,7 @@ func GetBranch(c *context.APIContext) {
|
||||
return
|
||||
}
|
||||
|
||||
c.JSONSuccess( convert.ToBranch(branch, commit))
|
||||
c.JSONSuccess(convert.ToBranch(branch, commit))
|
||||
}
|
||||
|
||||
// https://github.com/gogs/go-gogs-client/wiki/Repositories#list-branches
|
||||
@@ -46,5 +46,5 @@ func ListBranches(c *context.APIContext) {
|
||||
apiBranches[i] = convert.ToBranch(branches[i], commit)
|
||||
}
|
||||
|
||||
c.JSONSuccess( &apiBranches)
|
||||
c.JSONSuccess(&apiBranches)
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"net/http"
|
||||
|
||||
api "github.com/gogs/go-gogs-client"
|
||||
"github.com/json-iterator/go"
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/unknwon/com"
|
||||
|
||||
|
||||
@@ -44,6 +44,11 @@ func serveBatch(c *macaron.Context, owner *db.User, repo *db.Repository) {
|
||||
actions = batchActions{
|
||||
Upload: &batchAction{
|
||||
Href: fmt.Sprintf("%s/%s", baseHref, obj.Oid),
|
||||
Header: map[string]string{
|
||||
// NOTE: git-lfs v2.5.0 sets the Content-Type based on the uploaded file.
|
||||
// This ensures that the client always uses the designated value for the header.
|
||||
"Content-Type": "application/octet-stream",
|
||||
},
|
||||
},
|
||||
Verify: &batchAction{
|
||||
Href: fmt.Sprintf("%s/verify", baseHref),
|
||||
@@ -136,7 +141,8 @@ type batchError struct {
|
||||
}
|
||||
|
||||
type batchAction struct {
|
||||
Href string `json:"href"`
|
||||
Href string `json:"href"`
|
||||
Header map[string]string `json:"header,omitempty"`
|
||||
}
|
||||
|
||||
type batchActions struct {
|
||||
|
||||
@@ -6,6 +6,7 @@ package lfs
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
@@ -42,7 +43,7 @@ func Test_serveBatch(t *testing.T) {
|
||||
name: "unrecognized operation",
|
||||
body: `{"operation": "update"}`,
|
||||
expStatusCode: http.StatusBadRequest,
|
||||
expBody: `{"message":"Operation not recognized"}` + "\n",
|
||||
expBody: `{"message": "Operation not recognized"}` + "\n",
|
||||
},
|
||||
{
|
||||
name: "upload: contains invalid oid",
|
||||
@@ -53,7 +54,25 @@ func Test_serveBatch(t *testing.T) {
|
||||
{"oid": "ef797c8118f02dfb649607dd5d3f8c7623048c9c063d532cc95c5ed7a898a64f", "size": 123}
|
||||
]}`,
|
||||
expStatusCode: http.StatusOK,
|
||||
expBody: `{"transfer":"basic","objects":[{"oid":"bad_oid","size":123,"actions":{"error":{"code":422,"message":"Object has invalid oid"}}},{"oid":"ef797c8118f02dfb649607dd5d3f8c7623048c9c063d532cc95c5ed7a898a64f","size":123,"actions":{"upload":{"href":"https://gogs.example.com/owner/repo.git/info/lfs/objects/basic/ef797c8118f02dfb649607dd5d3f8c7623048c9c063d532cc95c5ed7a898a64f"},"verify":{"href":"https://gogs.example.com/owner/repo.git/info/lfs/objects/basic/verify"}}}]}` + "\n",
|
||||
expBody: `{
|
||||
"transfer": "basic",
|
||||
"objects": [
|
||||
{"oid": "bad_oid", "size":123, "actions": {"error": {"code": 422, "message": "Object has invalid oid"}}},
|
||||
{
|
||||
"oid": "ef797c8118f02dfb649607dd5d3f8c7623048c9c063d532cc95c5ed7a898a64f",
|
||||
"size": 123,
|
||||
"actions": {
|
||||
"upload": {
|
||||
"href": "https://gogs.example.com/owner/repo.git/info/lfs/objects/basic/ef797c8118f02dfb649607dd5d3f8c7623048c9c063d532cc95c5ed7a898a64f",
|
||||
"header": {"Content-Type": "application/octet-stream"}
|
||||
},
|
||||
"verify": {
|
||||
"href": "https://gogs.example.com/owner/repo.git/info/lfs/objects/basic/verify"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}` + "\n",
|
||||
},
|
||||
{
|
||||
name: "download: contains non-existent oid and mismatched size",
|
||||
@@ -78,7 +97,26 @@ func Test_serveBatch(t *testing.T) {
|
||||
},
|
||||
},
|
||||
expStatusCode: http.StatusOK,
|
||||
expBody: `{"transfer":"basic","objects":[{"oid":"bad_oid","size":123,"actions":{"error":{"code":404,"message":"Object does not exist"}}},{"oid":"ef797c8118f02dfb649607dd5d3f8c7623048c9c063d532cc95c5ed7a898a64f","size":123,"actions":{"error":{"code":422,"message":"Object size mismatch"}}},{"oid":"5cac0a318669fadfee734fb340a5f5b70b428ac57a9f4b109cb6e150b2ba7e57","size":456,"actions":{"download":{"href":"https://gogs.example.com/owner/repo.git/info/lfs/objects/basic/5cac0a318669fadfee734fb340a5f5b70b428ac57a9f4b109cb6e150b2ba7e57"}}}]}` + "\n",
|
||||
expBody: `{
|
||||
"transfer": "basic",
|
||||
"objects": [
|
||||
{"oid": "bad_oid", "size": 123, "actions": {"error": {"code": 404, "message": "Object does not exist"}}},
|
||||
{
|
||||
"oid": "ef797c8118f02dfb649607dd5d3f8c7623048c9c063d532cc95c5ed7a898a64f",
|
||||
"size": 123,
|
||||
"actions": {"error": {"code": 422, "message": "Object size mismatch"}}
|
||||
},
|
||||
{
|
||||
"oid": "5cac0a318669fadfee734fb340a5f5b70b428ac57a9f4b109cb6e150b2ba7e57",
|
||||
"size": 456,
|
||||
"actions": {
|
||||
"download": {
|
||||
"href": "https://gogs.example.com/owner/repo.git/info/lfs/objects/basic/5cac0a318669fadfee734fb340a5f5b70b428ac57a9f4b109cb6e150b2ba7e57"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}` + "\n",
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
@@ -100,7 +138,20 @@ func Test_serveBatch(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
assert.Equal(t, test.expBody, string(body))
|
||||
|
||||
var expBody bytes.Buffer
|
||||
err = json.Indent(&expBody, []byte(test.expBody), "", " ")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
var gotBody bytes.Buffer
|
||||
err = json.Indent(&gotBody, body, "", " ")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.Equal(t, expBody.String(), gotBody.String())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,6 +135,8 @@ func authorize(mode db.AccessMode) macaron.Handler {
|
||||
return
|
||||
}
|
||||
|
||||
log.Trace("[LFS] Authorized user %q to %q", actor.Name, username+"/"+reponame)
|
||||
|
||||
c.Map(owner) // NOTE: Override actor
|
||||
c.Map(repo)
|
||||
}
|
||||
@@ -144,10 +146,15 @@ func authorize(mode db.AccessMode) macaron.Handler {
|
||||
// When not, response given "failCode" as status code.
|
||||
func verifyHeader(key, value string, failCode int) macaron.Handler {
|
||||
return func(c *macaron.Context) {
|
||||
if !strings.Contains(c.Req.Header.Get(key), value) {
|
||||
c.Status(failCode)
|
||||
return
|
||||
vals := c.Req.Header.Values(key)
|
||||
for _, val := range vals {
|
||||
if strings.Contains(val, value) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
log.Trace("[LFS] HTTP header %q does not contain value %q", key, value)
|
||||
c.Status(failCode)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ func Branches(c *context.Context) {
|
||||
|
||||
c.Data["ActiveBranches"] = activeBranches
|
||||
c.Data["StaleBranches"] = staleBranches
|
||||
c.Success( BRANCHES_OVERVIEW)
|
||||
c.Success(BRANCHES_OVERVIEW)
|
||||
}
|
||||
|
||||
func AllBranches(c *context.Context) {
|
||||
@@ -104,7 +104,7 @@ func AllBranches(c *context.Context) {
|
||||
}
|
||||
c.Data["Branches"] = branches
|
||||
|
||||
c.Success( BRANCHES_ALL)
|
||||
c.Success(BRANCHES_ALL)
|
||||
}
|
||||
|
||||
func DeleteBranchPost(c *context.Context) {
|
||||
|
||||
@@ -320,7 +320,7 @@ func DeleteRelease(c *context.Context) {
|
||||
c.Flash.Success(c.Tr("repo.release.deletion_success"))
|
||||
}
|
||||
|
||||
c.JSONSuccess( map[string]interface{}{
|
||||
c.JSONSuccess(map[string]interface{}{
|
||||
"redirect": c.Repo.RepoLink + "/releases",
|
||||
})
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"gogs.io/gogs/internal/db"
|
||||
"gogs.io/gogs/internal/db/errors"
|
||||
"gogs.io/gogs/internal/form"
|
||||
"gogs.io/gogs/internal/netutil"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -118,24 +119,7 @@ func WebhooksNew(c *context.Context, orCtx *orgRepoContext) {
|
||||
c.Success(orCtx.TmplNew)
|
||||
}
|
||||
|
||||
var localHostnames = []string{
|
||||
"localhost",
|
||||
"127.0.0.1",
|
||||
"::1",
|
||||
"0:0:0:0:0:0:0:1",
|
||||
}
|
||||
|
||||
// isLocalHostname returns true if given hostname is a known local address.
|
||||
func isLocalHostname(hostname string) bool {
|
||||
for _, local := range localHostnames {
|
||||
if hostname == local {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func validateWebhook(actor *db.User, l macaron.Locale, w *db.Webhook) (field string, msg string, ok bool) {
|
||||
func validateWebhook(actor *db.User, l macaron.Locale, w *db.Webhook) (field, msg string, ok bool) {
|
||||
if !actor.IsAdmin {
|
||||
// 🚨 SECURITY: Local addresses must not be allowed by non-admins to prevent SSRF,
|
||||
// see https://github.com/gogs/gogs/issues/5366 for details.
|
||||
@@ -144,7 +128,7 @@ func validateWebhook(actor *db.User, l macaron.Locale, w *db.Webhook) (field str
|
||||
return "PayloadURL", l.Tr("repo.settings.webhook.err_cannot_parse_payload_url", err), false
|
||||
}
|
||||
|
||||
if isLocalHostname(payloadURL.Hostname()) {
|
||||
if netutil.IsLocalHostname(payloadURL.Hostname(), conf.Security.LocalNetworkAllowlist) {
|
||||
return "PayloadURL", l.Tr("repo.settings.webhook.err_cannot_use_local_addresses"), false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,25 +13,6 @@ import (
|
||||
"gogs.io/gogs/internal/mocks"
|
||||
)
|
||||
|
||||
func Test_isLocalHostname(t *testing.T) {
|
||||
tests := []struct {
|
||||
hostname string
|
||||
want bool
|
||||
}{
|
||||
{hostname: "localhost", want: true},
|
||||
{hostname: "127.0.0.1", want: true},
|
||||
{hostname: "::1", want: true},
|
||||
{hostname: "0:0:0:0:0:0:0:1", want: true},
|
||||
|
||||
{hostname: "gogs.io", want: false},
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run("", func(t *testing.T) {
|
||||
assert.Equal(t, test.want, isLocalHostname(test.hostname))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_validateWebhook(t *testing.T) {
|
||||
l := &mocks.Locale{
|
||||
MockLang: "en",
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
#!/bin/sh
|
||||
su git -c "/home/git/gogs/scripts/gogs_supervisord.sh restart"
|
||||
@@ -1,33 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
outPath=./output
|
||||
|
||||
rm -rf $outPath
|
||||
mkdir $outPath
|
||||
|
||||
go build ../gogs.go
|
||||
PLATFORM=$(uname | cut -d _ -f 1)
|
||||
if [ "$PLATFORM" = "MINGW32" ] || [ "$PLATFORM" = "MINGW64" ] || [ "$PLATFORM" = "CYGWIN" ]; then
|
||||
GOGS_EXE=gogs.exe
|
||||
else
|
||||
GOGS_EXE=gogs
|
||||
fi
|
||||
chmod +x $GOGS_EXE
|
||||
mv $GOGS_EXE $outPath/
|
||||
|
||||
cp -r ../conf/ $outPath/conf/
|
||||
cp -r ../custom/ $outPath/custom/
|
||||
cp -r dockerfiles/ $outPath/dockerfiles/
|
||||
cp -r ../public/ $outPath/public/
|
||||
cp -r ../templates/ $outPath/templates/
|
||||
cp ../cert.pem $outPath/
|
||||
cp ../CONTRIBUTING.md $outPath/
|
||||
cp gogs_supervisord.sh $outPath/
|
||||
cp ../key.pem $outPath/
|
||||
cp ../LICENSE $outPath/
|
||||
cp ../README.md $outPath/
|
||||
cp ../README_ZH.md $outPath/
|
||||
cp start.bat $outPath/
|
||||
cp start.sh $outPath/
|
||||
cp ../wercker.yml $outPath/
|
||||
cp mysql.sql $outPath/
|
||||
@@ -1,27 +0,0 @@
|
||||
outPlattform=freebsd
|
||||
outArch=amd64
|
||||
outPath=./output_${outPlattform}_$outArch
|
||||
|
||||
rm -rf $outPath
|
||||
mkdir $outPath
|
||||
|
||||
CGO_ENABLED=0 GOOS=$outPlattform GOARCH=$outArch go build ../gogs.go
|
||||
chmod +x gogs
|
||||
mv gogs $outPath/
|
||||
|
||||
cp -r ../conf/ $outPath/conf/
|
||||
cp -r ../custom/ $outPath/custom/
|
||||
cp -r dockerfiles/ $outPath/dockerfiles/
|
||||
cp -r ../public/ $outPath/public/
|
||||
cp -r ../templates/ $outPath/templates/
|
||||
cp ../cert.pem $outPath/
|
||||
cp ../CONTRIBUTING.md $outPath/
|
||||
cp gogs_supervisord.sh $outPath/
|
||||
cp ../key.pem $outPath/
|
||||
cp ../LICENSE $outPath/
|
||||
cp ../README.md $outPath/
|
||||
cp ../README_ZH.md $outPath/
|
||||
cp start.bat $outPath/
|
||||
cp start.sh $outPath/
|
||||
cp ../wercker.yml $outPath/
|
||||
cp mysql.sql $outPath/
|
||||
@@ -1,27 +0,0 @@
|
||||
outPlattform=linux
|
||||
outArch=amd64
|
||||
outPath=./output_${outPlattform}_$outArch
|
||||
|
||||
rm -rf $outPath
|
||||
mkdir $outPath
|
||||
|
||||
CGO_ENABLED=0 GOOS=$outPlattform GOARCH=$outArch go build -buildmode=pie ../gogs.go
|
||||
chmod +x gogs
|
||||
mv gogs $outPath/
|
||||
|
||||
cp -r ../conf/ $outPath/conf/
|
||||
cp -r ../custom/ $outPath/custom/
|
||||
cp -r dockerfiles/ $outPath/dockerfiles/
|
||||
cp -r ../public/ $outPath/public/
|
||||
cp -r ../templates/ $outPath/templates/
|
||||
cp ../cert.pem $outPath/
|
||||
cp ../CONTRIBUTING.md $outPath/
|
||||
cp gogs_supervisord.sh $outPath/
|
||||
cp ../key.pem $outPath/
|
||||
cp ../LICENSE $outPath/
|
||||
cp ../README.md $outPath/
|
||||
cp ../README_ZH.md $outPath/
|
||||
cp start.bat $outPath/
|
||||
cp start.sh $outPath/
|
||||
cp ../wercker.yml $outPath/
|
||||
cp mysql.sql $outPath/
|
||||
1
scripts/init/openbsd/gogs
Executable file → Normal file
1
scripts/init/openbsd/gogs
Executable file → Normal file
@@ -1,6 +1,7 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# $OpenBSD$
|
||||
# shellcheck disable=SC2034,SC1091,SC2154,SC2086
|
||||
|
||||
daemon="/home/git/gogs/gogs"
|
||||
daemon_user="git"
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
SET @s = IF(version() < 8 OR version() LIKE '%MariaDB%',
|
||||
'SET GLOBAL innodb_file_per_table = ON,
|
||||
innodb_file_format = Barracuda,
|
||||
innodb_large_prefix = ON;',
|
||||
SET @s = IF(version() < 8 OR (version() LIKE '%MariaDB%' AND version() < 10.3),
|
||||
'SET GLOBAL innodb_file_per_table = ON,
|
||||
innodb_file_format = Barracuda,
|
||||
innodb_large_prefix = ON;',
|
||||
'SET GLOBAL innodb_file_per_table = ON;');
|
||||
PREPARE stmt1 FROM @s;
|
||||
EXECUTE stmt1;
|
||||
EXECUTE stmt1;
|
||||
|
||||
DROP DATABASE IF EXISTS gogs;
|
||||
CREATE DATABASE IF NOT EXISTS gogs CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
|
||||
|
||||
|
||||
@@ -206,6 +206,8 @@
|
||||
<dd><i class="fa fa{{if .Security.EnableLoginStatusCookie}}-check{{end}}-square-o"></i></dd>
|
||||
<dt>{{.i18n.Tr "admin.config.security.login_status_cookie_name"}}</dt>
|
||||
<dd>{{.Security.LoginStatusCookieName}}</dd>
|
||||
<dt>{{.i18n.Tr "admin.config.security.local_network_allowlist"}}</dt>
|
||||
<dd><code>{{.Security.LocalNetworkAllowlist}}</code></dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
{{range .Members}}
|
||||
<div class="item ui grid">
|
||||
<div class="ui one wide column">
|
||||
<img class="ui avatar" src="{{.RelAvatarLink}}?s=48">
|
||||
<img class="ui avatar" src="{{AppendAvatarSize .RelAvatarLink 48}}">
|
||||
</div>
|
||||
<div class="ui three wide column">
|
||||
<div class="meta"><a href="{{.HomeLink}}">{{.Name}}</a></div>
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
{{if .Submodule}}
|
||||
<td>
|
||||
<span class="octicon octicon-file-submodule"></span>
|
||||
<a href="{{InferSubmoduleURL .Submodule}}">{{.Entry.Name}} @ {{ShortSHA1 .Submodule.Commit}}</a>
|
||||
<a href="{{InferSubmoduleURL $.RepoLink .Submodule}}">{{.Entry.Name}} @ {{ShortSHA1 .Submodule.Commit}}</a>
|
||||
</td>
|
||||
{{else}}
|
||||
<td class="name">
|
||||
|
||||
Reference in New Issue
Block a user