From 1cb7da9bac0e3d3773b40054e16bdce28bf68e76 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Thu, 26 Jan 2023 23:01:31 +0100 Subject: [PATCH] Send account details over socket and simplify NextcloudAccount members, turn all to Strings Signed-off-by: Claudio Cambra --- .../FileProviderEnumerator.swift | 25 ++++---- .../FileProviderExtension.swift | 10 +-- .../FileProviderSocketLineProcessor.swift | 13 ++-- .../FileProviderExt/NextcloudAccount.swift | 61 +++---------------- .../macOS/fileprovidersocketcontroller.cpp | 14 +++-- src/gui/macOS/fileprovidersocketcontroller.h | 2 +- 6 files changed, 42 insertions(+), 83 deletions(-) diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderEnumerator.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderEnumerator.swift index 128fab4ba..9754380aa 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderEnumerator.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderEnumerator.swift @@ -21,7 +21,7 @@ class FileProviderEnumerator: NSObject, NSFileProviderEnumerator { private let anchor = NSFileProviderSyncAnchor("an anchor".data(using: .utf8)!) private static let maxItemsPerFileProviderPage = 100 var ncAccount: NextcloudAccount? - var serverUrl: URL? + var serverUrl: String? init(enumeratedItemIdentifier: NSFileProviderItemIdentifier, ncAccount: NextcloudAccount?) { self.enumeratedItemIdentifier = enumeratedItemIdentifier @@ -34,7 +34,7 @@ class FileProviderEnumerator: NSObject, NSFileProviderEnumerator { if let itemMetadata = dbManager.itemMetadataFromFileProviderItemIdentifier(enumeratedItemIdentifier), let itemDirectoryMetadata = dbManager.parentDirectoryMetadataForItem(itemMetadata) { - self.serverUrl = URL(string: itemDirectoryMetadata.serverUrl + "/" + itemMetadata.fileName) + self.serverUrl = itemDirectoryMetadata.serverUrl + "/" + itemMetadata.fileName } } @@ -133,33 +133,32 @@ class FileProviderEnumerator: NSObject, NSFileProviderEnumerator { completionHandler(metadatas) } - private static func readServerUrl(_ serverUrl: URL, ncAccount: NextcloudAccount, completionHandler: @escaping (_ metadatas: [NextcloudItemMetadataTable]?) -> Void) { + private static func readServerUrl(_ serverUrl: String, ncAccount: NextcloudAccount, completionHandler: @escaping (_ metadatas: [NextcloudItemMetadataTable]?) -> Void) { let dbManager = NextcloudFilesDatabaseManager.shared - let serverUrlPath = serverUrl.path - let ncKitAccount = ncAccount.ncKitAccount! + let ncKitAccount = ncAccount.ncKitAccount var directoryEtag: String? - if let directoryMetadata = dbManager.directoryMetadata(account: ncKitAccount, serverUrl: serverUrl.path) { + if let directoryMetadata = dbManager.directoryMetadata(account: ncKitAccount, serverUrl: serverUrl) { directoryEtag = directoryMetadata.etag } - NextcloudKit.shared.readFileOrFolder(serverUrlFileName: serverUrlPath, depth: "0", showHiddenFiles: true) { account, files, _, error in + NextcloudKit.shared.readFileOrFolder(serverUrlFileName: serverUrl, depth: "0", showHiddenFiles: true) { account, files, _, error in guard directoryEtag != files.first?.etag else { - finishReadServerUrl(serverUrlPath, ncKitAccount: ncKitAccount, completionHandler: completionHandler) + finishReadServerUrl(serverUrl, ncKitAccount: ncKitAccount, completionHandler: completionHandler) return } - NextcloudKit.shared.readFileOrFolder(serverUrlFileName: serverUrlPath, depth: "1", showHiddenFiles: true) { account, files, _, error in + NextcloudKit.shared.readFileOrFolder(serverUrlFileName: serverUrl, depth: "1", showHiddenFiles: true) { account, files, _, error in guard error == .success else { - finishReadServerUrl(serverUrlPath, ncKitAccount: ncKitAccount, completionHandler: completionHandler) + finishReadServerUrl(serverUrl, ncKitAccount: ncKitAccount, completionHandler: completionHandler) return } DispatchQueue.global().async { dbManager.convertNKFilesToItemMetadatas(files, account: ncKitAccount) { _, childDirectoriesMetadata, metadatas in - dbManager.updateItemMetadatas(account: ncKitAccount, serverUrl: serverUrlPath, updatedMetadatas: metadatas) - dbManager.updateDirectoryMetadatasFromItemMetadatas(account: ncKitAccount, parentDirectoryServerUrl: serverUrlPath, updatedDirectoryItemMetadatas: childDirectoriesMetadata) - finishReadServerUrl(serverUrlPath, ncKitAccount: ncKitAccount, completionHandler: completionHandler) + dbManager.updateItemMetadatas(account: ncKitAccount, serverUrl: serverUrl, updatedMetadatas: metadatas) + dbManager.updateDirectoryMetadatasFromItemMetadatas(account: ncKitAccount, parentDirectoryServerUrl: serverUrl, updatedDirectoryItemMetadatas: childDirectoriesMetadata) + finishReadServerUrl(serverUrl, ncKitAccount: ncKitAccount, completionHandler: completionHandler) } } } diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift index e8ad2becb..b7891c2bf 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift @@ -66,19 +66,19 @@ class FileProviderExtension: NSObject, NSFileProviderReplicatedExtension { // resolve the given identifier to a record in the model if identifier == .rootContainer { - guard let ncAccount = ncAccount, let ncKitAccount = ncAccount.ncKitAccount, let serverUrl = ncAccount.serverUrl else { + guard let ncAccount = ncAccount else { completionHandler(nil, NSFileProviderError(.notAuthenticated)) return Progress() } let metadata = NextcloudItemMetadataTable() - metadata.account = ncKitAccount + metadata.account = ncAccount.ncKitAccount metadata.directory = true metadata.ocId = NSFileProviderItemIdentifier.rootContainer.rawValue metadata.fileName = "root" metadata.fileNameView = "root" - metadata.serverUrl = serverUrl.path + metadata.serverUrl = ncAccount.serverUrl metadata.classFile = NKCommon.typeClassFile.directory.rawValue completionHandler(FileProviderItem(metadata: metadata, parentItemIdentifier: NSFileProviderItemIdentifier.rootContainer), nil) @@ -136,7 +136,7 @@ class FileProviderExtension: NSObject, NSFileProviderReplicatedExtension { socketClient?.sendMessage(message) } - func setupDomainAccount(keychainAccount:String) { - ncAccount = NextcloudAccount(withKeychainAccount:keychainAccount) + func setupDomainAccount(user: String, serverUrl: String, password: String) { + ncAccount = NextcloudAccount(user: user, serverUrl: serverUrl, password: password) } } diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderSocketLineProcessor.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderSocketLineProcessor.swift index 5589e101e..08aad6b3d 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderSocketLineProcessor.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderSocketLineProcessor.swift @@ -35,10 +35,15 @@ class FileProviderSocketLineProcessor: NSObject, LineProcessor { NSLog("Received command: %@", command) if (command == "SEND_FILE_PROVIDER_DOMAIN_IDENTIFIER") { delegate.sendFileProviderDomainIdentifier() - } else if (command == "ACCOUNT_KEYCHAIN_NAME") { - guard let keychainAccountSubsequence = splitLine.last else { return } - let keychainAccountString = String(keychainAccountSubsequence) - delegate.setupDomainAccount(keychainAccount:keychainAccountString) + } else if (command == "ACCOUNT_DETAILS") { + guard let accountDetailsSubsequence = splitLine.last else { return } + let splitAccountDetails = accountDetailsSubsequence.split(separator: ":", maxSplits: 2) + + let user = String(splitAccountDetails[0]) + let serverUrl = String(splitAccountDetails[1]) + let password = String(splitAccountDetails[2]) + + delegate.setupDomainAccount(user: user, serverUrl: serverUrl, password: password) } } } diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/NextcloudAccount.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/NextcloudAccount.swift index b8b000dc4..6af7046ad 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/NextcloudAccount.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/NextcloudAccount.swift @@ -17,63 +17,16 @@ import FileProvider class NextcloudAccount: NSObject { let webDavFilesUrlSuffix: String = "/remote.php/dav/files/" - let username, password, ncKitAccount: String? - let serverUrl, davFilesUrl: URL? + let username, password, ncKitAccount, serverUrl, davFilesUrl: String - var isNull: Bool { - return username?.isEmpty ?? false || serverUrl?.absoluteString.isEmpty ?? false - } - - init?(withKeychainAccount account:String) { - // The client sets the account field in the keychain entry as a colon-separated string consisting of - // an account's username, its homeserver url, and the id of the account - guard let passwordData = NextcloudAccount.getUserPasswordFromKeychain(accountString: account), - let passwordString = String(data: passwordData, encoding: .utf8) else { - - return nil - } - - let keychainAccountSplit = account.split(separator: ":") - let usernameSubstring = keychainAccountSplit[0] - let serverUrlSubstring = keychainAccountSplit[1] - let clientAccountIdSubstring = keychainAccountSplit[2] - - let usernameString = String(usernameSubstring) - let serverUrlString = String(serverUrlSubstring) - let clientAccountIdString = String(clientAccountIdSubstring) - - guard let serverUrlUrl = URL(string: String(serverUrlString)) else { - return nil - } - - let davFilesUrlUrl = serverUrlUrl.appendingPathComponent(webDavFilesUrlSuffix + usernameString) - - username = usernameString - password = passwordString - ncKitAccount = usernameString + " " + serverUrlString - serverUrl = serverUrlUrl - davFilesUrl = davFilesUrlUrl + init(user: String, serverUrl: String, password: String) { + self.username = user + self.password = password + self.ncKitAccount = user + " " + serverUrl + self.serverUrl = serverUrl + self.davFilesUrl = serverUrl + webDavFilesUrlSuffix super.init() } - - private static func getUserPasswordFromKeychain(accountString:String) -> Data? { - let query = [ - kSecClass as String : kSecClassGenericPassword, - kSecAttrAccount as String : accountString, - kSecReturnData as String : kCFBooleanTrue!, - kSecMatchLimit as String : kSecMatchLimitOne - ] as [String : Any] - - var dataTypeRef: AnyObject? = nil - - let status: OSStatus = SecItemCopyMatching(query as CFDictionary, &dataTypeRef) - - if status == noErr { - return dataTypeRef as! Data? - } else { - return nil - } - } } diff --git a/src/gui/macOS/fileprovidersocketcontroller.cpp b/src/gui/macOS/fileprovidersocketcontroller.cpp index a473b5581..7dc1d4f92 100644 --- a/src/gui/macOS/fileprovidersocketcontroller.cpp +++ b/src/gui/macOS/fileprovidersocketcontroller.cpp @@ -81,7 +81,7 @@ void FileProviderSocketController::parseReceivedLine(const QString &receivedLine if (command == QStringLiteral("FILE_PROVIDER_DOMAIN_IDENTIFIER_REQUEST_REPLY")) { _accountState = accountStateFromFileProviderDomainIdentifier(argument); - sendAccountKeychainEntryKey(); + sendAccountDetails(); return; } @@ -135,19 +135,21 @@ void FileProviderSocketController::requestFileProviderDomainInfo() const sendMessage(requestMessage); } -void FileProviderSocketController::sendAccountKeychainEntryKey() const +void FileProviderSocketController::sendAccountDetails() const { Q_ASSERT(_accountState); const auto account = _accountState->account(); Q_ASSERT(account); const auto credentials = account->credentials(); Q_ASSERT(credentials); + const auto accountUser = credentials->user(); const auto accountUrl = account->url().toString(); - const auto accountUser = account->credentials()->user(); - const auto accountId = account->id(); - const auto accountKey = credentials->keychainKey(accountUrl, accountUser, accountId); + const auto accountPassword = credentials->password(); - const auto message = QString(QStringLiteral("ACCOUNT_KEYCHAIN_NAME:") + accountKey); + const auto message = QString(QStringLiteral("ACCOUNT_DETAILS:") + + accountUser + ":" + + accountUrl + ":" + + accountPassword); sendMessage(message); } diff --git a/src/gui/macOS/fileprovidersocketcontroller.h b/src/gui/macOS/fileprovidersocketcontroller.h index 67a4ebfd2..e5142a057 100644 --- a/src/gui/macOS/fileprovidersocketcontroller.h +++ b/src/gui/macOS/fileprovidersocketcontroller.h @@ -45,7 +45,7 @@ private slots: void parseReceivedLine(const QString &receivedLine); void requestFileProviderDomainInfo() const; - void sendAccountKeychainEntryKey() const; + void sendAccountDetails() const; private: static AccountStatePtr accountStateFromFileProviderDomainIdentifier(const QString &domainIdentifier); -- 2.30.2