Merge branch 'charlesmchen/blocking4'

pull/1/head
Matthew Chen 9 years ago
commit e4ec729844

@ -7,10 +7,10 @@ NS_ASSUME_NONNULL_BEGIN
@class TSStorageManager;
@class OWSMessageSender;
extern NSString * const kNSNotificationName_BlockedPhoneNumbersDidChange;
extern NSString *const kNSNotificationName_BlockedPhoneNumbersDidChange;
// This class can be safely accessed and used from any thread.
@interface TSBlockingManager : NSObject
@interface OWSBlockingManager : NSObject
- (instancetype)init NS_UNAVAILABLE;

@ -2,7 +2,7 @@
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "TSBlockingManager.h"
#import "OWSBlockingManager.h"
#import "OWSBlockedPhoneNumbersMessage.h"
#import "OWSMessageSender.h"
#import "TSStorageManager.h"
@ -10,14 +10,14 @@
NS_ASSUME_NONNULL_BEGIN
NSString * const kNSNotificationName_BlockedPhoneNumbersDidChange = @"kNSNotificationName_BlockedPhoneNumbersDidChange";
NSString * const kTSStorageManager_BlockedPhoneNumbersCollection = @"kTSStorageManager_BlockedPhoneNumbersCollection";
NSString *const kNSNotificationName_BlockedPhoneNumbersDidChange = @"kNSNotificationName_BlockedPhoneNumbersDidChange";
NSString *const kOWSBlockingManager_BlockedPhoneNumbersCollection = @"kOWSBlockingManager_BlockedPhoneNumbersCollection";
// This key is used to persist the current "blocked phone numbers" state.
NSString * const kTSStorageManager_BlockedPhoneNumbersKey = @"kTSStorageManager_BlockedPhoneNumbersKey";
NSString *const kOWSBlockingManager_BlockedPhoneNumbersKey = @"kOWSBlockingManager_BlockedPhoneNumbersKey";
// This key is used to persist the most recently synced "blocked phone numbers" state.
NSString *const kTSStorageManager_SyncedBlockedPhoneNumbersKey = @"kTSStorageManager_SyncedBlockedPhoneNumbersKey";
NSString *const kOWSBlockingManager_SyncedBlockedPhoneNumbersKey = @"kOWSBlockingManager_SyncedBlockedPhoneNumbersKey";
@interface TSBlockingManager ()
@interface OWSBlockingManager ()
@property (nonatomic, readonly) TSStorageManager *storageManager;
@property (nonatomic, readonly) OWSMessageSender *messageSender;
@ -31,11 +31,11 @@ NSString *const kTSStorageManager_SyncedBlockedPhoneNumbersKey = @"kTSStorageMan
#pragma mark -
@implementation TSBlockingManager
@implementation OWSBlockingManager
+ (instancetype)sharedManager
{
static TSBlockingManager *sharedMyManager = nil;
static OWSBlockingManager *sharedMyManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedMyManager = [[self alloc] initDefault];
@ -48,11 +48,10 @@ NSString *const kTSStorageManager_SyncedBlockedPhoneNumbersKey = @"kTSStorageMan
TSStorageManager *storageManager = [TSStorageManager sharedManager];
OWSMessageSender *messageSender = [TextSecureKitEnv sharedEnv].messageSender;
return [self initStorageManager:storageManager
messageSender:messageSender];
return [self initWithStorageManager:storageManager messageSender:messageSender];
}
- (instancetype)initStorageManager:(TSStorageManager *)storageManager messageSender:(OWSMessageSender *)messageSender
- (instancetype)initWithStorageManager:(TSStorageManager *)storageManager messageSender:(OWSMessageSender *)messageSender
{
self = [super init];
@ -68,15 +67,21 @@ NSString *const kTSStorageManager_SyncedBlockedPhoneNumbersKey = @"kTSStorageMan
OWSSingletonAssert();
// Register this manager with the message sender.
// This is a circular dependency.
[messageSender setBlockingManager:self];
return self;
}
- (void)addBlockedPhoneNumber:(NSString *)phoneNumber {
- (void)addBlockedPhoneNumber:(NSString *)phoneNumber
{
OWSAssert(phoneNumber.length > 0);
DDLogInfo(@"%@ addBlockedPhoneNumber: %@", self.tag, phoneNumber);
@synchronized (self) {
@synchronized(self)
{
[self lazyLoadBlockedPhoneNumbersIfNecessary];
if ([_blockedPhoneNumberSet containsObject:phoneNumber]) {
@ -90,12 +95,14 @@ NSString *const kTSStorageManager_SyncedBlockedPhoneNumbersKey = @"kTSStorageMan
[self handleUpdate];
}
- (void)removeBlockedPhoneNumber:(NSString *)phoneNumber {
- (void)removeBlockedPhoneNumber:(NSString *)phoneNumber
{
OWSAssert(phoneNumber.length > 0);
DDLogInfo(@"%@ removeBlockedPhoneNumber: %@", self.tag, phoneNumber);
@synchronized (self) {
@synchronized(self)
{
[self lazyLoadBlockedPhoneNumbersIfNecessary];
if (![_blockedPhoneNumberSet containsObject:phoneNumber]) {
@ -115,7 +122,8 @@ NSString *const kTSStorageManager_SyncedBlockedPhoneNumbersKey = @"kTSStorageMan
DDLogInfo(@"%@ setBlockedPhoneNumbers: %d", self.tag, (int)blockedPhoneNumbers.count);
@synchronized (self) {
@synchronized(self)
{
[self lazyLoadBlockedPhoneNumbersIfNecessary];
NSSet *newSet = [NSSet setWithArray:blockedPhoneNumbers];
@ -129,8 +137,10 @@ NSString *const kTSStorageManager_SyncedBlockedPhoneNumbersKey = @"kTSStorageMan
[self handleUpdate:sendSyncMessage];
}
- (NSArray<NSString *> *)blockedPhoneNumbers {
@synchronized (self) {
- (NSArray<NSString *> *)blockedPhoneNumbers
{
@synchronized(self)
{
[self lazyLoadBlockedPhoneNumbersIfNecessary];
return [_blockedPhoneNumberSet.allObjects sortedArrayUsingSelector:@selector(compare:)];
@ -150,8 +160,8 @@ NSString *const kTSStorageManager_SyncedBlockedPhoneNumbersKey = @"kTSStorageMan
NSArray<NSString *> *blockedPhoneNumbers = [self blockedPhoneNumbers];
[_storageManager setObject:blockedPhoneNumbers
forKey:kTSStorageManager_BlockedPhoneNumbersKey
inCollection:kTSStorageManager_BlockedPhoneNumbersCollection];
forKey:kOWSBlockingManager_BlockedPhoneNumbersKey
inCollection:kOWSBlockingManager_BlockedPhoneNumbersCollection];
dispatch_async(dispatch_get_main_queue(), ^{
if (sendSyncMessage) {
@ -186,15 +196,16 @@ NSString *const kTSStorageManager_SyncedBlockedPhoneNumbersKey = @"kTSStorageMan
return;
}
NSArray<NSString *> *blockedPhoneNumbers = [_storageManager objectForKey:kTSStorageManager_BlockedPhoneNumbersKey
inCollection:kTSStorageManager_BlockedPhoneNumbersCollection];
NSArray<NSString *> *blockedPhoneNumbers =
[_storageManager objectForKey:kOWSBlockingManager_BlockedPhoneNumbersKey
inCollection:kOWSBlockingManager_BlockedPhoneNumbersCollection];
_blockedPhoneNumberSet = [[NSMutableSet alloc] initWithArray:(blockedPhoneNumbers ?: [NSArray new])];
// If we haven't yet successfully synced the current "blocked phone numbers" changes,
// try again to sync now.
NSArray<NSString *> *syncedBlockedPhoneNumbers =
[_storageManager objectForKey:kTSStorageManager_SyncedBlockedPhoneNumbersKey
inCollection:kTSStorageManager_BlockedPhoneNumbersCollection];
[_storageManager objectForKey:kOWSBlockingManager_SyncedBlockedPhoneNumbersKey
inCollection:kOWSBlockingManager_BlockedPhoneNumbersCollection];
NSSet *syncedBlockedPhoneNumberSet = [[NSSet alloc] initWithArray:(syncedBlockedPhoneNumbers ?: [NSArray new])];
if (![_blockedPhoneNumberSet isEqualToSet:syncedBlockedPhoneNumberSet]) {
DDLogInfo(@"%@ retrying sync of blocked phone numbers", self.tag);
@ -231,8 +242,8 @@ NSString *const kTSStorageManager_SyncedBlockedPhoneNumbersKey = @"kTSStorageMan
// Record the last set of "blocked phone numbers" which we successfully synced.
[_storageManager setObject:blockedPhoneNumbers
forKey:kTSStorageManager_SyncedBlockedPhoneNumbersKey
inCollection:kTSStorageManager_BlockedPhoneNumbersCollection];
forKey:kOWSBlockingManager_SyncedBlockedPhoneNumbersKey
inCollection:kOWSBlockingManager_BlockedPhoneNumbersCollection];
}
#pragma mark - Logging

@ -7,6 +7,7 @@ NS_ASSUME_NONNULL_BEGIN
@class ContactsUpdater;
@class OWSUploadingService;
@class SignalRecipient;
@class OWSBlockingManager;
@class TSInvalidIdentityKeySendingErrorMessage;
@class TSNetworkManager;
@class TSOutgoingMessage;
@ -31,6 +32,8 @@ NS_SWIFT_NAME(MessageSender)
contactsManager:(id<ContactsManagerProtocol>)contactsManager
contactsUpdater:(ContactsUpdater *)contactsUpdater;
- (void)setBlockingManager:(OWSBlockingManager *)blockingManager;
/**
* Send and resend text messages or resend messages with existing attachments.
* If you haven't yet created the attachment, see the `sendAttachmentData:` variants.

@ -5,6 +5,7 @@
#import "OWSMessageSender.h"
#import "ContactsUpdater.h"
#import "NSData+messagePadding.h"
#import "OWSBlockingManager.h"
#import "OWSDevice.h"
#import "OWSDisappearingMessagesJob.h"
#import "OWSError.h"
@ -257,6 +258,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
@property (nonatomic, readonly) TSNetworkManager *networkManager;
@property (nonatomic, readonly) TSStorageManager *storageManager;
@property (nonatomic, readonly) OWSBlockingManager *blockingManager;
@property (nonatomic, readonly) OWSUploadingService *uploadingService;
@property (nonatomic, readonly) YapDatabaseConnection *dbConnection;
@property (nonatomic, readonly) id<ContactsManagerProtocol> contactsManager;
@ -293,6 +295,14 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
return self;
}
- (void)setBlockingManager:(OWSBlockingManager *)blockingManager
{
OWSAssert(blockingManager);
OWSAssert(!_blockingManager);
_blockingManager = blockingManager;
}
- (NSOperationQueue *)sendingQueueForMessage:(TSOutgoingMessage *)message
{
OWSAssert(message);
@ -516,10 +526,12 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
if (recipients.count == 0) {
if (error) {
return failureHandler(error);
failureHandler(error);
return;
} else {
DDLogError(@"%@ Unknown error finding contacts", self.tag);
return failureHandler(OWSErrorMakeFailedToSendOutgoingMessageError());
failureHandler(OWSErrorMakeFailedToSendOutgoingMessageError());
return;
}
}
@ -541,6 +553,15 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
? self.storageManager.localNumber
: contactThread.contactIdentifier;
OWSAssert(recipientContactId.length > 0);
NSArray<NSString *> *blockedPhoneNumbers = _blockingManager.blockedPhoneNumbers;
if ([blockedPhoneNumbers containsObject:recipientContactId]) {
DDLogInfo(@"%@ skipping 1:1 send to blocked contact: %@", self.tag, recipientContactId);
NSError *error = OWSErrorMakeMessageSendFailedToBlocklistError();
failureHandler(error);
return;
}
SignalRecipient *recipient = [SignalRecipient recipientWithTextSecureIdentifier:recipientContactId];
if (!recipient) {
NSError *error;
@ -554,14 +575,16 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
}
DDLogError(@"%@ contact lookup failed with error: %@", self.tag, error);
return failureHandler(error);
failureHandler(error);
return;
}
}
if (!recipient) {
NSError *error = OWSErrorMakeFailedToSendOutgoingMessageError();
DDLogWarn(@"recipient contact still not found after attempting lookup.");
return failureHandler(error);
failureHandler(error);
return;
}
[self sendMessage:message
@ -609,11 +632,31 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
[self saveGroupMessage:message inThread:thread];
NSMutableArray<TOCFuture *> *futures = [NSMutableArray array];
NSArray<NSString *> *blockedPhoneNumbers = _blockingManager.blockedPhoneNumbers;
int blockedCount = 0;
for (SignalRecipient *rec in recipients) {
// we don't need to send the message to ourselves, but otherwise we send
if (![[rec uniqueId] isEqualToString:[TSStorageManager localNumber]]) {
// We don't need to send the message to ourselves...
if ([rec.uniqueId isEqualToString:[TSStorageManager localNumber]]) {
continue;
}
// ...or to anyone on our blocklist...
OWSAssert(rec.uniqueId.length > 0);
if ([blockedPhoneNumbers containsObject:rec.uniqueId]) {
DDLogInfo(@"%@ skipping group send to blocked contact: %@", self.tag, rec.uniqueId);
blockedCount++;
continue;
}
// ...otherwise we send.
[futures addObject:[self sendMessageFuture:message recipient:rec thread:thread]];
}
// If all recipients in the group are in our blocklist,
// there's nothing to do.
if (blockedCount > 0 && futures.count == 0) {
NSError *error = OWSErrorMakeMessageSendFailedToBlocklistError();
failureHandler(error);
return;
}
TOCFuture *completionFuture = futures.toc_thenAll;

@ -10,6 +10,7 @@
#import "NSDate+millisecondTimeStamp.h"
#import "NotificationsProtocol.h"
#import "OWSAttachmentsProcessor.h"
#import "OWSBlockingManager.h"
#import "OWSCallMessageHandler.h"
#import "OWSDisappearingConfigurationUpdateInfoMessage.h"
#import "OWSDisappearingMessagesConfiguration.h"
@ -37,7 +38,6 @@
#import "TextSecureKitEnv.h"
#import <AxolotlKit/AxolotlExceptions.h>
#import <AxolotlKit/SessionCipher.h>
#import "TSBlockingManager.h"
NS_ASSUME_NONNULL_BEGIN
@ -49,7 +49,7 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, readonly) OWSMessageSender *messageSender;
@property (nonatomic, readonly) OWSDisappearingMessagesJob *disappearingMessagesJob;
@property (nonatomic, readonly) OWSIncomingMessageFinder *incomingMessageFinder;
@property (nonatomic, readonly) TSBlockingManager *blockingManager;
@property (nonatomic, readonly) OWSBlockingManager *blockingManager;
@end
@ -104,7 +104,7 @@ NS_ASSUME_NONNULL_BEGIN
_dbConnection = storageManager.newDatabaseConnection;
_disappearingMessagesJob = [[OWSDisappearingMessagesJob alloc] initWithStorageManager:storageManager];
_incomingMessageFinder = [[OWSIncomingMessageFinder alloc] initWithDatabase:storageManager.database];
_blockingManager = [TSBlockingManager sharedManager];
_blockingManager = [OWSBlockingManager sharedManager];
OWSSingletonAssert();
@ -157,6 +157,14 @@ NS_ASSUME_NONNULL_BEGIN
OWSAssert([NSThread isMainThread]);
DDLogInfo(@"%@ received envelope: %@", self.tag, [self descriptionForEnvelope:envelope]);
OWSAssert(envelope.source.length > 0);
BOOL isEnvelopeBlocked = [_blockingManager.blockedPhoneNumbers containsObject:envelope.source];
if (isEnvelopeBlocked) {
DDLogInfo(@"%@ ignoring blocked envelope: %@", self.tag, envelope.source);
return;
}
@try {
switch (envelope.type) {
case OWSSignalServiceProtosEnvelopeTypeCiphertext: {

@ -22,6 +22,7 @@ typedef NS_ENUM(NSInteger, OWSErrorCode) {
OWSErrorCodeUserError = 2001,
OWSErrorCodeNoSuchSignalRecipient = 777404,
OWSErrorCodeMessageSendDisabledDueToPreKeyUpdateFailures = 777405,
OWSErrorCodeMessageSendFailedToBlocklist = 777406,
};
extern NSError *OWSErrorWithCodeDescription(OWSErrorCode code, NSString *description);
@ -30,5 +31,6 @@ extern NSError *OWSErrorMakeFailedToSendOutgoingMessageError();
extern NSError *OWSErrorMakeNoSuchSignalRecipientError();
extern NSError *OWSErrorMakeAssertionError();
extern NSError *OWSErrorMakeMessageSendDisabledDueToPreKeyUpdateFailuresError();
extern NSError *OWSErrorMakeMessageSendFailedToBlocklistError();
NS_ASSUME_NONNULL_END

@ -47,4 +47,11 @@ NSError *OWSErrorMakeMessageSendDisabledDueToPreKeyUpdateFailuresError()
@"Error mesage indicating that message send is disabled due to prekey update failures"));
}
NSError *OWSErrorMakeMessageSendFailedToBlocklistError()
{
return OWSErrorWithCodeDescription(OWSErrorCodeMessageSendFailedToBlocklist,
NSLocalizedString(@"ERROR_DESCRIPTION_MESSAGE_SEND_FAILED_DUE_TO_BLOCKLIST",
@"Error mesage indicating that message send failed due to blocklist"));
}
NS_ASSUME_NONNULL_END

Loading…
Cancel
Save