Configure SessionMessagingKit

pull/311/head
nielsandriesse 4 years ago
parent f706e38ef7
commit b88bfd1da0

@ -0,0 +1,37 @@
extension AppDelegate : OpenGroupAPIDelegate {
public func updateProfileIfNeeded(for channel: UInt64, on server: String, from info: OpenGroupInfo) {
let storage = OWSPrimaryStorage.shared()
let publicChatID = "\(server).\(channel)"
Storage.writeSync { transaction in
// Update user count
storage.setUserCount(info.memberCount, forPublicChatWithID: publicChatID, in: transaction)
let groupThread = TSGroupThread.getOrCreateThread(withGroupId: publicChatID.data(using: .utf8)!, groupType: .openGroup, transaction: transaction)
// Update display name if needed
let groupModel = groupThread.groupModel
if groupModel.groupName != info.displayName {
let newGroupModel = TSGroupModel(title: info.displayName, memberIds: groupModel.groupMemberIds, image: groupModel.groupImage, groupId: groupModel.groupId, groupType: groupModel.groupType, adminIds: groupModel.groupAdminIds)
groupThread.groupModel = newGroupModel
groupThread.save(with: transaction)
}
// Download and update profile picture if needed
let oldProfilePictureURL = storage.getProfilePictureURL(forPublicChatWithID: publicChatID, in: transaction)
if oldProfilePictureURL != info.profilePictureURL || groupModel.groupImage == nil {
storage.setProfilePictureURL(info.profilePictureURL, forPublicChatWithID: publicChatID, in: transaction)
if let profilePictureURL = info.profilePictureURL {
var sanitizedServerURL = server
var sanitizedProfilePictureURL = profilePictureURL
while sanitizedServerURL.hasSuffix("/") { sanitizedServerURL.removeLast(1) }
while sanitizedProfilePictureURL.hasPrefix("/") { sanitizedProfilePictureURL.removeFirst(1) }
let url = "\(sanitizedServerURL)/\(sanitizedProfilePictureURL)"
FileServerAPI.downloadAttachment(from: url).map2 { data in
let attachmentStream = TSAttachmentStream(contentType: OWSMimeTypeImageJpeg, byteCount: UInt32(data.count), sourceFilename: nil, caption: nil, albumMessageId: nil)
try attachmentStream.write(data)
groupThread.updateAvatar(with: attachmentStream)
}
}
}
}
}
}

