Skip to content

Commit

Permalink
Added database extension.
Browse files Browse the repository at this point in the history
  • Loading branch information
Mikunj committed Sep 18, 2019
1 parent 5515937 commit 06ca007
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 14 deletions.
2 changes: 1 addition & 1 deletion Pods
Submodule Pods updated from 0018c3 to 1ab1cb
Original file line number Diff line number Diff line change
@@ -1,16 +1,37 @@
@objc(LKPairingAuthorisation)
public final class LokiPairingAuthorisation : NSObject {
public final class LokiPairingAuthorisation : NSObject, NSCoding {
@objc public let primaryDevicePubKey: String
@objc public let secondaryDevicePubKey: String
@objc public let isGranted: Bool
@objc public let requestSignature: Data?
@objc public let grantSignature: Data?

@objc public init(primaryDevicePubKey: String, secondaryDevicePubKey: String, isGranted: Bool, requestSignature: Data? = nil, grantSignature: Data? = nil) {
@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.isGranted = isGranted
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")
}
}
Original file line number Diff line number Diff line change
@@ -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
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,19 @@ public final class PairingAuthorisationsIndex : NSObject {
@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
// TODO: Handle pairing authorisations object
/*
guard let message = object as? TSMessage else { return }
// Only select sent friend requests which are pending
guard message is TSOutgoingMessage && message.friendRequestStatus == .pending else { return }
dict[friendRequestExpireColumn] = message.friendRequestExpiresAt
*/
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)
Expand All @@ -35,4 +32,22 @@ public final class PairingAuthorisationsIndex : NSObject {
@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
}
}

0 comments on commit 06ca007

Please sign in to comment.