123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 |
- // Copyright 2020 github.com. All rights reserved.
- // Use of this source code is governed by github.com.
- package middleware
- import (
- "git.getensh.com/common/gopkgs/jwtwrapper"
- "github.com/dgrijalva/jwt-go"
- "github.com/gin-gonic/gin"
- "github.com/tidwall/gjson"
- "google.golang.org/grpc/codes"
- "google.golang.org/grpc/status"
- "net/http"
- "property-system-gateway/errors"
- "property-system-gateway/utils"
- "strconv"
- "strings"
- )
- // 响应数据
- type Response struct {
- Code codes.Code `json:"code" default:"1"`
- Message string `json:"message" default:"success"`
- }
- // JWT is jwt middleware
- func Jwt() gin.HandlerFunc {
- return func(c *gin.Context) {
- //fmt.Printf("xxx:%v,%v\n", c.Request.RequestURI, c.Request.Method)
- s := status.New(1, "内部服务错误")
- token := c.GetHeader("token")
- if token == "" {
- if v, ok := status.FromError(errors.NoTokenError); ok {
- s = v
- }
- c.JSON(http.StatusOK, Response{s.Code(), s.Message()})
- c.Abort()
- return
- }
- // 解析token
- claims, err := jwtwrapper.ParseToken(token)
- if err != nil {
- switch err.(*jwt.ValidationError).Errors {
- case jwt.ValidationErrorExpired:
- if v, ok := status.FromError(errors.TokenExpiredError); ok {
- s = v
- }
- default:
- if v, ok := status.FromError(errors.TokenFailedError); ok {
- s = v
- }
- }
- c.JSON(http.StatusOK, Response{s.Code(), s.Message()})
- c.Abort()
- return
- }
- // 将claims信息保存到上下文,为后续使用
- c.Set("claims", claims)
- gardenId := gjson.GetBytes([]byte(claims.Subject), "garden_id").Int()
- uid, _ := strconv.ParseInt(claims.Id, 10, 64)
- cid := gjson.GetBytes([]byte(claims.Subject), "cid").Int()
- /*
- supper := gjson.GetBytes(utils.StrToBytes(claims.Subject), "supper").Bool()
- if c.Request.Method == "PUT" || c.Request.Method == "POST" || c.Request.Method == "DELETE" {
- if supper == false && strings.Contains(c.Request.RequestURI, "/user") == false {
- c.JSON(http.StatusOK, Response{10008, "权限不足"})
- }
- }
- */
- isCompanyEnter := gjson.GetBytes([]byte(claims.Subject), "is_company_enter").Bool()
- if isCompanyEnter && !strings.Contains(c.Request.RequestURI, "user/company_login") {
- c.JSON(http.StatusOK, Response{10010, "token错误"})
- c.Abort()
- return
- }
- if isCompanyEnter && strings.Contains(c.Request.RequestURI, "user/company_login") {
- c.Next()
- return
- }
- if uid == 0 && !strings.Contains(c.Request.RequestURI, "user/choose_user") {
- c.JSON(http.StatusOK, Response{10008, "请先选择账户"})
- c.Abort()
- return
- }
- gPermissionTime := gjson.GetBytes([]byte(claims.Subject), "g_permission_time").String()
- uPermissionTime := gjson.GetBytes([]byte(claims.Subject), "u_permission_time").String()
- byCompany := gjson.GetBytes([]byte(claims.Subject), "by_company").Bool()
- // 权限变更触发重新登录
- if gardenId > 0 && gPermissionTime != gloablePermissionTime(gardenId) {
- if strings.Contains(c.Request.RequestURI, "permission_reget") {
- c.Next()
- return
- }
- c.JSON(http.StatusOK, Response{19999, "权限已变更重新获取权限"})
- c.Abort()
- return
- }
- if !byCompany && uPermissionTime != userPermissionTime(uid) {
- if strings.Contains(c.Request.RequestURI, "permission_reget") {
- c.Next()
- return
- }
- c.JSON(http.StatusOK, Response{19999, "权限已变更重新获取权限"})
- c.Abort()
- return
- }
- // 单点登录检查
- if false {
- singleSignTime := gjson.GetBytes([]byte(claims.Subject), "single_sign_time").String()
- if singleSignTime != utils.GetSingleSignTime(utils.GetSingleFlag(byCompany, cid, gardenId, uid)) &&
- !strings.Contains(c.Request.RequestURI, "user/choose_user") &&
- !strings.Contains(c.Request.RequestURI, "user/company_login") {
- c.JSON(http.StatusOK, Response{10008, "账号已在其他地方登录"})
- c.Abort()
- return
- }
- }
- // 权限检查 TODO 目前暂时放开,后续需检查权限
- super := gjson.GetBytes([]byte(claims.Subject), "is_super_group").Bool()
- if super {
- //c.Next()
- //return
- }
- if byCompany {
- //c.Next()
- //return
- }
- if c.Request.Method == "GET" {
- c.Next()
- return
- }
- if strings.Contains(c.Request.RequestURI, "openim") {
- c.Next()
- return
- }
- routers := gjson.GetBytes([]byte(claims.Subject), "routers").Map()
- err = checkPermission(routers, c.Request.RequestURI, uid, gPermissionTime, uPermissionTime)
- if err != nil {
- if v, ok := status.FromError(err); ok {
- s = v
- }
- c.JSON(http.StatusOK, Response{s.Code(), s.Message()})
- c.Abort()
- return
- }
- c.Next()
- }
- }
|