Streamline SignalRecipient.

pull/1/head
Matthew Chen 7 years ago
parent ef3933bfaa
commit 05a4222b2d

@ -38,31 +38,27 @@ NS_ASSUME_NONNULL_BEGIN
return self;
}
- (SignalRecipient *)signalRecipientForRegisteredRecipientId:(NSString *)recipientId
{
__block SignalRecipient *recipient;
[OWSPrimaryStorage.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
recipient =
[SignalRecipient ensureRecipientExistsWithRegisteredRecipientId:recipientId transaction:transaction];
}];
return recipient;
}
- (void)lookupIdentifier:(NSString *)identifier
- (void)lookupIdentifier:(NSString *)recipientId
success:(void (^)(SignalRecipient *recipient))success
failure:(void (^)(NSError *error))failure
{
OWSAssert(recipientId.length > 0);
// This should never happen according to nullability annotations... but IIRC it does. =/
if (!identifier) {
if (!recipientId) {
OWSFail(@"%@ Cannot lookup nil identifier", self.logTag);
failure(OWSErrorWithCodeDescription(OWSErrorCodeInvalidMethodParameters, @"Cannot lookup nil identifier"));
return;
}
[self contactIntersectionWithSet:[NSSet setWithObject:identifier]
success:^(NSSet<NSString *> *_Nonnull matchedIds) {
if (matchedIds.count == 1) {
success([self signalRecipientForRegisteredRecipientId:identifier]);
NSSet *recipiendIds = [NSSet setWithObject:recipientId];
[self contactIntersectionWithSet:recipiendIds
success:^(NSSet<SignalRecipient *> *recipients) {
if (recipients.count > 0) {
OWSAssert(recipients.count == 1);
SignalRecipient *recipient = recipients.allObjects.firstObject;
success(recipient);
} else {
failure(OWSErrorMakeNoSuchSignalRecipientError());
}
@ -81,13 +77,8 @@ NS_ASSUME_NONNULL_BEGIN
}
[self contactIntersectionWithSet:[NSSet setWithArray:identifiers]
success:^(NSSet<NSString *> *_Nonnull matchedIds) {
if (matchedIds.count > 0) {
NSMutableArray<SignalRecipient *> *recipients = [NSMutableArray new];
for (NSString *identifier in matchedIds) {
[recipients
addObject:[self signalRecipientForRegisteredRecipientId:identifier]];
}
success:^(NSSet<SignalRecipient *> *recipients) {
if (recipients.count > 0) {
success([recipients copy]);
} else {
failure(OWSErrorMakeNoSuchSignalRecipientError());
@ -96,6 +87,7 @@ NS_ASSUME_NONNULL_BEGIN
failure:failure];
}
// TODO: Modify this to support delta lookups.
- (void)updateSignalContactIntersectionWithABContacts:(NSArray<Contact *> *)abContacts
success:(void (^)(void))success
failure:(void (^)(NSError *error))failure
@ -109,7 +101,8 @@ NS_ASSUME_NONNULL_BEGIN
}
NSMutableSet *recipientIds = [NSMutableSet set];
[OWSPrimaryStorage.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *_Nonnull transaction) {
[OWSPrimaryStorage.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction * transaction) {
// TODO: Don't do this.
NSArray *allRecipientKeys = [transaction allKeysInCollection:[SignalRecipient collection]];
[recipientIds addObjectsFromArray:allRecipientKeys];
}];
@ -117,62 +110,70 @@ NS_ASSUME_NONNULL_BEGIN
NSMutableSet<NSString *> *allContacts = [[abPhoneNumbers setByAddingObjectsFromSet:recipientIds] mutableCopy];
[self contactIntersectionWithSet:allContacts
success:^(NSSet<NSString *> *matchedIds) {
[recipientIds minusSet:matchedIds];
// TODO:
//
// Update cache of registered identifiers.
success:^(NSSet<SignalRecipient *> *recipients) {
DDLogInfo(@"%@ successfully intersected contacts.", self.logTag);
success();
}
failure:failure];
}
- (void)contactIntersectionWithSet:(NSSet<NSString *> *)idSet
success:(void (^)(NSSet<NSString *> *matchedIds))success
- (void)contactIntersectionWithSet:(NSSet<NSString *> *)recipientIdsToLookup
success:(void (^)(NSSet<SignalRecipient *> *recipients))success
failure:(void (^)(NSError *error))failure {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSMutableDictionary *phoneNumbersByHashes = [NSMutableDictionary dictionary];
for (NSString *identifier in idSet) {
[phoneNumbersByHashes setObject:identifier
forKey:[Cryptography truncatedSHA1Base64EncodedWithoutPadding:identifier]];
NSMutableDictionary<NSString *, NSString *> *phoneNumbersByHashes = [NSMutableDictionary new];
for (NSString *recipientId in recipientIdsToLookup) {
NSString *hash = [Cryptography truncatedSHA1Base64EncodedWithoutPadding:recipientId];
phoneNumbersByHashes[hash] = recipientId;
}
NSArray *hashes = [phoneNumbersByHashes allKeys];
NSArray<NSString *> *hashes = [phoneNumbersByHashes allKeys];
TSRequest *request = [OWSRequestFactory contactsIntersectionRequestWithHashesArray:hashes];
[[TSNetworkManager sharedManager] makeRequest:request
success:^(NSURLSessionDataTask *tsTask, id responseDict) {
NSMutableSet *identifiers = [NSMutableSet new];
NSArray *contactsArray = [(NSDictionary *)responseDict objectForKey:@"contacts"];
// Map attributes to phone numbers
if (contactsArray) {
for (NSDictionary *dict in contactsArray) {
NSString *hash = [dict objectForKey:@"token"];
NSString *identifier = [phoneNumbersByHashes objectForKey:hash];
if (identifier.length < 1) {
DDLogWarn(@"%@ An interesecting hash wasn't found in the mapping.", self.logTag);
success:^(NSURLSessionDataTask *task, id responseDict) {
NSMutableSet<NSString *> *registeredRecipientIds = [NSMutableSet new];
if ([responseDict isKindOfClass:[NSDictionary class]]) {
NSArray<NSDictionary *> *_Nullable contactsArray = responseDict[@"contacts"];
if ([contactsArray isKindOfClass:[NSArray class]]) {
for (NSDictionary *contactDict in contactsArray) {
if (![contactDict isKindOfClass:[NSDictionary class]]) {
OWSProdLogAndFail(@"%@ invalid contact dictionary.", self.logTag);
continue;
}
[identifiers addObject:identifier];
NSString *_Nullable hash = contactDict[@"token"];
if (hash.length < 1) {
OWSProdLogAndFail(@"%@ contact missing hash.", self.logTag);
continue;
}
NSString *_Nullable recipientId = phoneNumbersByHashes[hash];
if (recipientId.length < 1) {
OWSProdLogAndFail(@"%@ An intersecting hash wasn't found in the mapping.", self.logTag);
continue;
}
if (![recipientIdsToLookup containsObject:recipientId]) {
OWSProdLogAndFail(@"%@ Intersection response included unexpected recipient.", self.logTag);
continue;
}
[registeredRecipientIds addObject:recipientId];
}
}
}
// Insert or update contact attributes
//
// TODO: Do we need to _eagerly_ ensure a SignalRecipient instance exists?
[OWSPrimaryStorage.dbReadWriteConnection
readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
for (NSString *identifier in identifiers) {
[SignalRecipient ensureRecipientExistsWithRegisteredRecipientId:identifier
transaction:transaction];
NSMutableSet<SignalRecipient *> *recipients = [NSMutableSet new];
[OWSPrimaryStorage.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
for (NSString *recipientId in recipientIdsToLookup) {
if ([registeredRecipientIds containsObject:recipientId]) {
SignalRecipient *recipient =
[SignalRecipient markAccountAsRegistered:recipientId transaction:transaction];
[recipients addObject:recipient];
} else {
[SignalRecipient markAccountAsNotRegistered:recipientId transaction:transaction];
}
}
}];
success([identifiers copy]);
success([recipients copy]);
}
failure:^(NSURLSessionDataTask *task, NSError *error) {
if (!IsNSErrorNetworkFailure(error)) {

@ -21,12 +21,6 @@ NS_ASSUME_NONNULL_BEGIN
+ (SignalRecipient *)ensureRecipientExistsWithRecipientId:(NSString *)recipientId
transaction:(YapDatabaseReadWriteTransaction *)transaction;
+ (void)ensureRecipientExistsWithRecipientId:(NSString *)recipientId
deviceId:(UInt32)deviceId
transaction:(YapDatabaseReadWriteTransaction *)transaction;
// TODO: Replace with cache of known signal account ids.
// TODO: Remove?
+ (nullable instancetype)registeredRecipientForRecipientId:(NSString *)recipientId
transaction:(YapDatabaseReadTransaction *)transaction;
@ -40,11 +34,12 @@ NS_ASSUME_NONNULL_BEGIN
// TODO: Replace with cache of known signal account ids.
+ (BOOL)isRegisteredSignalAccount:(NSString *)recipientId transaction:(YapDatabaseReadTransaction *)transaction;
+ (void)markAccountAsRegistered:(NSString *)recipientId transaction:(YapDatabaseReadWriteTransaction *)transaction;
+ (SignalRecipient *)markAccountAsRegistered:(NSString *)recipientId transaction:(YapDatabaseReadWriteTransaction *)transaction;
+ (void)markAccountAsRegistered:(NSString *)recipientId
deviceId:(UInt32)deviceId
transaction:(YapDatabaseReadWriteTransaction *)transaction;
+ (void)markAccountAsNotRegistered:(NSString *)recipientId transaction:(YapDatabaseReadWriteTransaction *)transaction;
- (void)markAccountAsNotRegisteredWithTransaction:(YapDatabaseReadWriteTransaction *)transaction;
@end
NS_ASSUME_NONNULL_END

@ -57,36 +57,6 @@ NS_ASSUME_NONNULL_BEGIN
return recipient;
}
+ (void)ensureRecipientExistsWithRecipientId:(NSString *)recipientId
deviceId:(UInt32)deviceId
transaction:(YapDatabaseReadWriteTransaction *)transaction
{
SignalRecipient *_Nullable existingRecipient = [self recipientForRecipientId:recipientId transaction:transaction];
if (!existingRecipient) {
DDLogDebug(@"%@ in %s creating recipient: %@, with deviceId: %u",
self.logTag,
__PRETTY_FUNCTION__,
recipientId,
(unsigned int)deviceId);
SignalRecipient *newRecipient = [[self alloc] initWithTextSecureIdentifier:recipientId];
[newRecipient addDevices:[NSSet setWithObject:@(deviceId)]];
[newRecipient saveWithTransaction:transaction];
return;
}
if (![existingRecipient.devices containsObject:@(deviceId)]) {
DDLogDebug(@"%@ in %s adding device %u to existing recipient.",
self.logTag,
__PRETTY_FUNCTION__,
(unsigned int)deviceId);
[existingRecipient addDevices:[NSSet setWithObject:@(deviceId)]];
[existingRecipient saveWithTransaction:transaction];
}
}
- (instancetype)initWithTextSecureIdentifier:(NSString *)textSecureIdentifier
{
self = [super initWithUniqueId:textSecureIdentifier];
@ -184,17 +154,19 @@ NS_ASSUME_NONNULL_BEGIN
return;
}
NSMutableOrderedSet *updatedDevices = [self.devices mutableCopy];
NSMutableOrderedSet *updatedDevices = (self.devices
? [self.devices mutableCopy]
: [NSMutableOrderedSet new]);
[updatedDevices unionSet:set];
self.devices = [updatedDevices copy];
}
- (void)removeDevices:(NSSet *)set
{
NSMutableOrderedSet *updatedDevices = [self.devices mutableCopy];
NSMutableOrderedSet *updatedDevices = (self.devices
? [self.devices mutableCopy]
: [NSMutableOrderedSet new]);
[updatedDevices minusSet:set];
self.devices = [updatedDevices copy];
}
@ -230,7 +202,7 @@ NS_ASSUME_NONNULL_BEGIN
return (instance && !instance.mayBeUnregistered);
}
+ (void)markAccountAsRegistered:(NSString *)recipientId transaction:(YapDatabaseReadWriteTransaction *)transaction
+ (SignalRecipient *)markAccountAsRegistered:(NSString *)recipientId transaction:(YapDatabaseReadWriteTransaction *)transaction
{
OWSAssert(transaction);
OWSAssert(recipientId.length > 0);
@ -242,13 +214,30 @@ NS_ASSUME_NONNULL_BEGIN
instance = [[self alloc] initWithTextSecureIdentifier:recipientId];
[instance saveWithTransaction:transaction];
return;
}
if (!instance.mayBeUnregistered) {
return;
}
} else if (instance.mayBeUnregistered) {
instance.mayBeUnregistered = NO;
[instance saveWithTransaction:transaction];
}
return instance;
}
+ (void)markAccountAsRegistered:(NSString *)recipientId
deviceId:(UInt32)deviceId
transaction:(YapDatabaseReadWriteTransaction *)transaction
{
OWSAssert(transaction);
OWSAssert(recipientId.length > 0);
SignalRecipient *recipient = [self markAccountAsRegistered:recipientId transaction:transaction];
if (![recipient.devices containsObject:@(deviceId)]) {
DDLogDebug(@"%@ in %s adding device %u to existing recipient.",
self.logTag,
__PRETTY_FUNCTION__,
(unsigned int)deviceId);
[recipient addDevices:[NSSet setWithObject:@(deviceId)]];
[recipient saveWithTransaction:transaction];
}
}
+ (void)markAccountAsNotRegistered:(NSString *)recipientId transaction:(YapDatabaseReadWriteTransaction *)transaction
@ -267,15 +256,6 @@ NS_ASSUME_NONNULL_BEGIN
[instance saveWithTransaction:transaction];
}
- (void)markAccountAsNotRegisteredWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
{
OWSAssert(transaction);
self.mayBeUnregistered = YES;
[SignalRecipient markAccountAsNotRegistered:self.recipientId transaction:transaction];
}
@end
NS_ASSUME_NONNULL_END

@ -110,7 +110,7 @@ NS_ASSUME_NONNULL_BEGIN
DecryptSuccessBlock successBlock
= ^(NSData *_Nullable plaintextData, YapDatabaseReadWriteTransaction *transaction) {
[SignalRecipient ensureRecipientExistsWithRecipientId:envelope.source
[SignalRecipient markAccountAsRegistered:envelope.source
deviceId:envelope.sourceDevice
transaction:transaction];

@ -716,7 +716,8 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
return;
}
[recipient markAccountAsNotRegisteredWithTransaction:transaction];
[SignalRecipient markAccountAsNotRegistered:recipient.recipientId
transaction:transaction];
[[TSInfoMessage userNotRegisteredMessageInThread:thread recipientId:recipient.recipientId]
saveWithTransaction:transaction];

Loading…
Cancel
Save