pEpForiOS/UI/AccountsAndFolders/AccountSettingsViewModel.swift
author buff <andreas@pep-project.org>
Wed, 10 Jan 2018 11:04:02 +0100
branchIOS-768
changeset 3697 47448741003c
child 3877 5696e6ff1701
permissions -rw-r--r--
IOS-768 fixes typo
andreas@3697
     1
//
andreas@3697
     2
//  AccountSettingsViewModel.swift
andreas@3697
     3
//  pEpForiOS
andreas@3697
     4
//
andreas@3697
     5
//  Created by Xavier Algarra on 13/06/2017.
andreas@3697
     6
//  Copyright © 2017 p≡p Security S.A. All rights reserved.
andreas@3697
     7
//
andreas@3697
     8
andreas@3697
     9
import Foundation
andreas@3697
    10
import MessageModel
andreas@3697
    11
andreas@3697
    12
public class AccountSettingsViewModel {
andreas@3697
    13
andreas@3697
    14
    public struct ServerViewModel {
andreas@3697
    15
        var address: String?
andreas@3697
    16
        var port: String?
andreas@3697
    17
        var transport: String?
andreas@3697
    18
    }
andreas@3697
    19
andreas@3697
    20
    public struct SecurityViewModel {
andreas@3697
    21
andreas@3697
    22
        var options = Server.Transport.toArray()
andreas@3697
    23
        var size : Int {
andreas@3697
    24
            get {
andreas@3697
    25
                return options.count
andreas@3697
    26
            }
andreas@3697
    27
        }
andreas@3697
    28
andreas@3697
    29
        subscript(option: Int) -> String {
andreas@3697
    30
            get {
andreas@3697
    31
                return options[option].asString()
andreas@3697
    32
            }
andreas@3697
    33
        }
andreas@3697
    34
    }
andreas@3697
    35
andreas@3697
    36
    private var account: Account
andreas@3697
    37
    private var clonedAccount: Account?
andreas@3697
    38
    private let headers = [
andreas@3697
    39
        NSLocalizedString("Account", comment: "Account settings"),
andreas@3697
    40
        NSLocalizedString("IMAP Settings", comment: "Account settings title IMAP"),
andreas@3697
    41
        NSLocalizedString("SMTP Settings", comment: "Account settings title SMTP")
andreas@3697
    42
    ]
andreas@3697
    43
    private var controlWord = "noRealPassword"
andreas@3697
    44
andreas@3697
    45
    public let svm = SecurityViewModel()
andreas@3697
    46
andreas@3697
    47
    public init(account: Account) {
andreas@3697
    48
        self.account = account
andreas@3697
    49
    }
andreas@3697
    50
andreas@3697
    51
    var email: String {
andreas@3697
    52
        get {
andreas@3697
    53
            return account.user.address
andreas@3697
    54
        }
andreas@3697
    55
    }
andreas@3697
    56
andreas@3697
    57
    var loginName: String {
andreas@3697
    58
        get {
andreas@3697
    59
            // the email model is based on the assumption that imap.loginName == smtp.loginName
andreas@3697
    60
            return account.server(with: .imap)?.credentials.loginName ?? ""
andreas@3697
    61
        }
andreas@3697
    62
    }
andreas@3697
    63
andreas@3697
    64
    var name: String {
andreas@3697
    65
        get {
andreas@3697
    66
            return account.user.userName ?? ""
andreas@3697
    67
        }
andreas@3697
    68
    }
andreas@3697
    69
andreas@3697
    70
    var smtpServer: ServerViewModel {
andreas@3697
    71
        get {
andreas@3697
    72
            if let server = account.smtpServer {
andreas@3697
    73
                return ServerViewModel(address: server.address,
andreas@3697
    74
                                       port: "\(server.port)",
andreas@3697
    75
                    transport: server.transport?.asString())
andreas@3697
    76
            }
andreas@3697
    77
            return ServerViewModel()
andreas@3697
    78
        }
andreas@3697
    79
    }
andreas@3697
    80
andreas@3697
    81
    var imapServer: ServerViewModel {
andreas@3697
    82
        get {
andreas@3697
    83
            if let server = account.imapServer {
andreas@3697
    84
                return ServerViewModel(address: server.address,
andreas@3697
    85
                                       port: "\(server.port)",
andreas@3697
    86
                    transport: server.transport?.asString())
andreas@3697
    87
            }
andreas@3697
    88
            return ServerViewModel()
andreas@3697
    89
        }
andreas@3697
    90
    }
andreas@3697
    91
andreas@3697
    92
    var messageSyncService: MessageSyncServiceProtocol?
andreas@3697
    93
    weak var delegate: AccountVerificationResultDelegate?
andreas@3697
    94
andreas@3697
    95
    //Currently we assume imap and smtp servers exist already (update).
andreas@3697
    96
    // If we run into problems here modify to updateOrCreate
andreas@3697
    97
    func update(loginName: String, name: String, password: String? = nil, imap: ServerViewModel,
andreas@3697
    98
                smtp: ServerViewModel) {
andreas@3697
    99
        clonedAccount = account.clone()
andreas@3697
   100
        guard let serverImap = account.imapServer,
andreas@3697
   101
            let serverSmtp = account.smtpServer else {
andreas@3697
   102
                Log.shared.errorAndCrash(component: #function,
andreas@3697
   103
                                         errorString: "Account misses imap or smtp server.")
andreas@3697
   104
                return
andreas@3697
   105
        }
andreas@3697
   106
        let pass : String?
andreas@3697
   107
        if let p = password {
andreas@3697
   108
            pass = p
andreas@3697
   109
        } else {
andreas@3697
   110
            pass = serverImap.credentials.password
andreas@3697
   111
        }
andreas@3697
   112
        guard let editedServerImap = server(from: imap, serverType: .imap,
andreas@3697
   113
                                            loginName: loginName,
andreas@3697
   114
                                            password: pass,
andreas@3697
   115
                                            key: serverImap.credentials.key),
andreas@3697
   116
            let editedServerSmtp = server(from: smtp,
andreas@3697
   117
                                          serverType: .smtp,
andreas@3697
   118
                                          loginName: loginName,
andreas@3697
   119
                                          password: pass,
andreas@3697
   120
                                          key: serverSmtp.credentials.key)
andreas@3697
   121
            else {
andreas@3697
   122
                Log.shared.errorAndCrash(component: #function, errorString: "Invalid input.")
andreas@3697
   123
                return
andreas@3697
   124
        }
andreas@3697
   125
        serverImap.needsVerification = true
andreas@3697
   126
        serverSmtp.needsVerification = true
andreas@3697
   127
andreas@3697
   128
        serverImap.updateValues(with: editedServerImap)
andreas@3697
   129
        serverSmtp.updateValues(with: editedServerSmtp)
andreas@3697
   130
andreas@3697
   131
        self.account.user.userName = name
andreas@3697
   132
andreas@3697
   133
        guard let ms = messageSyncService else {
andreas@3697
   134
            Log.shared.errorAndCrash(component: #function, errorString: "no MessageSyncService")
andreas@3697
   135
            return
andreas@3697
   136
        }
andreas@3697
   137
        account.needsVerification = true
andreas@3697
   138
        account.save()
andreas@3697
   139
        ms.requestVerification(account: account, delegate: self)
andreas@3697
   140
    }
andreas@3697
   141
andreas@3697
   142
    func sectionIsValid(section: Int) -> Bool {
andreas@3697
   143
        return section >= 0 && section <= headers.count
andreas@3697
   144
    }
andreas@3697
   145
andreas@3697
   146
    var count: Int {
andreas@3697
   147
        get {
andreas@3697
   148
            return headers.count
andreas@3697
   149
        }
andreas@3697
   150
    }
andreas@3697
   151
andreas@3697
   152
    subscript(section: Int) -> String {
andreas@3697
   153
        get {
andreas@3697
   154
            assert(sectionIsValid(section: section), "Section out of range")
andreas@3697
   155
            return headers[section]
andreas@3697
   156
        }
andreas@3697
   157
    }
andreas@3697
   158
andreas@3697
   159
    //MARK: - PRIVATE
andreas@3697
   160
    private func server(from viewModel:ServerViewModel, serverType:Server.ServerType,
andreas@3697
   161
                        loginName: String, password: String?, key: String? = nil) -> Server? {
andreas@3697
   162
        guard let viewModelPort = viewModel.port,
andreas@3697
   163
            let port = UInt16(viewModelPort),
andreas@3697
   164
            let address = viewModel.address else {
andreas@3697
   165
                Log.shared.errorAndCrash(component: #function,
andreas@3697
   166
                                         errorString: "viewModel misses required data.")
andreas@3697
   167
                return nil
andreas@3697
   168
        }
andreas@3697
   169
        let transport = Server.Transport.init(fromString: viewModel.transport)
andreas@3697
   170
andreas@3697
   171
        let credentials = ServerCredentials.create(loginName: loginName, key: key)
andreas@3697
   172
        if password != nil && password != "" {
andreas@3697
   173
            credentials.password = password
andreas@3697
   174
        }
andreas@3697
   175
andreas@3697
   176
        let server = Server.create(serverType: serverType, port: port, address: address,
andreas@3697
   177
                                   transport: transport, credentials: credentials)
andreas@3697
   178
andreas@3697
   179
        return server
andreas@3697
   180
    }
andreas@3697
   181
andreas@3697
   182
    func cleanClonedAccount() {
andreas@3697
   183
        //account.update(to: clonedAccount)
andreas@3697
   184
    }
andreas@3697
   185
}
andreas@3697
   186
andreas@3697
   187
extension AccountSettingsViewModel: AccountVerificationServiceDelegate {
andreas@3697
   188
    func verified(account: Account, service: AccountVerificationServiceProtocol,
andreas@3697
   189
                  result: AccountVerificationResult) {
andreas@3697
   190
        cleanClonedAccount()
andreas@3697
   191
        DispatchQueue.main.sync {
andreas@3697
   192
            delegate?.didVerify(result: result)
andreas@3697
   193
        }
andreas@3697
   194
    }
andreas@3697
   195
}
andreas@3697
   196