fix: 修复群管理踢人权限过高问题

This commit is contained in:
Kkuil
2023-10-29 20:41:38 +08:00
parent 34162f14fe
commit d39755c7ee
3 changed files with 69 additions and 39 deletions

View File

@@ -104,6 +104,23 @@ public class GroupMemberDao extends ServiceImpl<GroupMemberMapper, GroupMember>
GroupMember groupMember = this.lambdaQuery() GroupMember groupMember = this.lambdaQuery()
.eq(GroupMember::getGroupId, id) .eq(GroupMember::getGroupId, id)
.eq(GroupMember::getUid, uid) .eq(GroupMember::getUid, uid)
.eq(GroupMember::getRole, GroupRoleEnum.LEADER.getType())
.one();
return ObjectUtil.isNotNull(groupMember);
}
/**
* 是否是管理员
*
* @param id 群组ID
* @param uid 用户ID
* @return 是否是管理员
*/
public Boolean isManager(Long id, Long uid) {
GroupMember groupMember = this.lambdaQuery()
.eq(GroupMember::getGroupId, id)
.eq(GroupMember::getUid, uid)
.eq(GroupMember::getRole, GroupRoleEnum.MANAGER.getType())
.one(); .one();
return ObjectUtil.isNotNull(groupMember); return ObjectUtil.isNotNull(groupMember);
} }

View File

