package handler import ( "esauth" "esauth/pkg/util" "net/http" "net/mail" "strconv" "github.com/gin-gonic/gin" ) // user godoc // @Summary Get current user // @Tags user // @Produce json // @Param Authorization header string true "JWT Bearer token (authorization)" // @Success 200 {object} esauth.User // @Router /api/user/self [get] func (h *Handler) profile(c *gin.Context) { id, _ := c.Get(userCtx) user, err := h.repo.GetUser(id.(int64)) if err != nil { util.NewErrorResponse(c, http.StatusNotFound, err.Error()) return } c.JSON(http.StatusOK, user) } // user/{user} godoc // @Summary Get user by id // @Tags user // @Produce json // @Param user path int true "search user by id" // @Param Authorization header string true "JWT Bearer token (authorization)" // @Success 200 {object} esauth.User // @Router /api/user/{user} [get] func (h *Handler) userById(c *gin.Context) { current, _ := c.Get(userCtx) currentUser, err := h.repo.GetUser(current.(int64)) if (err != nil) || (currentUser.Access != "admin") { util.NewErrorResponse(c, http.StatusForbidden, err.Error()) return } id, err := strconv.ParseInt(c.Param("id"), 10, 64) if err != nil { util.NewErrorResponse(c, http.StatusBadRequest, err.Error()) return } user, err := h.repo.GetUser(id) if err != nil { util.NewErrorResponse(c, http.StatusBadRequest, err.Error()) return } c.JSON(http.StatusOK, user) } type editInput struct { Username string `json:"username"` FirstName string `json:"first_name"` LastName string `json:"last_name"` Email string `json:"email"` PictureURL string `json:"picture_url"` } // user/self godoc // @Summary Edit user // @Tags user // @Produce json // @Success 200 {object} esauth.User // @Param user body handler.editInput true "User description JSON" // @Param Authorization header string true "JWT Bearer token (authorization)" // @Router /api/user/self [post] func (h *Handler) edit(c *gin.Context) { id, _ := c.Get(userCtx) user, err := h.repo.GetUser(id.(int64)) if err != nil { util.NewErrorResponse(c, http.StatusBadRequest, err.Error()) return } var input editInput if err := c.BindJSON(&input); err != nil { util.NewErrorResponse(c, http.StatusBadRequest, err.Error()) return } if input.Username != "" { user.Username = input.Username } if input.FirstName != "" { user.FirstName = input.FirstName } if input.LastName != "" { user.LastName = input.LastName } if input.Email != "" { if valid(input.Email) { user.Email = input.Email } else { util.NewErrorResponse(c, http.StatusBadRequest, "email is invalid") return } } if input.PictureURL != "" { user.PictureURL = input.PictureURL } if _, err = h.repo.SaveUser(&user); err != nil { util.NewErrorResponse(c, http.StatusBadRequest, err.Error()) return } c.JSON(http.StatusOK, user) } // user/{user} godoc // @Summary Edit user by id // @Tags user // @Produce json // @Param user path int true "edit user by id" // @Param user body esauth.User true "User data in JSON" // @Param Authorization header string true "JWT Bearer token (authorization)" // @Success 200 {object} esauth.User // @Router /api/user/{user} [post] func (h *Handler) editById(c *gin.Context) { current, _ := c.Get(userCtx) currentUser, err := h.repo.GetUser(current.(int64)) if (err != nil) || (currentUser.Access != "admin") { util.NewErrorResponse(c, http.StatusForbidden, err.Error()) return } id, _ := strconv.ParseInt(c.Param("id"), 10, 64) _, err = h.repo.GetUser(id) if err != nil { util.NewErrorResponse(c, http.StatusBadRequest, err.Error()) return } var input esauth.User if err := c.BindJSON(&input); err != nil { util.NewErrorResponse(c, http.StatusBadRequest, err.Error()) return } if input.Email != "" { if !valid(input.Email) { util.NewErrorResponse(c, http.StatusBadRequest, "email is invalid") return } } if _, err = h.repo.SaveUser(&input); err != nil { util.NewErrorResponse(c, http.StatusBadRequest, err.Error()) return } c.JSON(http.StatusOK, input) } func valid(email string) bool { _, err := mail.ParseAddress(email) return err == nil } // user/all godoc // @Summary Get ids of users // @Tags user // @Produce json // @Param limit query int true "limit of users size" // @Param start query int true "select offset" // @Param Authorization header string true "JWT Bearer token (authorization)" // @Success 200 {array} int // @Router /api/user/all [get] func (h *Handler) all(c *gin.Context) { current, _ := c.Get(userCtx) currentUser, err := h.repo.GetUser(current.(int64)) if (err != nil) || (currentUser.Access != "admin") { util.NewErrorResponse(c, http.StatusForbidden, err.Error()) return } limit, err := strconv.Atoi(c.Query("limit")) if err != nil { util.NewErrorResponse(c, http.StatusBadRequest, err.Error()) return } start, err := strconv.Atoi(c.Query("start")) if err != nil { util.NewErrorResponse(c, http.StatusBadRequest, err.Error()) return } c.JSON(http.StatusOK, h.repo.GetUsers(start, limit)) } // user/{user} godoc // @Summary Delete user by id // @Tags user // @Produce json // @Param id path int true "id of user" // @Param Authorization header string true "JWT Bearer token (authorization)" // @Success 200 // @Router /api/user/{user} [delete] func (h *Handler) delete(c *gin.Context) { current, _ := c.Get(userCtx) currentUser, err := h.repo.GetUser(current.(int64)) if (err != nil) || (currentUser.Access != "admin") { util.NewErrorResponse(c, http.StatusForbidden, err.Error()) return } id, _ := strconv.ParseInt(c.Param("id"), 10, 64) _, err = h.repo.GetUser(id) if err != nil { util.NewErrorResponse(c, http.StatusBadRequest, err.Error()) return } err = h.repo.DeleteUser(id) if err != nil { util.NewErrorResponse(c, http.StatusInternalServerError, err.Error()) return } c.JSON(http.StatusOK, "{ \"status\": \"ok\" }") } type countResponse struct { Count int64 `json:"count"` } // user/count godoc // @Summary Get count of users // @Tags user // @Produce json // @Param Authorization header string true "JWT Bearer token (authorization)" // @Success 200 {object} handler.countResponse // @Router /api/user/count [get] func (h *Handler) count(c *gin.Context) { current, _ := c.Get(userCtx) currentUser, err := h.repo.GetUser(current.(int64)) if (err != nil) || (currentUser.Access != "admin") { util.NewErrorResponse(c, http.StatusForbidden, err.Error()) return } c.JSON(http.StatusOK, countResponse{Count: h.repo.GetUsersCount()}) } // user/ godoc // @Summary Create new user // @Tags user // @Produce json // @Param user body esauth.User true "User data in JSON" // @Param Authorization header string true "JWT Bearer token (authorization)" // @Success 200 {object} esauth.User // @Router /api/user [put] func (h *Handler) create(c *gin.Context) { current, _ := c.Get(userCtx) currentUser, err := h.repo.GetUser(current.(int64)) if (err != nil) || (currentUser.Access != "admin") { util.NewErrorResponse(c, http.StatusForbidden, err.Error()) return } var input esauth.User if err := c.BindJSON(&input); err != nil { util.NewErrorResponse(c, http.StatusBadRequest, err.Error()) return } if input.Email != "" { if !valid(input.Email) { util.NewErrorResponse(c, http.StatusBadRequest, "email is invalid") return } } var id int64 if id, err = h.repo.CreateUser(&input); err != nil { util.NewErrorResponse(c, http.StatusBadRequest, err.Error()) return } var user esauth.User if user, err = h.repo.GetUser(id); err != nil { util.NewErrorResponse(c, http.StatusInternalServerError, err.Error()) return } c.JSON(http.StatusOK, user) } type infinityTokenResponce struct { Token string `json:"token"` } // user godoc // @Summary Create infinity token (only for admin) // @Tags user // @Produce json // @Param Authorization header string true "JWT Bearer token (authorization)" // @Success 200 {object} handler.infinityTokenResponce // @Router /api/user/infinity-token [get] func (h *Handler) infinityToken(c *gin.Context) { id, _ := c.Get(userCtx) user, err := h.repo.GetUser(id.(int64)) if err != nil { util.NewErrorResponse(c, http.StatusNotFound, err.Error()) return } if user.Access != "admin" { util.NewErrorResponse(c, http.StatusForbidden, "not admin") return } token, err := h.services.GenerateInfinityToken(user.Id) if err != nil { util.NewErrorResponse(c, http.StatusInternalServerError, err.Error()) return } c.JSON(http.StatusOK, infinityTokenResponce{ Token: token, }) }