mirror of https://github.com/oxen-io/session-ios
Add server certificate methods to UD manager.
parent
b714e528f5
commit
7fd15d2fd9
@ -0,0 +1,33 @@
|
||||
//
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public enum OWSSignalAddressError: Error {
|
||||
case assertionError(description: String)
|
||||
}
|
||||
|
||||
@objc
|
||||
public class OWSSignalAddress: NSObject {
|
||||
@objc
|
||||
public let recipientId: String
|
||||
|
||||
@objc
|
||||
public let deviceId: UInt
|
||||
|
||||
// MARK: Initializers
|
||||
|
||||
@objc public init(recipientId: String, deviceId: UInt) throws {
|
||||
guard recipientId.count > 0 else {
|
||||
throw OWSSignalAddressError.assertionError(description: "Invalid recipient id: \(deviceId)")
|
||||
}
|
||||
|
||||
guard deviceId > 0 else {
|
||||
throw OWSSignalAddressError.assertionError(description: "Invalid device id: \(deviceId)")
|
||||
}
|
||||
|
||||
self.recipientId = recipientId
|
||||
self.deviceId = deviceId
|
||||
}
|
||||
}
|
@ -0,0 +1,150 @@
|
||||
//
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import PromiseKit
|
||||
|
||||
public enum OWSUDError: Error {
|
||||
case assertionError(description: String)
|
||||
}
|
||||
|
||||
@objc public protocol OWSUDManager: class {
|
||||
|
||||
@objc func isUDRecipientId(_ recipientId: String) -> Bool
|
||||
|
||||
// No-op if this recipient id is already marked as a "UD recipient".
|
||||
@objc func addUDRecipientId(_ recipientId: String)
|
||||
|
||||
// No-op if this recipient id is already marked as _NOT_ a "UD recipient".
|
||||
@objc func removeUDRecipientId(_ recipientId: String)
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
|
||||
@objc
|
||||
public class OWSUDManagerImpl: NSObject, OWSUDManager {
|
||||
|
||||
private let dbConnection: YapDatabaseConnection
|
||||
|
||||
private let kUDRecipientModeCollection = "kUDRecipientModeCollection"
|
||||
private let kUDCollection = "kUDCollection"
|
||||
private let kUDCurrentServerCertificateKey = "kUDCurrentServerCertificateKey"
|
||||
|
||||
@objc
|
||||
public required init(primaryStorage: OWSPrimaryStorage) {
|
||||
self.dbConnection = primaryStorage.newDatabaseConnection()
|
||||
|
||||
super.init()
|
||||
|
||||
SwiftSingletons.register(self)
|
||||
}
|
||||
|
||||
// MARK: - Singletons
|
||||
|
||||
private var networkManager: TSNetworkManager {
|
||||
return SSKEnvironment.shared.networkManager
|
||||
}
|
||||
|
||||
// MARK: - Recipient state
|
||||
|
||||
@objc
|
||||
public func isUDRecipientId(_ recipientId: String) -> Bool {
|
||||
return dbConnection.bool(forKey: recipientId, inCollection: kUDRecipientModeCollection, defaultValue: false)
|
||||
}
|
||||
|
||||
@objc
|
||||
public func addUDRecipientId(_ recipientId: String) {
|
||||
dbConnection.setBool(true, forKey: recipientId, inCollection: kUDRecipientModeCollection)
|
||||
}
|
||||
|
||||
@objc
|
||||
public func removeUDRecipientId(_ recipientId: String) {
|
||||
dbConnection.removeObject(forKey: recipientId, inCollection: kUDRecipientModeCollection)
|
||||
}
|
||||
|
||||
// MARK: - Server Certificate
|
||||
|
||||
#if DEBUG
|
||||
@objc
|
||||
public func hasServerCertificate() -> Bool {
|
||||
return serverCertificate() != nil
|
||||
}
|
||||
#endif
|
||||
|
||||
private func serverCertificate() -> Data? {
|
||||
guard let certificateData = dbConnection.object(forKey: kUDCurrentServerCertificateKey, inCollection: kUDCollection) as? Data else {
|
||||
return nil
|
||||
}
|
||||
// TODO: Parse certificate and ensure that it is still valid.
|
||||
return certificateData
|
||||
}
|
||||
|
||||
private func setServerCertificate(_ certificateData: Data) {
|
||||
dbConnection.setObject(certificateData, forKey: kUDCurrentServerCertificateKey, inCollection: kUDCollection)
|
||||
}
|
||||
|
||||
@objc
|
||||
public func ensureServerCertificateObjC(success:@escaping (Data) -> Void,
|
||||
failure:@escaping (Error) -> Void) {
|
||||
ensureServerCertificate()
|
||||
.then(execute: { certificateData in
|
||||
success(certificateData)
|
||||
})
|
||||
.catch(execute: { (error) in
|
||||
failure(error)
|
||||
}).retainUntilComplete()
|
||||
}
|
||||
|
||||
public func ensureServerCertificate() -> Promise<Data> {
|
||||
return Promise { fulfill, reject in
|
||||
// If there is an existing server certificate, use that.
|
||||
if let certificateData = serverCertificate() {
|
||||
fulfill(certificateData)
|
||||
return
|
||||
}
|
||||
// Try to obtain a new server certificate.
|
||||
requestServerCertificate()
|
||||
.then(execute: { certificateData in
|
||||
fulfill(certificateData)
|
||||
})
|
||||
.catch(execute: { (error) in
|
||||
reject(error)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private func requestServerCertificate() -> Promise<Data> {
|
||||
return Promise { fulfill, reject in
|
||||
let request = OWSRequestFactory.udServerCertificateRequest()
|
||||
self.networkManager.makeRequest(
|
||||
request,
|
||||
success: { (_: URLSessionDataTask?, responseObject: Any?) -> Void in
|
||||
do {
|
||||
let certificateData = try self.parseServerCertificateResponse(responseObject: responseObject)
|
||||
|
||||
fulfill(certificateData)
|
||||
} catch {
|
||||
|
||||
reject(error)
|
||||
}
|
||||
},
|
||||
failure: { (_: URLSessionDataTask?, error: Error?) in
|
||||
guard let error = error else {
|
||||
Logger.error("Missing error.")
|
||||
return
|
||||
}
|
||||
|
||||
reject(error)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private func parseServerCertificateResponse(responseObject: Any?) throws -> Data {
|
||||
guard let parser = ParamParser(responseObject: responseObject) else {
|
||||
throw OWSUDError.assertionError(description: "Invalid server certificate response")
|
||||
}
|
||||
|
||||
return try parser.requiredBase64EncodedData(key: "certificate")
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
//
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
#if DEBUG
|
||||
|
||||
@objc
|
||||
public class OWSFakeUDManager: NSObject, OWSUDManager {
|
||||
|
||||
private var udRecipientSet = Set<String>()
|
||||
|
||||
// MARK: -
|
||||
|
||||
@objc
|
||||
public func isUDRecipientId(_ recipientId: String) -> Bool {
|
||||
return udRecipientSet.contains(recipientId)
|
||||
}
|
||||
|
||||
@objc
|
||||
public func addUDRecipientId(_ recipientId: String) {
|
||||
udRecipientSet.insert(recipientId)
|
||||
}
|
||||
|
||||
@objc
|
||||
public func removeUDRecipientId(_ recipientId: String) {
|
||||
udRecipientSet.remove(recipientId)
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,5 +0,0 @@
|
||||
//
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
@ -0,0 +1,40 @@
|
||||
//
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import SignalServiceKit
|
||||
import XCTest
|
||||
|
||||
class OWSSignalAddressTest: SSKBaseTestSwift {
|
||||
|
||||
override func setUp() {
|
||||
super.setUp()
|
||||
// Put setup code here. This method is called before the invocation of each test method in the class.
|
||||
}
|
||||
|
||||
override func tearDown() {
|
||||
// Put teardown code here. This method is called after the invocation of each test method in the class.
|
||||
super.tearDown()
|
||||
}
|
||||
|
||||
func testInitializer() {
|
||||
let recipientId = "+13213214321"
|
||||
let deviceId: UInt = 1
|
||||
let address = try! OWSSignalAddress(recipientId: recipientId, deviceId: deviceId)
|
||||
XCTAssertEqual(address.recipientId, recipientId)
|
||||
XCTAssertEqual(address.deviceId, deviceId)
|
||||
}
|
||||
|
||||
func testInitializer_badRecipientId() {
|
||||
let recipientId = ""
|
||||
let deviceId: UInt = 1
|
||||
XCTAssertThrowsError(try OWSSignalAddress(recipientId: recipientId, deviceId: deviceId))
|
||||
}
|
||||
|
||||
func testInitializer_badDeviceId() {
|
||||
let recipientId = "+13213214321"
|
||||
let deviceId: UInt = 0
|
||||
XCTAssertThrowsError(try OWSSignalAddress(recipientId: recipientId, deviceId: deviceId))
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
//
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
import XCTest
|
||||
import Foundation
|
||||
import SignalServiceKit
|
||||
|
||||
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.
|
||||
}
|
||||
|
||||
override func tearDown() {
|
||||
// Put teardown code here. This method is called after the invocation of each test method in the class.
|
||||
super.tearDown()
|
||||
}
|
||||
|
||||
func testInitializer() {
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
//
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
import XCTest
|
||||
import SignalServiceKit
|
||||
|
||||
@objc
|
||||
public class SSKBaseTestSwift: XCTestCase {
|
||||
|
||||
@objc
|
||||
public override func setUp() {
|
||||
super.setUp()
|
||||
|
||||
ClearCurrentAppContextForTests()
|
||||
SetCurrentAppContext(TestAppContext())
|
||||
|
||||
MockSSKEnvironment.activate()
|
||||
}
|
||||
|
||||
@objc
|
||||
public override func tearDown() {
|
||||
super.tearDown()
|
||||
|
||||
SSKEnvironment.shared.primaryStorage.closeForTests()
|
||||
|
||||
ClearCurrentAppContextForTests()
|
||||
SSKEnvironment.clearSharedForTests()
|
||||
}
|
||||
|
||||
@objc
|
||||
public func read(_ block: @escaping (YapDatabaseReadTransaction) -> Swift.Void) {
|
||||
return OWSPrimaryStorage.shared().dbReadConnection.read(block)
|
||||
}
|
||||
|
||||
@objc
|
||||
public func readWrite(_ block: @escaping (YapDatabaseReadWriteTransaction) -> Swift.Void) {
|
||||
return OWSPrimaryStorage.shared().dbReadWriteConnection.readWrite(block)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue