forked from chanyipiaomiao/devops-api
/
token.go
172 lines (142 loc) · 3.83 KB
/
token.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
package common
import (
"fmt"
"github.com/astaxie/beego"
"github.com/chanyipiaomiao/hltool"
)
const (
// 存放token的表名
tokenTableName = "token"
)
// Token 结构体
type Token struct{
TokenDb *hltool.BoltDB
SignString string
}
// NewToken 返回Token对象
func NewToken() (*Token, error) {
tokenDb, err := hltool.NewBoltDB(DBPath, tokenTableName)
if err != nil {
return nil, err
}
signString := beego.AppConfig.String("security::jwtokenSignString")
if signString == "" {
return nil, fmt.Errorf("warning: in conf file jwtokenSignString must not null")
}
return &Token{TokenDb:tokenDb, SignString: signString}, nil
}
// GetToken 根据name获取token
func (t *Token) GetToken(name string) (map[string][]byte, error) {
result, err := t.TokenDb.Get([]string{name})
if err != nil {
return nil, fmt.Errorf("get token < %s > error: %s", name, err)
}
return result, nil
}
// IsExistToken token 是否存在
// name token的名称
func (t *Token) IsExistToken(name string) (bool, error) {
result, err := t.GetToken(name)
if err != nil {
return false, err
}
if _, ok := result[name]; !ok {
return false, nil
}
if string(result[name]) != "" {
return true, fmt.Errorf("exist < %s > token", name)
}
return false, nil
}
// IsTokenValid token是否有效
func (t *Token) IsTokenValid(token string) (bool, error) {
jwt := hltool.NewJWToken(t.SignString)
parseToken, err := jwt.ParseJWToken(token)
if err != nil {
return false, err
}
tokenName := parseToken["name"].(string)
dbToken, err := t.GetToken(tokenName)
if err != nil {
return false, err
}
if _, ok := dbToken[tokenName]; !ok {
return false, fmt.Errorf("token is not exist")
}
if string(dbToken[tokenName]) == token {
return true, nil
}
return false, fmt.Errorf("token is not valid")
}
// IsRootToken 是否是root token,root token 不能被用来请求
func (t *Token) IsRootToken(token string) (bool, error) {
jwt := hltool.NewJWToken(t.SignString)
parseToken, err := jwt.ParseJWToken(token)
if err != nil {
return false, err
}
tokenName := parseToken["name"].(string)
return tokenName == "root", nil
}
// DeleteToken 删除Token
// name token名称
func (t *Token) DeleteToken(rootToken, name string) error {
if name == "root" {
return fmt.Errorf("can't delete root token")
}
if rootToken == "" {
return fmt.Errorf("need root token")
}
if ok, err := t.IsTokenValid(rootToken); !ok {
return err
}
r, err := t.IsExistToken(name)
if r {
err = t.TokenDb.Delete([]string{name})
if err != nil {
return fmt.Errorf("delete token < %s > error: %s", name, err)
}
fmt.Printf("delete token <%s> ok.\n", name)
return nil
}
return fmt.Errorf("token < %s > not exist", name)
}
// AddToken 生成一个root token 用于管理其他的token
// rootToken root token 创建其他token 需要root token
// name token的名称: root token名为: root , 其他token: 指定的名称
func (t *Token) AddToken(rootToken, name string) error {
if name != "root" && rootToken == "" {
return fmt.Errorf("warning: need root token")
}
if rootToken != "" {
if ok, err := t.IsTokenValid(rootToken); !ok {
return err
}
}
tokenValue := map[string]interface{}{
"name": name,
"updateTime": hltool.GetNowTimeStamp(),
}
jwt := hltool.NewJWToken(t.SignString)
token, err := jwt.GenJWToken(tokenValue)
if err != nil {
return err
}
t.TokenDb.Set(map[string][]byte{
name: []byte(token),
})
fmt.Printf("warning: For < %s > token only shows once, keep in mind!!! \n", name)
fmt.Printf("\t %s \n", token)
return nil
}
// AddRootToken 创建一个root token
// forceRefresh: 是否强制刷新 root token
func (t *Token) AddRootToken(forceRefresh bool) error {
if !forceRefresh {
r, err := t.IsExistToken("root")
if r {
return fmt.Errorf("%s, you can add --refresh-root-token refresh root token", err)
}
}
return t.AddToken("", "root")
}