diff --git a/cmd/webdav/config.go b/cmd/webdav/config.go deleted file mode 100644 index e35343a..0000000 --- a/cmd/webdav/config.go +++ /dev/null @@ -1,175 +0,0 @@ -package main - -import ( - "encoding/json" - "io/ioutil" - "log" - "os" - "path/filepath" - "regexp" - - "github.com/hacdias/webdav" - wd "golang.org/x/net/webdav" - yaml "gopkg.in/yaml.v2" -) - -func parseRules(raw []map[string]interface{}) []*webdav.Rule { - rules := []*webdav.Rule{} - - for _, r := range raw { - rule := &webdav.Rule{ - Regex: false, - Allow: false, - Path: "", - } - - if regex, ok := r["regex"].(bool); ok { - rule.Regex = regex - } - - if allow, ok := r["allow"].(bool); ok { - rule.Allow = allow - } - - path, ok := r["rule"].(string) - if !ok { - continue - } - - if rule.Regex { - rule.Regexp = regexp.MustCompile(path) - } else { - rule.Path = path - } - - rules = append(rules, rule) - } - - return rules -} - -func parseUsers(raw []map[string]interface{}, c *cfg) { - for _, r := range raw { - username, ok := r["username"].(string) - if !ok { - log.Fatal("user needs an username") - } - - password, ok := r["password"].(string) - if !ok { - log.Fatal("user needs a password") - } - - c.auth[username] = password - - user := &webdav.User{ - Scope: c.webdav.User.Scope, - Modify: c.webdav.User.Modify, - Rules: c.webdav.User.Rules, - } - - if scope, ok := r["scope"].(string); ok { - user.Scope = scope - } - - if modify, ok := r["modify"].(bool); ok { - user.Modify = modify - } - - if rules, ok := r["rules"].([]map[string]interface{}); ok { - user.Rules = parseRules(rules) - } - - user.Handler = &wd.Handler{ - FileSystem: wd.Dir(user.Scope), - LockSystem: wd.NewMemLS(), - } - - c.webdav.Users[username] = user - } -} - -func getConfig() []byte { - if config == "" { - for _, v := range defaultConfigs { - _, err := os.Stat(v) - if err == nil { - config = v - break - } - } - } - - if config == "" { - log.Fatal("no config file specified; couldn't find any config.{yaml,json}") - } - - file, err := ioutil.ReadFile(config) - if err != nil { - log.Fatal(err) - } - - return file -} - -type cfg struct { - webdav *webdav.Config - port string - auth map[string]string -} - -func parseConfig() *cfg { - file := getConfig() - - data := struct { - Port string `json:"port" yaml:"port"` - Scope string `json:"scope" yaml:"scope"` - Modify bool `json:"modify" yaml:"modify"` - Rules []map[string]interface{} `json:"rules" yaml:"rules"` - Users []map[string]interface{} `json:"users" yaml:"users"` - }{ - Port: "0", - Scope: "./", - Modify: true, - } - - var err error - if filepath.Ext(config) == ".json" { - err = json.Unmarshal(file, &data) - } else { - err = yaml.Unmarshal(file, &data) - } - - if err != nil { - log.Fatal(err) - } - - config := &cfg{ - port: data.Port, - auth: map[string]string{}, - webdav: &webdav.Config{ - BaseURL: "", - User: &webdav.User{ - Scope: data.Scope, - Modify: data.Modify, - Rules: []*webdav.Rule{}, - Handler: &wd.Handler{ - FileSystem: wd.Dir(data.Scope), - LockSystem: wd.NewMemLS(), - }, - }, - Users: map[string]*webdav.User{}, - }, - } - - if len(data.Users) == 0 { - log.Fatal("no user defined") - } - - if len(data.Rules) != 0 { - config.webdav.User.Rules = parseRules(data.Rules) - } - - parseUsers(data.Users, config) - return config -} diff --git a/cmd/webdav/main.go b/cmd/webdav/main.go index 3f739da..38e3b38 100644 --- a/cmd/webdav/main.go +++ b/cmd/webdav/main.go @@ -1,11 +1,20 @@ package main import ( + "encoding/json" "flag" "fmt" + "io/ioutil" "log" "net" "net/http" + "os" + "path/filepath" + "regexp" + + "github.com/hacdias/webdav" + wd "golang.org/x/net/webdav" + yaml "gopkg.in/yaml.v2" ) var ( @@ -17,6 +26,167 @@ func init() { flag.StringVar(&config, "config", "", "Configuration file") } +func parseRules(raw []map[string]interface{}) []*webdav.Rule { + rules := []*webdav.Rule{} + + for _, r := range raw { + rule := &webdav.Rule{ + Regex: false, + Allow: false, + Path: "", + } + + if regex, ok := r["regex"].(bool); ok { + rule.Regex = regex + } + + if allow, ok := r["allow"].(bool); ok { + rule.Allow = allow + } + + path, ok := r["rule"].(string) + if !ok { + continue + } + + if rule.Regex { + rule.Regexp = regexp.MustCompile(path) + } else { + rule.Path = path + } + + rules = append(rules, rule) + } + + return rules +} + +func parseUsers(raw []map[string]interface{}, c *cfg) { + for _, r := range raw { + username, ok := r["username"].(string) + if !ok { + log.Fatal("user needs an username") + } + + password, ok := r["password"].(string) + if !ok { + log.Fatal("user needs a password") + } + + c.auth[username] = password + + user := &webdav.User{ + Scope: c.webdav.User.Scope, + Modify: c.webdav.User.Modify, + Rules: c.webdav.User.Rules, + } + + if scope, ok := r["scope"].(string); ok { + user.Scope = scope + } + + if modify, ok := r["modify"].(bool); ok { + user.Modify = modify + } + + if rules, ok := r["rules"].([]map[string]interface{}); ok { + user.Rules = parseRules(rules) + } + + user.Handler = &wd.Handler{ + FileSystem: wd.Dir(user.Scope), + LockSystem: wd.NewMemLS(), + } + + c.webdav.Users[username] = user + } +} + +func getConfig() []byte { + if config == "" { + for _, v := range defaultConfigs { + _, err := os.Stat(v) + if err == nil { + config = v + break + } + } + } + + if config == "" { + log.Fatal("no config file specified; couldn't find any config.{yaml,json}") + } + + file, err := ioutil.ReadFile(config) + if err != nil { + log.Fatal(err) + } + + return file +} + +type cfg struct { + webdav *webdav.Config + port string + auth map[string]string +} + +func parseConfig() *cfg { + file := getConfig() + + data := struct { + Port string `json:"port" yaml:"port"` + Scope string `json:"scope" yaml:"scope"` + Modify bool `json:"modify" yaml:"modify"` + Rules []map[string]interface{} `json:"rules" yaml:"rules"` + Users []map[string]interface{} `json:"users" yaml:"users"` + }{ + Port: "0", + Scope: "./", + Modify: true, + } + + var err error + if filepath.Ext(config) == ".json" { + err = json.Unmarshal(file, &data) + } else { + err = yaml.Unmarshal(file, &data) + } + + if err != nil { + log.Fatal(err) + } + + config := &cfg{ + port: data.Port, + auth: map[string]string{}, + webdav: &webdav.Config{ + BaseURL: "", + User: &webdav.User{ + Scope: data.Scope, + Modify: data.Modify, + Rules: []*webdav.Rule{}, + Handler: &wd.Handler{ + FileSystem: wd.Dir(data.Scope), + LockSystem: wd.NewMemLS(), + }, + }, + Users: map[string]*webdav.User{}, + }, + } + + if len(data.Users) == 0 { + log.Fatal("no user defined") + } + + if len(data.Rules) != 0 { + config.webdav.User.Rules = parseRules(data.Rules) + } + + parseUsers(data.Users, config) + return config +} + func basicAuth(c *cfg) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`) diff --git a/readme.md b/readme.md index 09cd565..3019559 100644 --- a/readme.md +++ b/readme.md @@ -20,4 +20,6 @@ users: - path: /some/file ``` -You can specify the path to the configuration file using the `--config` flag. By default, it will search for a `config.{yaml,json}` file on your current working directory. \ No newline at end of file +You can specify the path to the configuration file using the `--config` flag. By default, it will search for a `config.{yaml,json}` file on your current working directory. + +Download it [here](https://github.com/hacdias/webdav/releases). \ No newline at end of file