experimental webdav upload
This commit is contained in:
parent
5e9ce5a306
commit
7570b09f9f
10 changed files with 47 additions and 2 deletions
|
|
@ -50,7 +50,8 @@ See the `scripts/` directory on how to install docstore on Linux or OpenBSD.
|
||||||
"tesseract_oem": 1, // tesseract oem value
|
"tesseract_oem": 1, // tesseract oem value
|
||||||
"foreground": false, // do not fork into the background
|
"foreground": false, // do not fork into the background
|
||||||
"secure_cookie": false, // enable secure cookie flag
|
"secure_cookie": false, // enable secure cookie flag
|
||||||
"debug": false // enable debugging
|
"debug": false, // enable debugging
|
||||||
|
"webdav": false // enable webdav upload
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -61,6 +62,9 @@ See the `scripts/` directory on how to install docstore on Linux or OpenBSD.
|
||||||
* The `Index All` button tries add every file not already indexed to the index
|
* The `Index All` button tries add every file not already indexed to the index
|
||||||
* Custom regex based tags (see https://golang.org/pkg/regexp/syntax/)
|
* Custom regex based tags (see https://golang.org/pkg/regexp/syntax/)
|
||||||
* The `Retag All` button will reapply the current tags to all indexed documents
|
* The `Retag All` button will reapply the current tags to all indexed documents
|
||||||
|
* Optional WebDav upload functionality
|
||||||
|
* WebDav can be accessed at `http://<ip>:<port>/webdav`
|
||||||
|
* This WebDav does only permit writing files **once** (reading files or creating directories is not allowed)
|
||||||
* Password hashing using BCrypt
|
* Password hashing using BCrypt
|
||||||
* 2FA using TOTP
|
* 2FA using TOTP
|
||||||
* Content Security Policy
|
* Content Security Policy
|
||||||
|
|
|
||||||
2
go.mod
2
go.mod
|
|
@ -3,6 +3,7 @@ module git.giftfish.de/ston1th/docstore
|
||||||
go 1.12
|
go 1.12
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
git.giftfish.de/ston1th/authdav v1.0.0
|
||||||
git.giftfish.de/ston1th/godrop/v2 v2.1.0
|
git.giftfish.de/ston1th/godrop/v2 v2.1.0
|
||||||
git.giftfish.de/ston1th/jwt/v3 v3.2.0
|
git.giftfish.de/ston1th/jwt/v3 v3.2.0
|
||||||
github.com/RoaringBitmap/roaring v0.4.17 // indirect
|
github.com/RoaringBitmap/roaring v0.4.17 // indirect
|
||||||
|
|
@ -32,4 +33,5 @@ require (
|
||||||
github.com/urfave/cli v1.20.0
|
github.com/urfave/cli v1.20.0
|
||||||
go.etcd.io/bbolt v1.3.3 // indirect
|
go.etcd.io/bbolt v1.3.3 // indirect
|
||||||
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734
|
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734
|
||||||
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3
|
||||||
)
|
)
|
||||||
|
|
|
||||||
2
go.sum
2
go.sum
|
|
@ -1,3 +1,5 @@
|
||||||
|
git.giftfish.de/ston1th/authdav v1.0.0 h1:lbDLK/nW5K0kNzry9rYVp0leNCbZ0trAWcH55668OPg=
|
||||||
|
git.giftfish.de/ston1th/authdav v1.0.0/go.mod h1:LKpYWom0EiBKDHHqVTDvagBLxT1J7L8Nz+JRybHEDmw=
|
||||||
git.giftfish.de/ston1th/godrop/v2 v2.1.0 h1:vR4aWVeMGJ+tHQH0p44esZrSl5dYJzuCmZqhKWP/vwI=
|
git.giftfish.de/ston1th/godrop/v2 v2.1.0 h1:vR4aWVeMGJ+tHQH0p44esZrSl5dYJzuCmZqhKWP/vwI=
|
||||||
git.giftfish.de/ston1th/godrop/v2 v2.1.0/go.mod h1:z8KA3HP/vB04wddLXZfYVKURYDxBGau9hlHtV61x9mM=
|
git.giftfish.de/ston1th/godrop/v2 v2.1.0/go.mod h1:z8KA3HP/vB04wddLXZfYVKURYDxBGau9hlHtV61x9mM=
|
||||||
git.giftfish.de/ston1th/jwt/v3 v3.2.0 h1:V6Lh7OjXn4D3HPd/LoDf7w5N7cyiSXEPAQCIfSVZ05c=
|
git.giftfish.de/ston1th/jwt/v3 v3.2.0 h1:V6Lh7OjXn4D3HPd/LoDf7w5N7cyiSXEPAQCIfSVZ05c=
|
||||||
|
|
|
||||||
|
|
@ -312,6 +312,11 @@ func serverFlags() []cli.Flag {
|
||||||
Usage: "enable debugging",
|
Usage: "enable debugging",
|
||||||
Destination: &config.Debug,
|
Destination: &config.Debug,
|
||||||
},
|
},
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "webdav",
|
||||||
|
Usage: "enable webdav file uploader",
|
||||||
|
Destination: &config.WebDav,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ const (
|
||||||
MovePrefix = "/move"
|
MovePrefix = "/move"
|
||||||
TagsPrefix = "/tags"
|
TagsPrefix = "/tags"
|
||||||
DeletePrefix = "/delete"
|
DeletePrefix = "/delete"
|
||||||
|
WebDavPrefix = "/webdav"
|
||||||
|
|
||||||
Favicon = "/favicon.ico"
|
Favicon = "/favicon.ico"
|
||||||
BootstrapCSS = "/bootstrap.css"
|
BootstrapCSS = "/bootstrap.css"
|
||||||
|
|
|
||||||
|
|
@ -80,4 +80,5 @@ type Config struct {
|
||||||
Foreground bool `json:"foreground,omitempty"`
|
Foreground bool `json:"foreground,omitempty"`
|
||||||
SecureCookie bool `json:"secure_cookie,omitempty"`
|
SecureCookie bool `json:"secure_cookie,omitempty"`
|
||||||
Debug bool `json:"debug,omitempty"`
|
Debug bool `json:"debug,omitempty"`
|
||||||
|
WebDav bool `json:"webdav,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,14 @@ func (db *DB) CreateUser(username, password string) error {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (db *DB) BasicAuth(username, password string) bool {
|
||||||
|
_, err := db.Login(username, password)
|
||||||
|
if err == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func (db *DB) Login(username, password string) (u core.User, err error) {
|
func (db *DB) Login(username, password string) (u core.User, err error) {
|
||||||
u, err = db.GetUser()
|
u, err = db.GetUser()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ var reserved = []string{
|
||||||
core.NewPrefix,
|
core.NewPrefix,
|
||||||
core.MovePrefix,
|
core.MovePrefix,
|
||||||
core.DeletePrefix,
|
core.DeletePrefix,
|
||||||
|
core.WebDavPrefix,
|
||||||
core.Favicon,
|
core.Favicon,
|
||||||
core.BootstrapCSS,
|
core.BootstrapCSS,
|
||||||
core.CustomCSS,
|
core.CustomCSS,
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"git.giftfish.de/ston1th/authdav"
|
||||||
"git.giftfish.de/ston1th/docstore/pkg/core"
|
"git.giftfish.de/ston1th/docstore/pkg/core"
|
||||||
"git.giftfish.de/ston1th/docstore/pkg/db"
|
"git.giftfish.de/ston1th/docstore/pkg/db"
|
||||||
"git.giftfish.de/ston1th/docstore/pkg/fs"
|
"git.giftfish.de/ston1th/docstore/pkg/fs"
|
||||||
|
|
@ -14,6 +15,7 @@ import (
|
||||||
"git.giftfish.de/ston1th/godrop/v2"
|
"git.giftfish.de/ston1th/godrop/v2"
|
||||||
"git.giftfish.de/ston1th/jwt/v3"
|
"git.giftfish.de/ston1th/jwt/v3"
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
|
"golang.org/x/net/webdav"
|
||||||
"html/template"
|
"html/template"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
@ -48,7 +50,6 @@ func NewHTTPServer(cfg core.Config, l net.Listener, s *scan.Scanner) (srv *HTTPS
|
||||||
Scanner: s,
|
Scanner: s,
|
||||||
Log: log.NewScanLog(0),
|
Log: log.NewScanLog(0),
|
||||||
}
|
}
|
||||||
srv.handler = srv.buildRoutes()
|
|
||||||
srv.loadTemplates()
|
srv.loadTemplates()
|
||||||
srv.srv = &http.Server{}
|
srv.srv = &http.Server{}
|
||||||
return
|
return
|
||||||
|
|
@ -75,6 +76,7 @@ func (s *HTTPServer) Start() (err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.New("server: " + err.Error())
|
return errors.New("server: " + err.Error())
|
||||||
}
|
}
|
||||||
|
s.handler = s.buildRoutes()
|
||||||
if !s.DB.UserExists() {
|
if !s.DB.UserExists() {
|
||||||
log.Debug("server: starting register handler")
|
log.Debug("server: starting register handler")
|
||||||
s.srv.Handler = s.register()
|
s.srv.Handler = s.register()
|
||||||
|
|
@ -107,6 +109,11 @@ func (s *HTTPServer) register() http.Handler {
|
||||||
func (s *HTTPServer) buildRoutes() http.Handler {
|
func (s *HTTPServer) buildRoutes() http.Handler {
|
||||||
r := mux.NewRouter()
|
r := mux.NewRouter()
|
||||||
r.NotFoundHandler = ¬FoundHandler{s}
|
r.NotFoundHandler = ¬FoundHandler{s}
|
||||||
|
if s.Config.WebDav {
|
||||||
|
fs := authdav.NewWriteOnlyOnceFileSystem(webdav.Dir(s.Config.DataDir))
|
||||||
|
h := authdav.NewWebdavBasicAuth(core.WebDavPrefix, fs, nil, webdavLogger, s.DB, "DocStore WebDav")
|
||||||
|
r.PathPrefix(core.WebDavPrefix).Handler(h)
|
||||||
|
}
|
||||||
for _, v := range routes {
|
for _, v := range routes {
|
||||||
r.HandleFunc(v.Path, s.contextWrapper(v.Handler)).Methods(v.Methods...)
|
r.HandleFunc(v.Path, s.contextWrapper(v.Handler)).Methods(v.Methods...)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
14
pkg/server/webdav.go
Normal file
14
pkg/server/webdav.go
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.giftfish.de/ston1th/docstore/pkg/log"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
func webdavLogger(r *http.Request, err error) {
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("webdav: %s %s %s error: %s\n", r.RemoteAddr, r.Method, r.URL, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Printf("webdav: %s %s %s\n", r.RemoteAddr, r.Method, r.URL)
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue