package main import ( "crypto/md5" "crypto/subtle" "encoding/hex" "html/template" "log" "net/http" "strconv" "time" ) type App struct { Store Template *template.Template } func logMux(handler http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { t := time.Now() handler.ServeHTTP(w, r) log.Println(r.Method, r.URL.Path, time.Since(t)) }) } func (app *App) validateHandler(w http.ResponseWriter, r *http.Request) { c, err := r.Cookie("id") //log.Println(r.Header.Get("X-Original-URI")) //log.Println(r.Host) if err != nil { w.WriteHeader(http.StatusUnauthorized) } else { if s, ok := app.GetSession(c.Value); ok { w.Header().Set("X-Remote-User", strconv.FormatInt(s.UserId, 10)) w.WriteHeader(http.StatusOK) } else { log.Println("Session does not exist:", c.Value) w.WriteHeader(http.StatusForbidden) } } } func (app *App) loginHandler(w http.ResponseWriter, r *http.Request) { if r.Method == http.MethodPost { if err := r.ParseForm(); err != nil { panic(err) } else { username := r.Form.Get("username") password := r.Form.Get("password") hash := md5.Sum([]byte(password)) dst := make([]byte, hex.EncodedLen(md5.Size)) hex.Encode(dst, hash[:]) u, ok := app.GetUser(username) if ok && subtle.ConstantTimeCompare(u.Password, dst) == 1 { } else { } } } else if r.Method == http.MethodGet { app.Template.ExecuteTemplate(w, "login.tmpl", nil) } } func main() { //log.SetFlags(log.LstdFlags) store := NewPgStore() template := template.Must(template.New("").ParseGlob("templates/*.tmpl")) app := &App{store, template} http.HandleFunc("/validate", app.validateHandler) http.HandleFunc("/login", app.loginHandler) if err := http.ListenAndServe(":8080", logMux(http.DefaultServeMux)); err != nil { panic(err) } }