summaryrefslogtreecommitdiff
path: root/Presence/Presence.hs
diff options
context:
space:
mode:
authorJoe Crayne <joe@jerkface.net>2018-06-28 22:54:28 -0400
committerJoe Crayne <joe@jerkface.net>2018-06-28 23:57:12 -0400
commit929789aff8840fb54026ffc46cfe46d4780ed0de (patch)
treed34f12d26f125992131e0f6bf8e62712dcb57163 /Presence/Presence.hs
parent8b817ae44034b5a0740df369c002e8953a530840 (diff)
Enable xmpp client to use long-form hex toxid for add-buddy operation.
Diffstat (limited to 'Presence/Presence.hs')
-rw-r--r--Presence/Presence.hs56
1 files changed, 41 insertions, 15 deletions
diff --git a/Presence/Presence.hs b/Presence/Presence.hs
index 53de4e93..45569d32 100644
--- a/Presence/Presence.hs
+++ b/Presence/Presence.hs
@@ -49,7 +49,7 @@ import ConsoleWriter
49import ClientState 49import ClientState
50import Util 50import Util
51import qualified Connection 51import qualified Connection
52import Network.Tox.NodeId (key2id) 52import Network.Tox.NodeId (key2id,parseNoSpamId,nospam64,NoSpamId(..))
53import Crypto.Tox (decodeSecret) 53import Crypto.Tox (decodeSecret)
54import DPut 54import DPut
55 55
@@ -334,25 +334,31 @@ rosterGetStuff
334 -> PresenceState -> ClientAddress -> IO [Text] 334 -> PresenceState -> ClientAddress -> IO [Text]
335rosterGetStuff what state k = forClient state k (return []) 335rosterGetStuff what state k = forClient state k (return [])
336 $ \client -> do 336 $ \client -> do
337 jids <- configText what (clientUser client) (clientProfile client) 337 jids0 <- configText what (clientUser client) (clientProfile client)
338 let hosts = map ((\(_,h,_)->h) . splitJID) jids 338 let jids = map splitJID jids0
339 -- Using case to bring 'status' type variable to Connection.Manager into scope. 339 -- Using case to bring 'status' type variable to Connection.Manager into scope.
340 case state of 340 case state of
341 PresenceState { server = svVar } -> do 341 PresenceState { server = svVar } -> do
342 (sv,conns) <- atomically $ takeTMVar svVar 342 (sv,conns) <- atomically $ takeTMVar svVar
343 -- Grok peers to associate with from the roster: 343 -- Grok peers to associate with from the roster:
344 forM_ hosts $ \host -> do 344 let isTox = do (me , ".tox") <- Just $ Text.splitAt 43 (clientProfile client)
345 return me
346 noToxUsers (u,h,r)
347 | Text.isSuffixOf ".tox" h = unsplitJID (Nothing,h,r)
348 | otherwise = unsplitJID (u,h,r)
349 forM_ jids $ \(_,host,_) -> do
345 -- We need either conns :: Connection.Manager TCPStatus Text 350 -- We need either conns :: Connection.Manager TCPStatus Text
346 -- or toxman :: ToxManager ClientAddress 351 -- or toxman :: ToxManager ClientAddress
347 -- It is decided by checking hostnames for .tox ending. 352 -- It is decided by checking hostnames for .tox ending.
348 let policySetter = fromMaybe (Connection.setPolicy conns host) $ do 353 let policySetter = fromMaybe (Connection.setPolicy conns host) $ do
354 isTox
349 toxman <- toxManager state 355 toxman <- toxManager state
350 (me , ".tox") <- Just $ Text.splitAt 43 (clientProfile client)
351 (them, ".tox") <- Just $ Text.splitAt 43 host 356 (them, ".tox") <- Just $ Text.splitAt 43 host
352 Just $ setToxConnectionPolicy toxman (clientProfile client) host 357 Just $ setToxConnectionPolicy toxman (clientProfile client) host
353 policySetter Connection.TryingToConnect 358 policySetter Connection.TryingToConnect
354 atomically $ putTMVar svVar (sv,conns) 359 atomically $ putTMVar svVar (sv,conns)
355 return jids 360 return $ fromMaybe jids0 $ do isTox
361 Just $ map noToxUsers jids
356 362
357rosterGetBuddies :: PresenceState -> ClientAddress -> IO [Text] 363rosterGetBuddies :: PresenceState -> ClientAddress -> IO [Text]
358rosterGetBuddies state k = rosterGetStuff ConfigFiles.getBuddies state k 364rosterGetBuddies state k = rosterGetStuff ConfigFiles.getBuddies state k
@@ -397,7 +403,7 @@ getSolicited' = configText ConfigFiles.getSolicited
397-- 403--
398-- * Text - Unix user who owns this roster entry. 404-- * Text - Unix user who owns this roster entry.
399-- 405--
400-- * Text - Profile, "." for xmpp, "tox" for a tox-enabled client. 406-- * Text - Profile, "." for xmpp, "<base64-key>.tox" for a tox-enabled client.
401-- 407--
402getBuddiesAndSolicited :: PresenceState 408getBuddiesAndSolicited :: PresenceState
403 -> Text -- ^ Config profile: "." or tox host. 409 -> Text -- ^ Config profile: "." or tox host.
@@ -993,14 +999,24 @@ clientSubscriptionRequest state fail k stanza chan = do
993 forClient state k fail $ \client -> do 999 forClient state k fail $ \client -> do
994 fromMaybe fail $ (splitJID <$> stanzaTo stanza) <&> \(mu,h,_) -> do 1000 fromMaybe fail $ (splitJID <$> stanzaTo stanza) <&> \(mu,h,_) -> do
995 dput XJabber $ "Forwarding solictation to peer" 1001 dput XJabber $ "Forwarding solictation to peer"
996 let to = unsplitJID (mu,h,Nothing) -- deleted resource 1002 let to0 = unsplitJID (mu,h,Nothing) -- deleted resource
997 cuser = clientUser client 1003 cuser = clientUser client
998 cprof = clientProfile client 1004 cprof = clientProfile client
999 fromMaybe fail $ mu <&> \u -> do 1005 mto = if ".tox" `Text.isSuffixOf` cprof
1006 then case parseNoSpamId to0 of
1007 Right toxjid@(NoSpamId nspam _) -> Just ( Text.pack $ '$' : nospam64 nspam
1008 , Text.pack $ show toxjid
1009 , return [] )
1010 Left _ | Text.isSuffixOf ".tox" h -> Nothing
1011 Left _ | Text.all isHexDigit h
1012 && Text.length h == 76 -> Nothing
1013 Left _ -> fmap (\u -> (u, to0 ,resolvePeer h)) mu
1014 else fmap (\u -> (u, to0 ,resolvePeer h)) mu
1015 fromMaybe fail $ mto <&> \(u,to,resolv) -> do
1000 -- add to-address to from's solicited 1016 -- add to-address to from's solicited
1001 addrs <- if all (".tox" `Text.isSuffixOf`) [cprof,h] 1017 dput XJabber $ unlines [ "to0=" ++ Text.unpack to0
1002 then return [] -- Avoid resolving .tox peers. 1018 , "to=" ++ show (Text.unpack to) ]
1003 else resolvePeer h 1019 addrs <- resolv
1004 addToRosterFile ConfigFiles.modifySolicited cuser cprof to addrs 1020 addToRosterFile ConfigFiles.modifySolicited cuser cprof to addrs
1005 removeFromRosterFile ConfigFiles.modifyBuddies cuser cprof to addrs 1021 removeFromRosterFile ConfigFiles.modifyBuddies cuser cprof to addrs
1006 resolved_subs <- resolvedFromRoster ConfigFiles.getSubscribers cuser cprof 1022 resolved_subs <- resolvedFromRoster ConfigFiles.getSubscribers cuser cprof
@@ -1026,12 +1042,16 @@ clientSubscriptionRequest state fail k stanza chan = do
1026 chans <- clientCons state cktc (clientUser client) 1042 chans <- clientCons state cktc (clientUser client)
1027 forM_ chans $ \( Conn { connChan=chan }, client ) -> do 1043 forM_ chans $ \( Conn { connChan=chan }, client ) -> do
1028 -- roster update ask="subscribe" 1044 -- roster update ask="subscribe"
1029 update <- makeRosterUpdate cjid to 1045 update <- myMakeRosterUpdate (clientProfile client) cjid to
1030 [ ("ask","subscribe") 1046 [ ("ask","subscribe")
1031 , if is_subscribed then ("subscription","from") 1047 , if is_subscribed then ("subscription","from")
1032 else ("subscription","none") 1048 else ("subscription","none")
1033 ] 1049 ]
1034 sendModifiedStanzaToClient update chan 1050 sendModifiedStanzaToClient update chan
1051 when (to /= to0) $ do
1052 removal <- myMakeRosterUpdate (clientProfile client) cjid to0
1053 [ ("subscription","remove") ]
1054 sendModifiedStanzaToClient removal chan
1035 _ -> return () 1055 _ -> return ()
1036 1056
1037 -- Send friend request to peer. 1057 -- Send friend request to peer.
@@ -1169,6 +1189,12 @@ peerSubscriptionRequest state fail k stanza chan = do
1169 , stanzaTo = Just $ unsplitJID totup } 1189 , stanzaTo = Just $ unsplitJID totup }
1170 chan 1190 chan
1171 1191
1192myMakeRosterUpdate prf tojid contact as
1193 | ".tox" `Text.isSuffixOf` prf
1194 , (Just u,h,r) <- splitJID contact
1195 , ".tox" `Text.isSuffixOf` u = XMPPServer.makeRosterUpdate tojid (unsplitJID (Nothing,h,r)) as
1196myMakeRosterUpdate _ tojid contact as = XMPPServer.makeRosterUpdate tojid contact as
1197
1172 1198
1173clientInformSubscription :: PresenceState 1199clientInformSubscription :: PresenceState
1174 -> IO () 1200 -> IO ()
@@ -1220,7 +1246,7 @@ clientInformSubscription state fail k stanza = do
1220 hostname <- nameForClient state ck 1246 hostname <- nameForClient state ck
1221 -- TODO: Should cjid include the resource? 1247 -- TODO: Should cjid include the resource?
1222 let cjid = unsplitJID (mu, hostname, Nothing) 1248 let cjid = unsplitJID (mu, hostname, Nothing)
1223 update <- makeRosterUpdate cjid to [relationship] 1249 update <- myMakeRosterUpdate (clientProfile client) cjid to [relationship]
1224 sendModifiedStanzaToClient update (connChan con) 1250 sendModifiedStanzaToClient update (connChan con)
1225 1251
1226 -- notify peer 1252 -- notify peer
@@ -1287,7 +1313,7 @@ peerInformSubscription state fail k stanza = do
1287 forM_ chans $ \(ckey,(Conn { connChan=chan }, client)) -> do 1313 forM_ chans $ \(ckey,(Conn { connChan=chan }, client)) -> do
1288 hostname <- nameForClient state ckey 1314 hostname <- nameForClient state ckey
1289 let to' = unsplitJID (Just user, hostname, Nothing) 1315 let to' = unsplitJID (Just user, hostname, Nothing)
1290 update <- makeRosterUpdate to' from'' [relationship] 1316 update <- myMakeRosterUpdate (clientProfile client) to' from'' [relationship]
1291 is_intereseted <- atomically $ clientIsInterested client 1317 is_intereseted <- atomically $ clientIsInterested client
1292 when is_intereseted $ do 1318 when is_intereseted $ do
1293 sendModifiedStanzaToClient update chan 1319 sendModifiedStanzaToClient update chan