diff options
author | sanine <sanine.not@pm.me> | 2023-05-14 20:12:06 -0500 |
---|---|---|
committer | sanine <sanine.not@pm.me> | 2023-05-14 20:12:06 -0500 |
commit | 5b4251fd39c43e4cfed27e032a4efb2bbba28e38 (patch) | |
tree | f51840d5607eba0db9262045e330a1c8b8393449 /main.go | |
parent | 9571ccc4d87907067df98edeaa78f0c167fcff43 (diff) |
add auth & pages
Diffstat (limited to 'main.go')
-rw-r--r-- | main.go | 112 |
1 files changed, 107 insertions, 5 deletions
@@ -3,15 +3,81 @@ package main import ( "os" "fmt" + "flag" + "errors" + "net/http" + "encoding/json" "sanine.net/git/phlox/config" + "sanine.net/git/phlox/auth" + "sanine.net/git/phlox/page" + log "github.com/sirupsen/logrus" ) func main() { - conf := loadConfig("config.json") - fmt.Println(conf.ListenAddress) - fmt.Println(conf.AssetDirectory) - fmt.Println(len(conf.Users)) - fmt.Println(len(conf.Endpoints)) + configFile := parseFlags() + + conf := loadConfig(configFile) + sessions := auth.NewSessionContainer() + pages := loadPages(conf) + users := getUsers(conf) + + // add phlox endpoints + http.HandleFunc("/phlox/login", func(w http.ResponseWriter, r *http.Request) { + Login(w, r, users, sessions, pages) + }) + + http.HandleFunc("/phlox/logout", func(w http.ResponseWriter, r *http.Request) { + Logout(w, r, sessions) + }) + + // add reverse proxy endpoints + for _, e := range conf.Endpoints { + addEndpoint(sessions, pages, e) + } + + log.Infof("listening on %v", conf.ListenAddress) + log.Fatal(http.ListenAndServe(conf.ListenAddress, nil)) +} + + +func parseFlags() string { + var configFile string + var username string + var passwd string + flag.StringVar(&configFile, "c", "./config.json", "the configuration file to use") + flag.StringVar(&passwd, "passwd", "", "hash a password") + flag.StringVar(&username, "user", "", "optional username for the JSON output of --passwd") + flag.Parse() + + if passwd != "" { + // generate a user JSON block with the password hash + // and random salt, then exit without launching the + // phlox daemon + showHash(username, passwd) + os.Exit(0) + } + + return configFile +} + + +func showHash(username, passwd string) { + salt, err := auth.GenerateSalt() + if err != nil { + fmt.Fprintf(os.Stderr, "failed to generate salt: %v\n", err.Error()) + } + + user := config.User{ + Name: username, + PasswordHash: auth.HashPassword(passwd, salt), + Salt: salt, + } + + blob, err := json.MarshalIndent(user, "", "\t") + if err != nil { + fmt.Fprintf(os.Stderr, "failed to generate JSON: %v\n", err.Error()) + } + fmt.Println(string(blob)) } @@ -23,3 +89,39 @@ func loadConfig(filename string) config.Config { } return conf } + + +func loadPages(c config.Config) page.Pages { + pages, err := page.LoadPages(c) + if err != nil { + fmt.Fprintf(os.Stderr, "failed to load html pages: %v\n", err.Error()) + os.Exit(1) + } + return pages +} + + +func getUsers(c config.Config) map[string]config.User { + users := make(map[string]config.User) + for _, user := range c.Users { + users[user.Name] = user + } + return users +} + + +func authenticateRequest(r *http.Request, s *auth.Sessions) bool { + cookie, err := r.Cookie("phlox-session") + if errors.Is(err, http.ErrNoCookie) { + return false + } + + id := cookie.Value + valid := s.IsSessionValid(id) + if !valid { + return false + } + + s.TouchSession(id) + return true +} |