Merge branch 'errcode' of github.com:OpenIMSDK/Open-IM-Server into errcode

 Conflicts:
	internal/push/sdk/tpns-server-sdk-go/go/auth/auth.go
	pkg/proto/group/group.proto
This commit is contained in:
wangchuxiao 2023-02-09 20:39:12 +08:00
commit 6eb231aae4
33 changed files with 907 additions and 571 deletions

View File

@ -117,7 +117,7 @@ const docTemplate = `{
{
"type": "object",
"properties": {
"Data": {
"Map": {
"$ref": "#/definitions/api_struct.ExpireTime"
}
}
@ -4369,7 +4369,7 @@ const docTemplate = `{
{
"type": "object",
"properties": {
"Data": {
"Map": {
"type": "array",
"items": {
"$ref": "#/definitions/sdkws.PublicUserInfo"

View File

@ -6,7 +6,6 @@ import (
"Open_IM/pkg/common/constant"
"Open_IM/pkg/common/log"
"Open_IM/pkg/common/tokenverify"
"Open_IM/pkg/getcdv3"
rpc "Open_IM/pkg/proto/auth"
open_im_sdk "Open_IM/pkg/proto/sdkws"
"Open_IM/pkg/utils"
@ -149,7 +148,7 @@ func UserToken(c *gin.Context) {
// @Param token header string true "im token"
// @Param req body api.ParseTokenReq true "secret为openIM密钥, 详细见服务端config.yaml secret字段<br>platform为平台ID"
// @Produce json
// @Success 0 {object} api.ParseTokenResp{Data=api.ExpireTime}
// @Success 0 {object} api.ParseTokenResp{Map=api.ExpireTime}
// @Failure 500 {object} api.Swagger500Resp "errCode为500 一般为服务器内部错误"
// @Failure 400 {object} api.Swagger400Resp "errCode为400 一般为参数输入错误, token未带上等"
// @Router /auth/parse_token [post]

View File

@ -343,7 +343,7 @@ package friend
// utils.CopyStructFields(&black, v)
// resp.BlackUserInfoList = append(resp.BlackUserInfoList, &black)
// }
// resp.Data = jsonData.JsonDataList(resp.BlackUserInfoList)
// resp.Map = jsonData.JsonDataList(resp.BlackUserInfoList)
// log.NewInfo(req.CommID.OperationID, "GetBlacklist api return ", resp)
// c.JSON(http.StatusOK, resp)
//}
@ -561,7 +561,7 @@ package friend
// }
//
// resp := api.GetFriendListResp{CommResp: api.CommResp{ErrCode: RpcResp.CommonResp.ErrCode, ErrMsg: RpcResp.CommonResp.ErrMsg}, FriendInfoList: RpcResp.FriendInfoList}
// resp.Data = jsonData.JsonDataList(resp.FriendInfoList)
// resp.Map = jsonData.JsonDataList(resp.FriendInfoList)
// log.NewInfo(req.CommID.OperationID, "GetFriendList api return ", resp)
// c.JSON(http.StatusOK, resp)
// //c.JSON(http.StatusOK, resp)
@ -618,7 +618,7 @@ package friend
// }
//
// resp := api.GetFriendApplyListResp{CommResp: api.CommResp{ErrCode: RpcResp.CommonResp.ErrCode, ErrMsg: RpcResp.CommonResp.ErrMsg}, FriendRequestList: RpcResp.FriendRequestList}
// resp.Data = jsonData.JsonDataList(resp.FriendRequestList)
// resp.Map = jsonData.JsonDataList(resp.FriendRequestList)
// log.NewInfo(req.CommID.OperationID, "GetFriendApplyList api return ", resp)
// c.JSON(http.StatusOK, resp)
//}
@ -672,7 +672,7 @@ package friend
// return
// }
// resp := api.GetSelfApplyListResp{CommResp: api.CommResp{ErrCode: RpcResp.CommonResp.ErrCode, ErrMsg: RpcResp.CommonResp.ErrMsg}, FriendRequestList: RpcResp.FriendRequestList}
// resp.Data = jsonData.JsonDataList(resp.FriendRequestList)
// resp.Map = jsonData.JsonDataList(resp.FriendRequestList)
// log.NewInfo(req.CommID.OperationID, "GetSelfApplyList api return ", resp)
// c.JSON(http.StatusOK, resp)
//}

View File

@ -142,7 +142,7 @@ package group
// }
//
// memberListResp := api.GetGroupMembersInfoResp{CommResp: api.CommResp{ErrCode: RpcResp.CommonResp.ErrCode, ErrMsg: RpcResp.CommonResp.ErrMsg}, MemberList: RpcResp.MemberList}
// memberListResp.Data = jsonData.JsonDataList(RpcResp.MemberList)
// memberListResp.Map = jsonData.JsonDataList(RpcResp.MemberList)
// log.NewInfo(req.OperationID, "GetGroupMembersInfo api return ", memberListResp)
// c.JSON(http.StatusOK, memberListResp)
//}
@ -186,7 +186,7 @@ package group
// }
//
// memberListResp := api.GetGroupMemberListResp{CommResp: api.CommResp{ErrCode: RpcResp.CommonResp.ErrCode, ErrMsg: RpcResp.CommonResp.ErrMsg}, MemberList: RpcResp.MemberList, NextSeq: RpcResp.NextSeq}
// memberListResp.Data = jsonData.JsonDataList(memberListResp.MemberList)
// memberListResp.Map = jsonData.JsonDataList(memberListResp.MemberList)
//
// log.NewInfo(req.OperationID, "FindGroupMemberAll api return ", memberListResp)
// c.JSON(http.StatusOK, memberListResp)
@ -243,7 +243,7 @@ package group
// }
//
// memberListResp := api.GetGroupAllMemberResp{CommResp: api.CommResp{ErrCode: RpcResp.CommonResp.ErrCode, ErrMsg: RpcResp.CommonResp.ErrMsg}, MemberList: RpcResp.MemberList}
// memberListResp.Data = jsonData.JsonDataList(memberListResp.MemberList)
// memberListResp.Map = jsonData.JsonDataList(memberListResp.MemberList)
// log.NewInfo(req.OperationID, "GetGroupAllMember api return ", len(memberListResp.MemberList))
// c.JSON(http.StatusOK, memberListResp)
//}
@ -298,7 +298,7 @@ package group
// }
//
// GroupListResp := api.GetJoinedGroupListResp{CommResp: api.CommResp{ErrCode: RpcResp.CommonResp.ErrCode, ErrMsg: RpcResp.CommonResp.ErrMsg}, GroupInfoList: RpcResp.GroupList}
// GroupListResp.Data = jsonData.JsonDataList(GroupListResp.GroupInfoList)
// GroupListResp.Map = jsonData.JsonDataList(GroupListResp.GroupInfoList)
// log.NewInfo(req.OperationID, "FindJoinedGroup api return ", GroupListResp)
// c.JSON(http.StatusOK, GroupListResp)
//}
@ -437,7 +437,7 @@ package group
//// resp := api.CreateGroupResp{CommResp: api.CommResp{ErrCode: RpcResp.ErrCode, ErrMsg: RpcResp.ErrMsg}}
//// if RpcResp.ErrCode == 0 {
//// utils.CopyStructFields(&resp.GroupInfo, RpcResp.GroupInfo)
//// resp.Data = jsonData.JsonDataOne(&resp.GroupInfo)
//// resp.Map = jsonData.JsonDataOne(&resp.GroupInfo)
//// }
//// log.NewInfo(req.OperationID, "CreateGroup api return ", resp)
//// c.JSON(http.StatusOK, resp)
@ -496,7 +496,7 @@ package group
// }
//
// resp := api.GetGroupApplicationListResp{CommResp: api.CommResp{ErrCode: reply.CommonResp.ErrCode, ErrMsg: reply.CommonResp.ErrMsg}, GroupRequestList: reply.GroupRequestList}
// resp.Data = jsonData.JsonDataList(resp.GroupRequestList)
// resp.Map = jsonData.JsonDataList(resp.GroupRequestList)
// log.NewInfo(req.OperationID, "GetGroupApplicationList api return ", resp)
// c.JSON(http.StatusOK, resp)
//}
@ -567,7 +567,7 @@ package group
// }
//
// resp := api.GetGroupInfoResp{CommResp: api.CommResp{ErrCode: RpcResp.CommonResp.ErrCode, ErrMsg: RpcResp.CommonResp.ErrMsg}, GroupInfoList: RpcResp.GroupInfoList}
// resp.Data = jsonData.JsonDataList(resp.GroupInfoList)
// resp.Map = jsonData.JsonDataList(resp.GroupInfoList)
// log.NewInfo(req.OperationID, "GetGroupsInfo api return ", resp)
// c.JSON(http.StatusOK, resp)
//}

View File

@ -4,8 +4,10 @@ import (
"Open_IM/pkg/api_struct"
"Open_IM/pkg/proto/group"
"context"
"errors"
"github.com/gin-gonic/gin"
"google.golang.org/grpc"
"reflect"
"testing"
)
@ -67,7 +69,8 @@ func KickGroupMember(c *gin.Context) {
// 默认 全部自动
NewRpc(NewApiBind[apistruct.KickGroupMemberReq, apistruct.KickGroupMemberResp](c), "", group.NewGroupClient, group.GroupClient.KickGroupMember).Execute()
// 可以自定义编辑请求和响应
NewRpc(NewApiBind[api_struct.KickGroupMemberReq, api_struct.KickGroupMemberResp](c), "", group.NewGroupClient, group.GroupClient.KickGroupMember).Before(func(apiReq *api_struct.KickGroupMemberReq, rpcReq *group.KickGroupMemberReq, bind func() error) error {
a := NewRpc(NewApiBind[api_struct.KickGroupMemberReq, api_struct.KickGroupMemberResp](c), "", group.NewGroupClient, group.GroupClient.KickGroupMember)
a.Before(func(apiReq *api_struct.KickGroupMemberReq, rpcReq *group.KickGroupMemberReq, bind func() error) error {
return bind()
}).After(func(rpcResp *group.KickGroupMemberResp, apiResp *api_struct.KickGroupMemberResp, bind func() error) error {
return bind()
@ -102,6 +105,22 @@ func (a *RpcRun[A, B, C, D, Z]) After(fn func(rpcResp D, apiResp *B, bind func()
return a
}
func (a *RpcRun[A, B, C, D, Z]) execute() (*B, error) {
userID, err := a.bind.OpUserID()
if err != nil {
return nil, err
}
opID := a.bind.OperationID()
var rpcReq C // C type => *Struct
rpcReq = reflect.New(reflect.TypeOf(rpcReq).Elem()).Interface().(C)
return nil, nil
}
func (a *RpcRun[A, B, C, D, Z]) Execute() {
}
func GetGrpcConn(name string) (*grpc.ClientConn, error) {
return nil, errors.New("todo")
}

View File

@ -46,7 +46,7 @@ package group
// return
// }
// GroupListResp := api.GetJoinedSuperGroupListResp{GetJoinedGroupListResp: api.GetJoinedGroupListResp{CommResp: api.CommResp{ErrCode: rpcResp.CommonResp.ErrCode, ErrMsg: rpcResp.CommonResp.ErrMsg}, GroupInfoList: rpcResp.GroupList}}
// GroupListResp.Data = jsonData.JsonDataList(GroupListResp.GroupInfoList)
// GroupListResp.Map = jsonData.JsonDataList(GroupListResp.GroupInfoList)
// log.NewInfo(req.OperationID, "GetJoinedSuperGroupList api return ", GroupListResp)
// c.JSON(http.StatusOK, GroupListResp)
//}
@ -83,7 +83,7 @@ package group
// }
//
// resp := api.GetSuperGroupsInfoResp{GetGroupInfoResp: api.GetGroupInfoResp{CommResp: api.CommResp{ErrCode: rpcResp.CommonResp.ErrCode, ErrMsg: rpcResp.CommonResp.ErrMsg}, GroupInfoList: rpcResp.GroupInfoList}}
// resp.Data = jsonData.JsonDataList(resp.GroupInfoList)
// resp.Map = jsonData.JsonDataList(resp.GroupInfoList)
// log.NewInfo(req.OperationID, "GetGroupsInfo api return ", resp)
// c.JSON(http.StatusOK, resp)
//}

View File

@ -13,7 +13,6 @@ import (
"Open_IM/pkg/common/db/mysql_model/im_mysql_model"
"Open_IM/pkg/common/log"
"Open_IM/pkg/common/tokenverify"
"Open_IM/pkg/getcdv3"
pbChat "Open_IM/pkg/proto/msg"
open_im_sdk "Open_IM/pkg/proto/sdkws"
"Open_IM/pkg/utils"
@ -165,7 +164,7 @@ func ManagementSendMsg(c *gin.Context) {
}
if err := mapstructure.WeakDecode(params.Content, &data); err != nil {
c.JSON(http.StatusOK, gin.H{"errCode": 401, "errMsg": err.Error()})
log.Error(c.PostForm("operationID"), "content to Data struct err", err.Error())
log.Error(c.PostForm("operationID"), "content to Map struct err", err.Error())
return
} else if err := validate.Struct(data); err != nil {
c.JSON(http.StatusOK, gin.H{"errCode": 403, "errMsg": err.Error()})
@ -298,7 +297,7 @@ func ManagementBatchSendMsg(c *gin.Context) {
}
if err := mapstructure.WeakDecode(params.Content, &data); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"errCode": 401, "errMsg": err.Error()})
log.Error(c.PostForm("operationID"), "content to Data struct err", err.Error())
log.Error(c.PostForm("operationID"), "content to Map struct err", err.Error())
return
} else if err := validate.Struct(data); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"errCode": 403, "errMsg": err.Error()})

View File

@ -5,7 +5,6 @@ import (
"Open_IM/pkg/common/config"
"Open_IM/pkg/common/log"
"Open_IM/pkg/common/tokenverify"
"Open_IM/pkg/getcdv3"
pbOffice "Open_IM/pkg/proto/office"
pbCommon "Open_IM/pkg/proto/sdkws"
"Open_IM/pkg/utils"
@ -565,7 +564,7 @@ func GetUserFriendWorkMoments(c *gin.Context) {
if err := utils.CopyStructFields(&resp, respPb.CommonResp); err != nil {
log.NewDebug(req.OperationID, utils.GetSelfFuncName(), "CopyStructFields failed", err.Error())
}
//if err := utils.CopyStructFields(&resp.Data.WorkMoments, respPb.WorkMoments); err != nil {
//if err := utils.CopyStructFields(&resp.Map.WorkMoments, respPb.WorkMoments); err != nil {
// log.NewDebug(req.OperationID, utils.GetSelfFuncName(), "CopyStructFields failed", err.Error())
//}
resp.Data.WorkMoments = []*api.WorkMoment{}

View File

@ -7,7 +7,6 @@ import (
"Open_IM/pkg/common/constant"
"Open_IM/pkg/common/log"
"Open_IM/pkg/common/tokenverify"
"Open_IM/pkg/getcdv3"
cacheRpc "Open_IM/pkg/proto/cache"
pbRelay "Open_IM/pkg/proto/relay"
open_im_sdk "Open_IM/pkg/proto/sdkws"
@ -156,7 +155,7 @@ func GetBlackIDListFromCache(c *gin.Context) {
// @Param token header string true "im token"
// @Param req body api.GetUsersInfoReq true "请求体"
// @Produce json
// @Success 0 {object} api.GetUsersInfoResp{Data=[]open_im_sdk.PublicUserInfo}
// @Success 0 {object} api.GetUsersInfoResp{Map=[]open_im_sdk.PublicUserInfo}
// @Failure 500 {object} api.Swagger500Resp "errCode为500 一般为服务器内部错误"
// @Failure 400 {object} api.Swagger400Resp "errCode为400 一般为参数输入错误, token未带上等"
// @Router /user/get_users_info [post]

View File

@ -36,6 +36,7 @@ func NewRpcServer(registerIPInConfig string, port int, registerName string, zkSe
return nil, err
}
s.RegisterCenter = zkClient
return s, nil
}

View File

@ -62,7 +62,7 @@ func (ws *WServer) argsValidate(m *Req, r int32, operationID string) (isPass boo
case constant.WSGetNewestSeq:
data := open_im_sdk.GetMaxAndMinSeqReq{}
if err := proto.Unmarshal(m.Data, &data); err != nil {
log.Error(operationID, "Decode Data struct err", err.Error(), r)
log.Error(operationID, "Decode Map struct err", err.Error(), r)
return false, 203, err.Error(), nil
}
if err := validate.Struct(data); err != nil {
@ -74,7 +74,7 @@ func (ws *WServer) argsValidate(m *Req, r int32, operationID string) (isPass boo
case constant.WSSendMsg:
data := open_im_sdk.MsgData{}
if err := proto.Unmarshal(m.Data, &data); err != nil {
log.Error(operationID, "Decode Data struct err", err.Error(), r)
log.Error(operationID, "Decode Map struct err", err.Error(), r)
return false, 203, err.Error(), nil
}
if err := validate.Struct(data); err != nil {
@ -86,7 +86,7 @@ func (ws *WServer) argsValidate(m *Req, r int32, operationID string) (isPass boo
case constant.WSSendSignalMsg:
data := pbRtc.SignalReq{}
if err := proto.Unmarshal(m.Data, &data); err != nil {
log.Error(operationID, "Decode Data struct err", err.Error(), r)
log.Error(operationID, "Decode Map struct err", err.Error(), r)
return false, 203, err.Error(), nil
}
if err := validate.Struct(data); err != nil {
@ -98,7 +98,7 @@ func (ws *WServer) argsValidate(m *Req, r int32, operationID string) (isPass boo
case constant.WSPullMsgBySeqList:
data := open_im_sdk.PullMessageBySeqListReq{}
if err := proto.Unmarshal(m.Data, &data); err != nil {
log.Error(operationID, "Decode Data struct err", err.Error(), r)
log.Error(operationID, "Decode Map struct err", err.Error(), r)
return false, 203, err.Error(), nil
}
if err := validate.Struct(data); err != nil {
@ -110,7 +110,7 @@ func (ws *WServer) argsValidate(m *Req, r int32, operationID string) (isPass boo
case constant.WsSetBackgroundStatus:
data := open_im_sdk.SetAppBackgroundStatusReq{}
if err := proto.Unmarshal(m.Data, &data); err != nil {
log.Error(operationID, "Decode Data struct err", err.Error(), r)
log.Error(operationID, "Decode Map struct err", err.Error(), r)
return false, 203, err.Error(), nil
}
if err := validate.Struct(data); err != nil {

View File

@ -0,0 +1,62 @@
package auth
import (
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
b64 "encoding/base64"
"encoding/hex"
"fmt"
"net/http"
"strconv"
"time"
)
type Auther struct {
AccessID string
SecretKey string
}
var UseSignAuthored = true
func (a *Auther) Auth(req *http.Request, useSignAuthored bool, auth Auther, reqBody string) {
if useSignAuthored {
now := time.Now()
timeStamp := now.Unix()
req.Header.Add("AccessId", auth.AccessID)
req.Header.Add("TimeStamp", strconv.Itoa(int(timeStamp)))
sign := GenSign(uint64(timeStamp), auth.AccessID, auth.SecretKey, reqBody)
req.Header.Add("Sign", sign)
} else {
author := makeAuthHeader(a.AccessID, a.SecretKey)
//log.Printf("author string:%v", author)
req.Header.Add("Authorization", author)
}
//req.Header.Add("Content-Type", "application/json")
}
func makeAuthHeader(appID, secretKey string) string {
base64Str := base64.StdEncoding.EncodeToString(
[]byte(
fmt.Sprintf("%s:%s", appID, secretKey),
),
)
return fmt.Sprintf("Basic %s", base64Str)
}
func GenSign(timeStamp uint64, accessId string, secretKey, requestBody string) string {
signBody := strconv.Itoa(int(timeStamp)) + accessId + requestBody
// Create a new HMAC by defining the hash type and the key (as byte array)
h := hmac.New(sha256.New, []byte(secretKey))
// Write Map to it
h.Write([]byte(signBody))
// Get result and encode as hexadecimal string
sha := hex.EncodeToString(h.Sum(nil))
//fmt.Println()
//fmt.Println("timeStamp: " + strconv.Itoa(int(timeStamp)) + " accessID:" + accessId + " body:" + requestBody)
sEnc := b64.StdEncoding.EncodeToString([]byte(sha))
//fmt.Println("final Result " + sEnc)
return sEnc
}

View File

@ -5,6 +5,7 @@ import (
"Open_IM/internal/common/rpc_server"
"Open_IM/pkg/common/config"
"Open_IM/pkg/common/constant"
"Open_IM/pkg/common/db/cache"
"Open_IM/pkg/common/db/controller"
"Open_IM/pkg/common/log"
promePkg "Open_IM/pkg/common/prometheus"
@ -23,8 +24,11 @@ func NewRpcAuthServer(port int) *rpcAuth {
if err != nil {
panic(err)
}
var redis cache.RedisClient
redis.InitRedis()
return &rpcAuth{
RpcServer: r,
RpcServer: r,
AuthInterface: controller.NewAuthController(redis.GetClient(), config.Config.TokenPolicy.AccessSecret, config.Config.TokenPolicy.AccessExpire),
}
}
@ -64,7 +68,7 @@ func (s *rpcAuth) UserToken(ctx context.Context, req *pbAuth.UserTokenReq) (*pbA
if _, err := check.GetUsersInfo(ctx, req.UserID); err != nil {
return nil, err
}
token, err := s.CreateToken(ctx, req.UserID, int(req.PlatformID), config.Config.TokenPolicy.AccessExpire)
token, err := s.CreateToken(ctx, req.UserID, constant.PlatformIDToName(int(req.PlatformID)))
if err != nil {
return nil, err
}
@ -73,39 +77,41 @@ func (s *rpcAuth) UserToken(ctx context.Context, req *pbAuth.UserTokenReq) (*pbA
return &resp, nil
}
func (s *rpcAuth) parseToken(ctx context.Context, tokensString, operationID string) (claims *tokenverify.Claims, err error) {
func (s *rpcAuth) parseToken(ctx context.Context, tokensString string) (claims *tokenverify.Claims, err error) {
claims, err = tokenverify.GetClaimFromToken(tokensString)
if err != nil {
return nil, utils.Wrap(err, "")
}
m, err := s.GetTokens(ctx, claims.UID, claims.Platform)
m, err := s.GetTokensWithoutError(ctx, claims.UID, claims.Platform)
if err != nil {
return nil, err
}
if len(m) == 0 {
return nil, constant.ErrTokenNotExist.Wrap()
}
if v, ok := m[tokensString]; ok {
switch v {
case constant.NormalToken:
return claims, nil
case constant.KickedToken:
return nil, utils.Wrap(constant.ErrTokenKicked, "this token has been kicked by other same terminal ")
return nil, constant.ErrTokenKicked.Wrap()
default:
return nil, utils.Wrap(constant.ErrTokenUnknown, "")
}
}
return nil, utils.Wrap(constant.ErrTokenNotExist, "redis token map not find")
return nil, constant.ErrTokenNotExist.Wrap()
}
func (s *rpcAuth) ParseToken(ctx context.Context, req *pbAuth.ParseTokenReq) (*pbAuth.ParseTokenResp, error) {
resp := pbAuth.ParseTokenResp{}
claims, err := s.parseToken(ctx, req.Token, req.OperationID)
func (s *rpcAuth) ParseToken(ctx context.Context, req *pbAuth.ParseTokenReq) (resp *pbAuth.ParseTokenResp, err error) {
resp = &pbAuth.ParseTokenResp{}
claims, err := s.parseToken(ctx, req.Token)
if err != nil {
return nil, err
}
resp.UserID = claims.UID
resp.Platform = claims.Platform
resp.ExpireTimeSeconds = claims.ExpiresAt.Unix()
return &resp, nil
return resp, nil
}
func (s *rpcAuth) ForceLogout(ctx context.Context, req *pbAuth.ForceLogoutReq) (*pbAuth.ForceLogoutResp, error) {

View File

@ -119,7 +119,7 @@ func CallbackBeforeMemberJoinGroup(ctx context.Context, operationID string, grou
return err
}
func CallbackBeforeSetGroupMemberInfo(ctx context.Context, req *pbGroup.SetGroupMemberInfoReq) (err error) {
func CallbackBeforeSetGroupMemberInfo(ctx context.Context, req *pbGroup.SetGroupMemberInfo) (err error) {
defer func() {
tracelog.SetCtxInfo(ctx, utils.GetFuncName(1), err, "req", *req)
}()

View File

@ -84,7 +84,7 @@ func DbToPbGroupRequest(m *relation.GroupRequestModel, user *open_im_sdk.PublicU
func DbToPbGroupAbstractInfo(groupID string, groupMemberNumber int32, groupMemberListHash uint64) *pbGroup.GroupAbstractInfo {
return &pbGroup.GroupAbstractInfo{
GroupID: groupID,
GroupMemberNumber: groupMemberNumber,
GroupMemberNumber: uint32(groupMemberNumber),
GroupMemberListHash: groupMemberListHash,
}
}

View File

@ -44,7 +44,7 @@ func UpdateGroupMemberMutedTimeMap(t time.Time) map[string]any {
}
}
func UpdateGroupMemberMap(req *pbGroup.SetGroupMemberInfoReq) map[string]any {
func UpdateGroupMemberMap(req *pbGroup.SetGroupMemberInfo) map[string]any {
m := make(map[string]any)
if req.Nickname != nil {
m["nickname"] = req.Nickname.Value

View File

@ -30,7 +30,6 @@ import (
"github.com/OpenIMSDK/openKeeper"
"google.golang.org/grpc"
"google.golang.org/protobuf/types/known/wrapperspb"
)
type groupServer struct {
@ -75,7 +74,7 @@ func NewGroupServer(port int) *groupServer {
//conns, err := g.registerCenter.GetConns(config.Config.RpcRegisterName.OpenImConversationName)
g.GroupInterface = controller.NewGroupInterface(controller.NewGroupDatabase(mysql.GormConn(), redis.GetClient(), mongo.GetClient()))
g.GroupInterface = controller.NewGroupInterface(mysql.GormConn(), redis.GetClient(), mongo.GetClient())
return &g
}
@ -191,7 +190,7 @@ func (s *groupServer) CreateGroup(ctx context.Context, req *pbGroup.CreateGroupR
}
}
}
if err := s.GroupInterface.CreateGroup(ctx, []*relation.GroupModel{group}, groupMembers); err != nil {
if err := s.GroupInterface.CreateGroup(ctx, []*relationTb.GroupModel{group}, groupMembers); err != nil {
return nil, err
}
resp.GroupInfo = DbToPbGroupInfo(group, req.OwnerUserID, uint32(len(userIDs)))
@ -287,9 +286,9 @@ func (s *groupServer) InviteUserToGroup(ctx context.Context, req *pbGroup.Invite
return nil, constant.ErrNoPermission.Wrap("not in group")
}
if !(member.RoleLevel == constant.GroupOwner || member.RoleLevel == constant.GroupAdmin) {
var requests []*relation.GroupRequestModel
var requests []*relationTb.GroupRequestModel
for _, userID := range req.InvitedUserIDs {
requests = append(requests, &relation.GroupRequestModel{
requests = append(requests, &relationTb.GroupRequestModel{
UserID: userID,
GroupID: req.GroupID,
JoinSource: constant.JoinByInvitation,
@ -951,50 +950,79 @@ func (s *groupServer) CancelMuteGroup(ctx context.Context, req *pbGroup.CancelMu
return resp, nil
}
func (s *groupServer) SetGroupMemberNickname(ctx context.Context, req *pbGroup.SetGroupMemberNicknameReq) (*pbGroup.SetGroupMemberNicknameResp, error) {
_, err := s.SetGroupMemberInfo(ctx, &pbGroup.SetGroupMemberInfoReq{GroupID: req.GroupID, UserID: req.UserID, Nickname: wrapperspb.String(req.Nickname)})
if err != nil {
return nil, err
}
return &pbGroup.SetGroupMemberNicknameResp{}, nil
}
func (s *groupServer) SetGroupMemberInfo(ctx context.Context, req *pbGroup.SetGroupMemberInfoReq) (*pbGroup.SetGroupMemberInfoResp, error) {
resp := &pbGroup.SetGroupMemberInfoResp{}
if req.RoleLevel != nil && req.RoleLevel.Value == constant.GroupOwner {
return nil, constant.ErrNoPermission.Wrap("set group owner")
if len(req.Members) == 0 {
return nil, constant.ErrArgs.Wrap("members empty")
}
group, err := s.GroupInterface.TakeGroup(ctx, req.GroupID)
if err != nil {
return nil, err
}
if group.Status == constant.GroupStatusDismissed {
return nil, constant.ErrArgs.Wrap("group status is dismissed")
}
member, err := s.GroupInterface.TakeGroupMember(ctx, req.GroupID, req.UserID)
if err != nil {
return nil, err
}
if tracelog.GetOpUserID(ctx) == req.UserID {
if req.RoleLevel != nil {
return nil, constant.ErrArgs.Wrap("update role level")
duplicateMap := make(map[[2]string]struct{})
userIDMap := make(map[string]struct{})
groupIDMap := make(map[string]struct{})
for _, member := range req.Members {
key := [...]string{member.GroupID, member.UserID}
if _, ok := duplicateMap[key]; ok {
return nil, constant.ErrArgs.Wrap("group user duplicate")
}
} else if !tokenverify.IsAppManagerUid(ctx) {
opMember, err := s.GroupInterface.TakeGroupMember(ctx, req.GroupID, tracelog.GetOpUserID(ctx))
if err != nil {
duplicateMap[key] = struct{}{}
userIDMap[member.UserID] = struct{}{}
groupIDMap[member.GroupID] = struct{}{}
}
groupIDs := utils.Keys(groupIDMap)
userIDs := utils.Keys(userIDMap)
members, err := s.GroupInterface.FindGroupMember(ctx, groupIDs, append(userIDs, tracelog.GetOpUserID(ctx)), nil)
if err != nil {
return nil, err
}
for _, member := range members {
delete(duplicateMap, [...]string{member.GroupID, member.UserID})
}
if len(duplicateMap) > 0 {
return nil, constant.ErrArgs.Wrap("group not found or user not in group")
}
memberMap := utils.SliceToMap(members, func(e *relationTb.GroupMemberModel) [2]string {
return [...]string{e.GroupID, e.UserID}
})
if !tokenverify.IsAppManagerUid(ctx) {
opUserID := tracelog.GetOpUserID(ctx)
for _, member := range members {
if member.UserID == opUserID {
continue
}
opMember, ok := memberMap[[...]string{member.GroupID, member.UserID}]
if !ok {
return nil, constant.ErrArgs.Wrap(fmt.Sprintf("user %s not in group %s", opUserID, member.GroupID))
}
if member.RoleLevel >= opMember.RoleLevel {
return nil, constant.ErrNoPermission.Wrap(fmt.Sprintf("group %s : %s RoleLevel %d >= %s RoleLevel %d", member.GroupID, member.UserID, member.RoleLevel, opMember.UserID, opMember.RoleLevel))
}
}
}
for _, member := range req.Members {
if member.RoleLevel == nil {
continue
}
if memberMap[[...]string{member.GroupID, member.UserID}].RoleLevel == constant.GroupOwner {
return nil, constant.ErrArgs.Wrap(fmt.Sprintf("group %s user %s is owner", member.GroupID, member.UserID))
}
}
for i := 0; i < len(req.Members); i++ {
if err := CallbackBeforeSetGroupMemberInfo(ctx, req.Members[i]); err != nil {
return nil, err
}
if opMember.RoleLevel <= member.RoleLevel {
return nil, constant.ErrNoPermission.Wrap(fmt.Sprintf("self RoleLevel %d target %d", opMember.RoleLevel, member.RoleLevel))
}
err = s.GroupInterface.UpdateGroupMembers(ctx, utils.Slice(req.Members, func(e *pbGroup.SetGroupMemberInfo) *controller.BatchUpdateGroupMember {
return &controller.BatchUpdateGroupMember{
GroupID: e.GroupID,
UserID: e.UserID,
Map: UpdateGroupMemberMap(e),
}
}
if err := CallbackBeforeSetGroupMemberInfo(ctx, req); err != nil {
}))
if err != nil {
return nil, err
}
if err := s.GroupInterface.UpdateGroupMember(ctx, req.GroupID, req.UserID, UpdateGroupMemberMap(req)); err != nil {
return nil, err
for _, member := range req.Members {
chat.GroupMemberInfoSetNotification(tracelog.GetOperationID(ctx), tracelog.GetOpUserID(ctx), member.GroupID, member.UserID)
}
chat.GroupMemberInfoSetNotification(tracelog.GetOperationID(ctx), tracelog.GetOpUserID(ctx), req.GroupID, req.UserID)
return resp, nil
}
@ -1038,3 +1066,13 @@ func (s *groupServer) GetUserInGroupMembers(ctx context.Context, req *pbGroup.Ge
})
return resp, nil
}
func (s *groupServer) GetGroupMemberUserID(ctx context.Context, req *pbGroup.GetGroupMemberUserIDReq) (*pbGroup.GetGroupMemberUserIDResp, error) {
resp := &pbGroup.GetGroupMemberUserIDResp{}
userIDs, err := s.GroupInterface.FindGroupMemberUserID(ctx, req.GroupID)
if err != nil {
return nil, err
}
resp.UserIDs = userIDs
return resp, nil
}

View File

@ -58,7 +58,7 @@ package apistruct
//type GetBlackListResp struct {
// CommResp
// BlackUserInfoList []*open_im_sdk.PublicUserInfo `json:"-"`
// Data []map[string]interface{} `json:"data" swaggerignore:"true"`
// Map []map[string]interface{} `json:"data" swaggerignore:"true"`
//}
//
////type PublicUserInfo struct {
@ -100,7 +100,7 @@ package apistruct
//type GetFriendsInfoResp struct {
// CommResp
// FriendInfoList []*open_im_sdk.FriendInfo `json:"-"`
// Data []map[string]interface{} `json:"data" swaggerignore:"true"`
// Map []map[string]interface{} `json:"data" swaggerignore:"true"`
//}
//
//type GetFriendListReq struct {
@ -110,7 +110,7 @@ package apistruct
//type GetFriendListResp struct {
// CommResp
// FriendInfoList []*open_im_sdk.FriendInfo `json:"-"`
// Data []map[string]interface{} `json:"data" swaggerignore:"true"`
// Map []map[string]interface{} `json:"data" swaggerignore:"true"`
//}
//
//type GetFriendApplyListReq struct {
@ -120,7 +120,7 @@ package apistruct
//type GetFriendApplyListResp struct {
// CommResp
// FriendRequestList []*open_im_sdk.FriendRequest `json:"-"`
// Data []map[string]interface{} `json:"data" swaggerignore:"true"`
// Map []map[string]interface{} `json:"data" swaggerignore:"true"`
//}
//
//type GetSelfApplyListReq struct {
@ -130,7 +130,7 @@ package apistruct
//type GetSelfApplyListResp struct {
// CommResp
// FriendRequestList []*open_im_sdk.FriendRequest `json:"-"`
// Data []map[string]interface{} `json:"data" swaggerignore:"true"`
// Map []map[string]interface{} `json:"data" swaggerignore:"true"`
//}
type FriendInfo struct {

View File

@ -92,7 +92,7 @@ type GetGroupAllMemberResp struct {
//type GetGroupAllMemberListBySplitResp struct {
// CommResp
// MemberList []*open_im_sdk.GroupMemberFullInfo `json:"-"`
// Data []map[string]interface{} `json:"data" swaggerignore:"true"`
// Map []map[string]interface{} `json:"data" swaggerignore:"true"`
//}
type CreateGroupReq struct {

View File

@ -621,15 +621,6 @@ func initConfig(config interface{}, configName, configPath string) {
func InitConfig(configPath string) {
initConfig(&Config, "config.yaml", configPath)
initConfig(&UsualConfig, "usualConfig.yaml", configPath)
if Config.Etcd.UserName == "" {
Config.Etcd.UserName = UsualConfig.Etcd.UserName
}
if Config.Etcd.Password == "" {
Config.Etcd.Password = UsualConfig.Etcd.Password
}
if Config.Etcd.Secret == "" {
Config.Etcd.Secret = UsualConfig.Etcd.Secret
}
if Config.Mysql.DBUserName == "" {
Config.Mysql.DBUserName = UsualConfig.Mysql.DBUserName

View File

@ -148,29 +148,6 @@ func (c *ConversationRedis) GetUserConversationIDs1(ctx context.Context, ownerUs
// return t, nil
//}
func GetCache[T any](ctx context.Context, rcClient *rockscache.Client, key string, expire time.Duration, fn func(ctx context.Context) (T, error)) (T, error) {
v, err := rcClient.Fetch(key, expire, func() (string, error) {
v, err := fn(ctx)
if err != nil {
return "", err
}
bs, err := json.Marshal(v)
if err != nil {
return "", utils.Wrap(err, "")
}
return string(bs), nil
})
var t T
if err != nil {
return t, err
}
err = json.Unmarshal([]byte(v), &t)
if err != nil {
return t, utils.Wrap(err, "")
}
return t, nil
}
func (c *ConversationRedis) DelUserConversationIDs(ctx context.Context, ownerUserID string) (err error) {
defer func() {
tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "ownerUserID", ownerUserID)

View File

@ -37,19 +37,18 @@ type GroupCache interface {
BatchDelJoinedSuperGroupIDs(ctx context.Context, userIDs []string, fn func(ctx context.Context, userIDs []string) error) (err error)
GetJoinedSuperGroupIDs(ctx context.Context, userID string, fn func(ctx context.Context, userID string) (joinedSuperGroupIDs []string, err error)) (joinedSuperGroupIDs []string, err error)
DelJoinedSuperGroupIDs(ctx context.Context, userID string, fn func(ctx context.Context, userID string) error) (err error)
DelJoinedSuperGroupIDs(ctx context.Context, userID string) (err error)
GetGroupMembersHash(ctx context.Context, groupID string, fn func(ctx context.Context, groupID string) (hashCodeUint64 uint64, err error)) (hashCodeUint64 uint64, err error)
DelGroupMembersHash(ctx context.Context, groupID string) (err error)
GetGroupMemberIDs(ctx context.Context, groupID string, fn func(ctx context.Context, groupID string) (groupMemberIDs []string, err error)) (groupMemberIDs []string, err error)
DelGroupMemberIDs(ctx context.Context, groupID string)
DelGroupMemberIDs(ctx context.Context, groupID string) error
GetJoinedGroupIDs(ctx context.Context, userID string, fn func(ctx context.Context, userID string) (joinedGroupIDs []string, err error)) (joinedGroupIDs []string, err error)
DelJoinedGroupIDs(ctx context.Context, userID string) (err error)
GetGroupMemberInfo(ctx context.Context, groupID, userID string, fn func(ctx context.Context, groupID, userID string) (groupMember *relationTb.GroupMemberModel, err error)) (groupMember *relationTb.GroupMemberModel, err error)
GetGroupMembersInfo(ctx context.Context, count, offset int32, groupID string, fn func(ctx context.Context, count, offset int32, groupID string) (groupMembers []*relationTb.GroupMemberModel, err error)) (groupMembers []*relationTb.GroupMemberModel, err error)
DelGroupMemberInfo(ctx context.Context, groupID, userID string) (err error)
GetGroupMemberNum(ctx context.Context, groupID string, fn func(ctx context.Context, groupID string) (num int, err error)) (num int, err error)
@ -57,16 +56,16 @@ type GroupCache interface {
}
type GroupCacheRedis struct {
group *relation.GroupGorm
groupMember *relation.GroupMemberGorm
groupRequest *relation.GroupRequestGorm
group relationTb.GroupModelInterface
groupMember relationTb.GroupMemberModelInterface
groupRequest relationTb.GroupRequestModelInterface
mongoDB *unrelation.SuperGroupMongoDriver
expireTime time.Duration
redisClient *RedisClient
rcClient *rockscache.Client
}
func NewGroupCacheRedis(rdb redis.UniversalClient, groupDB *relation.GroupGorm, groupMemberDB *relation.GroupMemberGorm, groupRequestDB *relation.GroupRequestGorm, mongoClient *unrelation.SuperGroupMongoDriver, opts rockscache.Options) *GroupCacheRedis {
func NewGroupCacheRedis(rdb redis.UniversalClient, groupDB relationTb.GroupModelInterface, groupMemberDB relationTb.GroupMemberModelInterface, groupRequestDB relationTb.GroupRequestModelInterface, mongoClient *unrelation.SuperGroupMongoDriver, opts rockscache.Options) *GroupCacheRedis {
return &GroupCacheRedis{rcClient: rockscache.NewClient(rdb, opts), expireTime: groupExpireTime,
group: groupDB, groupMember: groupMemberDB, groupRequest: groupRequestDB, redisClient: NewRedisClient(rdb),
mongoDB: mongoClient,
@ -106,39 +105,16 @@ func (g *GroupCacheRedis) getGroupMemberNumKey(groupID string) string {
}
// / groupInfo
func (g *GroupCacheRedis) GetGroupsInfo(ctx context.Context, groupIDs []string) (groups []*relation.Group, err error) {
for _, groupID := range groupIDs {
group, err := g.GetGroupInfo(ctx, groupID)
if err != nil {
return nil, err
}
groups = append(groups, group)
}
return groups, nil
func (g *GroupCacheRedis) GetGroupsInfo(ctx context.Context, groupIDs []string) (groups []*relationTb.GroupModel, err error) {
return GetCacheFor(ctx, g.rcClient, groupIDs, func(ctx context.Context, groupID string) (*relationTb.GroupModel, error) {
return g.GetGroupInfo(ctx, groupID)
})
}
func (g *GroupCacheRedis) GetGroupInfo(ctx context.Context, groupID string) (group *relation.GroupGorm, err error) {
getGroup := func() (string, error) {
groupInfo, err := g.group.Take(ctx, groupID)
if err != nil {
return "", utils.Wrap(err, "")
}
bytes, err := json.Marshal(groupInfo)
if err != nil {
return "", utils.Wrap(err, "")
}
return string(bytes), nil
}
group = &relation.GroupGorm{}
defer func() {
tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupID", groupID, "group", *group)
}()
groupStr, err := g.rcClient.Fetch(g.getGroupInfoKey(groupID), g.expireTime, getGroup)
if err != nil {
return nil, err
}
err = json.Unmarshal([]byte(groupStr), group)
return group, utils.Wrap(err, "")
func (g *GroupCacheRedis) GetGroupInfo(ctx context.Context, groupID string) (group *relationTb.GroupModel, err error) {
return GetCache(ctx, g.rcClient, g.getGroupInfoKey(groupID), g.expireTime, func(ctx context.Context) (*relationTb.GroupModel, error) {
return g.group.Take(ctx, groupID)
})
}
func (g *GroupCacheRedis) DelGroupInfo(ctx context.Context, groupID string) (err error) {
@ -339,6 +315,11 @@ func (g *GroupCacheRedis) GetGroupMemberInfo(ctx context.Context, groupID, userI
return groupMember, utils.Wrap(err, "")
}
func (g *GroupCacheRedis) GetGroupMembersInfo(ctx context.Context, groupID, userIDs []string) (groupMember *relationTb.GroupMemberModel, err error) {
return nil, err
}
func (g *GroupCacheRedis) GetGroupMembersInfo(ctx context.Context, count, offset int32, groupID string) (groupMembers []*relation.GroupMember, err error) {
defer func() {
tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "count", count, "offset", offset, "groupID", groupID, "groupMember", groupMembers)

View File

@ -20,10 +20,10 @@ import (
)
const (
userIncrSeq = "REDIS_USER_INCR_SEQ:" // user incr seq
appleDeviceToken = "DEVICE_TOKEN"
userMinSeq = "REDIS_USER_MIN_SEQ:"
uidPidToken = "UID_PID_TOKEN_STATUS:"
userIncrSeq = "REDIS_USER_INCR_SEQ:" // user incr seq
appleDeviceToken = "DEVICE_TOKEN"
userMinSeq = "REDIS_USER_MIN_SEQ:"
getuiToken = "GETUI_TOKEN"
getuiTaskID = "GETUI_TASK_ID"
messageCache = "MESSAGE_CACHE:"
@ -94,33 +94,33 @@ func NewRedisClient(rdb redis.UniversalClient) *RedisClient {
return &RedisClient{rdb: rdb}
}
//Perform seq auto-increment operation of user messages
// Perform seq auto-increment operation of user messages
func (r *RedisClient) IncrUserSeq(uid string) (uint64, error) {
key := userIncrSeq + uid
seq, err := r.rdb.Incr(context.Background(), key).Result()
return uint64(seq), err
}
//Get the largest Seq
// Get the largest Seq
func (r *RedisClient) GetUserMaxSeq(uid string) (uint64, error) {
key := userIncrSeq + uid
seq, err := r.rdb.Get(context.Background(), key).Result()
return uint64(utils.StringToInt(seq)), err
}
//set the largest Seq
// set the largest Seq
func (r *RedisClient) SetUserMaxSeq(uid string, maxSeq uint64) error {
key := userIncrSeq + uid
return r.rdb.Set(context.Background(), key, maxSeq, 0).Err()
}
//Set the user's minimum seq
// Set the user's minimum seq
func (r *RedisClient) SetUserMinSeq(uid string, minSeq uint32) (err error) {
key := userMinSeq + uid
return r.rdb.Set(context.Background(), key, minSeq, 0).Err()
}
//Get the smallest Seq
// Get the smallest Seq
func (r *RedisClient) GetUserMinSeq(uid string) (uint64, error) {
key := userMinSeq + uid
seq, err := r.rdb.Get(context.Background(), key).Result()
@ -159,7 +159,7 @@ func (r *RedisClient) SetGroupMinSeq(groupID string, minSeq uint32) error {
return r.rdb.Set(context.Background(), key, minSeq, 0).Err()
}
//Store userid and platform class to redis
// Store userid and platform class to redis
func (r *RedisClient) AddTokenFlag(userID string, platformID int, token string, flag int) error {
key := uidPidToken + userID + ":" + constant.PlatformIDToName(platformID)
log2.NewDebug("", "add token key is ", key)

75
pkg/common/db/cache/token.go vendored Normal file
View File

@ -0,0 +1,75 @@
package cache
import (
"Open_IM/pkg/common/constant"
"Open_IM/pkg/common/tokenverify"
"Open_IM/pkg/utils"
"context"
go_redis "github.com/go-redis/redis/v8"
"github.com/golang-jwt/jwt/v4"
)
const (
uidPidToken = "UID_PID_TOKEN_STATUS:"
)
type Token interface {
//结果为空 不返回错误
GetTokensWithoutError(ctx context.Context, userID, platform string) (map[string]int, error)
//创建token
CreateToken(ctx context.Context, userID string, platformID int) (string, error)
}
type TokenRedis struct {
RedisClient *RedisClient
AccessSecret string
AccessExpire int64
}
func NewTokenRedis(redisClient *RedisClient, accessSecret string, accessExpire int64) *TokenRedis {
return &TokenRedis{redisClient, accessSecret, accessExpire}
}
// 结果为空 不返回错误
func (t *TokenRedis) GetTokensWithoutError(ctx context.Context, userID, platform string) (map[string]int, error) {
key := uidPidToken + userID + ":" + platform
m, err := t.RedisClient.GetClient().HGetAll(context.Background(), key).Result()
if err != nil && err == go_redis.Nil {
return nil, nil
}
mm := make(map[string]int)
for k, v := range m {
mm[k] = utils.StringToInt(v)
}
return mm, utils.Wrap(err, "")
}
// 创建token
func (t *TokenRedis) CreateToken(ctx context.Context, userID string, platform string) (string, error) {
tokens, err := t.GetTokensWithoutError(ctx, userID, platform)
if err != nil {
return "", err
}
var deleteTokenKey []string
for k, v := range tokens {
_, err = tokenverify.GetClaimFromToken(k)
if err != nil || v != constant.NormalToken {
deleteTokenKey = append(deleteTokenKey, k)
}
}
if len(deleteTokenKey) != 0 {
key := uidPidToken + userID + ":" + platform
err := t.RedisClient.GetClient().HDel(context.Background(), key, deleteTokenKey...).Err()
if err != nil {
return "", err
}
}
claims := tokenverify.BuildClaims(userID, platform, t.AccessExpire)
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
tokenString, err := token.SignedString([]byte(t.AccessSecret))
if err != nil {
return "", utils.Wrap(err, "")
}
key := uidPidToken + userID + ":" + platform
return "", utils.Wrap(t.RedisClient.GetClient().HSet(context.Background(), key, tokenString, constant.NormalToken).Err(), "")
}

49
pkg/common/db/cache/utils.go vendored Normal file
View File

@ -0,0 +1,49 @@
package cache
import (
"Open_IM/pkg/utils"
"context"
"encoding/json"
"github.com/dtm-labs/rockscache"
"time"
)
func GetCache[T any](ctx context.Context, rcClient *rockscache.Client, key string, expire time.Duration, fn func(ctx context.Context) (T, error)) (T, error) {
var t T
var write bool
v, err := rcClient.Fetch(key, expire, func() (s string, err error) {
t, err = fn(ctx)
if err != nil {
return "", err
}
bs, err := json.Marshal(t)
if err != nil {
return "", utils.Wrap(err, "")
}
write = true
return string(bs), nil
})
if err != nil {
return t, err
}
if write {
return t, nil
}
err = json.Unmarshal([]byte(v), &t)
if err != nil {
return t, utils.Wrap(err, "")
}
return t, nil
}
func GetCacheFor[E any, T any](ctx context.Context, rcClient *rockscache.Client, list []E, fn func(ctx context.Context, item E) (T, error)) ([]T, error) {
rs := make([]T, 0, len(list))
for _, e := range list {
r, err := fn(ctx, e)
if err != nil {
return nil, err
}
rs = append(rs, r)
}
return rs, nil
}

View File

@ -1,9 +1,34 @@
package controller
import "context"
import (
"Open_IM/pkg/common/db/cache"
"context"
"github.com/go-redis/redis/v8"
)
type AuthInterface interface {
GetTokens(ctx context.Context, userID, platform string) (map[string]int, error)
DeleteToken(ctx context.Context, userID, platform string) error
CreateToken(ctx context.Context, userID string, platformID int, ttl int64) (string, error)
//结果为空 不返回错误
GetTokensWithoutError(ctx context.Context, userID, platform string) (map[string]int, error)
//创建token
CreateToken(ctx context.Context, userID string, platform string) (string, error)
}
type AuthController struct {
database *cache.TokenRedis
}
func NewAuthController(rdb redis.UniversalClient, accessSecret string, accessExpire int64) *AuthController {
cache.NewRedisClient(rdb)
return &AuthController{database: cache.NewTokenRedis(cache.NewRedisClient(rdb), accessSecret, accessExpire)}
}
// 结果为空 不返回错误
func (a *AuthController) GetTokensWithoutError(ctx context.Context, userID, platform string) (map[string]int, error) {
return a.database.GetTokensWithoutError(ctx, userID, platform)
}
// 创建token
func (a *AuthController) CreateToken(ctx context.Context, userID string, platform string) (string, error) {
return a.database.CreateToken(ctx, userID, platform)
}

View File

@ -19,6 +19,12 @@ import (
//type GroupInterface GroupDataBaseInterface
type BatchUpdateGroupMember struct {
GroupID string
UserID string
Map map[string]any
}
type GroupInterface interface {
CreateGroup(ctx context.Context, groups []*relationTb.GroupModel, groupMembers []*relationTb.GroupMemberModel) error
TakeGroup(ctx context.Context, groupID string) (group *relationTb.GroupModel, err error)
@ -30,6 +36,7 @@ type GroupInterface interface {
TakeGroupMember(ctx context.Context, groupID string, userID string) (groupMember *relationTb.GroupMemberModel, err error)
TakeGroupOwner(ctx context.Context, groupID string) (*relationTb.GroupMemberModel, error)
FindGroupMember(ctx context.Context, groupIDs []string, userIDs []string, roleLevels []int32) ([]*relationTb.GroupMemberModel, error)
FindGroupMemberUserID(ctx context.Context, groupID string) ([]string, error)
PageGroupMember(ctx context.Context, groupIDs []string, userIDs []string, roleLevels []int32, pageNumber, showNumber int32) (uint32, []*relationTb.GroupMemberModel, error)
SearchGroupMember(ctx context.Context, keyword string, groupIDs []string, userIDs []string, roleLevels []int32, pageNumber, showNumber int32) (uint32, []*relationTb.GroupMemberModel, error)
HandlerGroupRequest(ctx context.Context, groupID string, userID string, handledMsg string, handleResult int32, member *relationTb.GroupMemberModel) error
@ -37,7 +44,8 @@ type GroupInterface interface {
MapGroupMemberUserID(ctx context.Context, groupIDs []string) (map[string][]string, error)
MapGroupMemberNum(ctx context.Context, groupIDs []string) (map[string]uint32, error)
TransferGroupOwner(ctx context.Context, groupID string, oldOwnerUserID, newOwnerUserID string, roleLevel int32) error // 转让群
UpdateGroupMember(ctx context.Context, groupID, userID string, data map[string]any) error
UpdateGroupMember(ctx context.Context, groupID string, userID string, data map[string]any) error
UpdateGroupMembers(ctx context.Context, data []*BatchUpdateGroupMember) error
// GroupRequest
CreateGroupRequest(ctx context.Context, requests []*relationTb.GroupRequestModel) error
TakeGroupRequest(ctx context.Context, groupID string, userID string) (*relationTb.GroupRequestModel, error)
@ -61,6 +69,10 @@ type GroupController struct {
database GroupDataBaseInterface
}
func (g *GroupController) FindGroupMemberUserID(ctx context.Context, groupID string) ([]string, error) {
return g.database.FindGroupMemberUserID(ctx, groupID)
}
func (g *GroupController) CreateGroup(ctx context.Context, groups []*relationTb.GroupModel, groupMembers []*relationTb.GroupMemberModel) error {
return g.database.CreateGroup(ctx, groups, groupMembers)
}
@ -125,7 +137,11 @@ func (g *GroupController) TransferGroupOwner(ctx context.Context, groupID string
return g.database.TransferGroupOwner(ctx, groupID, oldOwnerUserID, newOwnerUserID, roleLevel)
}
func (g *GroupController) UpdateGroupMember(ctx context.Context, groupID, userID string, data map[string]any) error {
func (g *GroupController) UpdateGroupMembers(ctx context.Context, data []*BatchUpdateGroupMember) error {
return g.database.UpdateGroupMembers(ctx, data)
}
func (g *GroupController) UpdateGroupMember(ctx context.Context, groupID string, userID string, data map[string]any) error {
return g.database.UpdateGroupMember(ctx, groupID, userID, data)
}
@ -141,9 +157,6 @@ func (g *GroupController) PageGroupRequestUser(ctx context.Context, userID strin
return g.database.PageGroupRequestUser(ctx, userID, pageNumber, showNumber)
}
// func (g *GroupController) TakeSuperGroup(ctx context.Context, groupID string) (superGroup *unrelationTb.SuperGroupModel, err error) {
// return g.database.TakeSuperGroup(ctx, groupID)
// }
func (g *GroupController) FindSuperGroup(ctx context.Context, groupIDs []string) ([]*unrelationTb.SuperGroupModel, error) {
return g.database.FindSuperGroup(ctx, groupIDs)
}
@ -179,6 +192,7 @@ type GroupDataBaseInterface interface {
TakeGroupMember(ctx context.Context, groupID string, userID string) (groupMember *relationTb.GroupMemberModel, err error)
TakeGroupOwner(ctx context.Context, groupID string) (*relationTb.GroupMemberModel, error)
FindGroupMember(ctx context.Context, groupIDs []string, userIDs []string, roleLevels []int32) ([]*relationTb.GroupMemberModel, error)
FindGroupMemberUserID(ctx context.Context, groupID string) ([]string, error)
PageGroupMember(ctx context.Context, groupIDs []string, userIDs []string, roleLevels []int32, pageNumber, showNumber int32) (uint32, []*relationTb.GroupMemberModel, error)
SearchGroupMember(ctx context.Context, keyword string, groupIDs []string, userIDs []string, roleLevels []int32, pageNumber, showNumber int32) (uint32, []*relationTb.GroupMemberModel, error)
HandlerGroupRequest(ctx context.Context, groupID string, userID string, handledMsg string, handleResult int32, member *relationTb.GroupMemberModel) error
@ -186,7 +200,8 @@ type GroupDataBaseInterface interface {
MapGroupMemberUserID(ctx context.Context, groupIDs []string) (map[string][]string, error)
MapGroupMemberNum(ctx context.Context, groupIDs []string) (map[string]uint32, error)
TransferGroupOwner(ctx context.Context, groupID string, oldOwnerUserID, newOwnerUserID string, roleLevel int32) error // 转让群
UpdateGroupMember(ctx context.Context, groupID, userID string, data map[string]any) error
UpdateGroupMember(ctx context.Context, groupID string, userID string, data map[string]any) error
UpdateGroupMembers(ctx context.Context, data []*BatchUpdateGroupMember) error
// GroupRequest
CreateGroupRequest(ctx context.Context, requests []*relationTb.GroupRequestModel) error
TakeGroupRequest(ctx context.Context, groupID string, userID string) (*relationTb.GroupRequestModel, error)
@ -211,7 +226,7 @@ func NewGroupDatabase(db *gorm.DB, rdb redis.UniversalClient, mgoClient *mongo.C
groupMemberDB: groupMemberDB,
groupRequestDB: groupRequestDB,
db: &newDB,
cache: cache.NewGroupCache(rdb, groupDB, groupMemberDB, groupRequestDB, SuperGroupMongoDriver, rockscache.Options{
cache: cache.NewGroupCacheRedis(rdb, groupDB, groupMemberDB, groupRequestDB, SuperGroupMongoDriver, rockscache.Options{
RandomExpireAdjustment: 0.2,
DisableCacheRead: false,
DisableCacheDelete: false,
@ -230,10 +245,36 @@ type GroupDataBase struct {
groupRequestDB relationTb.GroupRequestModelInterface
db *gorm.DB
cache *cache.GroupCache
//cache cache.GroupCache
cache *cache.GroupCacheRedis
mongoDB *unrelation.SuperGroupMongoDriver
}
func (g *GroupDataBase) delGroupMemberCache(ctx context.Context, groupID string, userIDs []string) error {
for _, userID := range userIDs {
if err := g.cache.DelJoinedGroupIDs(ctx, userID); err != nil {
return err
}
if err := g.cache.DelJoinedSuperGroupIDs(ctx, userID); err != nil {
return err
}
}
if err := g.cache.DelGroupMemberIDs(ctx, groupID); err != nil {
return err
}
if err := g.cache.DelGroupMemberNum(ctx, groupID); err != nil {
return err
}
if err := g.cache.DelGroupMembersHash(ctx, groupID); err != nil {
return err
}
return nil
}
func (g *GroupDataBase) FindGroupMemberUserID(ctx context.Context, groupID string) ([]string, error) {
return g.cache.GetGroupMemberIDs(ctx, groupID)
}
func (g *GroupDataBase) CreateGroup(ctx context.Context, groups []*relationTb.GroupModel, groupMembers []*relationTb.GroupMemberModel) error {
if len(groups) > 0 && len(groupMembers) > 0 {
return g.db.Transaction(func(tx *gorm.DB) error {
@ -253,11 +294,11 @@ func (g *GroupDataBase) CreateGroup(ctx context.Context, groups []*relationTb.Gr
}
func (g *GroupDataBase) TakeGroup(ctx context.Context, groupID string) (group *relationTb.GroupModel, err error) {
return g.groupDB.Take(ctx, groupID)
return g.cache.GetGroupInfo(ctx, groupID)
}
func (g *GroupDataBase) FindGroup(ctx context.Context, groupIDs []string) (groups []*relationTb.GroupModel, err error) {
return g.groupDB.Find(ctx, groupIDs)
return g.cache.GetGroupsInfo(ctx, groupIDs)
}
func (g *GroupDataBase) SearchGroup(ctx context.Context, keyword string, pageNumber, showNumber int32) (uint32, []*relationTb.GroupModel, error) {
@ -265,7 +306,15 @@ func (g *GroupDataBase) SearchGroup(ctx context.Context, keyword string, pageNum
}
func (g *GroupDataBase) UpdateGroup(ctx context.Context, groupID string, data map[string]any) error {
return g.groupDB.UpdateMap(ctx, groupID, data)
return g.db.Transaction(func(tx *gorm.DB) error {
if err := g.groupDB.UpdateMap(ctx, groupID, data, tx); err != nil {
return err
}
if err := g.cache.DelGroupInfo(ctx, groupID); err != nil {
return err
}
return nil
})
}
func (g *GroupDataBase) DismissGroup(ctx context.Context, groupID string) error {
@ -273,13 +322,22 @@ func (g *GroupDataBase) DismissGroup(ctx context.Context, groupID string) error
if err := g.groupDB.UpdateStatus(ctx, groupID, constant.GroupStatusDismissed, tx); err != nil {
return err
}
return g.groupMemberDB.DeleteGroup(ctx, []string{groupID}, tx)
if err := g.groupMemberDB.DeleteGroup(ctx, []string{groupID}, tx); err != nil {
return err
}
userIDs, err := g.cache.GetGroupMemberIDs(ctx, groupID)
if err != nil {
return err
}
if err := g.delGroupMemberCache(ctx, groupID, userIDs); err != nil {
return err
}
return nil
})
}
func (g *GroupDataBase) TakeGroupMember(ctx context.Context, groupID string, userID string) (groupMember *relationTb.GroupMemberModel, err error) {
return g.groupMemberDB.Take(ctx, groupID, userID)
return g.cache.GetGroupMemberInfo(ctx, groupID, userID)
}
func (g *GroupDataBase) TakeGroupOwner(ctx context.Context, groupID string) (*relationTb.GroupMemberModel, error) {
@ -287,6 +345,7 @@ func (g *GroupDataBase) TakeGroupOwner(ctx context.Context, groupID string) (*re
}
func (g *GroupDataBase) FindGroupMember(ctx context.Context, groupIDs []string, userIDs []string, roleLevels []int32) ([]*relationTb.GroupMemberModel, error) {
//g.cache.GetGroupMembersInfo()
return g.groupMemberDB.Find(ctx, groupIDs, userIDs, roleLevels)
}
@ -299,19 +358,32 @@ func (g *GroupDataBase) SearchGroupMember(ctx context.Context, keyword string, g
}
func (g *GroupDataBase) HandlerGroupRequest(ctx context.Context, groupID string, userID string, handledMsg string, handleResult int32, member *relationTb.GroupMemberModel) error {
if member == nil {
return g.groupRequestDB.UpdateHandler(ctx, groupID, userID, handledMsg, handleResult)
}
return g.db.Transaction(func(tx *gorm.DB) error {
if err := g.groupRequestDB.UpdateHandler(ctx, groupID, userID, handledMsg, handleResult, tx); err != nil {
return err
}
return g.groupMemberDB.Create(ctx, []*relationTb.GroupMemberModel{member}, tx)
if member != nil {
if err := g.groupMemberDB.Create(ctx, []*relationTb.GroupMemberModel{member}, tx); err != nil {
return err
}
if err := g.delGroupMemberCache(ctx, groupID, []string{userID}); err != nil {
return err
}
}
return nil
})
}
func (g *GroupDataBase) DeleteGroupMember(ctx context.Context, groupID string, userIDs []string) error {
return g.groupMemberDB.Delete(ctx, groupID, userIDs)
return g.db.Transaction(func(tx *gorm.DB) error {
if err := g.groupMemberDB.Delete(ctx, groupID, userIDs, tx); err != nil {
return err
}
if err := g.delGroupMemberCache(ctx, groupID, userIDs); err != nil {
return err
}
return nil
})
}
func (g *GroupDataBase) MapGroupMemberUserID(ctx context.Context, groupIDs []string) (map[string][]string, error) {
@ -338,12 +410,37 @@ func (g *GroupDataBase) TransferGroupOwner(ctx context.Context, groupID string,
if rowsAffected != 1 {
return utils.Wrap(fmt.Errorf("newOwnerUserID %s rowsAffected = %d", newOwnerUserID, rowsAffected), "")
}
if err := g.delGroupMemberCache(ctx, groupID, []string{oldOwnerUserID, newOwnerUserID}); err != nil {
return err
}
return nil
})
}
func (g *GroupDataBase) UpdateGroupMember(ctx context.Context, groupID, userID string, data map[string]any) error {
return g.groupMemberDB.Update(ctx, groupID, userID, data)
func (g *GroupDataBase) UpdateGroupMember(ctx context.Context, groupID string, userID string, data map[string]any) error {
return g.db.Transaction(func(tx *gorm.DB) error {
if err := g.groupMemberDB.Update(ctx, groupID, userID, data, tx); err != nil {
return err
}
if err := g.cache.DelGroupMemberInfo(ctx, groupID, userID); err != nil {
return err
}
return nil
})
}
func (g *GroupDataBase) UpdateGroupMembers(ctx context.Context, data []*BatchUpdateGroupMember) error {
return g.db.Transaction(func(tx *gorm.DB) error {
for _, item := range data {
if err := g.groupMemberDB.Update(ctx, item.GroupID, item.UserID, item.Map, tx); err != nil {
return err
}
if err := g.cache.DelGroupMemberInfo(ctx, item.GroupID, item.UserID); err != nil {
return err
}
}
return nil
})
}
func (g *GroupDataBase) CreateGroupRequest(ctx context.Context, requests []*relationTb.GroupRequestModel) error {

View File

@ -52,8 +52,7 @@ func (g *GroupLocalCache) GetGroupMemberIDs(ctx context.Context, groupID string)
if ok && localHashInfo.memberListHash == resp.GroupAbstractInfos[0].GroupMemberListHash {
return localHashInfo.userIDs, nil
}
groupMembersResp, err := client.GetGroupMemberList(ctx, &group.GetGroupMemberListReq{
groupMembersResp, err := client.GetGroupMemberUserID(ctx, &group.GetGroupMemberUserIDReq{
GroupID: groupID,
})
if err != nil {
@ -61,7 +60,7 @@ func (g *GroupLocalCache) GetGroupMemberIDs(ctx context.Context, groupID string)
}
g.cache[groupID] = GroupMemberIDsHash{
memberListHash: resp.GroupAbstractInfos[0].GroupMemberListHash,
userIDs: groupMembersResp.Members,
userIDs: groupMembersResp.UserIDs,
}
return g.cache[groupID].userIDs, nil
}

View File

@ -40,13 +40,6 @@ func (g *GroupMemberGorm) DeleteGroup(ctx context.Context, groupIDs []string, tx
return utils.Wrap(getDBConn(g.DB, tx).Where("group_id in (?)", groupIDs).Delete(&relation.GroupMemberModel{}).Error, "")
}
//func (g *GroupMemberGorm) UpdateByMap(ctx context.Context, groupID string, userID string, args map[string]interface{}, tx ...any) (err error) {
// defer func() {
// tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupID", groupID, "userID", userID, "args", args)
// }()
// return utils.Wrap(getDBConn(g.DB, tx).Model(&relation.GroupMemberModel{}).Where("group_id = ? and user_id = ?", groupID, userID).Updates(args).Error, "")
//}
func (g *GroupMemberGorm) Update(ctx context.Context, groupID string, userID string, data map[string]any, tx ...any) (err error) {
defer func() {
tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupID", groupID, "userID", userID, "data", data)
@ -81,23 +74,6 @@ func (g *GroupMemberGorm) Find(ctx context.Context, groupIDs []string, userIDs [
return groupList, utils.Wrap(db.Find(&groupList).Error, "")
}
//func (g *GroupMemberGorm) FindGroupUser(ctx context.Context, groupIDs []string, userIDs []string, roleLevels []int32, tx ...any) (groupList []*relation.GroupMemberModel, err error) {
// defer func() {
// tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupIDs", groupIDs, "userIDs", userIDs, "groupList", groupList)
// }()
// db := getDBConn(g.DB, tx)
// if len(groupList) > 0 {
// db = db.Where("group_id in (?)", groupIDs)
// }
// if len(userIDs) > 0 {
// db = db.Where("user_id in (?)", userIDs)
// }
// if len(roleLevels) > 0 {
// db = db.Where("role_level in (?)", roleLevels)
// }
// return groupList, utils.Wrap(db.Find(&groupList).Error, "")
//}
func (g *GroupMemberGorm) Take(ctx context.Context, groupID string, userID string, tx ...any) (groupMember *relation.GroupMemberModel, err error) {
defer func() {
tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupID", groupID, "userID", userID, "groupMember", *groupMember)
@ -149,3 +125,10 @@ func (g *GroupMemberGorm) FindJoinUserID(ctx context.Context, groupIDs []string,
}
return groupUsers, nil
}
func (g *GroupMemberGorm) FindMemberUserID(ctx context.Context, groupID string, tx ...any) (userIDs []string, err error) {
defer func() {
tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "groupID", groupID, "userIDs", userIDs)
}()
return userIDs, utils.Wrap(getDBConn(g.DB, tx).Model(&relation.GroupMemberModel{}).Where("group_id = ?", groupID).Pluck("user_id", &userIDs), "")
}

View File

@ -31,11 +31,10 @@ type GroupMemberModelInterface interface {
Create(ctx context.Context, groupMemberList []*GroupMemberModel, tx ...any) (err error)
Delete(ctx context.Context, groupID string, userIDs []string, tx ...any) (err error)
DeleteGroup(ctx context.Context, groupIDs []string, tx ...any) (err error)
//UpdateByMap(ctx context.Context, groupID string, userID string, args map[string]interface{}, tx ...any) (err error)
Update(ctx context.Context, groupID string, userID string, data map[string]any, tx ...any) (err error)
UpdateRoleLevel(ctx context.Context, groupID string, userID string, roleLevel int32, tx ...any) (rowsAffected int64, err error)
Find(ctx context.Context, groupIDs []string, userIDs []string, roleLevels []int32, tx ...any) (groupList []*GroupMemberModel, err error)
//FindGroupUser(ctx context.Context, groupIDs []string, userIDs []string, roleLevels []int32, tx ...any) (groupList []*GroupMemberModel, err error)
FindMemberUserID(ctx context.Context, groupID string, tx ...any) (userIDs []string, err error)
Take(ctx context.Context, groupID string, userID string, tx ...any) (groupMember *GroupMemberModel, err error)
TakeOwner(ctx context.Context, groupID string, tx ...any) (groupMember *GroupMemberModel, err error)
SearchMember(ctx context.Context, keyword string, groupIDs []string, userIDs []string, roleLevels []int32, pageNumber, showNumber int32, tx ...any) (total uint32, groupList []*GroupMemberModel, err error)

View File

@ -24,7 +24,7 @@ func (f *fileHook) Levels() []logrus.Level {
}
//func (f *fileHook) Fire(entry *logrus.Entry) error {
// entry.Data["FilePath"] = findCaller(6)
// entry.Map["FilePath"] = findCaller(6)
// utils.GetSelfFuncName()
// return nil
//}

File diff suppressed because it is too large Load Diff

View File

@ -227,17 +227,6 @@ message CancelMuteGroupReq{
message CancelMuteGroupResp{
}
message SetGroupMemberNicknameReq{
string groupID = 1;
string nickname = 2;
string userID = 3;
}
message SetGroupMemberNicknameResp{
}
message GetJoinedSuperGroupListReq {
string userID = 1;
}
@ -254,7 +243,7 @@ message GetSuperGroupsInfoResp {
repeated sdkws.GroupInfo groupInfos = 1;
}
message SetGroupMemberInfoReq{
message SetGroupMemberInfo{
string groupID = 1;
string userID = 2;
google.protobuf.StringValue nickname = 3;
@ -263,6 +252,10 @@ message SetGroupMemberInfoReq{
google.protobuf.StringValue ex = 6;
}
message SetGroupMemberInfoReq{
repeated SetGroupMemberInfo members = 1;
}
message SetGroupMemberInfoResp{
}
@ -281,14 +274,25 @@ message GetGroupAbstractInfoResp{
repeated GroupAbstractInfo groupAbstractInfos = 1;
}
message getUserInGroupMembersReq {
message GetUserInGroupMembersReq {
string userID = 1;
repeated string groupIDs = 2;
}
message getUserInGroupMembersResp{
repeated sdkws.GroupMemberFullInfo members = 1;
}
message GetGroupMemberUserIDReq{
string groupID = 1;
}
message GetGroupMemberUserIDResp{
repeated string userIDs = 1;
}
service group{
//
rpc createGroup(CreateGroupReq) returns(CreateGroupResp);
@ -338,13 +342,14 @@ service group{
//
rpc getSuperGroupsInfo(GetSuperGroupsInfoReq) returns (GetSuperGroupsInfoResp);
//
rpc setGroupMemberNickname(SetGroupMemberNicknameReq) returns (SetGroupMemberNicknameResp);
//
rpc setGroupMemberInfo(SetGroupMemberInfoReq) returns (SetGroupMemberInfoResp);
//hash值
rpc getGroupAbstractInfo(GetGroupAbstractInfoReq) returns (GetGroupAbstractInfoResp);
//
rpc getUserInGroupMembers(getUserInGroupMembersReq) returns (getUserInGroupMembersResp);
rpc getUserInGroupMembers(GetUserInGroupMembersReq) returns (GetUserInGroupMembersResp);
//ID
rpc getGroupMemberUserID(GetGroupMemberUserIDReq) returns (GetGroupMemberUserIDResp);
}