From 4071a58107b34e7097deac3d452f84fe88404a0f Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Mon, 14 Aug 2017 18:35:25 +0100 Subject: [PATCH] close #203 Former-commit-id: e2d0b723963d3a82ac0f9042280885e800b1132a [formerly e1ae3f4da43f0481a57c39f11735c36b33fda857] [formerly 02ab5f5fb5f4b812cf413ebc923b853d4f0b4afb [formerly 83bc5550942b7f11e65bc2283b3a54e201da60d7]] Former-commit-id: bee2ec30c9aa9619a69eaa6320822f8525a41535 [formerly 1af59077494b5e8674af547d0361f50a2ecf8f26] Former-commit-id: 573870f4a6bffcee3e48fbc0b8349402eaeba407 --- caddy/filemanager/filemanager.go | 126 +---------------- caddy/hugo/hugo.go | 186 ++++--------------------- caddy/jekyll/jekyll.go | 186 ++++--------------------- caddy/parser/parser.go | 232 +++++++++++++++++++++++++++++++ 4 files changed, 297 insertions(+), 433 deletions(-) create mode 100644 caddy/parser/parser.go diff --git a/caddy/filemanager/filemanager.go b/caddy/filemanager/filemanager.go index 791681cb..98ae6812 100644 --- a/caddy/filemanager/filemanager.go +++ b/caddy/filemanager/filemanager.go @@ -4,17 +4,10 @@ package filemanager import ( - "crypto/md5" - "encoding/hex" - "fmt" "net/http" - "os" - "path/filepath" - "strconv" - "strings" - . "github.com/hacdias/filemanager" - "github.com/hacdias/fileutils" + "github.com/hacdias/filemanager" + "github.com/hacdias/filemanager/caddy/parser" "github.com/mholt/caddy" "github.com/mholt/caddy/caddyhttp/httpserver" ) @@ -28,19 +21,14 @@ func init() { type plugin struct { Next httpserver.Handler - Configs []*config -} - -type config struct { - *FileManager - baseURL string + Configs []*filemanager.FileManager } // ServeHTTP determines if the request is for this plugin, and if all prerequisites are met. func (f plugin) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) { for i := range f.Configs { // Checks if this Path should be handled by File Manager. - if !httpserver.Path(r.URL.Path).Matches(f.Configs[i].baseURL) { + if !httpserver.Path(r.URL.Path).Matches(f.Configs[i].BaseURL) { continue } @@ -53,7 +41,7 @@ func (f plugin) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) { // setup configures a new FileManager middleware instance. func setup(c *caddy.Controller) error { - configs, err := parse(c) + configs, err := parser.Parse(c, "") if err != nil { return err } @@ -64,107 +52,3 @@ func setup(c *caddy.Controller) error { return nil } - -func parse(c *caddy.Controller) ([]*config, error) { - var ( - configs []*config - ) - - for c.Next() { - baseURL := "/" - baseScope := "." - database := "" - noAuth := false - - // Get the baseURL and baseScope - args := c.RemainingArgs() - - if len(args) >= 1 { - baseURL = args[0] - } - - if len(args) > 1 { - baseScope = args[1] - } - - for c.NextBlock() { - switch c.Val() { - case "database": - if !c.NextArg() { - return nil, c.ArgErr() - } - - database = c.Val() - case "no_auth": - if !c.NextArg() { - noAuth = true - continue - } - - var err error - noAuth, err = strconv.ParseBool(c.Val()) - if err != nil { - return nil, err - } - } - } - - caddyConf := httpserver.GetConfig(c) - - path := filepath.Join(caddy.AssetsPath(), "filemanager") - err := os.MkdirAll(path, 0700) - if err != nil { - return nil, err - } - - // if there is a database path and it is not absolute, - // it will be relative to Caddy folder. - if !filepath.IsAbs(database) && database != "" { - database = filepath.Join(path, database) - } - - // If there is no database path on the settings, - // store one in .caddy/filemanager/name.db. - if database == "" { - // The name of the database is the hashed value of a string composed - // by the host, address path and the baseurl of this File Manager - // instance. - hasher := md5.New() - hasher.Write([]byte(caddyConf.Addr.Host + caddyConf.Addr.Path + baseURL)) - sha := hex.EncodeToString(hasher.Sum(nil)) - database = filepath.Join(path, sha+".db") - - fmt.Println("[WARNING] A database is going to be created for your File Manager instace at " + database + - ". It is highly recommended that you set the 'database' option to '" + sha + ".db'\n") - } - - fm, err := New(database, User{ - Locale: "en", - AllowCommands: true, - AllowEdit: true, - AllowNew: true, - Commands: []string{"git", "svn", "hg"}, - Rules: []*Rule{{ - Regex: true, - Allow: false, - Regexp: &Regexp{Raw: "\\/\\..+"}, - }}, - CSS: "", - FileSystem: fileutils.Dir(baseScope), - }) - - if err != nil { - return nil, err - } - - fm.NoAuth = noAuth - m := &config{FileManager: fm} - m.SetBaseURL(baseURL) - m.SetPrefixURL(strings.TrimSuffix(caddyConf.Addr.Path, "/")) - m.baseURL = strings.TrimSuffix(baseURL, "/") - - configs = append(configs, m) - } - - return configs, nil -} diff --git a/caddy/hugo/hugo.go b/caddy/hugo/hugo.go index 3453861a..f1a6cdbf 100644 --- a/caddy/hugo/hugo.go +++ b/caddy/hugo/hugo.go @@ -1,169 +1,14 @@ package hugo import ( - "crypto/md5" - "encoding/hex" - "fmt" "net/http" - "os" - "path/filepath" - "strconv" - "strings" "github.com/hacdias/filemanager" - "github.com/hacdias/fileutils" + "github.com/hacdias/filemanager/caddy/parser" "github.com/mholt/caddy" "github.com/mholt/caddy/caddyhttp/httpserver" ) -// setup configures a new FileManager middleware instance. -func setup(c *caddy.Controller) error { - configs, err := parse(c) - if err != nil { - return err - } - - httpserver.GetConfig(c).AddMiddleware(func(next httpserver.Handler) httpserver.Handler { - return plugin{Configs: configs, Next: next} - }) - - return nil -} - -func parse(c *caddy.Controller) ([]*filemanager.FileManager, error) { - var ( - configs []*filemanager.FileManager - ) - - for c.Next() { - // hugo [directory] [admin] { - // database path - // } - directory := "." - admin := "/admin" - database := "" - noAuth := false - - // Get the baseURL and baseScope - args := c.RemainingArgs() - - if len(args) >= 1 { - directory = args[0] - } - - if len(args) > 1 { - admin = args[1] - } - - for c.NextBlock() { - switch c.Val() { - case "database": - if !c.NextArg() { - return nil, c.ArgErr() - } - - database = c.Val() - case "no_auth": - if !c.NextArg() { - noAuth = true - continue - } - - var err error - noAuth, err = strconv.ParseBool(c.Val()) - if err != nil { - return nil, err - } - } - } - - caddyConf := httpserver.GetConfig(c) - - path := filepath.Join(caddy.AssetsPath(), "hugo") - err := os.MkdirAll(path, 0700) - if err != nil { - return nil, err - } - - // if there is a database path and it is not absolute, - // it will be relative to ".caddy" folder. - if !filepath.IsAbs(database) && database != "" { - database = filepath.Join(path, database) - } - - // If there is no database path on the settings, - // store one in .caddy/hugo/{name}.db. - if database == "" { - // The name of the database is the hashed value of a string composed - // by the host, address path and the baseurl of this File Manager - // instance. - hasher := md5.New() - hasher.Write([]byte(caddyConf.Addr.Host + caddyConf.Addr.Path + admin)) - sha := hex.EncodeToString(hasher.Sum(nil)) - database = filepath.Join(path, sha+".db") - - fmt.Println("[WARNING] A database is going to be created for your Hugo instace at " + database + - ". It is highly recommended that you set the 'database' option to '" + sha + ".db'\n") - } - - m, err := filemanager.New(database, filemanager.User{ - Locale: "en", - AllowCommands: true, - AllowEdit: true, - AllowNew: true, - AllowPublish: true, - Commands: []string{"git", "svn", "hg"}, - Rules: []*filemanager.Rule{{ - Regex: true, - Allow: false, - Regexp: &filemanager.Regexp{Raw: "\\/\\..+"}, - }}, - CSS: "", - FileSystem: fileutils.Dir(directory), - }) - - if err != nil { - return nil, err - } - - // Initialize the default settings for Hugo. - hugo := &filemanager.Hugo{ - Root: directory, - Public: filepath.Join(directory, "public"), - Args: []string{}, - CleanPublic: true, - } - - // Attaches Hugo plugin to this file manager instance. - err = m.EnableStaticGen(hugo) - if err != nil { - return nil, err - } - - m.NoAuth = noAuth - m.SetBaseURL(admin) - m.SetPrefixURL(strings.TrimSuffix(caddyConf.Addr.Path, "/")) - configs = append(configs, m) - } - - return configs, nil -} - -// ServeHTTP determines if the request is for this plugin, and if all prerequisites are met. -func (p plugin) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) { - for i := range p.Configs { - // Checks if this Path should be handled by File Manager. - if !httpserver.Path(r.URL.Path).Matches(p.Configs[i].BaseURL) { - continue - } - - p.Configs[i].ServeHTTP(w, r) - return 0, nil - } - - return p.Next.ServeHTTP(w, r) -} - func init() { caddy.RegisterPlugin("hugo", caddy.Plugin{ ServerType: "http", @@ -175,3 +20,32 @@ type plugin struct { Next httpserver.Handler Configs []*filemanager.FileManager } + +// ServeHTTP determines if the request is for this plugin, and if all prerequisites are met. +func (f plugin) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) { + for i := range f.Configs { + // Checks if this Path should be handled by File Manager. + if !httpserver.Path(r.URL.Path).Matches(f.Configs[i].BaseURL) { + continue + } + + f.Configs[i].ServeHTTP(w, r) + return 0, nil + } + + return f.Next.ServeHTTP(w, r) +} + +// setup configures a new FileManager middleware instance. +func setup(c *caddy.Controller) error { + configs, err := parser.Parse(c, "hugo") + if err != nil { + return err + } + + httpserver.GetConfig(c).AddMiddleware(func(next httpserver.Handler) httpserver.Handler { + return plugin{Configs: configs, Next: next} + }) + + return nil +} diff --git a/caddy/jekyll/jekyll.go b/caddy/jekyll/jekyll.go index a9fcd163..d2ffa964 100644 --- a/caddy/jekyll/jekyll.go +++ b/caddy/jekyll/jekyll.go @@ -1,169 +1,14 @@ package jekyll import ( - "crypto/md5" - "encoding/hex" - "fmt" "net/http" - "os" - "path/filepath" - "strconv" - "strings" "github.com/hacdias/filemanager" - "github.com/hacdias/fileutils" + "github.com/hacdias/filemanager/caddy/parser" "github.com/mholt/caddy" "github.com/mholt/caddy/caddyhttp/httpserver" ) -// setup configures a new FileManager middleware instance. -func setup(c *caddy.Controller) error { - configs, err := parse(c) - if err != nil { - return err - } - - httpserver.GetConfig(c).AddMiddleware(func(next httpserver.Handler) httpserver.Handler { - return plugin{Configs: configs, Next: next} - }) - - return nil -} - -func parse(c *caddy.Controller) ([]*filemanager.FileManager, error) { - var ( - configs []*filemanager.FileManager - ) - - for c.Next() { - // jekyll [directory] [admin] { - // database path - // } - directory := "." - admin := "/admin" - database := "" - noAuth := false - - // Get the baseURL and baseScope - args := c.RemainingArgs() - - if len(args) >= 1 { - directory = args[0] - } - - if len(args) > 1 { - admin = args[1] - } - - for c.NextBlock() { - switch c.Val() { - case "database": - if !c.NextArg() { - return nil, c.ArgErr() - } - - database = c.Val() - case "no_auth": - if !c.NextArg() { - noAuth = true - continue - } - - var err error - noAuth, err = strconv.ParseBool(c.Val()) - if err != nil { - return nil, err - } - } - } - - caddyConf := httpserver.GetConfig(c) - - path := filepath.Join(caddy.AssetsPath(), "jekyll") - err := os.MkdirAll(path, 0700) - if err != nil { - return nil, err - } - - // if there is a database path and it is not absolute, - // it will be relative to ".caddy" folder. - if !filepath.IsAbs(database) && database != "" { - database = filepath.Join(path, database) - } - - // If there is no database path on the settings, - // store one in .caddy/jekyll/{name}.db. - if database == "" { - // The name of the database is the hashed value of a string composed - // by the host, address path and the baseurl of this File Manager - // instance. - hasher := md5.New() - hasher.Write([]byte(caddyConf.Addr.Host + caddyConf.Addr.Path + admin)) - sha := hex.EncodeToString(hasher.Sum(nil)) - database = filepath.Join(path, sha+".db") - - fmt.Println("[WARNING] A database is going to be created for your Jekyll instace at " + database + - ". It is highly recommended that you set the 'database' option to '" + sha + ".db'\n") - } - - m, err := filemanager.New(database, filemanager.User{ - Locale: "en", - AllowCommands: true, - AllowEdit: true, - AllowNew: true, - AllowPublish: true, - Commands: []string{"git", "svn", "hg"}, - Rules: []*filemanager.Rule{{ - Regex: true, - Allow: false, - Regexp: &filemanager.Regexp{Raw: "\\/\\..+"}, - }}, - CSS: "", - FileSystem: fileutils.Dir(directory), - }) - - if err != nil { - return nil, err - } - - // Initialize the default settings for Jekyll. - jekyll := &filemanager.Jekyll{ - Root: directory, - Public: filepath.Join(directory, "_site"), - Args: []string{}, - CleanPublic: true, - } - - // Attaches Hugo plugin to this file manager instance. - err = m.EnableStaticGen(jekyll) - if err != nil { - return nil, err - } - - m.NoAuth = noAuth - m.SetBaseURL(admin) - m.SetPrefixURL(strings.TrimSuffix(caddyConf.Addr.Path, "/")) - configs = append(configs, m) - } - - return configs, nil -} - -// ServeHTTP determines if the request is for this plugin, and if all prerequisites are met. -func (p plugin) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) { - for i := range p.Configs { - // Checks if this Path should be handled by File Manager. - if !httpserver.Path(r.URL.Path).Matches(p.Configs[i].BaseURL) { - continue - } - - p.Configs[i].ServeHTTP(w, r) - return 0, nil - } - - return p.Next.ServeHTTP(w, r) -} - func init() { caddy.RegisterPlugin("jekyll", caddy.Plugin{ ServerType: "http", @@ -175,3 +20,32 @@ type plugin struct { Next httpserver.Handler Configs []*filemanager.FileManager } + +// ServeHTTP determines if the request is for this plugin, and if all prerequisites are met. +func (f plugin) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) { + for i := range f.Configs { + // Checks if this Path should be handled by File Manager. + if !httpserver.Path(r.URL.Path).Matches(f.Configs[i].BaseURL) { + continue + } + + f.Configs[i].ServeHTTP(w, r) + return 0, nil + } + + return f.Next.ServeHTTP(w, r) +} + +// setup configures a new FileManager middleware instance. +func setup(c *caddy.Controller) error { + configs, err := parser.Parse(c, "jekyll") + if err != nil { + return err + } + + httpserver.GetConfig(c).AddMiddleware(func(next httpserver.Handler) httpserver.Handler { + return plugin{Configs: configs, Next: next} + }) + + return nil +} diff --git a/caddy/parser/parser.go b/caddy/parser/parser.go new file mode 100644 index 00000000..33a886e3 --- /dev/null +++ b/caddy/parser/parser.go @@ -0,0 +1,232 @@ +package parser + +import ( + "crypto/md5" + "encoding/hex" + "fmt" + "io/ioutil" + "os" + "path/filepath" + "strconv" + "strings" + + "github.com/hacdias/filemanager" + "github.com/hacdias/fileutils" + "github.com/mholt/caddy" + "github.com/mholt/caddy/caddyhttp/httpserver" +) + +// Parse ... +func Parse(c *caddy.Controller, plugin string) ([]*filemanager.FileManager, error) { + var ( + configs []*filemanager.FileManager + err error + ) + + for c.Next() { + u := filemanager.User{ + Locale: "en", + AllowCommands: true, + AllowEdit: true, + AllowNew: true, + AllowPublish: true, + Commands: []string{"git", "svn", "hg"}, + CSS: "", + Rules: []*filemanager.Rule{{ + Regex: true, + Allow: false, + Regexp: &filemanager.Regexp{Raw: "\\/\\..+"}, + }}, + } + + baseURL := "/" + scope := "." + database := "" + noAuth := false + + if plugin != "" { + baseURL = "/admin" + } + + // Get the baseURL and scope + args := c.RemainingArgs() + + if plugin == "" { + if len(args) >= 1 { + baseURL = args[0] + } + + if len(args) > 1 { + scope = args[1] + } + } else { + if len(args) >= 1 { + scope = args[0] + } + + if len(args) > 1 { + baseURL = args[1] + } + } + + for c.NextBlock() { + switch c.Val() { + case "database": + if !c.NextArg() { + return nil, c.ArgErr() + } + + database = c.Val() + case "locale": + if !c.NextArg() { + return nil, c.ArgErr() + } + + u.Locale = c.Val() + case "allow_commands": + if !c.NextArg() { + u.AllowCommands = true + continue + } + + u.AllowCommands, err = strconv.ParseBool(c.Val()) + if err != nil { + return nil, err + } + case "allow_edit": + if !c.NextArg() { + u.AllowEdit = true + continue + } + + u.AllowEdit, err = strconv.ParseBool(c.Val()) + if err != nil { + return nil, err + } + case "allow_new": + if !c.NextArg() { + u.AllowNew = true + continue + } + + u.AllowNew, err = strconv.ParseBool(c.Val()) + if err != nil { + return nil, err + } + case "allow_publish": + if !c.NextArg() { + u.AllowPublish = true + continue + } + + u.AllowPublish, err = strconv.ParseBool(c.Val()) + if err != nil { + return nil, err + } + case "commands": + if !c.NextArg() { + return nil, c.ArgErr() + } + + u.Commands = strings.Split(c.Val(), " ") + case "css": + if !c.NextArg() { + return nil, c.ArgErr() + } + + file := c.Val() + css, err := ioutil.ReadFile(file) + if err != nil { + return nil, err + } + + u.CSS = string(css) + case "no_auth": + if !c.NextArg() { + noAuth = true + continue + } + + noAuth, err = strconv.ParseBool(c.Val()) + if err != nil { + return nil, err + } + } + } + + caddyConf := httpserver.GetConfig(c) + + path := filepath.Join(caddy.AssetsPath(), "filemanager") + err := os.MkdirAll(path, 0700) + if err != nil { + return nil, err + } + + // if there is a database path and it is not absolute, + // it will be relative to Caddy folder. + if !filepath.IsAbs(database) && database != "" { + database = filepath.Join(path, database) + } + + // If there is no database path on the settings, + // store one in .caddy/filemanager/name.db. + if database == "" { + // The name of the database is the hashed value of a string composed + // by the host, address path and the baseurl of this File Manager + // instance. + hasher := md5.New() + hasher.Write([]byte(caddyConf.Addr.Host + caddyConf.Addr.Path + baseURL)) + sha := hex.EncodeToString(hasher.Sum(nil)) + database = filepath.Join(path, sha+".db") + + fmt.Println("[WARNING] A database is going to be created for your File Manager instace at " + database + + ". It is highly recommended that you set the 'database' option to '" + sha + ".db'\n") + } + + u.FileSystem = fileutils.Dir(scope) + m, err := filemanager.New(database, u) + + switch plugin { + case "hugo": + // Initialize the default settings for Hugo. + hugo := &filemanager.Hugo{ + Root: scope, + Public: filepath.Join(scope, "public"), + Args: []string{}, + CleanPublic: true, + } + + // Attaches Hugo plugin to this file manager instance. + err = m.EnableStaticGen(hugo) + if err != nil { + return nil, err + } + case "jekyll": + // Initialize the default settings for Jekyll. + jekyll := &filemanager.Jekyll{ + Root: scope, + Public: filepath.Join(scope, "_site"), + Args: []string{}, + CleanPublic: true, + } + + // Attaches Hugo plugin to this file manager instance. + err = m.EnableStaticGen(jekyll) + if err != nil { + return nil, err + } + } + + if err != nil { + return nil, err + } + + m.NoAuth = noAuth + m.SetBaseURL(baseURL) + m.SetPrefixURL(strings.TrimSuffix(caddyConf.Addr.Path, "/")) + + configs = append(configs, m) + } + + return configs, nil +}