summaryrefslogtreecommitdiff
path: root/Presence/XMPP.hs
diff options
context:
space:
mode:
Diffstat (limited to 'Presence/XMPP.hs')
-rw-r--r--Presence/XMPP.hs92
1 files changed, 79 insertions, 13 deletions
diff --git a/Presence/XMPP.hs b/Presence/XMPP.hs
index 7d69e126..c2ae2fe2 100644
--- a/Presence/XMPP.hs
+++ b/Presence/XMPP.hs
@@ -457,6 +457,8 @@ fromClient session cmdChan = doNestingXML $ do
457 -> clientRequestsSubscription session cmdChan stanza 457 -> clientRequestsSubscription session cmdChan stanza
458 _ | stanza `isClientPresenceOf` presenceTypeSubscribed 458 _ | stanza `isClientPresenceOf` presenceTypeSubscribed
459 -> clientApprovesSubscription session stanza 459 -> clientApprovesSubscription session stanza
460 _ | stanza `isClientPresenceOf` presenceTypeUnsubscribed
461 -> clientRejectsSubscription session stanza
460 _ | otherwise -> unhandledStanza 462 _ | otherwise -> unhandledStanza
461 463
462 awaitCloser stanza_lvl 464 awaitCloser stanza_lvl
@@ -544,6 +546,29 @@ toClient session pchan cmdChan rchan = toClient' False False
544 [attr "subscription" subscription] 546 [attr "subscription" subscription]
545 send r 547 send r
546 loop 548 loop
549 RChan (RemovedBuddy who contact) -> do
550 liftIO . putStrLn $ "Roster push: RemovedBuddy "++show (isInterested,who,contact)
551 (jid,me) <- liftIO $ do
552 jid <- getJID session
553 me <- asHostNameJID jid
554 return (jid,me)
555 withJust me $ \me -> do
556 when (isInterested && Just who==name jid) $ do
557 send [ EventBeginElement "{jabber:client}presence"
558 [ attrbs "from" contact
559 , attrbs "to" me
560 , attr "type" "unsubscribed"
561 ]
562 , EventEndElement "{jabber:client}presence" ]
563 let f True = "from"
564 f False = "none"
565 subscription <- fmap f (liftIO $ isSubscribed session contact)
566 r <- liftIO . handleIO (\e -> putStrLn ("Roster RemovedBuddy error: "++show e) >> return []) $ do
567 rosterPush jid
568 (toStrict . L.decodeUtf8 $ contact)
569 [attr "subscription" subscription]
570 send r
571 loop
547 RChan (NewSubscriber who contact) -> do 572 RChan (NewSubscriber who contact) -> do
548 liftIO . putStrLn $ "Roster push: NewSubscriber "++show (isInterested,who,contact) 573 liftIO . putStrLn $ "Roster push: NewSubscriber "++show (isInterested,who,contact)
549 (jid,me) <- liftIO $ do 574 (jid,me) <- liftIO $ do
@@ -561,6 +586,23 @@ toClient session pchan cmdChan rchan = toClient' False False
561 [attr "subscription" subscription] 586 [attr "subscription" subscription]
562 send r 587 send r
563 loop 588 loop
589 RChan (RejectSubscriber who contact) -> do
590 liftIO . putStrLn $ "Roster push: RejectSubscriber "++show (isInterested,who,contact)
591 (jid,me) <- liftIO $ do
592 jid <- getJID session
593 me <- asHostNameJID jid
594 return (jid,me)
595 withJust me $ \me -> do
596 when (isInterested && Just who==name jid) $ do
597 let f True = "to"
598 f False = "none"
599 subscription <- fmap f (liftIO $ isBuddy session contact)
600 r <- liftIO . handleIO (\e -> putStrLn ("Roster RejectSubscriber error: "++show e) >> return []) $ do
601 rosterPush jid
602 (toStrict . L.decodeUtf8 $ contact)
603 [attr "subscription" subscription]
604 send r
605 loop
564 RChan (PendingSubscriber who contact) -> do 606 RChan (PendingSubscriber who contact) -> do
565 liftIO . putStrLn $ "Roster: Pending buddy "++show (isInterested,who,contact) 607 liftIO . putStrLn $ "Roster: Pending buddy "++show (isInterested,who,contact)
566 (jid,me) <- liftIO $ do 608 (jid,me) <- liftIO $ do
@@ -709,11 +751,12 @@ matchAttribMaybe name Nothing attrs
709 | otherwise 751 | otherwise
710 = False 752 = False
711 753
712presenceTypeOffline = Just "unavailable" 754presenceTypeOffline = Just "unavailable"
713presenceTypeOnline = Nothing 755presenceTypeOnline = Nothing
714presenceTypeProbe = Just "probe" 756presenceTypeProbe = Just "probe"
715presenceTypeSubscribe = Just "subscribe" 757presenceTypeSubscribe = Just "subscribe"
716presenceTypeSubscribed = Just "subscribed" 758presenceTypeSubscribed = Just "subscribed"
759presenceTypeUnsubscribed = Just "unsubscribed"
717 760
718isPresenceOf (EventBeginElement name attrs) testType 761isPresenceOf (EventBeginElement name attrs) testType
719 | name=="{jabber:server}presence" 762 | name=="{jabber:server}presence"
@@ -854,6 +897,11 @@ clientApprovesSubscription session stanza = do
854 withJust (lookupAttrib "to" (tagAttrs stanza)) $ \to_str -> do 897 withJust (lookupAttrib "to" (tagAttrs stanza)) $ \to_str -> do
855 liftIO $ approveSubscriber session (textToByteString to_str) 898 liftIO $ approveSubscriber session (textToByteString to_str)
856 899
900clientRejectsSubscription session stanza = do
901 liftIO $ putStrLn $ "CLIENT REJECTS SUBSCRIPTION"
902 withJust (lookupAttrib "to" (tagAttrs stanza)) $ \to_str -> do
903 liftIO $ rejectSubscriber session (textToByteString to_str)
904
857peerApprovesSubscription session stanza = do 905peerApprovesSubscription session stanza = do
858 liftIO $ putStrLn $ "PEER APPROVES SUBSCRIPTION" 906 liftIO $ putStrLn $ "PEER APPROVES SUBSCRIPTION"
859 whenJust (liftIO . handleIO (\e -> putStrLn ("peerApprovesSubscription: "++show e) >> return Nothing) 907 whenJust (liftIO . handleIO (\e -> putStrLn ("peerApprovesSubscription: "++show e) >> return Nothing)
@@ -861,6 +909,13 @@ peerApprovesSubscription session stanza = do
861 withJust (name tojid) $ \user -> do 909 withJust (name tojid) $ \user -> do
862 liftIO $ processApproval session user fromjid 910 liftIO $ processApproval session user fromjid
863 911
912peerRejectsSubscription session stanza = do
913 liftIO $ putStrLn $ "PEER REJECTS SUBSCRIPTION"
914 whenJust (liftIO . handleIO (\e -> putStrLn ("peerRejectsSubscription: "++show e) >> return Nothing)
915 $ stanzaFromTo session stanza) $ \(fromjid,tojid) -> do
916 withJust (name tojid) $ \user -> do
917 liftIO $ processRejection session user fromjid
918
864fromPeer :: (MonadThrow m,MonadIO m, JabberPeerSession session) => 919fromPeer :: (MonadThrow m,MonadIO m, JabberPeerSession session) =>
865 session -> Sink XML.Event m () 920 session -> Sink XML.Event m ()
866fromPeer session = doNestingXML $ do 921fromPeer session = doNestingXML $ do
@@ -891,6 +946,8 @@ fromPeer session = doNestingXML $ do
891 -> peerRequestsSubsription session stanza 946 -> peerRequestsSubsription session stanza
892 _ | stanza `isPresenceOf` presenceTypeSubscribed 947 _ | stanza `isPresenceOf` presenceTypeSubscribed
893 -> peerApprovesSubscription session stanza 948 -> peerApprovesSubscription session stanza
949 _ | stanza `isPresenceOf` presenceTypeUnsubscribed
950 -> peerRejectsSubscription session stanza
894 _ -> unhandledStanza 951 _ -> unhandledStanza
895 952
896 awaitCloser stanza_lvl 953 awaitCloser stanza_lvl
@@ -908,7 +965,7 @@ newServerConnections = newTVar Map.empty
908data CachedMessages = CachedMessages 965data CachedMessages = CachedMessages
909 { presences :: Map JID JabberShow 966 { presences :: Map JID JabberShow
910 , probes :: Map JID (Set (Bool,JID)) -- False means solicitation rather than probe 967 , probes :: Map JID (Set (Bool,JID)) -- False means solicitation rather than probe
911 , approvals :: Map JID (Set JID) 968 , approvals :: Map JID (Set (Bool,JID) ) -- False means rejection rather than approval
912 } 969 }
913newCache = CachedMessages Map.empty Map.empty Map.empty 970newCache = CachedMessages Map.empty Map.empty Map.empty
914 971
@@ -938,7 +995,11 @@ connect_to_server chan peer = (>> return ()) . runMaybeT $ do
938 writeIORef cached (cache { probes=probes' }) 995 writeIORef cached (cache { probes=probes' })
939 cacheCmd (Approval from to) cached = do 996 cacheCmd (Approval from to) cached = do
940 cache <- readIORef cached 997 cache <- readIORef cached
941 let approvals' = mmInsert from to $ approvals cache 998 let approvals' = mmInsert (True,from) to $ approvals cache
999 writeIORef cached (cache { approvals=approvals' })
1000 cacheCmd (Rejection from to) cached = do
1001 cache <- readIORef cached
1002 let approvals' = mmInsert (False,from) to $ approvals cache
942 writeIORef cached (cache { approvals=approvals' }) 1003 writeIORef cached (cache { approvals=approvals' })
943 1004
944 fix $ \sendmsgs -> do 1005 fix $ \sendmsgs -> do
@@ -1038,16 +1099,18 @@ toPeer sock cache chan fail = do
1038 sendSolicitation from to = 1099 sendSolicitation from to =
1039 sendOrFail (presenceStanza sock from to "subscribe") 1100 sendOrFail (presenceStanza sock from to "subscribe")
1040 (Solicitation from to) 1101 (Solicitation from to)
1041 sendApproval from to = 1102 sendApproval approve from to =
1042 sendOrFail (presenceStanza sock from to "subscribed") 1103 sendOrFail (presenceStanza sock from to
1043 (Approval from to) 1104 (if approve then "subscribed" else "unsubscribed"))
1105 (if approve then Approval from to
1106 else Rejection from to)
1044 1107
1045 1108
1046 send greetPeer 1109 send greetPeer
1047 forM_ (Map.assocs . approvals $ cache) $ \(to,froms) -> do 1110 forM_ (Map.assocs . approvals $ cache) $ \(to,froms) -> do
1048 forM_ (Set.toList froms) $ \from -> do 1111 forM_ (Set.toList froms) $ \(approve,from) -> do
1049 liftIO $ L.putStrLn "sending cached approval..." 1112 liftIO $ L.putStrLn "sending cached approval..."
1050 sendApproval from to 1113 sendApproval approve from to
1051 forM_ (Map.assocs . presences $ cache) $ \(jid,st) -> do 1114 forM_ (Map.assocs . presences $ cache) $ \(jid,st) -> do
1052 sendPresence (Presence jid st) 1115 sendPresence (Presence jid st)
1053 forM_ (Map.assocs . probes $ cache) $ \(to,froms) -> do 1116 forM_ (Map.assocs . probes $ cache) $ \(to,froms) -> do
@@ -1073,7 +1136,10 @@ toPeer sock cache chan fail = do
1073 sendSolicitation from to 1136 sendSolicitation from to
1074 Approval from to -> do 1137 Approval from to -> do
1075 liftIO . L.putStrLn $ "sending approval "<++>bshow (from,to) 1138 liftIO . L.putStrLn $ "sending approval "<++>bshow (from,to)
1076 sendApproval from to 1139 sendApproval True from to
1140 Rejection from to -> do
1141 liftIO . L.putStrLn $ "sending rejection "<++>bshow (from,to)
1142 sendApproval False from to
1077 loop 1143 loop
1078 send goodbyePeer 1144 send goodbyePeer
1079 1145