Skip to content

Commit 75a5833

Browse files
committed
Roster is only accepted if it has been asked for
Relates too robbiehanson#300
1 parent f7c593c commit 75a5833

File tree

2 files changed

+107
-47
lines changed

2 files changed

+107
-47
lines changed

Extensions/Roster/XMPPRoster.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
@protocol XMPPRosterStorage;
1414
@class DDList;
15+
@class XMPPIDTracker;
1516

1617
/**
1718
* The XMPPRoster provides the scaffolding for a roster solution.
@@ -41,6 +42,8 @@
4142
id multicastDelegate;
4243
*/
4344
__strong id <XMPPRosterStorage> xmppRosterStorage;
45+
46+
XMPPIDTracker *xmppIDTracker;
4447

4548
Byte config;
4649
Byte flags;

Extensions/Roster/XMPPRoster.m

Lines changed: 104 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#import "XMPPRoster.h"
22
#import "XMPP.h"
3+
#import "XMPPIDTracker.h"
34
#import "XMPPLogging.h"
45
#import "XMPPFramework.h"
56
#import "DDList.h"
@@ -88,7 +89,9 @@ - (BOOL)activate:(XMPPStream *)aXmppStream
8889

8990
if ([super activate:aXmppStream])
9091
{
91-
XMPPLogVerbose(@"%@: Activated", THIS_FILE);
92+
XMPPLogVerbose(@"%@: Activated", THIS_FILE);
93+
94+
xmppIDTracker = [[XMPPIDTracker alloc] initWithDispatchQueue:moduleQueue];
9295

9396
#ifdef _XMPP_VCARD_AVATAR_MODULE_H
9497
{
@@ -113,7 +116,7 @@ - (BOOL)activate:(XMPPStream *)aXmppStream
113116
}];
114117
}
115118
#endif
116-
119+
117120
return YES;
118121
}
119122

