package cmd import ( "io/ioutil" "log" "net" "net/http" "os" "path/filepath" "github.com/asdine/storm" filebrowser "github.com/filebrowser/filebrowser/lib" "github.com/filebrowser/filebrowser/lib/bolt" h "github.com/filebrowser/filebrowser/lib/http" "github.com/filebrowser/filebrowser/lib/staticgen" "github.com/hacdias/fileutils" "github.com/spf13/viper" lumberjack "gopkg.in/natefinch/lumberjack.v2" ) func Serve() { // Set up process log before anything bad happens. switch l := viper.GetString("log"); l { case "stdout": log.SetOutput(os.Stdout) case "stderr": log.SetOutput(os.Stderr) case "": log.SetOutput(ioutil.Discard) default: log.SetOutput(&lumberjack.Logger{ Filename: l, MaxSize: 100, MaxAge: 14, MaxBackups: 10, }) } // Validate the provided config before moving forward { // Map of valid authentication methods, containing a boolean value to indicate the need of Auth.Header validMethods := make(map[string]bool) validMethods["none"] = false validMethods["default"] = false validMethods["proxy"] = true m := viper.GetString("auth.method") b, ok := validMethods[m] if !ok { log.Fatal("The property 'auth.method' needs to be set to 'none', 'default' or 'proxy'.") } if b { if viper.GetString("auth.header") == "" { log.Fatal("The 'auth.header' needs to be specified when '", m, "' authentication is used.") } log.Println("[WARN] Filebrowser authentication is configured to '", m, "' authentication. This can cause a huge security issue if the infrastructure is not configured correctly.") } } // Builds the address and a listener. laddr := viper.GetString("address") + ":" + viper.GetString("port") listener, err := net.Listen("tcp", laddr) if err != nil { log.Fatal(err) } // Tell the user the port in which is listening. log.Println("Listening on", listener.Addr().String()) // Starts the server. if err := http.Serve(listener, handler()); err != nil { log.Fatal(err) } } func handler() http.Handler { db, err := storm.Open(viper.GetString("database")) if err != nil { log.Fatal(err) } fb := &filebrowser.FileBrowser{ Auth: &filebrowser.Auth{ Method: viper.GetString("auth.method"), Header: viper.GetString("auth.header"), }, ReCaptcha: &filebrowser.ReCaptcha{ Host: viper.GetString("recaptcha.host"), Key: viper.GetString("recaptcha.key"), Secret: viper.GetString("recaptcha.secret"), }, DefaultUser: &filebrowser.User{ AllowCommands: viper.GetBool("defaults.allowCommands"), AllowEdit: viper.GetBool("defaults.allowEdit"), AllowNew: viper.GetBool("defaults.allowNew"), AllowPublish: viper.GetBool("defaults.allowPublish"), Commands: viper.GetStringSlice("defaults.commands"), Rules: []*filebrowser.Rule{}, Locale: viper.GetString("defaults.locale"), CSS: "", Scope: viper.GetString("defaults.scope"), FileSystem: fileutils.Dir(viper.GetString("defaults.scope")), ViewMode: viper.GetString("defaults.viewMode"), }, 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) }, } fb.SetBaseURL(viper.GetString("baseurl")) fb.SetPrefixURL(viper.GetString("prefixurl")) err = fb.Setup() if err != nil { log.Fatal(err) } switch viper.GetString("staticgen") { case "hugo": hugo := &staticgen.Hugo{ Root: viper.GetString("Scope"), Public: filepath.Join(viper.GetString("Scope"), "public"), Args: []string{}, CleanPublic: true, } if err = fb.Attach(hugo); err != nil { log.Fatal(err) } case "jekyll": jekyll := &staticgen.Jekyll{ Root: viper.GetString("Scope"), Public: filepath.Join(viper.GetString("Scope"), "_site"), Args: []string{"build"}, CleanPublic: true, } if err = fb.Attach(jekyll); err != nil { log.Fatal(err) } } return h.Handler(fb) }