diff options
Diffstat (limited to 'Presence')
-rw-r--r-- | Presence/Presence.hs | 1 | ||||
-rw-r--r-- | Presence/XMPPServer.hs | 66 |
2 files changed, 56 insertions, 11 deletions
diff --git a/Presence/Presence.hs b/Presence/Presence.hs index 0ae9653f..224d3282 100644 --- a/Presence/Presence.hs +++ b/Presence/Presence.hs | |||
@@ -169,6 +169,7 @@ presenceHooks state verbosity mclient mpeer = XMPPServerParameters | |||
169 | , xmppClientInformSubscription = clientInformSubscription state | 169 | , xmppClientInformSubscription = clientInformSubscription state |
170 | , xmppPeerInformSubscription = peerInformSubscription state | 170 | , xmppPeerInformSubscription = peerInformSubscription state |
171 | , xmppVerbosity = return verbosity | 171 | , xmppVerbosity = return verbosity |
172 | , xmppGroupChat = Map.singleton "chat" MUC | ||
172 | , xmppClientBind = mclient | 173 | , xmppClientBind = mclient |
173 | , xmppPeerBind = mpeer | 174 | , xmppPeerBind = mpeer |
174 | } | 175 | } |
diff --git a/Presence/XMPPServer.hs b/Presence/XMPPServer.hs index dcbc9bf5..bc64ecd8 100644 --- a/Presence/XMPPServer.hs +++ b/Presence/XMPPServer.hs | |||
@@ -15,6 +15,7 @@ module XMPPServer | |||
15 | , Remote(..) | 15 | , Remote(..) |
16 | , ConnectionData(..) | 16 | , ConnectionData(..) |
17 | , ConnectionType(..) | 17 | , ConnectionType(..) |
18 | , MUC(..) | ||
18 | , XMPPServerParameters(..) | 19 | , XMPPServerParameters(..) |
19 | , XMPPServer | 20 | , XMPPServer |
20 | , classifyConnection | 21 | , classifyConnection |
@@ -93,7 +94,7 @@ import Data.XML.Types as XML | |||
93 | import Data.Maybe | 94 | import Data.Maybe |
94 | import Data.Monoid ( (<>) ) | 95 | import Data.Monoid ( (<>) ) |
95 | import Data.Text (Text) | 96 | import Data.Text (Text) |
96 | import qualified Data.Text as Text (pack,unpack,intercalate,drop,toLower) | 97 | import qualified Data.Text as Text |
97 | import qualified Data.Map as Map | 98 | import qualified Data.Map as Map |
98 | import Data.Set (Set, (\\) ) | 99 | import Data.Set (Set, (\\) ) |
99 | import qualified Data.Set as Set | 100 | import qualified Data.Set as Set |
@@ -118,6 +119,10 @@ my_uuid = "154ae29f-98f2-4af4-826d-a40c8a188574" | |||
118 | newtype Local a = Local a deriving (Eq,Ord,Show) | 119 | newtype Local a = Local a deriving (Eq,Ord,Show) |
119 | newtype Remote a = Remote a deriving (Eq,Ord,Show) | 120 | newtype Remote a = Remote a deriving (Eq,Ord,Show) |
120 | 121 | ||
122 | data MUC = MUC | ||
123 | { -- todo | ||
124 | } | ||
125 | |||
121 | data XMPPServerParameters = | 126 | data XMPPServerParameters = |
122 | XMPPServerParameters | 127 | XMPPServerParameters |
123 | { -- | Called when a client requests a resource id. The first Maybe indicates | 128 | { -- | Called when a client requests a resource id. The first Maybe indicates |
@@ -155,6 +160,7 @@ data XMPPServerParameters = | |||
155 | , xmppClientInformSubscription :: IO () -> ClientAddress -> Stanza -> IO () | 160 | , xmppClientInformSubscription :: IO () -> ClientAddress -> Stanza -> IO () |
156 | , -- | Called when a remote peer informs us of our subscription status. | 161 | , -- | Called when a remote peer informs us of our subscription status. |
157 | xmppPeerInformSubscription :: IO () -> PeerAddress -> Stanza -> IO () | 162 | xmppPeerInformSubscription :: IO () -> PeerAddress -> Stanza -> IO () |
163 | , xmppGroupChat :: Map.Map Text MUC -- Key should be lowercase identifier. | ||
158 | , xmppVerbosity :: IO Int | 164 | , xmppVerbosity :: IO Int |
159 | , xmppClientBind :: Maybe SockAddr | 165 | , xmppClientBind :: Maybe SockAddr |
160 | , xmppPeerBind :: Maybe SockAddr | 166 | , xmppPeerBind :: Maybe SockAddr |
@@ -640,12 +646,42 @@ makeInfo mid from mto = concat | |||
640 | , EventEndElement "{http://jabber.org/protocol/disco#info}identity" | 646 | , EventEndElement "{http://jabber.org/protocol/disco#info}identity" |
641 | , EventBeginElement "{http://jabber.org/protocol/disco#info}feature" | 647 | , EventBeginElement "{http://jabber.org/protocol/disco#info}feature" |
642 | [("var",[ContentText "http://jabber.org/protocol/disco#info"])] | 648 | [("var",[ContentText "http://jabber.org/protocol/disco#info"])] |
649 | , EventEndElement "{http://jabber.org/protocol/disco#info}feature" | ||
650 | , EventBeginElement "{http://jabber.org/protocol/disco#info}feature" | ||
651 | [("var",[ContentText "http://jabber.org/protocol/disco#items"])] | ||
643 | , EventEndElement "{http://jabber.org/protocol/disco#info}feature" ] | 652 | , EventEndElement "{http://jabber.org/protocol/disco#info}feature" ] |
644 | , [] -- todo | 653 | , [] -- todo |
645 | , [ EventEndElement "{http://jabber.org/protocol/disco#info}query" | 654 | , [ EventEndElement "{http://jabber.org/protocol/disco#info}query" |
646 | , EventEndElement "{jabber:client}iq" ] | 655 | , EventEndElement "{jabber:client}iq" ] |
647 | ] | 656 | ] |
648 | 657 | ||
658 | makeMUCInfo :: Maybe Text -> Text -> Maybe Text -> [Event] | ||
659 | makeMUCInfo mid from mto = concat | ||
660 | [ [ EventBeginElement "{jabber:client}iq" | ||
661 | $ consid mid $ maybe id (\to -> (("to", [ContentText to]) :)) mto | ||
662 | [("from", [ContentText from]) | ||
663 | ,("type", [ContentText "result"])] | ||
664 | , EventBeginElement "{http://jabber.org/protocol/disco#info}query" [] | ||
665 | , EventBeginElement "{http://jabber.org/protocol/disco#info}identity" | ||
666 | [("category",[ContentText "conference"]) | ||
667 | ,("type",[ContentText "text"])] | ||
668 | , EventEndElement "{http://jabber.org/protocol/disco#info}identity" | ||
669 | {- | ||
670 | , EventBeginElement "{http://jabber.org/protocol/disco#info}feature" | ||
671 | [("var",[ContentText "http://jabber.org/protocol/disco#info"])] | ||
672 | , EventEndElement "{http://jabber.org/protocol/disco#info}feature" | ||
673 | , EventBeginElement "{http://jabber.org/protocol/disco#info}feature" | ||
674 | [("var",[ContentText "http://jabber.org/protocol/disco#items"])] | ||
675 | , EventEndElement "{http://jabber.org/protocol/disco#info}feature" | ||
676 | -} | ||
677 | , EventBeginElement "{http://jabber.org/protocol/disco#info}feature" | ||
678 | [("var",[ContentText "http://jabber.org/protocol/muc"])] | ||
679 | , EventEndElement "{http://jabber.org/protocol/disco#info}feature" ] | ||
680 | , [] | ||
681 | , [ EventEndElement "{http://jabber.org/protocol/disco#info}query" | ||
682 | , EventEndElement "{jabber:client}iq" ] | ||
683 | ] | ||
684 | |||
649 | makeItemList :: Maybe Text -> [(Text,Maybe Text)] -> Text -> Maybe Text -> [Event] | 685 | makeItemList :: Maybe Text -> [(Text,Maybe Text)] -> Text -> Maybe Text -> [Event] |
650 | makeItemList mid items from mto = concat | 686 | makeItemList mid items from mto = concat |
651 | [ [ EventBeginElement "{jabber:client}iq" | 687 | [ [ EventBeginElement "{jabber:client}iq" |
@@ -1338,20 +1374,28 @@ applyStanza sv quitVar xmpp stanza = case stanzaOrigin stanza of | |||
1338 | NotifyClientVersion name version -> do | 1374 | NotifyClientVersion name version -> do |
1339 | enableClientHacks name version replyto | 1375 | enableClientHacks name version replyto |
1340 | RequestInfo -> do | 1376 | RequestInfo -> do |
1341 | -- TODO ItemNotFound | ||
1342 | me <- xmppTellMyNameToClient xmpp k | 1377 | me <- xmppTellMyNameToClient xmpp k |
1343 | if fmap Text.toLower (stanzaTo stanza) == Just (Text.toLower me) | 1378 | let fail = let query = "{http://jabber.org/protocol/disco#info}info" |
1344 | then | 1379 | reply = iq_service_unavailable (stanzaId stanza) me query |
1345 | let reply = makeInfo (stanzaId stanza) me (stanzaFrom stanza) | 1380 | in sendReply quitVar (Error ServiceUnavailable (head reply)) reply replyto |
1346 | in sendReply quitVar Info reply replyto | 1381 | case fmap Text.toLower (stanzaTo stanza) of |
1347 | else | 1382 | Nothing -> fail |
1348 | let query = "{http://jabber.org/protocol/disco#info}info" | 1383 | Just nm | nm == Text.toLower me |
1349 | reply = iq_service_unavailable (stanzaId stanza) me query | 1384 | -> let reply = makeInfo (stanzaId stanza) me (stanzaFrom stanza) |
1350 | in sendReply quitVar (Error ServiceUnavailable (head reply)) reply replyto | 1385 | in sendReply quitVar Info reply replyto |
1386 | Just nm | let (a,b) = Text.break (=='.') nm | ||
1387 | , Text.drop 1 b == Text.toLower me | ||
1388 | , Just muc <- Map.lookup a (xmppGroupChat xmpp) | ||
1389 | -> let reply = makeMUCInfo (stanzaId stanza) (a <> "." <> me) (stanzaFrom stanza) | ||
1390 | in sendReply quitVar Info reply replyto | ||
1391 | -- TODO ItemNotFound | ||
1392 | _ -> fail | ||
1351 | RequestItems -> do | 1393 | RequestItems -> do |
1352 | -- let query = "{http://jabber.org/protocol/disco#items}query" | 1394 | -- let query = "{http://jabber.org/protocol/disco#items}query" |
1353 | me <- xmppTellMyNameToClient xmpp k | 1395 | me <- xmppTellMyNameToClient xmpp k |
1354 | let items = [] | 1396 | let items = do |
1397 | (name,MUC {}) <- Map.toList $ xmppGroupChat xmpp | ||
1398 | return (name <> "." <> me, Nothing) | ||
1355 | reply = makeItemList (stanzaId stanza) items me (stanzaFrom stanza) | 1399 | reply = makeItemList (stanzaId stanza) items me (stanzaFrom stanza) |
1356 | sendReply quitVar Items reply replyto | 1400 | sendReply quitVar Items reply replyto |
1357 | UnrecognizedQuery query -> do | 1401 | UnrecognizedQuery query -> do |