filebrowser/config/config.go

257 lines
5.8 KiB
Go
Raw Normal View History

2016-06-25 20:57:10 +00:00
package config
import (
"fmt"
"io/ioutil"
"net/http"
2016-08-20 20:48:04 +00:00
"regexp"
2016-08-20 19:34:08 +00:00
"strconv"
2016-06-25 20:57:10 +00:00
"strings"
2016-10-17 20:05:52 +00:00
"golang.org/x/net/webdav"
2016-06-25 20:57:10 +00:00
"github.com/mholt/caddy"
"github.com/mholt/caddy/caddyhttp/httpserver"
2016-06-25 20:57:10 +00:00
)
// Config is a configuration for browsing in a particualr path.
type Config struct {
2016-08-22 10:37:56 +00:00
*User
2016-10-17 20:05:52 +00:00
BaseURL string
AbsoluteURL string
AddrPath string
Token string // Anti CSRF token
HugoEnabled bool // Enables the Hugo plugin for File Manager
Users map[string]*User
WebDav bool
WebDavURL string
WebDavHandler *webdav.Handler
CurrentUser *User
2016-08-20 20:48:04 +00:00
}
2016-08-20 19:34:08 +00:00
2016-08-21 17:44:22 +00:00
// Rule is a dissalow/allow rule
type Rule struct {
Regex bool
Allow bool
Path string
2016-08-22 10:37:56 +00:00
Regexp *regexp.Regexp
2016-06-25 20:57:10 +00:00
}
// Parse parses the configuration set by the user so it can
// be used by the middleware
func Parse(c *caddy.Controller) ([]Config, error) {
var (
configs []Config
err error
user *User
)
2016-06-25 20:57:10 +00:00
appendConfig := func(cfg Config) error {
for _, c := range configs {
if c.PathScope == cfg.PathScope {
return fmt.Errorf("duplicate file managing config for %s", c.PathScope)
}
}
configs = append(configs, cfg)
return nil
}
for c.Next() {
// Initialize the configuration with the default settings
cfg := Config{User: &User{}}
2016-08-21 19:25:40 +00:00
cfg.PathScope = "."
cfg.Root = http.Dir(cfg.PathScope)
2016-08-21 18:44:09 +00:00
cfg.BaseURL = ""
2016-08-20 20:48:04 +00:00
cfg.FrontMatter = "yaml"
cfg.HugoEnabled = false
2016-08-22 10:37:56 +00:00
cfg.Users = map[string]*User{}
2016-08-21 18:07:33 +00:00
cfg.AllowCommands = true
cfg.AllowEdit = true
cfg.AllowNew = true
cfg.Commands = []string{"git", "svn", "hg"}
2016-08-22 10:37:56 +00:00
cfg.Rules = []*Rule{&Rule{
Regex: true,
Allow: false,
Regexp: regexp.MustCompile("\\/\\..+"),
}}
2016-08-20 21:15:29 +00:00
2016-08-22 11:24:26 +00:00
// Get the baseURL
args := c.RemainingArgs()
if len(args) > 0 {
cfg.BaseURL = args[0]
}
2016-10-17 20:05:52 +00:00
cfg.BaseURL = strings.TrimPrefix(cfg.BaseURL, "/")
cfg.BaseURL = strings.TrimSuffix(cfg.BaseURL, "/")
cfg.BaseURL = "/" + cfg.BaseURL
if cfg.BaseURL == "/" {
cfg.BaseURL = ""
}
// Set the first user, the global user
user = cfg.User
2016-08-20 20:48:04 +00:00
2016-06-25 20:57:10 +00:00
for c.NextBlock() {
switch c.Val() {
2016-06-29 09:43:13 +00:00
case "frontmatter":
if !c.NextArg() {
return configs, c.ArgErr()
}
user.FrontMatter = c.Val()
if user.FrontMatter != "yaml" && user.FrontMatter != "json" && user.FrontMatter != "toml" {
2016-06-29 09:43:13 +00:00
return configs, c.Err("frontmatter type not supported")
}
2016-10-17 20:05:52 +00:00
case "webdav":
cfg.WebDav = true
prefix := "webdav"
if c.NextArg() {
prefix = c.Val()
}
prefix = strings.TrimPrefix(prefix, "/")
prefix = strings.TrimSuffix(prefix, "/")
prefix = cfg.BaseURL + "/" + prefix
cfg.WebDavURL = prefix
cfg.WebDavHandler = &webdav.Handler{
Prefix: prefix,
FileSystem: webdav.Dir(cfg.PathScope),
LockSystem: webdav.NewMemLS(),
}
// TODO
2016-08-20 21:15:29 +00:00
case "show":
2016-06-25 20:57:10 +00:00
if !c.NextArg() {
return configs, c.ArgErr()
}
user.PathScope = c.Val()
user.PathScope = strings.TrimSuffix(user.PathScope, "/")
user.Root = http.Dir(user.PathScope)
2016-06-25 20:57:10 +00:00
case "styles":
if !c.NextArg() {
return configs, c.ArgErr()
}
2016-08-20 19:34:08 +00:00
var tplBytes []byte
tplBytes, err = ioutil.ReadFile(c.Val())
2016-06-25 20:57:10 +00:00
if err != nil {
return configs, err
}
user.StyleSheet = string(tplBytes)
2016-08-20 19:34:08 +00:00
case "allow_new":
if !c.NextArg() {
return configs, c.ArgErr()
}
user.AllowNew, err = strconv.ParseBool(c.Val())
2016-08-20 19:34:08 +00:00
if err != nil {
return configs, err
}
case "allow_edit":
if !c.NextArg() {
return configs, c.ArgErr()
}
user.AllowEdit, err = strconv.ParseBool(c.Val())
2016-08-20 19:34:08 +00:00
if err != nil {
return configs, err
}
2016-08-21 18:07:33 +00:00
case "allow_commands":
2016-08-20 19:34:08 +00:00
if !c.NextArg() {
return configs, c.ArgErr()
}
user.AllowCommands, err = strconv.ParseBool(c.Val())
2016-08-20 19:34:08 +00:00
if err != nil {
return configs, err
}
2016-08-21 18:07:33 +00:00
case "allow_command":
if !c.NextArg() {
return configs, c.ArgErr()
}
user.Commands = append(user.Commands, c.Val())
2016-08-21 18:07:33 +00:00
case "block_command":
if !c.NextArg() {
return configs, c.ArgErr()
}
index := 0
for i, val := range user.Commands {
2016-08-21 18:07:33 +00:00
if val == c.Val() {
index = i
}
}
user.Commands = append(user.Commands[:index], user.Commands[index+1:]...)
case "allow", "allow_r", "block", "block_r":
ruleType := c.Val()
2016-08-21 18:07:33 +00:00
if !c.NextArg() {
return configs, c.ArgErr()
}
if c.Val() == "dotfiles" && !strings.HasSuffix(ruleType, "_r") {
ruleType += "_r"
2016-08-21 18:07:33 +00:00
}
rule := &Rule{
Allow: ruleType == "allow" || ruleType == "allow_r",
Regex: ruleType == "allow_r" || ruleType == "block_r",
2016-08-21 18:07:33 +00:00
}
if rule.Regex && c.Val() == "dotfiles" {
rule.Regexp = regexp.MustCompile("\\/\\..+")
} else if rule.Regex {
rule.Regexp = regexp.MustCompile(c.Val())
} else {
rule.Path = c.Val()
2016-08-21 18:07:33 +00:00
}
user.Rules = append(user.Rules, rule)
2016-08-20 21:15:29 +00:00
// NEW USER BLOCK?
default:
val := c.Val()
2016-08-20 21:15:29 +00:00
// Checks if it's a new user
if !strings.HasSuffix(val, ":") {
fmt.Println("Unknown option " + val)
}
// Get the username, sets the current user, and initializes it
val = strings.TrimSuffix(val, ":")
2016-08-22 10:37:56 +00:00
cfg.Users[val] = &User{}
2016-08-21 18:07:33 +00:00
// Initialize the new user
user = cfg.Users[val]
user.AllowCommands = cfg.AllowCommands
user.AllowEdit = cfg.AllowEdit
user.AllowNew = cfg.AllowEdit
user.Commands = cfg.Commands
user.FrontMatter = cfg.FrontMatter
user.PathScope = cfg.PathScope
user.Root = cfg.Root
user.Rules = cfg.Rules
user.StyleSheet = cfg.StyleSheet
2016-06-25 20:57:10 +00:00
}
}
caddyConf := httpserver.GetConfig(c)
2016-07-03 18:45:46 +00:00
cfg.AbsoluteURL = strings.TrimSuffix(caddyConf.Addr.Path, "/") + "/" + cfg.BaseURL
cfg.AbsoluteURL = strings.Replace(cfg.AbsoluteURL, "//", "/", -1)
2016-07-03 18:45:46 +00:00
cfg.AbsoluteURL = strings.TrimSuffix(cfg.AbsoluteURL, "/")
2016-07-01 14:51:02 +00:00
cfg.AddrPath = strings.TrimSuffix(caddyConf.Addr.Path, "/")
2016-06-25 20:57:10 +00:00
if err := appendConfig(cfg); err != nil {
return configs, err
}
}
return configs, nil
}