summaryrefslogtreecommitdiff
path: root/Presence
diff options
context:
space:
mode:
Diffstat (limited to 'Presence')
-rw-r--r--Presence/XMPPServer.hs39
1 files changed, 28 insertions, 11 deletions
diff --git a/Presence/XMPPServer.hs b/Presence/XMPPServer.hs
index 6f117204..aae5e97a 100644
--- a/Presence/XMPPServer.hs
+++ b/Presence/XMPPServer.hs
@@ -59,7 +59,7 @@ import Data.Maybe
59import Data.List (nub) 59import Data.List (nub)
60import Data.Monoid ( (<>) ) 60import Data.Monoid ( (<>) )
61import Data.Text (Text) 61import Data.Text (Text)
62import qualified Data.Text as Text (pack,unpack) 62import qualified Data.Text as Text (pack,unpack,words,intercalate)
63import Data.Char (toUpper,chr,ord) 63import Data.Char (toUpper,chr,ord)
64import Data.Map (Map) 64import Data.Map (Map)
65import qualified Data.Map as Map 65import qualified Data.Map as Map
@@ -144,6 +144,7 @@ data StanzaType
144 | PresenceStatus { presenceShow :: JabberShow 144 | PresenceStatus { presenceShow :: JabberShow
145 , presencePriority :: Maybe Int8 145 , presencePriority :: Maybe Int8
146 , presenceStatus :: [(Lang,Text)] 146 , presenceStatus :: [(Lang,Text)]
147 , presenceWhiteList :: [Text]
147 } 148 }
148 | PresenceInformError 149 | PresenceInformError
149 | PresenceInformSubscription Bool 150 | PresenceInformSubscription Bool
@@ -334,18 +335,29 @@ swapit old new (EventEndElement n) | nameNamespace n==Just old =
334swapit old new x = x 335swapit old new x = x
335 336
336fixHeaders :: Monad m => Stanza -> ConduitM Event Event m () 337fixHeaders :: Monad m => Stanza -> ConduitM Event Event m ()
337fixHeaders Stanza { stanzaTo=mto, stanzaFrom=mfrom } = do 338fixHeaders Stanza { stanzaType=typ, stanzaTo=mto, stanzaFrom=mfrom } = do
338 x <- await 339 x <- await
339 maybe (return ()) f x 340 maybe (return ()) f x
340 where 341 where
341 f (EventBeginElement n as) = do yield $ EventBeginElement n (update as) 342 f (EventBeginElement n as) = do yield $ EventBeginElement n (update n as)
342 awaitForever yield 343 awaitForever yield
343 f x = yield x >> awaitForever yield 344 f x = yield x >> awaitForever yield
344 update as = as'' 345 update n as = as3
345 where 346 where
346 as' = maybe as (\to->attr "to" to:as) mto 347 as' = maybe as (setAttrib "to" as) mto
347 as'' = maybe as' (\from->attr "from" from:as') mfrom 348 as'' = maybe as' (setAttrib "from" as') mfrom
348 349 as3 = case typ of
350 PresenceStatus {} | nameNamespace n == Just "jabber:client"
351 -> delAttrib "whitelist" as''
352 PresenceStatus {} | otherwise
353 -> case presenceWhiteList typ of
354 [] -> delAttrib "whitelist" as''
355 ws -> setAttrib "whitelist" as'' (Text.intercalate " " ws)
356 _ -> as''
357
358 setAttrib akey as aval = attr akey aval:filter ((/=akey) . fst) as
359 delAttrib akey as = filter ((/=akey) . fst) as
360
349conduitToChan 361conduitToChan
350 :: Conduit () IO Event 362 :: Conduit () IO Event
351 -> IO (LockedChan Event, TVar (Maybe [Event]), TMVar a) 363 -> IO (LockedChan Event, TVar (Maybe [Event]), TMVar a)
@@ -588,8 +600,8 @@ chanContents ch = do
588parsePresenceStatus 600parsePresenceStatus
589 :: ( MonadThrow m 601 :: ( MonadThrow m
590 , MonadIO m 602 , MonadIO m
591 ) => Text -> NestingXML o m (Maybe StanzaType) 603 ) => Text -> XML.Event -> NestingXML o m (Maybe StanzaType)
592parsePresenceStatus ns = do 604parsePresenceStatus ns stanzaTag = do
593 605
594 let toStat "away" = Away 606 let toStat "away" = Away
595 toStat "xa" = ExtendedAway 607 toStat "xa" = ExtendedAway
@@ -619,9 +631,13 @@ parsePresenceStatus ns = do
619 prio <- liftIO . atomically $ readTVar priov 631 prio <- liftIO . atomically $ readTVar priov
620 status <- liftIO $ chanContents statusv -- Could use unsafeInterleaveIO to 632 status <- liftIO $ chanContents statusv -- Could use unsafeInterleaveIO to
621 -- avoid multiple passes, but whatever. 633 -- avoid multiple passes, but whatever.
634 let wlist = do
635 w <- maybeToList $ lookupAttrib "whitelist" (tagAttrs stanzaTag)
636 Text.words w
622 return . Just $ PresenceStatus { presenceShow = show 637 return . Just $ PresenceStatus { presenceShow = show
623 , presencePriority = prio 638 , presencePriority = prio
624 , presenceStatus = status 639 , presenceStatus = status
640 , presenceWhiteList = wlist
625 } 641 }
626grokPresence 642grokPresence
627 :: ( MonadThrow m 643 :: ( MonadThrow m
@@ -630,9 +646,9 @@ grokPresence
630grokPresence ns stanzaTag = do 646grokPresence ns stanzaTag = do
631 let typ = lookupAttrib "type" (tagAttrs stanzaTag) 647 let typ = lookupAttrib "type" (tagAttrs stanzaTag)
632 case typ of 648 case typ of
633 Nothing -> parsePresenceStatus ns 649 Nothing -> parsePresenceStatus ns stanzaTag
634 Just "unavailable" -> fmap (fmap (\p -> p {presenceShow=Offline})) 650 Just "unavailable" -> fmap (fmap (\p -> p {presenceShow=Offline}))
635 $ parsePresenceStatus ns 651 $ parsePresenceStatus ns stanzaTag
636 Just "error" -> return . Just $ PresenceInformError 652 Just "error" -> return . Just $ PresenceInformError
637 Just "unsubscribed" -> return . Just $ PresenceInformSubscription False 653 Just "unsubscribed" -> return . Just $ PresenceInformSubscription False
638 Just "subscribed" -> return . Just $ PresenceInformSubscription True 654 Just "subscribed" -> return . Just $ PresenceInformSubscription True
@@ -775,6 +791,7 @@ makePresenceStanza namespace mjid pstat = do
775 stanzaFromList PresenceStatus { presenceShow = pstat 791 stanzaFromList PresenceStatus { presenceShow = pstat
776 , presencePriority = Nothing 792 , presencePriority = Nothing
777 , presenceStatus = [] 793 , presenceStatus = []
794 , presenceWhiteList = []
778 } 795 }
779 $ [ EventBeginElement (mkname namespace "presence") 796 $ [ EventBeginElement (mkname namespace "presence")
780 (setFrom $ typ pstat) ] 797 (setFrom $ typ pstat) ]