mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-10-28 01:12:42 +00:00
core: ignore relay join requests in groups without relays (#7875)
This commit is contained in:
1 parent
3de946b7d4
commit
ec8884f465
2 files changed
+44
-13
No files matched your search
@@ -1688,22 +1688,26 @@ processAgentMessageConn cxt user@User {userId} entity gks_ corrId agentConnId ag
|
||||
User {userChatRelay} = user
|
||||
-- TODO [relays] owner, relays: TBC how to communicate member rejection rules from owner to relays
|
||||
memberJoinRequestViaRelay :: InvitationId -> VersionRangeChat -> Maybe SignedMsg -> Profile -> MemberId -> MemberKey -> Maybe MemberId -> CM ()
|
||||
memberJoinRequestViaRelay invId chatVRange signedMsg_ p joiningMemberId joiningMemberKey@(MemberKey joiningKey) viaRelay = do
|
||||
memberJoinRequestViaRelay invId chatVRange signedMsg_ p@Profile {displayName} joiningMemberId joiningMemberKey@(MemberKey joiningKey) viaRelay = do
|
||||
(_ucl, gLinkInfo_) <- withStore $ \db -> getUserContactLinkById db userId uclId
|
||||
case gLinkInfo_ of
|
||||
Just GroupLinkInfo {groupId, memberRole = gLinkMemRole} -> do
|
||||
g@(GIK gInfo _) <- withStore $ \db -> getGroupInfoKeys db cxt user groupId
|
||||
existing_ <- withStore' $ \db -> eitherToMaybe <$> runExceptT (getGroupMemberByMemberId db cxt user gInfo joiningMemberId)
|
||||
let signed = memberSigned gInfo joiningMemberId joiningKey signedMsg_
|
||||
case existing_ of
|
||||
Just rosterMem
|
||||
-- a privileged memberId's key is owner-authoritative (the roster); the joiner must prove
|
||||
-- possession of that exact key, otherwise this is an attempt to impersonate it
|
||||
| isRosterRole (memberRole' rosterMem) ->
|
||||
if verifyKey gInfo rosterMem signed
|
||||
then acceptJoin g signed (Just rosterMem) (memberRole' rosterMem)
|
||||
else messageError "memberJoinRequestViaRelay: rejected join claiming privileged memberId (key mismatch or invalid signature)"
|
||||
_ -> acceptJoin g signed Nothing gLinkMemRole
|
||||
if
|
||||
| not (useRelays' gInfo) ->
|
||||
messageWarning $ "memberJoinRequestViaRelay (group " <> groupName' gInfo <> "): ignored relay join request from " <> displayName <> " (group does not use relays)"
|
||||
| otherwise -> do
|
||||
existing_ <- withStore' $ \db -> eitherToMaybe <$> runExceptT (getGroupMemberByMemberId db cxt user gInfo joiningMemberId)
|
||||
let signed = memberSigned gInfo joiningMemberId joiningKey signedMsg_
|
||||
case existing_ of
|
||||
Just rosterMem
|
||||
-- a privileged memberId's key is owner-authoritative (the roster); the joiner must prove
|
||||
-- possession of that exact key, otherwise this is an attempt to impersonate it
|
||||
| isRosterRole (memberRole' rosterMem) ->
|
||||
if verifyKey gInfo rosterMem signed
|
||||
then acceptJoin g signed (Just rosterMem) (memberRole' rosterMem)
|
||||
else messageError "memberJoinRequestViaRelay: rejected join claiming privileged memberId (key mismatch or invalid signature)"
|
||||
_ -> acceptJoin g signed Nothing gLinkMemRole
|
||||
Nothing ->
|
||||
messageError "memberJoinRequestViaRelay: no group link info for relay link"
|
||||
where
|
||||
|
||||
@@ -39,7 +39,7 @@ import Simplex.Chat.Messages (CIMention (..), CIMentionMember (..), ChatItemId)
|
||||
import Simplex.Chat.Messages.Batch (encodeBinaryBatch, encodeFwdElement)
|
||||
import Simplex.Chat.Messages.CIContent (publicGroupNoE2EText)
|
||||
import Simplex.Chat.Options
|
||||
import Simplex.Chat.Protocol (ChatMessage (ChatMessage), ChatMsgEvent (XGrpMemNew, XGrpRelayInv, XInfo, XMsgUpdate, XMsgNew, XMsgDel), FwdSender (FwdMember, FwdChannel), GrpMsgForward (GrpMsgForward), MsgContainer (..), MsgMention (..), MsgContent (..), VerifiedMsg (VMUnsigned), chatMsgToBody, mcSimple, msgContentText)
|
||||
import Simplex.Chat.Protocol (ChatMessage (ChatMessage), ChatMsgEvent (XGrpMemNew, XGrpRelayInv, XInfo, XMember, XMsgUpdate, XMsgNew, XMsgDel), FwdSender (FwdMember, FwdChannel), GrpMsgForward (GrpMsgForward), MsgContainer (..), MsgMention (..), MsgContent (..), VerifiedMsg (VMUnsigned), chatMsgToBody, mcSimple, msgContentText)
|
||||
import Simplex.Chat.Types
|
||||
import Simplex.Chat.Types.MemberRelations (MemberRelation (..), getRelation, setRelation)
|
||||
import Simplex.Chat.Types.Shared (GroupMemberRole (..), GroupAcceptance (..))
|
||||
@@ -135,6 +135,7 @@ chatGroupTests = do
|
||||
it "demotion does not remove group link" testGroupLinkDemotedAdmin
|
||||
it "host profile received" testGroupLinkHostProfileReceived
|
||||
it "existing contact merged" testGroupLinkExistingContactMerged
|
||||
it "ignore relay join request in group without relays" testGroupLinkIgnoreRelayJoinRequest
|
||||
describe "group links - member screening" $ do
|
||||
it "reject member - blocked name" testGLinkRejectBlockedName
|
||||
it "accept member - only host approval" testGLinkApproveMember
|
||||
@@ -3629,6 +3630,32 @@ testGroupLinkExistingContactMerged =
|
||||
bob #> "#team hi there"
|
||||
alice <# "#team bob> hi there"
|
||||
|
||||
testGroupLinkIgnoreRelayJoinRequest :: HasCallStack => TestParams -> IO ()
|
||||
testGroupLinkIgnoreRelayJoinRequest ps =
|
||||
withNewTestChatOpts ps (testOpts {coreOptions = testCoreOpts {logLevel = CLLWarning}}) "alice" aliceProfile $ \alice ->
|
||||
withNewTestChat ps "bob" bobProfile $ \bob -> do
|
||||
alice ##> "/g team"
|
||||
alice <## "group #team is created"
|
||||
alice <## "to add members use /a team <name> or /create link #team"
|
||||
alice ##> "/create link #team"
|
||||
(gShortLink, _gLink) <- getGroupLinks alice "team" GRMember True
|
||||
sendMemberJoinRequest bob gShortLink
|
||||
alice <## "warning: memberJoinRequestViaRelay (group team): ignored relay join request from bob (group does not use relays)"
|
||||
alice ##> "/ms team"
|
||||
alice <## "alice (Alice): owner, you, created group"
|
||||
|
||||
sendMemberJoinRequest :: TestCC -> String -> IO ()
|
||||
sendMemberJoinRequest cc groupLink =
|
||||
withCCUser cc $ \user -> do
|
||||
gLink :: ShortLinkContact <- either fail pure $ strDecode (B.pack groupLink)
|
||||
(memberKey, _) <- atomically . C.generateKeyPair =<< C.newRandom
|
||||
let joinGroup = do
|
||||
(_, _, cReq) <- getShortLinkConnReq NRMInteractive user gLink
|
||||
(connId, _) <- withAgent $ \a -> prepareConnectionToJoin a (aUserId user) True cReq PQSupportOff
|
||||
dm <- encodeConnInfo $ XMember bobProfile (MemberId "member") (MemberKey memberKey) Nothing
|
||||
withAgent $ \a -> joinConnection a NRMInteractive (aUserId user) connId True cReq dm PQSupportOff SMSubscribe
|
||||
runExceptT joinGroup `runReaderT` chatController cc >>= either (fail . show) (\_ -> pure ())
|
||||
|
||||
testGLinkRejectBlockedName :: HasCallStack => TestParams -> IO ()
|
||||
testGLinkRejectBlockedName =
|
||||
testChatCfg2 cfg aliceProfile bobProfile $
|
||||
|
||||
Reference in new issue
Block a user