|
|
@ -17,6 +17,8 @@ import (
|
|
|
|
type AuthDatabase interface {
|
|
|
|
type AuthDatabase interface {
|
|
|
|
// If the result is empty, no error is returned.
|
|
|
|
// If the result is empty, no error is returned.
|
|
|
|
GetTokensWithoutError(ctx context.Context, userID string, platformID int) (map[string]int, error)
|
|
|
|
GetTokensWithoutError(ctx context.Context, userID string, platformID int) (map[string]int, error)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GetTemporaryTokensWithoutError(ctx context.Context, userID string, platformID int, token string) error
|
|
|
|
// Create token
|
|
|
|
// Create token
|
|
|
|
CreateToken(ctx context.Context, userID string, platformID int) (string, error)
|
|
|
|
CreateToken(ctx context.Context, userID string, platformID int) (string, error)
|
|
|
|
|
|
|
|
|
|
|
@ -52,6 +54,10 @@ func (a *authDatabase) GetTokensWithoutError(ctx context.Context, userID string,
|
|
|
|
return a.cache.GetTokensWithoutError(ctx, userID, platformID)
|
|
|
|
return a.cache.GetTokensWithoutError(ctx, userID, platformID)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (a *authDatabase) GetTemporaryTokensWithoutError(ctx context.Context, userID string, platformID int, token string) error {
|
|
|
|
|
|
|
|
return a.cache.HasTemporaryToken(ctx, userID, platformID, token)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (a *authDatabase) SetTokenMapByUidPid(ctx context.Context, userID string, platformID int, m map[string]int) error {
|
|
|
|
func (a *authDatabase) SetTokenMapByUidPid(ctx context.Context, userID string, platformID int, m map[string]int) error {
|
|
|
|
return a.cache.SetTokenMapByUidPid(ctx, userID, platformID, m)
|
|
|
|
return a.cache.SetTokenMapByUidPid(ctx, userID, platformID, m)
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -85,23 +91,30 @@ func (a *authDatabase) CreateToken(ctx context.Context, userID string, platformI
|
|
|
|
return "", err
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
deleteTokenKey, kickedTokenKey, err := a.checkToken(ctx, tokens, platformID)
|
|
|
|
deleteTokenKey, kickedTokenKey, adminTokens, err := a.checkToken(ctx, tokens, platformID)
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if len(deleteTokenKey) != 0 {
|
|
|
|
if len(deleteTokenKey) != 0 {
|
|
|
|
err = a.cache.DeleteTokenByUidPid(ctx, userID, platformID, deleteTokenKey)
|
|
|
|
err = a.cache.DeleteTokenByTokenMap(ctx, userID, deleteTokenKey)
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if len(kickedTokenKey) != 0 {
|
|
|
|
if len(kickedTokenKey) != 0 {
|
|
|
|
for _, k := range kickedTokenKey {
|
|
|
|
for plt, ks := range kickedTokenKey {
|
|
|
|
err := a.cache.SetTokenFlagEx(ctx, userID, platformID, k, constant.KickedToken)
|
|
|
|
for _, k := range ks {
|
|
|
|
if err != nil {
|
|
|
|
err := a.cache.SetTokenFlagEx(ctx, userID, plt, k, constant.KickedToken)
|
|
|
|
return "", err
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
return "", err
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
log.ZDebug(ctx, "kicked token in create token", "token", k)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
log.ZDebug(ctx, "kicked token in create token", "token", k)
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(adminTokens) != 0 {
|
|
|
|
|
|
|
|
if err = a.cache.DeleteAndSetTemporary(ctx, userID, constant.AdminPlatformID, adminTokens); err != nil {
|
|
|
|
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -119,12 +132,13 @@ func (a *authDatabase) CreateToken(ctx context.Context, userID string, platformI
|
|
|
|
return tokenString, nil
|
|
|
|
return tokenString, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (a *authDatabase) checkToken(ctx context.Context, tokens map[int]map[string]int, platformID int) ([]string, []string, error) {
|
|
|
|
// checkToken will check token by tokenPolicy and return deleteToken,kickToken,deleteAdminToken
|
|
|
|
// todo: Move the logic for handling old data to another location.
|
|
|
|
func (a *authDatabase) checkToken(ctx context.Context, tokens map[int]map[string]int, platformID int) (map[int][]string, map[int][]string, []string, error) {
|
|
|
|
|
|
|
|
// todo: Asynchronous deletion of old data.
|
|
|
|
var (
|
|
|
|
var (
|
|
|
|
loginTokenMap = make(map[int][]string) // The length of the value of the map must be greater than 0
|
|
|
|
loginTokenMap = make(map[int][]string) // The length of the value of the map must be greater than 0
|
|
|
|
deleteToken = make([]string, 0)
|
|
|
|
deleteToken = make(map[int][]string)
|
|
|
|
kickToken = make([]string, 0)
|
|
|
|
kickToken = make(map[int][]string)
|
|
|
|
adminToken = make([]string, 0)
|
|
|
|
adminToken = make([]string, 0)
|
|
|
|
unkickTerminal = ""
|
|
|
|
unkickTerminal = ""
|
|
|
|
)
|
|
|
|
)
|
|
|
@ -133,7 +147,7 @@ func (a *authDatabase) checkToken(ctx context.Context, tokens map[int]map[string
|
|
|
|
for k, v := range tks {
|
|
|
|
for k, v := range tks {
|
|
|
|
_, err := tokenverify.GetClaimFromToken(k, authverify.Secret(a.accessSecret))
|
|
|
|
_, err := tokenverify.GetClaimFromToken(k, authverify.Secret(a.accessSecret))
|
|
|
|
if err != nil || v != constant.NormalToken {
|
|
|
|
if err != nil || v != constant.NormalToken {
|
|
|
|
deleteToken = append(deleteToken, k)
|
|
|
|
deleteToken[plfID] = append(deleteToken[plfID], k)
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
if plfID != constant.AdminPlatformID {
|
|
|
|
if plfID != constant.AdminPlatformID {
|
|
|
|
loginTokenMap[plfID] = append(loginTokenMap[plfID], k)
|
|
|
|
loginTokenMap[plfID] = append(loginTokenMap[plfID], k)
|
|
|
@ -153,14 +167,15 @@ func (a *authDatabase) checkToken(ctx context.Context, tokens map[int]map[string
|
|
|
|
}
|
|
|
|
}
|
|
|
|
limit := a.multiLogin.MaxNumOneEnd
|
|
|
|
limit := a.multiLogin.MaxNumOneEnd
|
|
|
|
if l > limit {
|
|
|
|
if l > limit {
|
|
|
|
kickToken = append(kickToken, ts[:l-limit]...)
|
|
|
|
kickToken[plt] = ts[:l-limit]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
case constant.AllLoginButSameTermKick:
|
|
|
|
case constant.AllLoginButSameTermKick:
|
|
|
|
for plt, ts := range loginTokenMap {
|
|
|
|
for plt, ts := range loginTokenMap {
|
|
|
|
kickToken = append(kickToken, ts[:len(ts)-1]...)
|
|
|
|
kickToken[plt] = ts[:len(ts)-1]
|
|
|
|
|
|
|
|
|
|
|
|
if plt == platformID {
|
|
|
|
if plt == platformID {
|
|
|
|
kickToken = append(kickToken, ts[len(ts)-1])
|
|
|
|
kickToken[plt] = append(kickToken[plt], ts[len(ts)-1])
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
case constant.PCAndOther:
|
|
|
|
case constant.PCAndOther:
|
|
|
@ -168,29 +183,33 @@ func (a *authDatabase) checkToken(ctx context.Context, tokens map[int]map[string
|
|
|
|
if constant.PlatformIDToClass(platformID) != unkickTerminal {
|
|
|
|
if constant.PlatformIDToClass(platformID) != unkickTerminal {
|
|
|
|
for plt, ts := range loginTokenMap {
|
|
|
|
for plt, ts := range loginTokenMap {
|
|
|
|
if constant.PlatformIDToClass(plt) != unkickTerminal {
|
|
|
|
if constant.PlatformIDToClass(plt) != unkickTerminal {
|
|
|
|
kickToken = append(kickToken, ts...)
|
|
|
|
kickToken[plt] = ts
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
var (
|
|
|
|
var (
|
|
|
|
preKick []string
|
|
|
|
preKickToken string
|
|
|
|
isReserve = true
|
|
|
|
preKickPlt int
|
|
|
|
|
|
|
|
reserveToken = false
|
|
|
|
)
|
|
|
|
)
|
|
|
|
for plt, ts := range loginTokenMap {
|
|
|
|
for plt, ts := range loginTokenMap {
|
|
|
|
if constant.PlatformIDToClass(plt) != unkickTerminal {
|
|
|
|
if constant.PlatformIDToClass(plt) != unkickTerminal {
|
|
|
|
// Keep a token from another end
|
|
|
|
// Keep a token from another end
|
|
|
|
if isReserve {
|
|
|
|
if !reserveToken {
|
|
|
|
isReserve = false
|
|
|
|
reserveToken = true
|
|
|
|
kickToken = append(kickToken, ts[:len(ts)-1]...)
|
|
|
|
kickToken[plt] = ts[:len(ts)-1]
|
|
|
|
preKick = append(preKick, ts[len(ts)-1])
|
|
|
|
preKickToken = ts[len(ts)-1]
|
|
|
|
|
|
|
|
preKickPlt = plt
|
|
|
|
continue
|
|
|
|
continue
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
// Prioritize keeping Android
|
|
|
|
// Prioritize keeping Android
|
|
|
|
if plt == constant.AndroidPlatformID {
|
|
|
|
if plt == constant.AndroidPlatformID {
|
|
|
|
kickToken = append(kickToken, preKick...)
|
|
|
|
if preKickToken != "" {
|
|
|
|
kickToken = append(kickToken, ts[:len(ts)-1]...)
|
|
|
|
kickToken[preKickPlt] = append(kickToken[preKickPlt], preKickToken)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
kickToken[plt] = ts[:len(ts)-1]
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
kickToken = append(kickToken, ts...)
|
|
|
|
kickToken[plt] = ts
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -203,19 +222,19 @@ func (a *authDatabase) checkToken(ctx context.Context, tokens map[int]map[string
|
|
|
|
|
|
|
|
|
|
|
|
for plt, ts := range loginTokenMap {
|
|
|
|
for plt, ts := range loginTokenMap {
|
|
|
|
if constant.PlatformIDToClass(plt) == constant.PlatformIDToClass(platformID) {
|
|
|
|
if constant.PlatformIDToClass(plt) == constant.PlatformIDToClass(platformID) {
|
|
|
|
kickToken = append(kickToken, ts...)
|
|
|
|
kickToken[plt] = ts
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
if _, ok := reserved[constant.PlatformIDToClass(plt)]; !ok {
|
|
|
|
if _, ok := reserved[constant.PlatformIDToClass(plt)]; !ok {
|
|
|
|
reserved[constant.PlatformIDToClass(plt)] = struct{}{}
|
|
|
|
reserved[constant.PlatformIDToClass(plt)] = struct{}{}
|
|
|
|
kickToken = append(kickToken, ts[:len(ts)-1]...)
|
|
|
|
kickToken[plt] = ts[:len(ts)-1]
|
|
|
|
continue
|
|
|
|
continue
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
kickToken = append(kickToken, ts...)
|
|
|
|
kickToken[plt] = ts
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
default:
|
|
|
|
return nil, nil, errs.New("unknown multiLogin policy").Wrap()
|
|
|
|
return nil, nil, nil, errs.New("unknown multiLogin policy").Wrap()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//var adminTokenMaxNum = a.multiLogin.MaxNumOneEnd
|
|
|
|
//var adminTokenMaxNum = a.multiLogin.MaxNumOneEnd
|
|
|
@ -226,8 +245,9 @@ func (a *authDatabase) checkToken(ctx context.Context, tokens map[int]map[string
|
|
|
|
//if l > adminTokenMaxNum {
|
|
|
|
//if l > adminTokenMaxNum {
|
|
|
|
// kickToken = append(kickToken, adminToken[:l-adminTokenMaxNum]...)
|
|
|
|
// kickToken = append(kickToken, adminToken[:l-adminTokenMaxNum]...)
|
|
|
|
//}
|
|
|
|
//}
|
|
|
|
|
|
|
|
var deleteAdminToken []string
|
|
|
|
if platformID == constant.AdminPlatformID {
|
|
|
|
if platformID == constant.AdminPlatformID {
|
|
|
|
kickToken = append(kickToken, adminToken...)
|
|
|
|
deleteAdminToken = adminToken
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return deleteToken, kickToken, nil
|
|
|
|
return deleteToken, kickToken, deleteAdminToken, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|