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) }