Statistics
| Branch: | Tag: | Revision:

chatsecureios / ChatSecure / Classes / Views / Cells / OMEMODeviceFingerprintCell.swift @ 9a71f7ed

History | View | Annotate | Download (5.18 KB)

1
//
2
//  OMEMODeviceFingerprintCell.swift
3
//  ChatSecure
4
//
5
//  Created by Chris Ballinger on 10/14/16.
6
//  Copyright © 2016 Chris Ballinger. All rights reserved.
7
//
8

    
9
import UIKit
10
import XLForm
11
import OTRAssets
12
import XMPPFramework
13
import FormatterKit
14
import OTRKit
15

    
16
private extension String {
17
    //http://stackoverflow.com/a/34454633/805882
18
    func splitEvery(_ n: Int) -> [String] {
19
        var result: [String] = []
20
        let chars = Array(self)
21
        for index in stride(from: 0, to: chars.count, by: n) {
22
            result.append(String(chars[index..<min(index+n, chars.count)]))
23
        }
24
        return result
25
    }
26
}
27

    
28
public extension NSData {
29
    /// hex, split every 8 bytes by a space
30
    @objc public func humanReadableFingerprint() -> String {
31
        return (self as NSData).xmpp_hexStringValue.splitEvery(8).joined(separator: " ")
32
    }
33
}
34

    
35
public extension XLFormBaseCell {
36
    
37
    @objc public class func defaultRowDescriptorType() -> String {
38
        let type = NSStringFromClass(self)
39
        return type
40
    }
41
    
42
    @objc public class func registerCellClass(_ forType: String) {
43
        let bundle = OTRAssets.resourcesBundle
44
        let path = bundle.bundlePath
45
        guard let bundleName = (path as NSString?)?.lastPathComponent else {
46
            return
47
        }
48
        let className = bundleName + "/" + NSStringFromClass(self)
49
        XLFormViewController.cellClassesForRowDescriptorTypes().setObject(className, forKey: forType as NSString)
50
    }
51
}
52

    
53
@objc(OMEMODeviceFingerprintCell)
54
open class OMEMODeviceFingerprintCell: XLFormBaseCell {
55
    
56
    @IBOutlet weak var fingerprintLabel: UILabel!
57
    @IBOutlet weak var trustSwitch: UISwitch!
58
    @IBOutlet weak var lastSeenLabel: UILabel!
59
    @IBOutlet weak var trustLevelLabel: UILabel!
60
    
61
    fileprivate static let intervalFormatter = TTTTimeIntervalFormatter()
62
    
63
    open override class func formDescriptorCellHeight(for rowDescriptor: XLFormRowDescriptor!) -> CGFloat {
64
        return 90
65
    }
66
    
67
    open override func update() {
68
        super.update()
69
        if let device = rowDescriptor.value as? OTROMEMODevice {
70
            updateCellFromDevice(device)
71
        }
72
        if let fingerprint = rowDescriptor.value as? OTRFingerprint {
73
            updateCellFromFingerprint(fingerprint)
74
        }
75
        let enabled = !rowDescriptor.isDisabled()
76
        trustSwitch.isEnabled = enabled
77
        fingerprintLabel.isEnabled = enabled
78
        lastSeenLabel.isEnabled = enabled
79
    }
80
    
81
    @IBAction func switchValueChanged(_ sender: UISwitch) {
82
        if let device = rowDescriptor.value as? OTROMEMODevice {
83
            switchValueWithDevice(device)
84
        }
85
        if let fingerprint = rowDescriptor.value as? OTRFingerprint {
86
            switchValueWithFingerprint(fingerprint)
87
        }
88
    }
89
    
90
    fileprivate func updateCellFromDevice(_ device: OTROMEMODevice) {
91
        let trusted = device.isTrusted()
92
        trustSwitch.isOn = trusted
93
        
94
        // we've already filtered out devices w/o public keys
95
        // so publicIdentityKeyData should never be nil
96
        let fingerprint = device.humanReadableFingerprint
97
        
98
        fingerprintLabel.text = fingerprint
99
        let interval = -Date().timeIntervalSince(device.lastSeenDate)
100
        let since = type(of: self).intervalFormatter.string(forTimeInterval: interval)
101
        let lastSeen = "OMEMO: " + since!
102
        lastSeenLabel.text = lastSeen
103
        if (device.trustLevel == .trustedTofu) {
104
            trustLevelLabel.text = "TOFU"
105
        } else if (device.trustLevel == .trustedUser) {
106
            trustLevelLabel.text = VERIFIED_STRING()
107
        } else if (device.trustLevel == .removed) {
108
            trustLevelLabel.text = Removed_By_Server()
109
        } else {
110
            trustLevelLabel.text = UNTRUSTED_DEVICE_STRING()
111
        }
112
    }
113
    
114
    fileprivate func switchValueWithDevice(_ device: OTROMEMODevice) {
115
        if (trustSwitch.isOn) {
116
            device.trustLevel = .trustedUser
117
            if (device.isExpired()){
118
                device.lastSeenDate = Date()
119
            }
120
        } else {
121
            device.trustLevel = .untrusted
122
        }
123
        rowDescriptor.value = device
124
        updateCellFromDevice(device)
125
    }
126
    
127
    fileprivate func updateCellFromFingerprint(_ fingerprint: OTRFingerprint) {
128
        fingerprintLabel.text = (fingerprint.fingerprint as NSData).humanReadableFingerprint()
129
        lastSeenLabel.text = "OTR"
130
        if (fingerprint.trustLevel == .trustedUser ||
131
            fingerprint.trustLevel == .trustedTofu) {
132
            trustSwitch.isOn = true
133
        } else {
134
            trustSwitch.isOn = false
135
        }
136
        if (fingerprint.trustLevel == .trustedTofu) {
137
            trustLevelLabel.text = "TOFU"
138
        } else if (fingerprint.trustLevel == .trustedUser) {
139
            trustLevelLabel.text = VERIFIED_STRING()
140
        } else {
141
            trustLevelLabel.text = UNTRUSTED_DEVICE_STRING()
142
        }
143
    }
144
    
145
    fileprivate func switchValueWithFingerprint(_ fingerprint: OTRFingerprint) {
146
        if (trustSwitch.isOn) {
147
            fingerprint.trustLevel = .trustedUser
148
        } else {
149
            fingerprint.trustLevel = .untrustedUser
150
        }
151
        rowDescriptor.value = fingerprint
152
        updateCellFromFingerprint(fingerprint)
153
    }
154

    
155
    
156
}