diff options
Diffstat (limited to 'Presence')
-rw-r--r-- | Presence/XMPP.hs | 87 |
1 files changed, 72 insertions, 15 deletions
diff --git a/Presence/XMPP.hs b/Presence/XMPP.hs index f25d3261..7b01711e 100644 --- a/Presence/XMPP.hs +++ b/Presence/XMPP.hs | |||
@@ -366,10 +366,10 @@ getRoster session iqid = do | |||
366 | xmlify solicited stype set = flip concatMap (Set.toList set) | 366 | xmlify solicited stype set = flip concatMap (Set.toList set) |
367 | $ \jid -> | 367 | $ \jid -> |
368 | [ EventBeginElement "item" | 368 | [ EventBeginElement "item" |
369 | ([("jid",[ContentText (toStrict . L.decodeUtf8 $ jid)]) | 369 | ([ attr "jid" (toStrict . L.decodeUtf8 $ jid) |
370 | ,("subscription",[ContentText stype]) | 370 | , attr "subscription" stype |
371 | ]++if Set.member jid solicited | 371 | ]++if Set.member jid solicited |
372 | then [("ask",[ContentText "subscribe"])] | 372 | then [attr "ask" "subscribe"] |
373 | else [] ) | 373 | else [] ) |
374 | , EventEndElement "item" | 374 | , EventEndElement "item" |
375 | ] | 375 | ] |
@@ -390,11 +390,11 @@ handleIQGet session cmdChan tag = do | |||
390 | let mjid = lookupAttrib "from" (tagAttrs tag) | 390 | let mjid = lookupAttrib "from" (tagAttrs tag) |
391 | let pong = [ EventBeginElement "{jabber:client}iq" | 391 | let pong = [ EventBeginElement "{jabber:client}iq" |
392 | $ (case mjid of | 392 | $ (case mjid of |
393 | Just jid -> (("to",[ContentText jid]):) | 393 | Just jid -> (attr "to" jid :) |
394 | _ -> id) | 394 | _ -> id ) |
395 | [("type",[ContentText "result"]) | 395 | [ attr "type" "result" |
396 | ,("id",[ContentText stanza_id]) | 396 | , attr "id" stanza_id |
397 | ,("from",[ContentText host]) | 397 | , attr "from" host |
398 | ] | 398 | ] |
399 | , EventEndElement "{jabber:client}iq" | 399 | , EventEndElement "{jabber:client}iq" |
400 | ] | 400 | ] |
@@ -442,6 +442,10 @@ fromClient session cmdChan = doNestingXML $ do | |||
442 | case () of | 442 | case () of |
443 | _ | stanza `isIQOf` iqTypeSet -> handleIQSet session cmdChan stanza | 443 | _ | stanza `isIQOf` iqTypeSet -> handleIQSet session cmdChan stanza |
444 | _ | stanza `isIQOf` iqTypeGet -> handleIQGet session cmdChan stanza | 444 | _ | stanza `isIQOf` iqTypeGet -> handleIQGet session cmdChan stanza |
445 | _ | stanza `isPresenceOf` presenceTypeSubscribe | ||
446 | -> clientRequestsSubscription session stanza | ||
447 | _ | stanza `isPresenceOf` presenceTypeSubscribed | ||
448 | -> clientApprovesSubscription session stanza | ||
445 | _ | otherwise -> unhandledStanza | 449 | _ | otherwise -> unhandledStanza |
446 | 450 | ||
447 | awaitCloser stanza_lvl | 451 | awaitCloser stanza_lvl |
@@ -597,6 +601,8 @@ matchAttribMaybe name Nothing attrs | |||
597 | presenceTypeOffline = Just "unavailable" | 601 | presenceTypeOffline = Just "unavailable" |
598 | presenceTypeOnline = Nothing | 602 | presenceTypeOnline = Nothing |
599 | presenceTypeProbe = Just "probe" | 603 | presenceTypeProbe = Just "probe" |
604 | presenceTypeSubscribe = Just "subscribe" | ||
605 | presenceTypeSubscribed = Just "subscribed" | ||
600 | 606 | ||
601 | isPresenceOf (EventBeginElement name attrs) testType | 607 | isPresenceOf (EventBeginElement name attrs) testType |
602 | | name=="{jabber:server}presence" | 608 | | name=="{jabber:server}presence" |
@@ -624,6 +630,53 @@ handlePresenceProbe session stanza = do | |||
624 | mapM_ (announcePresence session) ps | 630 | mapM_ (announcePresence session) ps |
625 | return () | 631 | return () |
626 | 632 | ||
633 | subscribeToPresence subscribers peer_jid user = do | ||
634 | pjid <- parseAddressJID peer_jid | ||
635 | if Set.member pjid subscribers | ||
636 | then return () | ||
637 | else return () | ||
638 | |||
639 | bare (JID n host _) = JID n host Nothing | ||
640 | |||
641 | clientRequestsSubscription session stanza = do | ||
642 | -- make bare jid | ||
643 | -- check local server and obey rules 3.1.3 of rfc 6121 | ||
644 | -- or forward to remote peer | ||
645 | -- or bail with type='error' as shown in 3.1.2 | ||
646 | -- if not bailed, | ||
647 | -- add to solicited | ||
648 | -- do roster push with subscription=none ask=subscribe | ||
649 | liftIO $ putStrLn $ "CLIENT PRESENCE SUBSCRIBE " ++ show stanza | ||
650 | -- add solicited | ||
651 | -- notify other clients | ||
652 | -- notify peer | ||
653 | return () | ||
654 | |||
655 | peerRequestsSubsription session stanza = do | ||
656 | liftIO $ putStrLn $ "PEER PRESENCE SUBSCRIBE " ++ show stanza | ||
657 | -- if no client: | ||
658 | -- add pending | ||
659 | -- else: | ||
660 | -- notify client | ||
661 | return () | ||
662 | |||
663 | clientApprovesSubscription session stanza = do | ||
664 | liftIO $ putStrLn $ "CLIENT APPROVES SUBSCRIPTION" | ||
665 | -- add subscribers | ||
666 | -- remove pending | ||
667 | -- remove others | ||
668 | -- notify peer | ||
669 | return () | ||
670 | |||
671 | peerApprovesSubscription session stanza = do | ||
672 | liftIO $ putStrLn $ "PEER APPROVES SUBSCRIPTION" | ||
673 | -- if solicited: | ||
674 | -- add buddies | ||
675 | -- remove others | ||
676 | -- remove solicited | ||
677 | -- notify client | ||
678 | return () | ||
679 | |||
627 | fromPeer :: (MonadThrow m,MonadIO m, JabberPeerSession session) => | 680 | fromPeer :: (MonadThrow m,MonadIO m, JabberPeerSession session) => |
628 | session -> Sink XML.Event m () | 681 | session -> Sink XML.Event m () |
629 | fromPeer session = doNestingXML $ do | 682 | fromPeer session = doNestingXML $ do |
@@ -650,6 +703,10 @@ fromPeer session = doNestingXML $ do | |||
650 | -> handlePeerPresence session stanza False | 703 | -> handlePeerPresence session stanza False |
651 | _ | stanza `isPresenceOf` presenceTypeProbe | 704 | _ | stanza `isPresenceOf` presenceTypeProbe |
652 | -> handlePresenceProbe session stanza | 705 | -> handlePresenceProbe session stanza |
706 | _ | stanza `isPresenceOf` presenceTypeSubscribe | ||
707 | -> peerRequestsSubsription session stanza | ||
708 | _ | stanza `isPresenceOf` presenceTypeSubscribed | ||
709 | -> peerApprovesSubscription session stanza | ||
653 | _ -> unhandledStanza | 710 | _ -> unhandledStanza |
654 | 711 | ||
655 | awaitCloser stanza_lvl | 712 | awaitCloser stanza_lvl |
@@ -718,8 +775,8 @@ connect_to_server chan peer = (>> return ()) . runMaybeT $ do | |||
718 | greetPeer = | 775 | greetPeer = |
719 | [ EventBeginDocument | 776 | [ EventBeginDocument |
720 | , EventBeginElement (streamP "stream") | 777 | , EventBeginElement (streamP "stream") |
721 | [("xmlns",[ContentText "jabber:server"]) | 778 | [ attr "xmlns" "jabber:server" |
722 | ,("version",[ContentText "1.0"]) | 779 | , attr "version" "1.0" |
723 | ] | 780 | ] |
724 | ] | 781 | ] |
725 | 782 | ||
@@ -740,9 +797,9 @@ presenceProbe sock fromjid tojid = do | |||
740 | <?++> showPeer (peer tojid) | 797 | <?++> showPeer (peer tojid) |
741 | return | 798 | return |
742 | [ EventBeginElement "{jabber:server}presence" | 799 | [ EventBeginElement "{jabber:server}presence" |
743 | [("from",[ContentText from]) | 800 | [ attr "from" from |
744 | ,("to",[ContentText to]) | 801 | , attr "to" to |
745 | ,("type",[ContentText "probe"]) | 802 | , attr "type" "probe" |
746 | ] | 803 | ] |
747 | , EventEndElement "{jabber:server}presence" | 804 | , EventEndElement "{jabber:server}presence" |
748 | ] | 805 | ] |
@@ -932,14 +989,14 @@ xmlifyPresenceForPeer sock (Presence jid stat) = do | |||
932 | $ n <$++> "@" <?++> showPeer (RemotePeer addr) <++?> "/" <++$> rsc | 989 | $ n <$++> "@" <?++> showPeer (RemotePeer addr) <++?> "/" <++$> rsc |
933 | return | 990 | return |
934 | [ EventBeginElement "{jabber:server}presence" | 991 | [ EventBeginElement "{jabber:server}presence" |
935 | (("from",[ContentText jidstr]):typ stat) | 992 | (attr "from" jidstr:typ stat) |
936 | , EventBeginElement "{jabber:server}show" [] | 993 | , EventBeginElement "{jabber:server}show" [] |
937 | , EventContent (ContentText . shw $ stat) | 994 | , EventContent (ContentText . shw $ stat) |
938 | , EventEndElement "{jabber:server}show" | 995 | , EventEndElement "{jabber:server}show" |
939 | , EventEndElement "{jabber:server}presence" | 996 | , EventEndElement "{jabber:server}presence" |
940 | ] | 997 | ] |
941 | where | 998 | where |
942 | typ Offline = [("type",[ContentText "unavailable"])] | 999 | typ Offline = [attr "type" "unavailable"] |
943 | typ _ = [] | 1000 | typ _ = [] |
944 | shw Available = "chat" | 1001 | shw Available = "chat" |
945 | shw Away = "away" | 1002 | shw Away = "away" |