Files
message-pusher/channel/token-store.go
T

206 lines
6.1 KiB
Go
Raw Normal View History

2022-11-11 22:05:31 +08:00
package channel
import (
"message-pusher/common"
"message-pusher/model"
"sync"
"time"
)
type TokenStoreItem interface {
Key() string
Token() string
Refresh()
IsFilled() bool
2022-11-11 22:05:31 +08:00
}
type tokenStore struct {
Map map[string]*TokenStoreItem
Mutex sync.RWMutex
ExpirationSeconds int
}
var s tokenStore
func TokenStoreInit() {
s.Map = make(map[string]*TokenStoreItem)
s.ExpirationSeconds = 2 * 60 * 60
go func() {
2022-11-18 17:17:53 +08:00
users, err := model.GetAllUsersWithSecrets()
2022-11-11 22:05:31 +08:00
if err != nil {
common.FatalLog(err.Error())
}
var items []TokenStoreItem
for _, user := range users {
if user.WeChatTestAccountId != "" {
item := &WeChatTestAccountTokenStoreItem{
AppID: user.WeChatTestAccountId,
AppSecret: user.WeChatTestAccountSecret,
}
items = append(items, item)
}
if user.WeChatCorpAccountId != "" {
item := &WeChatCorpAccountTokenStoreItem{
CorpId: user.WeChatCorpAccountId,
AgentSecret: user.WeChatCorpAccountAgentSecret,
AgentId: user.WeChatCorpAccountAgentId,
2022-11-11 22:05:31 +08:00
}
items = append(items, item)
}
}
s.Mutex.RLock()
2022-11-18 17:41:27 +08:00
for i := range items {
// s.Map[item.Key()] = &item // This is wrong, you are getting the address of a local variable!
s.Map[items[i].Key()] = &items[i]
2022-11-11 22:05:31 +08:00
}
s.Mutex.RUnlock()
for {
s.Mutex.RLock()
var tmpMap = make(map[string]*TokenStoreItem)
for k, v := range s.Map {
tmpMap[k] = v
}
s.Mutex.RUnlock()
for k := range tmpMap {
(*tmpMap[k]).Refresh()
}
s.Mutex.RLock()
// we shouldn't directly replace the old map with the new map, cause the old map's keys may already change
for k := range s.Map {
v, okay := tmpMap[k]
if okay {
s.Map[k] = v
}
}
sleepDuration := common.Max(s.ExpirationSeconds, 60)
s.Mutex.RUnlock()
time.Sleep(time.Duration(sleepDuration) * time.Second)
}
}()
}
// TokenStoreAddItem It's okay to add an incomplete item.
2022-11-22 12:44:41 +08:00
func TokenStoreAddItem(item TokenStoreItem) {
if !item.IsFilled() {
return
}
2022-11-22 12:44:41 +08:00
item.Refresh()
2022-11-11 22:05:31 +08:00
s.Mutex.RLock()
2022-11-22 12:44:41 +08:00
s.Map[item.Key()] = &item
2022-11-11 22:05:31 +08:00
s.Mutex.RUnlock()
}
2022-11-22 12:44:41 +08:00
func TokenStoreRemoveItem(item TokenStoreItem) {
2022-11-11 22:05:31 +08:00
s.Mutex.RLock()
2022-11-22 12:44:41 +08:00
delete(s.Map, item.Key())
2022-11-11 22:05:31 +08:00
s.Mutex.RUnlock()
}
func TokenStoreAddUser(user *model.User) {
testItem := WeChatTestAccountTokenStoreItem{
AppID: user.WeChatTestAccountId,
AppSecret: user.WeChatTestAccountSecret,
}
TokenStoreAddItem(&testItem)
corpItem := WeChatCorpAccountTokenStoreItem{
CorpId: user.WeChatCorpAccountId,
AgentSecret: user.WeChatCorpAccountAgentSecret,
AgentId: user.WeChatCorpAccountAgentId,
}
TokenStoreAddItem(&corpItem)
}
2022-11-22 12:44:41 +08:00
func TokenStoreUpdateUser(cleanUser *model.User, originUser *model.User) {
// WeChat Test Account
// The fields of cleanUser may be incomplete!
2022-11-22 12:44:41 +08:00
if cleanUser.WeChatTestAccountId == originUser.WeChatTestAccountId {
cleanUser.WeChatTestAccountId = ""
}
if cleanUser.WeChatTestAccountSecret == originUser.WeChatTestAccountSecret {
cleanUser.WeChatTestAccountSecret = ""
}
// This means the user updated those fields.
2022-11-22 12:44:41 +08:00
if cleanUser.WeChatTestAccountId != "" || cleanUser.WeChatTestAccountSecret != "" {
oldWeChatTestAccountTokenStoreItem := WeChatTestAccountTokenStoreItem{
AppID: originUser.WeChatTestAccountId,
AppSecret: originUser.WeChatTestAccountSecret,
}
// Yeah, it's a deep copy.
2022-11-22 12:44:41 +08:00
newWeChatTestAccountTokenStoreItem := oldWeChatTestAccountTokenStoreItem
if cleanUser.WeChatTestAccountId != "" {
newWeChatTestAccountTokenStoreItem.AppID = cleanUser.WeChatTestAccountId
}
if cleanUser.WeChatTestAccountSecret != "" {
newWeChatTestAccountTokenStoreItem.AppSecret = cleanUser.WeChatTestAccountSecret
}
2022-11-22 15:23:12 +08:00
if !oldWeChatTestAccountTokenStoreItem.IsShared() {
TokenStoreRemoveItem(&oldWeChatTestAccountTokenStoreItem)
}
2022-11-22 12:44:41 +08:00
TokenStoreAddItem(&newWeChatTestAccountTokenStoreItem)
}
// WeChat Corp Account
2022-11-22 12:44:41 +08:00
if cleanUser.WeChatCorpAccountId == originUser.WeChatCorpAccountId {
cleanUser.WeChatCorpAccountId = ""
}
if cleanUser.WeChatCorpAccountAgentId == originUser.WeChatCorpAccountAgentId {
cleanUser.WeChatCorpAccountAgentId = ""
}
if cleanUser.WeChatCorpAccountAgentSecret == originUser.WeChatCorpAccountAgentSecret {
cleanUser.WeChatCorpAccountAgentSecret = ""
2022-11-22 12:44:41 +08:00
}
if cleanUser.WeChatCorpAccountId != "" || cleanUser.WeChatCorpAccountAgentId != "" || cleanUser.WeChatCorpAccountAgentSecret != "" {
2022-11-22 12:44:41 +08:00
oldWeChatCorpAccountTokenStoreItem := WeChatCorpAccountTokenStoreItem{
CorpId: originUser.WeChatCorpAccountId,
AgentSecret: originUser.WeChatCorpAccountAgentSecret,
AgentId: originUser.WeChatCorpAccountAgentId,
2022-11-22 12:44:41 +08:00
}
newWeChatCorpAccountTokenStoreItem := oldWeChatCorpAccountTokenStoreItem
if cleanUser.WeChatCorpAccountId != "" {
newWeChatCorpAccountTokenStoreItem.CorpId = cleanUser.WeChatCorpAccountId
}
if cleanUser.WeChatCorpAccountAgentSecret != "" {
newWeChatCorpAccountTokenStoreItem.AgentSecret = cleanUser.WeChatCorpAccountAgentSecret
2022-11-22 12:44:41 +08:00
}
if cleanUser.WeChatCorpAccountAgentId != "" {
newWeChatCorpAccountTokenStoreItem.AgentId = cleanUser.WeChatCorpAccountAgentId
}
2022-11-22 15:23:12 +08:00
if !oldWeChatCorpAccountTokenStoreItem.IsShared() {
TokenStoreRemoveItem(&oldWeChatCorpAccountTokenStoreItem)
}
2022-11-22 12:44:41 +08:00
TokenStoreAddItem(&newWeChatCorpAccountTokenStoreItem)
}
}
// TokenStoreRemoveUser
// user must be filled.
// It's okay to delete a user that don't have an item here.
2022-11-22 12:44:41 +08:00
func TokenStoreRemoveUser(user *model.User) {
testAccountTokenStoreItem := WeChatTestAccountTokenStoreItem{
AppID: user.WeChatTestAccountId,
AppSecret: user.WeChatTestAccountSecret,
}
2022-11-22 15:23:12 +08:00
if !testAccountTokenStoreItem.IsShared() {
TokenStoreRemoveItem(&testAccountTokenStoreItem)
}
2022-11-22 12:44:41 +08:00
corpAccountTokenStoreItem := WeChatCorpAccountTokenStoreItem{
CorpId: user.WeChatCorpAccountId,
AgentSecret: user.WeChatCorpAccountAgentSecret,
AgentId: user.WeChatCorpAccountAgentId,
2022-11-22 12:44:41 +08:00
}
2022-11-22 15:23:12 +08:00
if !corpAccountTokenStoreItem.IsShared() {
TokenStoreRemoveItem(&corpAccountTokenStoreItem)
}
2022-11-22 12:44:41 +08:00
}
2022-11-11 22:05:31 +08:00
func TokenStoreGetToken(key string) string {
s.Mutex.RLock()
defer s.Mutex.RUnlock()
2022-11-18 17:17:53 +08:00
item, ok := s.Map[key]
if ok {
return (*item).Token()
}
common.SysError("token for " + key + " is blank!")
return ""
2022-11-11 22:05:31 +08:00
}