From 96dbd96527be8e7df90506893d3e737ab8309944 Mon Sep 17 00:00:00 2001 From: Maurice Parker Date: Tue, 12 Nov 2019 19:24:07 -0600 Subject: [PATCH] Change keychain accessiblity to allow access when the device is locked. Issue #1292 --- .../Credentials/CredentialsManager.swift | 28 +++++++++---------- .../Feedbin/FeedbinAccountDelegate.swift | 20 ------------- 2 files changed, 14 insertions(+), 34 deletions(-) diff --git a/Frameworks/Account/Credentials/CredentialsManager.swift b/Frameworks/Account/Credentials/CredentialsManager.swift index b52b6c30c..1043d9f6d 100644 --- a/Frameworks/Account/Credentials/CredentialsManager.swift +++ b/Frameworks/Account/Credentials/CredentialsManager.swift @@ -20,11 +20,12 @@ public struct CredentialsManager { }() public static func storeCredentials(_ credentials: Credentials, server: String) throws { - + var query: [String: Any] = [kSecClass as String: kSecClassInternetPassword, - kSecAttrAccount as String: credentials.username, - kSecAttrServer as String: server] - + kSecAttrAccessible as String: kSecAttrAccessibleAfterFirstUnlock, + kSecAttrAccount as String: credentials.username, + kSecAttrServer as String: server] + if credentials.type != .basic { query[kSecAttrSecurityDomain as String] = credentials.type.rawValue } @@ -32,26 +33,25 @@ public struct CredentialsManager { if let securityGroup = keychainGroup { query[kSecAttrAccessGroup as String] = securityGroup } - + let secretData = credentials.secret.data(using: String.Encoding.utf8)! - let attributes: [String: Any] = [kSecValueData as String: secretData] - let status = SecItemUpdate(query as CFDictionary, attributes as CFDictionary) - + query[kSecValueData as String] = secretData + + let status = SecItemAdd(query as CFDictionary, nil) + switch status { case errSecSuccess: return - case errSecItemNotFound: + case errSecDuplicateItem: break default: throw CredentialsError.unhandledError(status: status) } - guard status == errSecItemNotFound else { - return - } + var deleteQuery = query + deleteQuery.removeValue(forKey: kSecAttrAccessible as String) + SecItemDelete(deleteQuery as CFDictionary) - query[kSecValueData as String] = secretData - let addStatus = SecItemAdd(query as CFDictionary, nil) if addStatus != errSecSuccess { throw CredentialsError.unhandledError(status: status) diff --git a/Frameworks/Account/Feedbin/FeedbinAccountDelegate.swift b/Frameworks/Account/Feedbin/FeedbinAccountDelegate.swift index 50eb9356c..ea3027a4f 100644 --- a/Frameworks/Account/Feedbin/FeedbinAccountDelegate.swift +++ b/Frameworks/Account/Feedbin/FeedbinAccountDelegate.swift @@ -78,7 +78,6 @@ final class FeedbinAccountDelegate: AccountDelegate { } func refreshAll(for account: Account, completion: @escaping (Result) -> Void) { - retrieveCredentialsIfNecessary(account) refreshProgress.addToNumberOfTasksAndRemaining(5) @@ -112,7 +111,6 @@ final class FeedbinAccountDelegate: AccountDelegate { } func sendArticleStatus(for account: Account, completion: @escaping ((Result) -> Void)) { - retrieveCredentialsIfNecessary(account) os_log(.debug, log: log, "Sending article statuses...") @@ -169,7 +167,6 @@ final class FeedbinAccountDelegate: AccountDelegate { } func refreshArticleStatus(for account: Account, completion: @escaping ((Result) -> Void)) { - retrieveCredentialsIfNecessary(account) os_log(.debug, log: log, "Refreshing article statuses...") @@ -216,7 +213,6 @@ final class FeedbinAccountDelegate: AccountDelegate { } func importOPML(for account:Account, opmlFile: URL, completion: @escaping (Result) -> Void) { - retrieveCredentialsIfNecessary(account) var fileData: Data? @@ -263,7 +259,6 @@ final class FeedbinAccountDelegate: AccountDelegate { } func addFolder(for account: Account, name: String, completion: @escaping (Result) -> Void) { - retrieveCredentialsIfNecessary(account) if let folder = account.ensureFolder(with: name) { completion(.success(folder)) } else { @@ -272,7 +267,6 @@ final class FeedbinAccountDelegate: AccountDelegate { } func renameFolder(for account: Account, with folder: Folder, to name: String, completion: @escaping (Result) -> Void) { - retrieveCredentialsIfNecessary(account) guard folder.hasAtLeastOneFeed() else { folder.name = name @@ -300,7 +294,6 @@ final class FeedbinAccountDelegate: AccountDelegate { } func removeFolder(for account: Account, with folder: Folder, completion: @escaping (Result) -> Void) { - retrieveCredentialsIfNecessary(account) // Feedbin uses tags and if at least one feed isn't tagged, then the folder doesn't exist on their system guard folder.hasAtLeastOneFeed() else { @@ -364,7 +357,6 @@ final class FeedbinAccountDelegate: AccountDelegate { } func createFeed(for account: Account, url: String, name: String?, container: Container, completion: @escaping (Result) -> Void) { - retrieveCredentialsIfNecessary(account) refreshProgress.addToNumberOfTasksAndRemaining(1) caller.createSubscription(url: url) { result in @@ -397,7 +389,6 @@ final class FeedbinAccountDelegate: AccountDelegate { } func renameFeed(for account: Account, with feed: Feed, to name: String, completion: @escaping (Result) -> Void) { - retrieveCredentialsIfNecessary(account) // This error should never happen guard let subscriptionID = feed.subscriptionID else { @@ -433,7 +424,6 @@ final class FeedbinAccountDelegate: AccountDelegate { } func moveFeed(for account: Account, with feed: Feed, from: Container, to: Container, completion: @escaping (Result) -> Void) { - retrieveCredentialsIfNecessary(account) if from is Account { addFeed(for: account, with: feed, to: to, completion: completion) } else { @@ -449,7 +439,6 @@ final class FeedbinAccountDelegate: AccountDelegate { } func addFeed(for account: Account, with feed: Feed, to container: Container, completion: @escaping (Result) -> Void) { - retrieveCredentialsIfNecessary(account) if let folder = container as? Folder, let feedID = Int(feed.feedID) { refreshProgress.addToNumberOfTasksAndRemaining(1) @@ -482,7 +471,6 @@ final class FeedbinAccountDelegate: AccountDelegate { } func restoreFeed(for account: Account, feed: Feed, container: Container, completion: @escaping (Result) -> Void) { - retrieveCredentialsIfNecessary(account) if let existingFeed = account.existingFeed(withURL: feed.url) { account.addFeed(existingFeed, to: container) { result in @@ -507,7 +495,6 @@ final class FeedbinAccountDelegate: AccountDelegate { } func restoreFolder(for account: Account, folder: Folder, completion: @escaping (Result) -> Void) { - retrieveCredentialsIfNecessary(account) let group = DispatchGroup() @@ -536,7 +523,6 @@ final class FeedbinAccountDelegate: AccountDelegate { } func markArticles(for account: Account, articles: Set
, statusKey: ArticleStatus.Key, flag: Bool) -> Set
? { - retrieveCredentialsIfNecessary(account) let syncStatuses = articles.map { article in return SyncStatus(articleID: article.articleID, key: statusKey, flag: flag) @@ -1308,11 +1294,5 @@ private extension FeedbinAccountDelegate { } } - - func retrieveCredentialsIfNecessary(_ account: Account) { - if credentials == nil { - credentials = try? account.retrieveCredentials(type: .basic) - } - } }