@@ -28,6 +28,7 @@ import com.abin.mallchat.common.common.annotation.RedissonLock;
import com.abin.mallchat.common.common.domain.vo.request.CursorPageBaseReq; import com.abin.mallchat.common.common.domain.vo.request.CursorPageBaseReq;
import com.abin.mallchat.common.common.domain.vo.response.CursorPageBaseResp; import com.abin.mallchat.common.common.domain.vo.response.CursorPageBaseResp;
import com.abin.mallchat.common.common.event.GroupMemberAddEvent; import com.abin.mallchat.common.common.event.GroupMemberAddEvent;
import com.abin.mallchat.common.common.exception.GroupErrorEnum;
import com.abin.mallchat.common.common.utils.AssertUtil; import com.abin.mallchat.common.common.utils.AssertUtil;
import com.abin.mallchat.common.user.dao.UserDao; import com.abin.mallchat.common.user.dao.UserDao;
import com.abin.mallchat.common.user.domain.entity.User; import com.abin.mallchat.common.user.domain.entity.User;
@@ -95,29 +96,29 @@ public class RoomAppServiceImpl implements RoomAppService {
@Override @Override
public CursorPageBaseResp<ChatRoomResp> getContactPage(CursorPageBaseReq request, Long uid) { public CursorPageBaseResp<ChatRoomResp> getContactPage(CursorPageBaseReq request, Long uid) {
//查出用户要展示的会话列表 // 查出用户要展示的会话列表
CursorPageBaseResp<Long> page; CursorPageBaseResp<Long> page;
if (Objects.nonNull(uid)) { if (Objects.nonNull(uid)) {
Double hotEnd = getCursorOrNull(request.getCursor()); Double hotEnd = getCursorOrNull(request.getCursor());
Double hotStart = null; Double hotStart = null;
//用户基础会话 // 用户基础会话
CursorPageBaseResp<Contact> contactPage = contactDao.getContactPage(uid, request); CursorPageBaseResp<Contact> contactPage = contactDao.getContactPage(uid, request);
List<Long> baseRoomIds = contactPage.getList().stream().map(Contact::getRoomId).collect(Collectors.toList()); List<Long> baseRoomIds = contactPage.getList().stream().map(Contact::getRoomId).collect(Collectors.toList());
if (!contactPage.getIsLast()) { if (!contactPage.getIsLast()) {
hotStart = getCursorOrNull(contactPage.getCursor()); hotStart = getCursorOrNull(contactPage.getCursor());
} }
//热门房间 // 热门房间
Set<ZSetOperations.TypedTuple<String>> typedTuples = hotRoomCache.getRoomRange(hotStart, hotEnd); Set<ZSetOperations.TypedTuple<String>> typedTuples = hotRoomCache.getRoomRange(hotStart, hotEnd);
List<Long> hotRoomIds = typedTuples.stream().map(ZSetOperations.TypedTuple::getValue).filter(Objects::nonNull).map(Long::parseLong).collect(Collectors.toList()); List<Long> hotRoomIds = typedTuples.stream().map(ZSetOperations.TypedTuple::getValue).filter(Objects::nonNull).map(Long::parseLong).collect(Collectors.toList());
baseRoomIds.addAll(hotRoomIds); baseRoomIds.addAll(hotRoomIds);
//基础会话和热门房间合并 // 基础会话和热门房间合并
page = CursorPageBaseResp.init(contactPage, baseRoomIds); page = CursorPageBaseResp.init(contactPage, baseRoomIds);
} else {//用户未登录,只查全局房间 } else {// 用户未登录,只查全局房间
CursorPageBaseResp<Pair<Long, Double>> roomCursorPage = hotRoomCache.getRoomCursorPage(request); CursorPageBaseResp<Pair<Long, Double>> roomCursorPage = hotRoomCache.getRoomCursorPage(request);
List<Long> roomIds = roomCursorPage.getList().stream().map(Pair::getKey).collect(Collectors.toList()); List<Long> roomIds = roomCursorPage.getList().stream().map(Pair::getKey).collect(Collectors.toList());
page = CursorPageBaseResp.init(roomCursorPage, roomIds); page = CursorPageBaseResp.init(roomCursorPage, roomIds);
} }
//最后组装会话信息(名称,头像,未读数等) // 最后组装会话信息(名称,头像,未读数等)
List<ChatRoomResp> result = buildContactResp(uid, page.getList()); List<ChatRoomResp> result = buildContactResp(uid, page.getList());
return CursorPageBaseResp.init(page, result); return CursorPageBaseResp.init(page, result);
} }
@@ -142,7 +143,7 @@ public class RoomAppServiceImpl implements RoomAppService {
Room room = roomCache.get(roomId); Room room = roomCache.get(roomId);
AssertUtil.isNotEmpty(roomGroup, "roomId有误"); AssertUtil.isNotEmpty(roomGroup, "roomId有误");
Long onlineNum; Long onlineNum;
if (isHotGroup(room)) {//热点群从redis取人数 if (isHotGroup(room)) {// 热点群从redis取人数
onlineNum = userCache.getOnlineNum(); onlineNum = userCache.getOnlineNum();
} else { } else {
List<Long> memberUidList = groupMemberDao.getMemberUidList(roomGroup.getId()); List<Long> memberUidList = groupMemberDao.getMemberUidList(roomGroup.getId());
@@ -163,9 +164,9 @@ public class RoomAppServiceImpl implements RoomAppService {
Room room = roomCache.get(request.getRoomId()); Room room = roomCache.get(request.getRoomId());
AssertUtil.isNotEmpty(room, "房间号有误"); AssertUtil.isNotEmpty(room, "房间号有误");
List<Long> memberUidList; List<Long> memberUidList;
if (isHotGroup(room)) {//全员群展示所有用户 if (isHotGroup(room)) {// 全员群展示所有用户
memberUidList = null; memberUidList = null;
} else {//只展示房间内的群成员 } else {// 只展示房间内的群成员
RoomGroup roomGroup = roomGroupCache.get(request.getRoomId()); RoomGroup roomGroup = roomGroupCache.get(request.getRoomId());
memberUidList = groupMemberDao.getMemberUidList(roomGroup.getId()); memberUidList = groupMemberDao.getMemberUidList(roomGroup.getId());
} }
@@ -177,7 +178,7 @@ public class RoomAppServiceImpl implements RoomAppService {
public List<ChatMemberListResp> getMemberList(ChatMessageMemberReq request) { public List<ChatMemberListResp> getMemberList(ChatMessageMemberReq request) {
Room room = roomCache.get(request.getRoomId()); Room room = roomCache.get(request.getRoomId());
AssertUtil.isNotEmpty(room, "房间号有误"); AssertUtil.isNotEmpty(room, "房间号有误");
if (isHotGroup(room)) {//全员群展示所有用户100名 if (isHotGroup(room)) {// 全员群展示所有用户100名
List<User> memberList = userDao.getMemberList(); List<User> memberList = userDao.getMemberList();
return MemberAdapter.buildMemberList(memberList); return MemberAdapter.buildMemberList(memberList);
} else { } else {
@@ -196,12 +197,22 @@ public class RoomAppServiceImpl implements RoomAppService {
RoomGroup roomGroup = roomGroupCache.get(request.getRoomId()); RoomGroup roomGroup = roomGroupCache.get(request.getRoomId());
AssertUtil.isNotEmpty(roomGroup, "房间号有误"); AssertUtil.isNotEmpty(roomGroup, "房间号有误");
GroupMember self = groupMemberDao.getMember(roomGroup.getId(), uid); GroupMember self = groupMemberDao.getMember(roomGroup.getId(), uid);
AssertUtil.isNotEmpty(self, "您不是群管理"); AssertUtil.isNotEmpty(self, GroupErrorEnum.USER_NOT_IN_GROUP);
AssertUtil.isTrue(hasPower(self), "您不是群管理"); // 1. 判断被移除的人是否是群主或者管理员 (群主不可以被移除,管理员只能被群主移除)
GroupMember member = groupMemberDao.getMember(roomGroup.getId(), request.getUid()); Long removedUid = request.getUid();
AssertUtil.isNotEmpty(self, "用户已经移除"); // 1.1 群主 非法操作
AssertUtil.isFalse(groupMemberDao.isLord(roomGroup.getId(), removedUid), GroupErrorEnum.NOT_ALLOWED_FOR_REMOVE);
// 1.2 管理员 判断是否是群主操作
if (groupMemberDao.isManager(roomGroup.getId(), removedUid)) {
Boolean isLord = groupMemberDao.isLord(roomGroup.getId(), uid);
AssertUtil.isTrue(isLord, GroupErrorEnum.NOT_ALLOWED_FOR_REMOVE);
}
// 1.3 普通成员 判断是否有权限操作
AssertUtil.isTrue(hasPower(self), GroupErrorEnum.NOT_ALLOWED_FOR_REMOVE);
GroupMember member = groupMemberDao.getMember(roomGroup.getId(), removedUid);
AssertUtil.isNotEmpty(member, "用户已经移除");
groupMemberDao.removeById(member.getId()); groupMemberDao.removeById(member.getId());
//发送移除事件告知群成员 // 发送移除事件告知群成员
List<Long> memberUidList = groupMemberCache.getMemberUidList(roomGroup.getRoomId()); List<Long> memberUidList = groupMemberCache.getMemberUidList(roomGroup.getRoomId());
WSBaseResp<WSMemberChange> ws = MemberAdapter.buildMemberRemoveWS(roomGroup.getRoomId(), member.getUid()); WSBaseResp<WSMemberChange> ws = MemberAdapter.buildMemberRemoveWS(roomGroup.getRoomId(), member.getUid());
pushService.sendPushMsg(ws, memberUidList); pushService.sendPushMsg(ws, memberUidList);
@@ -235,10 +246,10 @@ public class RoomAppServiceImpl implements RoomAppService {
@Transactional @Transactional
public Long addGroup(Long uid, GroupAddReq request) { public Long addGroup(Long uid, GroupAddReq request) {
RoomGroup roomGroup = roomService.createGroupRoom(uid); RoomGroup roomGroup = roomService.createGroupRoom(uid);
//批量保存群成员 // 批量保存群成员
List<GroupMember> groupMembers = RoomAdapter.buildGroupMemberBatch(request.getUidList(), roomGroup.getId()); List<GroupMember> groupMembers = RoomAdapter.buildGroupMemberBatch(request.getUidList(), roomGroup.getId());
groupMemberDao.saveBatch(groupMembers); groupMemberDao.saveBatch(groupMembers);
//发送邀请加群消息==》触发每个人的会话 // 发送邀请加群消息==》触发每个人的会话
applicationEventPublisher.publishEvent(new GroupMemberAddEvent(this, roomGroup, groupMembers, uid)); applicationEventPublisher.publishEvent(new GroupMemberAddEvent(this, roomGroup, groupMembers, uid));
return roomGroup.getRoomId(); return roomGroup.getRoomId();
} }
@@ -294,32 +305,32 @@ public class RoomAppServiceImpl implements RoomAppService {
@NotNull @NotNull
private List<ChatRoomResp> buildContactResp(Long uid, List<Long> roomIds) { private List<ChatRoomResp> buildContactResp(Long uid, List<Long> roomIds) {
//表情和头像 // 表情和头像
Map<Long, RoomBaseInfo> roomBaseInfoMap = getRoomBaseInfoMap(roomIds, uid); Map<Long, RoomBaseInfo> roomBaseInfoMap = getRoomBaseInfoMap(roomIds, uid);
//最后一条消息 // 最后一条消息
List<Long> msgIds = roomBaseInfoMap.values().stream().map(RoomBaseInfo::getLastMsgId).collect(Collectors.toList()); List<Long> msgIds = roomBaseInfoMap.values().stream().map(RoomBaseInfo::getLastMsgId).collect(Collectors.toList());
List<Message> messages = CollectionUtil.isEmpty(msgIds) ? new ArrayList<>() : messageDao.listByIds(msgIds); List<Message> messages = CollectionUtil.isEmpty(msgIds) ? new ArrayList<>() : messageDao.listByIds(msgIds);
Map<Long, Message> msgMap = messages.stream().collect(Collectors.toMap(Message::getId, Function.identity())); Map<Long, Message> msgMap = messages.stream().collect(Collectors.toMap(Message::getId, Function.identity()));
Map<Long, User> lastMsgUidMap = userInfoCache.getBatch(messages.stream().map(Message::getFromUid).collect(Collectors.toList())); Map<Long, User> lastMsgUidMap = userInfoCache.getBatch(messages.stream().map(Message::getFromUid).collect(Collectors.toList()));
//消息未读数 // 消息未读数
Map<Long, Integer> unReadCountMap = getUnReadCountMap(uid, roomIds); Map<Long, Integer> unReadCountMap = getUnReadCountMap(uid, roomIds);
return roomBaseInfoMap.values().stream().map(room -> { return roomBaseInfoMap.values().stream().map(room -> {
ChatRoomResp resp = new ChatRoomResp(); ChatRoomResp resp = new ChatRoomResp();
RoomBaseInfo roomBaseInfo = roomBaseInfoMap.get(room.getRoomId()); RoomBaseInfo roomBaseInfo = roomBaseInfoMap.get(room.getRoomId());
resp.setAvatar(roomBaseInfo.getAvatar()); resp.setAvatar(roomBaseInfo.getAvatar());
resp.setRoomId(room.getRoomId()); resp.setRoomId(room.getRoomId());
resp.setActiveTime(room.getActiveTime()); resp.setActiveTime(room.getActiveTime());
resp.setHot_Flag(roomBaseInfo.getHotFlag()); resp.setHot_Flag(roomBaseInfo.getHotFlag());
resp.setType(roomBaseInfo.getType()); resp.setType(roomBaseInfo.getType());
resp.setName(roomBaseInfo.getName()); resp.setName(roomBaseInfo.getName());
Message message = msgMap.get(room.getLastMsgId()); Message message = msgMap.get(room.getLastMsgId());
if (Objects.nonNull(message)) { if (Objects.nonNull(message)) {
AbstractMsgHandler strategyNoNull = MsgHandlerFactory.getStrategyNoNull(message.getType()); AbstractMsgHandler strategyNoNull = MsgHandlerFactory.getStrategyNoNull(message.getType());
resp.setText(lastMsgUidMap.get(message.getFromUid()).getName() + ":" + strategyNoNull.showContactMsg(message)); resp.setText(lastMsgUidMap.get(message.getFromUid()).getName() + ":" + strategyNoNull.showContactMsg(message));
} }
resp.setUnreadCount(unReadCountMap.getOrDefault(room.getRoomId(), 0)); resp.setUnreadCount(unReadCountMap.getOrDefault(room.getRoomId(), 0));
return resp; return resp;
}).sorted(Comparator.comparing(ChatRoomResp::getActiveTime).reversed()) }).sorted(Comparator.comparing(ChatRoomResp::getActiveTime).reversed())
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
@@ -350,15 +361,16 @@ public class RoomAppServiceImpl implements RoomAppService {
return userBatch.get(friendUid); return userBatch.get(friendUid);
})); }));
} }
private Map<Long, RoomBaseInfo> getRoomBaseInfoMap(List<Long> roomIds, Long uid) { private Map<Long, RoomBaseInfo> getRoomBaseInfoMap(List<Long> roomIds, Long uid) {
Map<Long, Room> roomMap = roomCache.getBatch(roomIds); Map<Long, Room> roomMap = roomCache.getBatch(roomIds);
//房间根据好友和群组类型分组 // 房间根据好友和群组类型分组
Map<Integer, List<Long>> groupRoomIdMap = roomMap.values().stream().collect(Collectors.groupingBy(Room::getType, Map<Integer, List<Long>> groupRoomIdMap = roomMap.values().stream().collect(Collectors.groupingBy(Room::getType,
Collectors.mapping(Room::getId, Collectors.toList()))); Collectors.mapping(Room::getId, Collectors.toList())));
//获取群组信息 // 获取群组信息
List<Long> groupRoomId = groupRoomIdMap.get(RoomTypeEnum.GROUP.getType()); List<Long> groupRoomId = groupRoomIdMap.get(RoomTypeEnum.GROUP.getType());
Map<Long, RoomGroup> roomInfoBatch = roomGroupCache.getBatch(groupRoomId); Map<Long, RoomGroup> roomInfoBatch = roomGroupCache.getBatch(groupRoomId);
//获取好友信息 // 获取好友信息
List<Long> friendRoomId = groupRoomIdMap.get(RoomTypeEnum.FRIEND.getType()); List<Long> friendRoomId = groupRoomIdMap.get(RoomTypeEnum.FRIEND.getType());
Map<Long, User> friendRoomMap = getFriendRoomMap(friendRoomId, uid); Map<Long, User> friendRoomMap = getFriendRoomMap(friendRoomId, uid);

View File

@@ -18,6 +18,7 @@ public enum GroupErrorEnum implements ErrorEnum {
NOT_ALLOWED_OPERATION(9002, "您无权操作~"), NOT_ALLOWED_OPERATION(9002, "您无权操作~"),
MANAGE_COUNT_EXCEED(9003, "群管理员数量达到上限,请先删除后再操作~"), MANAGE_COUNT_EXCEED(9003, "群管理员数量达到上限,请先删除后再操作~"),
USER_NOT_IN_GROUP(9004, "非法操作,用户不存在群聊中~"), USER_NOT_IN_GROUP(9004, "非法操作,用户不存在群聊中~"),
NOT_ALLOWED_FOR_REMOVE(9005, "非法操作,你没有移除该成员的权限"),
; ;
private final Integer code; private final Integer code;
private final String msg; private final String msg;