mirror of
https://github.com/Ranchero-Software/NetNewsWire
synced 2025-08-12 06:26:36 +00:00
Convert validateCredentials to async/await.
This commit is contained in:
@@ -373,16 +373,16 @@ public enum FetchType {
|
||||
try CredentialsManager.removeCredentials(type: type, server: server, username: username)
|
||||
}
|
||||
|
||||
public static func validateCredentials(transport: Transport = URLSession.webserviceTransport(), type: AccountType, credentials: Credentials, endpoint: URL? = nil, completion: @escaping (Result<Credentials?, Error>) -> Void) {
|
||||
public static func validateCredentials(transport: Transport = URLSession.webserviceTransport(), type: AccountType, credentials: Credentials, endpoint: URL? = nil) async throws -> Credentials? {
|
||||
switch type {
|
||||
case .feedbin:
|
||||
FeedbinAccountDelegate.validateCredentials(transport: transport, credentials: credentials, completion: completion)
|
||||
return try await FeedbinAccountDelegate.validateCredentials(transport: transport, credentials: credentials)
|
||||
case .newsBlur:
|
||||
NewsBlurAccountDelegate.validateCredentials(transport: transport, credentials: credentials, completion: completion)
|
||||
return try await NewsBlurAccountDelegate.validateCredentials(transport: transport, credentials: credentials)
|
||||
case .freshRSS, .inoreader, .bazQux, .theOldReader:
|
||||
ReaderAPIAccountDelegate.validateCredentials(transport: transport, credentials: credentials, endpoint: endpoint, completion: completion)
|
||||
return try await ReaderAPIAccountDelegate.validateCredentials(transport: transport, credentials: credentials, endpoint: endpoint)
|
||||
default:
|
||||
break
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ import Secrets
|
||||
|
||||
func accountWillBeDeleted(_ account: Account)
|
||||
|
||||
static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL?, completion: @escaping (Result<Credentials?, Error>) -> Void)
|
||||
static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL?) async throws -> Credentials?
|
||||
|
||||
/// Suspend all network activity
|
||||
func suspendNetwork()
|
||||
|
||||
@@ -612,16 +612,21 @@ public enum FeedbinAccountDelegateError: String, Error {
|
||||
func accountWillBeDeleted(_ account: Account) {
|
||||
}
|
||||
|
||||
static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL? = nil, completion: @escaping (Result<Credentials?, Error>) -> Void) {
|
||||
static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL? = nil) async throws -> Credentials? {
|
||||
|
||||
let caller = FeedbinAPICaller(transport: transport)
|
||||
caller.credentials = credentials
|
||||
caller.validateCredentials() { result in
|
||||
DispatchQueue.main.async {
|
||||
completion(result)
|
||||
|
||||
return try await withCheckedThrowingContinuation { continuation in
|
||||
caller.validateCredentials() { result in
|
||||
switch result {
|
||||
case .success(let credentials):
|
||||
continuation.resume(returning: credentials)
|
||||
case .failure(let error):
|
||||
continuation.resume(throwing: error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: Suspend and Resume (for iOS)
|
||||
|
||||
@@ -205,8 +205,8 @@ final class LocalAccountDelegate: AccountDelegate, Logging {
|
||||
func accountWillBeDeleted(_ account: Account) {
|
||||
}
|
||||
|
||||
static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL? = nil, completion: (Result<Credentials?, Error>) -> Void) {
|
||||
return completion(.success(nil))
|
||||
static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL? = nil) async throws -> Credentials? {
|
||||
nil
|
||||
}
|
||||
|
||||
// MARK: Suspend and Resume (for iOS)
|
||||
|
||||
@@ -649,14 +649,21 @@ final class NewsBlurAccountDelegate: AccountDelegate, Logging {
|
||||
caller.logout() { _ in }
|
||||
}
|
||||
|
||||
class func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL? = nil, completion: @escaping (Result<Credentials?, Error>) -> ()) {
|
||||
static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL? = nil) async throws -> Credentials? {
|
||||
|
||||
let caller = NewsBlurAPICaller(transport: transport) { url, credentials in
|
||||
URLRequest(url: url, credentials: credentials)
|
||||
}
|
||||
caller.credentials = credentials
|
||||
caller.validateCredentials() { result in
|
||||
DispatchQueue.main.async {
|
||||
completion(result)
|
||||
|
||||
return try await withCheckedThrowingContinuation { continuation in
|
||||
caller.validateCredentials() { result in
|
||||
switch result {
|
||||
case .success(let credentials):
|
||||
continuation.resume(returning: credentials)
|
||||
case .failure(let error):
|
||||
continuation.resume(throwing: error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -660,17 +660,21 @@ public enum ReaderAPIAccountDelegateError: LocalizedError {
|
||||
func accountWillBeDeleted(_ account: Account) {
|
||||
}
|
||||
|
||||
static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL?, completion: @escaping (Result<Credentials?, Error>) -> Void) {
|
||||
static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL? = nil) async throws -> Credentials? {
|
||||
guard let endpoint = endpoint else {
|
||||
completion(.failure(TransportError.noURL))
|
||||
return
|
||||
throw TransportError.noURL
|
||||
}
|
||||
|
||||
ReaderAPICaller.validateCredentials(credentials: credentials, transport: transport, endpoint: endpoint, variant: .generic) { url, credentials in
|
||||
URLRequest(url: url, credentials: credentials)
|
||||
} completion: { result in
|
||||
Task { @MainActor in
|
||||
completion(result)
|
||||
return try await withCheckedThrowingContinuation { continuation in
|
||||
ReaderAPICaller.validateCredentials(credentials: credentials, transport: transport, endpoint: endpoint, variant: .generic) { url, credentials in
|
||||
URLRequest(url: url, credentials: credentials)
|
||||
} completion: { result in
|
||||
switch result {
|
||||
case .success(let credentials):
|
||||
continuation.resume(returning: credentials)
|
||||
case .failure(let error):
|
||||
continuation.resume(throwing: error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -474,8 +474,8 @@ final class CloudKitAccountDelegate: AccountDelegate, Logging {
|
||||
articlesZone.resetChangeToken()
|
||||
}
|
||||
|
||||
static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL? = nil, completion: (Result<Credentials?, Error>) -> Void) {
|
||||
return completion(.success(nil))
|
||||
static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL? = nil) async throws -> Credentials? {
|
||||
nil
|
||||
}
|
||||
|
||||
// MARK: Suspend and Resume (for iOS)
|
||||
|
||||
@@ -573,9 +573,9 @@ final class FeedlyAccountDelegate: AccountDelegate, Logging {
|
||||
MainThreadOperationQueue.shared.add(logout)
|
||||
}
|
||||
|
||||
static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL?, completion: @escaping (Result<Credentials?, Error>) -> Void) {
|
||||
static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL? = nil) async throws -> Credentials? {
|
||||
assertionFailure("An `account` instance should enqueue an \(FeedlyRefreshAccessTokenOperation.self) instead.")
|
||||
completion(.success(credentials))
|
||||
return credentials
|
||||
}
|
||||
|
||||
// MARK: Suspend and Resume (for iOS)
|
||||
|
||||
@@ -62,73 +62,64 @@ import Secrets
|
||||
}
|
||||
|
||||
@IBAction func action(_ sender: Any) {
|
||||
|
||||
|
||||
self.errorMessageLabel.stringValue = ""
|
||||
|
||||
|
||||
guard !usernameTextField.stringValue.isEmpty && !passwordTextField.stringValue.isEmpty else {
|
||||
self.errorMessageLabel.stringValue = LocalizedNetNewsWireError.userNameAndPasswordRequired.localizedDescription
|
||||
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
guard account != nil || !AccountManager.shared.duplicateServiceAccount(type: .feedbin, username: usernameTextField.stringValue) else {
|
||||
self.errorMessageLabel.stringValue = LocalizedNetNewsWireError.duplicateAccount.localizedDescription
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
actionButton.isEnabled = false
|
||||
progressIndicator.isHidden = false
|
||||
progressIndicator.startAnimation(self)
|
||||
|
||||
let credentials = Credentials(type: .basic, username: usernameTextField.stringValue, secret: passwordTextField.stringValue)
|
||||
Account.validateCredentials(type: .feedbin, credentials: credentials) { [weak self] result in
|
||||
|
||||
guard let self = self else { return }
|
||||
|
||||
self.actionButton.isEnabled = true
|
||||
self.progressIndicator.isHidden = true
|
||||
self.progressIndicator.stopAnimation(self)
|
||||
|
||||
switch result {
|
||||
case .success(let validatedCredentials):
|
||||
|
||||
guard let validatedCredentials = validatedCredentials else {
|
||||
self.errorMessageLabel.stringValue = LocalizedNetNewsWireError.invalidUsernameOrPassword.localizedDescription
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if self.account == nil {
|
||||
self.account = AccountManager.shared.createAccount(type: .feedbin)
|
||||
}
|
||||
|
||||
do {
|
||||
try self.account?.removeCredentials(type: .basic)
|
||||
try self.account?.storeCredentials(validatedCredentials)
|
||||
|
||||
self.account?.refreshAll() { result in
|
||||
switch result {
|
||||
case .success:
|
||||
break
|
||||
case .failure(let error):
|
||||
NSApplication.shared.presentError(error)
|
||||
}
|
||||
let credentials = Credentials(type: .basic, username: usernameTextField.stringValue, secret: passwordTextField.stringValue)
|
||||
|
||||
Task { @MainActor in
|
||||
do {
|
||||
let validatedCredentials = try await Account.validateCredentials(type: .feedbin, credentials: credentials)
|
||||
if let validatedCredentials {
|
||||
if self.account == nil {
|
||||
self.account = AccountManager.shared.createAccount(type: .feedbin)
|
||||
}
|
||||
|
||||
self.hostWindow?.endSheet(self.window!, returnCode: NSApplication.ModalResponse.OK)
|
||||
} catch {
|
||||
self.errorMessageLabel.stringValue = LocalizedNetNewsWireError.keychainError.localizedDescription
|
||||
self.logger.error("Keychain error while storing credentials: \(error.localizedDescription, privacy: .public)")
|
||||
do {
|
||||
try self.account?.removeCredentials(type: .basic)
|
||||
try self.account?.storeCredentials(validatedCredentials)
|
||||
|
||||
self.account?.refreshAll() { result in
|
||||
switch result {
|
||||
case .success:
|
||||
break
|
||||
case .failure(let error):
|
||||
NSApplication.shared.presentError(error)
|
||||
}
|
||||
}
|
||||
|
||||
self.hostWindow?.endSheet(self.window!, returnCode: NSApplication.ModalResponse.OK)
|
||||
} catch {
|
||||
self.errorMessageLabel.stringValue = LocalizedNetNewsWireError.keychainError.localizedDescription
|
||||
self.logger.error("Keychain error while storing credentials: \(error.localizedDescription, privacy: .public)")
|
||||
}
|
||||
}
|
||||
|
||||
case .failure:
|
||||
|
||||
else {
|
||||
self.errorMessageLabel.stringValue = LocalizedNetNewsWireError.invalidUsernameOrPassword.localizedDescription
|
||||
}
|
||||
} catch {
|
||||
self.errorMessageLabel.stringValue = LocalizedNetNewsWireError.networkError.localizedDescription
|
||||
|
||||
}
|
||||
|
||||
|
||||
actionButton.isEnabled = true
|
||||
progressIndicator.isHidden = true
|
||||
progressIndicator.stopAnimation(self)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@IBAction func createAccountWithProvider(_ sender: Any) {
|
||||
|
||||
@@ -77,49 +77,46 @@ import Secrets
|
||||
progressIndicator.startAnimation(self)
|
||||
|
||||
let credentials = Credentials(type: .newsBlurBasic, username: usernameTextField.stringValue, secret: passwordTextField.stringValue)
|
||||
Account.validateCredentials(type: .newsBlur, credentials: credentials) { [weak self] result in
|
||||
|
||||
guard let self = self else { return }
|
||||
Task { @MainActor in
|
||||
do {
|
||||
let validatedCredentials = try await Account.validateCredentials(type: .newsBlur, credentials: credentials)
|
||||
if let validatedCredentials {
|
||||
if self.account == nil {
|
||||
self.account = AccountManager.shared.createAccount(type: .newsBlur)
|
||||
}
|
||||
|
||||
do {
|
||||
try self.account?.removeCredentials(type: .newsBlurBasic)
|
||||
try self.account?.removeCredentials(type: .newsBlurSessionID)
|
||||
try self.account?.storeCredentials(credentials)
|
||||
try self.account?.storeCredentials(validatedCredentials)
|
||||
|
||||
self.account?.refreshAll() { result in
|
||||
switch result {
|
||||
case .success:
|
||||
break
|
||||
case .failure(let error):
|
||||
NSApplication.shared.presentError(error)
|
||||
}
|
||||
}
|
||||
|
||||
self.hostWindow?.endSheet(self.window!, returnCode: NSApplication.ModalResponse.OK)
|
||||
} catch {
|
||||
self.errorMessageLabel.stringValue = LocalizedNetNewsWireError.keychainError.localizedDescription
|
||||
self.logger.error("Keychain error while storing credentials: \(error.localizedDescription, privacy: .public)")
|
||||
}
|
||||
}
|
||||
else {
|
||||
self.errorMessageLabel.stringValue = LocalizedNetNewsWireError.invalidUsernameOrPassword.localizedDescription
|
||||
}
|
||||
} catch {
|
||||
self.errorMessageLabel.stringValue = LocalizedNetNewsWireError.networkError.localizedDescription
|
||||
}
|
||||
|
||||
self.actionButton.isEnabled = true
|
||||
self.progressIndicator.isHidden = true
|
||||
self.progressIndicator.stopAnimation(self)
|
||||
|
||||
switch result {
|
||||
case .success(let validatedCredentials):
|
||||
guard let validatedCredentials = validatedCredentials else {
|
||||
self.errorMessageLabel.stringValue = LocalizedNetNewsWireError.invalidUsernameOrPassword.localizedDescription
|
||||
return
|
||||
}
|
||||
|
||||
if self.account == nil {
|
||||
self.account = AccountManager.shared.createAccount(type: .newsBlur)
|
||||
}
|
||||
|
||||
do {
|
||||
try self.account?.removeCredentials(type: .newsBlurBasic)
|
||||
try self.account?.removeCredentials(type: .newsBlurSessionID)
|
||||
try self.account?.storeCredentials(credentials)
|
||||
try self.account?.storeCredentials(validatedCredentials)
|
||||
|
||||
self.account?.refreshAll() { result in
|
||||
switch result {
|
||||
case .success:
|
||||
break
|
||||
case .failure(let error):
|
||||
NSApplication.shared.presentError(error)
|
||||
}
|
||||
}
|
||||
|
||||
self.hostWindow?.endSheet(self.window!, returnCode: NSApplication.ModalResponse.OK)
|
||||
} catch {
|
||||
self.errorMessageLabel.stringValue = LocalizedNetNewsWireError.keychainError.localizedDescription
|
||||
self.logger.error("Keychain error while storing credentials: \(error.localizedDescription, privacy: .public)")
|
||||
}
|
||||
|
||||
case .failure:
|
||||
self.errorMessageLabel.stringValue = LocalizedNetNewsWireError.networkError.localizedDescription
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -133,54 +133,50 @@ import ReaderAPI
|
||||
progressIndicator.startAnimation(self)
|
||||
|
||||
let credentials = Credentials(type: .readerBasic, username: usernameTextField.stringValue, secret: passwordTextField.stringValue)
|
||||
Account.validateCredentials(type: accountType, credentials: credentials, endpoint: apiURL) { [weak self] result in
|
||||
|
||||
guard let self = self else { return }
|
||||
|
||||
|
||||
Task { @MainActor in
|
||||
|
||||
do {
|
||||
let validatedCredentials = try await Account.validateCredentials(type: accountType, credentials: credentials, endpoint: apiURL)
|
||||
if let validatedCredentials {
|
||||
if self.account == nil {
|
||||
self.account = AccountManager.shared.createAccount(type: self.accountType!)
|
||||
}
|
||||
|
||||
do {
|
||||
self.account?.endpointURL = apiURL
|
||||
|
||||
try self.account?.removeCredentials(type: .readerBasic)
|
||||
try self.account?.removeCredentials(type: .readerAPIKey)
|
||||
try self.account?.storeCredentials(credentials)
|
||||
try self.account?.storeCredentials(validatedCredentials)
|
||||
|
||||
self.account?.refreshAll() { result in
|
||||
switch result {
|
||||
case .success:
|
||||
break
|
||||
case .failure(let error):
|
||||
NSApplication.shared.presentError(error)
|
||||
}
|
||||
}
|
||||
|
||||
self.hostWindow?.endSheet(self.window!, returnCode: NSApplication.ModalResponse.OK)
|
||||
} catch {
|
||||
self.errorMessageLabel.stringValue = LocalizedNetNewsWireError.keychainError.localizedDescription
|
||||
self.logger.error("Keychain error while storing credentials: \(error.localizedDescription, privacy: .public)")
|
||||
}
|
||||
}
|
||||
else {
|
||||
self.errorMessageLabel.stringValue = LocalizedNetNewsWireError.invalidUsernameOrPassword.localizedDescription
|
||||
}
|
||||
} catch {
|
||||
self.errorMessageLabel.stringValue = LocalizedNetNewsWireError.networkError.localizedDescription
|
||||
}
|
||||
|
||||
self.actionButton.isEnabled = true
|
||||
self.progressIndicator.isHidden = true
|
||||
self.progressIndicator.stopAnimation(self)
|
||||
|
||||
switch result {
|
||||
case .success(let validatedCredentials):
|
||||
guard let validatedCredentials = validatedCredentials else {
|
||||
self.errorMessageLabel.stringValue = LocalizedNetNewsWireError.invalidUsernameOrPassword.localizedDescription
|
||||
return
|
||||
}
|
||||
|
||||
if self.account == nil {
|
||||
self.account = AccountManager.shared.createAccount(type: self.accountType!)
|
||||
}
|
||||
|
||||
do {
|
||||
self.account?.endpointURL = apiURL
|
||||
|
||||
try self.account?.removeCredentials(type: .readerBasic)
|
||||
try self.account?.removeCredentials(type: .readerAPIKey)
|
||||
try self.account?.storeCredentials(credentials)
|
||||
try self.account?.storeCredentials(validatedCredentials)
|
||||
|
||||
self.account?.refreshAll() { result in
|
||||
switch result {
|
||||
case .success:
|
||||
break
|
||||
case .failure(let error):
|
||||
NSApplication.shared.presentError(error)
|
||||
}
|
||||
}
|
||||
|
||||
self.hostWindow?.endSheet(self.window!, returnCode: NSApplication.ModalResponse.OK)
|
||||
} catch {
|
||||
self.errorMessageLabel.stringValue = LocalizedNetNewsWireError.keychainError.localizedDescription
|
||||
self.logger.error("Keychain error while storing credentials: \(error.localizedDescription, privacy: .public)")
|
||||
}
|
||||
|
||||
case .failure:
|
||||
self.errorMessageLabel.stringValue = LocalizedNetNewsWireError.networkError.localizedDescription
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@IBAction func createAccountWithProvider(_ sender: Any) {
|
||||
|
||||
Reference in New Issue
Block a user