Merge pull request #7240 from nextcloud/bugfix/mac-vfs-login-loop

This commit is contained in:
Claudio Cambra 2024-10-11 16:43:27 +08:00 коммит произвёл GitHub
Родитель 7b826d5ef2 690303f952
Коммит b68da202e4
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
6 изменённых файлов: 66 добавлений и 16 удалений

Просмотреть файл

@ -19,6 +19,10 @@ import NextcloudKit
import NextcloudFileProviderKit
import OSLog
let AuthenticationTimeouts: [UInt64] = [ // Have progressively longer timeouts to not hammer server
3_000_000_000, 6_000_000_000, 30_000_000_000, 60_000_000_000, 120_000_000_000, 300_000_000_000
]
extension FileProviderExtension: NSFileProviderServicing, ChangeNotificationInterface {
/*
This FileProviderExtension extension contains everything needed to communicate with the client.
@ -100,14 +104,57 @@ extension FileProviderExtension: NSFileProviderServicing, ChangeNotificationInte
}
}
@objc func setupDomainAccount(user: String, serverUrl: String, password: String) {
let newNcAccount = Account(user: user, serverUrl: serverUrl, password: password)
@objc func setupDomainAccount(
user: String, userId: String, serverUrl: String, password: String
) {
let semaphore = DispatchSemaphore(value: 0)
var authAttemptState = AuthenticationAttemptResultState.connectionError // default
Task {
let authTestNcKit = NextcloudKit()
authTestNcKit.setup(user: user, userId: userId, password: password, urlBase: serverUrl)
// Retry a few times if we have a connection issue
for authTimeout in AuthenticationTimeouts {
authAttemptState = await authTestNcKit.tryAuthenticationAttempt()
guard authAttemptState == .connectionError else { break }
Logger.fileProviderExtension.info(
"\(user, privacy: .public) authentication try timed out. Trying again soon."
)
try? await Task.sleep(nanoseconds: authTimeout)
}
semaphore.signal()
}
semaphore.wait()
switch (authAttemptState) {
case .authenticationError:
Logger.fileProviderExtension.info(
"\(user, privacy: .public) authentication failed due to bad creds, stopping"
)
return
case .connectionError:
// Despite multiple connection attempts we are still getting connection issues, so quit.
Logger.fileProviderExtension.info(
"\(user, privacy: .public) authentication try failed, no connection."
)
return
case .success:
Logger.fileProviderExtension.info(
"""
Authenticated! Nextcloud account set up in File Provider extension.
User: \(user, privacy: .public) at server: \(serverUrl, privacy: .public)
"""
)
}
let newNcAccount = Account(user: user, id: userId, serverUrl: serverUrl, password: password)
guard newNcAccount != ncAccount else { return }
ncAccount = newNcAccount
ncKit.setup(
account: newNcAccount.ncKitAccount,
user: newNcAccount.username,
userId: newNcAccount.username,
userId: newNcAccount.id,
password: newNcAccount.password,
urlBase: newNcAccount.serverUrl,
userAgent: "Nextcloud-macOS/FileProviderExt",
@ -118,11 +165,6 @@ extension FileProviderExtension: NSFileProviderServicing, ChangeNotificationInte
remoteInterface: ncKit, changeNotificationInterface: self, domain: domain
)
ncKit.setup(delegate: changeObserver)
Logger.fileProviderExtension.info(
"Nextcloud account set up in File Provider extension for user: \(user, privacy: .public) at server: \(serverUrl, privacy: .public)"
)
signalEnumeratorAfterAccountSetup()
}

Просмотреть файл

@ -46,13 +46,14 @@ class FileProviderSocketLineProcessor: NSObject, LineProcessor {
delegate.removeAccountConfig()
} else if command == "ACCOUNT_DETAILS" {
guard let accountDetailsSubsequence = splitLine.last else { return }
let splitAccountDetails = accountDetailsSubsequence.split(separator: "~", maxSplits: 2)
let splitAccountDetails = accountDetailsSubsequence.split(separator: "~", maxSplits: 3)
let user = String(splitAccountDetails[0])
let serverUrl = String(splitAccountDetails[1])
let password = String(splitAccountDetails[2])
let userId = String(splitAccountDetails[1])
let serverUrl = String(splitAccountDetails[2])
let password = String(splitAccountDetails[3])
delegate.setupDomainAccount(user: user, serverUrl: serverUrl, password: password)
delegate.setupDomainAccount(user: user, userId: userId, serverUrl: serverUrl, password: password)
}
}
}

Просмотреть файл

@ -21,6 +21,7 @@
- (void)getExtensionAccountIdWithCompletionHandler:(void(^)(NSString *extensionAccountId, NSError *error))completionHandler;
- (void)configureAccountWithUser:(NSString *)user
userId:(NSString *)userId
serverUrl:(NSString *)serverUrl
password:(NSString *)password;
- (void)removeAccountConfig;

Просмотреть файл

@ -48,11 +48,13 @@ class ClientCommunicationService: NSObject, NSFileProviderServiceSource, NSXPCLi
completionHandler(accountUserId, nil)
}
func configureAccount(withUser user: String,
func configureAccount(withUser user: String,
userId: String,
serverUrl: String,
password: String) {
Logger.desktopClientConnection.info("Received configure account information over client communication service")
self.fpExtension.setupDomainAccount(user: user,
userId: userId,
serverUrl: serverUrl,
password: password)
}

Просмотреть файл

@ -213,13 +213,15 @@ void FileProviderSocketController::sendAccountDetails() const
const auto credentials = account->credentials();
Q_ASSERT(credentials);
const auto accountUser = account->davUser();
const auto accountUrl = account->url().toString();
const auto accountPassword = credentials->password();
const auto accountUser = credentials->user(); // User-provided username/email
const auto accountUserId = account->davUser(); // Backing user id on server
const auto accountUrl = account->url().toString(); // Server base URL
const auto accountPassword = credentials->password(); // Account password
// We cannot use colons as separators here due to "https://" in the url
const auto message = QString(QStringLiteral("ACCOUNT_DETAILS:") +
accountUser + "~" +
accountUserId + "~" +
accountUrl + "~" +
accountPassword);
sendMessage(message);

Просмотреть файл

@ -64,11 +64,13 @@ void FileProviderXPC::authenticateExtension(const QString &extensionAccountId) c
const auto account = accountState->account();
const auto credentials = account->credentials();
NSString *const user = credentials->user().toNSString();
NSString *const userId = account->davUser().toNSString();
NSString *const serverUrl = account->url().toString().toNSString();
NSString *const password = credentials->password().toNSString();
const auto clientCommService = (NSObject<ClientCommunicationProtocol> *)_clientCommServices.value(extensionAccountId);
[clientCommService configureAccountWithUser:user
userId:userId
serverUrl:serverUrl
password:password];
}