mirror of https://github.com/oxen-io/session-ios
Merge pull request #52 from loki-project/multi-device-database
[Multi Device] Database Changespull/55/head
commit
dc554a6082
@ -1 +1 @@
|
||||
Subproject commit 9188141c9666093156f4b54b9aef025330651505
|
||||
Subproject commit 1b8d82e0d7917369c92ad5bb116cb61c734533d6
|
@ -0,0 +1,37 @@
|
||||
@objc(LKPairingAuthorisation)
|
||||
public final class LokiPairingAuthorisation : NSObject, NSCoding {
|
||||
@objc public let primaryDevicePubKey: String
|
||||
@objc public let secondaryDevicePubKey: String
|
||||
@objc public let requestSignature: Data?
|
||||
@objc public let grantSignature: Data?
|
||||
|
||||
@objc public var isGranted: Bool {
|
||||
return grantSignature != nil
|
||||
}
|
||||
|
||||
@objc public init(primaryDevicePubKey: String, secondaryDevicePubKey: String, requestSignature: Data? = nil, grantSignature: Data? = nil) {
|
||||
self.primaryDevicePubKey = primaryDevicePubKey
|
||||
self.secondaryDevicePubKey = secondaryDevicePubKey
|
||||
self.requestSignature = requestSignature
|
||||
self.grantSignature = grantSignature
|
||||
}
|
||||
|
||||
public convenience init?(coder aDecoder: NSCoder) {
|
||||
guard let primaryDevicePubKey = aDecoder.decodeObject(forKey: "primaryDevicePubKey") as? String,
|
||||
let secondaryDevicePubKey = aDecoder.decodeObject(forKey: "secondaryDevicePubKey") as? String else {
|
||||
return nil
|
||||
}
|
||||
|
||||
let requestSignature = aDecoder.decodeObject(forKey: "requestSignature") as? Data
|
||||
let grantSignature = aDecoder.decodeObject(forKey: "grantSignature") as? Data
|
||||
|
||||
self.init(primaryDevicePubKey: primaryDevicePubKey, secondaryDevicePubKey: secondaryDevicePubKey, requestSignature: requestSignature, grantSignature: grantSignature)
|
||||
}
|
||||
|
||||
public func encode(with aCoder: NSCoder) {
|
||||
aCoder.encode(primaryDevicePubKey, forKey: "primaryDevicePubKey")
|
||||
aCoder.encode(secondaryDevicePubKey, forKey: "secondaryDevicePubKey")
|
||||
aCoder.encode(requestSignature, forKey: "requestSignature")
|
||||
aCoder.encode(grantSignature, forKey: "grantSignature")
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
extension OWSPrimaryStorage {
|
||||
private func getCollection(for primaryDevice: String) -> String {
|
||||
return "LokiMultiDevice-\(primaryDevice)"
|
||||
}
|
||||
|
||||
public func getAuthorisation(forSecondaryDevice secondaryDevice: String, with transaction: YapDatabaseReadTransaction) -> LokiPairingAuthorisation? {
|
||||
let query = YapDatabaseQuery(string: "WHERE \(PairingAuthorisationsIndex.secondaryDevicePubKey) = ?", parameters: [secondaryDevice])
|
||||
let authorisations = PairingAuthorisationsIndex.getPairingAuthorisations(with: query, transaction: transaction)
|
||||
|
||||
// This should never be the case
|
||||
if (authorisations.count > 1) { owsFailDebug("[Loki][Multidevice] Found multiple authorisations for secondary device: \(secondaryDevice)") }
|
||||
|
||||
return authorisations.first
|
||||
}
|
||||
|
||||
public func createOrUpdatePairingAuthorisation(_ authorisation: LokiPairingAuthorisation, with transaction: YapDatabaseReadWriteTransaction) {
|
||||
// iOS makes this easy, we can group all authorizations into the primary device collection
|
||||
// Then we associate an authorisation with the secondary device key
|
||||
transaction.setObject(authorisation, forKey: authorisation.secondaryDevicePubKey, inCollection: getCollection(for: authorisation.primaryDevicePubKey))
|
||||
}
|
||||
|
||||
public func getSecondaryDevices(forPrimaryDevice primaryDevice: String, with transaction: YapDatabaseReadTransaction) -> [String] {
|
||||
// primary device collection should have secondary devices as its keys
|
||||
return transaction.allKeys(inCollection: getCollection(for: primaryDevice))
|
||||
}
|
||||
|
||||
public func getPrimaryDevice(forSecondaryDevice secondaryDevice: String, with transaction: YapDatabaseReadTransaction) -> String? {
|
||||
let authorisation = getAuthorisation(forSecondaryDevice: secondaryDevice, with: transaction)
|
||||
return authorisation?.primaryDevicePubKey
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
@objc(LKPairingAuthorisationsIndex)
|
||||
public final class PairingAuthorisationsIndex : NSObject {
|
||||
private static let name = "loki_index_pairing_authorisations"
|
||||
|
||||
// Fields
|
||||
@objc public static let primaryDevicePubKey = "pairing_primary_device_pub_key"
|
||||
@objc public static let secondaryDevicePubKey = "pairing_secondary_device_pub_key"
|
||||
@objc public static let isGranted = "pairing_is_granted"
|
||||
|
||||
// MARK: Database Extension
|
||||
|
||||
@objc public static var indexDatabaseExtension: YapDatabaseSecondaryIndex {
|
||||
let setup = YapDatabaseSecondaryIndexSetup()
|
||||
setup.addColumn(primaryDevicePubKey, with: .text)
|
||||
setup.addColumn(secondaryDevicePubKey, with: .text)
|
||||
setup.addColumn(isGranted, with: .integer)
|
||||
|
||||
let handler = YapDatabaseSecondaryIndexHandler.withObjectBlock { (transaction, dict, collection, key, object) in
|
||||
guard let pairing = object as? LokiPairingAuthorisation else { return }
|
||||
dict[primaryDevicePubKey] = pairing.primaryDevicePubKey
|
||||
dict[secondaryDevicePubKey] = pairing.secondaryDevicePubKey
|
||||
dict[isGranted] = pairing.isGranted
|
||||
}
|
||||
|
||||
return YapDatabaseSecondaryIndex(setup: setup, handler: handler)
|
||||
}
|
||||
|
||||
@objc public static var databaseExtensionName: String {
|
||||
return name
|
||||
}
|
||||
|
||||
@objc public static func asyncRegisterDatabaseExtensions(_ storage: OWSStorage) {
|
||||
storage.register(indexDatabaseExtension, withName: name)
|
||||
}
|
||||
|
||||
// MARK: Helper
|
||||
|
||||
public static func enumeratePairingAuthorisations(with query: YapDatabaseQuery, transaction: YapDatabaseReadTransaction, block: @escaping (LokiPairingAuthorisation, UnsafeMutablePointer<ObjCBool>) -> Void) {
|
||||
let ext = transaction.ext(PairingAuthorisationsIndex.name) as? YapDatabaseSecondaryIndexTransaction
|
||||
ext?.enumerateKeysAndObjects(matching: query) { (collection, key, object, stop) in
|
||||
guard let authorisation = object as? LokiPairingAuthorisation else { return }
|
||||
block(authorisation, stop)
|
||||
}
|
||||
}
|
||||
|
||||
public static func getPairingAuthorisations(with query: YapDatabaseQuery, transaction: YapDatabaseReadTransaction) -> [LokiPairingAuthorisation] {
|
||||
var authorisations = [LokiPairingAuthorisation]()
|
||||
enumeratePairingAuthorisations(with: query, transaction: transaction) { (authorisation, _) in
|
||||
authorisations.append(authorisation)
|
||||
}
|
||||
return authorisations
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue