mirror of
https://github.com/hacdias/webdav.git
synced 2026-09-22 11:20:42 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
764a69cd33 | ||
|
|
d266f1150e | ||
|
|
76ebaffaef | ||
|
|
60f2697615 | ||
|
|
e5b3946388 |
@@ -26,6 +26,11 @@ scope: .
|
||||
modify: true
|
||||
rules: []
|
||||
|
||||
# CORS configuration
|
||||
cors:
|
||||
- enabled: false
|
||||
allowed_hosts: []
|
||||
|
||||
users:
|
||||
- username: admin
|
||||
password: admin
|
||||
|
||||
+1
-1
@@ -9,4 +9,4 @@ func Execute() {
|
||||
if err := rootCmd.Execute(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+41
-1
@@ -5,6 +5,7 @@ import (
|
||||
"log"
|
||||
"os"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/hacdias/webdav/webdav"
|
||||
@@ -81,6 +82,10 @@ func parseUsers(raw []interface{}, c *webdav.Config) {
|
||||
password, ok := u["password"].(string)
|
||||
if !ok {
|
||||
password = ""
|
||||
|
||||
if numPwd, ok := u["password"].(int); ok {
|
||||
password = strconv.Itoa(numPwd)
|
||||
}
|
||||
}
|
||||
|
||||
if strings.HasPrefix(password, "{env}") {
|
||||
@@ -118,6 +123,32 @@ func parseUsers(raw []interface{}, c *webdav.Config) {
|
||||
}
|
||||
}
|
||||
|
||||
func parseCors(raw []interface{}, c *webdav.Config) {
|
||||
hosts := []string{}
|
||||
|
||||
for _, v := range raw {
|
||||
|
||||
if cfg, ok := v.(map[interface{}]interface{}); ok {
|
||||
|
||||
cors := webdav.CorsCfg{
|
||||
Enabled: cfg["enabled"].(bool),
|
||||
AllowedHosts: []string{},
|
||||
}
|
||||
|
||||
if allowedHosts, ok := cfg["allowed_hosts"]; ok {
|
||||
hosts = append(hosts, strings.Split(allowedHosts.(string), ",")...)
|
||||
}
|
||||
|
||||
if len(hosts) == 0 {
|
||||
hosts = append(hosts, "*")
|
||||
}
|
||||
|
||||
cors.AllowedHosts = hosts
|
||||
c.Cors = cors
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func readConfig(flags *pflag.FlagSet) *webdav.Config {
|
||||
cfg := &webdav.Config{
|
||||
User: &webdav.User{
|
||||
@@ -129,7 +160,11 @@ func readConfig(flags *pflag.FlagSet) *webdav.Config {
|
||||
LockSystem: wd.NewMemLS(),
|
||||
},
|
||||
},
|
||||
Auth: getOptB(flags, "auth"),
|
||||
Auth: getOptB(flags, "auth"),
|
||||
Cors: webdav.CorsCfg{
|
||||
Enabled: false,
|
||||
AllowedHosts: []string{},
|
||||
},
|
||||
Users: map[string]*webdav.User{},
|
||||
}
|
||||
|
||||
@@ -143,6 +178,11 @@ func readConfig(flags *pflag.FlagSet) *webdav.Config {
|
||||
parseUsers(users, cfg)
|
||||
}
|
||||
|
||||
rawCors := v.Get("cors")
|
||||
if cors, ok := rawCors.([]interface{}); ok {
|
||||
parseCors(cors, cfg)
|
||||
}
|
||||
|
||||
if len(cfg.Users) != 0 && !cfg.Auth {
|
||||
log.Print("Users will be ignored due to auth=false")
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ func init() {
|
||||
flags := rootCmd.Flags()
|
||||
flags.StringVarP(&cfgFile, "config", "c", "", "config file path")
|
||||
flags.BoolP("tls", "t", false, "enable tls")
|
||||
flags.Bool("auth", true, "enable auth")
|
||||
flags.String("cert", "cert.pem", "TLS certificate")
|
||||
flags.String("key", "key.pem", "TLS key")
|
||||
flags.StringP("address", "a", "0.0.0.0", "address to listen to")
|
||||
|
||||
Regular → Executable
Regular → Executable
+9
@@ -14,3 +14,12 @@ func checkPassword(saved, input string) bool {
|
||||
|
||||
return saved == input
|
||||
}
|
||||
|
||||
func isAllowedHost(allowedHosts []string, origin string) bool {
|
||||
for _, host := range allowedHosts {
|
||||
if host == origin {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
Regular → Executable
+28
@@ -6,16 +6,44 @@ import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// CorsCfg is the CORS config.
|
||||
type CorsCfg struct {
|
||||
Enabled bool
|
||||
AllowedHosts []string
|
||||
}
|
||||
|
||||
// Config is the configuration of a WebDAV instance.
|
||||
type Config struct {
|
||||
*User
|
||||
Auth bool
|
||||
Cors CorsCfg
|
||||
Users map[string]*User
|
||||
}
|
||||
|
||||
// ServeHTTP determines if the request is for this plugin, and if all prerequisites are met.
|
||||
func (c *Config) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
u := c.User
|
||||
requestOrigin := r.Header.Get("Origin")
|
||||
|
||||
// add cors headers before any operation so even on 401 unauthorized cors will working only when Origin header is present so request came from browser
|
||||
if c.Cors.Enabled && requestOrigin != "" {
|
||||
|
||||
headers := w.Header()
|
||||
|
||||
if len(c.Cors.AllowedHosts) == 1 && c.Cors.AllowedHosts[0] == "*" {
|
||||
headers.Set("Access-Control-Allow-Methods", "*")
|
||||
headers.Set("Access-Control-Allow-Headers", "*")
|
||||
headers.Set("Access-Control-Allow-Origin", "*")
|
||||
} else if isAllowedHost(c.Cors.AllowedHosts, requestOrigin) {
|
||||
headers.Set("Access-Control-Allow-Origin", requestOrigin)
|
||||
headers.Set("Access-Control-Allow-Headers", "*")
|
||||
headers.Set("Access-Control-Allow-Methods", "*")
|
||||
}
|
||||
}
|
||||
|
||||
if r.Method == "OPTIONS" && c.Cors.Enabled && requestOrigin != "" {
|
||||
return
|
||||
}
|
||||
|
||||
if c.Auth {
|
||||
w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`)
|
||||
|
||||
Reference in New Issue
Block a user