Files
OpenVPNAdapter/Carthage/Checkouts/KeychainAccess/Lib/KeychainAccessTests/KeychainAccessTests.swift
2017-03-06 21:24:37 +03:00

1476 lines
66 KiB
Swift

//
// KeychainAccessTests.swift
// KeychainAccessTests
//
// Created by kishikawa katsumi on 2014/12/24.
// Copyright (c) 2014 kishikawa katsumi. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
import Foundation
import XCTest
import KeychainAccess
class KeychainAccessTests: XCTestCase {
override func setUp() {
super.setUp()
do { try Keychain(service: "Twitter", accessGroup: "27AEDK3C9F.shared").removeAll() } catch {}
do { try Keychain(service: "Twitter").removeAll() } catch {}
do { try Keychain(server: URL(string: "https://example.com")!, protocolType: .https).removeAll() } catch {}
do { try Keychain(server: URL(string: "https://example.com:443")!, protocolType: .https).removeAll() } catch {}
do { try Keychain().removeAll() } catch {}
}
override func tearDown() {
super.tearDown()
}
// MARK:
func testGenericPassword() {
do {
// Add Keychain items
let keychain = Keychain(service: "Twitter")
do { try keychain.set("kishikawa_katsumi", key: "username") } catch {}
do { try keychain.set("password_1234", key: "password") } catch {}
let username = try! keychain.get("username")
XCTAssertEqual(username, "kishikawa_katsumi")
let password = try! keychain.get("password")
XCTAssertEqual(password, "password_1234")
}
do {
// Update Keychain items
let keychain = Keychain(service: "Twitter")
do { try keychain.set("katsumi_kishikawa", key: "username") } catch {}
do { try keychain.set("1234_password", key: "password") } catch {}
let username = try! keychain.get("username")
XCTAssertEqual(username, "katsumi_kishikawa")
let password = try! keychain.get("password")
XCTAssertEqual(password, "1234_password")
}
do {
// Remove Keychain items
let keychain = Keychain(service: "Twitter")
do { try keychain.remove("username") } catch {}
do { try keychain.remove("password") } catch {}
XCTAssertNil(try! keychain.get("username"))
XCTAssertNil(try! keychain.get("password"))
}
}
func testGenericPasswordSubscripting() {
do {
// Add Keychain items
let keychain = Keychain(service: "Twitter", accessGroup: "27AEDK3C9F.shared")
keychain["username"] = "kishikawa_katsumi"
keychain["password"] = "password_1234"
let username = keychain["username"]
XCTAssertEqual(username, "kishikawa_katsumi")
let password = keychain["password"]
XCTAssertEqual(password, "password_1234")
}
do {
// Update Keychain items
let keychain = Keychain(service: "Twitter", accessGroup: "27AEDK3C9F.shared")
keychain["username"] = "katsumi_kishikawa"
keychain["password"] = "1234_password"
let username = keychain["username"]
XCTAssertEqual(username, "katsumi_kishikawa")
let password = keychain["password"]
XCTAssertEqual(password, "1234_password")
}
do {
// Remove Keychain items
let keychain = Keychain(service: "Twitter", accessGroup: "27AEDK3C9F.shared")
keychain["username"] = nil
keychain["password"] = nil
XCTAssertNil(keychain["username"])
XCTAssertNil(keychain["password"])
}
}
// MARK:
func testInternetPassword() {
do {
// Add Keychain items
let keychain = Keychain(server: URL(string: "https://kishikawakatsumi.com")!, protocolType: .https)
do { try keychain.set("kishikawa_katsumi", key: "username") } catch {}
do { try keychain.set("password_1234", key: "password") } catch {}
let username = try! keychain.get("username")
XCTAssertEqual(username, "kishikawa_katsumi")
let password = try! keychain.get("password")
XCTAssertEqual(password, "password_1234")
}
do {
// Update Keychain items
let keychain = Keychain(server: URL(string: "https://kishikawakatsumi.com")!, protocolType: .https)
do { try keychain.set("katsumi_kishikawa", key: "username") } catch {}
do { try keychain.set("1234_password", key: "password") } catch {}
let username = try! keychain.get("username")
XCTAssertEqual(username, "katsumi_kishikawa")
let password = try! keychain.get("password")
XCTAssertEqual(password, "1234_password")
}
do {
// Remove Keychain items
let keychain = Keychain(server: URL(string: "https://kishikawakatsumi.com")!, protocolType: .https)
do { try keychain.remove("username") } catch {}
do { try keychain.remove("password") } catch {}
XCTAssertNil(try! keychain.get("username"))
XCTAssertNil(try! keychain.get("password"))
}
}
func testInternetPasswordSubscripting() {
do {
// Add Keychain items
let keychain = Keychain(server: URL(string: "https://kishikawakatsumi.com")!, protocolType: .https)
keychain["username"] = "kishikawa_katsumi"
keychain["password"] = "password_1234"
let username = keychain["username"]
XCTAssertEqual(username, "kishikawa_katsumi")
let password = keychain["password"]
XCTAssertEqual(password, "password_1234")
}
do {
// Update Keychain items
let keychain = Keychain(server: URL(string: "https://kishikawakatsumi.com")!, protocolType: .https)
keychain["username"] = "katsumi_kishikawa"
keychain["password"] = "1234_password"
let username = keychain["username"]
XCTAssertEqual(username, "katsumi_kishikawa")
let password = keychain["password"]
XCTAssertEqual(password, "1234_password")
}
do {
// Remove Keychain items
let keychain = Keychain(server: URL(string: "https://kishikawakatsumi.com")!, protocolType: .https)
keychain["username"] = nil
keychain["password"] = nil
XCTAssertNil(keychain["username"])
XCTAssertNil(keychain["password"])
}
}
// MARK:
func testDefaultInitializer() {
let keychain = Keychain()
XCTAssertEqual(keychain.service, Bundle.main.bundleIdentifier)
XCTAssertEqual(keychain.service, "com.kishikawakatsumi.KeychainAccess.TestHost")
XCTAssertNil(keychain.accessGroup)
}
func testInitializerWithService() {
let keychain = Keychain(service: "com.example.github-token")
XCTAssertEqual(keychain.service, "com.example.github-token")
XCTAssertNil(keychain.accessGroup)
}
func testInitializerWithAccessGroup() {
let keychain = Keychain(accessGroup: "27AEDK3C9F.shared")
XCTAssertEqual(keychain.service, "com.kishikawakatsumi.KeychainAccess.TestHost")
XCTAssertEqual(keychain.accessGroup, "27AEDK3C9F.shared")
}
func testInitializerWithServiceAndAccessGroup() {
let keychain = Keychain(service: "com.example.github-token", accessGroup: "27AEDK3C9F.shared")
XCTAssertEqual(keychain.service, "com.example.github-token")
XCTAssertEqual(keychain.accessGroup, "27AEDK3C9F.shared")
}
func testInitializerWithServer() {
let server = "https://kishikawakatsumi.com"
let url = URL(string: server)!
do {
let keychain = Keychain(server: server, protocolType: .https)
XCTAssertEqual(keychain.server, url)
XCTAssertEqual(keychain.protocolType, ProtocolType.https)
XCTAssertEqual(keychain.authenticationType, AuthenticationType.default)
}
do {
let keychain = Keychain(server: url, protocolType: .https)
XCTAssertEqual(keychain.server, url)
XCTAssertEqual(keychain.protocolType, ProtocolType.https)
XCTAssertEqual(keychain.authenticationType, AuthenticationType.default)
}
}
func testInitializerWithServerAndAuthenticationType() {
let server = "https://kishikawakatsumi.com"
let url = URL(string: server)!
do {
let keychain = Keychain(server: server, protocolType: .https, authenticationType: .htmlForm)
XCTAssertEqual(keychain.server, url)
XCTAssertEqual(keychain.protocolType, ProtocolType.https)
XCTAssertEqual(keychain.authenticationType, AuthenticationType.htmlForm)
}
do {
let keychain = Keychain(server: url, protocolType: .https, authenticationType: .htmlForm)
XCTAssertEqual(keychain.server, url)
XCTAssertEqual(keychain.protocolType, ProtocolType.https)
XCTAssertEqual(keychain.authenticationType, AuthenticationType.htmlForm)
}
}
// MARK:
func testContains() {
let keychain = Keychain(service: "Twitter")
XCTAssertFalse(try! keychain.contains("username"), "not stored username")
XCTAssertFalse(try! keychain.contains("password"), "not stored password")
do { try keychain.set("kishikawakatsumi", key: "username") } catch {}
XCTAssertTrue(try! keychain.contains("username"), "stored username")
XCTAssertFalse(try! keychain.contains("password"), "not stored password")
do { try keychain.set("password1234", key: "password") } catch {}
XCTAssertTrue(try! keychain.contains("username"), "stored username")
XCTAssertTrue(try! keychain.contains("password"), "stored password")
}
// MARK:
func testSetString() {
let keychain = Keychain(service: "Twitter")
XCTAssertNil(try! keychain.get("username"), "not stored username")
XCTAssertNil(try! keychain.get("password"), "not stored password")
do { try keychain.set("kishikawakatsumi", key: "username") } catch {}
XCTAssertEqual(try! keychain.get("username"), "kishikawakatsumi", "stored username")
XCTAssertNil(try! keychain.get("password"), "not stored password")
do { try keychain.set("password1234", key: "password") } catch {}
XCTAssertEqual(try! keychain.get("username"), "kishikawakatsumi", "stored username")
XCTAssertEqual(try! keychain.get("password"), "password1234", "stored password")
}
func testSetStringWithLabel() {
let keychain = Keychain(service: "Twitter")
.label("Twitter Account")
XCTAssertNil(keychain["kishikawakatsumi"], "not stored password")
do {
let label = try keychain.get("kishikawakatsumi") { (attributes) -> String? in
return attributes?.label
}
XCTAssertNil(label)
} catch {
XCTFail("error occurred")
}
keychain["kishikawakatsumi"] = "password1234"
XCTAssertEqual(keychain["kishikawakatsumi"], "password1234", "stored password")
do {
let label = try keychain.get("kishikawakatsumi") { (attributes) -> String? in
return attributes?.label
}
XCTAssertEqual(label, "Twitter Account")
} catch {
XCTFail("error occurred")
}
}
func testSetStringWithComment() {
let keychain = Keychain(service: "Twitter")
.comment("Kishikawa Katsumi")
XCTAssertNil(keychain["kishikawakatsumi"], "not stored password")
do {
let comment = try keychain.get("kishikawakatsumi") { (attributes) -> String? in
return attributes?.comment
}
XCTAssertNil(comment)
} catch {
XCTFail("error occurred")
}
keychain["kishikawakatsumi"] = "password1234"
XCTAssertEqual(keychain["kishikawakatsumi"], "password1234", "stored password")
do {
let comment = try keychain.get("kishikawakatsumi") { (attributes) -> String? in
return attributes?.comment
}
XCTAssertEqual(comment, "Kishikawa Katsumi")
} catch {
XCTFail("error occurred")
}
}
func testSetStringWithLabelAndComment() {
let keychain = Keychain(service: "Twitter")
.label("Twitter Account")
.comment("Kishikawa Katsumi")
XCTAssertNil(keychain["kishikawakatsumi"], "not stored password")
do {
let label = try keychain.get("kishikawakatsumi") { (attributes) -> String? in
return attributes?.label
}
XCTAssertNil(label)
let comment = try keychain.get("kishikawakatsumi") { (attributes) -> String? in
return attributes?.comment
}
XCTAssertNil(comment)
} catch {
XCTFail("error occurred")
}
keychain["kishikawakatsumi"] = "password1234"
XCTAssertEqual(keychain["kishikawakatsumi"], "password1234", "stored password")
do {
let label = try keychain.get("kishikawakatsumi") { (attributes) -> String? in
return attributes?.label
}
XCTAssertEqual(label, "Twitter Account")
let comment = try keychain.get("kishikawakatsumi") { (attributes) -> String? in
return attributes?.comment
}
XCTAssertEqual(comment, "Kishikawa Katsumi")
} catch {
XCTFail("error occurred")
}
}
func testSetData() {
let JSONObject = ["username": "kishikawakatsumi", "password": "password1234"]
let JSONData = try! JSONSerialization.data(withJSONObject: JSONObject, options: [])
let keychain = Keychain(service: "Twitter")
XCTAssertNil(try! keychain.getData("JSONData"), "not stored JSON data")
do { try keychain.set(JSONData, key: "JSONData") } catch {}
XCTAssertEqual(try! keychain.getData("JSONData"), JSONData, "stored JSON data")
}
func testStringConversionError() {
let keychain = Keychain(service: "Twitter")
let length = 256
let data = NSMutableData(length: length)!
let bytes = data.mutableBytes.bindMemory(to: UInt8.self, capacity: length)
_ = SecRandomCopyBytes(kSecRandomDefault, length, bytes)
do {
try keychain.set(data as Data, key: "RandomData")
let _ = try keychain.getString("RandomData")
XCTFail("no error occurred")
} catch let error as NSError {
XCTAssertEqual(error.domain, KeychainAccessErrorDomain)
XCTAssertEqual(error.code, Int(Status.conversionError.rawValue))
XCTAssertEqual(error.userInfo[NSLocalizedDescriptionKey] as! String, Status.conversionError.localizedDescription)
} catch {
XCTFail("unexpected error occurred")
}
do {
try keychain.set(data as Data, key: "RandomData")
let _ = try keychain.getString("RandomData")
XCTFail("no error occurred")
} catch Status.conversionError {
XCTAssertTrue(true)
} catch {
XCTFail("unexpected error occurred")
}
}
func testGetPersistentRef() {
let keychain = Keychain(service: "Twitter")
XCTAssertNil(keychain["kishikawakatsumi"], "not stored password")
do {
let persistentRef = try keychain.get("kishikawakatsumi") { $0?.persistentRef }
XCTAssertNil(persistentRef)
} catch {
XCTFail("error occurred")
}
keychain["kishikawakatsumi"] = "password1234"
XCTAssertEqual(keychain["kishikawakatsumi"], "password1234", "stored password")
do {
let persistentRef = try keychain.get("kishikawakatsumi") { $0?.persistentRef }
XCTAssertNotNil(persistentRef)
} catch {
XCTFail("error occurred")
}
}
#if os(iOS) || os(tvOS)
func testSetAttributes() {
let expectation = self.expectation(description: "Touch ID authentication")
DispatchQueue.global(qos: .default).async {
do {
var attributes = [String: Any]()
attributes[String(kSecAttrDescription)] = "Description Test"
attributes[String(kSecAttrComment)] = "Comment Test"
attributes[String(kSecAttrCreator)] = "Creator Test"
attributes[String(kSecAttrType)] = "Type Test"
attributes[String(kSecAttrLabel)] = "Label Test"
attributes[String(kSecAttrIsInvisible)] = true
attributes[String(kSecAttrIsNegative)] = true
let keychain = Keychain(service: "Twitter")
.attributes(attributes)
.accessibility(.whenPasscodeSetThisDeviceOnly, authenticationPolicy: .userPresence)
XCTAssertNil(keychain["kishikawakatsumi"], "not stored password")
do {
let attributes = try keychain.get("kishikawakatsumi") { $0 }
XCTAssertNil(attributes)
} catch {
XCTFail("error occurred")
}
keychain["kishikawakatsumi"] = "password1234"
XCTAssertEqual(keychain["kishikawakatsumi"], "password1234", "stored password")
do {
let attributes = try keychain.get("kishikawakatsumi") { $0 }
XCTAssertEqual(attributes?.`class`, ItemClass.genericPassword.rawValue)
XCTAssertEqual(attributes?.data, "password1234".data(using: .utf8))
XCTAssertNil(attributes?.ref)
XCTAssertNotNil(attributes?.persistentRef)
XCTAssertEqual(attributes?.accessible, Accessibility.whenPasscodeSetThisDeviceOnly.rawValue)
XCTAssertNotNil(attributes?.accessControl)
XCTAssertEqual(attributes?.accessGroup, "27AEDK3C9F.com.kishikawakatsumi.KeychainAccess.TestHost")
XCTAssertNotNil(attributes?.synchronizable)
XCTAssertNotNil(attributes?.creationDate)
XCTAssertNotNil(attributes?.modificationDate)
XCTAssertEqual(attributes?.attributeDescription, "Description Test")
XCTAssertEqual(attributes?.comment, "Comment Test")
XCTAssertEqual(attributes?.creator, "Creator Test")
XCTAssertEqual(attributes?.type, "Type Test")
XCTAssertEqual(attributes?.label, "Label Test")
XCTAssertEqual(attributes?.isInvisible, true)
XCTAssertEqual(attributes?.isNegative, true)
XCTAssertEqual(attributes?.account, "kishikawakatsumi")
XCTAssertEqual(attributes?.service, "Twitter")
XCTAssertNil(attributes?.generic)
XCTAssertNil(attributes?.securityDomain)
XCTAssertNil(attributes?.server)
XCTAssertNil(attributes?.`protocol`)
XCTAssertNil(attributes?.authenticationType)
XCTAssertNil(attributes?.port)
XCTAssertNil(attributes?.path)
XCTAssertEqual(attributes![String(kSecClass)] as? String, ItemClass.genericPassword.rawValue)
XCTAssertEqual(attributes![String(kSecValueData)] as? Data, "password1234".data(using: .utf8))
expectation.fulfill()
} catch {
XCTFail("error occurred")
}
}
}
waitForExpectations(timeout: 10.0, handler: nil)
do {
var attributes = [String: Any]()
attributes[String(kSecAttrDescription)] = "Description Test"
attributes[String(kSecAttrComment)] = "Comment Test"
attributes[String(kSecAttrCreator)] = "Creator Test"
attributes[String(kSecAttrType)] = "Type Test"
attributes[String(kSecAttrLabel)] = "Label Test"
attributes[String(kSecAttrIsInvisible)] = true
attributes[String(kSecAttrIsNegative)] = true
attributes[String(kSecAttrSecurityDomain)] = "securitydomain"
let keychain = Keychain(server: URL(string: "https://example.com:443/api/login/")!, protocolType: .https)
.attributes(attributes)
XCTAssertNil(keychain["kishikawakatsumi"], "not stored password")
do {
let attributes = try keychain.get("kishikawakatsumi") { $0 }
XCTAssertNil(attributes)
} catch {
XCTFail("error occurred")
}
do {
keychain["kishikawakatsumi"] = "password1234"
XCTAssertEqual(keychain["kishikawakatsumi"], "password1234", "stored password")
let attributes = try keychain.get("kishikawakatsumi") { $0 }
XCTAssertEqual(attributes?.`class`, ItemClass.internetPassword.rawValue)
XCTAssertEqual(attributes?.data, "password1234".data(using: .utf8))
XCTAssertNil(attributes?.ref)
XCTAssertNotNil(attributes?.persistentRef)
XCTAssertEqual(attributes?.accessible, Accessibility.afterFirstUnlock.rawValue)
if #available(iOS 9.0, *) {
XCTAssertNil(attributes?.accessControl)
} else {
XCTAssertNotNil(attributes?.accessControl)
}
XCTAssertEqual(attributes?.accessGroup, "27AEDK3C9F.com.kishikawakatsumi.KeychainAccess.TestHost")
XCTAssertNotNil(attributes?.synchronizable)
XCTAssertNotNil(attributes?.creationDate)
XCTAssertNotNil(attributes?.modificationDate)
XCTAssertEqual(attributes?.attributeDescription, "Description Test")
XCTAssertEqual(attributes?.comment, "Comment Test")
XCTAssertEqual(attributes?.creator, "Creator Test")
XCTAssertEqual(attributes?.type, "Type Test")
XCTAssertEqual(attributes?.label, "Label Test")
XCTAssertEqual(attributes?.isInvisible, true)
XCTAssertEqual(attributes?.isNegative, true)
XCTAssertEqual(attributes?.account, "kishikawakatsumi")
XCTAssertNil(attributes?.service)
XCTAssertNil(attributes?.generic)
XCTAssertEqual(attributes?.securityDomain, "securitydomain")
XCTAssertEqual(attributes?.server, "example.com")
XCTAssertEqual(attributes?.`protocol`, ProtocolType.https.rawValue)
XCTAssertEqual(attributes?.authenticationType, AuthenticationType.default.rawValue)
XCTAssertEqual(attributes?.port, 443)
XCTAssertEqual(attributes?.path, "")
} catch {
XCTFail("error occurred")
}
do {
let keychain = Keychain(server: URL(string: "https://example.com:443/api/login/")!, protocolType: .https)
XCTAssertEqual(keychain["kishikawakatsumi"], "password1234", "stored password")
keychain["kishikawakatsumi"] = "1234password"
XCTAssertEqual(keychain["kishikawakatsumi"], "1234password", "updated password")
let attributes = try keychain.get("kishikawakatsumi") { $0 }
XCTAssertEqual(attributes?.`class`, ItemClass.internetPassword.rawValue)
XCTAssertEqual(attributes?.data, "1234password".data(using: .utf8))
XCTAssertNil(attributes?.ref)
XCTAssertNotNil(attributes?.persistentRef)
XCTAssertEqual(attributes?.accessible, Accessibility.afterFirstUnlock.rawValue)
if #available(iOS 9.0, *) {
XCTAssertNil(attributes?.accessControl)
} else {
XCTAssertNotNil(attributes?.accessControl)
}
XCTAssertEqual(attributes?.accessGroup, "27AEDK3C9F.com.kishikawakatsumi.KeychainAccess.TestHost")
XCTAssertNotNil(attributes?.synchronizable)
XCTAssertNotNil(attributes?.creationDate)
XCTAssertNotNil(attributes?.modificationDate)
XCTAssertEqual(attributes?.attributeDescription, "Description Test")
XCTAssertEqual(attributes?.comment, "Comment Test")
XCTAssertEqual(attributes?.creator, "Creator Test")
XCTAssertEqual(attributes?.type, "Type Test")
XCTAssertEqual(attributes?.label, "Label Test")
XCTAssertEqual(attributes?.isInvisible, true)
XCTAssertEqual(attributes?.isNegative, true)
XCTAssertEqual(attributes?.account, "kishikawakatsumi")
XCTAssertNil(attributes?.service)
XCTAssertNil(attributes?.generic)
XCTAssertEqual(attributes?.securityDomain, "securitydomain")
XCTAssertEqual(attributes?.server, "example.com")
XCTAssertEqual(attributes?.`protocol`, ProtocolType.https.rawValue)
XCTAssertEqual(attributes?.authenticationType, AuthenticationType.default.rawValue)
XCTAssertEqual(attributes?.port, 443)
XCTAssertEqual(attributes?.path, "")
} catch {
XCTFail("error occurred")
}
do {
let keychain = Keychain(server: URL(string: "https://example.com:443/api/login/")!, protocolType: .https)
.attributes([String(kSecAttrDescription): "Updated Description"])
XCTAssertEqual(keychain["kishikawakatsumi"], "1234password", "stored password")
keychain["kishikawakatsumi"] = "password1234"
XCTAssertEqual(keychain["kishikawakatsumi"], "password1234", "updated password")
let attributes = keychain[attributes: "kishikawakatsumi"]
XCTAssertEqual(attributes?.`class`, ItemClass.internetPassword.rawValue)
XCTAssertEqual(attributes?.data, "password1234".data(using: .utf8))
XCTAssertNil(attributes?.ref)
XCTAssertNotNil(attributes?.persistentRef)
XCTAssertEqual(attributes?.accessible, Accessibility.afterFirstUnlock.rawValue)
if #available(iOS 9.0, *) {
XCTAssertNil(attributes?.accessControl)
} else {
XCTAssertNotNil(attributes?.accessControl)
}
XCTAssertEqual(attributes?.accessGroup, "27AEDK3C9F.com.kishikawakatsumi.KeychainAccess.TestHost")
XCTAssertNotNil(attributes?.synchronizable)
XCTAssertNotNil(attributes?.creationDate)
XCTAssertNotNil(attributes?.modificationDate)
XCTAssertEqual(attributes?.attributeDescription, "Updated Description")
XCTAssertEqual(attributes?.comment, "Comment Test")
XCTAssertEqual(attributes?.creator, "Creator Test")
XCTAssertEqual(attributes?.type, "Type Test")
XCTAssertEqual(attributes?.label, "Label Test")
XCTAssertEqual(attributes?.isInvisible, true)
XCTAssertEqual(attributes?.isNegative, true)
XCTAssertEqual(attributes?.account, "kishikawakatsumi")
XCTAssertNil(attributes?.service)
XCTAssertNil(attributes?.generic)
XCTAssertEqual(attributes?.securityDomain, "securitydomain")
XCTAssertEqual(attributes?.server, "example.com")
XCTAssertEqual(attributes?.`protocol`, ProtocolType.https.rawValue)
XCTAssertEqual(attributes?.authenticationType, AuthenticationType.default.rawValue)
XCTAssertEqual(attributes?.port, 443)
XCTAssertEqual(attributes?.path, "")
}
}
}
#endif
func testRemoveString() {
let keychain = Keychain(service: "Twitter")
XCTAssertNil(try! keychain.get("username"), "not stored username")
XCTAssertNil(try! keychain.get("password"), "not stored password")
do { try keychain.set("kishikawakatsumi", key: "username") } catch {}
XCTAssertEqual(try! keychain.get("username"), "kishikawakatsumi", "stored username")
do { try keychain.set("password1234", key: "password") } catch {}
XCTAssertEqual(try! keychain.get("password"), "password1234", "stored password")
do { try keychain.remove("username") } catch {}
XCTAssertNil(try! keychain.get("username"), "removed username")
XCTAssertEqual(try! keychain.get("password"), "password1234", "left password")
do { try keychain.remove("password") } catch {}
XCTAssertNil(try! keychain.get("username"), "removed username")
XCTAssertNil(try! keychain.get("password"), "removed password")
}
func testRemoveData() {
let JSONObject = ["username": "kishikawakatsumi", "password": "password1234"]
let JSONData = try! JSONSerialization.data(withJSONObject: JSONObject, options: [])
let keychain = Keychain(service: "Twitter")
XCTAssertNil(try! keychain.getData("JSONData"), "not stored JSON data")
do { try keychain.set(JSONData, key: "JSONData") } catch {}
XCTAssertEqual(try! keychain.getData("JSONData"), JSONData, "stored JSON data")
do { try keychain.remove("JSONData") } catch {}
XCTAssertNil(try! keychain.getData("JSONData"), "removed JSON data")
}
// MARK:
func testSubscripting() {
let keychain = Keychain(service: "Twitter")
XCTAssertNil(keychain["username"], "not stored username")
XCTAssertNil(keychain["password"], "not stored password")
XCTAssertNil(keychain[string: "username"], "not stored username")
XCTAssertNil(keychain[string: "password"], "not stored password")
keychain["username"] = "kishikawakatsumi"
XCTAssertEqual(keychain["username"], "kishikawakatsumi", "stored username")
XCTAssertEqual(keychain[string: "username"], "kishikawakatsumi", "stored username")
keychain["password"] = "password1234"
XCTAssertEqual(keychain["password"], "password1234", "stored password")
XCTAssertEqual(keychain[string: "password"], "password1234", "stored password")
keychain[string: "username"] = nil
XCTAssertNil(keychain["username"], "removed username")
XCTAssertEqual(keychain["password"], "password1234", "left password")
XCTAssertNil(keychain[string: "username"], "removed username")
XCTAssertEqual(keychain[string: "password"], "password1234", "left password")
keychain[string: "password"] = nil
XCTAssertNil(keychain["username"], "removed username")
XCTAssertNil(keychain["password"], "removed password")
XCTAssertNil(keychain[string: "username"], "removed username")
XCTAssertNil(keychain[string: "password"], "removed password")
let JSONObject = ["username": "kishikawakatsumi", "password": "password1234"]
let JSONData = try! JSONSerialization.data(withJSONObject: JSONObject, options: [])
XCTAssertNil(keychain[data:"JSONData"], "not stored JSON data")
keychain[data: "JSONData"] = JSONData
XCTAssertEqual(keychain[data: "JSONData"], JSONData, "stored JSON data")
keychain[data: "JSONData"] = nil
XCTAssertNil(keychain[data:"JSONData"], "removed JSON data")
}
// MARK:
func testErrorHandling() {
do {
let keychain = Keychain(service: "Twitter", accessGroup: "27AEDK3C9F.shared")
try keychain.removeAll()
XCTAssertTrue(true, "no error occurred")
} catch {
XCTFail("error occurred")
}
do {
let keychain = Keychain(service: "Twitter")
try keychain.removeAll()
XCTAssertTrue(true, "no error occurred")
} catch {
XCTFail("error occurred")
}
do {
let keychain = Keychain(server: URL(string: "https://kishikawakatsumi.com")!, protocolType: .https)
try keychain.removeAll()
XCTAssertTrue(true, "no error occurred")
} catch {
XCTFail("error occurred")
}
do {
let keychain = Keychain()
try keychain.removeAll()
XCTAssertTrue(true, "no error occurred")
} catch {
XCTFail("error occurred")
}
do {
// Add Keychain items
let keychain = Keychain(service: "Twitter")
do {
try keychain.set("kishikawa_katsumi", key: "username")
XCTAssertTrue(true, "no error occurred")
} catch {
XCTFail("error occurred")
}
do {
try keychain.set("password_1234", key: "password")
XCTAssertTrue(true, "no error occurred")
} catch {
XCTFail("error occurred")
}
do {
let username = try keychain.get("username")
XCTAssertEqual(username, "kishikawa_katsumi")
} catch {
XCTFail("error occurred")
}
do {
let password = try keychain.get("password")
XCTAssertEqual(password, "password_1234")
} catch {
XCTFail("error occurred")
}
}
do {
// Update Keychain items
let keychain = Keychain(service: "Twitter")
do {
try keychain.set("katsumi_kishikawa", key: "username")
XCTAssertTrue(true, "no error occurred")
} catch {
XCTFail("error occurred")
}
do {
try keychain.set("1234_password", key: "password")
XCTAssertTrue(true, "no error occurred")
} catch {
XCTFail("error occurred")
}
do {
let username = try keychain.get("username")
XCTAssertEqual(username, "katsumi_kishikawa")
} catch {
XCTFail("error occurred")
}
do {
let password = try keychain.get("password")
XCTAssertEqual(password, "1234_password")
} catch {
XCTFail("error occurred")
}
}
do {
// Remove Keychain items
let keychain = Keychain(service: "Twitter")
do {
try keychain.remove("username")
XCTAssertNil(try! keychain.get("username"))
} catch {
XCTFail("error occurred")
}
do {
try keychain.remove("password")
XCTAssertNil(try! keychain.get("username"))
} catch {
XCTFail("error occurred")
}
}
}
// MARK:
func testSetStringWithCustomService() {
let username_1 = "kishikawakatsumi"
let password_1 = "password1234"
let username_2 = "kishikawa_katsumi"
let password_2 = "password_1234"
let username_3 = "k_katsumi"
let password_3 = "12341234"
let service_1 = ""
let service_2 = "com.kishikawakatsumi.KeychainAccess"
let service_3 = "example.com"
do { try Keychain().removeAll() } catch {}
do { try Keychain(service: service_1).removeAll() } catch {}
do { try Keychain(service: service_2).removeAll() } catch {}
do { try Keychain(service: service_3).removeAll() } catch {}
XCTAssertNil(try! Keychain().get("username"), "not stored username")
XCTAssertNil(try! Keychain().get("password"), "not stored password")
XCTAssertNil(try! Keychain(service: service_1).get("username"), "not stored username")
XCTAssertNil(try! Keychain(service: service_1).get("password"), "not stored password")
XCTAssertNil(try! Keychain(service: service_2).get("username"), "not stored username")
XCTAssertNil(try! Keychain(service: service_2).get("password"), "not stored password")
XCTAssertNil(try! Keychain(service: service_3).get("username"), "not stored username")
XCTAssertNil(try! Keychain(service: service_3).get("password"), "not stored password")
do { try Keychain().set(username_1, key: "username") } catch {}
XCTAssertEqual(try! Keychain().get("username"), username_1, "stored username")
XCTAssertNil(try! Keychain(service: service_1).get("password"), "not stored password")
XCTAssertNil(try! Keychain(service: service_2).get("username"), "not stored username")
XCTAssertNil(try! Keychain(service: service_3).get("username"), "not stored username")
do { try Keychain(service: service_1).set(username_1, key: "username") } catch {}
XCTAssertEqual(try! Keychain().get("username"), username_1, "stored username")
XCTAssertEqual(try! Keychain(service: service_1).get("username"), username_1, "stored username")
XCTAssertNil(try! Keychain(service: service_2).get("username"), "not stored username")
XCTAssertNil(try! Keychain(service: service_3).get("username"), "not stored username")
do { try Keychain(service: service_2).set(username_2, key: "username") } catch {}
XCTAssertEqual(try! Keychain().get("username"), username_1, "stored username")
XCTAssertEqual(try! Keychain(service: service_1).get("username"), username_1, "stored username")
XCTAssertEqual(try! Keychain(service: service_2).get("username"), username_2, "stored username")
XCTAssertNil(try! Keychain(service: service_3).get("username"), "not stored username")
do { try Keychain(service: service_3).set(username_3, key: "username") } catch {}
XCTAssertEqual(try! Keychain().get("username"), username_1, "stored username")
XCTAssertEqual(try! Keychain(service: service_1).get("username"), username_1, "stored username")
XCTAssertEqual(try! Keychain(service: service_2).get("username"), username_2, "stored username")
XCTAssertEqual(try! Keychain(service: service_3).get("username"), username_3, "stored username")
do { try Keychain().set(password_1, key: "password") } catch {}
XCTAssertEqual(try! Keychain().get("password"), password_1, "stored password")
XCTAssertNil(try! Keychain(service: service_1).get("password"), "not stored password")
XCTAssertNil(try! Keychain(service: service_2).get("password"), "not stored password")
XCTAssertNil(try! Keychain(service: service_3).get("password"), "not stored password")
do { try Keychain(service: service_1).set(password_1, key: "password") } catch {}
XCTAssertEqual(try! Keychain().get("password"), password_1, "stored password")
XCTAssertEqual(try! Keychain(service: service_1).get("password"), password_1, "stored password")
XCTAssertNil(try! Keychain(service: service_2).get("password"), "not stored password")
XCTAssertNil(try! Keychain(service: service_3).get("password"), "not stored password")
do { try Keychain(service: service_2).set(password_2, key: "password") } catch {}
XCTAssertEqual(try! Keychain().get("password"), password_1, "stored password")
XCTAssertEqual(try! Keychain(service: service_1).get("password"), password_1, "stored password")
XCTAssertEqual(try! Keychain(service: service_2).get("password"), password_2, "stored password")
XCTAssertNil(try! Keychain(service: service_3).get("password"), "not stored password")
do { try Keychain(service: service_3).set(password_3, key: "password") } catch {}
XCTAssertEqual(try! Keychain().get("password"), password_1, "stored password")
XCTAssertEqual(try! Keychain(service: service_1).get("password"), password_1, "stored password")
XCTAssertEqual(try! Keychain(service: service_2).get("password"), password_2, "stored password")
XCTAssertEqual(try! Keychain(service: service_3).get("password"), password_3, "stored password")
do { try Keychain().remove("username") } catch {}
XCTAssertNil(try! Keychain().get("username"), "removed username")
XCTAssertEqual(try! Keychain(service: service_1).get("username"), username_1, "left username")
XCTAssertEqual(try! Keychain(service: service_2).get("username"), username_2, "left username")
XCTAssertEqual(try! Keychain(service: service_3).get("username"), username_3, "left username")
do { try Keychain(service: service_1).remove("username") } catch {}
XCTAssertNil(try! Keychain().get("username"), "removed username")
XCTAssertNil(try! Keychain(service: service_1).get("username"), "removed username")
XCTAssertEqual(try! Keychain(service: service_2).get("username"), username_2, "left username")
XCTAssertEqual(try! Keychain(service: service_3).get("username"), username_3, "left username")
do { try Keychain(service: service_2).remove("username") } catch {}
XCTAssertNil(try! Keychain().get("username"), "removed username")
XCTAssertNil(try! Keychain(service: service_1).get("username"), "removed username")
XCTAssertNil(try! Keychain(service: service_2).get("username"), "removed username")
XCTAssertEqual(try! Keychain(service: service_3).get("username"), username_3, "left username")
do { try Keychain(service: service_3).remove("username") } catch {}
XCTAssertNil(try! Keychain().get("username"), "removed username")
XCTAssertNil(try! Keychain(service: service_1).get("username"), "removed username")
XCTAssertNil(try! Keychain(service: service_2).get("username"), "removed username")
XCTAssertNil(try! Keychain(service: service_3).get("username"), "removed username")
do { try Keychain().remove("password") } catch {}
XCTAssertNil(try! Keychain().get("password"), "removed password")
XCTAssertEqual(try! Keychain(service: service_1).get("password"), password_1, "left password")
XCTAssertEqual(try! Keychain(service: service_2).get("password"), password_2, "left password")
XCTAssertEqual(try! Keychain(service: service_3).get("password"), password_3, "left password")
do { try Keychain(service: service_1).remove("password") } catch {}
XCTAssertNil(try! Keychain().get("password"), "removed password")
XCTAssertNil(try! Keychain(service: service_1).get("password"), "removed password")
XCTAssertEqual(try! Keychain(service: service_2).get("password"), password_2, "left password")
XCTAssertEqual(try! Keychain(service: service_3).get("password"), password_3, "left password")
do { try Keychain(service: service_2).remove("password") } catch {}
XCTAssertNil(try! Keychain().get("password"), "removed password")
XCTAssertNil(try! Keychain(service: service_1).get("password"), "removed password")
XCTAssertNil(try! Keychain(service: service_2).get("password"), "removed password")
XCTAssertEqual(try! Keychain(service: service_3).get("password"), password_3, "left password")
do { try Keychain(service: service_3).remove("password") } catch {}
XCTAssertNil(try! Keychain().get("password"), "removed password")
XCTAssertNil(try! Keychain(service: service_2).get("password"), "removed password")
XCTAssertNil(try! Keychain(service: service_2).get("password"), "removed password")
XCTAssertNil(try! Keychain(service: service_2).get("password"), "removed password")
}
// MARK:
func testProperties() {
guard #available(OSX 10.10, *) else {
return
}
let keychain = Keychain()
XCTAssertEqual(keychain.synchronizable, false)
XCTAssertEqual(keychain.synchronizable(true).synchronizable, true)
XCTAssertEqual(keychain.synchronizable(false).synchronizable, false)
XCTAssertEqual(keychain.accessibility(.afterFirstUnlock).accessibility, Accessibility.afterFirstUnlock)
XCTAssertEqual(keychain.accessibility(.whenPasscodeSetThisDeviceOnly, authenticationPolicy: .userPresence).accessibility, Accessibility.whenPasscodeSetThisDeviceOnly)
XCTAssertEqual(keychain.accessibility(.whenPasscodeSetThisDeviceOnly, authenticationPolicy: .userPresence).authenticationPolicy, AuthenticationPolicy.userPresence)
XCTAssertNil(keychain.label)
XCTAssertEqual(keychain.label("Label").label, "Label")
XCTAssertNil(keychain.comment)
XCTAssertEqual(keychain.comment("Comment").comment, "Comment")
XCTAssertEqual(keychain.authenticationPrompt("Prompt").authenticationPrompt, "Prompt")
}
// MARK:
func testAllKeys() {
do {
let keychain = Keychain()
keychain["key1"] = "value1"
keychain["key2"] = "value2"
keychain["key3"] = "value3"
let allKeys = keychain.allKeys()
XCTAssertEqual(allKeys.count, 3)
XCTAssertEqual(allKeys.sorted(), ["key1", "key2", "key3"])
let allItems = keychain.allItems()
XCTAssertEqual(allItems.count, 3)
let sortedItems = allItems.sorted { (item1, item2) -> Bool in
let key1 = item1["key"] as! String
let key2 = item2["key"] as! String
return key1.compare(key2) == .orderedAscending || key1.compare(key2) == .orderedSame
}
#if !os(OSX)
XCTAssertEqual(sortedItems[0]["accessGroup"] as? String, "27AEDK3C9F.com.kishikawakatsumi.KeychainAccess.TestHost")
XCTAssertEqual(sortedItems[0]["synchronizable"] as? String, "false")
XCTAssertEqual(sortedItems[0]["service"] as? String, "com.kishikawakatsumi.KeychainAccess.TestHost")
XCTAssertEqual(sortedItems[0]["value"] as? String, "value1")
XCTAssertEqual(sortedItems[0]["key"] as? String, "key1")
XCTAssertEqual(sortedItems[0]["class"] as? String, "GenericPassword")
XCTAssertEqual(sortedItems[0]["accessibility"] as? String, "AfterFirstUnlock")
XCTAssertEqual(sortedItems[1]["accessGroup"] as? String, "27AEDK3C9F.com.kishikawakatsumi.KeychainAccess.TestHost")
XCTAssertEqual(sortedItems[1]["synchronizable"] as? String, "false")
XCTAssertEqual(sortedItems[1]["service"] as? String, "com.kishikawakatsumi.KeychainAccess.TestHost")
XCTAssertEqual(sortedItems[1]["value"] as? String, "value2")
XCTAssertEqual(sortedItems[1]["key"] as? String, "key2")
XCTAssertEqual(sortedItems[1]["class"] as? String, "GenericPassword")
XCTAssertEqual(sortedItems[1]["accessibility"] as? String, "AfterFirstUnlock")
XCTAssertEqual(sortedItems[2]["accessGroup"] as? String, "27AEDK3C9F.com.kishikawakatsumi.KeychainAccess.TestHost")
XCTAssertEqual(sortedItems[2]["synchronizable"] as? String, "false")
XCTAssertEqual(sortedItems[2]["service"] as? String, "com.kishikawakatsumi.KeychainAccess.TestHost")
XCTAssertEqual(sortedItems[2]["value"] as? String, "value3")
XCTAssertEqual(sortedItems[2]["key"] as? String, "key3")
XCTAssertEqual(sortedItems[2]["class"] as? String, "GenericPassword")
XCTAssertEqual(sortedItems[2]["accessibility"] as? String, "AfterFirstUnlock")
#else
XCTAssertEqual(sortedItems[0]["service"] as? String, "com.kishikawakatsumi.KeychainAccess.TestHost")
XCTAssertEqual(sortedItems[0]["key"] as? String, "key1")
XCTAssertEqual(sortedItems[0]["class"] as? String, "GenericPassword")
XCTAssertEqual(sortedItems[1]["service"] as? String, "com.kishikawakatsumi.KeychainAccess.TestHost")
XCTAssertEqual(sortedItems[1]["key"] as? String, "key2")
XCTAssertEqual(sortedItems[1]["class"] as? String, "GenericPassword")
XCTAssertEqual(sortedItems[2]["service"] as? String, "com.kishikawakatsumi.KeychainAccess.TestHost")
XCTAssertEqual(sortedItems[2]["key"] as? String, "key3")
XCTAssertEqual(sortedItems[2]["class"] as? String, "GenericPassword")
#endif
}
do {
let keychain = Keychain(service: "service1")
try! keychain
.synchronizable(true)
.accessibility(.whenUnlockedThisDeviceOnly)
.set("service1_value1", key: "service1_key1")
try! keychain
.synchronizable(false)
.accessibility(.afterFirstUnlockThisDeviceOnly)
.set("service1_value2", key: "service1_key2")
let allKeys = keychain.allKeys()
XCTAssertEqual(allKeys.count, 2)
XCTAssertEqual(allKeys.sorted(), ["service1_key1", "service1_key2"])
let allItems = keychain.allItems()
XCTAssertEqual(allItems.count, 2)
let sortedItems = allItems.sorted { (item1, item2) -> Bool in
let key1 = item1["key"] as! String
let key2 = item2["key"] as! String
return key1.compare(key2) == .orderedAscending || key1.compare(key2) == .orderedSame
}
#if !os(OSX)
XCTAssertEqual(sortedItems[0]["accessGroup"] as? String, "27AEDK3C9F.com.kishikawakatsumi.KeychainAccess.TestHost")
XCTAssertEqual(sortedItems[0]["synchronizable"] as? String, "true")
XCTAssertEqual(sortedItems[0]["service"] as? String, "service1")
XCTAssertEqual(sortedItems[0]["value"] as? String, "service1_value1")
XCTAssertEqual(sortedItems[0]["key"] as? String, "service1_key1")
XCTAssertEqual(sortedItems[0]["class"] as? String, "GenericPassword")
XCTAssertEqual(sortedItems[0]["accessibility"] as? String, "WhenUnlockedThisDeviceOnly")
XCTAssertEqual(sortedItems[1]["accessGroup"] as? String, "27AEDK3C9F.com.kishikawakatsumi.KeychainAccess.TestHost")
XCTAssertEqual(sortedItems[1]["synchronizable"] as? String, "false")
XCTAssertEqual(sortedItems[1]["service"] as? String, "service1")
XCTAssertEqual(sortedItems[1]["value"] as? String, "service1_value2")
XCTAssertEqual(sortedItems[1]["key"] as? String, "service1_key2")
XCTAssertEqual(sortedItems[1]["class"] as? String, "GenericPassword")
XCTAssertEqual(sortedItems[1]["accessibility"] as? String, "AfterFirstUnlockThisDeviceOnly")
#else
XCTAssertEqual(sortedItems[0]["service"] as? String, "service1")
XCTAssertEqual(sortedItems[0]["key"] as? String, "service1_key1")
XCTAssertEqual(sortedItems[0]["class"] as? String, "GenericPassword")
XCTAssertEqual(sortedItems[1]["service"] as? String, "service1")
XCTAssertEqual(sortedItems[1]["key"] as? String, "service1_key2")
XCTAssertEqual(sortedItems[1]["class"] as? String, "GenericPassword")
#endif
}
do {
let keychain = Keychain(server: "https://google.com", protocolType: .https)
try! keychain
.synchronizable(false)
.accessibility(.alwaysThisDeviceOnly)
.set("google.com_value1", key: "google.com_key1")
try! keychain
.synchronizable(true)
.accessibility(.always)
.set("google.com_value2", key: "google.com_key2")
let allKeys = keychain.allKeys()
XCTAssertEqual(allKeys.count, 2)
XCTAssertEqual(allKeys.sorted(), ["google.com_key1", "google.com_key2"])
let allItems = keychain.allItems()
XCTAssertEqual(allItems.count, 2)
let sortedItems = allItems.sorted { (item1, item2) -> Bool in
let key1 = item1["key"] as! String
let key2 = item2["key"] as! String
return key1.compare(key2) == .orderedAscending || key1.compare(key2) == .orderedSame
}
#if !os(OSX)
XCTAssertEqual(sortedItems[0]["synchronizable"] as? String, "false")
XCTAssertEqual(sortedItems[0]["value"] as? String, "google.com_value1")
XCTAssertEqual(sortedItems[0]["key"] as? String, "google.com_key1")
XCTAssertEqual(sortedItems[0]["server"] as? String, "google.com")
XCTAssertEqual(sortedItems[0]["class"] as? String, "InternetPassword")
XCTAssertEqual(sortedItems[0]["authenticationType"] as? String, "Default")
XCTAssertEqual(sortedItems[0]["protocol"] as? String, "HTTPS")
XCTAssertEqual(sortedItems[0]["accessibility"] as? String, "AlwaysThisDeviceOnly")
XCTAssertEqual(sortedItems[1]["synchronizable"] as? String, "true")
XCTAssertEqual(sortedItems[1]["value"] as? String, "google.com_value2")
XCTAssertEqual(sortedItems[1]["key"] as? String, "google.com_key2")
XCTAssertEqual(sortedItems[1]["server"] as? String, "google.com")
XCTAssertEqual(sortedItems[1]["class"] as? String, "InternetPassword")
XCTAssertEqual(sortedItems[1]["authenticationType"] as? String, "Default")
XCTAssertEqual(sortedItems[1]["protocol"] as? String, "HTTPS")
XCTAssertEqual(sortedItems[1]["accessibility"] as? String, "Always")
#else
XCTAssertEqual(sortedItems[0]["key"] as? String, "google.com_key1")
XCTAssertEqual(sortedItems[0]["server"] as? String, "google.com")
XCTAssertEqual(sortedItems[0]["class"] as? String, "InternetPassword")
XCTAssertEqual(sortedItems[0]["authenticationType"] as? String, "Default")
XCTAssertEqual(sortedItems[0]["protocol"] as? String, "HTTPS")
XCTAssertEqual(sortedItems[1]["key"] as? String, "google.com_key2")
XCTAssertEqual(sortedItems[1]["server"] as? String, "google.com")
XCTAssertEqual(sortedItems[1]["class"] as? String, "InternetPassword")
XCTAssertEqual(sortedItems[1]["authenticationType"] as? String, "Default")
XCTAssertEqual(sortedItems[1]["protocol"] as? String, "HTTPS")
#endif
}
#if !os(OSX)
do {
let allKeys = Keychain.allKeys(.genericPassword)
XCTAssertEqual(allKeys.count, 5)
let sortedKeys = allKeys.sorted { (key1, key2) -> Bool in
return key1.1.compare(key2.1) == .orderedAscending || key1.1.compare(key2.1) == .orderedSame
}
XCTAssertEqual(sortedKeys[0].0, "com.kishikawakatsumi.KeychainAccess.TestHost")
XCTAssertEqual(sortedKeys[0].1, "key1")
XCTAssertEqual(sortedKeys[1].0, "com.kishikawakatsumi.KeychainAccess.TestHost")
XCTAssertEqual(sortedKeys[1].1, "key2")
XCTAssertEqual(sortedKeys[2].0, "com.kishikawakatsumi.KeychainAccess.TestHost")
XCTAssertEqual(sortedKeys[2].1, "key3")
XCTAssertEqual(sortedKeys[3].0, "service1")
XCTAssertEqual(sortedKeys[3].1, "service1_key1")
XCTAssertEqual(sortedKeys[4].0, "service1")
XCTAssertEqual(sortedKeys[4].1, "service1_key2")
}
do {
let allKeys = Keychain.allKeys(.internetPassword)
XCTAssertEqual(allKeys.count, 2)
let sortedKeys = allKeys.sorted { (key1, key2) -> Bool in
return key1.1.compare(key2.1) == .orderedAscending || key1.1.compare(key2.1) == .orderedSame
}
XCTAssertEqual(sortedKeys[0].0, "google.com")
XCTAssertEqual(sortedKeys[0].1, "google.com_key1")
XCTAssertEqual(sortedKeys[1].0, "google.com")
XCTAssertEqual(sortedKeys[1].1, "google.com_key2")
}
#endif
}
func testDescription() {
do {
let keychain = Keychain()
XCTAssertEqual(keychain.description, "[]")
XCTAssertEqual(keychain.debugDescription, "[]")
}
}
// MARK:
func testAuthenticationPolicy() {
guard #available(iOS 9.0, OSX 10.11, *) else {
return
}
do {
let accessibility: Accessibility = .whenPasscodeSetThisDeviceOnly
let policy: AuthenticationPolicy = [.userPresence]
let flags = SecAccessControlCreateFlags(rawValue: policy.rawValue)
var error: Unmanaged<CFError>?
let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault, accessibility.rawValue as CFTypeRef, flags, &error)
XCTAssertNil(error)
XCTAssertNotNil(accessControl)
}
#if os(iOS)
do {
let accessibility: Accessibility = .whenPasscodeSetThisDeviceOnly
let policy: AuthenticationPolicy = [.userPresence, .applicationPassword]
let flags = SecAccessControlCreateFlags(rawValue: policy.rawValue)
var error: Unmanaged<CFError>?
let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault, accessibility.rawValue as CFTypeRef, flags, &error)
XCTAssertNil(error)
XCTAssertNotNil(accessControl)
}
do {
let accessibility: Accessibility = .whenPasscodeSetThisDeviceOnly
let policy: AuthenticationPolicy = [.userPresence, .applicationPassword, .privateKeyUsage]
let flags = SecAccessControlCreateFlags(rawValue: policy.rawValue)
var error: Unmanaged<CFError>?
let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault, accessibility.rawValue as CFTypeRef, flags, &error)
XCTAssertNil(error)
XCTAssertNotNil(accessControl)
}
do {
let accessibility: Accessibility = .whenPasscodeSetThisDeviceOnly
let policy: AuthenticationPolicy = [.applicationPassword]
let flags = SecAccessControlCreateFlags(rawValue: policy.rawValue)
var error: Unmanaged<CFError>?
let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault, accessibility.rawValue as CFTypeRef, flags, &error)
XCTAssertNil(error)
XCTAssertNotNil(accessControl)
}
do {
let accessibility: Accessibility = .whenPasscodeSetThisDeviceOnly
let policy: AuthenticationPolicy = [.applicationPassword, .privateKeyUsage]
let flags = SecAccessControlCreateFlags(rawValue: policy.rawValue)
var error: Unmanaged<CFError>?
let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault, accessibility.rawValue as CFTypeRef, flags, &error)
XCTAssertNil(error)
XCTAssertNotNil(accessControl)
}
do {
let accessibility: Accessibility = .whenPasscodeSetThisDeviceOnly
let policy: AuthenticationPolicy = [.privateKeyUsage]
let flags = SecAccessControlCreateFlags(rawValue: policy.rawValue)
var error: Unmanaged<CFError>?
let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault, accessibility.rawValue as CFTypeRef, flags, &error)
XCTAssertNil(error)
XCTAssertNotNil(accessControl)
}
do {
let accessibility: Accessibility = .whenPasscodeSetThisDeviceOnly
let policy: AuthenticationPolicy = [.touchIDAny]
let flags = SecAccessControlCreateFlags(rawValue: policy.rawValue)
var error: Unmanaged<CFError>?
let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault, accessibility.rawValue as CFTypeRef, flags, &error)
XCTAssertNil(error)
XCTAssertNotNil(accessControl)
}
do {
let accessibility: Accessibility = .whenPasscodeSetThisDeviceOnly
let policy: AuthenticationPolicy = [.touchIDAny, .devicePasscode]
let flags = SecAccessControlCreateFlags(rawValue: policy.rawValue)
var error: Unmanaged<CFError>?
let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault, accessibility.rawValue as CFTypeRef, flags, &error)
XCTAssertNil(error)
XCTAssertNotNil(accessControl)
}
do {
let accessibility: Accessibility = .whenPasscodeSetThisDeviceOnly
let policy: AuthenticationPolicy = [.touchIDAny, .applicationPassword]
let flags = SecAccessControlCreateFlags(rawValue: policy.rawValue)
var error: Unmanaged<CFError>?
let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault, accessibility.rawValue as CFTypeRef, flags, &error)
XCTAssertNil(error)
XCTAssertNotNil(accessControl)
}
do {
let accessibility: Accessibility = .whenPasscodeSetThisDeviceOnly
let policy: AuthenticationPolicy = [.touchIDAny, .applicationPassword, .privateKeyUsage]
let flags = SecAccessControlCreateFlags(rawValue: policy.rawValue)
var error: Unmanaged<CFError>?
let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault, accessibility.rawValue as CFTypeRef, flags, &error)
XCTAssertNil(error)
XCTAssertNotNil(accessControl)
}
do {
let accessibility: Accessibility = .whenPasscodeSetThisDeviceOnly
let policy: AuthenticationPolicy = [.touchIDCurrentSet]
let flags = SecAccessControlCreateFlags(rawValue: policy.rawValue)
var error: Unmanaged<CFError>?
let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault, accessibility.rawValue as CFTypeRef, flags, &error)
XCTAssertNil(error)
XCTAssertNotNil(accessControl)
}
do {
let accessibility: Accessibility = .whenPasscodeSetThisDeviceOnly
let policy: AuthenticationPolicy = [.touchIDCurrentSet, .devicePasscode]
let flags = SecAccessControlCreateFlags(rawValue: policy.rawValue)
var error: Unmanaged<CFError>?
let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault, accessibility.rawValue as CFTypeRef, flags, &error)
XCTAssertNil(error)
XCTAssertNotNil(accessControl)
}
do {
let accessibility: Accessibility = .whenPasscodeSetThisDeviceOnly
let policy: AuthenticationPolicy = [.touchIDCurrentSet, .applicationPassword]
let flags = SecAccessControlCreateFlags(rawValue: policy.rawValue)
var error: Unmanaged<CFError>?
let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault, accessibility.rawValue as CFTypeRef, flags, &error)
XCTAssertNil(error)
XCTAssertNotNil(accessControl)
}
do {
let accessibility: Accessibility = .whenPasscodeSetThisDeviceOnly
let policy: AuthenticationPolicy = [.touchIDCurrentSet, .applicationPassword, .privateKeyUsage]
let flags = SecAccessControlCreateFlags(rawValue: policy.rawValue)
var error: Unmanaged<CFError>?
let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault, accessibility.rawValue as CFTypeRef, flags, &error)
XCTAssertNil(error)
XCTAssertNotNil(accessControl)
}
do {
let accessibility: Accessibility = .whenPasscodeSetThisDeviceOnly
let policy: AuthenticationPolicy = [.touchIDAny, .or, .devicePasscode]
let flags = SecAccessControlCreateFlags(rawValue: policy.rawValue)
var error: Unmanaged<CFError>?
let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault, accessibility.rawValue as CFTypeRef, flags, &error)
XCTAssertNil(error)
XCTAssertNotNil(accessControl)
}
do {
let accessibility: Accessibility = .whenPasscodeSetThisDeviceOnly
let policy: AuthenticationPolicy = [.touchIDAny, .and, .devicePasscode]
let flags = SecAccessControlCreateFlags(rawValue: policy.rawValue)
var error: Unmanaged<CFError>?
let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault, accessibility.rawValue as CFTypeRef, flags, &error)
XCTAssertNil(error)
XCTAssertNotNil(accessControl)
}
#endif
#if os(OSX)
do {
let accessibility: Accessibility = .whenPasscodeSetThisDeviceOnly
let policy: AuthenticationPolicy = [.userPresence]
let flags = SecAccessControlCreateFlags(rawValue: policy.rawValue)
var error: Unmanaged<CFError>?
let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault, accessibility.rawValue as CFTypeRef, flags, &error)
XCTAssertNil(error)
XCTAssertNotNil(accessControl)
}
do {
let accessibility: Accessibility = .whenPasscodeSetThisDeviceOnly
let policy: AuthenticationPolicy = [.devicePasscode]
let flags = SecAccessControlCreateFlags(rawValue: policy.rawValue)
var error: Unmanaged<CFError>?
let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault, accessibility.rawValue as CFTypeRef, flags, &error)
XCTAssertNil(error)
XCTAssertNotNil(accessControl)
}
#endif
}
}