// Copyright (c) 2021. Huawei Technologies Co., Ltd. All rights reserved.

// Package common the common package of the program
package common

import (
"errors"
"github.com/gin-gonic/gin"
"golang.org/x/net/context"
"huawei.com/npu-exporter/hwlog"
"net/http"
"strconv"
)

const (
base = 10
bitSize = 64

// HeaderUserIDKey HeaderUserIDKey
HeaderUserIDKey = "UserID"
// HeaderGroupIDKey HeaderGroupIDKey
HeaderGroupIDKey = "GroupID"
// HeaderRoleIDKey HeaderRoleIDKey
HeaderRoleIDKey = "RoleID"
// HeaderRequestIDKey HeaderRequestIDKey
HeaderRequestIDKey = "RequestID"
// HeaderRoleCodeKey HeaderRoleCodeKey
HeaderRoleCodeKey = "RoleCode"
)

// RespMsg response msg
type RespMsg struct {
Status string `json:"status"`
Msg string `json:"msg"`
Data interface{} `json:"data,omitempty"`
}

// HeaderInfo header struct
type HeaderInfo struct {
TraceID string `sql:"-" json:"requestID,omitempty"`
UserID uint64 `gorm:"" json:"userId,omitempty"`
GroupID uint64 `gorm:"" json:"groupId,omitempty"`
RoleID uint64 `sql:"-" json:"roleId,omitempty"`
RoleCode string `sql:"-" json:"roleCode,omitempty"`
}

// ConstructResp construct response
func ConstructResp(c *gin.Context, errorCode string, msg string, data interface{}) {
ConstructRespWithStatus(c, errorCode, msg, data, http.StatusOK)
}

// ConstructRespWithStatus construct response
func ConstructRespWithStatus(c *gin.Context, errorCode string, msg string, data interface{}, status int) {
if msg == "" {
msg = ErrorMap[errorCode]
}
result := RespMsg{
Status: errorCode,
Msg: msg,
Data: data,
}
c.JSON(status, result)
}

// GetHeaderInfo get header info
func GetHeaderInfo(c *gin.Context) (HeaderInfo, string, error) {
var hInfo HeaderInfo
uuid := c.GetHeader(HeaderRequestIDKey)
hInfo.TraceID = uuid
userIDStr := c.GetHeader(HeaderUserIDKey)
if userIDStr == "" {
return HeaderInfo{}, ErrorNotFoundUserID, errors.New("no login")
}
userID, err := strconv.ParseUint(userIDStr, base, bitSize)
if err != nil {
return HeaderInfo{}, ErrorConvertStr2Uint, errors.New("convert userID failed")
}
hInfo.UserID = userID
groupIDStr := c.GetHeader(HeaderGroupIDKey)
if groupIDStr == "" {
return hInfo, ErrorNotFoundGroupID, errors.New("not found groupID")
}
groupID, err := strconv.ParseUint(groupIDStr, base, bitSize)
if err != nil {
return HeaderInfo{}, ErrorConvertStr2Uint, errors.New("convert groupID failed")
}
hInfo.GroupID = groupID
roleIDStr := c.GetHeader(HeaderRoleIDKey)
if roleIDStr == "" {
return hInfo, ErrorNotFoundRoleID, errors.New("not found roleID")
}
roleID, err := strconv.ParseUint(roleIDStr, base, bitSize)
if err != nil {
return HeaderInfo{}, ErrorConvertStr2Uint, errors.New("convert groupID failed")
}
hInfo.RoleID = roleID
code := c.GetHeader(HeaderRoleCodeKey)
hInfo.RoleCode = code
return hInfo, "", nil
}

// BaseCtx the base of all controller
type BaseCtx struct {
Ctx context.Context
HdInfo HeaderInfo
}

// WrapHeader check and wrap the header parameter
func WrapHeader() gin.HandlerFunc {
return func(c *gin.Context) {
hInfo, errorCode, err := GetHeaderInfo(c)
if err != nil {
hwlog.OpLog.Error(err)
c.Abort()
ConstructRespWithStatus(c, errorCode, err.Error(), nil, http.StatusUnauthorized)
return
}
ctx := context.WithValue(context.TODO(), hwlog.ReqID, hInfo.TraceID)
ctx = context.WithValue(ctx, hwlog.UserID, hInfo.UserID)
baseCtx := BaseCtx{
Ctx: ctx,
HdInfo: hInfo,
}
c.Set("Ctx", baseCtx)
}
}

// Convert extract the baseCtx from gin.context and use as a parameter
func Convert(f func(b BaseCtx, c *gin.Context)) gin.HandlerFunc {
return func(c *gin.Context) {
baseCtx, ok := c.Get("Ctx")
if !ok {
ConstructResp(c, ErrNoLoginInfo, "", nil)
}
b, err := baseCtx.(BaseCtx)
if !err {
ConstructResp(c, ErrTypeConvert, "", nil)
}
f(b, c)
}
}

