From 0a81dd040f64f01b4fbc862c58545d030c0284aa Mon Sep 17 00:00:00 2001 From: withchao <993506633@qq.com> Date: Sun, 29 Jan 2023 18:13:02 +0800 Subject: [PATCH] 1 --- internal/rpc/group/g.go | 16 ++- internal/rpc/group/group.go | 198 +++++++++++++-------------- pkg/common/db/controller/group.go | 7 + pkg/common/token_verify/jwt_token.go | 4 + 4 files changed, 118 insertions(+), 107 deletions(-) diff --git a/internal/rpc/group/g.go b/internal/rpc/group/g.go index 9afde7115..1228a1c15 100644 --- a/internal/rpc/group/g.go +++ b/internal/rpc/group/g.go @@ -5,7 +5,7 @@ import ( relation "Open_IM/pkg/common/db/mysql" "Open_IM/pkg/common/tools" pbGroup "Open_IM/pkg/proto/group" - sdk "Open_IM/pkg/proto/sdk_ws" + sdk_ws "Open_IM/pkg/proto/sdk_ws" "Open_IM/pkg/utils" "context" "math/big" @@ -40,10 +40,22 @@ func getDBGroupMember(ctx context.Context, groupID, userID string) (dbGroupMembe return dbGroupMember, nil } -func getUsersInfo(ctx context.Context, userIDs []string) ([]*sdk.UserInfo, error) { +func getUsersInfo(ctx context.Context, userIDs []string) ([]*sdk_ws.UserInfo, error) { return nil, nil } +func getUserMap(ctx context.Context, userIDs []string) (map[string]*sdk_ws.UserInfo, error) { + users, err := getUsersInfo(ctx, userIDs) + if err != nil { + return nil, err + } + userMap := make(map[string]*sdk_ws.UserInfo) + for i, user := range users { + userMap[user.UserID] = users[i] + } + return userMap, nil +} + func genGroupID(ctx context.Context, groupID string) string { if groupID != "" { return groupID diff --git a/internal/rpc/group/group.go b/internal/rpc/group/group.go index 48154c8e0..a1d51ff9f 100644 --- a/internal/rpc/group/group.go +++ b/internal/rpc/group/group.go @@ -25,13 +25,12 @@ import ( "Open_IM/pkg/utils" "context" "errors" + grpcPrometheus "github.com/grpc-ecosystem/go-grpc-prometheus" "net" "strconv" "strings" "time" - grpcPrometheus "github.com/grpc-ecosystem/go-grpc-prometheus" - "google.golang.org/grpc" "google.golang.org/protobuf/types/known/wrapperspb" "gorm.io/gorm" @@ -259,139 +258,128 @@ func (s *groupServer) GetJoinedGroupList(ctx context.Context, req *pbGroup.GetJo groupNode.NotificationUpdateTime = group.NotificationUpdateTime.UnixMilli() resp.GroupList = append(resp.GroupList, &groupNode) } - resp.Total = uint32(len(resp.GroupList)) + resp.Total = int32(len(resp.GroupList)) return resp, nil } func (s *groupServer) InviteUserToGroup(ctx context.Context, req *pbGroup.InviteUserToGroupReq) (*pbGroup.InviteUserToGroupResp, error) { resp := &pbGroup.InviteUserToGroupResp{} - opUserID := tools.OpUserID(ctx) - if err := token_verify.CheckManagerUserID(ctx, opUserID); err != nil { - if err := relation.CheckIsExistGroupMember(ctx, req.GroupID, opUserID); err != nil { - return nil, err - } + if len(req.InvitedUserIDList) == 0 { + return nil, constant.ErrArgs.Wrap("user empty") } - groupInfo, err := (*relation.Group)(nil).Take(ctx, req.GroupID) + if utils.IsDuplicateID(req.InvitedUserIDList) { + return nil, constant.ErrArgs.Wrap("userID duplicate") + } + group, err := s.GroupInterface.TakeGroupByID(ctx, req.GroupID) if err != nil { return nil, err } - if groupInfo.Status == constant.GroupStatusDismissed { - return nil, utils.Wrap(constant.ErrDismissedAlready, "") + if group.Status == constant.GroupStatusDismissed { + return nil, constant.ErrDismissedAlready.Wrap() } - if groupInfo.NeedVerification == constant.AllNeedVerification && - !relation.IsGroupOwnerAdmin(req.GroupID, tools.OpUserID(ctx)) && !token_verify.IsManagerUserID(tools.OpUserID(ctx)) { - joinReq := pbGroup.JoinGroupReq{} - for _, v := range req.InvitedUserIDList { - var groupRequest relation.GroupRequest - groupRequest.UserID = v - groupRequest.GroupID = req.GroupID - groupRequest.JoinSource = constant.JoinByInvitation - groupRequest.InviterUserID = tools.OpUserID(ctx) - err = relation.InsertIntoGroupRequest(groupRequest) - if err != nil { - var resultNode pbGroup.Id2Result - resultNode.Result = -1 - resultNode.UserID = v - resp.Id2ResultList = append(resp.Id2ResultList, &resultNode) - continue - } else { - var resultNode pbGroup.Id2Result - resultNode.Result = 0 - resultNode.UserID = v - resp.Id2ResultList = append(resp.Id2ResultList, &resultNode) - joinReq.GroupID = req.GroupID - resp.Id2ResultList = append(resp.Id2ResultList, &resultNode) - chat.JoinGroupApplicationNotification(ctx, &joinReq) - } - } - return resp, nil - } - if err := s.DelGroupAndUserCache(ctx, req.GroupID, req.InvitedUserIDList); err != nil { + members, err := s.GroupInterface.GetGroupMemberList(ctx, group.GroupID) + if err != nil { return nil, err } - //from User: invite: applicant - //to user: invite: invited - var okUserIDList []string - if groupInfo.GroupType != constant.SuperGroup { - for _, v := range req.InvitedUserIDList { - var resultNode pbGroup.Id2Result - resultNode.UserID = v - resultNode.Result = 0 - toUserInfo, err := relation.GetUserByUserID(v) - if err != nil { - trace_log.SetCtxInfo(ctx, "GetUserByUserID", err, "userID", v) - resultNode.Result = -1 - resp.Id2ResultList = append(resp.Id2ResultList, &resultNode) - continue - } - - if relation.IsExistGroupMember(req.GroupID, v) { - trace_log.SetCtxInfo(ctx, "IsExistGroupMember", err, "groupID", req.GroupID, "userID", v) - resultNode.Result = -1 - resp.Id2ResultList = append(resp.Id2ResultList, &resultNode) - continue - } - var toInsertInfo relation.GroupMember - utils.CopyStructFields(&toInsertInfo, toUserInfo) - toInsertInfo.GroupID = req.GroupID - toInsertInfo.RoleLevel = constant.GroupOrdinaryUsers - toInsertInfo.OperatorUserID = tools.OpUserID(ctx) - toInsertInfo.InviterUserID = tools.OpUserID(ctx) - toInsertInfo.JoinSource = constant.JoinByInvitation - if err := CallbackBeforeMemberJoinGroup(ctx, tools.OperationID(ctx), &toInsertInfo, groupInfo.Ex); err != nil { - return nil, err - } - err = relation.InsertIntoGroupMember(toInsertInfo) - if err != nil { - trace_log.SetCtxInfo(ctx, "InsertIntoGroupMember", err, "args", toInsertInfo) - resultNode.Result = -1 - resp.Id2ResultList = append(resp.Id2ResultList, &resultNode) - continue - } - okUserIDList = append(okUserIDList, v) - err = db.DB.AddGroupMember(req.GroupID, toUserInfo.UserID) - if err != nil { - trace_log.SetCtxInfo(ctx, "AddGroupMember", err, "groupID", req.GroupID, "userID", toUserInfo.UserID) - } - resp.Id2ResultList = append(resp.Id2ResultList, &resultNode) - } - } else { - okUserIDList = req.InvitedUserIDList - if err := db.DB.AddUserToSuperGroup(req.GroupID, req.InvitedUserIDList); err != nil { - return nil, err + memberMap := make(map[string]*relation.GroupMember) + for i, member := range members { + memberMap[member.GroupID] = members[i] + } + for _, userID := range req.InvitedUserIDList { + if _, ok := memberMap[userID]; ok { + return nil, constant.ErrArgs.Wrap("user in group " + userID) } } - - if groupInfo.GroupType != constant.SuperGroup { - chat.MemberInvitedNotification(tools.OperationID(ctx), req.GroupID, tools.OpUserID(ctx), req.Reason, okUserIDList) - } else { - for _, userID := range req.InvitedUserIDList { - if err := rocksCache.DelJoinedSuperGroupIDListFromCache(ctx, userID); err != nil { - trace_log.SetCtxInfo(ctx, "DelJoinedSuperGroupIDListFromCache", err, "userID", userID) + userMap, err := getUserMap(ctx, req.InvitedUserIDList) + if err != nil { + return nil, err + } + for _, userID := range req.InvitedUserIDList { + if _, ok := userMap[userID]; !ok { + return nil, constant.ErrUserIDNotFound.Wrap(userID) + } + } + if group.NeedVerification == constant.AllNeedVerification { + if !token_verify.IsAppManagerUid(ctx) { + opUserID := tools.OpUserID(ctx) + member, ok := memberMap[opUserID] + if ok { + return nil, constant.ErrNoPermission.Wrap("not in group") + } + if !(member.RoleLevel == constant.GroupOwner || member.RoleLevel == constant.GroupAdmin) { + var requests []*relation.GroupRequest + for _, userID := range req.InvitedUserIDList { + requests = append(requests, &relation.GroupRequest{ + UserID: userID, + GroupID: req.GroupID, + JoinSource: constant.JoinByInvitation, + InviterUserID: opUserID, + }) + } + if err := s.GroupInterface.CreateGroupRequest(ctx, requests); err != nil { + return nil, err + } + for _, request := range requests { + chat.JoinGroupApplicationNotification(ctx, &pbGroup.JoinGroupReq{ + GroupID: request.GroupID, + ReqMessage: request.ReqMsg, + JoinSource: request.JoinSource, + InviterUserID: request.InviterUserID, + }) + } + return resp, nil } } - for _, v := range req.InvitedUserIDList { - chat.SuperGroupNotification(tools.OperationID(ctx), v, v) + } + if group.GroupType == constant.SuperGroup { + if err := s.GroupInterface.AddUserToSuperGroup(ctx, req.GroupID, req.InvitedUserIDList); err != nil { + return nil, err } + for _, userID := range req.InvitedUserIDList { + chat.SuperGroupNotification(tools.OperationID(ctx), userID, userID) + } + } else { + var groupMembers []*relation.GroupMember + for _, userID := range req.InvitedUserIDList { + user := userMap[userID] + var member relation.GroupMember + utils.CopyStructFields(&member, user) + member.GroupID = req.GroupID + member.RoleLevel = constant.GroupOrdinaryUsers + member.OperatorUserID = tools.OpUserID(ctx) + member.InviterUserID = tools.OpUserID(ctx) + member.JoinSource = constant.JoinByInvitation + if err := CallbackBeforeMemberJoinGroup(ctx, tools.OperationID(ctx), &member, group.Ex); err != nil { + return nil, err + } + groupMembers = append(groupMembers, &member) + } + if err := s.GroupInterface.CreateGroupMember(ctx, groupMembers); err != nil { + return nil, err + } + chat.MemberInvitedNotification(tools.OperationID(ctx), req.GroupID, tools.OpUserID(ctx), req.Reason, req.InvitedUserIDList) } return resp, nil } func (s *groupServer) GetGroupAllMember(ctx context.Context, req *pbGroup.GetGroupAllMemberReq) (*pbGroup.GetGroupAllMemberResp, error) { resp := &pbGroup.GetGroupAllMemberResp{} - - groupInfo, err := rocksCache.GetGroupInfoFromCache(ctx, req.GroupID) + group, err := s.GroupInterface.TakeGroupByID(ctx, req.GroupID) if err != nil { return nil, err } - if groupInfo.GroupType != constant.SuperGroup { - memberList, err := rocksCache.GetGroupMembersInfoFromCache(ctx, req.Count, req.Offset, req.GroupID) + if group.GroupType != constant.SuperGroup { + members, err := s.GroupInterface.GetGroupMemberList(ctx, req.GroupID) if err != nil { return nil, err } - for _, v := range memberList { + var userIDs []string + for _, member := range members { + userIDs = append(userIDs, member.UserID) + } + for _, member := range members { var node open_im_sdk.GroupMemberFullInfo - cp.GroupMemberDBCopyOpenIM(&node, v) + utils.CopyStructFields(&node, member) resp.MemberList = append(resp.MemberList, &node) } } diff --git a/pkg/common/db/controller/group.go b/pkg/common/db/controller/group.go index 56358db17..f87389428 100644 --- a/pkg/common/db/controller/group.go +++ b/pkg/common/db/controller/group.go @@ -18,10 +18,17 @@ type GroupInterface interface { DeleteGroupByIDs(ctx context.Context, groupIDs []string) error TakeGroupByID(ctx context.Context, groupID string) (group *relation.Group, err error) GetJoinedGroupList(ctx context.Context, userID string) ([]*relation.Group, error) + GetGroupMemberList(ctx context.Context, groupID string) ([]*relation.GroupMember, error) GetGroupMemberNum(ctx context.Context, groupIDs []string) (map[string]int, error) GetGroupOwnerUserID(ctx context.Context, groupIDs []string) (map[string]string, error) + + CreateGroupMember(ctx context.Context, groupMember []*relation.GroupMember) error + + CreateGroupRequest(ctx context.Context, requests []*relation.GroupRequest) error + //mongo CreateSuperGroup(ctx context.Context, groupID string, initMemberIDList []string) error + AddUserToSuperGroup(ctx context.Context, groupID string, userIDs []string) error GetSuperGroupByID(ctx context.Context, groupID string) (superGroup *unrelation.SuperGroup, err error) } diff --git a/pkg/common/token_verify/jwt_token.go b/pkg/common/token_verify/jwt_token.go index be0b5f217..9f3ace2d8 100644 --- a/pkg/common/token_verify/jwt_token.go +++ b/pkg/common/token_verify/jwt_token.go @@ -173,6 +173,10 @@ func CheckAccessV3(ctx context.Context, ownerUserID string) (err error) { return constant.ErrIdentity.Wrap(utils.GetSelfFuncName()) } +func IsAppManagerUid(ctx context.Context) bool { + return utils.IsContain(tools.OpUserID(ctx), config.Config.Manager.AppManagerUid) +} + func CheckAdmin(ctx context.Context) error { if utils.IsContain(tools.OpUserID(ctx), config.Config.Manager.AppManagerUid) { return nil