Files

327 lines
9.0 KiB
Go

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