Fix breakage in UD manager; add UD manager test, hang TSAccountManager on SSKEnv, fix bugs in tests.

pull/1/head
Matthew Chen 7 years ago
parent 1f2bfe8df4
commit 03f23b5f79

@ -64,6 +64,7 @@ NS_ASSUME_NONNULL_BEGIN
[[OWSBatchMessageProcessor alloc] initWithPrimaryStorage:primaryStorage];
OWSMessageReceiver *messageReceiver = [[OWSMessageReceiver alloc] initWithPrimaryStorage:primaryStorage];
TSSocketManager *socketManager = [[TSSocketManager alloc] init];
TSAccountManager *tsAccountManager = [[TSAccountManager alloc] initWithPrimaryStorage:primaryStorage];
[Environment setShared:[[Environment alloc] initWithPreferences:preferences]];
@ -80,7 +81,8 @@ NS_ASSUME_NONNULL_BEGIN
messageDecrypter:messageDecrypter
batchMessageProcessor:batchMessageProcessor
messageReceiver:messageReceiver
socketManager:socketManager]];
socketManager:socketManager
tsAccountManager:tsAccountManager]];
appSpecificSingletonBlock();

@ -27,13 +27,10 @@ extern NSString *const kNSNotificationName_LocalNumberDidChange;
- (instancetype)init NS_UNAVAILABLE;
- (instancetype)initWithNetworkManager:(TSNetworkManager *)networkManager
primaryStorage:(OWSPrimaryStorage *)primaryStorage NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithPrimaryStorage:(OWSPrimaryStorage *)primaryStorage NS_DESIGNATED_INITIALIZER;
+ (instancetype)sharedInstance;
@property (nonatomic, strong, readonly) TSNetworkManager *networkManager;
/**
* Returns if a user is registered or not
*
@ -140,6 +137,10 @@ extern NSString *const kNSNotificationName_LocalNumberDidChange;
- (BOOL)isManualMessageFetchEnabled;
- (void)setIsManualMessageFetchEnabled:(BOOL)value;
#ifdef DEBUG
- (void)registerForTestsWithLocalNumber:(NSString *)localNumber;
#endif
@end
NS_ASSUME_NONNULL_END

@ -9,6 +9,7 @@
#import "OWSError.h"
#import "OWSPrimaryStorage+SessionStore.h"
#import "OWSRequestFactory.h"
#import "SSKEnvironment.h"
#import "TSNetworkManager.h"
#import "TSPreKeyManager.h"
#import "YapDatabaseConnection+OWS.h"
@ -57,15 +58,13 @@ NSString *const TSAccountManager_ManualMessageFetchKey = @"TSAccountManager_Manu
@synthesize isRegistered = _isRegistered;
- (instancetype)initWithNetworkManager:(TSNetworkManager *)networkManager
primaryStorage:(OWSPrimaryStorage *)primaryStorage
- (instancetype)initWithPrimaryStorage:(OWSPrimaryStorage *)primaryStorage
{
self = [super init];
if (!self) {
return self;
}
_networkManager = networkManager;
_dbConnection = [primaryStorage newDatabaseConnection];
OWSSingletonAssert();
@ -87,16 +86,22 @@ NSString *const TSAccountManager_ManualMessageFetchKey = @"TSAccountManager_Manu
+ (instancetype)sharedInstance
{
static dispatch_once_t onceToken;
static id sharedInstance = nil;
dispatch_once(&onceToken, ^{
sharedInstance = [[self alloc] initWithNetworkManager:[TSNetworkManager sharedManager]
primaryStorage:[OWSPrimaryStorage sharedManager]];
});
OWSAssertDebug(SSKEnvironment.shared.tsAccountManager);
return SSKEnvironment.shared.tsAccountManager;
}
#pragma mark - Dependencies
return sharedInstance;
- (TSNetworkManager *)networkManager
{
OWSAssertDebug(SSKEnvironment.shared.networkManager);
return SSKEnvironment.shared.networkManager;
}
#pragma mark -
- (void)setPhoneNumberAwaitingVerification:(NSString *_Nullable)phoneNumberAwaitingVerification
{
_phoneNumberAwaitingVerification = phoneNumberAwaitingVerification;
@ -598,6 +603,13 @@ NSString *const TSAccountManager_ManualMessageFetchKey = @"TSAccountManager_Manu
inCollection:TSAccountManager_UserAccountCollection];
}
- (void)registerForTestsWithLocalNumber:(NSString *)localNumber
{
OWSAssertDebug(localNumber.length > 0);
[self storeLocalNumber:localNumber];
}
@end
NS_ASSUME_NONNULL_END

@ -60,6 +60,8 @@ public class OWSUDManagerImpl: NSObject, OWSUDManager {
private let dbConnection: YapDatabaseConnection
var certificateValidator: SMKCertificateValidator?
// MARK: Local Configuration State
private let kUDCollection = "kUDCollection"
private let kUDCurrentSenderCertificateKey = "kUDCurrentSenderCertificateKey"
@ -74,6 +76,8 @@ public class OWSUDManagerImpl: NSObject, OWSUDManager {
super.init()
self.certificateValidator = SMKCertificateDefaultValidator(trustRoot: trustRoot())
SwiftSingletons.register(self)
}
@ -111,6 +115,11 @@ public class OWSUDManagerImpl: NSObject, OWSUDManager {
@objc
public func getAccess(forRecipientId recipientId: RecipientIdentifier) -> SSKUnidentifiedAccessPair? {
let theirAccessMode = unidentifiedAccessMode(recipientId: recipientId)
guard theirAccessMode == .enabled || theirAccessMode == .unrestricted else {
return nil
}
guard let theirAccessKey = self.udAccessKeyForRecipient(recipientId) else {
return nil
}
@ -141,7 +150,7 @@ public class OWSUDManagerImpl: NSObject, OWSUDManager {
}
@objc
private func unidentifiedAccessMode(recipientId: RecipientIdentifier) -> UnidentifiedAccessMode {
func unidentifiedAccessMode(recipientId: RecipientIdentifier) -> UnidentifiedAccessMode {
if tsAccountManager.localNumber() == recipientId {
if shouldAllowUnrestrictedAccessLocal() {
return .unrestricted
@ -168,6 +177,11 @@ public class OWSUDManagerImpl: NSObject, OWSUDManager {
// if we have a valid profile key for them.
@objc
public func udAccessKeyForRecipient(_ recipientId: RecipientIdentifier) -> SMKUDAccessKey? {
let theirAccessMode = unidentifiedAccessMode(recipientId: recipientId)
if theirAccessMode == .unrestricted {
return SMKUDAccessKey(randomKeyData: ())
}
guard let profileKey = profileManager.profileKeyData(forRecipientId: recipientId) else {
// Mark as "not a UD recipient".
return nil
@ -210,7 +224,7 @@ public class OWSUDManagerImpl: NSObject, OWSUDManager {
}
}
private func setSenderCertificate(_ certificateData: Data) {
func setSenderCertificate(_ certificateData: Data) {
dbConnection.setObject(certificateData, forKey: kUDCurrentSenderCertificateKey, inCollection: kUDCollection)
}
@ -254,8 +268,10 @@ public class OWSUDManagerImpl: NSObject, OWSUDManager {
}
private func isValidCertificate(_ certificate: SMKSenderCertificate) -> Bool {
let certificateValidator = SMKCertificateDefaultValidator(trustRoot: trustRoot())
guard let certificateValidator = self.certificateValidator else {
owsFail("Missing certificateValidator.")
return false
}
// Ensure that the certificate will not expire in the next hour.
// We want a threshold long enough to ensure that any outgoing message

@ -13,6 +13,7 @@ NS_ASSUME_NONNULL_BEGIN
@class OWSMessageReceiver;
@class OWSMessageSender;
@class OWSPrimaryStorage;
@class TSAccountManager;
@class TSNetworkManager;
@class TSSocketManager;
@class YapDatabaseConnection;
@ -38,7 +39,8 @@ NS_ASSUME_NONNULL_BEGIN
messageDecrypter:(OWSMessageDecrypter *)messageDecrypter
batchMessageProcessor:(OWSBatchMessageProcessor *)batchMessageProcessor
messageReceiver:(OWSMessageReceiver *)messageReceiver
socketManager:(TSSocketManager *)socketManager NS_DESIGNATED_INITIALIZER;
socketManager:(TSSocketManager *)socketManager
tsAccountManager:(TSAccountManager *)tsAccountManager NS_DESIGNATED_INITIALIZER;
- (instancetype)init NS_UNAVAILABLE;
@ -65,6 +67,7 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, readonly) OWSBatchMessageProcessor *batchMessageProcessor;
@property (nonatomic, readonly) OWSMessageReceiver *messageReceiver;
@property (nonatomic, readonly) TSSocketManager *socketManager;
@property (nonatomic, readonly) TSAccountManager *tsAccountManager;
// This property is configured after Environment is created.
@property (atomic, nullable) id<OWSCallMessageHandler> callMessageHandler;

@ -26,6 +26,7 @@ static SSKEnvironment *sharedSSKEnvironment;
@property (nonatomic) OWSBatchMessageProcessor *batchMessageProcessor;
@property (nonatomic) OWSMessageReceiver *messageReceiver;
@property (nonatomic) TSSocketManager *socketManager;
@property (nonatomic) TSAccountManager *tsAccountManager;
@end
@ -51,6 +52,7 @@ static SSKEnvironment *sharedSSKEnvironment;
batchMessageProcessor:(OWSBatchMessageProcessor *)batchMessageProcessor
messageReceiver:(OWSMessageReceiver *)messageReceiver
socketManager:(TSSocketManager *)socketManager
tsAccountManager:(TSAccountManager *)tsAccountManager
{
self = [super init];
if (!self) {
@ -71,6 +73,7 @@ static SSKEnvironment *sharedSSKEnvironment;
OWSAssertDebug(batchMessageProcessor);
OWSAssertDebug(messageReceiver);
OWSAssertDebug(socketManager);
OWSAssertDebug(tsAccountManager);
_contactsManager = contactsManager;
_messageSender = messageSender;
@ -86,6 +89,7 @@ static SSKEnvironment *sharedSSKEnvironment;
_batchMessageProcessor = batchMessageProcessor;
_messageReceiver = messageReceiver;
_socketManager = socketManager;
_tsAccountManager = tsAccountManager;
return self;
}

@ -824,8 +824,10 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
OWSProdCritical([OWSAnalyticsEvents storageErrorCouldNotLoadDatabaseSecondAttempt]);
}
// Try to reset app by deleting database.
[OWSStorage resetAllStorage];
if (!CurrentAppContext().isRunningTests) {
// Try to reset app by deleting database.
[OWSStorage resetAllStorage];
}
keySpec = [Randomness generateRandomBytes:(int)kSQLCipherKeySpecLength];
[[self class] storeDatabaseCipherKeySpec:keySpec];

@ -17,6 +17,7 @@
#import "OWSMessageManager.h"
#import "OWSMessageReceiver.h"
#import "OWSPrimaryStorage.h"
#import "TSAccountManager.h"
#import "TSSocketManager.h"
#import <SignalServiceKit/SignalServiceKit-Swift.h>
@ -58,6 +59,7 @@ NS_ASSUME_NONNULL_BEGIN
[[OWSBatchMessageProcessor alloc] initWithPrimaryStorage:primaryStorage];
OWSMessageReceiver *messageReceiver = [[OWSMessageReceiver alloc] initWithPrimaryStorage:primaryStorage];
TSSocketManager *socketManager = [[TSSocketManager alloc] init];
TSAccountManager *tsAccountManager = [[TSAccountManager alloc] initWithPrimaryStorage:primaryStorage];
self = [super initWithContactsManager:contactsManager
messageSender:messageSender
@ -72,7 +74,8 @@ NS_ASSUME_NONNULL_BEGIN
messageDecrypter:messageDecrypter
batchMessageProcessor:batchMessageProcessor
messageReceiver:messageReceiver
socketManager:socketManager];
socketManager:socketManager
tsAccountManager:tsAccountManager];
if (!self) {
return nil;
}

@ -5,6 +5,7 @@
#import "OWSFakeProfileManager.h"
#import "TSThread.h"
#import <SignalCoreKit/Cryptography.h>
#import <SignalCoreKit/NSData+OWS.h>
NS_ASSUME_NONNULL_BEGIN
@ -19,6 +20,8 @@ NS_ASSUME_NONNULL_BEGIN
@end
#pragma mark -
@implementation OWSFakeProfileManager
@synthesize localProfileKey = _localProfileKey;
@ -37,7 +40,6 @@ NS_ASSUME_NONNULL_BEGIN
return self;
}
- (OWSAES256Key *)localProfileKey
{
if (_localProfileKey == nil) {
@ -53,6 +55,10 @@ NS_ASSUME_NONNULL_BEGIN
self.profileKeys[recipientId] = key;
}
- (nullable NSData *)profileKeyDataForRecipientId:(NSString *)recipientId {
return self.profileKeys[recipientId].keyData;
}
- (BOOL)isUserInProfileWhitelist:(NSString *)recipientId
{
return [self.recipientWhitelist containsObject:recipientId];
@ -68,6 +74,10 @@ NS_ASSUME_NONNULL_BEGIN
[self.recipientWhitelist addObject:recipientId];
}
- (void)addGroupIdToProfileWhitelist:(NSData *)groupId {
[self.threadWhitelist addObject:groupId.hexadecimalString];
}
@end
#endif

@ -48,7 +48,8 @@
attachmentIds:@[]
expiresInSeconds:0
quotedMessage:nil
contactShare:nil];
contactShare:nil
serverTimestamp:nil];
[incomingMessage save];
TSOutgoingMessage *outgoingMessage =
@ -100,7 +101,8 @@
attachmentIds:@[ incomingAttachment.uniqueId ]
expiresInSeconds:0
quotedMessage:nil
contactShare:nil];
contactShare:nil
serverTimestamp:nil];
[incomingMessage save];
TSAttachmentStream *outgoingAttachment =

@ -2,8 +2,8 @@
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import "OWSIncomingMessageFinder.h"
#import "OWSDevice.h"
#import "OWSIncomingMessageFinder.h"
#import "OWSPrimaryStorage.h"
#import "SSKBaseTestObjC.h"
#import "TSContactThread.h"
@ -54,7 +54,8 @@ NS_ASSUME_NONNULL_BEGIN
attachmentIds:@[]
expiresInSeconds:0
quotedMessage:nil
contactShare:nil];
contactShare:nil
serverTimestamp:nil];
[incomingMessage save];
}

@ -4,13 +4,51 @@
import XCTest
import Foundation
import SignalServiceKit
import SignalCoreKit
import SignalMetadataKit
@testable import SignalServiceKit
class MockCertificateValidator: NSObject, SMKCertificateValidator {
@objc public func validate(senderCertificate: SMKSenderCertificate, validationTime: UInt64) throws {
// Do not throw
}
@objc public func validate(serverCertificate: SMKServerCertificate) throws {
// Do not throw
}
}
// MARK: -
class OWSUDManagerTest: SSKBaseTestSwift {
override func setUp() {
super.setUp()
// Put setup code here. This method is called before the invocation of each test method in the class.
let aliceRecipientId = "+13213214321"
SSKEnvironment.shared.tsAccountManager.registerForTests(withLocalNumber: aliceRecipientId)
// Configure UDManager
let profileManager = SSKEnvironment.shared.profileManager
profileManager.setProfileKeyData(OWSAES256Key.generateRandom().keyData, forRecipientId: aliceRecipientId)
let udManager = SSKEnvironment.shared.udManager as! OWSUDManagerImpl
udManager.certificateValidator = MockCertificateValidator()
let serverCertificate = SMKServerCertificate(keyId: 1,
key: try! ECPublicKey(keyData: Randomness.generateRandomBytes(ECCKeyLength)),
// TODO: What's the right length?
signatureData: Randomness.generateRandomBytes(ECCSignatureLength))
let senderCertificate = SMKSenderCertificate(signer: serverCertificate,
key: try! ECPublicKey(keyData: Randomness.generateRandomBytes(ECCKeyLength)),
senderDeviceId: 1,
senderRecipientId: aliceRecipientId,
expirationTimestamp: NSDate.ows_millisecondTimeStamp() + kWeekInMs,
// TODO: What's the right length?
signatureData: Randomness.generateRandomBytes(ECCSignatureLength))
udManager.setSenderCertificate(try! senderCertificate.serialized())
}
override func tearDown() {
@ -18,6 +56,100 @@ class OWSUDManagerTest: SSKBaseTestSwift {
super.tearDown()
}
func testInitializer() {
func testMode_self() {
let udManager = SSKEnvironment.shared.udManager as! OWSUDManagerImpl
XCTAssert(udManager.hasSenderCertificate())
XCTAssert(SSKEnvironment.shared.tsAccountManager.isRegistered())
XCTAssertNotNil(SSKEnvironment.shared.tsAccountManager.localNumber())
XCTAssert(SSKEnvironment.shared.tsAccountManager.localNumber()!.count > 0)
let aliceRecipientId = "+13213214321"
// Self should be enabled regardless of what we "set" our mode to.
XCTAssert(UnidentifiedAccessMode.enabled == udManager.unidentifiedAccessMode(recipientId: aliceRecipientId))
XCTAssertNotNil(udManager.getAccess(forRecipientId: aliceRecipientId))
udManager.setUnidentifiedAccessMode(.unknown, recipientId: aliceRecipientId)
XCTAssert(UnidentifiedAccessMode.enabled == udManager.unidentifiedAccessMode(recipientId: aliceRecipientId))
XCTAssertNotNil(udManager.getAccess(forRecipientId: aliceRecipientId))
udManager.setUnidentifiedAccessMode(.disabled, recipientId: aliceRecipientId)
XCTAssert(UnidentifiedAccessMode.enabled == udManager.unidentifiedAccessMode(recipientId: aliceRecipientId))
XCTAssertNotNil(udManager.getAccess(forRecipientId: aliceRecipientId))
udManager.setUnidentifiedAccessMode(.enabled, recipientId: aliceRecipientId)
XCTAssert(UnidentifiedAccessMode.enabled == udManager.unidentifiedAccessMode(recipientId: aliceRecipientId))
XCTAssertNotNil(udManager.getAccess(forRecipientId: aliceRecipientId))
udManager.setUnidentifiedAccessMode(.unrestricted, recipientId: aliceRecipientId)
XCTAssert(UnidentifiedAccessMode.enabled == udManager.unidentifiedAccessMode(recipientId: aliceRecipientId))
XCTAssertNotNil(udManager.getAccess(forRecipientId: aliceRecipientId))
}
func testMode_noProfileKey() {
let udManager = SSKEnvironment.shared.udManager as! OWSUDManagerImpl
XCTAssert(udManager.hasSenderCertificate())
XCTAssert(SSKEnvironment.shared.tsAccountManager.isRegistered())
XCTAssertNotNil(SSKEnvironment.shared.tsAccountManager.localNumber())
XCTAssert(SSKEnvironment.shared.tsAccountManager.localNumber()!.count > 0)
let bobRecipientId = "+13213214322"
XCTAssertEqual(UnidentifiedAccessMode.unknown, udManager.unidentifiedAccessMode(recipientId: bobRecipientId))
XCTAssertNil(udManager.getAccess(forRecipientId: bobRecipientId))
udManager.setUnidentifiedAccessMode(.unknown, recipientId: bobRecipientId)
XCTAssertEqual(UnidentifiedAccessMode.unknown, udManager.unidentifiedAccessMode(recipientId: bobRecipientId))
XCTAssertNil(udManager.getAccess(forRecipientId: bobRecipientId))
udManager.setUnidentifiedAccessMode(.disabled, recipientId: bobRecipientId)
XCTAssertEqual(UnidentifiedAccessMode.disabled, udManager.unidentifiedAccessMode(recipientId: bobRecipientId))
XCTAssertNil(udManager.getAccess(forRecipientId: bobRecipientId))
udManager.setUnidentifiedAccessMode(.enabled, recipientId: bobRecipientId)
XCTAssertEqual(UnidentifiedAccessMode.enabled, udManager.unidentifiedAccessMode(recipientId: bobRecipientId))
XCTAssertNil(udManager.getAccess(forRecipientId: bobRecipientId))
// Bob should work in unrestricted mode, even if he doesn't have a profile key.
udManager.setUnidentifiedAccessMode(.unrestricted, recipientId: bobRecipientId)
XCTAssertEqual(UnidentifiedAccessMode.unrestricted, udManager.unidentifiedAccessMode(recipientId: bobRecipientId))
XCTAssertNotNil(udManager.getAccess(forRecipientId: bobRecipientId))
}
func testMode_withProfileKey() {
let udManager = SSKEnvironment.shared.udManager as! OWSUDManagerImpl
XCTAssert(udManager.hasSenderCertificate())
XCTAssert(SSKEnvironment.shared.tsAccountManager.isRegistered())
XCTAssertNotNil(SSKEnvironment.shared.tsAccountManager.localNumber())
XCTAssert(SSKEnvironment.shared.tsAccountManager.localNumber()!.count > 0)
let bobRecipientId = "+13213214322"
let profileManager = SSKEnvironment.shared.profileManager
profileManager.setProfileKeyData(OWSAES256Key.generateRandom().keyData, forRecipientId: bobRecipientId)
XCTAssertEqual(UnidentifiedAccessMode.unknown, udManager.unidentifiedAccessMode(recipientId: bobRecipientId))
XCTAssertNil(udManager.getAccess(forRecipientId: bobRecipientId))
udManager.setUnidentifiedAccessMode(.unknown, recipientId: bobRecipientId)
XCTAssertEqual(UnidentifiedAccessMode.unknown, udManager.unidentifiedAccessMode(recipientId: bobRecipientId))
XCTAssertNil(udManager.getAccess(forRecipientId: bobRecipientId))
udManager.setUnidentifiedAccessMode(.disabled, recipientId: bobRecipientId)
XCTAssertEqual(UnidentifiedAccessMode.disabled, udManager.unidentifiedAccessMode(recipientId: bobRecipientId))
XCTAssertNil(udManager.getAccess(forRecipientId: bobRecipientId))
udManager.setUnidentifiedAccessMode(.enabled, recipientId: bobRecipientId)
XCTAssertEqual(UnidentifiedAccessMode.enabled, udManager.unidentifiedAccessMode(recipientId: bobRecipientId))
XCTAssertNotNil(udManager.getAccess(forRecipientId: bobRecipientId))
udManager.setUnidentifiedAccessMode(.unrestricted, recipientId: bobRecipientId)
XCTAssertEqual(UnidentifiedAccessMode.unrestricted, udManager.unidentifiedAccessMode(recipientId: bobRecipientId))
XCTAssertNotNil(udManager.getAccess(forRecipientId: bobRecipientId))
}
}

@ -21,11 +21,6 @@ public class SSKBaseTestSwift: XCTestCase {
@objc
public override func tearDown() {
super.tearDown()
SSKEnvironment.shared.primaryStorage.closeForTests()
ClearCurrentAppContextForTests()
SSKEnvironment.clearSharedForTests()
}
@objc

Loading…
Cancel
Save