diff options
-rw-r--r-- | Presence/XMPPServer.hs | 39 |
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 | |||
59 | import Data.List (nub) | 59 | import Data.List (nub) |
60 | import Data.Monoid ( (<>) ) | 60 | import Data.Monoid ( (<>) ) |
61 | import Data.Text (Text) | 61 | import Data.Text (Text) |
62 | import qualified Data.Text as Text (pack,unpack) | 62 | import qualified Data.Text as Text (pack,unpack,words,intercalate) |
63 | import Data.Char (toUpper,chr,ord) | 63 | import Data.Char (toUpper,chr,ord) |
64 | import Data.Map (Map) | 64 | import Data.Map (Map) |
65 | import qualified Data.Map as Map | 65 | import 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 = | |||
334 | swapit old new x = x | 335 | swapit old new x = x |
335 | 336 | ||
336 | fixHeaders :: Monad m => Stanza -> ConduitM Event Event m () | 337 | fixHeaders :: Monad m => Stanza -> ConduitM Event Event m () |
337 | fixHeaders Stanza { stanzaTo=mto, stanzaFrom=mfrom } = do | 338 | fixHeaders 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 | |||
349 | conduitToChan | 361 | conduitToChan |
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 | |||
588 | parsePresenceStatus | 600 | parsePresenceStatus |
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) |
592 | parsePresenceStatus ns = do | 604 | parsePresenceStatus 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 | } |
626 | grokPresence | 642 | grokPresence |
627 | :: ( MonadThrow m | 643 | :: ( MonadThrow m |
@@ -630,9 +646,9 @@ grokPresence | |||
630 | grokPresence ns stanzaTag = do | 646 | grokPresence 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) ] |