-
Notifications
You must be signed in to change notification settings - Fork 43
/
init.go
120 lines (108 loc) · 3.36 KB
/
init.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
package api
import (
"encoding/hex"
"time"
"github.com/baetyl/baetyl-go/v2/json"
"github.com/baetyl/baetyl-go/v2/log"
"github.com/baetyl/baetyl-cloud/v2/common"
"github.com/baetyl/baetyl-cloud/v2/config"
"github.com/baetyl/baetyl-cloud/v2/service"
)
//go:generate mockgen -destination=../mock/api/init.go -package=api github.com/baetyl/baetyl-cloud/v2/api InitAPI
type InitAPI struct {
Init service.InitService
Sign service.SignService
}
func NewInitAPI(cfg *config.CloudConfig) (*InitAPI, error) {
initService, err := service.NewInitService(cfg)
if err != nil {
return nil, err
}
signService, err := service.NewSignService(cfg)
if err != nil {
return nil, err
}
return &InitAPI{
Init: initService,
Sign: signService,
}, nil
}
func (api *InitAPI) GetResource(c *common.Context) (interface{}, error) {
resourceName := c.Param("resource")
query := &struct {
Token string `form:"token,omitempty"`
Node string `form:"node,omitempty"`
InitApplyYaml string `form:"initApplyYaml,omitempty"`
Mode string `form:"mode,omitempty"`
Path string `form:"path,omitempty"`
}{}
err := c.Bind(query)
if err != nil {
return nil, common.Error(
common.ErrRequestParamInvalid,
common.Field("error", err))
}
data, err := CheckAndParseToken(query.Token, api.Sign.GenToken)
if err != nil {
return nil, common.Error(
common.ErrRequestParamInvalid,
common.Field("error", err))
}
return api.Init.GetResource(data[service.InfoNamespace].(string), data[service.InfoName].(string), resourceName, map[string]interface{}{
"Token": query.Token,
"KubeNodeName": query.Node,
"InitApplyYaml": query.InitApplyYaml,
"Mode": query.Mode,
"BaetylHostPath": query.Path,
})
}
func CheckAndParseToken(token string, genToken func(map[string]interface{}) (string, error)) (map[string]interface{}, error) {
// check len
if len(token) < 10 {
log.L().Info("invalid token length")
return nil, common.Error(common.ErrInvalidToken)
}
// check sign
data, err := hex.DecodeString(token[10:])
if err != nil {
log.L().Info("invalid token string hex", log.Error(err))
return nil, common.Error(common.ErrInvalidToken)
}
info := map[string]interface{}{}
err = json.Unmarshal(data, &info)
if err != nil {
log.L().Info("invalid token string json", log.Error(err))
return nil, common.Error(common.ErrInvalidToken)
}
realToken, err := genToken(info)
if err != nil {
log.L().Info("invalid token struct", log.Error(err))
return nil, common.Error(common.ErrInvalidToken)
}
if realToken != token {
log.L().Info("token not match", log.Error(err))
return nil, common.Error(common.ErrInvalidToken)
}
_, ok := info[service.InfoNamespace].(string)
if !ok {
log.L().Info("invalid token no namespace", log.Error(err))
return nil, common.Error(common.ErrInvalidToken)
}
_, ok = info[service.InfoName].(string)
if !ok {
log.L().Info("invalid token no node name", log.Error(err))
return nil, common.Error(common.ErrInvalidToken)
}
expiry, ok := info[service.InfoExpiry].(float64)
if !ok {
log.L().Info("invalid token no expiry", log.Error(err))
return nil, common.Error(common.ErrInvalidToken)
}
// check expiration
timestamp := time.Unix(int64(expiry), 0)
if timestamp.Unix() < time.Now().Unix() {
log.L().Info("token expired", log.Error(err))
return nil, common.Error(common.ErrInvalidToken)
}
return info, nil
}