diff options
author | Joe Crayne <joe@jerkface.net> | 2018-06-28 22:54:28 -0400 |
---|---|---|
committer | Joe Crayne <joe@jerkface.net> | 2018-06-28 23:57:12 -0400 |
commit | 929789aff8840fb54026ffc46cfe46d4780ed0de (patch) | |
tree | d34f12d26f125992131e0f6bf8e62712dcb57163 /Presence | |
parent | 8b817ae44034b5a0740df369c002e8953a530840 (diff) |
Enable xmpp client to use long-form hex toxid for add-buddy operation.
Diffstat (limited to 'Presence')
-rw-r--r-- | Presence/Presence.hs | 56 |
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 | |||
49 | import ClientState | 49 | import ClientState |
50 | import Util | 50 | import Util |
51 | import qualified Connection | 51 | import qualified Connection |
52 | import Network.Tox.NodeId (key2id) | 52 | import Network.Tox.NodeId (key2id,parseNoSpamId,nospam64,NoSpamId(..)) |
53 | import Crypto.Tox (decodeSecret) | 53 | import Crypto.Tox (decodeSecret) |
54 | import DPut | 54 | import DPut |
55 | 55 | ||
@@ -334,25 +334,31 @@ rosterGetStuff | |||
334 | -> PresenceState -> ClientAddress -> IO [Text] | 334 | -> PresenceState -> ClientAddress -> IO [Text] |
335 | rosterGetStuff what state k = forClient state k (return []) | 335 | rosterGetStuff 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 | ||
357 | rosterGetBuddies :: PresenceState -> ClientAddress -> IO [Text] | 363 | rosterGetBuddies :: PresenceState -> ClientAddress -> IO [Text] |
358 | rosterGetBuddies state k = rosterGetStuff ConfigFiles.getBuddies state k | 364 | rosterGetBuddies 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 | -- |
402 | getBuddiesAndSolicited :: PresenceState | 408 | getBuddiesAndSolicited :: 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 | ||
1192 | myMakeRosterUpdate 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 | ||
1196 | myMakeRosterUpdate _ tojid contact as = XMPPServer.makeRosterUpdate tojid contact as | ||
1197 | |||
1172 | 1198 | ||
1173 | clientInformSubscription :: PresenceState | 1199 | clientInformSubscription :: 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 |