@ -1,10 +1,24 @@
import SessionMessagingKit
import SessionProtocolKit
import SessionSnodeKit
@objc(SNConfiguration)
final class Configuration : NSObject {
private static let pnServerURL = "https://live.apns.getsession.org"
private static let pnServerPublicKey = "642a6585919742e5a2d4dc51244964fbcd8bcab2b75612407de58b810740d049"
@objc static func performMainSetup() {
SNMessagingKit.configure(
storage: Storage.shared,
signalStorage: OWSPrimaryStorage.shared(),
identityKeyStore: OWSIdentityManager.shared(),
sessionRestorationImplementation: SessionRestorationImplementation(),
certificateValidator: SMKCertificateDefaultValidator(trustRoot: OWSUDManagerImpl.trustRoot()),
openGroupAPIDelegate: UIApplication.shared.delegate as! AppDelegate,
pnServerURL: pnServerURL,
pnServerPublicKey: pnServerURL
)
SessionProtocolKit.configure(storage: Storage.shared, sharedSenderKeysDelegate: UIApplication.shared.delegate as! AppDelegate)
SessionSnodeKit.configure(storage: Storage.shared)
}

@ -0,0 +1,158 @@
import Foundation
import PromiseKit
extension Storage : SessionMessagingKitStorageProtocol {
// MARK: Signal Protocol
public func getOrGenerateRegistrationID(using transaction: Any) -> UInt32 {
SSKEnvironment.shared.tsAccountManager.getOrGenerateRegistrationId(transaction as! YapDatabaseReadWriteTransaction)
}
public func getSenderCertificate(for publicKey: String) -> SMKSenderCertificate {
let (promise, seal) = Promise<SMKSenderCertificate>.pending()
SSKEnvironment.shared.udManager.ensureSenderCertificate { senderCertificate in
seal.fulfill(senderCertificate)
} failure: { error in
// Should never fail
}
return try! promise.wait()
}
// MARK: Shared Sender Keys
private static let closedGroupPrivateKeyCollection = "LokiClosedGroupPrivateKeyCollection"
public func getClosedGroupPrivateKey(for publicKey: String) -> String? {
var result: String?
Storage.read { transaction in
result = transaction.object(forKey: publicKey, inCollection: Storage.closedGroupPrivateKeyCollection) as? String
}
return result
}
internal static func setClosedGroupPrivateKey(_ privateKey: String, for publicKey: String, using transaction: Any) {
(transaction as! YapDatabaseReadWriteTransaction).setObject(privateKey, forKey: publicKey, inCollection: Storage.closedGroupPrivateKeyCollection)
}
internal static func removeClosedGroupPrivateKey(for publicKey: String, using transaction: Any) {
(transaction as! YapDatabaseReadWriteTransaction).removeObject(forKey: publicKey, inCollection: Storage.closedGroupPrivateKeyCollection)
}
func getUserClosedGroupPublicKeys() -> Set<String> {
var result: Set<String> = []
Storage.read { transaction in
result = Set(transaction.allKeys(inCollection: Storage.closedGroupPrivateKeyCollection))
}
return result
}
public func isClosedGroup(_ publicKey: String) -> Bool {
getUserClosedGroupPublicKeys().contains(publicKey)
}
// MARK: Jobs
public func persist(_ job: Job, using transaction: Any) { fatalError("Not implemented.") }
public func markJobAsSucceeded(_ job: Job, using transaction: Any) { fatalError("Not implemented.") }
public func markJobAsFailed(_ job: Job, using transaction: Any) { fatalError("Not implemented.") }
// MARK: Authorization
private static func getAuthTokenCollection(for server: String) -> String {
return (server == FileServerAPI.server) ? "LokiStorageAuthTokenCollection" : "LokiGroupChatAuthTokenCollection"
}
public func getAuthToken(for server: String) -> String? {
let collection = Storage.getAuthTokenCollection(for: server)
var result: String? = nil
Storage.read { transaction in
result = transaction.object(forKey: server, inCollection: collection) as? String
}
return result
}
public func setAuthToken(for server: String, to newValue: String, using transaction: Any) {
let collection = Storage.getAuthTokenCollection(for: server)
(transaction as! YapDatabaseReadWriteTransaction).setObject(newValue, forKey: server, inCollection: collection)
}
public func removeAuthToken(for server: String, using transaction: Any) {
let collection = Storage.getAuthTokenCollection(for: server)
(transaction as! YapDatabaseReadWriteTransaction).removeObject(forKey: server, inCollection: collection)
}
// MARK: Open Group Public Keys
private static let openGroupPublicKeyCollection = "LokiOpenGroupPublicKeyCollection"
public func getOpenGroupPublicKey(for server: String) -> String? {
var result: String? = nil
Storage.read { transaction in
result = transaction.object(forKey: server, inCollection: Storage.openGroupPublicKeyCollection) as? String
}
return result
}
public func setOpenGroupPublicKey(for server: String, to newValue: String, using transaction: Any) {
(transaction as! YapDatabaseReadWriteTransaction).setObject(newValue, forKey: server, inCollection: Storage.openGroupPublicKeyCollection)
}
// MARK: Last Message Server ID
private static let lastMessageServerIDCollection = "LokiGroupChatLastMessageServerIDCollection"
public func getLastMessageServerID(for group: UInt64, on server: String) -> UInt64? {
var result: UInt64? = nil
Storage.read { transaction in
result = transaction.object(forKey: "\(server).\(group)", inCollection: Storage.lastMessageServerIDCollection) as? UInt64
}
return result
}
public func setLastMessageServerID(for group: UInt64, on server: String, to newValue: UInt64, using transaction: Any) {
(transaction as! YapDatabaseReadWriteTransaction).setObject(newValue, forKey: "\(server).\(group)", inCollection: Storage.lastMessageServerIDCollection)
}
public func removeLastMessageServerID(for group: UInt64, on server: String, using transaction: Any) {
(transaction as! YapDatabaseReadWriteTransaction).removeObject(forKey: "\(server).\(group)", inCollection: Storage.lastMessageServerIDCollection)
}
// MARK: Last Deletion Server ID
private static let lastDeletionServerIDCollection = "LokiGroupChatLastDeletionServerIDCollection"
public func getLastDeletionServerID(for group: UInt64, on server: String) -> UInt64? {
var result: UInt64? = nil
Storage.read { transaction in
result = transaction.object(forKey: "\(server).\(group)", inCollection: Storage.lastDeletionServerIDCollection) as? UInt64
}
return result
}
public func setLastDeletionServerID(for group: UInt64, on server: String, to newValue: UInt64, using transaction: Any) {
(transaction as! YapDatabaseReadWriteTransaction).setObject(newValue, forKey: "\(server).\(group)", inCollection: Storage.lastDeletionServerIDCollection)
}
public func removeLastDeletionServerID(for group: UInt64, on server: String, using transaction: Any) {
(transaction as! YapDatabaseReadWriteTransaction).removeObject(forKey: "\(server).\(group)", inCollection: Storage.lastDeletionServerIDCollection)
}
// MARK: Open Group Metadata
private static let openGroupUserCountCollection = "LokiPublicChatUserCountCollection"
private static let openGroupMessageIDCollection = "LKMessageIDCollection"
public func setUserCount(to newValue: Int, forOpenGroupWithID openGroupID: String, using transaction: Any) {
(transaction as! YapDatabaseReadWriteTransaction).setObject(newValue, forKey: openGroupID, inCollection: Storage.openGroupUserCountCollection)
}
public func getIDForMessage(withServerID serverID: UInt64) -> UInt64? {
var result: UInt64? = nil
Storage.read { transaction in
result = transaction.object(forKey: String(serverID), inCollection: Storage.openGroupMessageIDCollection) as? UInt64
}
return result
}
public func setOpenGroupDisplayName(to displayName: String, for publicKey: String, on channel: UInt64, server: String, using transaction: Any) {
let collection = "\(server).\(channel)" // FIXME: This should be a proper collection
(transaction as! YapDatabaseReadWriteTransaction).setObject(displayName, forKey: publicKey, inCollection: collection)
}
public func setLastProfilePictureUploadDate(_ date: Date) {
UserDefaults.standard[.lastProfilePictureUpload] = date
}
}

@ -2,7 +2,7 @@
extension Storage : SessionSnodeKitStorageProtocol {
// MARK: Onion Request Paths
internal static let onionRequestPathCollection = "LokiOnionRequestPathCollection"
private static let onionRequestPathCollection = "LokiOnionRequestPathCollection"
public func getOnionRequestPaths() -> [OnionRequestAPI.Path] {
let collection = Storage.onionRequestPathCollection

@ -7,7 +7,17 @@ extension Storage {
Storage.writeSync { work($0) }
}
public func withAsync(_ work: @escaping (Any) -> Void, completion: @escaping () -> Void) {
Storage.write(with: { work($0) }, completion: completion)
}
public func getUserPublicKey() -> String? {
return OWSIdentityManager.shared().identityKeyPair()?.publicKey.toHexString()
}
public func getUserKeyPair() -> ECKeyPair? {
return OWSIdentityManager.shared().identityKeyPair()
}
public func getUserDisplayName() -> String? { fatalError() }
}

@ -13,7 +13,7 @@ public struct Configuration {
internal static var shared: Configuration!
}
public enum SessionMessagingKitX { // Just to make the external API nice
public enum SNMessagingKit { // Just to make the external API nice
public static func configure(
storage: SessionMessagingKitStorageProtocol,

@ -122,7 +122,7 @@ public final class OpenGroupAPI : DotNetAPI {
SNLog("Ignoring open group message with invalid signature.")
return nil
}
let existingMessageID = storage.getIDForMessage(withServerID: UInt(result.serverID!))
let existingMessageID = storage.getIDForMessage(withServerID: result.serverID!)
guard existingMessageID == nil else {
SNLog("Ignoring duplicate open group message.")
return nil

@ -2,8 +2,8 @@ import SessionProtocolKit
public protocol SessionMessagingKitStorageProtocol {
func with(_ work: (Any) -> Void)
func withAsync(_ work: (Any) -> Void, completion: () -> Void)
func with(_ work: @escaping (Any) -> Void)
func withAsync(_ work: @escaping (Any) -> Void, completion: @escaping () -> Void)
func getUserPublicKey() -> String?
func getUserKeyPair() -> ECKeyPair?
@ -20,14 +20,14 @@ public protocol SessionMessagingKitStorageProtocol {
func removeAuthToken(for server: String, using transaction: Any)
func getOpenGroupPublicKey(for server: String) -> String?
func setOpenGroupPublicKey(for server: String, to newValue: String, using transaction: Any)
func getLastMessageServerID(for group: UInt64, on server: String) -> UInt?
func getLastMessageServerID(for group: UInt64, on server: String) -> UInt64?
func setLastMessageServerID(for group: UInt64, on server: String, to newValue: UInt64, using transaction: Any)
func removeLastMessageServerID(for group: UInt64, on server: String, using transaction: Any)
func getLastDeletionServerID(for group: UInt64, on server: String) -> UInt64?
func setLastDeletionServerID(for group: UInt64, on server: String, to newValue: UInt64, using transaction: Any)
func removeLastDeletionServerID(for group: UInt64, on server: String, using transaction: Any)
func setUserCount(to newValue: Int, forOpenGroupWithID: String, using transaction: Any)
func getIDForMessage(withServerID serverID: UInt) -> UInt?
func setUserCount(to newValue: Int, forOpenGroupWithID openGroupID: String, using transaction: Any)
func getIDForMessage(withServerID serverID: UInt64) -> UInt64?
func setOpenGroupDisplayName(to displayName: String, for publicKey: String, on channel: UInt64, server: String, using transaction: Any)
func setLastProfilePictureUploadDate(_ date: Date) // Stored in user defaults so no transaction is needed
}

@ -801,6 +801,8 @@
C3548F0624456447009433A8 /* PNModeVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3548F0524456447009433A8 /* PNModeVC.swift */; };
C3548F0824456AB6009433A8 /* UIView+Wrapping.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3548F0724456AB6009433A8 /* UIView+Wrapping.swift */; };
C354E75A23FE2A7600CE22E3 /* BaseVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C354E75923FE2A7600CE22E3 /* BaseVC.swift */; };
C3550A03255DD6D900194B6A /* AppDelegate+OpenGroupAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3550A02255DD6D900194B6A /* AppDelegate+OpenGroupAPI.swift */; };
C3550A1D255DD73500194B6A /* Storage+SessionMessagingKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3550A1C255DD73500194B6A /* Storage+SessionMessagingKit.swift */; };
C35E8AA82485C85800ACB629 /* GeoLite2-Country-Locations-English.csv in Resources */ = {isa = PBXBuildFile; fileRef = C35E8AA52485C85400ACB629 /* GeoLite2-Country-Locations-English.csv */; };
C35E8AA92485C85800ACB629 /* GeoLite2-Country-Blocks-IPv4.csv in Resources */ = {isa = PBXBuildFile; fileRef = C35E8AA62485C85600ACB629 /* GeoLite2-Country-Blocks-IPv4.csv */; };
C35E8AAE2485E51D00ACB629 /* IP2Country.swift in Sources */ = {isa = PBXBuildFile; fileRef = C35E8AAD2485E51D00ACB629 /* IP2Country.swift */; };
@ -2165,6 +2167,8 @@
C3548F0524456447009433A8 /* PNModeVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PNModeVC.swift; sourceTree = "<group>"; };
C3548F0724456AB6009433A8 /* UIView+Wrapping.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+Wrapping.swift"; sourceTree = "<group>"; };
C354E75923FE2A7600CE22E3 /* BaseVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseVC.swift; sourceTree = "<group>"; };
C3550A02255DD6D900194B6A /* AppDelegate+OpenGroupAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppDelegate+OpenGroupAPI.swift"; sourceTree = "<group>"; };
C3550A1C255DD73500194B6A /* Storage+SessionMessagingKit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Storage+SessionMessagingKit.swift"; sourceTree = "<group>"; };
C35E8AA22485C72300ACB629 /* SwiftCSV.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftCSV.framework; path = ThirdParty/Carthage/Build/iOS/SwiftCSV.framework; sourceTree = "<group>"; };
C35E8AA52485C85400ACB629 /* GeoLite2-Country-Locations-English.csv */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "GeoLite2-Country-Locations-English.csv"; sourceTree = "<group>"; };
C35E8AA62485C85600ACB629 /* GeoLite2-Country-Blocks-IPv4.csv */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "GeoLite2-Country-Blocks-IPv4.csv"; sourceTree = "<group>"; };
@ -3272,6 +3276,7 @@
C31F812425258F9C00DD9FD9 /* Database */ = {
isa = PBXGroup;
children = (
C3550A1C255DD73500194B6A /* Storage+SessionMessagingKit.swift */,
C3F0A619255C9902007BE2A3 /* Storage+SessionProtocolKit.swift */,
C3F0A607255C98A6007BE2A3 /* Storage+SessionSnodeKit.swift */,
C3F0A5FD255C988A007BE2A3 /* Storage+Shared.swift */,
@ -4477,6 +4482,7 @@
isa = PBXGroup;
children = (
C3F0A58F255C8E3D007BE2A3 /* Meta */,
C3550A02255DD6D900194B6A /* AppDelegate+OpenGroupAPI.swift */,
C3F0A62B255C9937007BE2A3 /* AppDelegate+SharedSenderKeys.swift */,
C3F0A5EB255C970D007BE2A3 /* Configuration.swift */,
B8CCF63B239757C10091D419 /* Components */,
@ -6159,6 +6165,7 @@
34D99C931F2937CC00D284D6 /* OWSAnalytics.swift in Sources */,
B8783E9E23EB948D00404FB8 /* UILabel+Interaction.swift in Sources */,
B80C6B5B2384C7F900FDBC8B /* DeviceNameModalDelegate.swift in Sources */,
C3550A03255DD6D900194B6A /* AppDelegate+OpenGroupAPI.swift in Sources */,
340FC8B8204DAC8D007AEB0F /* AddToGroupViewController.m in Sources */,
B893063F2383961A005EAA8E /* ScanQRCodeWrapperVC.swift in Sources */,
B879D449247E1BE300DB3608 /* PathVC.swift in Sources */,
@ -6268,6 +6275,7 @@
340FC8AB204DAC8D007AEB0F /* DomainFrontingCountryViewController.m in Sources */,
4C586926224FAB83003FD070 /* AVAudioSession+OWS.m in Sources */,
3496744D2076768700080B5F /* OWSMessageBubbleView.m in Sources */,
C3550A1D255DD73500194B6A /* Storage+SessionMessagingKit.swift in Sources */,
C331FFF42558FF0300070591 /* PNOptionView.swift in Sources */,
34B3F8751E8DF1700035BE1A /* CallViewController.swift in Sources */,
4C4AE6A1224AF35700D4AF6F /* SendMediaNavigationController.swift in Sources */,

Loading…
Cancel
Save