From ebe0fa8dbe2475614fa09505e96da58e8517f940 Mon Sep 17 00:00:00 2001 From: Oliver Wiese <oliver.wiese@fu-berlin.de> Date: Tue, 15 Aug 2017 14:51:31 +0200 Subject: [PATCH] update keyrecords --- enzevalos_iphone/AddressHandler.swift | 9 +- enzevalos_iphone/DataHandler.swift | 120 +++++++++++++--- enzevalos_iphone/Folder+CoreDataClass.swift | 72 ++-------- enzevalos_iphone/KeyRecord.swift | 134 ++++++------------ enzevalos_iphone/MailAddress.swift | 3 +- .../PersistentMail +CoreDataProperties.swift | 2 +- enzevalos_iphone/Record.swift | 4 - enzevalos_iphone/SendViewController.swift | 2 +- enzevalos_iphone/UserData.swift | 16 +-- 9 files changed, 178 insertions(+), 184 deletions(-) diff --git a/enzevalos_iphone/AddressHandler.swift b/enzevalos_iphone/AddressHandler.swift index af8b9850..749d64e3 100644 --- a/enzevalos_iphone/AddressHandler.swift +++ b/enzevalos_iphone/AddressHandler.swift @@ -162,7 +162,7 @@ class AddressHandler { } } catch { - print("exception") + print("exception in contact IN") } } else { print("no Access!") @@ -172,6 +172,9 @@ class AddressHandler { static func getContact(_ name: String) -> [CNContact] { + if name == ""{ + return [] + } AppDelegate.getAppDelegate().requestForAccess({ access in }) let authorizationStatus = CNContactStore.authorizationStatus(for: CNEntityType.contacts) if authorizationStatus == CNAuthorizationStatus.authorized { @@ -180,7 +183,7 @@ class AddressHandler { return conList } catch { - print("exception") + print("exception in contacts get for name: \(name)") } } else { print("no Access!") @@ -199,7 +202,7 @@ class AddressHandler { return conList } catch { - print("exception") + print("exception in contacts") } } else { print("no Access!") diff --git a/enzevalos_iphone/DataHandler.swift b/enzevalos_iphone/DataHandler.swift index 975e88a4..d1d28893 100644 --- a/enzevalos_iphone/DataHandler.swift +++ b/enzevalos_iphone/DataHandler.swift @@ -37,6 +37,7 @@ fileprivate func > <T : Comparable>(lhs: T?, rhs: T?) -> Bool { //TODO: TO Felder mit Strings // KeyRecord mergen?? IMAP Snyc? +typealias requestTuple = (request: String, value: Any) class DataHandler { static let handler: DataHandler = DataHandler() @@ -46,6 +47,8 @@ class DataHandler { private let MaxRecords = 50 private let MaxMailsPerRecord = 100 + + var allFolders: [Folder]{ get{ var folders = [Folder]() @@ -90,8 +93,93 @@ class DataHandler { done(false) } } + + + func allAddressesInFolder(folder: Folder, withoutSecure: Bool) -> [MailAddress]{ + let fReq = NSFetchRequest<NSFetchRequestResult>(entityName: "PersistentMail") + fReq.predicate = NSPredicate(format: "folder = %@", folder) + // fReq.resultType = NSFetchRequestResultType.dictionaryResultType + fReq.propertiesToFetch = ["from"] + //fReq.returnsDistinctResults = true + var addresses = Set<Mail_Address>() + //TODO: improve https://stackoverflow.com/questions/24432895/swift-core-data-request-with-distinct-results#24433996 + + if let result = (try? self.managedObjectContext.fetch(fReq)) as? [PersistentMail]{ + for object in result { + if let adr = object.from as? Mail_Address{ + if !(withoutSecure && object.isSecure){ + addresses.insert(adr) + } + } + } + } + return Array(addresses) + } + + func allKeysInFolder(folder: Folder) -> [String]{ + let fReq = NSFetchRequest<NSFetchRequestResult>(entityName: "PersistentMail") + var predicates = [NSPredicate]() + predicates.append(NSPredicate(format: "folder = %@", folder)) + predicates.append(NSPredicate(format: "keyID != nil")) + let andPredicates = NSCompoundPredicate(andPredicateWithSubpredicates: predicates) + + fReq.predicate = andPredicates + // fReq.resultType = NSFetchRequestResultType.dictionaryResultType + fReq.propertiesToFetch = ["keyID"] + // Add KEYID CONTAINS -! + //fReq.returnsDistinctResults = true + var keys = Set<String>() + //TODO: improve https://stackoverflow.com/questions/24432895/swift-core-data-request-with-distinct-results#24433996 + + if let result = (try? self.managedObjectContext.fetch(fReq)) as? [PersistentMail]{ + print("Key not empty! \(result.count)") + for object in result { + if let key = object.keyID{ + if object.isSecure && key != ""{ + keys.insert(key) + print("My key: \(key)") + } + } + } + } + print("#keys: \(keys.count)") + return Array(keys) + } + + + func allMailsInFolder(key :String?, contact :EnzevalosContact?, folder: Folder?, isSecure: Bool) -> [PersistentMail]{ + let fReq = NSFetchRequest<NSFetchRequestResult>(entityName: "PersistentMail") + var predicates = [NSPredicate]() + if let k = key{ + predicates.append(NSPredicate(format:"keyID MATCHES %@", k)) + } + if let c = contact{ + let adr: Mail_Address = c.getMailAddresses()[0] as! Mail_Address + predicates.append(NSPredicate(format:"from == %@", adr)) + + } + if let f = folder{ + predicates.append(NSPredicate(format:"folder == %@", f)) + } + let andPredicates = NSCompoundPredicate(andPredicateWithSubpredicates: predicates) - + fReq.predicate = andPredicates + fReq.sortDescriptors = [NSSortDescriptor(key: "date", ascending: false)] + if let result = (try? self.managedObjectContext.fetch(fReq)) as? [PersistentMail]{ + + if isSecure{ + let secureMails = result.filter({ + return $0.isSecure + }) + return secureMails + } + + return result + } + return [] + } + + init() { // This resource is the same name as your xcdatamodeld contained in your project. guard let modelURL = Bundle.main.url(forResource: "enzevalos_iphone", withExtension: "momd") else { @@ -362,6 +450,7 @@ class DataHandler { return contact } + func getContact(_ name: String, address: String, key: String, prefer_enc: Bool) -> EnzevalosContact { let contact = getContactByAddress(address) @@ -436,13 +525,6 @@ class DataHandler { if let tmpMails = finding as? [PersistentMail] { mails = tmpMails - print(mails) - } - if uid == 2 { - print(sender) - print(time) - print(subject) - print(body) } if finding == nil || finding!.count == 0 || mails.filter( { $0.folder.path == folderPath }).count == 0 { @@ -468,14 +550,11 @@ class DataHandler { handleCCAddresses(cc, mail: mail) mail.unableToDecrypt = false - if decryptedData == nil{ - // Maybe PGPInline? - // TODO: Refactoring! - mail.decryptIfPossible() - } - else{ - let encState: EncryptionState = (decryptedData?.encryptionState)! - let signState: SignatureState = (decryptedData?.signatureState)! + + if let decData = decryptedData{ + let encState: EncryptionState = decData.encryptionState + let signState: SignatureState = decData.signatureState + mail.keyID = decData.keyID switch encState { case EncryptionState.NoEncryption: @@ -505,6 +584,12 @@ class DataHandler { } mail.decryptedBody = body print("Mail from \(mail.from.mailAddress) about \(String(describing: mail.subject)) has states: enc: \(mail.isEncrypted) and sign: \(mail.isSigned), correct signed: \(mail.isCorrectlySigned) has troubles:\(mail.trouble) and is secure? \(mail.isSecure) unable to decrypt? \(mail.unableToDecrypt)") + + } + else{ + // Maybe PGPInline? + // TODO: Refactoring! + mail.decryptIfPossible() } } else { @@ -523,9 +608,6 @@ class DataHandler { save() - if let r = record { - _ = r.addNewMail(mail) - } } private func readMails() -> [PersistentMail] { diff --git a/enzevalos_iphone/Folder+CoreDataClass.swift b/enzevalos_iphone/Folder+CoreDataClass.swift index 5537c3bd..15a4aada 100644 --- a/enzevalos_iphone/Folder+CoreDataClass.swift +++ b/enzevalos_iphone/Folder+CoreDataClass.swift @@ -41,15 +41,22 @@ public class Folder: NSManagedObject { var liveRecords: [KeyRecord]{ get{ var records = [KeyRecord]() - let mails = self.mailsOfFolder - for m in mails { - addToRecords(m, records: &records) + // Get all Keys, get all + let keys = DataHandler.handler.allKeysInFolder(folder: self) + let adrs = DataHandler.handler.allAddressesInFolder(folder: self, withoutSecure: true) + + for key in keys{ + let record = KeyRecord(keyID: key, folder: self) + records.append(record) } - for r in records { - r.mails.sort() + for adr in adrs{ + if let ec = adr.contact{ + let record = KeyRecord(contact: ec, folder: self) + records.append(record) + } + } - records.sort() - print("Folder: \(self.name) with #KeyRecords: \(records.count) and \(mails.count) mails") + return records } } @@ -80,57 +87,6 @@ public class Folder: NSManagedObject { } } - private func addToRecords(_ m: PersistentMail, records: inout [KeyRecord]) { - - var found = false - for r in records { - if r.addNewMail(m) { - found = true - records.sort() - break - } - } - if !found { - let r = KeyRecord(mail: m) - mergeRecords(newRecord: r, records: &records) - records.append(r) - records.sort() - } - } - - - private func mergeRecords(newRecord: KeyRecord, records: inout[KeyRecord]) { - var j = 0 - if !newRecord.hasKey { - return - } - while j < records.count { - let r = records[j] - if !r.hasKey && r.ezContact == newRecord.ezContact { - var i = 0 - while i < r.mails.count { - let mail = r.mails[i] - var remove = false - if mail.from.keyID == newRecord.key { - remove = newRecord.addNewMail(mail) - if remove { - r.mails.remove(at: i) - } - } - if !remove { - i = i + 1 - } - } - if r.mails.count == 0 { - records.remove(at: j) - } else { - j = j + 1 - } - } else { - j = j + 1 - } - } - } //write value of liveRecords to records func updateRecords() { diff --git a/enzevalos_iphone/KeyRecord.swift b/enzevalos_iphone/KeyRecord.swift index fca1e605..88e2abbf 100644 --- a/enzevalos_iphone/KeyRecord.swift +++ b/enzevalos_iphone/KeyRecord.swift @@ -19,8 +19,21 @@ open class KeyRecord: Record { */ let key: String? + + let folder: Folder + + open var mails: [PersistentMail] { + get{ + return mailsInFolder(folder: folder) + } + } - open var addresses: [MailAddress] = [MailAddress]() + open var addresses: [MailAddress] { + if let adr = ezContact.addresses{ + return Array(adr) as! [MailAddress] + } + return [] + } open var name: String { return ezContact.name @@ -42,10 +55,6 @@ open class KeyRecord: Record { return false } - - open var mails: [PersistentMail] = [PersistentMail]() - - open var ezContact: EnzevalosContact open var cnContact: CNContact? { @@ -60,57 +69,47 @@ open class KeyRecord: Record { } - public init(mail: PersistentMail) { - self.isSecure = mail.isSecure - if(mail.isSecure && mail.from.hasKey) { - self.key = mail.from.keyID - } - else { - self.key = nil + public init(keyID: String?, contact: EnzevalosContact, folder: Folder) { + key = keyID + ezContact = contact + self.folder = folder + if key != nil{ + isSecure = true } - mails.append(mail) - mails.sort() - self.ezContact = mail.from.contact! - _ = addNewAddress(mail.from) } - - open static func deleteRecordFromRecordArray(_ records: [KeyRecord], delRecord: KeyRecord) -> [KeyRecord] { - var myrecords = [KeyRecord](records) - let index = indexInRecords(myrecords, record: delRecord) - if index >= 0 { - myrecords.remove(at: index) - } - return myrecords + + public init(contact: EnzevalosContact, folder: Folder){ + key = nil + ezContact = contact + self.folder = folder + isSecure = false } - - open static func indexInRecords(_ records: [KeyRecord], record: KeyRecord) -> Int { - for (index, r) in records.enumerated() { - if (matchAddresses(r, record2: record) && r.hasKey == record.hasKey && r.key == record.key) { - return index + + public init (keyID: String, folder: Folder){ + key = keyID + self.folder = folder + isSecure = true + let mails = DataHandler.handler.allMailsInFolder(key: keyID, contact: nil, folder: folder, isSecure: isSecure) + if mails.count > 0{ + if let c = mails[0].from.contact{ + ezContact = c + } + else{ + ezContact = DataHandler.handler.getContact("", address: "", key: "", prefer_enc: false) } } - return -1 - } - - private func isInRecords(_ records: [KeyRecord]) -> Bool { - if KeyRecord.indexInRecords(records, record: self) >= 0 { - return true + else{ + ezContact = DataHandler.handler.getContact("", address: "", key: "", prefer_enc: false) } - return false } + - - private static func matchAddresses(_ record1: KeyRecord, record2: KeyRecord) -> Bool { - for adr1 in record1.addresses { - for adr2 in record2.addresses { - if adr1.mailAddress == adr2.mailAddress { - return true - } - } - } - return false + + func mailsInFolder(folder: Folder?) -> [PersistentMail]{ + return DataHandler.handler.allMailsInFolder(key: key, contact: ezContact, folder: folder, isSecure: isSecure) } + @@ -121,49 +120,6 @@ open class KeyRecord: Record { print("subj: \(String(describing: mails.first?.subject?.capitalized))") } - open func addNewAddress(_ adr: MailAddress) -> Bool { - for a in addresses { - if a.mailAddress == adr.mailAddress { - return false - } - } - addresses.append(adr) - return true - } - - open func addNewMail(_ mail: PersistentMail) -> Bool { - // TODO: signed only mails are dropped ?? - if mail.isSecure && self.isSecure { - if mail.from.keyID == self.key { - mails.append(mail) - mails.sort() - _ = addNewAddress(mail.from) - return true - } - return false - - } - else if mail.isSecure != self.isSecure { - return false - } - - if ezContact.getAddress(mail.from.mailAddress) != nil { - for m in mails { - if m.uid == mail.uid { - return true - } - else if m.uid < mail.uid { - break - } - } - mails.append(mail) - mails.sort() - _ = addNewAddress(mail.from) - return true - } - return false - } - open func getImageOrDefault() -> UIImage { return ezContact.getImageOrDefault() } diff --git a/enzevalos_iphone/MailAddress.swift b/enzevalos_iphone/MailAddress.swift index 4067663e..fd1b0a91 100644 --- a/enzevalos_iphone/MailAddress.swift +++ b/enzevalos_iphone/MailAddress.swift @@ -64,7 +64,7 @@ public enum EncState { } -public protocol MailAddress { +public protocol MailAddress { var mailAddress:String{get} var label: CNLabeledValue<NSString>{get} //FIXME: ist der NSString hier wirklich richtig? (http://stackoverflow.com/questions/39648830/how-to-add-new-email-to-cnmutablecontact-in-swift-3) var prefEnc: EncState{get set} @@ -73,3 +73,4 @@ public protocol MailAddress { var keyID: String?{get} var contact: EnzevalosContact?{get} } + diff --git a/enzevalos_iphone/PersistentMail +CoreDataProperties.swift b/enzevalos_iphone/PersistentMail +CoreDataProperties.swift index 1cc95d50..6098b58a 100644 --- a/enzevalos_iphone/PersistentMail +CoreDataProperties.swift +++ b/enzevalos_iphone/PersistentMail +CoreDataProperties.swift @@ -46,7 +46,7 @@ extension PersistentMail { @NSManaged public var isEncrypted: Bool @NSManaged public var isSigned: Bool @NSManaged public var isCorrectlySigned: Bool - @NSManaged public var keyID: String + @NSManaged public var keyID: String? @NSManaged public var unableToDecrypt: Bool @NSManaged public var subject: String? @NSManaged public var folder: Folder diff --git a/enzevalos_iphone/Record.swift b/enzevalos_iphone/Record.swift index 7da8e203..8484dfbf 100644 --- a/enzevalos_iphone/Record.swift +++ b/enzevalos_iphone/Record.swift @@ -22,8 +22,4 @@ public protocol Record: Comparable { var color: UIColor { get } var image: UIImage { get } var addresses: [MailAddress] { get } - - - func addNewAddress(_ adr: MailAddress) -> Bool - func addNewMail(_ mail:PersistentMail) -> Bool } diff --git a/enzevalos_iphone/SendViewController.swift b/enzevalos_iphone/SendViewController.swift index 47506801..d7f2f98d 100644 --- a/enzevalos_iphone/SendViewController.swift +++ b/enzevalos_iphone/SendViewController.swift @@ -351,7 +351,7 @@ class SendViewController: UIViewController { tableview.reloadData() } catch { - print("exception") + print("exception in contacts search") } } else { print("no Access!") diff --git a/enzevalos_iphone/UserData.swift b/enzevalos_iphone/UserData.swift index 539baec6..ad7a70b3 100644 --- a/enzevalos_iphone/UserData.swift +++ b/enzevalos_iphone/UserData.swift @@ -40,8 +40,8 @@ enum Attribute: Int{ case .imapAuthType: return MCOAuthType.saslPlain.rawValue as AnyObject? case .smtpConnectionType: - return MCOConnectionType.TLS.rawValue as AnyObject?//startTLS.rawValue - //return MCOConnectionType.startTLS.rawValue as AnyObject?//startTLS.rawValue + //return MCOConnectionType.TLS.rawValue as AnyObject?//startTLS.rawValue + return MCOConnectionType.startTLS.rawValue as AnyObject?//startTLS.rawValue case .sentFolderPath: return NSLocalizedString("Sent", comment: "Default name for the sentFolder") as AnyObject? case .draftFolderPath: @@ -62,8 +62,8 @@ enum Attribute: Int{ } static let allAttributes = [accountname, userName, userAddr, userPW, smtpHostname, smtpPort, imapHostname, imapPort, prefEncryption, publicKey, autocryptType] - //static var name = "Alice2005@web.de"//"Ullimuelle@web.de" - //static var pw = "WJ$CE:EtUo3E$"//"dun3bate" + static var name = "Alice2005@web.de"//"Ullimuelle@web.de" + static var pw = "WJ$CE:EtUo3E$"//"dun3bate" //static let name = "Ullimuelle@web.de" //static let pw = "dun3bate" @@ -71,11 +71,11 @@ enum Attribute: Int{ // static let pw = "VagotOshaicceov" // static let name = "alice" //static let pw = "egOavOpeecOntew" - static let name = "charlie" - static let pw = "tydpawdAwIdPyuc" + //static let name = "charlie" + //static let pw = "tydpawdAwIdPyuc" static var attributeValues: - //[Attribute : AnyObject?] = [.accountname : name as AnyObject?, .userName : name as Optional<AnyObject>, .userAddr : name as Optional<AnyObject>, .userPW : pw as Optional<AnyObject>, .smtpHostname : "smtp.web.de" as Optional<AnyObject>, .smtpPort : 587 as Optional<AnyObject>, .imapHostname : "imap.web.de" as Optional<AnyObject>, .imapPort : 993 as AnyObject?, .prefEncryption : "yes" as AnyObject?, .autocryptType : "p" as AnyObject?, .publicKey : "" as AnyObject?] - [Attribute : AnyObject?] = [.accountname : name as AnyObject?, .userName : name as Optional<AnyObject>, .userAddr : name+"@enzevalos.de" as Optional<AnyObject>, .userPW : pw as Optional<AnyObject>, .smtpHostname : "mail.enzevalos.de" as Optional<AnyObject>, .smtpPort : 465 as Optional<AnyObject>, .imapHostname : "mail.enzevalos.de" as Optional<AnyObject>, .imapPort : 993 as AnyObject?, .prefEncryption : "yes" as AnyObject?, .autocryptType : "p" as AnyObject?, .publicKey : "" as AnyObject?] + [Attribute : AnyObject?] = [.accountname : name as AnyObject?, .userName : name as Optional<AnyObject>, .userAddr : name as Optional<AnyObject>, .userPW : pw as Optional<AnyObject>, .smtpHostname : "smtp.web.de" as Optional<AnyObject>, .smtpPort : 587 as Optional<AnyObject>, .imapHostname : "imap.web.de" as Optional<AnyObject>, .imapPort : 993 as AnyObject?, .prefEncryption : "yes" as AnyObject?, .autocryptType : "p" as AnyObject?, .publicKey : "" as AnyObject?] + //[Attribute : AnyObject?] = [.accountname : name as AnyObject?, .userName : name as Optional<AnyObject>, .userAddr : name+"@enzevalos.de" as Optional<AnyObject>, .userPW : pw as Optional<AnyObject>, .smtpHostname : "mail.enzevalos.de" as Optional<AnyObject>, .smtpPort : 465 as Optional<AnyObject>, .imapHostname : "mail.enzevalos.de" as Optional<AnyObject>, .imapPort : 993 as AnyObject?, .prefEncryption : "yes" as AnyObject?, .autocryptType : "p" as AnyObject?, .publicKey : "" as AnyObject?] } -- GitLab