From a67ab1c95190e7e03eacb280823167e93a55018e Mon Sep 17 00:00:00 2001 From: icey-yu <119291641+icey-yu@users.noreply.github.com> Date: Thu, 7 Nov 2024 11:32:12 +0800 Subject: [PATCH] fix: admin token cache (#613) * fix: admin token cache * fix: admin token cache --- internal/api/admin/admin.go | 10 +++---- internal/api/chat/chat.go | 16 ++--------- pkg/common/imapi/caller.go | 37 +++++++++++++++++--------- pkg/common/tokenverify/token_verify.go | 2 +- tools/check-component/main.go | 2 +- 5 files changed, 34 insertions(+), 33 deletions(-) diff --git a/internal/api/admin/admin.go b/internal/api/admin/admin.go index e4f34b90..b3b3ee39 100644 --- a/internal/api/admin/admin.go +++ b/internal/api/admin/admin.go @@ -113,7 +113,7 @@ func (o *Api) AdminUpdateInfo(c *gin.Context) { } imAdminUserID := o.GetDefaultIMAdminUserID() - imToken, err := o.imApiCaller.GetAdminToken(c, imAdminUserID) + imToken, err := o.imApiCaller.GetAdminTokenCache(c, imAdminUserID) if err != nil { log.ZError(c, "AdminUpdateInfo ImAdminTokenWithDefaultAdmin", err, "imAdminUserID", imAdminUserID) return @@ -193,7 +193,7 @@ func (o *Api) AddDefaultGroup(c *gin.Context) { apiresp.GinError(c, err) return } - imToken, err := o.imApiCaller.GetAdminToken(c, o.GetDefaultIMAdminUserID()) + imToken, err := o.imApiCaller.ImAdminTokenWithDefaultAdmin(c) if err != nil { apiresp.GinError(c, err) return @@ -241,7 +241,7 @@ func (o *Api) SearchDefaultGroup(c *gin.Context) { Groups: make([]*sdkws.GroupInfo, 0, len(searchResp.GroupIDs)), } if len(searchResp.GroupIDs) > 0 { - imToken, err := o.imApiCaller.GetAdminToken(c, o.GetDefaultIMAdminUserID()) + imToken, err := o.imApiCaller.ImAdminTokenWithDefaultAdmin(c) if err != nil { apiresp.GinError(c, err) return @@ -323,7 +323,7 @@ func (o *Api) BlockUser(c *gin.Context) { apiresp.GinError(c, err) return } - imToken, err := o.imApiCaller.GetAdminToken(c, o.GetDefaultIMAdminUserID()) + imToken, err := o.imApiCaller.ImAdminTokenWithDefaultAdmin(c) if err != nil { apiresp.GinError(c, err) return @@ -382,7 +382,7 @@ func (o *Api) NewUserCount(c *gin.Context) { apiresp.GinError(c, err) return } - imToken, err := o.imApiCaller.GetAdminToken(c, o.GetDefaultIMAdminUserID()) + imToken, err := o.imApiCaller.ImAdminTokenWithDefaultAdmin(c) if err != nil { apiresp.GinError(c, err) return diff --git a/internal/api/chat/chat.go b/internal/api/chat/chat.go index d6d8d51e..e61978ed 100644 --- a/internal/api/chat/chat.go +++ b/internal/api/chat/chat.go @@ -22,7 +22,6 @@ import ( "github.com/gin-gonic/gin" "github.com/openimsdk/chat/pkg/common/apistruct" - "github.com/openimsdk/chat/pkg/common/constant" "github.com/openimsdk/chat/pkg/common/imapi" "github.com/openimsdk/chat/pkg/common/mctx" "github.com/openimsdk/chat/pkg/protocol/admin" @@ -235,20 +234,9 @@ func (o *Api) UpdateUserInfo(c *gin.Context) { apiresp.GinError(c, err) return } - opUserType, err := mctx.GetUserType(c) - if err != nil { - apiresp.GinError(c, err) - return - } + var imToken string - if opUserType == constant.NormalUser { - imToken, err = o.imApiCaller.ImAdminTokenWithDefaultAdmin(c) - } else if opUserType == constant.AdminUser { - imToken, err = o.imApiCaller.GetAdminToken(c, o.GetDefaultIMAdminUserID()) - } else { - apiresp.GinError(c, errs.ErrArgs.WrapMsg("opUserType unknown")) - return - } + imToken, err = o.imApiCaller.ImAdminTokenWithDefaultAdmin(c) if err != nil { apiresp.GinError(c, err) return diff --git a/pkg/common/imapi/caller.go b/pkg/common/imapi/caller.go index 88f8f914..3ebee921 100644 --- a/pkg/common/imapi/caller.go +++ b/pkg/common/imapi/caller.go @@ -20,7 +20,7 @@ type CallerInterface interface { ImAdminTokenWithDefaultAdmin(ctx context.Context) (string, error) ImportFriend(ctx context.Context, ownerUserID string, friendUserID []string) error GetUserToken(ctx context.Context, userID string, platform int32) (string, error) - GetAdminToken(ctx context.Context, userID string) (string, error) + GetAdminTokenCache(ctx context.Context, userID string) (string, error) InviteToGroup(ctx context.Context, userID string, groupIDs []string) error UpdateUserInfo(ctx context.Context, userID string, nickName string, faceURL string) error ForceOffLine(ctx context.Context, userID string) error @@ -31,13 +31,17 @@ type CallerInterface interface { AccountCheckSingle(ctx context.Context, userID string) (bool, error) } +type authToken struct { + token string + timeout time.Time +} + type Caller struct { imApi string imSecret string defaultIMUserID string - token string - timeout time.Time - lock sync.Mutex + tokenCache map[string]*authToken + lock sync.RWMutex } func New(imApi string, imSecret string, defaultIMUserID string) CallerInterface { @@ -45,6 +49,8 @@ func New(imApi string, imSecret string, defaultIMUserID string) CallerInterface imApi: imApi, imSecret: imSecret, defaultIMUserID: defaultIMUserID, + tokenCache: make(map[string]*authToken), + lock: sync.RWMutex{}, } } @@ -60,25 +66,32 @@ func (c *Caller) ImportFriend(ctx context.Context, ownerUserID string, friendUse } func (c *Caller) ImAdminTokenWithDefaultAdmin(ctx context.Context) (string, error) { - if c.token == "" || c.timeout.Before(time.Now()) { + return c.GetAdminTokenCache(ctx, c.defaultIMUserID) +} + +func (c *Caller) GetAdminTokenCache(ctx context.Context, userID string) (string, error) { + c.lock.RLock() + t, ok := c.tokenCache[userID] + c.lock.RUnlock() + if !ok || t.timeout.Before(time.Now()) { c.lock.Lock() - if c.token == "" || c.timeout.Before(time.Now()) { - userID := c.defaultIMUserID - token, err := c.GetAdminToken(ctx, userID) + t, ok = c.tokenCache[userID] + if !ok || t.timeout.Before(time.Now()) { + token, err := c.getAdminTokenServer(ctx, userID) if err != nil { log.ZError(ctx, "get im admin token", err, "userID", userID) return "", err } log.ZDebug(ctx, "get im admin token", "userID", userID) - c.token = token - c.timeout = time.Now().Add(time.Minute * 5) + t = &authToken{token: token, timeout: time.Now().Add(time.Minute * 5)} + c.tokenCache[userID] = t } c.lock.Unlock() } - return c.token, nil + return t.token, nil } -func (c *Caller) GetAdminToken(ctx context.Context, userID string) (string, error) { +func (c *Caller) getAdminTokenServer(ctx context.Context, userID string) (string, error) { resp, err := getAdminToken.Call(ctx, c.imApi, &auth.GetAdminTokenReq{ Secret: c.imSecret, UserID: userID, diff --git a/pkg/common/tokenverify/token_verify.go b/pkg/common/tokenverify/token_verify.go index 3c35ffa7..f53cd5ae 100644 --- a/pkg/common/tokenverify/token_verify.go +++ b/pkg/common/tokenverify/token_verify.go @@ -109,7 +109,7 @@ func (t *Token) GetToken(token string) (string, int32, error) { return userID, userType, nil } -//func (t *Token) GetAdminToken(token string) (string, error) { +//func (t *Token) GetAdminTokenCache(token string) (string, error) { // userID, userType, err := getToken(token) // if err != nil { // return "", err diff --git a/tools/check-component/main.go b/tools/check-component/main.go index ab7676a1..f3f2dd25 100644 --- a/tools/check-component/main.go +++ b/tools/check-component/main.go @@ -57,7 +57,7 @@ func CheckRedis(ctx context.Context, config *config.Redis) error { func CheckOpenIM(ctx context.Context, apiURL, secret, adminUserID string) error { imAPI := imapi.New(apiURL, secret, adminUserID) - _, err := imAPI.GetAdminToken(mcontext.SetOperationID(ctx, "CheckOpenIM"+idutil.OperationIDGenerator()), adminUserID) + _, err := imAPI.GetAdminTokenCache(mcontext.SetOperationID(ctx, "CheckOpenIM"+idutil.OperationIDGenerator()), adminUserID) return err }