webdav: add prefix support

This commit is contained in:
Nicola Murino 2021-03-07 17:10:45 +01:00
parent 1ab02d5891
commit 4c658bb6f0
No known key found for this signature in database
GPG key ID: 2F1FB59433D5A8CB
9 changed files with 25 additions and 3 deletions

View file

@ -165,6 +165,8 @@ After starting SFTPGo you can manage users and folders using:
To support embedded data providers like `bolt` and `SQLite` we can't have a CLI that directly write users and folders to the data provider, we always have to use the REST API.
Full details for users, folders, admins and other resources are documented in the [OpenAPI](/httpd/schema/openapi.yaml) schema. If you want to render the schema without importing it manually, you can explore it on [Stoplight](https://sftpgo.stoplight.io/docs/sftpgo/openapi.yaml).
## Tutorials
Some step-to-step tutorials can be found inside the source tree [howto](./docs/howto "How-to") directory.

View file

@ -59,6 +59,7 @@ var (
EnableHTTPS: false,
ClientAuthType: 0,
TLSCipherSuites: nil,
Prefix: "",
}
defaultHTTPDBinding = httpd.Binding{
Address: "127.0.0.1",
@ -675,6 +676,12 @@ func getWebDAVDBindingFromEnv(idx int) {
isSet = true
}
prefix, ok := os.LookupEnv(fmt.Sprintf("SFTPGO_WEBDAVD__BINDINGS__%v__PREFIX", idx))
if ok {
binding.Prefix = prefix
isSet = true
}
if isSet {
if len(globalConf.WebDAVD.Bindings) > idx {
globalConf.WebDAVD.Bindings[idx] = binding

View file

@ -523,6 +523,7 @@ func TestWebDAVBindingsFromEnv(t *testing.T) {
os.Setenv("SFTPGO_WEBDAVD__BINDINGS__2__PORT", "9000")
os.Setenv("SFTPGO_WEBDAVD__BINDINGS__2__ENABLE_HTTPS", "1")
os.Setenv("SFTPGO_WEBDAVD__BINDINGS__2__CLIENT_AUTH_TYPE", "1")
os.Setenv("SFTPGO_WEBDAVD__BINDINGS__2__PREFIX", "/dav2")
t.Cleanup(func() {
os.Unsetenv("SFTPGO_WEBDAVD__BINDINGS__1__ADDRESS")
os.Unsetenv("SFTPGO_WEBDAVD__BINDINGS__1__PORT")
@ -532,6 +533,7 @@ func TestWebDAVBindingsFromEnv(t *testing.T) {
os.Unsetenv("SFTPGO_WEBDAVD__BINDINGS__2__PORT")
os.Unsetenv("SFTPGO_WEBDAVD__BINDINGS__2__ENABLE_HTTPS")
os.Unsetenv("SFTPGO_WEBDAVD__BINDINGS__2__CLIENT_AUTH_TYPE")
os.Unsetenv("SFTPGO_WEBDAVD__BINDINGS__2__PREFIX")
})
configDir := ".."
@ -543,17 +545,20 @@ func TestWebDAVBindingsFromEnv(t *testing.T) {
require.Empty(t, bindings[0].Address)
require.False(t, bindings[0].EnableHTTPS)
require.Len(t, bindings[0].TLSCipherSuites, 0)
require.Empty(t, bindings[0].Prefix)
require.Equal(t, 8000, bindings[1].Port)
require.Equal(t, "127.0.0.1", bindings[1].Address)
require.False(t, bindings[1].EnableHTTPS)
require.Equal(t, 0, bindings[1].ClientAuthType)
require.Len(t, bindings[1].TLSCipherSuites, 1)
require.Equal(t, "TLS_RSA_WITH_AES_128_CBC_SHA", bindings[1].TLSCipherSuites[0])
require.Empty(t, bindings[1].Prefix)
require.Equal(t, 9000, bindings[2].Port)
require.Equal(t, "127.0.1.1", bindings[2].Address)
require.True(t, bindings[2].EnableHTTPS)
require.Equal(t, 1, bindings[2].ClientAuthType)
require.Nil(t, bindings[2].TLSCipherSuites)
require.Equal(t, "/dav2", bindings[2].Prefix)
}
func TestHTTPDBindingsFromEnv(t *testing.T) {

View file

@ -134,6 +134,7 @@ The configuration file contains the following sections:
- `enable_https`, boolean. Set to `true` and provide both a certificate and a key file to enable HTTPS connection for this binding. Default `false`.
- `client_auth_type`, integer. Set to `1` to require a client certificate and verify it. Set to `2` to request a client certificate during the TLS handshake and verify it if given, in this mode the client is allowed not to send a certificate. At least one certification authority must be defined in order to verify client certificates. If no certification authority is defined, this setting is ignored. Default: 0.
- `tls_cipher_suites`, list of strings. List of supported cipher suites for TLS version 1.2. If empty, a default list of secure cipher suites is used, with a preference order based on hardware performance. Note that TLS 1.3 ciphersuites are not configurable. The supported ciphersuites names are defined [here](https://github.com/golang/go/blob/master/src/crypto/tls/cipher_suites.go#L52). Any invalid name will be silently ignored. The order matters, the ciphers listed first will be the preferred ones. Default: empty.
- `prefix`, string. Prefix for WebDAV resources, if empty WebDAV resources will be available at the `/` URI. If defined it must be an absolute URI, for example `/dav`. Default: "".
- `bind_port`, integer. Deprecated, please use `bindings`.
- `bind_address`, string. Deprecated, please use `bindings`.
- `certificate_file`, string. Certificate for WebDAV over HTTPS. This can be an absolute path or a path relative to the config dir.

View file

@ -40,7 +40,7 @@ You can create other administrator and assign them the following permissions:
You can also restrict administrator access based on the source IP address. If you are running SFTPGo behind a reverse proxy you need to allow both the proxy IP address and the real client IP.
The OpenAPI 3 schema for the exposed API can be found inside the source tree: [openapi.yaml](../httpd/schema/openapi.yaml "OpenAPI 3 specs").
The OpenAPI 3 schema for the exposed API can be found inside the source tree: [openapi.yaml](../httpd/schema/openapi.yaml "OpenAPI 3 specs"). If you want to render the schema without importing it manually, you can explore it on [Stoplight](https://sftpgo.stoplight.io/docs/sftpgo/openapi.yaml).
You can generate your own REST client in your preferred programming language, or even bash scripts, using an OpenAPI generator such as [swagger-codegen](https://github.com/swagger-api/swagger-codegen) or [OpenAPI Generator](https://openapi-generator.tech/).

View file

@ -2,7 +2,7 @@
The `WebDAV` support can be enabled by configuring one or more `bindings` inside the `webdavd` configuration section.
Each user can access their home directory using the path `http/s://<SFTPGo ip>:<WevDAVPORT>/`.
Each user can access their home directory using the path `http/s://<SFTPGo ip>:<WevDAVPORT>/<prefix>`. By default `prefix` is empty. If you define a prefix it must be an abosulte URI, for example `/dav`.
WebDAV is quite a different protocol than SCP/FTP, there is no session concept, each command is a separate HTTP request and must be authenticated, to improve performance SFTPGo caches authenticated users. This way SFTPGo don't need to do a dataprovider query and a password check for each request.
@ -19,6 +19,8 @@ The MIME types caching configurations allows to set the maximum number of MIME t
WebDAV should work as expected for most use cases but there are some minor issues and some missing features.
If you use WebDAV behind a reverse proxy ensure to preserve the `Host` header or `COPY`/`MOVE` operations will fail. For example for apache you have to set `ProxyPreserveHost On`.
Know issues:
- removing a directory tree on Cloud Storage backends could generate a `not found` error when removing the last (virtual) directory. This happens if the client cycles the directories tree itself and removes files and directories one by one instead of issuing a single remove command

View file

@ -86,7 +86,8 @@
"address": "",
"enable_https": false,
"client_auth_type": 0,
"tls_cipher_suites": []
"tls_cipher_suites": [],
"prefix": ""
}
],
"certificate_file": "",

View file

@ -203,6 +203,7 @@ func (s *webDavServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}
handler := webdav.Handler{
Prefix: s.binding.Prefix,
FileSystem: connection,
LockSystem: lockSystem,
Logger: writeLog,

View file

@ -86,6 +86,9 @@ type Binding struct {
// any invalid name will be silently ignored.
// The order matters, the ciphers listed first will be the preferred ones.
TLSCipherSuites []string `json:"tls_cipher_suites" mapstructure:"tls_cipher_suites"`
// Prefix for WebDAV resources, if empty WebDAV resources will be available at the
// root ("/") URI. If defined it must be an absolute URI.
Prefix string `json:"prefix" mapstructure:"prefix"`
}
func (b *Binding) isMutualTLSEnabled() bool {