Skip to content

Commit b68da20

Browse files
authored
Merge pull request #7240 from nextcloud/bugfix/mac-vfs-login-loop
2 parents 7b826d5 + 690303f commit b68da20

File tree

6 files changed

+66
-16
lines changed

6 files changed

+66
-16
lines changed

shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension+ClientInterface.swift

Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ import NextcloudKit
1919
import NextcloudFileProviderKit
2020
import OSLog
2121

22+
let AuthenticationTimeouts: [UInt64] = [ // Have progressively longer timeouts to not hammer server
23+
3_000_000_000, 6_000_000_000, 30_000_000_000, 60_000_000_000, 120_000_000_000, 300_000_000_000
24+
]
25+
2226
extension FileProviderExtension: NSFileProviderServicing, ChangeNotificationInterface {
2327
/*
2428
This FileProviderExtension extension contains everything needed to communicate with the client.
@@ -100,14 +104,57 @@ extension FileProviderExtension: NSFileProviderServicing, ChangeNotificationInte
100104
}
101105
}
102106

103-
@objc func setupDomainAccount(user: String, serverUrl: String, password: String) {
104-
let newNcAccount = Account(user: user, serverUrl: serverUrl, password: password)
107+
@objc func setupDomainAccount(
108+
user: String, userId: String, serverUrl: String, password: String
109+
) {
110+
let semaphore = DispatchSemaphore(value: 0)
111+
var authAttemptState = AuthenticationAttemptResultState.connectionError // default
112+
Task {
113+
let authTestNcKit = NextcloudKit()
114+
authTestNcKit.setup(user: user, userId: userId, password: password, urlBase: serverUrl)
115+
116+
// Retry a few times if we have a connection issue
117+
for authTimeout in AuthenticationTimeouts {
118+
authAttemptState = await authTestNcKit.tryAuthenticationAttempt()
119+
guard authAttemptState == .connectionError else { break }
120+
121+
Logger.fileProviderExtension.info(
122+
"\(user, privacy: .public) authentication try timed out. Trying again soon."
123+
)
124+
try? await Task.sleep(nanoseconds: authTimeout)
125+
}
126+
semaphore.signal()
127+
}
128+
semaphore.wait()
129+
130+
switch (authAttemptState) {
131+
case .authenticationError:
132+
Logger.fileProviderExtension.info(
133+
"\(user, privacy: .public) authentication failed due to bad creds, stopping"
134+
)
135+
return
136+
case .connectionError:
137+
// Despite multiple connection attempts we are still getting connection issues, so quit.
138+
Logger.fileProviderExtension.info(
139+
"\(user, privacy: .public) authentication try failed, no connection."
140+
)
141+
return
142+
case .success:
143+
Logger.fileProviderExtension.info(
144+
"""
145+
Authenticated! Nextcloud account set up in File Provider extension.
146+
User: \(user, privacy: .public) at server: \(serverUrl, privacy: .public)
147+
"""
148+
)
149+
}
150+
151+
let newNcAccount = Account(user: user, id: userId, serverUrl: serverUrl, password: password)
105152
guard newNcAccount != ncAccount else { return }
106153
ncAccount = newNcAccount
107154
ncKit.setup(
108155
account: newNcAccount.ncKitAccount,
109156
user: newNcAccount.username,
110-
userId: newNcAccount.username,
157+
userId: newNcAccount.id,
111158
password: newNcAccount.password,
112159
urlBase: newNcAccount.serverUrl,
113160
userAgent: "Nextcloud-macOS/FileProviderExt",
@@ -118,11 +165,6 @@ extension FileProviderExtension: NSFileProviderServicing, ChangeNotificationInte
118165
remoteInterface: ncKit, changeNotificationInterface: self, domain: domain
119166
)
120167
ncKit.setup(delegate: changeObserver)
121-
122-
Logger.fileProviderExtension.info(
123-
"Nextcloud account set up in File Provider extension for user: \(user, privacy: .public) at server: \(serverUrl, privacy: .public)"
124-
)
125-
126168
signalEnumeratorAfterAccountSetup()
127169
}
128170

shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderSocketLineProcessor.swift

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,14 @@ class FileProviderSocketLineProcessor: NSObject, LineProcessor {
4646
delegate.removeAccountConfig()
4747
} else if command == "ACCOUNT_DETAILS" {
4848
guard let accountDetailsSubsequence = splitLine.last else { return }
49-
let splitAccountDetails = accountDetailsSubsequence.split(separator: "~", maxSplits: 2)
49+
let splitAccountDetails = accountDetailsSubsequence.split(separator: "~", maxSplits: 3)
5050

5151
let user = String(splitAccountDetails[0])
52-
let serverUrl = String(splitAccountDetails[1])
53-
let password = String(splitAccountDetails[2])
52+
let userId = String(splitAccountDetails[1])
53+
let serverUrl = String(splitAccountDetails[2])
54+
let password = String(splitAccountDetails[3])
5455

55-
delegate.setupDomainAccount(user: user, serverUrl: serverUrl, password: password)
56+
delegate.setupDomainAccount(user: user, userId: userId, serverUrl: serverUrl, password: password)
5657
}
5758
}
5859
}

shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/Services/ClientCommunicationProtocol.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
- (void)getExtensionAccountIdWithCompletionHandler:(void(^)(NSString *extensionAccountId, NSError *error))completionHandler;
2323
- (void)configureAccountWithUser:(NSString *)user
24+
userId:(NSString *)userId
2425
serverUrl:(NSString *)serverUrl
2526
password:(NSString *)password;
2627
- (void)removeAccountConfig;

shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/Services/ClientCommunicationService.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,13 @@ class ClientCommunicationService: NSObject, NSFileProviderServiceSource, NSXPCLi
4848
completionHandler(accountUserId, nil)
4949
}
5050

51-
func configureAccount(withUser user: String,
51+
func configureAccount(withUser user: String,
52+
userId: String,
5253
serverUrl: String,
5354
password: String) {
5455
Logger.desktopClientConnection.info("Received configure account information over client communication service")
5556
self.fpExtension.setupDomainAccount(user: user,
57+
userId: userId,
5658
serverUrl: serverUrl,
5759
password: password)
5860
}

src/gui/macOS/fileprovidersocketcontroller.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -213,13 +213,15 @@ void FileProviderSocketController::sendAccountDetails() const
213213

214214
const auto credentials = account->credentials();
215215
Q_ASSERT(credentials);
216-
const auto accountUser = account->davUser();
217-
const auto accountUrl = account->url().toString();
218-
const auto accountPassword = credentials->password();
216+
const auto accountUser = credentials->user(); // User-provided username/email
217+
const auto accountUserId = account->davUser(); // Backing user id on server
218+
const auto accountUrl = account->url().toString(); // Server base URL
219+
const auto accountPassword = credentials->password(); // Account password
219220

220221
// We cannot use colons as separators here due to "https://" in the url
221222
const auto message = QString(QStringLiteral("ACCOUNT_DETAILS:") +
222223
accountUser + "~" +
224+
accountUserId + "~" +
223225
accountUrl + "~" +
224226
accountPassword);
225227
sendMessage(message);

src/gui/macOS/fileproviderxpc_mac.mm

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,13 @@
6464
const auto account = accountState->account();
6565
const auto credentials = account->credentials();
6666
NSString *const user = credentials->user().toNSString();
67+
NSString *const userId = account->davUser().toNSString();
6768
NSString *const serverUrl = account->url().toString().toNSString();
6869
NSString *const password = credentials->password().toNSString();
6970

7071
const auto clientCommService = (NSObject<ClientCommunicationProtocol> *)_clientCommServices.value(extensionAccountId);
7172
[clientCommService configureAccountWithUser:user
73+
userId:userId
7274
serverUrl:serverUrl
7375
password:password];
7476
}

0 commit comments

Comments
 (0)