feat: readd caddy to this repo
Former-commit-id: cf48e35cd8c5ceff57d1353c75ffacd1de96e9ad [formerly d62bc138c736881547184977110cd622f2d31847] [formerly 4270b9fb5c907097ce6babffcedafccb5a8b6356 [formerly 385cfba0ff
]]
Former-commit-id: 04e6142a81d677781664c9a79e960465fadd3eb4 [formerly 2152b2410fb078914c788bf7f15ca8028af54c58]
Former-commit-id: e88a3fce1b9d16421ce9c1aa9c63c90705878bd2
pull/726/head
parent
4a7bdfc59b
commit
68bfbe5103
|
@ -0,0 +1,52 @@
|
||||||
|
package filemanager
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/filebrowser/filebrowser"
|
||||||
|
"github.com/filebrowser/filebrowser/caddy/parser"
|
||||||
|
h "github.com/filebrowser/filebrowser/http"
|
||||||
|
"github.com/mholt/caddy"
|
||||||
|
"github.com/mholt/caddy/caddyhttp/httpserver"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
caddy.RegisterPlugin("filemanager", caddy.Plugin{
|
||||||
|
ServerType: "http",
|
||||||
|
Action: setup,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type plugin struct {
|
||||||
|
Next httpserver.Handler
|
||||||
|
Configs []*filebrowser.FileBrowser
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
||||||
|
h.Handler(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, "")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
httpserver.GetConfig(c).AddMiddleware(func(next httpserver.Handler) httpserver.Handler {
|
||||||
|
return plugin{Configs: configs, Next: next}
|
||||||
|
})
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
package hugo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/filebrowser/filebrowser"
|
||||||
|
"github.com/filebrowser/filebrowser/caddy/parser"
|
||||||
|
h "github.com/filebrowser/filebrowser/http"
|
||||||
|
"github.com/mholt/caddy"
|
||||||
|
"github.com/mholt/caddy/caddyhttp/httpserver"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
caddy.RegisterPlugin("hugo", caddy.Plugin{
|
||||||
|
ServerType: "http",
|
||||||
|
Action: setup,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type plugin struct {
|
||||||
|
Next httpserver.Handler
|
||||||
|
Configs []*filebrowser.FileBrowser
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
||||||
|
h.Handler(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
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
package jekyll
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/filebrowser/filebrowser"
|
||||||
|
"github.com/filebrowser/filebrowser/caddy/parser"
|
||||||
|
h "github.com/filebrowser/filebrowser/http"
|
||||||
|
"github.com/mholt/caddy"
|
||||||
|
"github.com/mholt/caddy/caddyhttp/httpserver"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
caddy.RegisterPlugin("jekyll", caddy.Plugin{
|
||||||
|
ServerType: "http",
|
||||||
|
Action: setup,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type plugin struct {
|
||||||
|
Next httpserver.Handler
|
||||||
|
Configs []*filebrowser.FileBrowser
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
|
||||||
|
h.Handler(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
|
||||||
|
}
|
|
@ -0,0 +1,295 @@
|
||||||
|
package parser
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/md5"
|
||||||
|
"encoding/hex"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/asdine/storm"
|
||||||
|
"github.com/filebrowser/filebrowser"
|
||||||
|
"github.com/filebrowser/filebrowser/bolt"
|
||||||
|
"github.com/filebrowser/filebrowser/staticgen"
|
||||||
|
"github.com/hacdias/fileutils"
|
||||||
|
"github.com/mholt/caddy"
|
||||||
|
"github.com/mholt/caddy/caddyhttp/httpserver"
|
||||||
|
)
|
||||||
|
|
||||||
|
var databases = map[string]*storm.DB{}
|
||||||
|
|
||||||
|
// Parse ...
|
||||||
|
func Parse(c *caddy.Controller, plugin string) ([]*filebrowser.FileBrowser, error) {
|
||||||
|
var (
|
||||||
|
configs []*filebrowser.FileBrowser
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
for c.Next() {
|
||||||
|
u := &filebrowser.User{
|
||||||
|
Locale: "en",
|
||||||
|
AllowCommands: true,
|
||||||
|
AllowEdit: true,
|
||||||
|
AllowNew: true,
|
||||||
|
AllowPublish: true,
|
||||||
|
Commands: []string{"git", "svn", "hg"},
|
||||||
|
CSS: "",
|
||||||
|
ViewMode: "mosaic",
|
||||||
|
Rules: []*filebrowser.Rule{{
|
||||||
|
Regex: true,
|
||||||
|
Allow: false,
|
||||||
|
Regexp: &filebrowser.Regexp{Raw: "\\/\\..+"},
|
||||||
|
}},
|
||||||
|
}
|
||||||
|
|
||||||
|
baseURL := "/"
|
||||||
|
scope := "."
|
||||||
|
database := ""
|
||||||
|
noAuth := false
|
||||||
|
reCaptchaKey := ""
|
||||||
|
reCaptchaSecret := ""
|
||||||
|
|
||||||
|
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 "view_mode":
|
||||||
|
if !c.NextArg() {
|
||||||
|
return nil, c.ArgErr()
|
||||||
|
}
|
||||||
|
|
||||||
|
u.ViewMode = c.Val()
|
||||||
|
if u.ViewMode != filebrowser.MosaicViewMode && u.ViewMode != filebrowser.ListViewMode {
|
||||||
|
return nil, c.ArgErr()
|
||||||
|
}
|
||||||
|
case "recaptcha_key":
|
||||||
|
if !c.NextArg() {
|
||||||
|
return nil, c.ArgErr()
|
||||||
|
}
|
||||||
|
|
||||||
|
reCaptchaKey = c.Val()
|
||||||
|
case "recaptcha_secret":
|
||||||
|
if !c.NextArg() {
|
||||||
|
return nil, c.ArgErr()
|
||||||
|
}
|
||||||
|
|
||||||
|
reCaptchaSecret = c.Val()
|
||||||
|
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 instance at " + database +
|
||||||
|
". It is highly recommended that you set the 'database' option to '" + sha + ".db'\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
u.Scope = scope
|
||||||
|
u.FileSystem = fileutils.Dir(scope)
|
||||||
|
|
||||||
|
var db *storm.DB
|
||||||
|
if stored, ok := databases[database]; ok {
|
||||||
|
db = stored
|
||||||
|
} else {
|
||||||
|
db, err = storm.Open(database)
|
||||||
|
databases[database] = db
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
m := &filebrowser.FileBrowser{
|
||||||
|
NoAuth: noAuth,
|
||||||
|
BaseURL: "",
|
||||||
|
PrefixURL: "",
|
||||||
|
ReCaptchaKey: reCaptchaKey,
|
||||||
|
ReCaptchaSecret: reCaptchaSecret,
|
||||||
|
DefaultUser: u,
|
||||||
|
Store: &filebrowser.Store{
|
||||||
|
Config: bolt.ConfigStore{DB: db},
|
||||||
|
Users: bolt.UsersStore{DB: db},
|
||||||
|
Share: bolt.ShareStore{DB: db},
|
||||||
|
},
|
||||||
|
NewFS: func(scope string) filebrowser.FileSystem {
|
||||||
|
return fileutils.Dir(scope)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
err = m.Setup()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
switch plugin {
|
||||||
|
case "hugo":
|
||||||
|
// Initialize the default settings for Hugo.
|
||||||
|
hugo := &staticgen.Hugo{
|
||||||
|
Root: scope,
|
||||||
|
Public: filepath.Join(scope, "public"),
|
||||||
|
Args: []string{},
|
||||||
|
CleanPublic: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attaches Hugo plugin to this file manager instance.
|
||||||
|
err = m.Attach(hugo)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
case "jekyll":
|
||||||
|
// Initialize the default settings for Jekyll.
|
||||||
|
jekyll := &staticgen.Jekyll{
|
||||||
|
Root: scope,
|
||||||
|
Public: filepath.Join(scope, "_site"),
|
||||||
|
Args: []string{},
|
||||||
|
CleanPublic: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attaches Hugo plugin to this file manager instance.
|
||||||
|
err = m.Attach(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
|
||||||
|
}
|
Loading…
Reference in New Issue