From 3d2c3e7c47cdbf98479716aed424017faef54d47 Mon Sep 17 00:00:00 2001 From: Matt Rubin Date: Sat, 28 Apr 2018 10:54:35 -0400 Subject: [PATCH 1/4] Ignore un-deserializable tokens when getting allPersistentTokens() --- Sources/Keychain.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Sources/Keychain.swift b/Sources/Keychain.swift index e84a1a09..cd82da47 100644 --- a/Sources/Keychain.swift +++ b/Sources/Keychain.swift @@ -47,7 +47,8 @@ public final class Keychain { /// /// - throws: A `Keychain.Error` if an error occurred. public func allPersistentTokens() throws -> Set { - return Set(try allKeychainItems().map(PersistentToken.init(keychainDictionary:))) + let allItems = try allKeychainItems() + return Set(allItems.flatMap({ try? PersistentToken.init(keychainDictionary:$0) })) } // MARK: Write From c14a295bd17cddd4ddafc2e76927b40a4a8ff841 Mon Sep 17 00:00:00 2001 From: Matt Rubin Date: Sun, 29 Apr 2018 10:58:55 -0400 Subject: [PATCH 2/4] Add comments and fix tests --- Sources/Keychain.swift | 4 ++++ Tests/KeychainTests.swift | 12 ++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/Sources/Keychain.swift b/Sources/Keychain.swift index cd82da47..ff1637b8 100644 --- a/Sources/Keychain.swift +++ b/Sources/Keychain.swift @@ -48,6 +48,10 @@ public final class Keychain { /// - throws: A `Keychain.Error` if an error occurred. public func allPersistentTokens() throws -> Set { let allItems = try allKeychainItems() + // This code intentionally ignores items which fail deserialization, instead opting to return as many readable + // tokens as possible. + // TODO: Restore deserialization error handling, in a way that provides info on the failure reason and allows + // the caller to choose whether to fail completely or recover some data. return Set(allItems.flatMap({ try? PersistentToken.init(keychainDictionary:$0) })) } diff --git a/Tests/KeychainTests.swift b/Tests/KeychainTests.swift index c2068368..5d90daa1 100644 --- a/Tests/KeychainTests.swift +++ b/Tests/KeychainTests.swift @@ -231,7 +231,8 @@ class KeychainTests: XCTestCase { let persistentRef = try addKeychainItem(withAttributes: keychainAttributes) XCTAssertThrowsError(try keychain.persistentToken(withIdentifier: persistentRef)) - XCTAssertThrowsError(try keychain.allPersistentTokens()) + // TODO: Restore deserialization error handling in allPersistentTokens() +// XCTAssertThrowsError(try keychain.allPersistentTokens()) XCTAssertNoThrow(try deleteKeychainItem(forPersistentRef: persistentRef), "Failed to delete the test token from the keychain. This may cause future test runs to fail.") @@ -247,7 +248,8 @@ class KeychainTests: XCTestCase { let persistentRef = try addKeychainItem(withAttributes: keychainAttributes) XCTAssertThrowsError(try keychain.persistentToken(withIdentifier: persistentRef)) - XCTAssertThrowsError(try keychain.allPersistentTokens()) + // TODO: Restore deserialization error handling in allPersistentTokens() +// XCTAssertThrowsError(try keychain.allPersistentTokens()) XCTAssertNoThrow(try deleteKeychainItem(forPersistentRef: persistentRef), "Failed to delete the test token from the keychain. This may cause future test runs to fail.") @@ -264,7 +266,8 @@ class KeychainTests: XCTestCase { let persistentRef = try addKeychainItem(withAttributes: keychainAttributes) XCTAssertThrowsError(try keychain.persistentToken(withIdentifier: persistentRef)) - XCTAssertThrowsError(try keychain.allPersistentTokens()) + // TODO: Restore deserialization error handling in allPersistentTokens() +// XCTAssertThrowsError(try keychain.allPersistentTokens()) XCTAssertNoThrow(try deleteKeychainItem(forPersistentRef: persistentRef), "Failed to delete the test token from the keychain. This may cause future test runs to fail.") @@ -281,7 +284,8 @@ class KeychainTests: XCTestCase { let persistentRef = try addKeychainItem(withAttributes: keychainAttributes) XCTAssertThrowsError(try keychain.persistentToken(withIdentifier: persistentRef)) - XCTAssertThrowsError(try keychain.allPersistentTokens()) + // TODO: Restore deserialization error handling in allPersistentTokens() +// XCTAssertThrowsError(try keychain.allPersistentTokens()) XCTAssertNoThrow(try deleteKeychainItem(forPersistentRef: persistentRef), "Failed to delete the test token from the keychain. This may cause future test runs to fail.") From ee0d5cb8650b48c9bfceb04aa04112637c8799f3 Mon Sep 17 00:00:00 2001 From: Matt Rubin Date: Sun, 29 Apr 2018 11:11:56 -0400 Subject: [PATCH 3/4] Bump the version number to 3.1.3 --- OneTimePassword.podspec | 2 +- Sources/Info.plist | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/OneTimePassword.podspec b/OneTimePassword.podspec index f988c7b4..0d0fc894 100644 --- a/OneTimePassword.podspec +++ b/OneTimePassword.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "OneTimePassword" - s.version = "3.1.2" + s.version = "3.1.3" s.summary = "A small library for generating TOTP and HOTP one-time passwords." s.homepage = "https://github.com/mattrubin/OneTimePassword" s.license = "MIT" diff --git a/Sources/Info.plist b/Sources/Info.plist index ba9f4e86..fa3725f0 100644 --- a/Sources/Info.plist +++ b/Sources/Info.plist @@ -15,11 +15,11 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 3.1.2 + 3.1.3 CFBundleSignature ???? CFBundleVersion - 3.1.2 + 3.1.3 NSPrincipalClass From 4515cfd3ebe276957f45b431fc80931fe6709e9a Mon Sep 17 00:00:00 2001 From: Matt Rubin Date: Sun, 29 Apr 2018 11:15:21 -0400 Subject: [PATCH 4/4] Update the changelog --- CHANGELOG.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7bb13ec3..775cc84c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ +## [3.1.3][] (2018-04-29) +- Ignore un-deserializable tokens in `allPersistentTokens()`. ([#179](https://github.com/mattrubin/OneTimePassword/pull/179)) + + ## [3.1.2][] (2018-04-23) - Synthesize Equatable conformance when compiling with Swift 4.1. ([#173](https://github.com/mattrubin/OneTimePassword/pull/173)) - Fix a warning about deprecation of cross-module struct initializers by simplifying test cases for impossible-to-create invalid Generators. ([#174](https://github.com/mattrubin/OneTimePassword/pull/174)) @@ -155,8 +159,9 @@ Changes between prerelease versions of OneTimePassword version 2 can be found be ## [1.0.0][] (2014-07-17) -[develop]: https://github.com/mattrubin/OneTimePassword/compare/3.1.2...develop +[develop]: https://github.com/mattrubin/OneTimePassword/compare/3.1.3...develop +[3.1.3]: https://github.com/mattrubin/OneTimePassword/compare/3.1.2...3.1.3 [3.1.2]: https://github.com/mattrubin/OneTimePassword/compare/3.1.1...3.1.2 [3.1.1]: https://github.com/mattrubin/OneTimePassword/compare/3.1...3.1.1 [3.1]: https://github.com/mattrubin/OneTimePassword/compare/3.0.1...3.1