diff --git a/broker/config/wildfirechat.conf b/broker/config/wildfirechat.conf index 526b9a30..a7db5bcc 100755 --- a/broker/config/wildfirechat.conf +++ b/broker/config/wildfirechat.conf @@ -201,6 +201,9 @@ group.visible_quit_or_kickoff_notification 0 ## Server API不受此限制。 #group.forbidden_client_operation 0xFFF +## 是否禁止陌生人拉人入群,默认为false +group.disable_stranger_invite false + ## 隐藏用户信息属性类型,2是性别,3是电话号码,4是邮箱,5是地址,6是公司信息,7是社交账号,8是Extra信息。当需要隐藏多个时以英文逗号分开; ## 本配置是为了提高安全性,避免把对应信息同步到客户端,这样就能防止程序被破解从而拿到用户关键信息。仅对客户端有效,server api不受影响。 ## 注意,修改本配置不会对已经同步的信息产生影响。 diff --git a/broker/src/main/java/io/moquette/BrokerConstants.java b/broker/src/main/java/io/moquette/BrokerConstants.java index f3ac43e6..b9dd2a04 100755 --- a/broker/src/main/java/io/moquette/BrokerConstants.java +++ b/broker/src/main/java/io/moquette/BrokerConstants.java @@ -185,6 +185,8 @@ public final class BrokerConstants { public static final String GROUP_Visible_Quit_Kickoff_Notification = "group.visible_quit_or_kickoff_notification"; public static final String GROUP_Forbidden_Client_Operation = "group.forbidden_client_operation"; + public static final String GROUP_Disable_Stranger_Invite = "group.disable_stranger_invite"; + public static final String USER_HIDE_PROPERTIES = "user.hide_properties"; public static final String USER_KEEP_DISPLAY_NAME_WHEN_DESTROY = "user.keep_display_name_when_destroy"; diff --git a/broker/src/main/java/io/moquette/imhandler/CreateGroupHandler.java b/broker/src/main/java/io/moquette/imhandler/CreateGroupHandler.java index bd613759..a6cf56ef 100644 --- a/broker/src/main/java/io/moquette/imhandler/CreateGroupHandler.java +++ b/broker/src/main/java/io/moquette/imhandler/CreateGroupHandler.java @@ -50,6 +50,14 @@ public class CreateGroupHandler extends GroupHandler 0) { diff --git a/broker/src/main/java/io/moquette/persistence/MemoryMessagesStore.java b/broker/src/main/java/io/moquette/persistence/MemoryMessagesStore.java index 60d96175..76e48b55 100755 --- a/broker/src/main/java/io/moquette/persistence/MemoryMessagesStore.java +++ b/broker/src/main/java/io/moquette/persistence/MemoryMessagesStore.java @@ -23,6 +23,7 @@ import com.google.gson.Gson; import com.google.protobuf.ByteString; import com.hazelcast.core.*; import com.hazelcast.util.StringUtil; +import com.xiaoleilu.hutool.system.UserInfo; import com.xiaoleilu.loServer.action.admin.AdminAction; import com.xiaoleilu.loServer.model.FriendData; import cn.wildfirechat.common.ErrorCode; @@ -159,6 +160,7 @@ public class MemoryMessagesStore implements IMessagesStore { private boolean mMobileDefaultSilentWhenPCOnline = true; private boolean mDisableStrangerChat = false; private Set mAllowStrangerChatSet = new HashSet<>(); + private boolean mDisableStrangerAddGroup = false; private Set mClientSignatureSet = new HashSet<>(); private boolean mRejectEmptySignature = true; @@ -515,6 +517,11 @@ public class MemoryMessagesStore implements IMessagesStore { } + try { + mDisableStrangerAddGroup = Boolean.parseBoolean(server.getConfig().getProperty(BrokerConstants.GROUP_Disable_Stranger_Invite, "false")); + } catch (Exception e) { + } + try { String s = server.getConfig().getProperty(GROUP_Forbidden_Client_Operation, null); if(!StringUtil.isNullOrEmptyAfterTrim(s)) { @@ -1194,6 +1201,85 @@ public class MemoryMessagesStore implements IMessagesStore { return messageSeq; } + @Override + public ErrorCode canAddGroupMembers(String fromUser, List memberList) { + HazelcastInstance hzInstance = m_Server.getHazelcastInstance(); + MultiMap friendsMap = hzInstance.getMultiMap(USER_FRIENDS); + IMap mUserMap = hzInstance.getMap(USERS); + + WFCMessage.User operator = mUserMap.get(fromUser); + if(operator != null && operator.getType() > 1) { + return ErrorCode.ERROR_CODE_SUCCESS; + } + + if (mDisableStrangerAddGroup) { + for (WFCMessage.GroupMember groupMember : memberList) { + String targetUser = groupMember.getMemberId(); + if(fromUser.equals(targetUser)) { + continue; + } + + Collection friendDatas = friendsMap.get(targetUser); + if (friendDatas == null || friendDatas.size() == 0) { + friendDatas = loadFriend(friendsMap, targetUser); + } + + boolean allow = false; + for (FriendData friendData : friendDatas) { + if (friendData.getFriendUid().equals(fromUser)) { + if (friendData.getBlacked() == 1) { + return ErrorCode.ERROR_CODE_IN_BLACK_LIST; + } else { + if (friendData.getState() == 0) { + allow = true; + } + break; + } + } + } + if(allow) { + continue; + } + + //在禁止私聊时,是否是允许私聊的用户id + if(mAllowStrangerChatSet.contains(targetUser) || mAllowStrangerChatSet.contains(fromUser)) { + continue; + } + + //在禁止私聊时,允许机器人,物联网设备及管理员进行私聊。 + WFCMessage.User target = mUserMap.get(targetUser); + if (target != null && target.getType() != ProtoConstants.UserType.UserType_Normal) { + continue; + } + + return ErrorCode.ERROR_CODE_NOT_RIGHT; + } + } else { + for (WFCMessage.GroupMember groupMember : memberList) { + String targetUser = groupMember.getMemberId(); + if(fromUser.equals(targetUser)) { + continue; + } + + Collection friendDatas = friendsMap.get(targetUser); + if (friendDatas == null || friendDatas.size() == 0) { + friendDatas = loadFriend(friendsMap, targetUser); + } + + for (FriendData friendData : friendDatas) { + if (friendData.getFriendUid().equals(fromUser)) { + if (friendData.getBlacked() == 1) { + return ErrorCode.ERROR_CODE_IN_BLACK_LIST; + } else { + break; + } + } + } + } + } + return ErrorCode.ERROR_CODE_SUCCESS; + } + @Override public WFCMessage.GroupInfo createGroup(String fromUser, WFCMessage.GroupInfo groupInfo, List memberList, String memberExtra, boolean isAdmin) { HazelcastInstance hzInstance = m_Server.getHazelcastInstance(); diff --git a/broker/src/main/java/io/moquette/spi/IMessagesStore.java b/broker/src/main/java/io/moquette/spi/IMessagesStore.java index b6dcded9..8c846060 100755 --- a/broker/src/main/java/io/moquette/spi/IMessagesStore.java +++ b/broker/src/main/java/io/moquette/spi/IMessagesStore.java @@ -102,6 +102,7 @@ public interface IMessagesStore { WFCMessage.PullMessageResult fetchMessage(String user, String exceptClientId, long fromMessageId, int pullType); WFCMessage.PullMessageResult loadRemoteMessages(String user, WFCMessage.Conversation conversation, long beforeUid, int count, Collection contentTypes); long insertUserMessages(String sender, int conversationType, String target, int line, int messageContentType, String userId, long messageId, boolean directing); + ErrorCode canAddGroupMembers(String operator, List memberList); WFCMessage.GroupInfo createGroup(String operator, WFCMessage.GroupInfo groupInfo, List memberList, String memberExtra, boolean isAdmin); ErrorCode addGroupMembers(String operator, boolean isAdmin, String groupId, List memberList, String extra); ErrorCode kickoffGroupMembers(String operator, boolean isAdmin, String groupId, List memberList); diff --git a/distribution/src/main/resources/wildfirechat.conf b/distribution/src/main/resources/wildfirechat.conf index e47d958b..23e4068b 100755 --- a/distribution/src/main/resources/wildfirechat.conf +++ b/distribution/src/main/resources/wildfirechat.conf @@ -200,6 +200,9 @@ group.visible_quit_or_kickoff_notification 0 ## 如果有客户端有被破解的风险,可以禁止客户端群操作,然后通过Server API操作。Server API不受限制。 #group.forbidden_client_operation 0xFFF +## 是否禁止陌生人拉人入群,默认为false +group.disable_stranger_invite false + ## 隐藏用户信息属性类型,2是性别,3是电话号码,4是邮箱,5是地址,6是公司信息,7是社交账号,8是Extra信息。当需要隐藏多个时以英文逗号分开; ## 本配置是为了提高安全性,避免把对应信息同步到客户端,这样就能防止程序被破解从而拿到用户关键信息。仅对客户端有效,server api不受影响。 ## 注意,修改本配置不会对已经同步的信息产生影响。