package user import ( "log" "net/http" "github.com/volatiletech/sqlboiler/v4/boil" "gitlab.com/alexkavon/newsstand/src/models" "gitlab.com/alexkavon/newsstand/src/server" "gitlab.com/alexkavon/newsstand/src/sessions" ) func init() { InitInsertHooks() } var Routes = server.Routes{ server.Route{ Name: "Create", Method: "GET", Path: "/u/create", HandlerFunc: Create, Middlewares: server.NewMiddlewares(sessions.GuestSession), }, server.Route{ Name: "Store", Method: "POST", Path: "/u", HandlerFunc: Store, Middlewares: server.NewMiddlewares(sessions.GuestSession), }, server.Route{ Name: "LoginForm", Method: "GET", Path: "/u/auth", HandlerFunc: LoginForm, Middlewares: server.NewMiddlewares(sessions.GuestSession), }, server.Route{ Name: "Authenticate", Method: "POST", Path: "/u/auth", HandlerFunc: Login, Middlewares: server.NewMiddlewares(sessions.GuestSession), }, server.Route{ Name: "Logout", Method: "GET", Path: "/u/logout", HandlerFunc: Logout, Middlewares: server.NewMiddlewares(sessions.AuthSession), }, server.Route{ Name: "Me", Method: "GET", Path: "/u/me", HandlerFunc: Show, Middlewares: server.NewMiddlewares(sessions.AuthSession), }, } func Create(s *server.Server) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { s.Ui.Render(w, r, "user/create", nil) } } func Store(s *server.Server) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { var user models.User user.Username = r.PostFormValue("username") user.Secret = r.PostFormValue("secret") // Store user, this package (user) will init // a validation hook to check values and hash secret err := user.Insert(r.Context(), s.Db.ToSqlDb(), boil.Infer()) if err != nil { log.Fatal("Insert Error", err) } // Create cookie session sessions.NewSession(w, sessions.SessionValues{"uid": user.ID, "username": user.Username}) // Redirect to user profile http.Redirect(w, r, "/u/me", http.StatusSeeOther) } } func LoginForm(s *server.Server) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { s.Ui.Render(w, r, "user/login", nil) } } func Login(s *server.Server) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { // look up the user from the db user, err := models.Users(models.UserWhere.Username.EQ(r.PostFormValue("username"))).One(r.Context(), s.Db.ToSqlDb()) if err != nil { log.Fatal(err) } // hash the form secret // compare form hash to db hash err = compareSecretToHash(r.PostFormValue("secret"), user.Secret) if err != nil { log.Println(err) log.Fatal("Incorrect login credentials TODO resolve with compareSecretToHash err") } // login or dont sessions.NewSession(w, sessions.SessionValues{"uid": user.ID, "username": user.Username}) http.Redirect(w, r, "/u/me", http.StatusSeeOther) } } func Logout(s *server.Server) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { if session := r.Context().Value(sessions.SessionCtxKey("session")); session != nil { session.(*sessions.Session).Destroy(w) } http.Redirect(w, r, "/u/auth", http.StatusSeeOther) } } func Show(s *server.Server) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { pageData := map[string]any{"message": "Congrats on getting this far!"} s.Ui.Render(w, r, "user/me", pageData) } }