175 lines
5.4 KiB
Go
175 lines
5.4 KiB
Go
package response
|
|
|
|
import (
|
|
"context"
|
|
"lone-services/pkg/utils"
|
|
"net/http"
|
|
"net/url"
|
|
"strconv"
|
|
|
|
"google.golang.org/grpc"
|
|
"google.golang.org/grpc/metadata"
|
|
)
|
|
|
|
type ctxKey string
|
|
|
|
const (
|
|
CtxUserId ctxKey = "X-User-Id"
|
|
CtxUserName ctxKey = "X-User-Name"
|
|
CtxRefresh ctxKey = "X-Refresh"
|
|
CtxClientIP ctxKey = "X-Client-Ip"
|
|
CtxUserAgent ctxKey = "X-User-Agent"
|
|
CtxClientCode ctxKey = "X-Client-Code"
|
|
CtxSaleId ctxKey = "X-Sale-Id"
|
|
CtxSaleName ctxKey = "X-Sale-Name"
|
|
CtxSaleMobile ctxKey = "X-Sale-Mobile"
|
|
CtxSaleProvince ctxKey = "X-Sale-Province"
|
|
CtxStoreId ctxKey = "X-Store-Id"
|
|
CtxStoreName ctxKey = "X-Store-Name"
|
|
CtxGroupId ctxKey = "X-Group-Id"
|
|
CtxGroupName ctxKey = "X-Group-Name"
|
|
CtxUserType ctxKey = "X-User-Type"
|
|
)
|
|
|
|
type UserInfo struct {
|
|
ID int64
|
|
Name string
|
|
RawUID string
|
|
Refresh string
|
|
ClientIP string
|
|
UserAgent string
|
|
Type string
|
|
ClientCode string
|
|
SaleId string
|
|
SaleName string
|
|
SaleMobile string
|
|
SaleProvince string
|
|
StoreId string
|
|
StoreName string
|
|
GroupId string
|
|
GroupName string
|
|
Valid bool
|
|
}
|
|
|
|
func GetUserInfo(ctx context.Context) UserInfo {
|
|
rawUID, _ := ctx.Value(CtxUserId).(string)
|
|
name, _ := ctx.Value(CtxUserName).(string)
|
|
refresh, _ := ctx.Value(CtxRefresh).(string)
|
|
clientIP, _ := ctx.Value(CtxClientIP).(string)
|
|
userAgent, _ := ctx.Value(CtxUserAgent).(string)
|
|
userType, _ := ctx.Value(CtxUserType).(string)
|
|
clientCode, _ := ctx.Value(CtxClientCode).(string)
|
|
saleId, _ := ctx.Value(CtxSaleId).(string)
|
|
saleName, _ := ctx.Value(CtxSaleName).(string)
|
|
saleMobile, _ := ctx.Value(CtxSaleMobile).(string)
|
|
saleProvince, _ := ctx.Value(CtxSaleProvince).(string)
|
|
storeId, _ := ctx.Value(CtxStoreId).(string)
|
|
storeName, _ := ctx.Value(CtxStoreName).(string)
|
|
groupId, _ := ctx.Value(CtxGroupId).(string)
|
|
groupName, _ := ctx.Value(CtxGroupName).(string)
|
|
|
|
info := UserInfo{
|
|
RawUID: rawUID,
|
|
Name: name,
|
|
Refresh: refresh,
|
|
ClientIP: clientIP,
|
|
UserAgent: userAgent,
|
|
Type: userType,
|
|
ClientCode: clientCode,
|
|
SaleId: saleId,
|
|
SaleName: saleName,
|
|
SaleMobile: saleMobile,
|
|
SaleProvince: saleProvince,
|
|
StoreId: storeId,
|
|
StoreName: storeName,
|
|
GroupId: groupId,
|
|
GroupName: groupName,
|
|
}
|
|
if rawUID == "" {
|
|
return info
|
|
}
|
|
uid, err := strconv.ParseInt(rawUID, 10, 64)
|
|
if err != nil {
|
|
info.Valid = false
|
|
return info
|
|
}
|
|
info.ID = uid
|
|
info.Valid = true
|
|
return info
|
|
}
|
|
|
|
func getRealClientIP(r *http.Request) string {
|
|
xff := r.Header.Get("X-Forwarded-For")
|
|
if xff != "" {
|
|
return xff
|
|
}
|
|
xri := r.Header.Get("X-Real-Ip")
|
|
if xri != "" {
|
|
return xri
|
|
}
|
|
return r.RemoteAddr
|
|
}
|
|
|
|
func UserReadMiddleware(next http.HandlerFunc) http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
newCtx := r.Context()
|
|
newCtx = context.WithValue(newCtx, CtxUserId, r.Header.Get("X-User-Id"))
|
|
newCtx = context.WithValue(newCtx, CtxUserName, r.Header.Get("X-User-Name"))
|
|
newCtx = context.WithValue(newCtx, CtxRefresh, r.Header.Get("X-Refresh"))
|
|
newCtx = context.WithValue(newCtx, CtxClientIP, getRealClientIP(r))
|
|
newCtx = context.WithValue(newCtx, CtxUserAgent, r.UserAgent())
|
|
newCtx = context.WithValue(newCtx, CtxUserType, r.Header.Get("X-User-Type"))
|
|
newCtx = context.WithValue(newCtx, CtxClientCode, r.Header.Get("X-Client-Code"))
|
|
newCtx = context.WithValue(newCtx, CtxSaleId, r.Header.Get("X-Sale-Id"))
|
|
newCtx = context.WithValue(newCtx, CtxSaleName, r.Header.Get("X-Sale-Name"))
|
|
newCtx = context.WithValue(newCtx, CtxSaleMobile, r.Header.Get("X-Sale-Mobile"))
|
|
newCtx = context.WithValue(newCtx, CtxSaleProvince, r.Header.Get("X-Sale-Province"))
|
|
newCtx = context.WithValue(newCtx, CtxStoreId, r.Header.Get("X-Store-Id"))
|
|
newCtx = context.WithValue(newCtx, CtxStoreName, r.Header.Get("X-Store-Name"))
|
|
newCtx = context.WithValue(newCtx, CtxGroupId, r.Header.Get("X-Group-Id"))
|
|
newCtx = context.WithValue(newCtx, CtxGroupName, r.Header.Get("X-Group-Name"))
|
|
next(w, r.WithContext(newCtx))
|
|
}
|
|
}
|
|
|
|
func setMDIfNotEmpty(md metadata.MD, key, value string) {
|
|
if value != utils.StringEmpty {
|
|
md.Set(key, value)
|
|
}
|
|
}
|
|
|
|
func UserClientInterceptor(ctx context.Context, method string, req, reply any, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
|
|
user := GetUserInfo(ctx)
|
|
md := metadata.New(map[string]string{})
|
|
|
|
if user.Valid {
|
|
md.Set("x-user-id", user.RawUID)
|
|
md.Set("x-user-name", url.QueryEscape(user.Name))
|
|
}
|
|
|
|
setMDIfNotEmpty(md, "x-refresh", user.Refresh)
|
|
setMDIfNotEmpty(md, "x-client-ip", user.ClientIP)
|
|
if user.UserAgent != utils.StringEmpty {
|
|
md.Set("x-user-agent", url.QueryEscape(user.UserAgent))
|
|
}
|
|
setMDIfNotEmpty(md, "x-user-type", user.Type)
|
|
setMDIfNotEmpty(md, "x-client-code", user.ClientCode)
|
|
setMDIfNotEmpty(md, "x-sale-id", user.SaleId)
|
|
if user.SaleName != utils.StringEmpty {
|
|
md.Set("x-sale-name", url.QueryEscape(user.SaleName))
|
|
}
|
|
setMDIfNotEmpty(md, "x-sale-mobile", user.SaleMobile)
|
|
setMDIfNotEmpty(md, "x-sale-province", user.SaleProvince)
|
|
setMDIfNotEmpty(md, "x-store-id", user.StoreId)
|
|
if user.StoreName != utils.StringEmpty {
|
|
md.Set("x-store-name", url.QueryEscape(user.StoreName))
|
|
}
|
|
setMDIfNotEmpty(md, "x-group-id", user.GroupId)
|
|
if user.GroupName != utils.StringEmpty {
|
|
md.Set("x-group-name", url.QueryEscape(user.GroupName))
|
|
}
|
|
|
|
ctx = metadata.NewOutgoingContext(ctx, md)
|
|
return invoker(ctx, method, req, reply, cc, opts...)
|
|
}
|