mirror of
https://github.com/hacdias/webdav.git
synced 2026-09-22 03:20:41 +08:00
Compare commits
37
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9bc219271c | ||
|
|
7ca822bcaf | ||
|
|
a98d0c2616 | ||
|
|
98e92d0c13 | ||
|
|
53416e57da | ||
|
|
ff6637f396 | ||
|
|
15fbcd391b | ||
|
|
70b3630d08 | ||
|
|
aa014b092b | ||
|
|
b4553710eb | ||
|
|
e07e55d97a | ||
|
|
cfee0f9f0b | ||
|
|
79eb02aba4 | ||
|
|
7bbe36e4c1 | ||
|
|
520b7df04d | ||
|
|
8f3a3298a8 | ||
|
|
1753aa2945 | ||
|
|
4645f6f46f | ||
|
|
e998e2a838 | ||
|
|
3b3dedc4eb | ||
|
|
8706802dac | ||
|
|
5676a1c382 | ||
|
|
c938367dc0 | ||
|
|
758410ba64 | ||
|
|
1bbf52e475 | ||
|
|
2c2a325215 | ||
|
|
f7e006b449 | ||
|
|
49f61eab79 | ||
|
|
5d1a68c4f2 | ||
|
|
04cee682fb | ||
|
|
19d128cfbd | ||
|
|
118a0dda88 | ||
|
|
aad8e563a7 | ||
|
|
8446f9bdae | ||
|
|
5226853fca | ||
|
|
e350dc989a | ||
|
|
65de8e8578 |
@@ -12,10 +12,10 @@ jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-go@v5
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: "1.24.x"
|
||||
go-version: "1.25.x"
|
||||
- run: go build .
|
||||
env:
|
||||
CGO_ENABLED: '0'
|
||||
|
||||
@@ -18,7 +18,7 @@ jobs:
|
||||
id-token: write
|
||||
steps:
|
||||
- name: Check out the repo
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
@@ -12,10 +12,10 @@ jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-go@v5
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: "1.24.x"
|
||||
- uses: golangci/golangci-lint-action@v6
|
||||
go-version: "1.25.x"
|
||||
- uses: golangci/golangci-lint-action@v8
|
||||
with:
|
||||
version: "v1.64"
|
||||
version: "latest"
|
||||
|
||||
@@ -12,10 +12,10 @@ jobs:
|
||||
goreleaser:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-go@v5
|
||||
- uses: actions/setup-go@v6
|
||||
- uses: goreleaser/goreleaser-action@v6
|
||||
with:
|
||||
distribution: goreleaser
|
||||
|
||||
@@ -13,9 +13,9 @@ jobs:
|
||||
name: test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-go@v5
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-go@v6
|
||||
with:
|
||||
go-version: "1.24.x"
|
||||
go-version: "1.25.x"
|
||||
- name: Run test with coverage
|
||||
run: go test -race -coverprofile=coverage.txt -covermode=atomic ./...
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
FROM golang:1.24-alpine3.20 AS build
|
||||
FROM golang:1.25-alpine3.22 AS build
|
||||
|
||||
ARG VERSION="untracked"
|
||||
|
||||
|
||||
@@ -14,6 +14,14 @@ For a manual install, please refer to the [releases](https://github.com/hacdias/
|
||||
go install github.com/hacdias/webdav/v5@latest
|
||||
```
|
||||
|
||||
### Homebrew
|
||||
|
||||
If you have Homebrew available on your system, you can also install `webdav` using it:
|
||||
|
||||
```
|
||||
brew install webdav
|
||||
```
|
||||
|
||||
### Docker
|
||||
|
||||
Docker images are provided on both [GitHub's registry](https://github.com/hacdias/webdav/pkgs/container/webdav) and [Docker Hub](https://hub.docker.com/r/hacdias/webdav). You can pull the images using one of the following two commands. Note that this commands pull the latest released version. You can use specific tags to pin specific versions, or use `main` for the development branch.
|
||||
@@ -94,7 +102,8 @@ permissions: R
|
||||
|
||||
# The default permissions rules for users. Default is none. Rules are applied
|
||||
# from last to first, that is, the first rule that matches the request, starting
|
||||
# from the end, will be applied to the request.
|
||||
# from the end, will be applied to the request. Rule paths are always relative to
|
||||
# the user's directory.
|
||||
rules: []
|
||||
|
||||
# The behavior of redefining the rules for users. It can be:
|
||||
@@ -158,14 +167,15 @@ users:
|
||||
# Override default permissions.
|
||||
permissions: CRUD
|
||||
rules:
|
||||
# With this rule, the user CANNOT access /some/files.
|
||||
# With this rule, the user CANNOT access {user directory}/some/files.
|
||||
- path: /some/file
|
||||
permissions: none
|
||||
# With this rule, the user CAN create, read, update and delete within /public/access.
|
||||
# With this rule, the user CAN create, read, update and delete within
|
||||
# {user directory}/public/access.
|
||||
- path: /public/access/
|
||||
permissions: CRUD
|
||||
# With this rule, the user CAN read and update all files ending with .js. It uses
|
||||
# a regular expression.
|
||||
# With this rule, the user CAN read and update all files ending with .js.
|
||||
# It uses a regular expression.
|
||||
- regex: "^.+.js$"
|
||||
permissions: RU
|
||||
```
|
||||
@@ -181,7 +191,9 @@ The `allowed_*` properties are optional, the default value for each of them will
|
||||
|
||||
### Reverse Proxy Service
|
||||
|
||||
When using a reverse proxy implementation, like Caddy, Nginx, or Apache, note that you need to forward the correct headers in order to avoid 502 errors. Here's a Nginx configuration example:
|
||||
When using a reverse proxy implementation, like Caddy, Nginx, or Apache, note that you need to forward the correct headers in order to avoid 502 errors.
|
||||
|
||||
#### Nginx Configuration Example
|
||||
|
||||
```nginx
|
||||
location / {
|
||||
@@ -191,6 +203,32 @@ location / {
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header Host $host;
|
||||
proxy_redirect off;
|
||||
|
||||
# Ensure COPY and MOVE commands work. Change https://example.com to the
|
||||
# correct address where the WebDAV server will be deployed at.
|
||||
set $dest $http_destination;
|
||||
if ($http_destination ~ "^https://example.com(?<path>(.+))") {
|
||||
set $dest /$path;
|
||||
}
|
||||
proxy_set_header Destination $dest;
|
||||
}
|
||||
```
|
||||
|
||||
#### Caddy Configuration Example
|
||||
|
||||
```Caddyfile
|
||||
example.com {
|
||||
tls internal # for local development
|
||||
# tls [email protected] # so that Caddy gets certs for you via Letsencrypt
|
||||
|
||||
# Rewrites destination to remove host and include only the path e.g. /test.txt
|
||||
@hasDest header_regexp dest ^https?://[^/]+(.*)$
|
||||
header @hasDest Destination {re.dest.1}
|
||||
|
||||
reverse_proxy 127.0.0.1:6065 { # if running on the same network in docker you can just point to the service name e.g. webdav:6065
|
||||
header_up X-Real-IP {remote_host}
|
||||
header_up REMOTE-HOST {remote_host}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -1,34 +1,35 @@
|
||||
module github.com/hacdias/webdav/v5
|
||||
|
||||
go 1.24.0
|
||||
go 1.25.0
|
||||
|
||||
require (
|
||||
github.com/coreos/go-systemd/v22 v22.5.0
|
||||
github.com/go-viper/mapstructure/v2 v2.2.1
|
||||
github.com/coreos/go-systemd/v22 v22.6.0
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0
|
||||
github.com/rs/cors v1.11.1
|
||||
github.com/spf13/cobra v1.9.1
|
||||
github.com/spf13/pflag v1.0.6
|
||||
github.com/spf13/viper v1.20.0
|
||||
github.com/stretchr/testify v1.10.0
|
||||
github.com/studio-b12/gowebdav v0.9.0
|
||||
github.com/spf13/cobra v1.10.1
|
||||
github.com/spf13/pflag v1.0.10
|
||||
github.com/spf13/viper v1.21.0
|
||||
github.com/stretchr/testify v1.11.1
|
||||
github.com/studio-b12/gowebdav v0.11.0
|
||||
go.uber.org/zap v1.27.0
|
||||
golang.org/x/crypto v0.36.0
|
||||
golang.org/x/net v0.37.0
|
||||
golang.org/x/crypto v0.43.0
|
||||
golang.org/x/net v0.46.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/fsnotify/fsnotify v1.8.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.9.0 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/sagikazarmark/locafero v0.8.0 // indirect
|
||||
github.com/sourcegraph/conc v0.3.0 // indirect
|
||||
github.com/spf13/afero v1.14.0 // indirect
|
||||
github.com/spf13/cast v1.7.1 // indirect
|
||||
github.com/sagikazarmark/locafero v0.11.0 // indirect
|
||||
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect
|
||||
github.com/spf13/afero v1.15.0 // indirect
|
||||
github.com/spf13/cast v1.10.0 // indirect
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/sys v0.31.0 // indirect
|
||||
golang.org/x/text v0.23.0 // indirect
|
||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||
golang.org/x/sys v0.37.0 // indirect
|
||||
golang.org/x/text v0.30.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
|
||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/coreos/go-systemd/v22 v22.6.0 h1:aGVa/v8B7hpb0TKl0MWoAavPDmHvobFe5R5zn0bCJWo=
|
||||
github.com/coreos/go-systemd/v22 v22.6.0/go.mod h1:iG+pp635Fo7ZmV/j14KUcmEyWF+0X7Lua8rrTWzYgWU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
||||
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||
github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M=
|
||||
github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
||||
github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss=
|
||||
github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
|
||||
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
@@ -18,8 +17,8 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
|
||||
github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
|
||||
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
|
||||
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||
@@ -27,24 +26,25 @@ github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/f
|
||||
github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA=
|
||||
github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sagikazarmark/locafero v0.8.0 h1:mXaMVw7IqxNBxfv3LdWt9MDmcWDQ1fagDH918lOdVaQ=
|
||||
github.com/sagikazarmark/locafero v0.8.0/go.mod h1:UBUyz37V+EdMS3hDF3QWIiVr/2dPrx49OMO0Bn0hJqk=
|
||||
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
|
||||
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
|
||||
github.com/spf13/afero v1.14.0 h1:9tH6MapGnn/j0eb0yIXiLjERO8RB6xIVZRDCX7PtqWA=
|
||||
github.com/spf13/afero v1.14.0/go.mod h1:acJQ8t0ohCGuMN3O+Pv0V0hgMxNYDlvdk+VTfyZmbYo=
|
||||
github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y=
|
||||
github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
|
||||
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
|
||||
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
|
||||
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
|
||||
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.20.0 h1:zrxIyR3RQIOsarIrgL8+sAvALXul9jeEPa06Y0Ph6vY=
|
||||
github.com/spf13/viper v1.20.0/go.mod h1:P9Mdzt1zoHIG8m2eZQinpiBjo6kCmZSKBClNNqjJvu4=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/studio-b12/gowebdav v0.9.0 h1:1j1sc9gQnNxbXXM4M/CebPOX4aXYtr7MojAVcN4dHjU=
|
||||
github.com/studio-b12/gowebdav v0.9.0/go.mod h1:bHA7t77X/QFExdeAnDzK6vKM34kEZAcE1OX4MfiwjkE=
|
||||
github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc=
|
||||
github.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik=
|
||||
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw=
|
||||
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U=
|
||||
github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I=
|
||||
github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg=
|
||||
github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY=
|
||||
github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo=
|
||||
github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s=
|
||||
github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0=
|
||||
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
|
||||
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU=
|
||||
github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
github.com/studio-b12/gowebdav v0.11.0 h1:qbQzq4USxY28ZYsGJUfO5jR+xkFtcnwWgitp4Zp1irU=
|
||||
github.com/studio-b12/gowebdav v0.11.0/go.mod h1:bHA7t77X/QFExdeAnDzK6vKM34kEZAcE1OX4MfiwjkE=
|
||||
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
|
||||
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
@@ -53,14 +53,16 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
|
||||
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
|
||||
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
|
||||
golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
|
||||
golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
|
||||
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
|
||||
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
|
||||
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
|
||||
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
|
||||
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
||||
golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04=
|
||||
golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0=
|
||||
golang.org/x/net v0.46.0 h1:giFlY12I07fugqwPuWJi68oOnpfqFnJIJzaIIm2JVV4=
|
||||
golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210=
|
||||
golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
|
||||
golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k=
|
||||
golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/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=
|
||||
|
||||
@@ -3,6 +3,7 @@ package lib
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
@@ -53,6 +54,10 @@ func ParseConfig(filename string, flags *pflag.FlagSet) (*Config, error) {
|
||||
// Configuration file settings
|
||||
v.AddConfigPath(".")
|
||||
v.AddConfigPath("/etc/webdav/")
|
||||
if path, err := os.Executable(); err == nil {
|
||||
v.AddConfigPath(filepath.Dir(path))
|
||||
}
|
||||
|
||||
v.SetConfigName("config")
|
||||
if filename != "" {
|
||||
v.SetConfigFile(filename)
|
||||
|
||||
+1
-1
@@ -47,7 +47,7 @@ type noSniffFileInfo struct {
|
||||
}
|
||||
|
||||
func (w noSniffFileInfo) ContentType(ctx context.Context) (contentType string, err error) {
|
||||
if mimeType := mime.TypeByExtension(path.Ext(w.FileInfo.Name())); mimeType != "" {
|
||||
if mimeType := mime.TypeByExtension(path.Ext(w.Name())); mimeType != "" {
|
||||
// We can figure out the mime from the extension.
|
||||
return mimeType, nil
|
||||
} else {
|
||||
|
||||
+10
-2
@@ -23,6 +23,8 @@ type Handler struct {
|
||||
}
|
||||
|
||||
func NewHandler(c *Config) (http.Handler, error) {
|
||||
ls := webdav.NewMemLS()
|
||||
|
||||
h := &Handler{
|
||||
noPassword: c.NoPassword,
|
||||
behindProxy: c.BehindProxy,
|
||||
@@ -36,7 +38,10 @@ func NewHandler(c *Config) (http.Handler, error) {
|
||||
Dir: webdav.Dir(c.Directory),
|
||||
noSniff: c.NoSniff,
|
||||
},
|
||||
LockSystem: webdav.NewMemLS(),
|
||||
LockSystem: &lockSystem{
|
||||
LockSystem: ls,
|
||||
directory: c.Directory,
|
||||
},
|
||||
},
|
||||
},
|
||||
users: map[string]*handlerUser{},
|
||||
@@ -51,7 +56,10 @@ func NewHandler(c *Config) (http.Handler, error) {
|
||||
Dir: webdav.Dir(u.Directory),
|
||||
noSniff: c.NoSniff,
|
||||
},
|
||||
LockSystem: webdav.NewMemLS(),
|
||||
LockSystem: &lockSystem{
|
||||
LockSystem: ls,
|
||||
directory: u.Directory,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
+46
-1
@@ -217,7 +217,7 @@ users:
|
||||
})
|
||||
}
|
||||
|
||||
func TestServerRules(t *testing.T) {
|
||||
func TestServerRulesRestrictive(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
dir := makeTestDirectory(t, map[string][]byte{
|
||||
@@ -292,6 +292,51 @@ users:
|
||||
require.ErrorContains(t, err, "403")
|
||||
}
|
||||
|
||||
func TestServerRulesAdditive(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
dir := makeTestDirectory(t, map[string][]byte{
|
||||
"foo.txt": []byte("foo"),
|
||||
"bar.js": []byte("foo js"),
|
||||
"a/foo.js": []byte("foo js"),
|
||||
"a/foo.txt": []byte("foo txt"),
|
||||
"b/foo.txt": []byte("foo b"),
|
||||
})
|
||||
|
||||
srv := makeTestServer(t, fmt.Sprintf(`
|
||||
directory: %s
|
||||
permissions: none
|
||||
|
||||
users:
|
||||
- username: basic
|
||||
password: basic
|
||||
rules:
|
||||
- regex: "^.+.js$"
|
||||
permissions: R
|
||||
- path: "/a/foo.txt"
|
||||
permissions: CRU
|
||||
- path: "/b/"
|
||||
permissions: D
|
||||
`, dir))
|
||||
|
||||
client := gowebdav.NewClient(srv.URL, "basic", "basic")
|
||||
|
||||
_, err := client.ReadDir("/")
|
||||
require.ErrorContains(t, err, "403")
|
||||
|
||||
err = client.Write("/foo.txt", []byte("new"), 0666)
|
||||
require.ErrorContains(t, err, "403")
|
||||
|
||||
err = client.Write("/new.txt", []byte("new"), 0666)
|
||||
require.ErrorContains(t, err, "403")
|
||||
|
||||
err = client.Copy("/bar.js", "/a/foo.txt", true)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = client.Remove("/b/foo.txt")
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestServerRulesPrefix(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package lib
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"golang.org/x/net/webdav"
|
||||
)
|
||||
|
||||
var _ webdav.LockSystem = &lockSystem{}
|
||||
|
||||
// LockSystem wraps a [webdav.LockSystem] with a root directory, allowing
|
||||
// to reuse the same [webdav.LockSystem] for multiple users with different base
|
||||
// directories, meaning we can correctly lock the files across different users.
|
||||
type lockSystem struct {
|
||||
webdav.LockSystem
|
||||
directory string
|
||||
}
|
||||
|
||||
func (l *lockSystem) Confirm(now time.Time, name0, name1 string, conditions ...webdav.Condition) (release func(), err error) {
|
||||
if name0 != "" {
|
||||
name0 = filepath.Join(l.directory, name0)
|
||||
}
|
||||
|
||||
if name1 != "" {
|
||||
name1 = filepath.Join(l.directory, name1)
|
||||
}
|
||||
|
||||
return l.LockSystem.Confirm(now, name0, name1, conditions...)
|
||||
}
|
||||
|
||||
func (l *lockSystem) Create(now time.Time, details webdav.LockDetails) (token string, err error) {
|
||||
details.Root = filepath.Join(l.directory, details.Root)
|
||||
return l.LockSystem.Create(now, details)
|
||||
}
|
||||
+3
-1
@@ -56,9 +56,11 @@ func (p UserPermissions) Allowed(r *request, fileExists func(string) bool) bool
|
||||
// we fail immediately. If no rule matches, we check the global permissions.
|
||||
if r.method == "COPY" || r.method == "MOVE" {
|
||||
dst := r.destination
|
||||
ruleMatched := false
|
||||
|
||||
for i := len(p.Rules) - 1; i >= 0; i-- {
|
||||
if p.Rules[i].Matches(dst) {
|
||||
ruleMatched = true
|
||||
if !p.Rules[i].Permissions.AllowedDestination(r, fileExists) {
|
||||
return false
|
||||
}
|
||||
@@ -68,7 +70,7 @@ func (p UserPermissions) Allowed(r *request, fileExists func(string) bool) bool
|
||||
}
|
||||
}
|
||||
|
||||
if !p.Permissions.AllowedDestination(r, fileExists) {
|
||||
if !ruleMatched && !p.Permissions.AllowedDestination(r, fileExists) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||
"extends": [
|
||||
"config:recommended",
|
||||
"group:allNonMajor",
|
||||
"group:allDigest",
|
||||
":disableDependencyDashboard"
|
||||
],
|
||||
"postUpdateOptions": [
|
||||
"gomodUpdateImportPaths",
|
||||
"gomodTidy"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user