You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
sonic/handler/middleware/auth.go

93 lines
2.7 KiB
Go

package middleware
import (
"net/http"
"github.com/gin-gonic/gin"
"github.com/go-sonic/sonic/cache"
"github.com/go-sonic/sonic/consts"
"github.com/go-sonic/sonic/model/dto"
"github.com/go-sonic/sonic/model/property"
"github.com/go-sonic/sonic/service"
"github.com/go-sonic/sonic/util/xerr"
)
type AuthMiddleware struct {
OptionService service.OptionService
OneTimeTokenService service.OneTimeTokenService
UserService service.UserService
Cache cache.Cache
}
func NewAuthMiddleware(optionService service.OptionService, oneTimeTokenService service.OneTimeTokenService, cache cache.Cache, userService service.UserService) *AuthMiddleware {
authMiddleware := &AuthMiddleware{
OptionService: optionService,
OneTimeTokenService: oneTimeTokenService,
Cache: cache,
UserService: userService,
}
return authMiddleware
}
func (a *AuthMiddleware) GetWrapHandler() gin.HandlerFunc {
return func(ctx *gin.Context) {
isInstalled, err := a.OptionService.GetOrByDefaultWithErr(ctx, property.IsInstalled, false)
if err != nil {
abortWithStatusJSON(ctx, http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
return
}
if !isInstalled.(bool) {
abortWithStatusJSON(ctx, http.StatusBadRequest, "Blog is not initialized")
return
}
oneTimeToken, ok := ctx.GetQuery(consts.OneTimeTokenQueryName)
if ok {
allowedURL, ok := a.OneTimeTokenService.Get(oneTimeToken)
if !ok {
abortWithStatusJSON(ctx, http.StatusBadRequest, "OneTimeToken is not exist or expired")
return
}
currentURL := ctx.Request.URL.Path
if currentURL != allowedURL {
abortWithStatusJSON(ctx, http.StatusBadRequest, "The one-time token does not correspond the request uri")
return
}
return
}
token := ctx.GetHeader(consts.AdminTokenHeaderName)
if token == "" {
abortWithStatusJSON(ctx, http.StatusUnauthorized, "未登录,请登录后访问")
return
}
userID, ok := a.Cache.Get(cache.BuildTokenAccessKey(token))
if !ok || userID == nil {
abortWithStatusJSON(ctx, http.StatusUnauthorized, "Token 已过期或不存在")
return
}
user, err := a.UserService.GetByID(ctx, userID.(int32))
if xerr.GetType(err) == xerr.NoRecord {
_ = ctx.Error(err)
abortWithStatusJSON(ctx, http.StatusUnauthorized, "用户不存在")
return
}
if err != nil {
_ = ctx.Error(err)
abortWithStatusJSON(ctx, http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
return
}
ctx.Set(consts.AuthorizedUser, user)
}
}
func abortWithStatusJSON(ctx *gin.Context, status int, message string) {
ctx.AbortWithStatusJSON(status, &dto.BaseDTO{
Status: status,
Message: message,
})
}