mirror of
https://github.com/muety/wakapi.git
synced 2023-08-10 21:12:56 +03:00
feat: user signup
This commit is contained in:
138
routes/index.go
138
routes/index.go
@ -1,11 +1,13 @@
|
||||
package routes
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gorilla/schema"
|
||||
"github.com/muety/wakapi/models"
|
||||
"github.com/muety/wakapi/services"
|
||||
"github.com/muety/wakapi/utils"
|
||||
"net/http"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
type IndexHandler struct {
|
||||
@ -14,6 +16,7 @@ type IndexHandler struct {
|
||||
}
|
||||
|
||||
var loginDecoder = schema.NewDecoder()
|
||||
var signupDecoder = schema.NewDecoder()
|
||||
|
||||
func NewIndexHandler(config *models.Config, userService *services.UserService) *IndexHandler {
|
||||
return &IndexHandler{
|
||||
@ -32,15 +35,18 @@ func (h *IndexHandler) Index(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if err := r.URL.Query().Get("error"); err != "" {
|
||||
if err == "unauthorized" {
|
||||
respondError(w, err, http.StatusUnauthorized)
|
||||
} else {
|
||||
respondError(w, err, http.StatusInternalServerError)
|
||||
}
|
||||
if handleAlerts(w, r, "") {
|
||||
return
|
||||
}
|
||||
|
||||
// TODO: make this more generic and reusable
|
||||
if success := r.URL.Query().Get("success"); success != "" {
|
||||
templates["index.tpl.html"].Execute(w, struct {
|
||||
Success string
|
||||
Error string
|
||||
}{Success: success})
|
||||
return
|
||||
}
|
||||
templates["index.tpl.html"].Execute(w, nil)
|
||||
}
|
||||
|
||||
@ -49,30 +55,35 @@ func (h *IndexHandler) Login(w http.ResponseWriter, r *http.Request) {
|
||||
loadTemplates()
|
||||
}
|
||||
|
||||
if cookie, err := r.Cookie(models.AuthCookieKey); err == nil && cookie.Value != "" {
|
||||
http.Redirect(w, r, "/summary", http.StatusFound)
|
||||
return
|
||||
}
|
||||
|
||||
var login models.Login
|
||||
if err := r.ParseForm(); err != nil {
|
||||
respondError(w, "missing parameters", http.StatusBadRequest)
|
||||
respondAlert(w, "missing parameters", "", "", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
if err := loginDecoder.Decode(&login, r.PostForm); err != nil {
|
||||
respondError(w, "missing parameters", http.StatusBadRequest)
|
||||
respondAlert(w, "missing parameters", "", "", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
user, err := h.userSrvc.GetUserById(login.Username)
|
||||
if err != nil {
|
||||
respondError(w, "resource not found", http.StatusNotFound)
|
||||
respondAlert(w, "resource not found", "", "", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
if !utils.CheckPassword(user, login.Password) {
|
||||
respondError(w, "invalid credentials", http.StatusUnauthorized)
|
||||
respondAlert(w, "invalid credentials", "", "", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
encoded, err := h.config.SecureCookie.Encode(models.AuthCookieKey, login)
|
||||
if err != nil {
|
||||
respondError(w, "internal server error", http.StatusInternalServerError)
|
||||
respondAlert(w, "internal server error", "", "", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
@ -96,9 +107,108 @@ func (h *IndexHandler) Logout(w http.ResponseWriter, r *http.Request) {
|
||||
http.Redirect(w, r, "/", http.StatusFound)
|
||||
}
|
||||
|
||||
func respondError(w http.ResponseWriter, error string, status int) {
|
||||
func (h *IndexHandler) Signup(w http.ResponseWriter, r *http.Request) {
|
||||
if h.config.IsDev() {
|
||||
loadTemplates()
|
||||
}
|
||||
|
||||
if cookie, err := r.Cookie(models.AuthCookieKey); err == nil && cookie.Value != "" {
|
||||
http.Redirect(w, r, "/summary", http.StatusFound)
|
||||
return
|
||||
}
|
||||
|
||||
switch r.Method {
|
||||
case http.MethodPost:
|
||||
h.handlePostSignup(w, r)
|
||||
return
|
||||
default:
|
||||
h.handleGetSignup(w, r)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (h *IndexHandler) handleGetSignup(w http.ResponseWriter, r *http.Request) {
|
||||
if h.config.IsDev() {
|
||||
loadTemplates()
|
||||
}
|
||||
|
||||
if cookie, err := r.Cookie(models.AuthCookieKey); err == nil && cookie.Value != "" {
|
||||
http.Redirect(w, r, "/summary", http.StatusFound)
|
||||
return
|
||||
}
|
||||
|
||||
if handleAlerts(w, r, "signup.tpl.html") {
|
||||
return
|
||||
}
|
||||
|
||||
templates["signup.tpl.html"].Execute(w, nil)
|
||||
}
|
||||
|
||||
func (h *IndexHandler) handlePostSignup(w http.ResponseWriter, r *http.Request) {
|
||||
if h.config.IsDev() {
|
||||
loadTemplates()
|
||||
}
|
||||
|
||||
if cookie, err := r.Cookie(models.AuthCookieKey); err == nil && cookie.Value != "" {
|
||||
http.Redirect(w, r, "/summary", http.StatusFound)
|
||||
return
|
||||
}
|
||||
|
||||
var signup models.Signup
|
||||
if err := r.ParseForm(); err != nil {
|
||||
respondAlert(w, "missing parameters", "", "signup.tpl.html", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
if err := signupDecoder.Decode(&signup, r.PostForm); err != nil {
|
||||
respondAlert(w, "missing parameters", "", "signup.tpl.html", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if signup.Password != signup.PasswordRepeat {
|
||||
respondAlert(w, "passwords do not match", "", "signup.tpl.html", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
_, created, err := h.userSrvc.CreateOrGet(&signup)
|
||||
if err != nil {
|
||||
respondAlert(w, "failed to create new user", "", "signup.tpl.html", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
if !created {
|
||||
respondAlert(w, "user already existing", "", "signup.tpl.html", http.StatusConflict)
|
||||
return
|
||||
}
|
||||
|
||||
msg := url.QueryEscape("account created successfully")
|
||||
http.Redirect(w, r, fmt.Sprintf("/?success=%s", msg), http.StatusFound)
|
||||
}
|
||||
|
||||
func respondAlert(w http.ResponseWriter, error, success, tplName string, status int) {
|
||||
w.WriteHeader(status)
|
||||
templates["index.tpl.html"].Execute(w, struct {
|
||||
Error string
|
||||
if tplName == "" {
|
||||
tplName = "index.tpl.html"
|
||||
}
|
||||
templates[tplName].Execute(w, struct {
|
||||
Error string
|
||||
Success string
|
||||
}{Error: error})
|
||||
}
|
||||
|
||||
// TODO: do better
|
||||
func handleAlerts(w http.ResponseWriter, r *http.Request, tplName string) bool {
|
||||
if err := r.URL.Query().Get("error"); err != "" {
|
||||
if err == "unauthorized" {
|
||||
respondAlert(w, err, "", tplName, http.StatusUnauthorized)
|
||||
} else {
|
||||
respondAlert(w, err, "", tplName, http.StatusInternalServerError)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
if success := r.URL.Query().Get("success"); success != "" {
|
||||
respondAlert(w, "", success, tplName, http.StatusOK)
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
"html/template"
|
||||
"io/ioutil"
|
||||
"path"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@ -17,8 +18,10 @@ var templates map[string]*template.Template
|
||||
func loadTemplates() {
|
||||
tplPath := "views"
|
||||
tpls := template.New("").Funcs(template.FuncMap{
|
||||
"json": utils.Json,
|
||||
"date": utils.FormatDateHuman,
|
||||
"json": utils.Json,
|
||||
"date": utils.FormatDateHuman,
|
||||
"title": strings.Title,
|
||||
"capitalize": utils.Capitalize,
|
||||
})
|
||||
templates = make(map[string]*template.Template)
|
||||
|
Reference in New Issue
Block a user