mindxdl--common--head_handler.go的更多相关文章

  1. Socket聊天程序——Common

    写在前面: 上一篇记录了Socket聊天程序的客户端设计,为了记录的完整性,这里还是将Socket聊天的最后一个模块--Common模块记录一下.Common的设计如下: 功能说明: Common模块 ...

  2. angularjs 1 开发简单案例(包含common.js,service.js,controller.js,page)

    common.js var app = angular.module('app', ['ngFileUpload']) .factory('SV_Common', function ($http) { ...

  3. Common Bugs in C Programming

    There are some Common Bugs in C Programming. Most of the contents are directly from or modified from ...

  4. ANSI Common Lisp Practice - My Answers - Chatper - 3

    Ok, Go ahead. 1 (a) (b) (c) (d) 2 注:union 在 Common Lisp 中的作用就是求两个集合的并集.但是这有一个前提,即给的两个列表已经满足集合的属性了.具体 ...

  5. [LeetCode] Lowest Common Ancestor of a Binary Tree 二叉树的最小共同父节点

    Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree. According ...

  6. [LeetCode] Lowest Common Ancestor of a Binary Search Tree 二叉搜索树的最小共同父节点

    Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BS ...

  7. [LeetCode] Longest Common Prefix 最长共同前缀

    Write a function to find the longest common prefix string amongst an array of strings. 这道题让我们求一系列字符串 ...

  8. 48. 二叉树两结点的最低共同父结点(3种变种情况)[Get lowest common ancestor of binary tree]

    [题目] 输入二叉树中的两个结点,输出这两个结点在数中最低的共同父结点. 二叉树的结点定义如下:  C++ Code  123456   struct BinaryTreeNode {     int ...

  9. 动态规划求最长公共子序列(Longest Common Subsequence, LCS)

    1. 问题描述 子串应该比较好理解,至于什么是子序列,这里给出一个例子:有两个母串 cnblogs belong 比如序列bo, bg, lg在母串cnblogs与belong中都出现过并且出现顺序与 ...

  10. 【leetcode】Longest Common Prefix

    题目简述: Write a function to find the longest common prefix string amongst an array of strings. 解题思路: c ...

随机推荐

  1. KingbaseES时间函数的比较

    KingbaseES提供了多种的时间函数,这些函数在使用过程中存在哪些不同? **同一事务** test=# begin test-# for i in 1.. 10 loop test-# rais ...

  2. Pytest fixture及conftest详解

    前言 fixture是在测试函数运行前后,由pytest执行的外壳函数.fixture中的代码可以定制,满足多变的测试需求,包括定义传入测试中的数据集.配置测试前系统的初始状态.为批量测试提供数据源等 ...

  3. WSUS无法发现客户端

    这几天遇到一个问题,刚装好的WSUS服务器同步完补丁后,打算上线使用.挑了几个客户端,使用注册表配置了WSUS,但是迟迟无法在控制台上看到这些客户端.由于部分客户端不在域中,无法使用组策略配置,就写了 ...

  4. MySQL8.0报错:Access denied; you need (at least one of) the SYSTEM_USER privilege(s) for this operation

    MySQL8.0.16版本中新增了一个system_user帐户类型,当新增用户并赋予权限时 mysql> create user 'proxysql'@'192.168.20.%' ident ...

  5. KVM 下如何关闭 virbr0

    安装KVM 后都会发现网络接口里多了一个叫做 virbr0 的虚拟网络接口: 这是由于安装和启用了 libvirt 服务后生成的,libvirt 在服务器(host)上生成一个 virtual net ...

  6. Centos7搭建 KVM 环境

    注意:使用KVM管理虚拟机分命令行和图形化界面两种方式,这里最后一步安装的工具是图形化管理工具 安装前准备 验证CPU是否支持KVM 如果结果中有vmx(Intel)或svm(AMD)字样,就说明CP ...

  7. 最佳实践:4个黄金指标和USE方法

    Prometheus鼓励用户监控所有的东西,首先是及时发现问题其次是要能够快速对问题进行定位. 4个黄金指标 4个黄金指标可以在服务级别帮助衡量终端用户体验.服务中断.业务影响等层面的问题. 主要关注 ...

  8. @property装饰器和property()函数

    @property装饰器 Python内置的@property装饰器可以把类的方法伪装成属性调用的方式.也就是本来是Foo.func()的调用方法,变成Foo.func的方式. class Peopl ...

  9. MyCLI :一个支持自动补全和语法高亮的 MySQL/MariaDB 客户端

    MyCLI 是一个易于使用的命令行客户端,可用于受欢迎的数据库管理系统 MySQL.MariaDB 和 Percona,支持自动补全和语法高亮.它是使用 prompt_toolkit 库写的,需要 P ...

  10. Git使用与心得体会

    Git使用与心得体会 一.闲聊 闲暇时间学一下Git,也算是不用在网页端操作github了 二.Git相关 集中式与分布式 Git是一个分布式的版本控制系统,而传统的SVN则属于集中式 集中式与分布式 ...