diff --git a/.gitignore b/.gitignore index 18dca76a..c774651a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ .DS_Store node_modules/ */dist/* +*.db +*.db.lock npm-debug.log* yarn-debug.log* yarn-error.log* diff --git a/README.md b/README.md index f118878f..0e69ac90 100644 --- a/README.md +++ b/README.md @@ -18,13 +18,32 @@ filemanager provides a file managing interface within a specified directory and This is a library so it can be used on your own applications as a middleware or as a standalone app (examples are going to be added in the future). -The easiest way to get started is using this with Caddy web server. You just need to download Caddy from its [official website](https://caddyserver.com/download) with `http.filemanager` plugin enabled. For more information about the plugin itself, please refer to its [documentation](https://caddyserver.com/docs/http.filemanager). - Once you have everything deployed, the default credentials to login to the filemanager are: **Username:** `admin` **Password:** `admin` +## Caddy + +The easiest way to get started is using this with Caddy web server. You just need to download Caddy from its [official website](https://caddyserver.com/download) with `http.filemanager` plugin enabled. For more information about the plugin itself, please refer to its [documentation](https://caddyserver.com/docs/http.filemanager). + +## Standalone + +```json +{ + "port": 80, + "database": "/path/to/database.db", + "scope": "/path/to/my/files", + "allowCommands": true, + "allowEdit": true, + "allowNew": true, + "commands": [ + "git", + "svn" + ] +} +``` + # Features Easy login system. diff --git a/caddy/filemanager/filemanager.go b/caddy/filemanager/filemanager.go index c138a5c3..9d7f740e 100644 --- a/caddy/filemanager/filemanager.go +++ b/caddy/filemanager/filemanager.go @@ -44,7 +44,7 @@ func (f plugin) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) { continue } - return f.Configs[i].ServeHTTP(w, r) + return f.Configs[i].ServeWithErrorHTTP(w, r) } return f.Next.ServeHTTP(w, r) diff --git a/caddy/hugo/setup.go b/caddy/hugo/setup.go index aca848ff..56995eea 100644 --- a/caddy/hugo/setup.go +++ b/caddy/hugo/setup.go @@ -170,7 +170,7 @@ func (p plugin) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) { continue } - return p.Configs[i].ServeHTTP(w, r) + return p.Configs[i].ServeWithErrorHTTP(w, r) } return p.Next.ServeHTTP(w, r) diff --git a/cmd/filemanager/main.go b/cmd/filemanager/main.go new file mode 100644 index 00000000..d413e20a --- /dev/null +++ b/cmd/filemanager/main.go @@ -0,0 +1,102 @@ +package main + +import ( + "encoding/json" + "flag" + "fmt" + "io/ioutil" + "net/http" + "strconv" + "strings" + + "github.com/hacdias/filemanager" + + "golang.org/x/net/webdav" +) + +// confFile contains the configuration file for this File Manager instance. +// If the user chooses to use a configuration file, the flags will be ignored. +type confFile struct { + Database string `json:"database"` + Scope string `json:"scope"` + Commands []string `json:"commands"` + Port int `json:"port"` + AllowCommands bool `json:"allowCommands"` + AllowEdit bool `json:"allowEdit"` + AllowNew bool `json:"allowNew"` +} + +var ( + config string + database string + scope string + commands string + port string + allowCommands bool + allowEdit bool + allowNew bool +) + +func init() { + flag.StringVar(&config, "config", "", "JSON configuration file") + flag.StringVar(&port, "port", "80", "HTTP Port") + flag.StringVar(&database, "database", "./filemanager.db", "Database path") + flag.StringVar(&scope, "scope", ".", "Defualt scope for new users") + flag.StringVar(&commands, "commands", "git svn hg", "Space separated commands available for new users") + flag.BoolVar(&allowCommands, "allow-commands", true, "Default allow commands option") + flag.BoolVar(&allowEdit, "allow-edit", true, "Default allow edit option") + flag.BoolVar(&allowNew, "allow-new", true, "Default allow new option") +} + +func main() { + flag.Parse() + + if config != "" { + loadConfig() + } + + fm, err := filemanager.New(database, filemanager.User{ + Username: "admin", + Password: "admin", + AllowCommands: allowCommands, + AllowEdit: allowEdit, + AllowNew: allowNew, + Commands: strings.Split(strings.TrimSpace(commands), " "), + Rules: []*filemanager.Rule{}, + CSS: "", + FileSystem: webdav.Dir(scope), + }) + + if err != nil { + panic(err) + } + + fm.SetBaseURL("/") + fm.SetPrefixURL("/") + + fmt.Println("Starting filemanager on *:" + port) + if err := http.ListenAndServe(":"+port, fm); err != nil { + panic(err) + } +} + +func loadConfig() { + file, err := ioutil.ReadFile(config) + if err != nil { + panic(err) + } + + var conf *confFile + err = json.Unmarshal(file, &conf) + if err != nil { + panic(err) + } + + database = conf.Database + scope = conf.Scope + commands = strings.Join(conf.Commands, " ") + port = strconv.Itoa(conf.Port) + allowNew = conf.AllowNew + allowEdit = conf.AllowEdit + allowCommands = conf.AllowCommands +} diff --git a/filemanager.go b/filemanager.go index a5325597..56bdc898 100644 --- a/filemanager.go +++ b/filemanager.go @@ -322,20 +322,32 @@ func (m *FileManager) RegisterPermission(name string, value bool) error { } // ServeHTTP determines if the request is for this plugin, and if all prerequisites are met. -func (m *FileManager) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) { +// Compatible with http.Handler. +func (m *FileManager) ServeHTTP(w http.ResponseWriter, r *http.Request) { code, err := serveHTTP(&RequestContext{ FM: m, User: nil, FI: nil, }, w, r) - if code != 0 && err != nil { + if code != 0 { w.WriteHeader(code) - w.Write([]byte(err.Error())) - return 0, nil - } - return code, err + if err != nil { + w.Write([]byte(err.Error())) + } else { + w.Write([]byte(http.StatusText(code))) + } + } +} + +// ServeWithErrorHTTP returns the code and error of the request. +func (m *FileManager) ServeWithErrorHTTP(w http.ResponseWriter, r *http.Request) (int, error) { + return serveHTTP(&RequestContext{ + FM: m, + User: nil, + FI: nil, + }, w, r) } // Allowed checks if the user has permission to access a directory/file.