update api.go, auth.go, docs.go, handler.go, service.go, swagger.json, swagger.yaml
This commit is contained in:
1 parent
4c8b4e9fce
commit
362a6d1041
7 files changed
+1564
No files matched your search
@@ -0,0 +1,326 @@
|
||||
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,
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"esauth/pkg/handler/oauth"
|
||||
"esauth/pkg/repository"
|
||||
"esauth/pkg/service"
|
||||
"net/http"
|
||||
|
||||
"esauth/docs"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/sirupsen/logrus"
|
||||
swaggerFiles "github.com/swaggo/files"
|
||||
ginSwagger "github.com/swaggo/gin-swagger"
|
||||
)
|
||||
|
||||
type Handler struct {
|
||||
services *service.Service
|
||||
repo *repository.Repository
|
||||
telegramOAuth *oauth.TelegramOAuth
|
||||
googleOAuth *oauth.GoogleOAuth
|
||||
}
|
||||
|
||||
func NewHandler(services *service.Service, repo *repository.Repository, telegramOAuth *oauth.TelegramOAuth, googleOAuth *oauth.GoogleOAuth) *Handler {
|
||||
return &Handler{services: services, repo: repo, telegramOAuth: telegramOAuth, googleOAuth: googleOAuth}
|
||||
}
|
||||
|
||||
// @title EasyStartup Auth
|
||||
// @version 1.0
|
||||
// @description Auth server for EasyStartup.
|
||||
//
|
||||
// @contact.name API Support
|
||||
// @contact.email red.tea.dev@gmail.com
|
||||
//
|
||||
// @host auth.easystartup.su
|
||||
// @BasePath /api
|
||||
//
|
||||
|
||||
func (h *Handler) InitRoutes() *gin.Engine {
|
||||
router := gin.New()
|
||||
docs.SwaggerInfo.BasePath = "/"
|
||||
router.StaticFS("/static", http.Dir("./public/resources"))
|
||||
router.LoadHTMLGlob("public/html/*")
|
||||
|
||||
router.GET("/", func(c *gin.Context) {
|
||||
c.HTML(http.StatusOK, "index.html", gin.H{
|
||||
"botId": h.telegramOAuth.BotId,
|
||||
})
|
||||
})
|
||||
router.GET("/google-callback", func(c *gin.Context) {
|
||||
c.HTML(http.StatusOK, "google-callback.html", gin.H{})
|
||||
})
|
||||
router.GET("/telegram-callback", func(c *gin.Context) {
|
||||
c.HTML(http.StatusOK, "telegram-callback.html", gin.H{})
|
||||
})
|
||||
|
||||
router.GET("/telegram-callback-process", h.telegramOAuth.HandleTelegramOAuthCallback)
|
||||
router.GET("/google-callback-process", h.googleOAuth.HandleGoogleCallback)
|
||||
router.GET("/redir/google", func(c *gin.Context) {
|
||||
url := h.googleOAuth.GoogleOauthConfig.AuthCodeURL(oauth.GOOGLE_RANDOM_STATE)
|
||||
logrus.Info(url)
|
||||
c.Redirect(http.StatusTemporaryRedirect, url)
|
||||
})
|
||||
|
||||
api := router.Group("/api", h.userIdentity)
|
||||
{
|
||||
api.GET("user/self", h.profile)
|
||||
api.POST("user/self", h.edit)
|
||||
api.GET("user/all", h.all)
|
||||
api.GET("user/count", h.count)
|
||||
api.GET("user/infinity-token", h.infinityToken)
|
||||
api.PUT("user", h.create)
|
||||
api.GET("user/:id", h.userById)
|
||||
api.POST("user/:id", h.editById)
|
||||
api.DELETE("user/:id", h.delete)
|
||||
}
|
||||
|
||||
router.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
|
||||
return router
|
||||
}
|
||||
Reference in new issue
Block a user