From d55cb0fa8b910d84f8cbd5b9f535e5451b2be112 Mon Sep 17 00:00:00 2001 From: withchao <993506633@qq.com> Date: Thu, 22 May 2025 14:37:54 +0800 Subject: [PATCH] feat: add group friend rpc interface permission check --- .../msgtransfer/online_history_msg_handler.go | 6 +- internal/rpc/group/cache.go | 3 + internal/rpc/group/group.go | 63 ++++++++++++------- internal/rpc/group/statistics.go | 4 ++ internal/rpc/group/sync.go | 18 +++++- internal/rpc/relation/friend.go | 15 +++++ internal/rpc/relation/sync.go | 6 +- 7 files changed, 88 insertions(+), 27 deletions(-) diff --git a/internal/msgtransfer/online_history_msg_handler.go b/internal/msgtransfer/online_history_msg_handler.go index b85848d9e..7a173d67b 100644 --- a/internal/msgtransfer/online_history_msg_handler.go +++ b/internal/msgtransfer/online_history_msg_handler.go @@ -18,13 +18,14 @@ import ( "context" "encoding/json" "errors" - "github.com/openimsdk/open-im-server/v3/pkg/rpcli" - "github.com/openimsdk/tools/discovery" "strconv" "strings" "sync" "time" + "github.com/openimsdk/open-im-server/v3/pkg/rpcli" + "github.com/openimsdk/tools/discovery" + "github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics" "github.com/IBM/sarama" @@ -289,6 +290,7 @@ func (och *OnlineHistoryRedisConsumerHandler) handleMsg(ctx context.Context, key } if isNewConversation { + ctx := storageList[0].ctx switch msg.SessionType { case constant.ReadGroupChatType: log.ZDebug(ctx, "group chat first create conversation", "conversationID", diff --git a/internal/rpc/group/cache.go b/internal/rpc/group/cache.go index 022a0f4ef..6ddfb32b3 100644 --- a/internal/rpc/group/cache.go +++ b/internal/rpc/group/cache.go @@ -33,6 +33,9 @@ func (s *groupServer) GetGroupInfoCache(ctx context.Context, req *pbgroup.GetGro } func (s *groupServer) GetGroupMemberCache(ctx context.Context, req *pbgroup.GetGroupMemberCacheReq) (*pbgroup.GetGroupMemberCacheResp, error) { + if err := s.checkAdminOrInGroup(ctx, req.GroupID); err != nil { + return nil, err + } members, err := s.db.TakeGroupMember(ctx, req.GroupID, req.GroupMemberID) if err != nil { return nil, err diff --git a/internal/rpc/group/group.go b/internal/rpc/group/group.go index bdd3920c1..9a9f4d4d9 100644 --- a/internal/rpc/group/group.go +++ b/internal/rpc/group/group.go @@ -491,7 +491,25 @@ func (g *groupServer) GetGroupAllMember(ctx context.Context, req *pbgroup.GetGro return &resp, nil } +func (g *groupServer) checkAdminOrInGroup(ctx context.Context, groupID string) error { + if authverify.IsAppManagerUid(ctx, g.config.Share.IMAdminUserID) { + return nil + } + opUserID := mcontext.GetOpUserID(ctx) + members, err := g.db.FindGroupMembers(ctx, groupID, []string{opUserID}) + if err != nil { + return err + } + if len(members) == 0 { + return errs.ErrNoPermission.WrapMsg("op user not in group") + } + return nil +} + func (g *groupServer) GetGroupMemberList(ctx context.Context, req *pbgroup.GetGroupMemberListReq) (*pbgroup.GetGroupMemberListResp, error) { + if err := g.checkAdminOrInGroup(ctx, req.GroupID); err != nil { + return nil, err + } var ( total int64 members []*model.GroupMember @@ -500,7 +518,7 @@ func (g *groupServer) GetGroupMemberList(ctx context.Context, req *pbgroup.GetGr if req.Keyword == "" { total, members, err = g.db.PageGetGroupMember(ctx, req.GroupID, req.Pagination) } else { - members, err = g.db.FindGroupMemberAll(ctx, req.GroupID) + total, members, err = g.db.SearchGroupMember(ctx, req.GroupID, req.Keyword, req.Pagination) } if err != nil { return nil, err @@ -508,27 +526,6 @@ func (g *groupServer) GetGroupMemberList(ctx context.Context, req *pbgroup.GetGr if err := g.PopulateGroupMember(ctx, members...); err != nil { return nil, err } - if req.Keyword != "" { - groupMembers := make([]*model.GroupMember, 0) - for _, member := range members { - if member.UserID == req.Keyword { - groupMembers = append(groupMembers, member) - total++ - continue - } - if member.Nickname == req.Keyword { - groupMembers = append(groupMembers, member) - total++ - continue - } - } - - members := datautil.Paginate(groupMembers, int(req.Pagination.GetPageNumber()), int(req.Pagination.GetShowNumber())) - return &pbgroup.GetGroupMemberListResp{ - Total: uint32(total), - Members: datautil.Batch(convert.Db2PbGroupMember, members), - }, nil - } return &pbgroup.GetGroupMemberListResp{ Total: uint32(total), Members: datautil.Batch(convert.Db2PbGroupMember, members), @@ -652,6 +649,9 @@ func (g *groupServer) GetGroupMembersInfo(ctx context.Context, req *pbgroup.GetG if req.GroupID == "" { return nil, errs.ErrArgs.WrapMsg("groupID empty") } + if err := g.checkAdminOrInGroup(ctx, req.GroupID); err != nil { + return nil, err + } members, err := g.getGroupMembersInfo(ctx, req.GroupID, req.UserIDs) if err != nil { return nil, err @@ -1297,6 +1297,9 @@ func (g *groupServer) GetGroups(ctx context.Context, req *pbgroup.GetGroupsReq) } func (g *groupServer) GetGroupMembersCMS(ctx context.Context, req *pbgroup.GetGroupMembersCMSReq) (*pbgroup.GetGroupMembersCMSResp, error) { + if err := g.checkAdminOrInGroup(ctx, req.GroupID); err != nil { + return nil, err + } total, members, err := g.db.SearchGroupMember(ctx, req.UserName, req.GroupID, req.Pagination) if err != nil { return nil, err @@ -1672,6 +1675,11 @@ func (g *groupServer) GetGroupAbstractInfo(ctx context.Context, req *pbgroup.Get if datautil.Duplicate(req.GroupIDs) { return nil, errs.ErrArgs.WrapMsg("groupIDs duplicate") } + for _, groupID := range req.GroupIDs { + if err := g.checkAdminOrInGroup(ctx, groupID); err != nil { + return nil, err + } + } groups, err := g.db.FindGroup(ctx, req.GroupIDs) if err != nil { return nil, err @@ -1700,6 +1708,9 @@ func (g *groupServer) GetUserInGroupMembers(ctx context.Context, req *pbgroup.Ge if len(req.GroupIDs) == 0 { return nil, errs.ErrArgs.WrapMsg("groupIDs empty") } + if err := authverify.CheckAccessV3(ctx, req.UserID, g.config.Share.IMAdminUserID); err != nil { + return nil, err + } members, err := g.db.FindGroupMemberUser(ctx, req.GroupIDs, req.UserID) if err != nil { return nil, err @@ -1719,6 +1730,11 @@ func (g *groupServer) GetGroupMemberUserIDs(ctx context.Context, req *pbgroup.Ge if err != nil { return nil, err } + if !authverify.IsAppManagerUid(ctx, g.config.Share.IMAdminUserID) { + if !datautil.Contain(mcontext.GetOpUserID(ctx), userIDs...) { + return nil, errs.ErrNoPermission.WrapMsg("opUser no permission") + } + } return &pbgroup.GetGroupMemberUserIDsResp{ UserIDs: userIDs, }, nil @@ -1728,6 +1744,9 @@ func (g *groupServer) GetGroupMemberRoleLevel(ctx context.Context, req *pbgroup. if len(req.RoleLevels) == 0 { return nil, errs.ErrArgs.WrapMsg("RoleLevels empty") } + if err := g.checkAdminOrInGroup(ctx, req.GroupID); err != nil { + return nil, err + } members, err := g.db.FindGroupMemberRoleLevels(ctx, req.GroupID, req.RoleLevels) if err != nil { return nil, err diff --git a/internal/rpc/group/statistics.go b/internal/rpc/group/statistics.go index 6adb1261a..0357999d5 100644 --- a/internal/rpc/group/statistics.go +++ b/internal/rpc/group/statistics.go @@ -18,6 +18,7 @@ import ( "context" "time" + "github.com/openimsdk/open-im-server/v3/pkg/authverify" "github.com/openimsdk/protocol/group" "github.com/openimsdk/tools/errs" ) @@ -26,6 +27,9 @@ func (s *groupServer) GroupCreateCount(ctx context.Context, req *group.GroupCrea if req.Start > req.End { return nil, errs.ErrArgs.WrapMsg("start > end: %d > %d", req.Start, req.End) } + if err := authverify.CheckAdmin(ctx, s.config.Share.IMAdminUserID); err != nil { + return nil, err + } total, err := s.db.CountTotal(ctx, nil) if err != nil { return nil, err diff --git a/internal/rpc/group/sync.go b/internal/rpc/group/sync.go index 1a3ecdfbe..d02c787b4 100644 --- a/internal/rpc/group/sync.go +++ b/internal/rpc/group/sync.go @@ -11,16 +11,24 @@ import ( "github.com/openimsdk/protocol/constant" pbgroup "github.com/openimsdk/protocol/group" "github.com/openimsdk/protocol/sdkws" + "github.com/openimsdk/tools/errs" + "github.com/openimsdk/tools/mcontext" + "github.com/openimsdk/tools/utils/datautil" ) const versionSyncLimit = 500 func (g *groupServer) GetFullGroupMemberUserIDs(ctx context.Context, req *pbgroup.GetFullGroupMemberUserIDsReq) (*pbgroup.GetFullGroupMemberUserIDsResp, error) { - vl, err := g.db.FindMaxGroupMemberVersionCache(ctx, req.GroupID) + userIDs, err := g.db.FindGroupMemberUserID(ctx, req.GroupID) if err != nil { return nil, err } - userIDs, err := g.db.FindGroupMemberUserID(ctx, req.GroupID) + if !authverify.IsAppManagerUid(ctx, g.config.Share.IMAdminUserID) { + if !datautil.Contain(mcontext.GetOpUserID(ctx), userIDs...) { + return nil, errs.ErrNoPermission.WrapMsg("op user not in group") + } + } + vl, err := g.db.FindMaxGroupMemberVersionCache(ctx, req.GroupID) if err != nil { return nil, err } @@ -37,6 +45,9 @@ func (g *groupServer) GetFullGroupMemberUserIDs(ctx context.Context, req *pbgrou } func (s *groupServer) GetFullJoinGroupIDs(ctx context.Context, req *pbgroup.GetFullJoinGroupIDsReq) (*pbgroup.GetFullJoinGroupIDsResp, error) { + if err := authverify.CheckAccessV3(ctx, req.UserID, s.config.Share.IMAdminUserID); err != nil { + return nil, err + } vl, err := s.db.FindMaxJoinGroupVersionCache(ctx, req.UserID) if err != nil { return nil, err @@ -58,6 +69,9 @@ func (s *groupServer) GetFullJoinGroupIDs(ctx context.Context, req *pbgroup.GetF } func (s *groupServer) GetIncrementalGroupMember(ctx context.Context, req *pbgroup.GetIncrementalGroupMemberReq) (*pbgroup.GetIncrementalGroupMemberResp, error) { + if err := s.checkAdminOrInGroup(ctx, req.GroupID); err != nil { + return nil, err + } group, err := s.db.TakeGroup(ctx, req.GroupID) if err != nil { return nil, err diff --git a/internal/rpc/relation/friend.go b/internal/rpc/relation/friend.go index e9a5818ed..e5164ac93 100644 --- a/internal/rpc/relation/friend.go +++ b/internal/rpc/relation/friend.go @@ -16,6 +16,7 @@ package relation import ( "context" + "github.com/openimsdk/open-im-server/v3/pkg/rpcli" "github.com/openimsdk/tools/mq/memamq" @@ -280,6 +281,9 @@ func (s *friendServer) SetFriendRemark(ctx context.Context, req *relation.SetFri } func (s *friendServer) GetFriendInfo(ctx context.Context, req *relation.GetFriendInfoReq) (*relation.GetFriendInfoResp, error) { + if err := authverify.CheckAccessV3(ctx, req.OwnerUserID, s.config.Share.IMAdminUserID); err != nil { + return nil, err + } friends, err := s.db.FindFriendsWithError(ctx, req.OwnerUserID, req.FriendUserIDs) if err != nil { return nil, err @@ -292,6 +296,9 @@ func (s *friendServer) GetDesignatedFriends(ctx context.Context, req *relation.G if datautil.Duplicate(req.FriendUserIDs) { return nil, errs.ErrArgs.WrapMsg("friend userID repeated") } + if err := authverify.CheckAccessV3(ctx, req.OwnerUserID, s.config.Share.IMAdminUserID); err != nil { + return nil, err + } friends, err := s.getFriend(ctx, req.OwnerUserID, req.FriendUserIDs) if err != nil { return nil, err @@ -426,6 +433,10 @@ func (s *friendServer) GetSpecifiedFriendsInfo(ctx context.Context, req *relatio return nil, errs.ErrArgs.WrapMsg("userIDList repeated") } + if err := authverify.CheckAccessV3(ctx, req.OwnerUserID, s.config.Share.IMAdminUserID); err != nil { + return nil, err + } + userMap, err := s.userClient.GetUsersInfoMap(ctx, req.UserIDList) if err != nil { return nil, err @@ -505,6 +516,10 @@ func (s *friendServer) UpdateFriends( return nil, errs.ErrArgs.WrapMsg("friendIDList repeated") } + if err := authverify.CheckAccessV3(ctx, req.OwnerUserID, s.config.Share.IMAdminUserID); err != nil { + return nil, err + } + _, err := s.db.FindFriendsWithError(ctx, req.OwnerUserID, req.FriendUserIDs) if err != nil { return nil, err diff --git a/internal/rpc/relation/sync.go b/internal/rpc/relation/sync.go index 0ad94fe82..94617841e 100644 --- a/internal/rpc/relation/sync.go +++ b/internal/rpc/relation/sync.go @@ -2,10 +2,11 @@ package relation import ( "context" + "slices" + "github.com/openimsdk/open-im-server/v3/pkg/util/hashutil" "github.com/openimsdk/protocol/sdkws" "github.com/openimsdk/tools/log" - "slices" "github.com/openimsdk/open-im-server/v3/internal/rpc/incrversion" "github.com/openimsdk/open-im-server/v3/pkg/authverify" @@ -39,6 +40,9 @@ func (s *friendServer) NotificationUserInfoUpdate(ctx context.Context, req *rela } func (s *friendServer) GetFullFriendUserIDs(ctx context.Context, req *relation.GetFullFriendUserIDsReq) (*relation.GetFullFriendUserIDsResp, error) { + if err := authverify.CheckAccessV3(ctx, req.UserID, s.config.Share.IMAdminUserID); err != nil { + return nil, err + } vl, err := s.db.FindMaxFriendVersionCache(ctx, req.UserID) if err != nil { return nil, err