diff options
Diffstat (limited to 'Presence/XMPP.hs')
-rw-r--r-- | Presence/XMPP.hs | 92 |
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 | ||
712 | presenceTypeOffline = Just "unavailable" | 754 | presenceTypeOffline = Just "unavailable" |
713 | presenceTypeOnline = Nothing | 755 | presenceTypeOnline = Nothing |
714 | presenceTypeProbe = Just "probe" | 756 | presenceTypeProbe = Just "probe" |
715 | presenceTypeSubscribe = Just "subscribe" | 757 | presenceTypeSubscribe = Just "subscribe" |
716 | presenceTypeSubscribed = Just "subscribed" | 758 | presenceTypeSubscribed = Just "subscribed" |
759 | presenceTypeUnsubscribed = Just "unsubscribed" | ||
717 | 760 | ||
718 | isPresenceOf (EventBeginElement name attrs) testType | 761 | isPresenceOf (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 | ||
900 | clientRejectsSubscription 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 | |||
857 | peerApprovesSubscription session stanza = do | 905 | peerApprovesSubscription 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 | ||
912 | peerRejectsSubscription 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 | |||
864 | fromPeer :: (MonadThrow m,MonadIO m, JabberPeerSession session) => | 919 | fromPeer :: (MonadThrow m,MonadIO m, JabberPeerSession session) => |
865 | session -> Sink XML.Event m () | 920 | session -> Sink XML.Event m () |
866 | fromPeer session = doNestingXML $ do | 921 | fromPeer 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 | |||
908 | data CachedMessages = CachedMessages | 965 | data 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 | } |
913 | newCache = CachedMessages Map.empty Map.empty Map.empty | 970 | newCache = 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 | ||