diff --git a/.swiftlint.yml b/.swiftlint.yml index 975ea6f57..c604212fb 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -34,6 +34,7 @@ disabled_rules: - implicit_getter - computed_accessors_order - unneeded_notification_center_removal + - function_parameter_count custom_rules: empty_line_after_guard_statement: included: ".*\\.swift" diff --git a/ownCloud/Bookmarks/BookmarkViewController.swift b/ownCloud/Bookmarks/BookmarkViewController.swift index 8dc74aabe..c3e14b54a 100644 --- a/ownCloud/Bookmarks/BookmarkViewController.swift +++ b/ownCloud/Bookmarks/BookmarkViewController.swift @@ -471,6 +471,7 @@ class BookmarkViewController: StaticTableViewController { } options[.presentingViewControllerKey] = self + options[.requiredUsernameKey] = connectionBookmark.userName guard let bookmarkAuthenticationMethodIdentifier = bookmark?.authenticationMethodIdentifier else { return } diff --git a/ownCloud/Client/ClientAuthenticationUpdater.swift b/ownCloud/Client/ClientAuthenticationUpdater.swift index 9b4150e83..34478fbdd 100644 --- a/ownCloud/Client/ClientAuthenticationUpdater.swift +++ b/ownCloud/Client/ClientAuthenticationUpdater.swift @@ -67,6 +67,7 @@ class ClientAuthenticationUpdater: NSObject { } options[.presentingViewControllerKey] = viewController + options[.requiredUsernameKey] = bookmark.userName tempBookmark.authenticationMethodIdentifier = authenticationMethodID diff --git a/ownCloud/Client/ClientRootViewController.swift b/ownCloud/Client/ClientRootViewController.swift index c95f84a03..e49ed22a6 100644 --- a/ownCloud/Client/ClientRootViewController.swift +++ b/ownCloud/Client/ClientRootViewController.swift @@ -467,6 +467,7 @@ extension ClientRootViewController : OCCoreDelegate { issueNSError.isOCError(withCode: .authorizationMethodNotAllowed) || issueNSError.isOCError(withCode: .authorizationMethodUnknown) || issueNSError.isOCError(withCode: .authorizationNoMethodData) || + issueNSError.isOCError(withCode: .authorizationNotMatchingRequiredUserID) || issueNSError.isOCError(withCode: .authorizationMissingData) { nsError = issueNSError issue = nil @@ -536,46 +537,8 @@ extension ClientRootViewController : OCCoreDelegate { var queueCompletionHandlerScheduled : Bool = false if isAuthFailure { - let alertController = ThemedAlertController(title: authFailureTitle, - message: authFailureMessage, - preferredStyle: .alert) + self?.presentAuthAlert(for: editBookmark, error: nsError, title: authFailureTitle, message: authFailureMessage, ignoreLabel: authFailureIgnoreLabel, ignoreStyle: authFailureIgnoreStyle, hasEditOption: authFailureHasEditOption, preferredAuthenticationMethods: preferredAuthenticationMethods, completionHandler: queueCompletionHandler) - alertController.addAction(UIAlertAction(title: authFailureIgnoreLabel, style: authFailureIgnoreStyle, handler: { (_) in - queueCompletionHandler() - })) - - if authFailureHasEditOption { - alertController.addAction(UIAlertAction(title: "Sign in".localized, style: .default, handler: { (_) in - queueCompletionHandler() - - var notifyAuthDelegate = true - - if let bookmark = self?.bookmark { - let updater = ClientAuthenticationUpdater(with: bookmark, preferredAuthenticationMethods: preferredAuthenticationMethods) - - if updater.canUpdateInline, let self = self { - notifyAuthDelegate = false - - updater.updateAuthenticationData(on: self, completion: { (error) in - if error == nil { - OCSynchronized(self) { - self.skipAuthorizationFailure = false // Auth failure fixed -> allow new failures to prompt for sign in again - } - } - }) - } - } - - if notifyAuthDelegate { - if let authDelegate = self?.authDelegate, let self = self, let nsError = nsError { - authDelegate.handleAuthError(for: self, error: nsError, editBookmark: editBookmark, preferredAuthenticationMethods: preferredAuthenticationMethods) - } - } - - })) - } - - self?.present(alertController, animated: true, completion: nil) queueCompletionHandlerScheduled = true return @@ -666,6 +629,51 @@ extension ClientRootViewController : OCCoreDelegate { } } + func presentAuthAlert(for editBookmark: OCBookmark, error nsError: NSError?, title authFailureTitle: String, message authFailureMessage: String?, ignoreLabel authFailureIgnoreLabel: String, ignoreStyle authFailureIgnoreStyle: UIAlertAction.Style, hasEditOption authFailureHasEditOption: Bool, preferredAuthenticationMethods: [OCAuthenticationMethodIdentifier]?, completionHandler: @escaping () -> Void) { + let alertController = ThemedAlertController(title: authFailureTitle, + message: authFailureMessage, + preferredStyle: .alert) + + alertController.addAction(UIAlertAction(title: authFailureIgnoreLabel, style: authFailureIgnoreStyle, handler: { (_) in + completionHandler() + })) + + if authFailureHasEditOption { + alertController.addAction(UIAlertAction(title: "Sign in".localized, style: .default, handler: { [weak self] (_) in + completionHandler() + + var notifyAuthDelegate = true + + if let bookmark = self?.bookmark { + let updater = ClientAuthenticationUpdater(with: bookmark, preferredAuthenticationMethods: preferredAuthenticationMethods) + + if updater.canUpdateInline, let self = self { + notifyAuthDelegate = false + + updater.updateAuthenticationData(on: self, completion: { (error) in + if error == nil { + OCSynchronized(self) { + self.skipAuthorizationFailure = false // Auth failure fixed -> allow new failures to prompt for sign in again + } + } else if let nsError = error as NSError?, !nsError.isOCError(withCode: .authorizationCancelled) { + // Error updating authentication -> inform the user and provide option to retry + self.alertQueue.async { [weak self] (queueCompletionHandler) in + self?.presentAuthAlert(for: editBookmark, error: error as NSError?, title: "Error".localized, message: error?.localizedDescription, ignoreLabel: authFailureIgnoreLabel, ignoreStyle: authFailureIgnoreStyle, hasEditOption: authFailureHasEditOption, preferredAuthenticationMethods: preferredAuthenticationMethods, completionHandler: queueCompletionHandler) + } + } + }) + } + } + + if notifyAuthDelegate, let authDelegate = self?.authDelegate, let self = self, let nsError = nsError { + authDelegate.handleAuthError(for: self, error: nsError, editBookmark: editBookmark, preferredAuthenticationMethods: preferredAuthenticationMethods) + } + })) + } + + self.present(alertController, animated: true, completion: nil) + } + func presentAlertAsCard(viewController: UIViewController, withHandle: Bool = false, dismissable: Bool = true) { alertQueue.async { [weak self] (queueCompletionHandler) in if let startViewController = self {