Browse Source

Add support subscripting attributes

kishikawa katsumi 9 years ago
parent
commit
2a0e16a062
4 changed files with 113 additions and 28 deletions
  1. 6 0
      Lib/KeychainAccess/Keychain.swift
  2. 85 9
      Lib/KeychainAccessTests/KeychainAccessTests.swift
  3. 8 7
      Lib/Rakefile
  4. 14 12
      README.md

+ 6 - 0
Lib/KeychainAccess/Keychain.swift

@@ -657,6 +657,12 @@ public class Keychain {
             }
         }
     }
+
+    public subscript(attributes key: String) -> Attributes? {
+        get {
+            return (try? get(key) { $0 }).flatMap { $0 }
+        }
+    }
     
     // MARK:
     

+ 85 - 9
Lib/KeychainAccessTests/KeychainAccessTests.swift

@@ -20,6 +20,7 @@ class KeychainAccessTests: XCTestCase {
         do { try Keychain(service: "Twitter").removeAll() } catch {}
         
         do { try Keychain(server: NSURL(string: "https://example.com")!, protocolType: .HTTPS).removeAll() } catch {}
+        do { try Keychain(server: NSURL(string: "https://example.com:443")!, protocolType: .HTTPS).removeAll() } catch {}
         
         do { try Keychain().removeAll() } catch {}
     }
@@ -498,6 +499,7 @@ class KeychainAccessTests: XCTestCase {
                 XCTFail("error occurred")
             }
         }
+
         do {
             var attributes = [String: AnyObject]()
             attributes[String(kSecAttrDescription)] = "Description Test"
@@ -509,9 +511,8 @@ class KeychainAccessTests: XCTestCase {
             attributes[String(kSecAttrIsNegative)] = true
             attributes[String(kSecAttrSecurityDomain)] = "securitydomain"
 
-            let keychain = Keychain(server: NSURL(string: "https://example.com:443//api/login/")!, protocolType: .HTTPS)
+            let keychain = Keychain(server: NSURL(string: "https://example.com:443/api/login/")!, protocolType: .HTTPS)
                 .attributes(attributes)
-                .accessibility(.WhenPasscodeSetThisDeviceOnly, authenticationPolicy: .UserPresence)
 
             XCTAssertNil(keychain["kishikawakatsumi"], "not stored password")
 
@@ -522,17 +523,17 @@ class KeychainAccessTests: XCTestCase {
                 XCTFail("error occurred")
             }
 
-            keychain["kishikawakatsumi"] = "password1234"
-            XCTAssertEqual(keychain["kishikawakatsumi"], "password1234", "stored password")
-
             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".dataUsingEncoding(NSUTF8StringEncoding))
                 XCTAssertNil(attributes?.ref)
                 XCTAssertNotNil(attributes?.persistentRef)
-                XCTAssertEqual(attributes?.accessible, Accessibility.WhenPasscodeSetThisDeviceOnly.rawValue)
-                XCTAssertNotNil(attributes?.accessControl)
+                XCTAssertEqual(attributes?.accessible, Accessibility.AfterFirstUnlock.rawValue)
+                XCTAssertNil(attributes?.accessControl)
                 XCTAssertEqual(attributes?.accessGroup, "")
                 XCTAssertNotNil(attributes?.synchronizable)
                 XCTAssertNotNil(attributes?.creationDate)
@@ -556,13 +557,88 @@ class KeychainAccessTests: XCTestCase {
             } catch {
                 XCTFail("error occurred")
             }
+            do {
+                let keychain = Keychain(server: NSURL(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".dataUsingEncoding(NSUTF8StringEncoding))
+                XCTAssertNil(attributes?.ref)
+                XCTAssertNotNil(attributes?.persistentRef)
+                XCTAssertEqual(attributes?.accessible, Accessibility.AfterFirstUnlock.rawValue)
+                XCTAssertNil(attributes?.accessControl)
+                XCTAssertEqual(attributes?.accessGroup, "")
+                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: NSURL(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".dataUsingEncoding(NSUTF8StringEncoding))
+                XCTAssertNil(attributes?.ref)
+                XCTAssertNotNil(attributes?.persistentRef)
+                XCTAssertEqual(attributes?.accessible, Accessibility.AfterFirstUnlock.rawValue)
+                XCTAssertNil(attributes?.accessControl)
+                XCTAssertEqual(attributes?.accessGroup, "")
+                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")
         

+ 8 - 7
Lib/Rakefile

@@ -6,13 +6,14 @@ def destinations
         'name=iPhone 6 Plus,OS=9.0'
       ]
   else
-    [ 'name=iPad 2,OS=8.1',
-      'name=iPad Air,OS=8.1',
-      'name=iPhone 4s,OS=8.1',
-      'name=iPhone 5,OS=8.1',
-      'name=iPhone 5s,OS=8.1',
-      'name=iPhone 6,OS=8.1',
-      'name=iPhone 6 Plus,OS=8.1',
+    [ 
+      # 'name=iPad 2,OS=8.1',
+      # 'name=iPad Air,OS=8.1',
+      # 'name=iPhone 4s,OS=8.1',
+      # 'name=iPhone 5,OS=8.1',
+      # 'name=iPhone 5s,OS=8.1',
+      # 'name=iPhone 6,OS=8.1',
+      # 'name=iPhone 6 Plus,OS=8.1',
       'name=iPhone 6,OS=9.0',
       'name=iPhone 6 Plus,OS=9.0',
       'name=iPhone 6,OS=9.1',

+ 14 - 12
README.md

@@ -180,24 +180,16 @@ do {
 
 ```swift
 let keychain = Keychain()
-do {
-    let persistentRef = try keychain.get("kishikawakatsumi") { $0?.persistentRef }
-    ...
-} catch let error {
-    print("error: \(error)")
-}
+let persistentRef = keychain[attributes: "kishikawakatsumi"].persistentRef
+...
 ```
 
 #### Creation Date
 
 ```swift
 let keychain = Keychain()
-do {
-    let creationDate = try keychain.get("kishikawakatsumi") { $0?.creationDate }
-    ...
-} catch let error {
-    print("error: \(error)")
-}
+let creationDate = keychain[attributes: "kishikawakatsumi"].creationDate
+...
 ```
 
 #### All Attributes
@@ -215,6 +207,16 @@ do {
 }
 ```
 
+##### subscripting
+
+```swift
+let keychain = Keychain()
+let attributes = keychain[attributes: "kishikawakatsumi"]
+print(attributes.comment)
+print(attributes.label)
+print(attributes.creator)
+```
+
 ### :key: Configuration (Accessibility, Sharing, iCould Sync)
 
 **Provides fluent interfaces**