Introduce enum for password generator flavour

This commit is contained in:
Danny Moesch 2018-11-28 22:58:24 +01:00 committed by Bob Sun
parent 1f57305203
commit 3cd8df310c
10 changed files with 102 additions and 47 deletions

View file

@ -16,6 +16,8 @@
301F646D216166AA0071A4CE /* AdditionFieldTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 301F646C216166AA0071A4CE /* AdditionFieldTest.swift */; }; 301F646D216166AA0071A4CE /* AdditionFieldTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 301F646C216166AA0071A4CE /* AdditionFieldTest.swift */; };
302E85612125ECC70031BA64 /* Parser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 302E85602125ECC70031BA64 /* Parser.swift */; }; 302E85612125ECC70031BA64 /* Parser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 302E85602125ECC70031BA64 /* Parser.swift */; };
302E85632125EE550031BA64 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 302E85622125EE550031BA64 /* Constants.swift */; }; 302E85632125EE550031BA64 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 302E85622125EE550031BA64 /* Constants.swift */; };
30A1D29C21AF451E00E2D1F7 /* PasswordGeneratorFlavourTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30A1D29B21AF451E00E2D1F7 /* PasswordGeneratorFlavourTest.swift */; };
30A1D29E21AF468F00E2D1F7 /* PasswordGeneratorFlavour.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30A1D29D21AF468E00E2D1F7 /* PasswordGeneratorFlavour.swift */; };
30AAC05321989DCE00F656CE /* PasswordHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30AAC05221989DCE00F656CE /* PasswordHelpers.swift */; }; 30AAC05321989DCE00F656CE /* PasswordHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30AAC05221989DCE00F656CE /* PasswordHelpers.swift */; };
30B04860209A5141001013CA /* PasswordTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B0485F209A5141001013CA /* PasswordTest.swift */; }; 30B04860209A5141001013CA /* PasswordTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B0485F209A5141001013CA /* PasswordTest.swift */; };
30FD2F78214D9E0E005E0A92 /* ParserTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30FD2F77214D9E0E005E0A92 /* ParserTest.swift */; }; 30FD2F78214D9E0E005E0A92 /* ParserTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30FD2F77214D9E0E005E0A92 /* ParserTest.swift */; };
@ -190,6 +192,8 @@
301F646C216166AA0071A4CE /* AdditionFieldTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdditionFieldTest.swift; sourceTree = "<group>"; }; 301F646C216166AA0071A4CE /* AdditionFieldTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdditionFieldTest.swift; sourceTree = "<group>"; };
302E85602125ECC70031BA64 /* Parser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Parser.swift; sourceTree = "<group>"; }; 302E85602125ECC70031BA64 /* Parser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Parser.swift; sourceTree = "<group>"; };
302E85622125EE550031BA64 /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = "<group>"; }; 302E85622125EE550031BA64 /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = "<group>"; };
30A1D29B21AF451E00E2D1F7 /* PasswordGeneratorFlavourTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PasswordGeneratorFlavourTest.swift; sourceTree = "<group>"; };
30A1D29D21AF468E00E2D1F7 /* PasswordGeneratorFlavour.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PasswordGeneratorFlavour.swift; path = Helpers/PasswordGeneratorFlavour.swift; sourceTree = "<group>"; };
30AAC05221989DCE00F656CE /* PasswordHelpers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PasswordHelpers.swift; path = Helpers/PasswordHelpers.swift; sourceTree = "<group>"; }; 30AAC05221989DCE00F656CE /* PasswordHelpers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PasswordHelpers.swift; path = Helpers/PasswordHelpers.swift; sourceTree = "<group>"; };
30B0485F209A5141001013CA /* PasswordTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PasswordTest.swift; sourceTree = "<group>"; }; 30B0485F209A5141001013CA /* PasswordTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PasswordTest.swift; sourceTree = "<group>"; };
30FD2F77214D9E0E005E0A92 /* ParserTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParserTest.swift; sourceTree = "<group>"; }; 30FD2F77214D9E0E005E0A92 /* ParserTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParserTest.swift; sourceTree = "<group>"; };
@ -382,6 +386,7 @@
children = ( children = (
301F6465216164830071A4CE /* PasswordHelpersTest.swift */, 301F6465216164830071A4CE /* PasswordHelpersTest.swift */,
301F6469216166000071A4CE /* StringExtensionTest.swift */, 301F6469216166000071A4CE /* StringExtensionTest.swift */,
30A1D29B21AF451E00E2D1F7 /* PasswordGeneratorFlavourTest.swift */,
); );
path = Helpers; path = Helpers;
sourceTree = "<group>"; sourceTree = "<group>";
@ -528,6 +533,7 @@
A239F5202157B75E00576CBF /* FileManagerExtension.swift */, A239F5202157B75E00576CBF /* FileManagerExtension.swift */,
A2F4E21A1EED80160011986E /* Globals.swift */, A2F4E21A1EED80160011986E /* Globals.swift */,
A2F4E21B1EED80160011986E /* NotificationNames.swift */, A2F4E21B1EED80160011986E /* NotificationNames.swift */,
30A1D29D21AF468E00E2D1F7 /* PasswordGeneratorFlavour.swift */,
30AAC05221989DCE00F656CE /* PasswordHelpers.swift */, 30AAC05221989DCE00F656CE /* PasswordHelpers.swift */,
A239F51E2157B72700576CBF /* StringExtension.swift */, A239F51E2157B72700576CBF /* StringExtension.swift */,
A2F4E21C1EED80160011986E /* UITextFieldExtension.swift */, A2F4E21C1EED80160011986E /* UITextFieldExtension.swift */,
@ -1149,6 +1155,7 @@
A2C532BB201E5A9600DB9F53 /* PasscodeLock.swift in Sources */, A2C532BB201E5A9600DB9F53 /* PasscodeLock.swift in Sources */,
A2F4E2151EED800F0011986E /* Password.swift in Sources */, A2F4E2151EED800F0011986E /* Password.swift in Sources */,
A26075AD1EEC7125005DB03E /* pass.xcdatamodeld in Sources */, A26075AD1EEC7125005DB03E /* pass.xcdatamodeld in Sources */,
30A1D29E21AF468F00E2D1F7 /* PasswordGeneratorFlavour.swift in Sources */,
A239F51F2157B72700576CBF /* StringExtension.swift in Sources */, A239F51F2157B72700576CBF /* StringExtension.swift in Sources */,
A239F5212157B75E00576CBF /* FileManagerExtension.swift in Sources */, A239F5212157B75E00576CBF /* FileManagerExtension.swift in Sources */,
A2F4E21E1EED80160011986E /* AppError.swift in Sources */, A2F4E21E1EED80160011986E /* AppError.swift in Sources */,
@ -1177,6 +1184,7 @@
30FD2F78214D9E0E005E0A92 /* ParserTest.swift in Sources */, 30FD2F78214D9E0E005E0A92 /* ParserTest.swift in Sources */,
30B04860209A5141001013CA /* PasswordTest.swift in Sources */, 30B04860209A5141001013CA /* PasswordTest.swift in Sources */,
301F6468216165290071A4CE /* ConstantsTest.swift in Sources */, 301F6468216165290071A4CE /* ConstantsTest.swift in Sources */,
30A1D29C21AF451E00E2D1F7 /* PasswordGeneratorFlavourTest.swift in Sources */,
A26075881EEC6F34005DB03E /* passKitTests.swift in Sources */, A26075881EEC6F34005DB03E /* passKitTests.swift in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;

View file

@ -33,7 +33,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
self.perform(#selector(postSearchNotification), with: nil, afterDelay: 0.4) self.perform(#selector(postSearchNotification), with: nil, afterDelay: 0.4)
} }
} }
Utils.initDefaultKeys()
return true return true
} }

View file

@ -20,8 +20,7 @@ class AddPasswordTableViewController: PasswordEditorTableViewController {
[[.type: PasswordEditorCellType.additionsCell, .title: "additions"]], [[.type: PasswordEditorCellType.additionsCell, .title: "additions"]],
[[.type: PasswordEditorCellType.scanQRCodeCell]] [[.type: PasswordEditorCellType.scanQRCodeCell]]
] ]
if let lengthSetting = Globals.passwordDefaultLength[SharedDefaults[.passwordGeneratorFlavor]], if PasswordGeneratorFlavour.from(SharedDefaults[.passwordGeneratorFlavor]) == PasswordGeneratorFlavour.RANDOM {
lengthSetting.max > lengthSetting.min {
tableData[1].append([.type: PasswordEditorCellType.passwordLengthCell, .title: "passwordlength"]) tableData[1].append([.type: PasswordEditorCellType.passwordLengthCell, .title: "passwordlength"])
} }
tableData[1].append([.type: PasswordEditorCellType.memorablePasswordGeneratorCell]) tableData[1].append([.type: PasswordEditorCellType.memorablePasswordGeneratorCell])

View file

@ -18,8 +18,7 @@ class EditPasswordTableViewController: PasswordEditorTableViewController {
[[.type: PasswordEditorCellType.scanQRCodeCell], [[.type: PasswordEditorCellType.scanQRCodeCell],
[.type: PasswordEditorCellType.deletePasswordCell]] [.type: PasswordEditorCellType.deletePasswordCell]]
] ]
if let lengthSetting = Globals.passwordDefaultLength[SharedDefaults[.passwordGeneratorFlavor]], if PasswordGeneratorFlavour.from(SharedDefaults[.passwordGeneratorFlavor]) == PasswordGeneratorFlavour.RANDOM {
lengthSetting.max > lengthSetting.min {
tableData[1].append([.type: PasswordEditorCellType.passwordLengthCell, .title: "passwordlength"]) tableData[1].append([.type: PasswordEditorCellType.passwordLengthCell, .title: "passwordlength"])
} }
tableData[1].append([.type: PasswordEditorCellType.memorablePasswordGeneratorCell]) tableData[1].append([.type: PasswordEditorCellType.memorablePasswordGeneratorCell])

View file

@ -104,11 +104,10 @@ class PasswordEditorTableViewController: UITableViewController, FillPasswordTabl
return fillPasswordCell! return fillPasswordCell!
case .passwordLengthCell: case .passwordLengthCell:
passwordLengthCell = tableView.dequeueReusableCell(withIdentifier: "passwordLengthCell", for: indexPath) as? SliderTableViewCell passwordLengthCell = tableView.dequeueReusableCell(withIdentifier: "passwordLengthCell", for: indexPath) as? SliderTableViewCell
let lengthSetting = Globals.passwordDefaultLength[SharedDefaults[.passwordGeneratorFlavor]] ?? let lengthSetting = PasswordGeneratorFlavour.from(SharedDefaults[.passwordGeneratorFlavor]).defaultLength
Globals.passwordDefaultLength["Random"] let minimumLength = lengthSetting.min
let minimumLength = lengthSetting?.min ?? 0 let maximumLength = lengthSetting.max
let maximumLength = lengthSetting?.max ?? 0 var defaultLength = lengthSetting.def
var defaultLength = lengthSetting?.def ?? 0
if let currentPasswordLength = (tableData[passwordSection][0][PasswordEditorCellKey.content] as? String)?.count, if let currentPasswordLength = (tableData[passwordSection][0][PasswordEditorCellKey.content] as? String)?.count,
currentPasswordLength >= minimumLength, currentPasswordLength >= minimumLength,
currentPasswordLength <= maximumLength { currentPasswordLength <= maximumLength {
@ -203,7 +202,7 @@ class PasswordEditorTableViewController: UITableViewController, FillPasswordTabl
showPasswordSettings() showPasswordSettings()
let length = passwordLengthCell?.roundedValue ?? 0 let length = passwordLengthCell?.roundedValue ?? 0
let plainPassword = Password.generatePassword(length: length) let plainPassword = PasswordGeneratorFlavour.from(SharedDefaults[.passwordGeneratorFlavor]).generatePassword(length: length)
SecurePasteboard.shared.copy(textToCopy: plainPassword) SecurePasteboard.shared.copy(textToCopy: plainPassword)
// update tableData so to make sure reloadData() works correctly // update tableData so to make sure reloadData() works correctly

View file

@ -39,9 +39,6 @@ public class Globals {
public static let iTunesFileSharingPGPPrivate = iTunesFileSharingPath + "/gpg_key" public static let iTunesFileSharingPGPPrivate = iTunesFileSharingPath + "/gpg_key"
public static let iTunesFileSharingSSHPrivate = iTunesFileSharingPath + "/ssh_key" public static let iTunesFileSharingSSHPrivate = iTunesFileSharingPath + "/ssh_key"
public static let passwordDefaultLength = ["Random": (min: 4, max: 64, def: 16),
"Apple": (min: 15, max: 15, def: 15)]
public static let gitSignatureDefaultName = "Pass for iOS" public static let gitSignatureDefaultName = "Pass for iOS"
public static let gitSignatureDefaultEmail = "user@passforios" public static let gitSignatureDefaultEmail = "user@passforios"

View file

@ -0,0 +1,44 @@
//
// PasswordGeneratorFlavour.swift
// passKit
//
// Created by Danny Moesch on 28.11.18.
// Copyright © 2018 Bob Sun. All rights reserved.
//
import KeychainAccess
public enum PasswordGeneratorFlavour: String {
case APPLE = "Apple"
case RANDOM = "Random"
private static let ALLOWED_CHARACTERS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*_+-="
public static func from(_ option: String) -> PasswordGeneratorFlavour {
return PasswordGeneratorFlavour(rawValue: option) ?? PasswordGeneratorFlavour.RANDOM
}
public var defaultLength: (min: Int, max: Int, def: Int) {
switch self {
case .APPLE:
return (15, 15, 15)
default:
return (4, 64, 16)
}
}
public func generatePassword(length: Int) -> String {
switch self {
case .APPLE:
return Keychain.generatePassword()
default:
return PasswordGeneratorFlavour.randomString(length: length)
}
}
private static func randomString(length: Int) -> String {
return String((0..<length).map { _ in ALLOWED_CHARACTERS.randomElement()! })
}
}
extension PasswordGeneratorFlavour: CaseIterable {}

View file

@ -53,11 +53,6 @@ public class Utils {
} }
return attributedPassword return attributedPassword
} }
public static func initDefaultKeys() {
if SharedDefaults[.passwordGeneratorFlavor] == "" {
SharedDefaults[.passwordGeneratorFlavor] = "Random"
}
}
public static func alert(title: String, message: String, controller: UIViewController, handler: ((UIAlertAction) -> Void)? = nil, completion: (() -> Void)? = nil) { public static func alert(title: String, message: String, controller: UIViewController, handler: ((UIAlertAction) -> Void)? = nil, completion: (() -> Void)? = nil) {
let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.alert) let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.alert)

View file

@ -9,7 +9,6 @@
import SwiftyUserDefaults import SwiftyUserDefaults
import OneTimePassword import OneTimePassword
import Base32 import Base32
import KeychainAccess
public class Password { public class Password {
@ -276,31 +275,4 @@ public class Password {
// get and return the password // get and return the password
return self.otpToken?.currentPassword return self.otpToken?.currentPassword
} }
public static func generatePassword(length: Int) -> String{
switch SharedDefaults[.passwordGeneratorFlavor] {
case "Random":
return randomString(length: length)
case "Apple":
return Keychain.generatePassword()
default:
return randomString(length: length)
}
}
private static func randomString(length: Int) -> String {
let letters : NSString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*_+-="
let len = UInt32(letters.length)
var randomString = ""
for _ in 0 ..< length {
let rand = arc4random_uniform(len)
var nextChar = letters.character(at: Int(rand))
randomString += NSString(characters: &nextChar, length: 1) as String
}
return randomString
}
} }

View file

@ -0,0 +1,43 @@
//
// PasswordGeneratorFlavourTest.swift
// passKitTests
//
// Created by Danny Moesch on 28.11.18.
// Copyright © 2018 Bob Sun. All rights reserved.
//
import KeychainAccess
import XCTest
@testable import passKit
class PasswordGeneratorFlavourTest: XCTestCase {
private let KEYCHAIN_PASSWORD_LENGTH = Keychain.generatePassword().count
func testFrom() {
XCTAssertEqual(PasswordGeneratorFlavour.from("Apple"), PasswordGeneratorFlavour.APPLE)
XCTAssertEqual(PasswordGeneratorFlavour.from("Random"), PasswordGeneratorFlavour.RANDOM)
XCTAssertEqual(PasswordGeneratorFlavour.from("Something"), PasswordGeneratorFlavour.RANDOM)
XCTAssertEqual(PasswordGeneratorFlavour.from(""), PasswordGeneratorFlavour.RANDOM)
}
func testDefaultLength() {
// Ensure properly chosen default length values. So this check no longer needs to be performed in the code.
PasswordGeneratorFlavour.allCases.map { $0.defaultLength }.forEach { defaultLength in
XCTAssertLessThanOrEqual(defaultLength.min, defaultLength.max)
XCTAssertLessThanOrEqual(defaultLength.def, defaultLength.max)
XCTAssertGreaterThanOrEqual(defaultLength.def, defaultLength.min)
}
}
func testGeneratePassword() {
let apple = PasswordGeneratorFlavour.APPLE
let random = PasswordGeneratorFlavour.RANDOM
XCTAssertEqual(apple.generatePassword(length: 4).count, KEYCHAIN_PASSWORD_LENGTH)
XCTAssertEqual(random.generatePassword(length: 0).count, 0)
XCTAssertEqual(random.generatePassword(length: 4).count, 4)
XCTAssertEqual(random.generatePassword(length: 100).count, 100)
}
}