Browse Source

Merge pull request #447 from kishikawakatsumi/MikeLeber117-remove-architecture-check

Mike leber117 remove architecture check
Kishikawa Katsumi 5 years ago
parent
commit
cc4d90ec67
2 changed files with 121 additions and 0 deletions
  1. 2 0
      Lib/KeychainAccess/Keychain.swift
  2. 119 0
      Lib/KeychainAccessTests/KeychainAccessTests.swift

+ 2 - 0
Lib/KeychainAccess/Keychain.swift

@@ -384,6 +384,8 @@ public final class Keychain {
         return options.service
     }
 
+    // This attribute (kSecAttrAccessGroup) applies to macOS keychain items only if you also set a value of true for the
+    // kSecUseDataProtectionKeychain key, the kSecAttrSynchronizable key, or both.
     public var accessGroup: String? {
         return options.accessGroup
     }

+ 119 - 0
Lib/KeychainAccessTests/KeychainAccessTests.swift

@@ -130,6 +130,125 @@ class KeychainAccessTests: XCTestCase {
         }
     }
 
+    func testGenericPasswordWithAccessGroup1() {
+        do {
+            // Add Keychain items
+            // This attribute (kSecAttrAccessGroup) applies to macOS keychain items only if you also set a value of true for the
+            // kSecUseDataProtectionKeychain key, the kSecAttrSynchronizable key, or both.
+            // https://developer.apple.com/documentation/security/ksecattraccessgroup
+            let keychain = Keychain(service: "Twitter").synchronizable(true)
+            let keychainWithAccessGroup = Keychain(service: "Twitter", accessGroup: "27AEDK3C9F.shared").synchronizable(true)
+
+            do { try keychain.set("kishikawa_katsumi", key: "username") } catch {}
+            do { try keychain.set("password_1234", key: "password") } catch {}
+            do { try keychainWithAccessGroup.set("kishikawa_katsumi_access_group", key: "username") } catch {}
+            do { try keychainWithAccessGroup.set("password_1234_access_group", key: "password") } catch {}
+
+            XCTAssertEqual(try! keychain.get("username"), "kishikawa_katsumi")
+            XCTAssertEqual(try! keychain.get("password"), "password_1234")
+
+            XCTAssertEqual(try! keychainWithAccessGroup.get("username"), "kishikawa_katsumi_access_group")
+            XCTAssertEqual(try! keychainWithAccessGroup.get("password"), "password_1234_access_group")
+        }
+
+        do {
+            // Update Keychain items
+            let keychain = Keychain(service: "Twitter").synchronizable(true)
+            let keychainWithAccessGroup = Keychain(service: "Twitter", accessGroup: "27AEDK3C9F.shared").synchronizable(true)
+
+            do { try keychain.set("katsumi_kishikawa", key: "username") } catch {}
+            do { try keychain.set("1234_password", key: "password") } catch {}
+            do { try keychainWithAccessGroup.set("katsumi_kishikawa_access_group", key: "username") } catch {}
+            do { try keychainWithAccessGroup.set("1234_password_access_group", key: "password") } catch {}
+
+            XCTAssertEqual(try! keychain.get("username"), "katsumi_kishikawa")
+            XCTAssertEqual(try! keychain.get("password"), "1234_password")
+
+            XCTAssertEqual(try! keychainWithAccessGroup.get("username"), "katsumi_kishikawa_access_group")
+            XCTAssertEqual(try! keychainWithAccessGroup.get("password"), "1234_password_access_group")
+        }
+
+        do {
+            // Remove Keychain items
+            let keychain = Keychain(service: "Twitter").synchronizable(true)
+            let keychainWithAccessGroup = Keychain(service: "Twitter", accessGroup: "27AEDK3C9F.shared").synchronizable(true)
+
+            XCTAssertNotNil(try! keychainWithAccessGroup.get("username"))
+            XCTAssertNotNil(try! keychainWithAccessGroup.get("password"))
+
+            do { try keychainWithAccessGroup.remove("username") } catch {}
+            do { try keychainWithAccessGroup.remove("password") } catch {}
+
+
+            XCTAssertNil(try! keychainWithAccessGroup.get("username"))
+            XCTAssertNil(try! keychainWithAccessGroup.get("password"))
+
+            XCTAssertNotNil(try! keychain.get("username"))
+            XCTAssertNotNil(try! keychain.get("password"))
+
+            do { try keychain.remove("username") } catch {}
+            do { try keychain.remove("password") } catch {}
+
+            XCTAssertNil(try! keychain.get("username"))
+            XCTAssertNil(try! keychain.get("password"))
+        }
+    }
+
+    func testGenericPasswordWithAccessGroup2() {
+        do {
+            // Add Keychain items
+            let keychain = Keychain(service: "Twitter").synchronizable(true)
+            let keychainWithAccessGroup = Keychain(service: "Twitter", accessGroup: "27AEDK3C9F.shared").synchronizable(true)
+
+            do { try keychain.set("kishikawa_katsumi", key: "username") } catch {}
+            do { try keychain.set("password_1234", key: "password") } catch {}
+            do { try keychainWithAccessGroup.set("kishikawa_katsumi_access_group", key: "username") } catch {}
+            do { try keychainWithAccessGroup.set("password_1234_access_group", key: "password") } catch {}
+
+            XCTAssertEqual(try! keychain.get("username"), "kishikawa_katsumi")
+            XCTAssertEqual(try! keychain.get("password"), "password_1234")
+
+            XCTAssertEqual(try! keychainWithAccessGroup.get("username"), "kishikawa_katsumi_access_group")
+            XCTAssertEqual(try! keychainWithAccessGroup.get("password"), "password_1234_access_group")
+        }
+
+        do {
+            // Update Keychain items
+            let keychain = Keychain(service: "Twitter").synchronizable(true)
+            let keychainWithAccessGroup = Keychain(service: "Twitter", accessGroup: "27AEDK3C9F.shared").synchronizable(true)
+
+            do { try keychain.set("katsumi_kishikawa", key: "username") } catch {}
+            do { try keychain.set("1234_password", key: "password") } catch {}
+            do { try keychainWithAccessGroup.set("katsumi_kishikawa_access_group", key: "username") } catch {}
+            do { try keychainWithAccessGroup.set("1234_password_access_group", key: "password") } catch {}
+
+            XCTAssertEqual(try! keychain.get("username"), "katsumi_kishikawa")
+            XCTAssertEqual(try! keychain.get("password"), "1234_password")
+
+            XCTAssertEqual(try! keychainWithAccessGroup.get("username"), "katsumi_kishikawa_access_group")
+            XCTAssertEqual(try! keychainWithAccessGroup.get("password"), "1234_password_access_group")
+        }
+
+        do {
+            // Remove Keychain items
+            let keychain = Keychain(service: "Twitter").synchronizable(true)
+            let keychainWithAccessGroup = Keychain(service: "Twitter", accessGroup: "27AEDK3C9F.shared").synchronizable(true)
+
+            XCTAssertNotNil(try! keychainWithAccessGroup.get("username"))
+            XCTAssertNotNil(try! keychainWithAccessGroup.get("password"))
+
+            do { try keychain.remove("username") } catch {}
+            do { try keychain.remove("password") } catch {}
+
+            // If the access group is empty, the query will match all access group. So delete all values in other access groups.
+            XCTAssertNil(try! keychain.get("username"))
+            XCTAssertNil(try! keychain.get("password"))
+
+            XCTAssertNil(try! keychainWithAccessGroup.get("username"))
+            XCTAssertNil(try! keychainWithAccessGroup.get("password"))
+        }
+    }
+
     // MARK:
 
     func testInternetPassword() {