package http import ( "context" "fmt" "net/http" "git.javil.eu/jacob1123/budgeteer" "git.javil.eu/jacob1123/budgeteer/postgres" "github.com/gin-gonic/gin" ) func (h *Handler) verifyLogin(c *gin.Context) (budgeteer.Token, error) { tokenString := c.GetHeader("Authorization") tokenString = tokenString[7:] token, err := h.TokenVerifier.VerifyToken(tokenString) if err != nil { return nil, fmt.Errorf("verify token '%s': %w", tokenString, err) } return token, nil } func (h *Handler) verifyLoginWithForbidden(c *gin.Context) { token, err := h.verifyLogin(c) if err != nil { //c.Header("WWW-Authenticate", "Bearer") c.AbortWithError(http.StatusForbidden, err) return } c.Set("token", token) c.Next() } func (h *Handler) verifyLoginWithRedirect(c *gin.Context) { token, err := h.verifyLogin(c) if err != nil { c.Redirect(http.StatusTemporaryRedirect, "/login") c.Abort() return } c.Set("token", token) c.Next() } func (h *Handler) login(c *gin.Context) { if _, err := h.verifyLogin(c); err == nil { c.Redirect(http.StatusTemporaryRedirect, "/dashboard") return } c.HTML(http.StatusOK, "login.html", nil) } func (h *Handler) register(c *gin.Context) { if _, err := h.verifyLogin(c); err == nil { c.Redirect(http.StatusTemporaryRedirect, "/dashboard") return } c.HTML(http.StatusOK, "register.html", nil) } type loginInformation struct { Password string `json:"password"` User string `json:"user"` } func (h *Handler) loginPost(c *gin.Context) { var login loginInformation err := c.BindJSON(&login) if err != nil { return } user, err := h.Service.GetUserByUsername(c.Request.Context(), login.User) if err != nil { c.AbortWithError(http.StatusUnauthorized, err) return } if err = h.CredentialsVerifier.Verify(login.Password, user.Password); err != nil { c.AbortWithError(http.StatusUnauthorized, err) return } t, err := h.TokenVerifier.CreateToken(&user) if err != nil { c.AbortWithError(http.StatusUnauthorized, err) } go h.Service.UpdateLastLogin(context.Background(), user.ID) c.JSON(http.StatusOK, struct { Token string User postgres.User }{t, user}) } type registerInformation struct { Password string `json:"password"` Email string `json:"email"` Name string `json:"name"` } func (h *Handler) registerPost(c *gin.Context) { var register registerInformation c.BindJSON(®ister) if register.Email == "" || register.Password == "" || register.Name == "" { c.AbortWithError(http.StatusBadRequest, fmt.Errorf("e-mail, password and name are required")) return } _, err := h.Service.GetUserByUsername(c.Request.Context(), register.Email) if err == nil { c.AbortWithError(http.StatusUnauthorized, err) return } hash, err := h.CredentialsVerifier.Hash(register.Password) if err != nil { c.AbortWithError(http.StatusUnauthorized, err) return } createUser := postgres.CreateUserParams{ Name: register.Name, Password: hash, Email: register.Email, } user, err := h.Service.CreateUser(c.Request.Context(), createUser) if err != nil { c.AbortWithError(http.StatusInternalServerError, err) } t, err := h.TokenVerifier.CreateToken(&user) if err != nil { c.AbortWithError(http.StatusUnauthorized, err) } go h.Service.UpdateLastLogin(context.Background(), user.ID) c.JSON(http.StatusOK, struct { Token string User postgres.User }{t, user}) }