package controller import ( "log" "net/http" "github.com/google/uuid" "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) } // (GET /users) func (u *User) GetUsers(c echo.Context) error { list, err := u.UserService.List(c.Request().Context()) if err != nil { return err } result := make(api.UsersListResponse, 0, len(list)) for _, u := range list { level := utils.ExpToLevel(u.Experience) finished := 0 for _, g := range u.Games { if g.Finish { finished++ } } result = append(result, api.UserShortView{ Experience: u.Experience, GamesFinished: finished, GamesStarted: len(u.Games), Id: u.ID, Level: level, Username: u.Username, }) } return c.JSON(200, result) } // (GET /users/{uid}) func (s *User) GetUserInfo(c echo.Context, uid uuid.UUID) error { user, err := s.UserService.GetUserByID(c.Request().Context(), uid) if err != nil { log.Println(err) return echo.ErrNotFound } level := utils.ExpToLevel(user.Experience) expToCur := utils.LevelToExp(level) expToNext := utils.LevelToExp(level + 1) games := make([]api.GameView, 0, len(user.Games)) 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), Icon: gc.Game.IconID, }) } res := &api.UserShortView{ ExpToCurrentLevel: &expToCur, ExpToNextLevel: &expToNext, Experience: user.Experience, Games: &games, GamesFinished: 0, GamesStarted: 0, Id: user.ID, Level: level, Username: user.Username, } return c.JSON(200, res) } 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), Icon: gc.Game.IconID, }) } 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, }) }