localNumber persistance from Category -> TSAccountManager

Following the pattern that singleton methods for effectively global
state should get/set on their own dedicated dbConnection for consistency
and to avoid being blocked by unrelated writes.
pull/1/head
Michael Kirk 8 years ago
parent 8a4712bf4c
commit 01e808febe

@ -113,7 +113,7 @@ EXTERNAL SOURCES:
AxolotlKit: AxolotlKit:
:git: https://github.com/WhisperSystems/SignalProtocolKit.git :git: https://github.com/WhisperSystems/SignalProtocolKit.git
SignalServiceKit: SignalServiceKit:
:path: "../../../SignalServiceKit.podspec" :path: ../../../SignalServiceKit.podspec
SocketRocket: SocketRocket:
:git: https://github.com/facebook/SocketRocket.git :git: https://github.com/facebook/SocketRocket.git

@ -20,44 +20,24 @@ NSString *const TSRegistrationErrorUserInfoHTTPStatus = @"TSHTTPStatus";
NSString *const kNSNotificationName_RegistrationStateDidChange = @"kNSNotificationName_RegistrationStateDidChange"; NSString *const kNSNotificationName_RegistrationStateDidChange = @"kNSNotificationName_RegistrationStateDidChange";
NSString *const kNSNotificationName_LocalNumberDidChange = @"kNSNotificationName_LocalNumberDidChange"; NSString *const kNSNotificationName_LocalNumberDidChange = @"kNSNotificationName_LocalNumberDidChange";
NSString *const TSAccountManager_RegisteredNumberKey = @"TSStorageRegisteredNumberKey";
NSString *const TSAccountManager_LocalRegistrationIdKey = @"TSStorageLocalRegistrationId";
@interface TSAccountManager () @interface TSAccountManager ()
@property (nonatomic, readonly) BOOL isRegistered;
@property (nonatomic, nullable) NSString *phoneNumberAwaitingVerification; @property (nonatomic, nullable) NSString *phoneNumberAwaitingVerification;
@property (nonatomic, nullable) NSString *cachedLocalNumber; @property (nonatomic, nullable) NSString *cachedLocalNumber;
@property (nonatomic, readonly) TSStorageManager *storageManager; @property (nonatomic, readonly) YapDatabaseConnection *dbConnection;
@end @end
#pragma mark - #pragma mark -
@interface TSStorageManager (TSAccountManagerStorage)
/**
* Stored registered phone number
*
* @return E164 string of the registered phone number
*/
+ (nullable NSString *)localNumber;
- (nullable NSString *)localNumber;
@end
@implementation TSStorageManager (TSAccountManagerStorage)
+ (nullable NSString *)localNumber
{
return [[self sharedManager] localNumber];
}
- (nullable NSString *)localNumber
{
return [self stringForKey:TSStorageRegisteredNumberKey inCollection:TSStorageUserAccountCollection];
}
@end
@implementation TSAccountManager @implementation TSAccountManager
@synthesize isRegistered = _isRegistered;
- (instancetype)initWithNetworkManager:(TSNetworkManager *)networkManager - (instancetype)initWithNetworkManager:(TSNetworkManager *)networkManager
storageManager:(TSStorageManager *)storageManager storageManager:(TSStorageManager *)storageManager
{ {
@ -67,7 +47,7 @@ NSString *const kNSNotificationName_LocalNumberDidChange = @"kNSNotificationName
} }
_networkManager = networkManager; _networkManager = networkManager;
_storageManager = storageManager; _dbConnection = [storageManager newDatabaseConnection];
OWSSingletonAssert(); OWSSingletonAssert();
@ -95,13 +75,42 @@ NSString *const kNSNotificationName_LocalNumberDidChange = @"kNSNotificationName
userInfo:nil]; userInfo:nil];
} }
+ (BOOL)isRegistered { + (BOOL)isRegistered
return [TSStorageManager localNumber] ? YES : NO; {
return [[self sharedInstance] isRegistered];
} }
- (void)ifRegistered:(BOOL)isRegistered runAsync:(void (^)())block - (BOOL)isRegistered
{ {
[self.storageManager ifLocalNumberPresent:isRegistered runAsync:block]; if (_isRegistered) {
return YES;
} else {
@synchronized (self) {
// Cache this once it's true since it's called alot, involves a dbLookup, and once set - it doesn't change.
_isRegistered = [self storedLocalNumber] != nil;
}
}
return _isRegistered;
}
- (void)ifRegistered:(BOOL)runIfRegistered runAsync:(void (^)())block
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
if ([self isRegistered] == runIfRegistered) {
if (runIfRegistered) {
DDLogDebug(@"%@ Running existing-user block", self.tag);
} else {
DDLogDebug(@"%@ Running new-user block", self.tag);
}
block();
} else {
if (runIfRegistered) {
DDLogDebug(@"%@ Skipping existing-user block for new-user", self.tag);
} else {
DDLogDebug(@"%@ Skipping new-user block for existing-user", self.tag);
}
}
});
} }
- (void)didRegister - (void)didRegister
@ -113,7 +122,7 @@ NSString *const kNSNotificationName_LocalNumberDidChange = @"kNSNotificationName
@throw [NSException exceptionWithName:@"RegistrationFail" reason:@"Internal Corrupted State" userInfo:nil]; @throw [NSException exceptionWithName:@"RegistrationFail" reason:@"Internal Corrupted State" userInfo:nil];
} }
[self.storageManager storePhoneNumber:phoneNumber]; [self storeLocalNumber:phoneNumber];
[[NSNotificationCenter defaultCenter] postNotificationName:kNSNotificationName_RegistrationStateDidChange [[NSNotificationCenter defaultCenter] postNotificationName:kNSNotificationName_RegistrationStateDidChange
object:nil object:nil
@ -136,30 +145,47 @@ NSString *const kNSNotificationName_LocalNumberDidChange = @"kNSNotificationName
@synchronized(self) @synchronized(self)
{ {
if (self.cachedLocalNumber == nil) { if (self.cachedLocalNumber == nil) {
self.cachedLocalNumber = [TSStorageManager localNumber]; self.cachedLocalNumber = self.storedLocalNumber;
} }
} }
return self.cachedLocalNumber; return self.cachedLocalNumber;
} }
+ (uint32_t)getOrGenerateRegistrationId { - (nullable NSString *)storedLocalNumber
YapDatabaseConnection *dbConn = [[TSStorageManager sharedManager] newDatabaseConnection]; {
__block uint32_t registrationID = 0; @synchronized (self) {
return [self.dbConnection stringForKey:TSAccountManager_RegisteredNumberKey
inCollection:TSStorageUserAccountCollection];
}
}
- (void)storeLocalNumber:(NSString *)localNumber
{
@synchronized (self) {
[self.dbConnection setObject:localNumber
forKey:TSAccountManager_RegisteredNumberKey
inCollection:TSStorageUserAccountCollection];
}
}
+ (uint32_t)getOrGenerateRegistrationId
{
return [[self sharedInstance] getOrGenerateRegistrationId];
}
[dbConn readWithBlock:^(YapDatabaseReadTransaction *transaction) { - (uint32_t)getOrGenerateRegistrationId
registrationID = [[transaction objectForKey:TSStorageLocalRegistrationId {
inCollection:TSStorageUserAccountCollection] unsignedIntValue]; uint32_t registrationID = [[self.dbConnection objectForKey:TSAccountManager_LocalRegistrationIdKey
}]; inCollection:TSStorageUserAccountCollection] unsignedIntValue];
if (registrationID == 0) { if (registrationID == 0) {
registrationID = (uint32_t)arc4random_uniform(16380) + 1; registrationID = (uint32_t)arc4random_uniform(16380) + 1;
DDLogWarn(@"%@ Generated a new registrationID: %u", self.tag, registrationID);
[dbConn readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [self.dbConnection setObject:[NSNumber numberWithUnsignedInteger:registrationID]
[transaction setObject:[NSNumber numberWithUnsignedInteger:registrationID] forKey:TSAccountManager_LocalRegistrationIdKey
forKey:TSStorageLocalRegistrationId inCollection:TSStorageUserAccountCollection];
inCollection:TSStorageUserAccountCollection];
}];
} }
return registrationID; return registrationID;

@ -1,9 +1,5 @@
// //
// TSStorageKeys.h // Copyright (c) 2017 Open Whisper Systems. All rights reserved.
// TextSecureKit
//
// Created by Frederic Jacobs on 28/10/14.
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
// //
#ifndef TextSecureKit_TSStorageKeys_h #ifndef TextSecureKit_TSStorageKeys_h
@ -13,10 +9,8 @@
#define TSStorageUserAccountCollection @"TSStorageUserAccountCollection" #define TSStorageUserAccountCollection @"TSStorageUserAccountCollection"
#define TSStorageRegisteredNumberKey @"TSStorageRegisteredNumberKey"
#define TSStorageServerAuthToken @"TSStorageServerAuthToken" #define TSStorageServerAuthToken @"TSStorageServerAuthToken"
#define TSStorageServerSignalingKey @"TSStorageServerSignalingKey" #define TSStorageServerSignalingKey @"TSStorageServerSignalingKey"
#define TSStorageLocalRegistrationId @"TSStorageLocalRegistrationId"
/** /**
* Preferences exposed to the user * Preferences exposed to the user

@ -24,10 +24,6 @@
+ (NSString *)serverAuthToken; + (NSString *)serverAuthToken;
- (void)ifLocalNumberPresent:(BOOL)isPresent runAsync:(void (^)())block;
+ (void)storeServerToken:(NSString *)authToken signalingKey:(NSString *)signalingKey; + (void)storeServerToken:(NSString *)authToken signalingKey:(NSString *)signalingKey;
- (void)storePhoneNumber:(NSString *)phoneNumber;
@end @end

@ -4,34 +4,9 @@
#import "TSStorageManager+keyingMaterial.h" #import "TSStorageManager+keyingMaterial.h"
// TODO merge this category extension's functionality into TSAccountManager
@implementation TSStorageManager (keyingMaterial) @implementation TSStorageManager (keyingMaterial)
- (void)ifLocalNumberPresent:(BOOL)runIfPresent runAsync:(void (^)())block;
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
__block BOOL isPresent;
[self.newDatabaseConnection readWithBlock:^(YapDatabaseReadTransaction *_Nonnull transaction) {
isPresent = [[transaction objectForKey:TSStorageRegisteredNumberKey
inCollection:TSStorageUserAccountCollection] boolValue];
}];
if (isPresent == runIfPresent) {
if (runIfPresent) {
DDLogDebug(@"%@ Running existing-user block", self.logTag);
} else {
DDLogDebug(@"%@ Running new-user block", self.logTag);
}
block();
} else {
if (runIfPresent) {
DDLogDebug(@"%@ Skipping existing-user block for new-user", self.logTag);
} else {
DDLogDebug(@"%@ Skipping new-user block for existing-user", self.logTag);
}
}
});
}
+ (NSString *)signalingKey { + (NSString *)signalingKey {
return [[self sharedManager] stringForKey:TSStorageServerSignalingKey inCollection:TSStorageUserAccountCollection]; return [[self sharedManager] stringForKey:TSStorageServerSignalingKey inCollection:TSStorageUserAccountCollection];
} }
@ -40,15 +15,6 @@
return [[self sharedManager] stringForKey:TSStorageServerAuthToken inCollection:TSStorageUserAccountCollection]; return [[self sharedManager] stringForKey:TSStorageServerAuthToken inCollection:TSStorageUserAccountCollection];
} }
- (void)storePhoneNumber:(NSString *)phoneNumber
{
[self.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
[transaction setObject:phoneNumber
forKey:TSStorageRegisteredNumberKey
inCollection:TSStorageUserAccountCollection];
}];
}
+ (void)storeServerToken:(NSString *)authToken signalingKey:(NSString *)signalingKey { + (void)storeServerToken:(NSString *)authToken signalingKey:(NSString *)signalingKey {
TSStorageManager *sharedManager = self.sharedManager; TSStorageManager *sharedManager = self.sharedManager;
[sharedManager.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [sharedManager.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {

Loading…
Cancel
Save