From 97ce1a667545bed883ccc4bb59159b008d79c747 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Fri, 8 Dec 2017 14:43:11 -0500 Subject: [PATCH] Rework user profile saves; block SAE if no local user profile key. --- SignalMessaging/profiles/OWSProfileManager.h | 3 ++ SignalMessaging/profiles/OWSProfileManager.m | 5 +++ SignalMessaging/profiles/OWSUserProfile.h | 2 + SignalMessaging/profiles/OWSUserProfile.m | 38 ++++++++++++++----- .../src/Storage/TSYapDatabaseObject.h | 4 ++ .../src/Storage/TSYapDatabaseObject.m | 11 +++++- .../ShareViewController.swift | 10 +++-- 7 files changed, 59 insertions(+), 14 deletions(-) diff --git a/SignalMessaging/profiles/OWSProfileManager.h b/SignalMessaging/profiles/OWSProfileManager.h index 659ac94925..149439bba0 100644 --- a/SignalMessaging/profiles/OWSProfileManager.h +++ b/SignalMessaging/profiles/OWSProfileManager.h @@ -30,6 +30,9 @@ extern const NSUInteger kOWSProfileManager_MaxAvatarDiameter; // These two methods should only be called from the main thread. - (OWSAES256Key *)localProfileKey; +// localUserProfileExists is true if there is _ANY_ local profile. +- (BOOL)localProfileExists; +// localUserProfileExists is true if there is a local profile with a name or avatar. - (BOOL)hasLocalProfile; - (nullable NSString *)localProfileName; - (nullable UIImage *)localProfileAvatarImage; diff --git a/SignalMessaging/profiles/OWSProfileManager.m b/SignalMessaging/profiles/OWSProfileManager.m index bd991ae536..4f4e54e121 100644 --- a/SignalMessaging/profiles/OWSProfileManager.m +++ b/SignalMessaging/profiles/OWSProfileManager.m @@ -165,6 +165,11 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640; return _localUserProfile; } +- (BOOL)localProfileExists +{ + return [OWSUserProfile localUserProfileExists:self.dbConnection]; +} + - (OWSAES256Key *)localProfileKey { OWSAssert(self.localUserProfile.profileKey.keyData.length == kAES256_KeyByteLength); diff --git a/SignalMessaging/profiles/OWSUserProfile.h b/SignalMessaging/profiles/OWSUserProfile.h index cae7284c80..804482d749 100644 --- a/SignalMessaging/profiles/OWSUserProfile.h +++ b/SignalMessaging/profiles/OWSUserProfile.h @@ -40,6 +40,8 @@ extern NSString *const kLocalProfileUniqueId; + (OWSUserProfile *)getOrBuildUserProfileForRecipientId:(NSString *)recipientId dbConnection:(YapDatabaseConnection *)dbConnection; ++ (BOOL)localUserProfileExists:(YapDatabaseConnection *)dbConnection; + #pragma mark - Update With... Methods - (void)updateWithProfileName:(nullable NSString *)profileName diff --git a/SignalMessaging/profiles/OWSUserProfile.m b/SignalMessaging/profiles/OWSUserProfile.m index a5b51e9f1d..6038dddb1f 100644 --- a/SignalMessaging/profiles/OWSUserProfile.m +++ b/SignalMessaging/profiles/OWSUserProfile.m @@ -6,6 +6,7 @@ #import "NSString+OWS.h" #import #import +#import #import #import #import @@ -60,6 +61,16 @@ NSString *const kLocalProfileUniqueId = @"kLocalProfileUniqueId"; return userProfile; } ++ (BOOL)localUserProfileExists:(YapDatabaseConnection *)dbConnection +{ + __block BOOL result = NO; + [dbConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) { + result = [OWSUserProfile fetchObjectWithUniqueID:kLocalProfileUniqueId transaction:transaction] != nil; + }]; + + return result; +} + - (instancetype)initWithRecipientId:(NSString *)recipientId { self = [super initWithUniqueId:recipientId]; @@ -125,7 +136,8 @@ NSString *const kLocalProfileUniqueId = @"kLocalProfileUniqueId"; [userProfile setProfileName:[profileName ows_stripped]]; [userProfile setAvatarUrlPath:avatarUrlPath]; [userProfile setAvatarFileName:avatarFileName]; - }]; + } + saveIfMissing:YES]; }]; [self finalizeWithCompletion:completion]; } @@ -144,7 +156,8 @@ NSString *const kLocalProfileUniqueId = @"kLocalProfileUniqueId"; [userProfile setAvatarUrlPath:avatarUrlPath]; [userProfile setAvatarFileName:avatarFileName]; [userProfile setLastUpdateDate:lastUpdateDate]; - }]; + } + saveIfMissing:YES]; }]; [self finalizeWithCompletion:completion]; } @@ -161,7 +174,8 @@ NSString *const kLocalProfileUniqueId = @"kLocalProfileUniqueId"; [userProfile setProfileName:[profileName ows_stripped]]; [userProfile setAvatarUrlPath:avatarUrlPath]; [userProfile setLastUpdateDate:lastUpdateDate]; - }]; + } + saveIfMissing:YES]; }]; [self finalizeWithCompletion:completion]; } @@ -180,7 +194,8 @@ NSString *const kLocalProfileUniqueId = @"kLocalProfileUniqueId"; [userProfile setProfileKey:profileKey]; [userProfile setAvatarUrlPath:avatarUrlPath]; [userProfile setAvatarFileName:avatarFileName]; - }]; + } + saveIfMissing:YES]; }]; [self finalizeWithCompletion:completion]; } @@ -195,7 +210,8 @@ NSString *const kLocalProfileUniqueId = @"kLocalProfileUniqueId"; changeBlock:^(OWSUserProfile *userProfile) { [userProfile setAvatarUrlPath:avatarUrlPath]; [userProfile setAvatarFileName:avatarFileName]; - }]; + } + saveIfMissing:YES]; }]; [self finalizeWithCompletion:completion]; } @@ -208,7 +224,8 @@ NSString *const kLocalProfileUniqueId = @"kLocalProfileUniqueId"; [self applyChangeToSelfAndLatestCopy:transaction changeBlock:^(OWSUserProfile *userProfile) { [userProfile setAvatarFileName:avatarFileName]; - }]; + } + saveIfMissing:YES]; }]; [self finalizeWithCompletion:completion]; } @@ -221,7 +238,8 @@ NSString *const kLocalProfileUniqueId = @"kLocalProfileUniqueId"; [self applyChangeToSelfAndLatestCopy:transaction changeBlock:^(OWSUserProfile *userProfile) { [userProfile setLastUpdateDate:lastUpdateDate]; - }]; + } + saveIfMissing:YES]; }]; [self finalizeWithCompletion:completion]; } @@ -240,7 +258,8 @@ NSString *const kLocalProfileUniqueId = @"kLocalProfileUniqueId"; [userProfile setAvatarUrlPath:nil]; [userProfile setAvatarFileName:nil]; [userProfile setLastUpdateDate:nil]; - }]; + } + saveIfMissing:YES]; }]; [self finalizeWithCompletion:completion]; } @@ -257,7 +276,8 @@ NSString *const kLocalProfileUniqueId = @"kLocalProfileUniqueId"; [self applyChangeToSelfAndLatestCopy:transaction changeBlock:^(OWSUserProfile *userProfile) { [userProfile setProfileKey:profileKey]; - }]; + } + saveIfMissing:YES]; }]; [self finalizeWithCompletion:completion]; } diff --git a/SignalServiceKit/src/Storage/TSYapDatabaseObject.h b/SignalServiceKit/src/Storage/TSYapDatabaseObject.h index 03f8f115c6..728b7b38df 100644 --- a/SignalServiceKit/src/Storage/TSYapDatabaseObject.h +++ b/SignalServiceKit/src/Storage/TSYapDatabaseObject.h @@ -151,6 +151,10 @@ NS_ASSUME_NONNULL_BEGIN - (void)applyChangeToSelfAndLatestCopy:(YapDatabaseReadWriteTransaction *)transaction changeBlock:(void (^)(id))changeBlock; +- (void)applyChangeToSelfAndLatestCopy:(YapDatabaseReadWriteTransaction *)transaction + changeBlock:(void (^)(id))changeBlock + saveIfMissing:(BOOL)saveIfMissing; + @end NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Storage/TSYapDatabaseObject.m b/SignalServiceKit/src/Storage/TSYapDatabaseObject.m index 22c637e089..0b6d4e5410 100644 --- a/SignalServiceKit/src/Storage/TSYapDatabaseObject.m +++ b/SignalServiceKit/src/Storage/TSYapDatabaseObject.m @@ -200,10 +200,15 @@ NS_ASSUME_NONNULL_BEGIN #pragma mark Update With... -// This method does the work for the "updateWith..." methods. Please see -// the header for a discussion of those methods. - (void)applyChangeToSelfAndLatestCopy:(YapDatabaseReadWriteTransaction *)transaction changeBlock:(void (^)(id))changeBlock +{ + [self applyChangeToSelfAndLatestCopy:transaction changeBlock:changeBlock saveIfMissing:NO]; +} + +- (void)applyChangeToSelfAndLatestCopy:(YapDatabaseReadWriteTransaction *)transaction + changeBlock:(void (^)(id))changeBlock + saveIfMissing:(BOOL)saveIfMissing { OWSAssert(transaction); @@ -214,6 +219,8 @@ NS_ASSUME_NONNULL_BEGIN if (latestInstance) { changeBlock(latestInstance); [latestInstance saveWithTransaction:transaction]; + } else if (saveIfMissing) { + [self saveWithTransaction:transaction]; } } diff --git a/SignalShareExtension/ShareViewController.swift b/SignalShareExtension/ShareViewController.swift index 020579fe49..453cbc407c 100644 --- a/SignalShareExtension/ShareViewController.swift +++ b/SignalShareExtension/ShareViewController.swift @@ -232,10 +232,14 @@ public class ShareViewController: UINavigationController, ShareViewDelegate, SAE Logger.info("Presenting initial root view controller") - if TSAccountManager.isRegistered() { - presentConversationPicker() - } else { + if !TSAccountManager.isRegistered() { showNotRegisteredView() + } else if !OWSProfileManager.shared().localProfileExists() { + // This is a rare edge case, but we want to ensure that the user + // is has already saved their local profile key in the main app. + showNotReadyView() + } else { + presentConversationPicker() } // We don't use the AppUpdateNag in the SAE.