github.com/OrigamiWang/msd/micro@v0.0.0-20240229032328-b62246268db9/midware/posthandler.go (about)

     1  package midware
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/OrigamiWang/msd/micro/auth"
     6  	"github.com/OrigamiWang/msd/micro/const/errcode"
     7  	"github.com/OrigamiWang/msd/micro/model"
     8  	"github.com/OrigamiWang/msd/micro/model/errx"
     9  	"github.com/OrigamiWang/msd/micro/util"
    10  	logutil "github.com/OrigamiWang/msd/micro/util/log"
    11  	"github.com/gin-gonic/gin"
    12  	"github.com/gin-gonic/gin/render"
    13  	"net/http"
    14  	"reflect"
    15  	"runtime"
    16  	"strings"
    17  	"time"
    18  )
    19  
    20  type PostHandlerFunc func(c *gin.Context, req interface{}) (resp interface{}, err errx.ErrX)
    21  
    22  type HandlerReqBinder func() (req interface{})
    23  
    24  func PostHandler(handlerfunc PostHandlerFunc, binder ...HandlerReqBinder) gin.HandlerFunc {
    25  	return func(c *gin.Context) {
    26  		start := time.Now()
    27  		funcName := runtime.FuncForPC(reflect.ValueOf(handlerfunc).Pointer()).Name()
    28  
    29  		var resp interface{}
    30  		var err errx.ErrX
    31  		if len(binder) > 0 {
    32  			req := binder[0]()
    33  			bindErr := c.BindJSON(req)
    34  			if bindErr != nil {
    35  				logutil.Error("PostHandler. handler begin, Bind json failed, funcName: %v, error: %v", funcName, bindErr)
    36  				c.JSON(http.StatusOK, &model.Response{Code: errcode.WrongArgs, Ts: fmt.Sprintf("%v", time.Now().Unix()), Msg: "Wrong argument"})
    37  				return
    38  			}
    39  			logutil.Info("PostHandler. handler begin, funcName: %v, req: %s", funcName, util.ReflectToString(req))
    40  			resp, err = handlerfunc(c, req)
    41  		} else {
    42  			logutil.Info("PostHandler. handler begin, funcName: %v, req: <nil>", funcName)
    43  			resp, err = handlerfunc(c, nil)
    44  		}
    45  		if err == nil {
    46  			c.Render(http.StatusOK, render.JSON{Data: &model.Response{Code: errcode.Success, Ts: fmt.Sprintf("%v", time.Now().Unix()), Msg: "Success", Data: resp}})
    47  			logutil.Info("PostHandler. handler finish, funcName: %v, code: %v, msg: %v. elapse: %v", funcName, errcode.Success, "success", time.Since(start))
    48  			logutil.Debug("PostHandler. handler finish, funcName: %v, resp: %+v", funcName, util.ReflectToString(resp))
    49  		} else {
    50  			c.JSON(http.StatusOK, &model.Response{Code: err.Code(), Ts: fmt.Sprintf("%v", time.Now().Unix()), Msg: err.Error(), Data: resp})
    51  			logutil.Info("PostHandler. handler finish, funcName: %v, code: %v, msg: %v. elapse: %v", funcName, err.Code(), err.Error(), time.Since(start))
    52  			logutil.Debug("PostHandler. handler finish, funcName: %v, resp: %+v", funcName, util.ReflectToString(resp))
    53  		}
    54  		c.Next()
    55  	}
    56  }
    57  
    58  func PostHandlerWithJwt(handlerfunc PostHandlerFunc, binder ...HandlerReqBinder) gin.HandlerFunc {
    59  	return func(c *gin.Context) {
    60  		start := time.Now()
    61  		funcName := runtime.FuncForPC(reflect.ValueOf(handlerfunc).Pointer()).Name()
    62  
    63  		// check the jwt token
    64  		// Authorization: 'Bearer JwtToken'
    65  		authorization := c.GetHeader("Authorization")
    66  		m, e := checkJwt(authorization)
    67  		if e != nil {
    68  			logutil.Error("check jwt failed, err: %v", e)
    69  			c.JSON(http.StatusOK, &model.Response{Code: errcode.WrongJwt, Ts: fmt.Sprintf("%v", time.Now().Unix()), Msg: "Wrong jwt"})
    70  			return
    71  		}
    72  		uid := m["uid"].(int)
    73  		uname := m["uname"].(string)
    74  		logutil.Info("check jwt success, uid: %v, uname: %v", uid, uname)
    75  
    76  		var resp interface{}
    77  		var err errx.ErrX
    78  		if len(binder) > 0 {
    79  
    80  			// get request body
    81  			req := binder[0]()
    82  			bindErr := c.BindJSON(req)
    83  			if bindErr != nil {
    84  				logutil.Error("PostHandler. handler begin, Bind json failed, funcName: %v, error: %v", funcName, bindErr)
    85  				c.JSON(http.StatusOK, &model.Response{Code: errcode.WrongArgs, Ts: fmt.Sprintf("%v", time.Now().Unix()), Msg: "Wrong argument"})
    86  				return
    87  			}
    88  			logutil.Info("PostHandler. handler begin, funcName: %v, req: %s", funcName, util.ReflectToString(req))
    89  			resp, err = handlerfunc(c, req)
    90  		} else {
    91  			logutil.Info("PostHandler. handler begin, funcName: %v, req: <nil>", funcName)
    92  			resp, err = handlerfunc(c, nil)
    93  		}
    94  		if err == nil {
    95  			c.Render(http.StatusOK, render.JSON{Data: &model.Response{Code: errcode.Success, Ts: fmt.Sprintf("%v", time.Now().Unix()), Msg: "Success", Data: resp}})
    96  			logutil.Info("PostHandler. handler finish, funcName: %v, code: %v, msg: %v. elapse: %v", funcName, errcode.Success, "success", time.Since(start))
    97  			logutil.Debug("PostHandler. handler finish, funcName: %v, resp: %+v", funcName, util.ReflectToString(resp))
    98  		} else {
    99  			c.JSON(http.StatusOK, &model.Response{Code: err.Code(), Ts: fmt.Sprintf("%v", time.Now().Unix()), Msg: err.Error(), Data: resp})
   100  			logutil.Info("PostHandler. handler finish, funcName: %v, code: %v, msg: %v. elapse: %v", funcName, err.Code(), err.Error(), time.Since(start))
   101  			logutil.Debug("PostHandler. handler finish, funcName: %v, resp: %+v", funcName, util.ReflectToString(resp))
   102  		}
   103  		c.Next()
   104  	}
   105  }
   106  
   107  func checkJwt(authorization string) (map[string]interface{}, error) {
   108  	if authorization == "" {
   109  		logutil.Error("the authorization is nil")
   110  		return nil, fmt.Errorf("the authorization is nil")
   111  	}
   112  	arr := strings.Split(authorization, " ")
   113  	// invalid
   114  	if arr == nil || len(arr) != 2 || arr[0] != "Bearer" {
   115  		logutil.Error("invalid request")
   116  		return nil, fmt.Errorf("invalid request")
   117  	}
   118  	jwtToken := arr[1]
   119  	uid, uname, err := auth.Authenticate(jwtToken)
   120  	if err != nil {
   121  		logutil.Error("cli. jwt token authenticate failed, err: %v", err)
   122  		return nil, err
   123  	}
   124  	m := make(map[string]interface{})
   125  	m["uid"] = uid
   126  	m["uname"] = uname
   127  	return m, nil
   128  }