KeychainAccessTests.swift 46 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067
  1. //
  2. // KeychainAccessTests.swift
  3. // KeychainAccessTests
  4. //
  5. // Created by kishikawa katsumi on 2014/12/24.
  6. // Copyright (c) 2014 kishikawa katsumi. All rights reserved.
  7. //
  8. import Foundation
  9. import XCTest
  10. import KeychainAccess
  11. class KeychainAccessTests: XCTestCase {
  12. override func setUp() {
  13. super.setUp()
  14. do { try Keychain(service: "Twitter", accessGroup: "12ABCD3E4F.shared").removeAll() } catch {}
  15. do { try Keychain(service: "Twitter").removeAll() } catch {}
  16. do { try Keychain(server: NSURL(string: "https://example.com")!, protocolType: .HTTPS).removeAll() } catch {}
  17. do { try Keychain().removeAll() } catch {}
  18. }
  19. override func tearDown() {
  20. super.tearDown()
  21. }
  22. // MARK:
  23. func testGenericPassword() {
  24. do {
  25. // Add Keychain items
  26. let keychain = Keychain(service: "Twitter")
  27. do { try keychain.set("kishikawa_katsumi", key: "username") } catch {}
  28. do { try keychain.set("password_1234", key: "password") } catch {}
  29. let username = try! keychain.get("username")
  30. XCTAssertEqual(username, "kishikawa_katsumi")
  31. let password = try! keychain.get("password")
  32. XCTAssertEqual(password, "password_1234")
  33. }
  34. do {
  35. // Update Keychain items
  36. let keychain = Keychain(service: "Twitter")
  37. do { try keychain.set("katsumi_kishikawa", key: "username") } catch {}
  38. do { try keychain.set("1234_password", key: "password") } catch {}
  39. let username = try! keychain.get("username")
  40. XCTAssertEqual(username, "katsumi_kishikawa")
  41. let password = try! keychain.get("password")
  42. XCTAssertEqual(password, "1234_password")
  43. }
  44. do {
  45. // Remove Keychain items
  46. let keychain = Keychain(service: "Twitter")
  47. do { try keychain.remove("username") } catch {}
  48. do { try keychain.remove("password") } catch {}
  49. XCTAssertNil(try! keychain.get("username"))
  50. XCTAssertNil(try! keychain.get("password"))
  51. }
  52. }
  53. func testGenericPasswordSubscripting() {
  54. do {
  55. // Add Keychain items
  56. let keychain = Keychain(service: "Twitter", accessGroup: "12ABCD3E4F.shared")
  57. keychain["username"] = "kishikawa_katsumi"
  58. keychain["password"] = "password_1234"
  59. let username = keychain["username"]
  60. XCTAssertEqual(username, "kishikawa_katsumi")
  61. let password = keychain["password"]
  62. XCTAssertEqual(password, "password_1234")
  63. }
  64. do {
  65. // Update Keychain items
  66. let keychain = Keychain(service: "Twitter", accessGroup: "12ABCD3E4F.shared")
  67. keychain["username"] = "katsumi_kishikawa"
  68. keychain["password"] = "1234_password"
  69. let username = keychain["username"]
  70. XCTAssertEqual(username, "katsumi_kishikawa")
  71. let password = keychain["password"]
  72. XCTAssertEqual(password, "1234_password")
  73. }
  74. do {
  75. // Remove Keychain items
  76. let keychain = Keychain(service: "Twitter", accessGroup: "12ABCD3E4F.shared")
  77. keychain["username"] = nil
  78. keychain["password"] = nil
  79. XCTAssertNil(keychain["username"])
  80. XCTAssertNil(keychain["password"])
  81. }
  82. }
  83. // MARK:
  84. func testInternetPassword() {
  85. do {
  86. // Add Keychain items
  87. let keychain = Keychain(server: NSURL(string: "https://kishikawakatsumi.com")!, protocolType: .HTTPS)
  88. do { try keychain.set("kishikawa_katsumi", key: "username") } catch {}
  89. do { try keychain.set("password_1234", key: "password") } catch {}
  90. let username = try! keychain.get("username")
  91. XCTAssertEqual(username, "kishikawa_katsumi")
  92. let password = try! keychain.get("password")
  93. XCTAssertEqual(password, "password_1234")
  94. }
  95. do {
  96. // Update Keychain items
  97. let keychain = Keychain(server: NSURL(string: "https://kishikawakatsumi.com")!, protocolType: .HTTPS)
  98. do { try keychain.set("katsumi_kishikawa", key: "username") } catch {}
  99. do { try keychain.set("1234_password", key: "password") } catch {}
  100. let username = try! keychain.get("username")
  101. XCTAssertEqual(username, "katsumi_kishikawa")
  102. let password = try! keychain.get("password")
  103. XCTAssertEqual(password, "1234_password")
  104. }
  105. do {
  106. // Remove Keychain items
  107. let keychain = Keychain(server: NSURL(string: "https://kishikawakatsumi.com")!, protocolType: .HTTPS)
  108. do { try keychain.remove("username") } catch {}
  109. do { try keychain.remove("password") } catch {}
  110. XCTAssertNil(try! keychain.get("username"))
  111. XCTAssertNil(try! keychain.get("password"))
  112. }
  113. }
  114. func testInternetPasswordSubscripting() {
  115. do {
  116. // Add Keychain items
  117. let keychain = Keychain(server: NSURL(string: "https://kishikawakatsumi.com")!, protocolType: .HTTPS)
  118. keychain["username"] = "kishikawa_katsumi"
  119. keychain["password"] = "password_1234"
  120. let username = keychain["username"]
  121. XCTAssertEqual(username, "kishikawa_katsumi")
  122. let password = keychain["password"]
  123. XCTAssertEqual(password, "password_1234")
  124. }
  125. do {
  126. // Update Keychain items
  127. let keychain = Keychain(server: NSURL(string: "https://kishikawakatsumi.com")!, protocolType: .HTTPS)
  128. keychain["username"] = "katsumi_kishikawa"
  129. keychain["password"] = "1234_password"
  130. let username = keychain["username"]
  131. XCTAssertEqual(username, "katsumi_kishikawa")
  132. let password = keychain["password"]
  133. XCTAssertEqual(password, "1234_password")
  134. }
  135. do {
  136. // Remove Keychain items
  137. let keychain = Keychain(server: NSURL(string: "https://kishikawakatsumi.com")!, protocolType: .HTTPS)
  138. keychain["username"] = nil
  139. keychain["password"] = nil
  140. XCTAssertNil(keychain["username"])
  141. XCTAssertNil(keychain["password"])
  142. }
  143. }
  144. // MARK:
  145. func testDefaultInitializer() {
  146. let keychain = Keychain()
  147. XCTAssertEqual(keychain.service, "")
  148. XCTAssertNil(keychain.accessGroup)
  149. }
  150. func testInitializerWithService() {
  151. let keychain = Keychain(service: "com.example.github-token")
  152. XCTAssertEqual(keychain.service, "com.example.github-token")
  153. XCTAssertNil(keychain.accessGroup)
  154. }
  155. func testInitializerWithAccessGroup() {
  156. let keychain = Keychain(accessGroup: "12ABCD3E4F.shared")
  157. XCTAssertEqual(keychain.service, "")
  158. XCTAssertEqual(keychain.accessGroup, "12ABCD3E4F.shared")
  159. }
  160. func testInitializerWithServiceAndAccessGroup() {
  161. let keychain = Keychain(service: "com.example.github-token", accessGroup: "12ABCD3E4F.shared")
  162. XCTAssertEqual(keychain.service, "com.example.github-token")
  163. XCTAssertEqual(keychain.accessGroup, "12ABCD3E4F.shared")
  164. }
  165. func testInitializerWithServer() {
  166. let server = "https://kishikawakatsumi.com"
  167. let URL = NSURL(string: server)!
  168. do {
  169. let keychain = Keychain(server: server, protocolType: .HTTPS)
  170. XCTAssertEqual(keychain.server, URL)
  171. XCTAssertEqual(keychain.protocolType, ProtocolType.HTTPS)
  172. XCTAssertEqual(keychain.authenticationType, AuthenticationType.Default)
  173. }
  174. do {
  175. let keychain = Keychain(server: URL, protocolType: .HTTPS)
  176. XCTAssertEqual(keychain.server, URL)
  177. XCTAssertEqual(keychain.protocolType, ProtocolType.HTTPS)
  178. XCTAssertEqual(keychain.authenticationType, AuthenticationType.Default)
  179. }
  180. }
  181. func testInitializerWithServerAndAuthenticationType() {
  182. let server = "https://kishikawakatsumi.com"
  183. let URL = NSURL(string: server)!
  184. do {
  185. let keychain = Keychain(server: server, protocolType: .HTTPS, authenticationType: .HTMLForm)
  186. XCTAssertEqual(keychain.server, URL)
  187. XCTAssertEqual(keychain.protocolType, ProtocolType.HTTPS)
  188. XCTAssertEqual(keychain.authenticationType, AuthenticationType.HTMLForm)
  189. }
  190. do {
  191. let keychain = Keychain(server: URL, protocolType: .HTTPS, authenticationType: .HTMLForm)
  192. XCTAssertEqual(keychain.server, URL)
  193. XCTAssertEqual(keychain.protocolType, ProtocolType.HTTPS)
  194. XCTAssertEqual(keychain.authenticationType, AuthenticationType.HTMLForm)
  195. }
  196. }
  197. // MARK:
  198. func testContains() {
  199. let keychain = Keychain(service: "Twitter")
  200. XCTAssertFalse(try! keychain.contains("username"), "not stored username")
  201. XCTAssertFalse(try! keychain.contains("password"), "not stored password")
  202. do { try keychain.set("kishikawakatsumi", key: "username") } catch {}
  203. XCTAssertTrue(try! keychain.contains("username"), "stored username")
  204. XCTAssertFalse(try! keychain.contains("password"), "not stored password")
  205. do { try keychain.set("password1234", key: "password") } catch {}
  206. XCTAssertTrue(try! keychain.contains("username"), "stored username")
  207. XCTAssertTrue(try! keychain.contains("password"), "stored password")
  208. }
  209. // MARK:
  210. func testSetString() {
  211. let keychain = Keychain(service: "Twitter")
  212. XCTAssertNil(try! keychain.get("username"), "not stored username")
  213. XCTAssertNil(try! keychain.get("password"), "not stored password")
  214. do { try keychain.set("kishikawakatsumi", key: "username") } catch {}
  215. XCTAssertEqual(try! keychain.get("username"), "kishikawakatsumi", "stored username")
  216. XCTAssertNil(try! keychain.get("password"), "not stored password")
  217. do { try keychain.set("password1234", key: "password") } catch {}
  218. XCTAssertEqual(try! keychain.get("username")!, "kishikawakatsumi", "stored username")
  219. XCTAssertEqual(try! keychain.get("password")!, "password1234", "stored password")
  220. }
  221. func testSetData() {
  222. let JSONObject = ["username": "kishikawakatsumi", "password": "password1234"]
  223. let JSONData = try! NSJSONSerialization.dataWithJSONObject(JSONObject, options: [])
  224. let keychain = Keychain(service: "Twitter")
  225. XCTAssertNil(try! keychain.getData("JSONData"), "not stored JSON data")
  226. do { try keychain.set(JSONData, key: "JSONData") } catch {}
  227. XCTAssertEqual(try! keychain.getData("JSONData"), JSONData, "stored JSON data")
  228. }
  229. func testStringConversionError() {
  230. let keychain = Keychain(service: "Twitter")
  231. let length = 256
  232. let data = NSMutableData(length: length)!
  233. SecRandomCopyBytes(kSecRandomDefault, length, UnsafeMutablePointer<UInt8>(data.mutableBytes))
  234. do {
  235. try keychain.set(data, key: "RandomData")
  236. let _ = try keychain.getString("RandomData")
  237. } catch let error as NSError {
  238. XCTAssertEqual(error.domain, KeychainAccessErrorDomain)
  239. XCTAssertEqual(error.code, Int(Status.ConversionError.rawValue))
  240. }
  241. }
  242. func testRemoveString() {
  243. let keychain = Keychain(service: "Twitter")
  244. XCTAssertNil(try! keychain.get("username"), "not stored username")
  245. XCTAssertNil(try! keychain.get("password"), "not stored password")
  246. do { try keychain.set("kishikawakatsumi", key: "username") } catch {}
  247. XCTAssertEqual(try! keychain.get("username"), "kishikawakatsumi", "stored username")
  248. do { try keychain.set("password1234", key: "password") } catch {}
  249. XCTAssertEqual(try! keychain.get("password"), "password1234", "stored password")
  250. do { try keychain.remove("username") } catch {}
  251. XCTAssertNil(try! keychain.get("username"), "removed username")
  252. XCTAssertEqual(try! keychain.get("password"), "password1234", "left password")
  253. do { try keychain.remove("password") } catch {}
  254. XCTAssertNil(try! keychain.get("username"), "removed username")
  255. XCTAssertNil(try! keychain.get("password"), "removed password")
  256. }
  257. func testRemoveData() {
  258. let JSONObject = ["username": "kishikawakatsumi", "password": "password1234"]
  259. let JSONData = try! NSJSONSerialization.dataWithJSONObject(JSONObject, options: [])
  260. let keychain = Keychain(service: "Twitter")
  261. XCTAssertNil(try! keychain.getData("JSONData"), "not stored JSON data")
  262. do { try keychain.set(JSONData, key: "JSONData") } catch {}
  263. XCTAssertEqual(try! keychain.getData("JSONData"), JSONData, "stored JSON data")
  264. do { try keychain.remove("JSONData") } catch {}
  265. XCTAssertNil(try! keychain.getData("JSONData"), "removed JSON data")
  266. }
  267. // MARK:
  268. func testSubscripting() {
  269. let keychain = Keychain(service: "Twitter")
  270. XCTAssertNil(keychain["username"], "not stored username")
  271. XCTAssertNil(keychain["password"], "not stored password")
  272. XCTAssertNil(keychain[string: "username"], "not stored username")
  273. XCTAssertNil(keychain[string: "password"], "not stored password")
  274. keychain["username"] = "kishikawakatsumi"
  275. XCTAssertEqual(keychain["username"], "kishikawakatsumi", "stored username")
  276. XCTAssertEqual(keychain[string: "username"], "kishikawakatsumi", "stored username")
  277. keychain["password"] = "password1234"
  278. XCTAssertEqual(keychain["password"], "password1234", "stored password")
  279. XCTAssertEqual(keychain[string: "password"], "password1234", "stored password")
  280. keychain[string: "username"] = nil
  281. XCTAssertNil(keychain["username"], "removed username")
  282. XCTAssertEqual(keychain["password"], "password1234", "left password")
  283. XCTAssertNil(keychain[string: "username"], "removed username")
  284. XCTAssertEqual(keychain[string: "password"], "password1234", "left password")
  285. keychain[string: "password"] = nil
  286. XCTAssertNil(keychain["username"], "removed username")
  287. XCTAssertNil(keychain["password"], "removed password")
  288. XCTAssertNil(keychain[string: "username"], "removed username")
  289. XCTAssertNil(keychain[string: "password"], "removed password")
  290. let JSONObject = ["username": "kishikawakatsumi", "password": "password1234"]
  291. let JSONData = try! NSJSONSerialization.dataWithJSONObject(JSONObject, options: [])
  292. XCTAssertNil(keychain[data:"JSONData"], "not stored JSON data")
  293. keychain[data: "JSONData"] = JSONData
  294. XCTAssertEqual(keychain[data: "JSONData"], JSONData, "stored JSON data")
  295. keychain[data: "JSONData"] = nil
  296. XCTAssertNil(keychain[data:"JSONData"], "removed JSON data")
  297. }
  298. // MARK:
  299. #if os(iOS)
  300. func testErrorHandling() {
  301. do {
  302. let keychain = Keychain(service: "Twitter", accessGroup: "12ABCD3E4F.shared")
  303. try keychain.removeAll()
  304. XCTAssertTrue(true, "no error occurred")
  305. } catch {
  306. XCTFail("error occurred")
  307. }
  308. do {
  309. let keychain = Keychain(service: "Twitter")
  310. try keychain.removeAll()
  311. XCTAssertTrue(true, "no error occurred")
  312. } catch {
  313. XCTFail("error occurred")
  314. }
  315. do {
  316. let keychain = Keychain(server: NSURL(string: "https://kishikawakatsumi.com")!, protocolType: .HTTPS)
  317. try keychain.removeAll()
  318. XCTAssertTrue(true, "no error occurred")
  319. } catch {
  320. XCTFail("error occurred")
  321. }
  322. do {
  323. let keychain = Keychain()
  324. try keychain.removeAll()
  325. XCTAssertTrue(true, "no error occurred")
  326. } catch {
  327. XCTFail("error occurred")
  328. }
  329. do {
  330. // Add Keychain items
  331. let keychain = Keychain(service: "Twitter")
  332. do {
  333. try keychain.set("kishikawa_katsumi", key: "username")
  334. XCTAssertTrue(true, "no error occurred")
  335. } catch {
  336. XCTFail("error occurred")
  337. }
  338. do {
  339. try keychain.set("password_1234", key: "password")
  340. XCTAssertTrue(true, "no error occurred")
  341. } catch {
  342. XCTFail("error occurred")
  343. }
  344. do {
  345. let username = try keychain.get("username")
  346. XCTAssertEqual(username, "kishikawa_katsumi")
  347. } catch {
  348. XCTFail("error occurred")
  349. }
  350. do {
  351. let password = try keychain.get("password")
  352. XCTAssertEqual(password, "password_1234")
  353. } catch {
  354. XCTFail("error occurred")
  355. }
  356. }
  357. do {
  358. // Update Keychain items
  359. let keychain = Keychain(service: "Twitter")
  360. do {
  361. try keychain.set("katsumi_kishikawa", key: "username")
  362. XCTAssertTrue(true, "no error occurred")
  363. } catch {
  364. XCTFail("error occurred")
  365. }
  366. do {
  367. try keychain.set("1234_password", key: "password")
  368. XCTAssertTrue(true, "no error occurred")
  369. } catch {
  370. XCTFail("error occurred")
  371. }
  372. do {
  373. let username = try keychain.get("username")
  374. XCTAssertEqual(username, "katsumi_kishikawa")
  375. } catch {
  376. XCTFail("error occurred")
  377. }
  378. do {
  379. let password = try keychain.get("password")
  380. XCTAssertEqual(password, "1234_password")
  381. } catch {
  382. XCTFail("error occurred")
  383. }
  384. }
  385. do {
  386. // Remove Keychain items
  387. let keychain = Keychain(service: "Twitter")
  388. do {
  389. try keychain.remove("username")
  390. XCTAssertNil(try! keychain.get("username"))
  391. } catch {
  392. XCTFail("error occurred")
  393. }
  394. do {
  395. try keychain.remove("password")
  396. XCTAssertNil(try! keychain.get("username"))
  397. } catch {
  398. XCTFail("error occurred")
  399. }
  400. }
  401. }
  402. #endif
  403. // MARK:
  404. func testSetStringWithCustomService() {
  405. let username_1 = "kishikawakatsumi"
  406. let password_1 = "password1234"
  407. let username_2 = "kishikawa_katsumi"
  408. let password_2 = "password_1234"
  409. let username_3 = "k_katsumi"
  410. let password_3 = "12341234"
  411. let service_1 = ""
  412. let service_2 = "com.kishikawakatsumi.KeychainAccess"
  413. let service_3 = "example.com"
  414. do { try Keychain().removeAll() } catch {}
  415. do { try Keychain(service: service_1).removeAll() } catch {}
  416. do { try Keychain(service: service_2).removeAll() } catch {}
  417. do { try Keychain(service: service_3).removeAll() } catch {}
  418. XCTAssertNil(try! Keychain().get("username"), "not stored username")
  419. XCTAssertNil(try! Keychain().get("password"), "not stored password")
  420. XCTAssertNil(try! Keychain(service: service_1).get("username"), "not stored username")
  421. XCTAssertNil(try! Keychain(service: service_1).get("password"), "not stored password")
  422. XCTAssertNil(try! Keychain(service: service_2).get("username"), "not stored username")
  423. XCTAssertNil(try! Keychain(service: service_2).get("password"), "not stored password")
  424. XCTAssertNil(try! Keychain(service: service_3).get("username"), "not stored username")
  425. XCTAssertNil(try! Keychain(service: service_3).get("password"), "not stored password")
  426. do { try Keychain().set(username_1, key: "username") } catch {}
  427. XCTAssertEqual(try! Keychain().get("username"), username_1, "stored username")
  428. XCTAssertEqual(try! Keychain(service: service_1).get("username"), username_1, "stored username")
  429. XCTAssertNil(try! Keychain(service: service_2).get("username"), "not stored username")
  430. XCTAssertNil(try! Keychain(service: service_3).get("username"), "not stored username")
  431. do { try Keychain(service: service_1).set(username_1, key: "username") } catch {}
  432. XCTAssertEqual(try! Keychain().get("username"), username_1, "stored username")
  433. XCTAssertEqual(try! Keychain(service: service_1).get("username"), username_1, "stored username")
  434. XCTAssertNil(try! Keychain(service: service_2).get("username"), "not stored username")
  435. XCTAssertNil(try! Keychain(service: service_3).get("username"), "not stored username")
  436. do { try Keychain(service: service_2).set(username_2, key: "username") } catch {}
  437. XCTAssertEqual(try! Keychain().get("username"), username_1, "stored username")
  438. XCTAssertEqual(try! Keychain(service: service_1).get("username"), username_1, "stored username")
  439. XCTAssertEqual(try! Keychain(service: service_2).get("username"), username_2, "stored username")
  440. XCTAssertNil(try! Keychain(service: service_3).get("username"), "not stored username")
  441. do { try Keychain(service: service_3).set(username_3, key: "username") } catch {}
  442. XCTAssertEqual(try! Keychain().get("username"), username_1, "stored username")
  443. XCTAssertEqual(try! Keychain(service: service_1).get("username"), username_1, "stored username")
  444. XCTAssertEqual(try! Keychain(service: service_2).get("username"), username_2, "stored username")
  445. XCTAssertEqual(try! Keychain(service: service_3).get("username"), username_3, "stored username")
  446. do { try Keychain().set(password_1, key: "password") } catch {}
  447. XCTAssertEqual(try! Keychain().get("password"), password_1, "stored password")
  448. XCTAssertEqual(try! Keychain(service: service_1).get("password"), password_1, "stored password")
  449. XCTAssertNil(try! Keychain(service: service_2).get("password"), "not stored password")
  450. XCTAssertNil(try! Keychain(service: service_3).get("password"), "not stored password")
  451. do { try Keychain(service: service_1).set(password_1, key: "password") } catch {}
  452. XCTAssertEqual(try! Keychain().get("password"), password_1, "stored password")
  453. XCTAssertEqual(try! Keychain(service: service_1).get("password"), password_1, "stored password")
  454. XCTAssertNil(try! Keychain(service: service_2).get("password"), "not stored password")
  455. XCTAssertNil(try! Keychain(service: service_3).get("password"), "not stored password")
  456. do { try Keychain(service: service_2).set(password_2, key: "password") } catch {}
  457. XCTAssertEqual(try! Keychain().get("password"), password_1, "stored password")
  458. XCTAssertEqual(try! Keychain(service: service_1).get("password"), password_1, "stored password")
  459. XCTAssertEqual(try! Keychain(service: service_2).get("password"), password_2, "stored password")
  460. XCTAssertNil(try! Keychain(service: service_3).get("password"), "not stored password")
  461. do { try Keychain(service: service_3).set(password_3, key: "password") } catch {}
  462. XCTAssertEqual(try! Keychain().get("password"), password_1, "stored password")
  463. XCTAssertEqual(try! Keychain(service: service_1).get("password"), password_1, "stored password")
  464. XCTAssertEqual(try! Keychain(service: service_2).get("password"), password_2, "stored password")
  465. XCTAssertEqual(try! Keychain(service: service_3).get("password"), password_3, "stored password")
  466. do { try Keychain().remove("username") } catch {}
  467. XCTAssertNil(try! Keychain().get("username"), "removed username")
  468. XCTAssertNil(try! Keychain(service: service_1).get("username"), "removed username")
  469. XCTAssertEqual(try! Keychain(service: service_2).get("username"), username_2, "left username")
  470. XCTAssertEqual(try! Keychain(service: service_3).get("username"), username_3, "left username")
  471. do { try Keychain(service: service_1).remove("username") } catch {}
  472. XCTAssertNil(try! Keychain().get("username"), "removed username")
  473. XCTAssertNil(try! Keychain(service: service_1).get("username"), "removed username")
  474. XCTAssertEqual(try! Keychain(service: service_2).get("username"), username_2, "left username")
  475. XCTAssertEqual(try! Keychain(service: service_3).get("username"), username_3, "left username")
  476. do { try Keychain(service: service_2).remove("username") } catch {}
  477. XCTAssertNil(try! Keychain().get("username"), "removed username")
  478. XCTAssertNil(try! Keychain(service: service_1).get("username"), "removed username")
  479. XCTAssertNil(try! Keychain(service: service_2).get("username"), "removed username")
  480. XCTAssertEqual(try! Keychain(service: service_3).get("username"), username_3, "left username")
  481. do { try Keychain(service: service_3).remove("username") } catch {}
  482. XCTAssertNil(try! Keychain().get("username"), "removed username")
  483. XCTAssertNil(try! Keychain(service: service_1).get("username"), "removed username")
  484. XCTAssertNil(try! Keychain(service: service_2).get("username"), "removed username")
  485. XCTAssertNil(try! Keychain(service: service_3).get("username"), "removed username")
  486. do { try Keychain().remove("password") } catch {}
  487. XCTAssertNil(try! Keychain().get("password"), "removed password")
  488. XCTAssertNil(try! Keychain(service: service_1).get("password"), "removed password")
  489. XCTAssertEqual(try! Keychain(service: service_2).get("password"), password_2, "left password")
  490. XCTAssertEqual(try! Keychain(service: service_3).get("password"), password_3, "left password")
  491. do { try Keychain(service: service_1).remove("password") } catch {}
  492. XCTAssertNil(try! Keychain().get("password"), "removed password")
  493. XCTAssertNil(try! Keychain(service: service_1).get("password"), "removed password")
  494. XCTAssertEqual(try! Keychain(service: service_2).get("password"), password_2, "left password")
  495. XCTAssertEqual(try! Keychain(service: service_3).get("password"), password_3, "left password")
  496. do { try Keychain(service: service_2).remove("password") } catch {}
  497. XCTAssertNil(try! Keychain().get("password"), "removed password")
  498. XCTAssertNil(try! Keychain(service: service_1).get("password"), "removed password")
  499. XCTAssertNil(try! Keychain(service: service_2).get("password"), "removed password")
  500. XCTAssertEqual(try! Keychain(service: service_3).get("password"), password_3, "left password")
  501. do { try Keychain(service: service_3).remove("password") } catch {}
  502. XCTAssertNil(try! Keychain().get("password"), "removed password")
  503. XCTAssertNil(try! Keychain(service: service_2).get("password"), "removed password")
  504. XCTAssertNil(try! Keychain(service: service_2).get("password"), "removed password")
  505. XCTAssertNil(try! Keychain(service: service_2).get("password"), "removed password")
  506. }
  507. // MARK:
  508. func testProperties() {
  509. guard #available(OSX 10.10, *) else {
  510. return
  511. }
  512. let keychain = Keychain()
  513. XCTAssertEqual(keychain.synchronizable, false)
  514. XCTAssertEqual(keychain.synchronizable(true).synchronizable, true)
  515. XCTAssertEqual(keychain.synchronizable(false).synchronizable, false)
  516. XCTAssertEqual(keychain.accessibility(.AfterFirstUnlock).accessibility, Accessibility.AfterFirstUnlock)
  517. XCTAssertEqual(keychain.accessibility(.WhenPasscodeSetThisDeviceOnly, authenticationPolicy: .UserPresence).accessibility, Accessibility.WhenPasscodeSetThisDeviceOnly)
  518. XCTAssertEqual(keychain.accessibility(.WhenPasscodeSetThisDeviceOnly, authenticationPolicy: .UserPresence).authenticationPolicy, AuthenticationPolicy.UserPresence)
  519. XCTAssertNil(keychain.label)
  520. XCTAssertEqual(keychain.label("Label").label, "Label")
  521. XCTAssertNil(keychain.comment)
  522. XCTAssertEqual(keychain.comment("Comment").comment, "Comment")
  523. XCTAssertEqual(keychain.authenticationPrompt("Prompt").authenticationPrompt, "Prompt")
  524. }
  525. // MARK:
  526. #if os(iOS)
  527. func testAllKeys() {
  528. do {
  529. let keychain = Keychain()
  530. keychain["key1"] = "value1"
  531. keychain["key2"] = "value2"
  532. keychain["key3"] = "value3"
  533. let allKeys = keychain.allKeys()
  534. XCTAssertEqual(allKeys.count, 3)
  535. XCTAssertEqual(allKeys.sort(), ["key1", "key2", "key3"])
  536. let allItems = keychain.allItems()
  537. XCTAssertEqual(allItems.count, 3)
  538. let sortedItems = allItems.sort { (item1, item2) -> Bool in
  539. let value1 = item1["value"] as! String
  540. let value2 = item2["value"] as! String
  541. return value1.compare(value2) == NSComparisonResult.OrderedAscending || value1.compare(value2) == NSComparisonResult.OrderedSame
  542. }
  543. XCTAssertEqual(sortedItems[0]["accessGroup"] as? String, "")
  544. XCTAssertEqual(sortedItems[0]["synchronizable"] as? String, "false")
  545. XCTAssertEqual(sortedItems[0]["service"] as? String, "")
  546. XCTAssertEqual(sortedItems[0]["value"] as? String, "value1")
  547. XCTAssertEqual(sortedItems[0]["key"] as? String, "key1")
  548. XCTAssertEqual(sortedItems[0]["class"] as? String, "GenericPassword")
  549. XCTAssertEqual(sortedItems[0]["accessibility"] as? String, "AfterFirstUnlock")
  550. XCTAssertEqual(sortedItems[1]["accessGroup"] as? String, "")
  551. XCTAssertEqual(sortedItems[1]["synchronizable"] as? String, "false")
  552. XCTAssertEqual(sortedItems[1]["service"] as? String, "")
  553. XCTAssertEqual(sortedItems[1]["value"] as? String, "value2")
  554. XCTAssertEqual(sortedItems[1]["key"] as? String, "key2")
  555. XCTAssertEqual(sortedItems[1]["class"] as? String, "GenericPassword")
  556. XCTAssertEqual(sortedItems[1]["accessibility"] as? String, "AfterFirstUnlock")
  557. XCTAssertEqual(sortedItems[2]["accessGroup"] as? String, "")
  558. XCTAssertEqual(sortedItems[2]["synchronizable"] as? String, "false")
  559. XCTAssertEqual(sortedItems[2]["service"] as? String, "")
  560. XCTAssertEqual(sortedItems[2]["value"] as? String, "value3")
  561. XCTAssertEqual(sortedItems[2]["key"] as? String, "key3")
  562. XCTAssertEqual(sortedItems[2]["class"] as? String, "GenericPassword")
  563. XCTAssertEqual(sortedItems[2]["accessibility"] as? String, "AfterFirstUnlock")
  564. }
  565. do {
  566. let keychain = Keychain(service: "service1")
  567. try! keychain
  568. .synchronizable(true)
  569. .accessibility(.WhenUnlockedThisDeviceOnly)
  570. .set("service1_value1", key: "service1_key1")
  571. try! keychain
  572. .synchronizable(false)
  573. .accessibility(.AfterFirstUnlockThisDeviceOnly)
  574. .set("service1_value2", key: "service1_key2")
  575. let allKeys = keychain.allKeys()
  576. XCTAssertEqual(allKeys.count, 2)
  577. XCTAssertEqual(allKeys.sort(), ["service1_key1", "service1_key2"])
  578. let allItems = keychain.allItems()
  579. XCTAssertEqual(allItems.count, 2)
  580. let sortedItems = allItems.sort { (item1, item2) -> Bool in
  581. let value1 = item1["value"] as! String
  582. let value2 = item2["value"] as! String
  583. return value1.compare(value2) == NSComparisonResult.OrderedAscending || value1.compare(value2) == NSComparisonResult.OrderedSame
  584. }
  585. XCTAssertEqual(sortedItems[0]["accessGroup"] as? String, "")
  586. XCTAssertEqual(sortedItems[0]["synchronizable"] as? String, "true")
  587. XCTAssertEqual(sortedItems[0]["service"] as? String, "service1")
  588. XCTAssertEqual(sortedItems[0]["value"] as? String, "service1_value1")
  589. XCTAssertEqual(sortedItems[0]["key"] as? String, "service1_key1")
  590. XCTAssertEqual(sortedItems[0]["class"] as? String, "GenericPassword")
  591. XCTAssertEqual(sortedItems[0]["accessibility"] as? String, "WhenUnlockedThisDeviceOnly")
  592. XCTAssertEqual(sortedItems[1]["accessGroup"] as? String, "")
  593. XCTAssertEqual(sortedItems[1]["synchronizable"] as? String, "false")
  594. XCTAssertEqual(sortedItems[1]["service"] as? String, "service1")
  595. XCTAssertEqual(sortedItems[1]["value"] as? String, "service1_value2")
  596. XCTAssertEqual(sortedItems[1]["key"] as? String, "service1_key2")
  597. XCTAssertEqual(sortedItems[1]["class"] as? String, "GenericPassword")
  598. XCTAssertEqual(sortedItems[1]["accessibility"] as? String, "AfterFirstUnlockThisDeviceOnly")
  599. }
  600. do {
  601. let keychain = Keychain(server: "https://google.com", protocolType: .HTTPS)
  602. try! keychain
  603. .synchronizable(false)
  604. .accessibility(.AlwaysThisDeviceOnly)
  605. .set("google.com_value1", key: "google.com_key1")
  606. try! keychain
  607. .synchronizable(true)
  608. .accessibility(.Always)
  609. .set("google.com_value2", key: "google.com_key2")
  610. let allKeys = keychain.allKeys()
  611. XCTAssertEqual(allKeys.count, 2)
  612. XCTAssertEqual(allKeys.sort(), ["google.com_key1", "google.com_key2"])
  613. let allItems = keychain.allItems()
  614. XCTAssertEqual(allItems.count, 2)
  615. let sortedItems = allItems.sort { (item1, item2) -> Bool in
  616. let value1 = item1["value"] as! String
  617. let value2 = item2["value"] as! String
  618. return value1.compare(value2) == NSComparisonResult.OrderedAscending || value1.compare(value2) == NSComparisonResult.OrderedSame
  619. }
  620. XCTAssertEqual(sortedItems[0]["synchronizable"] as? String, "false")
  621. XCTAssertEqual(sortedItems[0]["value"] as? String, "google.com_value1")
  622. XCTAssertEqual(sortedItems[0]["key"] as? String, "google.com_key1")
  623. XCTAssertEqual(sortedItems[0]["server"] as? String, "google.com")
  624. XCTAssertEqual(sortedItems[0]["class"] as? String, "InternetPassword")
  625. XCTAssertEqual(sortedItems[0]["authenticationType"] as? String, "Default")
  626. XCTAssertEqual(sortedItems[0]["protocol"] as? String, "HTTPS")
  627. XCTAssertEqual(sortedItems[0]["accessibility"] as? String, "AlwaysThisDeviceOnly")
  628. XCTAssertEqual(sortedItems[1]["synchronizable"] as? String, "true")
  629. XCTAssertEqual(sortedItems[1]["value"] as? String, "google.com_value2")
  630. XCTAssertEqual(sortedItems[1]["key"] as? String, "google.com_key2")
  631. XCTAssertEqual(sortedItems[1]["server"] as? String, "google.com")
  632. XCTAssertEqual(sortedItems[1]["class"] as? String, "InternetPassword")
  633. XCTAssertEqual(sortedItems[1]["authenticationType"] as? String, "Default")
  634. XCTAssertEqual(sortedItems[1]["protocol"] as? String, "HTTPS")
  635. XCTAssertEqual(sortedItems[1]["accessibility"] as? String, "Always")
  636. }
  637. do {
  638. let allKeys = Keychain.allKeys(.GenericPassword)
  639. XCTAssertEqual(allKeys.count, 5)
  640. let sortedKeys = allKeys.sort { (key1, key2) -> Bool in
  641. return key1.1.compare(key2.1) == NSComparisonResult.OrderedAscending || key1.1.compare(key2.1) == NSComparisonResult.OrderedSame
  642. }
  643. XCTAssertEqual(sortedKeys[0].0, "")
  644. XCTAssertEqual(sortedKeys[0].1, "key1")
  645. XCTAssertEqual(sortedKeys[1].0, "")
  646. XCTAssertEqual(sortedKeys[1].1, "key2")
  647. XCTAssertEqual(sortedKeys[2].0, "")
  648. XCTAssertEqual(sortedKeys[2].1, "key3")
  649. XCTAssertEqual(sortedKeys[3].0, "service1")
  650. XCTAssertEqual(sortedKeys[3].1, "service1_key1")
  651. XCTAssertEqual(sortedKeys[4].0, "service1")
  652. XCTAssertEqual(sortedKeys[4].1, "service1_key2")
  653. }
  654. do {
  655. let allKeys = Keychain.allKeys(.InternetPassword)
  656. XCTAssertEqual(allKeys.count, 2)
  657. let sortedKeys = allKeys.sort { (key1, key2) -> Bool in
  658. return key1.1.compare(key2.1) == NSComparisonResult.OrderedAscending || key1.1.compare(key2.1) == NSComparisonResult.OrderedSame
  659. }
  660. XCTAssertEqual(sortedKeys[0].0, "google.com")
  661. XCTAssertEqual(sortedKeys[0].1, "google.com_key1")
  662. XCTAssertEqual(sortedKeys[1].0, "google.com")
  663. XCTAssertEqual(sortedKeys[1].1, "google.com_key2")
  664. }
  665. }
  666. func testDescription() {
  667. do {
  668. let keychain = Keychain()
  669. XCTAssertEqual(keychain.description, "[]")
  670. XCTAssertEqual(keychain.debugDescription, "[]")
  671. }
  672. }
  673. #endif
  674. // MARK:
  675. func testAuthenticationPolicy() {
  676. guard #available(iOS 9.0, OSX 10.11, *) else {
  677. return
  678. }
  679. do {
  680. let accessibility: Accessibility = .WhenPasscodeSetThisDeviceOnly
  681. let policy: AuthenticationPolicy = [.UserPresence]
  682. let flags = SecAccessControlCreateFlags(rawValue: policy.rawValue)
  683. var error: Unmanaged<CFError>?
  684. let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault, accessibility.rawValue, flags, &error)
  685. XCTAssertNil(error)
  686. XCTAssertNotNil(accessControl)
  687. }
  688. #if os(iOS)
  689. do {
  690. let accessibility: Accessibility = .WhenPasscodeSetThisDeviceOnly
  691. let policy: AuthenticationPolicy = [.UserPresence, .ApplicationPassword]
  692. let flags = SecAccessControlCreateFlags(rawValue: policy.rawValue)
  693. var error: Unmanaged<CFError>?
  694. let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault, accessibility.rawValue, flags, &error)
  695. XCTAssertNil(error)
  696. XCTAssertNotNil(accessControl)
  697. }
  698. do {
  699. let accessibility: Accessibility = .WhenPasscodeSetThisDeviceOnly
  700. let policy: AuthenticationPolicy = [.UserPresence, .ApplicationPassword, .PrivateKeyUsage]
  701. let flags = SecAccessControlCreateFlags(rawValue: policy.rawValue)
  702. var error: Unmanaged<CFError>?
  703. let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault, accessibility.rawValue, flags, &error)
  704. XCTAssertNil(error)
  705. XCTAssertNotNil(accessControl)
  706. }
  707. do {
  708. let accessibility: Accessibility = .WhenPasscodeSetThisDeviceOnly
  709. let policy: AuthenticationPolicy = [.ApplicationPassword]
  710. let flags = SecAccessControlCreateFlags(rawValue: policy.rawValue)
  711. var error: Unmanaged<CFError>?
  712. let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault, accessibility.rawValue, flags, &error)
  713. XCTAssertNil(error)
  714. XCTAssertNotNil(accessControl)
  715. }
  716. do {
  717. let accessibility: Accessibility = .WhenPasscodeSetThisDeviceOnly
  718. let policy: AuthenticationPolicy = [.ApplicationPassword, .PrivateKeyUsage]
  719. let flags = SecAccessControlCreateFlags(rawValue: policy.rawValue)
  720. var error: Unmanaged<CFError>?
  721. let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault, accessibility.rawValue, flags, &error)
  722. XCTAssertNil(error)
  723. XCTAssertNotNil(accessControl)
  724. }
  725. do {
  726. let accessibility: Accessibility = .WhenPasscodeSetThisDeviceOnly
  727. let policy: AuthenticationPolicy = [.PrivateKeyUsage]
  728. let flags = SecAccessControlCreateFlags(rawValue: policy.rawValue)
  729. var error: Unmanaged<CFError>?
  730. let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault, accessibility.rawValue, flags, &error)
  731. XCTAssertNil(error)
  732. XCTAssertNotNil(accessControl)
  733. }
  734. do {
  735. let accessibility: Accessibility = .WhenPasscodeSetThisDeviceOnly
  736. let policy: AuthenticationPolicy = [.TouchIDAny]
  737. let flags = SecAccessControlCreateFlags(rawValue: policy.rawValue)
  738. var error: Unmanaged<CFError>?
  739. let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault, accessibility.rawValue, flags, &error)
  740. XCTAssertNil(error)
  741. XCTAssertNotNil(accessControl)
  742. }
  743. do {
  744. let accessibility: Accessibility = .WhenPasscodeSetThisDeviceOnly
  745. let policy: AuthenticationPolicy = [.TouchIDAny, .DevicePasscode]
  746. let flags = SecAccessControlCreateFlags(rawValue: policy.rawValue)
  747. var error: Unmanaged<CFError>?
  748. let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault, accessibility.rawValue, flags, &error)
  749. XCTAssertNil(error)
  750. XCTAssertNotNil(accessControl)
  751. }
  752. do {
  753. let accessibility: Accessibility = .WhenPasscodeSetThisDeviceOnly
  754. let policy: AuthenticationPolicy = [.TouchIDAny, .ApplicationPassword]
  755. let flags = SecAccessControlCreateFlags(rawValue: policy.rawValue)
  756. var error: Unmanaged<CFError>?
  757. let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault, accessibility.rawValue, flags, &error)
  758. XCTAssertNil(error)
  759. XCTAssertNotNil(accessControl)
  760. }
  761. do {
  762. let accessibility: Accessibility = .WhenPasscodeSetThisDeviceOnly
  763. let policy: AuthenticationPolicy = [.TouchIDAny, .ApplicationPassword, .PrivateKeyUsage]
  764. let flags = SecAccessControlCreateFlags(rawValue: policy.rawValue)
  765. var error: Unmanaged<CFError>?
  766. let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault, accessibility.rawValue, flags, &error)
  767. XCTAssertNil(error)
  768. XCTAssertNotNil(accessControl)
  769. }
  770. do {
  771. let accessibility: Accessibility = .WhenPasscodeSetThisDeviceOnly
  772. let policy: AuthenticationPolicy = [.TouchIDCurrentSet]
  773. let flags = SecAccessControlCreateFlags(rawValue: policy.rawValue)
  774. var error: Unmanaged<CFError>?
  775. let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault, accessibility.rawValue, flags, &error)
  776. XCTAssertNil(error)
  777. XCTAssertNotNil(accessControl)
  778. }
  779. do {
  780. let accessibility: Accessibility = .WhenPasscodeSetThisDeviceOnly
  781. let policy: AuthenticationPolicy = [.TouchIDCurrentSet, .DevicePasscode]
  782. let flags = SecAccessControlCreateFlags(rawValue: policy.rawValue)
  783. var error: Unmanaged<CFError>?
  784. let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault, accessibility.rawValue, flags, &error)
  785. XCTAssertNil(error)
  786. XCTAssertNotNil(accessControl)
  787. }
  788. do {
  789. let accessibility: Accessibility = .WhenPasscodeSetThisDeviceOnly
  790. let policy: AuthenticationPolicy = [.TouchIDCurrentSet, .ApplicationPassword]
  791. let flags = SecAccessControlCreateFlags(rawValue: policy.rawValue)
  792. var error: Unmanaged<CFError>?
  793. let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault, accessibility.rawValue, flags, &error)
  794. XCTAssertNil(error)
  795. XCTAssertNotNil(accessControl)
  796. }
  797. do {
  798. let accessibility: Accessibility = .WhenPasscodeSetThisDeviceOnly
  799. let policy: AuthenticationPolicy = [.TouchIDCurrentSet, .ApplicationPassword, .PrivateKeyUsage]
  800. let flags = SecAccessControlCreateFlags(rawValue: policy.rawValue)
  801. var error: Unmanaged<CFError>?
  802. let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault, accessibility.rawValue, flags, &error)
  803. XCTAssertNil(error)
  804. XCTAssertNotNil(accessControl)
  805. }
  806. do {
  807. let accessibility: Accessibility = .WhenPasscodeSetThisDeviceOnly
  808. let policy: AuthenticationPolicy = [.TouchIDAny, .Or, .DevicePasscode]
  809. let flags = SecAccessControlCreateFlags(rawValue: policy.rawValue)
  810. var error: Unmanaged<CFError>?
  811. let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault, accessibility.rawValue, flags, &error)
  812. XCTAssertNil(error)
  813. XCTAssertNotNil(accessControl)
  814. }
  815. do {
  816. let accessibility: Accessibility = .WhenPasscodeSetThisDeviceOnly
  817. let policy: AuthenticationPolicy = [.TouchIDAny, .And, .DevicePasscode]
  818. let flags = SecAccessControlCreateFlags(rawValue: policy.rawValue)
  819. var error: Unmanaged<CFError>?
  820. let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault, accessibility.rawValue, flags, &error)
  821. XCTAssertNil(error)
  822. XCTAssertNotNil(accessControl)
  823. }
  824. #endif
  825. #if os(OSX)
  826. do {
  827. let accessibility: Accessibility = .WhenPasscodeSetThisDeviceOnly
  828. let policy: AuthenticationPolicy = [.UserPresence]
  829. let flags = SecAccessControlCreateFlags(rawValue: policy.rawValue)
  830. var error: Unmanaged<CFError>?
  831. let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault, accessibility.rawValue, flags, &error)
  832. XCTAssertNil(error)
  833. XCTAssertNotNil(accessControl)
  834. }
  835. do {
  836. let accessibility: Accessibility = .WhenPasscodeSetThisDeviceOnly
  837. let policy: AuthenticationPolicy = [.DevicePasscode]
  838. let flags = SecAccessControlCreateFlags(rawValue: policy.rawValue)
  839. var error: Unmanaged<CFError>?
  840. let accessControl = SecAccessControlCreateWithFlags(kCFAllocatorDefault, accessibility.rawValue, flags, &error)
  841. XCTAssertNil(error)
  842. XCTAssertNotNil(accessControl)
  843. }
  844. #endif
  845. }
  846. }