@@ -123,6 +126,18 @@ - (BOOL)activate:(XMPPStream *)aXmppStream
123126
- (void)deactivate
124127
{
125128
XMPPLogTrace();
129+
130+
dispatch_block_t block = ^{ @autoreleasepool {
131+
132+
[xmppIDTracker removeAllIDs];
133+
xmppIDTracker = nil;
134+
135+
}};
136+
137+
if (dispatch_get_specific(moduleQueueTag))
138+
block();
139+
else
140+
dispatch_sync(moduleQueue, block);
126141

127142
#ifdef _XMPP_VCARD_AVATAR_MODULE_H
128143
{
@@ -371,6 +386,28 @@ - (void)_setPopulatingRoster:(BOOL)flag
371386
else
372387
flags &= ~kPopulatingRoster;
373388
}
389+
390+
- (void)_addRosterItems:(NSArray *)rosterItems
391+
{
392+
NSAssert(dispatch_get_specific(moduleQueueTag) , @"Invoked on incorrect queue");
393+
394+
BOOL hasRoster = [self _hasRoster];
395+
396+
for (NSXMLElement *item in rosterItems)
397+
{
398+
// During roster population, we need to filter out items for users who aren't actually in our roster.
399+
// That is, those users who have requested to be our buddy, but we haven't approved yet.
400+
// This is described in more detail in the method isRosterItem above.
401+
402+
[multicastDelegate xmppRoster:self didReceiveRosterItem:item];
403+
404+
if (hasRoster || [self isRosterItem:item])
405+
{
406+
[xmppRosterStorage handleRosterItem:item xmppStream:xmppStream];
407+
}
408+
}
409+
}
410+
374411
/**
375412
* Some server's include in our roster the JID's of user's NOT in our roster.
376413
* This happens when another user adds us to their roster, and requests permission to receive our presence.
@@ -652,9 +689,13 @@ - (void)fetchRoster
652689

653690
NSXMLElement *query = [NSXMLElement elementWithName:@"query" xmlns:@"jabber:iq:roster"];
654691

655-
NSXMLElement *iq = [NSXMLElement elementWithName:@"iq"];
656-
[iq addAttributeWithName:@"type" stringValue:@"get"];
692+
XMPPIQ *iq = [XMPPIQ iqWithType:@"get" elementID:[xmppStream generateUUID]];
657693
[iq addChild:query];
694+
695+
[xmppIDTracker addElement:iq
696+
target:self
697+
selector:@selector(handleFetchRosterQueryIQ:withInfo:)
698+
timeout:60];
658699

659700
[xmppStream sendElement:iq];
660701

@@ -668,38 +709,14 @@ - (void)fetchRoster
668709
}
669710

670711
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
671-
#pragma mark XMPPStream Delegate
712+
#pragma mark XMPPIDTracker
672713
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
673714

674-
- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender
675-
{
676-
// This method is invoked on the moduleQueue.
677-
678-
XMPPLogTrace();
679-
680-
if ([self autoFetchRoster])
681-
{
682-
[self fetchRoster];
683-
}
684-
}
685-
686-
- (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq
687-
{
688-
// This method is invoked on the moduleQueue.
689-
690-
XMPPLogTrace();
691-
692-
// Note: Some jabber servers send an iq element with an xmlns.
693-
// Because of the bug in Apple's NSXML (documented in our elementForName method),
694-
// it is important we specify the xmlns for the query.
695-
696-
NSXMLElement *query = [iq elementForName:@"query" xmlns:@"jabber:iq:roster"];
697-
if (query)
698-
{
699-
if([iq isSetIQ])
700-
{
701-
[multicastDelegate xmppRoster:self didReceiveRosterPush:iq];
702-
}
715+
- (void)handleFetchRosterQueryIQ:(XMPPIQ *)iq withInfo:(XMPPBasicTrackingInfo *)basicTrackingInfo{
716+
717+
dispatch_block_t block = ^{ @autoreleasepool {
718+
719+
NSXMLElement *query = [iq elementForName:@"query" xmlns:@"jabber:iq:roster"];
703720

704721
BOOL hasRoster = [self _hasRoster];
705722

@@ -712,19 +729,7 @@ - (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq
712729
}
713730

714731
NSArray *items = [query elementsForName:@"item"];
715-
for (NSXMLElement *item in items)
716-
{
717-
// During roster population, we need to filter out items for users who aren't actually in our roster.
718-
// That is, those users who have requested to be our buddy, but we haven't approved yet.
719-
// This is described in more detail in the method isRosterItem above.
720-
721-
[multicastDelegate xmppRoster:self didReceiveRosterItem:item];
722-
723-
if (hasRoster || [self isRosterItem:item])
724-
{
725-
[xmppRosterStorage handleRosterItem:item xmppStream:xmppStream];
726-
}
727-
}
732+
[self _addRosterItems:items];
728733

729734
if (!hasRoster)
730735
{
@@ -741,8 +746,60 @@ - (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq
741746
{
742747
[self xmppStream:xmppStream didReceivePresence:presence];
743748
}
749+
744750
[earlyPresenceElements removeAllObjects];
745751
}
752+
753+
}};
754+
755+
if (dispatch_get_specific(moduleQueueTag))
756+
block();
757+
else
758+
dispatch_async(moduleQueue, block);
759+
760+
}
761+
762+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
763+
#pragma mark XMPPStream Delegate
764+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
765+
766+
- (void)xmppStreamDidAuthenticate:(XMPPStream *)sender
767+
{
768+
// This method is invoked on the moduleQueue.
769+
770+
XMPPLogTrace();
771+
772+
if ([self autoFetchRoster])
773+
{
774+
[self fetchRoster];
775+
}
776+
}
777+
778+
- (BOOL)xmppStream:(XMPPStream *)sender didReceiveIQ:(XMPPIQ *)iq
779+
{
780+
// This method is invoked on the moduleQueue.
781+
782+
XMPPLogTrace();
783+
784+
// Note: Some jabber servers send an iq element with an xmlns.
785+
// Because of the bug in Apple's NSXML (documented in our elementForName method),
786+
// it is important we specify the xmlns for the query.
787+
788+
NSXMLElement *query = [iq elementForName:@"query" xmlns:@"jabber:iq:roster"];
789+
790+
if (query)
791+
{
792+
if([iq isSetIQ])
793+
{
794+
[multicastDelegate xmppRoster:self didReceiveRosterPush:iq];
795+
796+
NSArray *items = [query elementsForName:@"item"];
797+
[self _addRosterItems:items];
798+
}
799+
else if([iq isResultIQ])
800+
{
801+
[xmppIDTracker invokeForID:[iq elementID] withObject:iq];
802+
}
746803

747804
return YES;
748805
}

0 commit comments

Comments
 (0)