Files
go-fishing/internal/handlers/v1/auth.go
T
2026-09-15 09:15:53 -05:00

123 lines
2.9 KiB
Go

package v1
import (
"database/sql"
"errors"
"net/http"
"github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin"
"jp.wtf/go-fishing/internal/api"
"jp.wtf/go-fishing/internal/models"
)
func (h *V1Router) Login(c *gin.Context) {
if api.CheckIfLoggedIn(c) {
api.Fail(c, http.StatusBadRequest, api.APIErrorCodeInvalidRequest, "You are already logged in!")
return
}
var json struct {
Username string `json:"username"`
Password string `json:"password"`
}
if err := c.ShouldBind(&json); err != nil {
api.Fail(c, http.StatusBadRequest, api.APIErrorCodeInvalidBody, err.Error())
return
}
angler, err := h.DB.GetRawAnglerByUsername(json.Username)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
api.Fail(c, http.StatusUnauthorized, api.APIErrorCodeUnauthorized, "Invalid username or password")
return
}
api.Fail(c, http.StatusInternalServerError, api.APIErrorCodeUnknown, err.Error())
return
}
if valid := api.CheckPassword(json.Password, angler.PasswordHash); valid {
s := sessions.Default(c)
s.Set("angler_id", angler.ID)
err := s.Save()
if err != nil {
api.Fail(c, http.StatusInternalServerError, api.APIErrorCodeUnknown, "Failed to create new session")
return
}
api.OK(c, models.Angler{
ID: angler.ID,
Username: angler.Username,
})
return
}
api.Fail(c, http.StatusUnauthorized, api.APIErrorCodeUnauthorized, "Invalid username or password")
}
func (h *V1Router) Signup(c *gin.Context) {
if api.CheckIfLoggedIn(c) {
api.Fail(c, http.StatusBadRequest, api.APIErrorCodeInvalidRequest, "You are already logged in!")
return
}
var json api.CreateAnglerRequest
if err := c.ShouldBind(&json); err != nil {
api.Fail(c, http.StatusBadRequest, api.APIErrorCodeInvalidBody, err.Error())
return
}
hashed_password, hash_err := api.HashPassword(json.Password)
if hash_err != nil {
api.Fail(c, http.StatusInternalServerError, api.APIErrorCodeUnknown, hash_err.Error())
return
}
new_angler, create_err := h.DB.CreateNewAngler(json.Username, hashed_password)
if create_err != nil {
api.Fail(c, http.StatusInternalServerError, api.APIErrorCodeUnknown, create_err.Error())
return
}
s := sessions.Default(c)
s.Set("angler_id", new_angler.ID)
if err := s.Save(); err != nil {
api.Fail(c, http.StatusInternalServerError, api.APIErrorCodeUnknown, "Failed to create new session")
return
}
api.OK(c, models.Angler{
ID: new_angler.ID,
Username: new_angler.Username,
})
}
func (h *V1Router) Logout(c *gin.Context) {
if !api.CheckIfLoggedIn(c) {
api.Fail(c, http.StatusBadRequest, api.APIErrorCodeInvalidRequest, "You are not logged in...thus you cannot logout!")
return
}
s := sessions.Default(c)
s.Clear()
s.Save()
api.OK(c, nil)
}
func (h *V1Router) GetMe(c *gin.Context) {
angler, err := api.GetAnglerFromSession(c)
if err != nil {
api.Fail(c, http.StatusInternalServerError, api.APIErrorCodeUnknown, err.Error())
return
}
api.OK(c, angler)
}