package controller import ( "net/http" "github.com/gorilla/sessions" "github.com/labstack/echo-contrib/session" "github.com/labstack/echo/v4" "gitrepo.ru/neonxp/nquest/api" "gitrepo.ru/neonxp/nquest/pkg/models" "gitrepo.ru/neonxp/nquest/pkg/service" "gitrepo.ru/neonxp/nquest/pkg/utils" ) type User struct { UserService *service.User } func (u *User) PostUserLogin(c echo.Context) error { req := new(api.PostUserLoginJSONRequestBody) if err := c.Bind(req); err != nil { return err } user, err := u.UserService.Login( c.Request().Context(), req.Email, req.Password, ) if err != nil { return c.JSON(http.StatusBadRequest, &api.ErrorResponse{ Code: http.StatusBadRequest, Message: err.Error(), }) } if err := setUser(c, user); err != nil { return c.JSON(http.StatusBadRequest, &api.ErrorResponse{ Code: http.StatusBadRequest, Message: err.Error(), }) } return mapUser(c, user) } func (u *User) PostUserRegister(c echo.Context) error { req := new(api.PostUserRegisterJSONRequestBody) if err := c.Bind(req); err != nil { return err } user, err := u.UserService.Register( c.Request().Context(), req.Username, req.Email, req.Password, req.Password2, ) if err != nil { return c.JSON(http.StatusBadRequest, &api.ErrorResponse{ Code: http.StatusBadRequest, Message: err.Error(), }) } if err := setUser(c, user); err != nil { return c.JSON(http.StatusBadRequest, &api.ErrorResponse{ Code: http.StatusBadRequest, Message: err.Error(), }) } return mapUser(c, user) } func (u *User) PostUserLogout(c echo.Context) error { if err := setUser(c, nil); err != nil { return err } return c.NoContent(http.StatusOK) } func (u *User) GetUser(c echo.Context) error { user := u.UserService.GetUser(c) if user == nil { return c.JSON(http.StatusNotFound, &api.ErrorResponse{ Code: http.StatusNotFound, Message: "User not found", }) } return mapUser(c, user) } func setUser(c echo.Context, user *models.User) error { sess, err := session.Get("session", c) if err != nil { return err } if user == nil { sess.Options = &sessions.Options{ Path: "/", MaxAge: -86400 * 7, HttpOnly: true, } if err := sess.Save(c.Request(), c.Response()); err != nil { return err } return nil } sess.Options = &sessions.Options{ Path: "/", MaxAge: 86400 * 7, HttpOnly: true, } sess.Values["userID"] = user.ID.String() if err := sess.Save(c.Request(), c.Response()); err != nil { return err } return nil } func mapUser(c echo.Context, user *models.User) error { games := make([]api.GameView, 0) for _, gc := range user.Games { games = append(games, api.GameView{ Id: gc.GameID, Title: gc.Game.Title, Description: gc.Game.Description, Type: api.MapGameTypeReverse(gc.Game.Type), }) } level := utils.ExpToLevel(user.Experience) role := api.User switch user.Role { case models.RoleUser: role = api.User case models.RoleCreator: role = api.Creator case models.RoleAdmin: role = api.Admin } return c.JSON(http.StatusOK, &api.UserResponse{ Id: user.ID, Username: user.Username, Email: user.Email, Experience: user.Experience, ExpToCurrentLevel: utils.LevelToExp(level), ExpToNextLevel: utils.LevelToExp(level + 1), Level: int(level), Games: games, Role: role, }) }