/
tokenmanager.go
123 lines (107 loc) · 3.21 KB
/
tokenmanager.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
/*
* Copyright (c) 2023 Lark Technologies Pte. Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package core
import (
"context"
"encoding/json"
"fmt"
"net/http"
"time"
)
var tokenManager TokenManager = TokenManager{cache: cache}
type TokenManager struct {
cache Cache
}
func (m *TokenManager) getAccessToken(ctx context.Context, config *Config) (string, error) {
token, err := m.get(ctx, accessTokenKey(config.AppID))
if err != nil {
return "", err
}
if token == "" {
token, err = m.getAccessTokenThenCache(ctx, config, int(config.AccessTokenType))
if err != nil {
return "", err
}
return token, nil
}
return token, nil
}
func (m *TokenManager) set(ctx context.Context, key, value string, ttl time.Duration) error {
return m.cache.Set(ctx, key, value, ttl)
}
func (m *TokenManager) get(ctx context.Context, tokenKey string) (string, error) {
token, err := m.cache.Get(ctx, tokenKey)
return token, err
}
type GetAccessTokenReq struct {
PluginId string `json:"plugin_id"`
PluginSecret string `json:"plugin_secret"`
Type int `json:"type"`
}
type AccessToken struct {
ExpireTime int `json:"expire_time"`
Token string `json:"token"`
}
type GetAccessTokenResp struct {
*APIResp `json:"-"`
Error *AccessTokenErr `json:"error"`
Data *AccessToken `json:"data"`
}
func (t *GetAccessTokenResp) Success() bool {
return t.Error.Code == 0
}
type MarketplaceAppAccessTokenReq struct {
AppID string `json:"app_id"`
AppSecret string `json:"app_secret"`
AppTicket string `json:"app_ticket"`
}
type MarketplaceTenantAccessTokenReq struct {
AppAccessToken string `json:"app_access_token"`
TenantKey string `json:"tenant_key"`
}
func accessTokenKey(appID string) string {
return fmt.Sprintf("%s-%s", accessTokenKeyPrefix, appID)
}
func (m *TokenManager) getAccessTokenThenCache(ctx context.Context, config *Config, tokenType int) (string, error) {
rawResp, err := Request(ctx, &APIReq{
HttpMethod: http.MethodPost,
ApiPath: PluginAccessTokenInternalUrlPath,
Body: &GetAccessTokenReq{
PluginId: config.AppID,
PluginSecret: config.AppSecret,
Type: tokenType,
},
SkipAuth: true,
}, config)
if err != nil {
return "", err
}
resp := &GetAccessTokenResp{}
err = json.Unmarshal(rawResp.RawBody, resp)
if err != nil {
return "", err
}
if resp.Error.Code != 0 {
config.Logger.Warn(ctx, fmt.Sprintf("get accessToken err:%v", Prettify(resp)))
return "", resp.Error
}
expire := time.Duration(resp.Data.ExpireTime)*time.Second - expiryDelta
err = m.set(ctx, accessTokenKey(config.AppID), resp.Data.Token, expire)
if err != nil {
config.Logger.Warn(ctx, fmt.Sprintf("accessToken save cache, err:%v", err))
}
return resp.Data.Token, err
}