add passcode and touch ID

This commit is contained in:
Bob Sun 2017-02-07 20:24:58 +08:00
parent b022612e83
commit a31e9776fe
No known key found for this signature in database
GPG key ID: 1F86BA2052FED3B4
8 changed files with 133 additions and 8 deletions

View file

@ -1,3 +1,4 @@
github "SVProgressHUD/SVProgressHUD"
github "radex/SwiftyUserDefaults"
github "libgit2/objective-git"
github "zahlz/SwiftPasscodeLock"

View file

@ -10,6 +10,9 @@
94BA784B85E071D25EE89B59 /* libPods-pass.a in Frameworks */ = {isa = PBXBuildFile; fileRef = ADCE7A5C3CCC67D7D21BB3C4 /* libPods-pass.a */; };
DC1208581E35EBE60042942E /* ObjectiveGit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1208571E35EBE60042942E /* ObjectiveGit.framework */; };
DC193FFA1E49B4430077E0A3 /* AdvancedSettingsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC193FF91E49B4430077E0A3 /* AdvancedSettingsTableViewController.swift */; };
DC193FFC1E49E0340077E0A3 /* PasscodeLock.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC193FFB1E49E0340077E0A3 /* PasscodeLock.framework */; };
DC193FFE1E49E0760077E0A3 /* PasscodeLockRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC193FFD1E49E0760077E0A3 /* PasscodeLockRepository.swift */; };
DC1940001E49E1A60077E0A3 /* PasscodeLockConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC193FFF1E49E1A60077E0A3 /* PasscodeLockConfiguration.swift */; };
DC4914961E434301007FF592 /* LabelTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC4914941E434301007FF592 /* LabelTableViewCell.swift */; };
DC4914991E434600007FF592 /* PasswordDetailTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC4914981E434600007FF592 /* PasswordDetailTableViewController.swift */; };
DC5734AE1E439AD400D09270 /* PasswordsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC5734AD1E439AD400D09270 /* PasswordsViewController.swift */; };
@ -41,6 +44,9 @@
AEAD6B31EAF5D061447A68CC /* Pods-pass.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-pass.release.xcconfig"; path = "Pods/Target Support Files/Pods-pass/Pods-pass.release.xcconfig"; sourceTree = "<group>"; };
DC1208571E35EBE60042942E /* ObjectiveGit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ObjectiveGit.framework; path = Carthage/Build/iOS/ObjectiveGit.framework; sourceTree = "<group>"; };
DC193FF91E49B4430077E0A3 /* AdvancedSettingsTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AdvancedSettingsTableViewController.swift; sourceTree = "<group>"; };
DC193FFB1E49E0340077E0A3 /* PasscodeLock.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PasscodeLock.framework; path = Carthage/Build/iOS/PasscodeLock.framework; sourceTree = "<group>"; };
DC193FFD1E49E0760077E0A3 /* PasscodeLockRepository.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PasscodeLockRepository.swift; sourceTree = "<group>"; };
DC193FFF1E49E1A60077E0A3 /* PasscodeLockConfiguration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PasscodeLockConfiguration.swift; sourceTree = "<group>"; };
DC4914941E434301007FF592 /* LabelTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LabelTableViewCell.swift; sourceTree = "<group>"; };
DC4914981E434600007FF592 /* PasswordDetailTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PasswordDetailTableViewController.swift; sourceTree = "<group>"; };
DC4A746D1E30FBDE00E8EB18 /* Objective-CBridgingHeader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Objective-CBridgingHeader.h"; sourceTree = "<group>"; };
@ -76,6 +82,7 @@
files = (
DC917BEF1E2F38C5000FDF54 /* Result.framework in Frameworks */,
DCC408C71E307DBB00F29B0E /* SVProgressHUD.framework in Frameworks */,
DC193FFC1E49E0340077E0A3 /* PasscodeLock.framework in Frameworks */,
DC1208581E35EBE60042942E /* ObjectiveGit.framework in Frameworks */,
DCA049961E3357E000522E8F /* SwiftyUserDefaults.framework in Frameworks */,
94BA784B85E071D25EE89B59 /* libPods-pass.a in Frameworks */,
@ -115,6 +122,8 @@
DC917BD51E2E8231000FDF54 /* pass */ = {
isa = PBXGroup;
children = (
DC193FFD1E49E0760077E0A3 /* PasscodeLockRepository.swift */,
DC193FFF1E49E1A60077E0A3 /* PasscodeLockConfiguration.swift */,
DC193FF91E49B4430077E0A3 /* AdvancedSettingsTableViewController.swift */,
DC4A746D1E30FBDE00E8EB18 /* Objective-CBridgingHeader.h */,
DC917BE21E2E8231000FDF54 /* Info.plist */,
@ -145,6 +154,7 @@
DC917BED1E2F38C4000FDF54 /* Frameworks */ = {
isa = PBXGroup;
children = (
DC193FFB1E49E0340077E0A3 /* PasscodeLock.framework */,
DC1208571E35EBE60042942E /* ObjectiveGit.framework */,
DCA049951E3357E000522E8F /* SwiftyUserDefaults.framework */,
DCC408C61E307DBB00F29B0E /* SVProgressHUD.framework */,
@ -284,6 +294,7 @@
"$(SRCROOT)/Carthage/Build/iOS/SVProgressHUD.framework",
"$(SRCROOT)/Carthage/Build/iOS/SwiftyUserDefaults.framework",
"$(SRCROOT)/Carthage/Build/iOS/ObjectiveGit.framework",
"$(SRCROOT)/Carthage/Build/iOS/PasscodeLock.framework",
);
outputPaths = (
);
@ -311,7 +322,9 @@
DC4914991E434600007FF592 /* PasswordDetailTableViewController.swift in Sources */,
DC5734AE1E439AD400D09270 /* PasswordsViewController.swift in Sources */,
DC8963BE1E38AD8300828B09 /* GitRepositoryAuthenticationSettingTableViewController.swift in Sources */,
DC1940001E49E1A60077E0A3 /* PasscodeLockConfiguration.swift in Sources */,
DC917BD71E2E8231000FDF54 /* AppDelegate.swift in Sources */,
DC193FFE1E49E0760077E0A3 /* PasscodeLockRepository.swift in Sources */,
DCA049981E33586A00522E8F /* DefaultKeys.swift in Sources */,
DCA0499E1E33BAC100522E8F /* Globals.swift in Sources */,
);

View file

@ -8,6 +8,7 @@
import UIKit
import CoreData
import PasscodeLock
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
@ -23,6 +24,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
func applicationWillResignActive(_ application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
let passcodeEnterViewController = PasscodeLockViewController(state: .enter, configuration: Globals.shared.passcodeConfiguration)
UIApplication.shared.keyWindow?.rootViewController?.present(passcodeEnterViewController, animated: true, completion: nil)
}
func applicationDidEnterBackground(_ application: UIApplication) {

View file

@ -25,6 +25,6 @@ extension DefaultsKeys {
static let gitRepositorySSHPrivateKeyPassphrase = DefaultsKey<String?>("gitRepositorySSHPrivateKeyPassphrase")
static let lastUpdatedTime = DefaultsKey<Date?>("lasteUpdatedTime")
static let isPasscodeOn = DefaultsKey<Bool>("isPasscodeOn")
static let isTouchIDOn = DefaultsKey<Bool>("isTouchIDOn")
static let passcodeKey = DefaultsKey<String?>("passcodeKey")
}

View file

@ -14,5 +14,6 @@ class Globals {
let secringPath = "\(NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0])/secring.gpg"
let sshPublicKeyPath = URL(fileURLWithPath: "\(NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0])/ssh_key.pub")
let sshPrivateKeyPath = URL(fileURLWithPath: "\(NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0])/ssh_key")
var passcodeConfiguration = PasscodeLockConfiguration()
private init() { }
}

View file

@ -0,0 +1,29 @@
//
// PasscodeLockConfiguration.swift
// pass
//
// Created by Mingshen Sun on 7/2/2017.
// Copyright © 2017 Bob Sun. All rights reserved.
//
import Foundation
import PasscodeLock
struct PasscodeLockConfiguration: PasscodeLockConfigurationType {
let repository: PasscodeRepositoryType
let passcodeLength = 4
var isTouchIDAllowed = false
let shouldRequestTouchIDImmediately = true
let maximumInccorectPasscodeAttempts = 3
init(repository: PasscodeRepositoryType) {
self.repository = repository
}
init() {
self.repository = PasscodeLockRepository()
}
}

View file

@ -0,0 +1,42 @@
//
// PasscodeRepository.swift
// pass
//
// Created by Mingshen Sun on 7/2/2017.
// Copyright © 2017 Bob Sun. All rights reserved.
//
import Foundation
import PasscodeLock
import SwiftyUserDefaults
public class PasscodeLockRepository: PasscodeRepositoryType {
private let passcodeKey = "passcode.lock.passcode"
public var hasPasscode: Bool {
if passcode != nil {
return true
}
return false
}
private var passcode: String? {
return Defaults[.passcodeKey]
}
public func save(passcode: String) {
Defaults[.passcodeKey] = passcode
print(passcode)
}
public func check(passcode: String) -> Bool {
return self.passcode == passcode
}
public func delete() {
Defaults[.passcodeKey] = nil
print("delete")
}
}

View file

@ -10,9 +10,11 @@ import UIKit
import SVProgressHUD
import CoreData
import SwiftyUserDefaults
import PasscodeLock
class SettingsTableViewController: UITableViewController {
let repository = PasscodeLockRepository()
@IBOutlet weak var pgpKeyTableViewCell: UITableViewCell!
@IBOutlet weak var touchIDTableViewCell: UITableViewCell!
@IBOutlet weak var passcodeTableViewCell: UITableViewCell!
@ -108,13 +110,27 @@ class SettingsTableViewController: UITableViewController {
super.viewDidLoad()
let touchIDSwitch = UISwitch(frame: CGRect.zero)
touchIDTableViewCell.accessoryView = touchIDSwitch
touchIDSwitch.isOn = false
touchIDSwitch.addTarget(self, action: #selector(touchIDSwitchAction), for: UIControlEvents.valueChanged)
if Defaults[.isTouchIDOn] {
touchIDSwitch.isOn = true
} else {
touchIDSwitch.isOn = false
}
if repository.hasPasscode {
self.passcodeTableViewCell.detailTextLabel?.text = "On"
print(Defaults[.passcodeKey]!)
} else {
self.passcodeTableViewCell.detailTextLabel?.text = "Off"
}
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if tableView.cellForRow(at: indexPath) == passcodeTableViewCell {
if Defaults[.passcodeKey] != nil{
showPasscodeActionSheet()
} else {
setPasscodeLock()
}
tableView.deselectRow(at: indexPath, animated: true)
}
}
@ -130,20 +146,40 @@ class SettingsTableViewController: UITableViewController {
func touchIDSwitchAction(uiSwitch: UISwitch) {
if uiSwitch.isOn {
print("UISwitch is ON")
Globals.shared.passcodeConfiguration.isTouchIDAllowed = true
} else {
print("UISwitch is OFF")
Globals.shared.passcodeConfiguration.isTouchIDAllowed = false
}
}
func showPasscodeActionSheet() {
let passcodeChangeViewController = PasscodeLockViewController(state: .change, configuration: Globals.shared.passcodeConfiguration)
let passcodeRemoveViewController = PasscodeLockViewController(state: .remove, configuration: Globals.shared.passcodeConfiguration)
let optionMenu = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
let removePasscodeAction = UIAlertAction(title: "Remove Passcode", style: .destructive, handler: nil)
let changePasscodeAction = UIAlertAction(title: "Change Passcode", style: .default, handler: nil)
let removePasscodeAction = UIAlertAction(title: "Remove Passcode", style: .destructive) { [unowned self] _ in
passcodeRemoveViewController.successCallback = { _ in
self.passcodeTableViewCell.detailTextLabel?.text = "Off"
}
self.present(passcodeRemoveViewController, animated: true, completion: nil)
}
let changePasscodeAction = UIAlertAction(title: "Change Passcode", style: .default) { [unowned self] _ in
self.present(passcodeChangeViewController, animated: true, completion: nil)
}
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
optionMenu.addAction(removePasscodeAction)
optionMenu.addAction(changePasscodeAction)
optionMenu.addAction(cancelAction)
self.present(optionMenu, animated: true, completion: nil)
}
func setPasscodeLock() {
let passcodeSetViewController = PasscodeLockViewController(state: .set, configuration: Globals.shared.passcodeConfiguration)
passcodeSetViewController.successCallback = { _ in
self.passcodeTableViewCell.detailTextLabel?.text = "On"
}
present(passcodeSetViewController, animated: true, completion: nil)
}
}