mirror of
https://github.com/nextcloud/desktop.git
synced 2024-11-26 06:55:59 +03:00
Send account details over socket and simplify NextcloudAccount members, turn all to Strings
Signed-off-by: Claudio Cambra <claudio.cambra@nextcloud.com>
This commit is contained in:
parent
81b5c33571
commit
1cb7da9bac
6 changed files with 42 additions and 83 deletions
|
@ -21,7 +21,7 @@ class FileProviderEnumerator: NSObject, NSFileProviderEnumerator {
|
||||||
private let anchor = NSFileProviderSyncAnchor("an anchor".data(using: .utf8)!)
|
private let anchor = NSFileProviderSyncAnchor("an anchor".data(using: .utf8)!)
|
||||||
private static let maxItemsPerFileProviderPage = 100
|
private static let maxItemsPerFileProviderPage = 100
|
||||||
var ncAccount: NextcloudAccount?
|
var ncAccount: NextcloudAccount?
|
||||||
var serverUrl: URL?
|
var serverUrl: String?
|
||||||
|
|
||||||
init(enumeratedItemIdentifier: NSFileProviderItemIdentifier, ncAccount: NextcloudAccount?) {
|
init(enumeratedItemIdentifier: NSFileProviderItemIdentifier, ncAccount: NextcloudAccount?) {
|
||||||
self.enumeratedItemIdentifier = enumeratedItemIdentifier
|
self.enumeratedItemIdentifier = enumeratedItemIdentifier
|
||||||
|
@ -34,7 +34,7 @@ class FileProviderEnumerator: NSObject, NSFileProviderEnumerator {
|
||||||
if let itemMetadata = dbManager.itemMetadataFromFileProviderItemIdentifier(enumeratedItemIdentifier),
|
if let itemMetadata = dbManager.itemMetadataFromFileProviderItemIdentifier(enumeratedItemIdentifier),
|
||||||
let itemDirectoryMetadata = dbManager.parentDirectoryMetadataForItem(itemMetadata) {
|
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)
|
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 dbManager = NextcloudFilesDatabaseManager.shared
|
||||||
let serverUrlPath = serverUrl.path
|
let ncKitAccount = ncAccount.ncKitAccount
|
||||||
let ncKitAccount = ncAccount.ncKitAccount!
|
|
||||||
var directoryEtag: String?
|
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
|
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 {
|
guard directoryEtag != files.first?.etag else {
|
||||||
finishReadServerUrl(serverUrlPath, ncKitAccount: ncKitAccount, completionHandler: completionHandler)
|
finishReadServerUrl(serverUrl, ncKitAccount: ncKitAccount, completionHandler: completionHandler)
|
||||||
return
|
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 {
|
guard error == .success else {
|
||||||
finishReadServerUrl(serverUrlPath, ncKitAccount: ncKitAccount, completionHandler: completionHandler)
|
finishReadServerUrl(serverUrl, ncKitAccount: ncKitAccount, completionHandler: completionHandler)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
DispatchQueue.global().async {
|
DispatchQueue.global().async {
|
||||||
dbManager.convertNKFilesToItemMetadatas(files, account: ncKitAccount) { _, childDirectoriesMetadata, metadatas in
|
dbManager.convertNKFilesToItemMetadatas(files, account: ncKitAccount) { _, childDirectoriesMetadata, metadatas in
|
||||||
dbManager.updateItemMetadatas(account: ncKitAccount, serverUrl: serverUrlPath, updatedMetadatas: metadatas)
|
dbManager.updateItemMetadatas(account: ncKitAccount, serverUrl: serverUrl, updatedMetadatas: metadatas)
|
||||||
dbManager.updateDirectoryMetadatasFromItemMetadatas(account: ncKitAccount, parentDirectoryServerUrl: serverUrlPath, updatedDirectoryItemMetadatas: childDirectoriesMetadata)
|
dbManager.updateDirectoryMetadatasFromItemMetadatas(account: ncKitAccount, parentDirectoryServerUrl: serverUrl, updatedDirectoryItemMetadatas: childDirectoriesMetadata)
|
||||||
finishReadServerUrl(serverUrlPath, ncKitAccount: ncKitAccount, completionHandler: completionHandler)
|
finishReadServerUrl(serverUrl, ncKitAccount: ncKitAccount, completionHandler: completionHandler)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,19 +66,19 @@ class FileProviderExtension: NSObject, NSFileProviderReplicatedExtension {
|
||||||
// resolve the given identifier to a record in the model
|
// resolve the given identifier to a record in the model
|
||||||
|
|
||||||
if identifier == .rootContainer {
|
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))
|
completionHandler(nil, NSFileProviderError(.notAuthenticated))
|
||||||
return Progress()
|
return Progress()
|
||||||
}
|
}
|
||||||
|
|
||||||
let metadata = NextcloudItemMetadataTable()
|
let metadata = NextcloudItemMetadataTable()
|
||||||
|
|
||||||
metadata.account = ncKitAccount
|
metadata.account = ncAccount.ncKitAccount
|
||||||
metadata.directory = true
|
metadata.directory = true
|
||||||
metadata.ocId = NSFileProviderItemIdentifier.rootContainer.rawValue
|
metadata.ocId = NSFileProviderItemIdentifier.rootContainer.rawValue
|
||||||
metadata.fileName = "root"
|
metadata.fileName = "root"
|
||||||
metadata.fileNameView = "root"
|
metadata.fileNameView = "root"
|
||||||
metadata.serverUrl = serverUrl.path
|
metadata.serverUrl = ncAccount.serverUrl
|
||||||
metadata.classFile = NKCommon.typeClassFile.directory.rawValue
|
metadata.classFile = NKCommon.typeClassFile.directory.rawValue
|
||||||
|
|
||||||
completionHandler(FileProviderItem(metadata: metadata, parentItemIdentifier: NSFileProviderItemIdentifier.rootContainer), nil)
|
completionHandler(FileProviderItem(metadata: metadata, parentItemIdentifier: NSFileProviderItemIdentifier.rootContainer), nil)
|
||||||
|
@ -136,7 +136,7 @@ class FileProviderExtension: NSObject, NSFileProviderReplicatedExtension {
|
||||||
socketClient?.sendMessage(message)
|
socketClient?.sendMessage(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
func setupDomainAccount(keychainAccount:String) {
|
func setupDomainAccount(user: String, serverUrl: String, password: String) {
|
||||||
ncAccount = NextcloudAccount(withKeychainAccount:keychainAccount)
|
ncAccount = NextcloudAccount(user: user, serverUrl: serverUrl, password: password)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,10 +35,15 @@ class FileProviderSocketLineProcessor: NSObject, LineProcessor {
|
||||||
NSLog("Received command: %@", command)
|
NSLog("Received command: %@", command)
|
||||||
if (command == "SEND_FILE_PROVIDER_DOMAIN_IDENTIFIER") {
|
if (command == "SEND_FILE_PROVIDER_DOMAIN_IDENTIFIER") {
|
||||||
delegate.sendFileProviderDomainIdentifier()
|
delegate.sendFileProviderDomainIdentifier()
|
||||||
} else if (command == "ACCOUNT_KEYCHAIN_NAME") {
|
} else if (command == "ACCOUNT_DETAILS") {
|
||||||
guard let keychainAccountSubsequence = splitLine.last else { return }
|
guard let accountDetailsSubsequence = splitLine.last else { return }
|
||||||
let keychainAccountString = String(keychainAccountSubsequence)
|
let splitAccountDetails = accountDetailsSubsequence.split(separator: ":", maxSplits: 2)
|
||||||
delegate.setupDomainAccount(keychainAccount:keychainAccountString)
|
|
||||||
|
let user = String(splitAccountDetails[0])
|
||||||
|
let serverUrl = String(splitAccountDetails[1])
|
||||||
|
let password = String(splitAccountDetails[2])
|
||||||
|
|
||||||
|
delegate.setupDomainAccount(user: user, serverUrl: serverUrl, password: password)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,63 +17,16 @@ import FileProvider
|
||||||
|
|
||||||
class NextcloudAccount: NSObject {
|
class NextcloudAccount: NSObject {
|
||||||
let webDavFilesUrlSuffix: String = "/remote.php/dav/files/"
|
let webDavFilesUrlSuffix: String = "/remote.php/dav/files/"
|
||||||
let username, password, ncKitAccount: String?
|
let username, password, ncKitAccount, serverUrl, davFilesUrl: String
|
||||||
let serverUrl, davFilesUrl: URL?
|
|
||||||
|
|
||||||
var isNull: Bool {
|
init(user: String, serverUrl: String, password: String) {
|
||||||
return username?.isEmpty ?? false || serverUrl?.absoluteString.isEmpty ?? false
|
self.username = user
|
||||||
}
|
self.password = password
|
||||||
|
self.ncKitAccount = user + " " + serverUrl
|
||||||
init?(withKeychainAccount account:String) {
|
self.serverUrl = serverUrl
|
||||||
// The client sets the account field in the keychain entry as a colon-separated string consisting of
|
self.davFilesUrl = serverUrl + webDavFilesUrlSuffix
|
||||||
// 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
|
|
||||||
|
|
||||||
super.init()
|
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -81,7 +81,7 @@ void FileProviderSocketController::parseReceivedLine(const QString &receivedLine
|
||||||
|
|
||||||
if (command == QStringLiteral("FILE_PROVIDER_DOMAIN_IDENTIFIER_REQUEST_REPLY")) {
|
if (command == QStringLiteral("FILE_PROVIDER_DOMAIN_IDENTIFIER_REQUEST_REPLY")) {
|
||||||
_accountState = accountStateFromFileProviderDomainIdentifier(argument);
|
_accountState = accountStateFromFileProviderDomainIdentifier(argument);
|
||||||
sendAccountKeychainEntryKey();
|
sendAccountDetails();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,19 +135,21 @@ void FileProviderSocketController::requestFileProviderDomainInfo() const
|
||||||
sendMessage(requestMessage);
|
sendMessage(requestMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileProviderSocketController::sendAccountKeychainEntryKey() const
|
void FileProviderSocketController::sendAccountDetails() const
|
||||||
{
|
{
|
||||||
Q_ASSERT(_accountState);
|
Q_ASSERT(_accountState);
|
||||||
const auto account = _accountState->account();
|
const auto account = _accountState->account();
|
||||||
Q_ASSERT(account);
|
Q_ASSERT(account);
|
||||||
const auto credentials = account->credentials();
|
const auto credentials = account->credentials();
|
||||||
Q_ASSERT(credentials);
|
Q_ASSERT(credentials);
|
||||||
|
const auto accountUser = credentials->user();
|
||||||
const auto accountUrl = account->url().toString();
|
const auto accountUrl = account->url().toString();
|
||||||
const auto accountUser = account->credentials()->user();
|
const auto accountPassword = credentials->password();
|
||||||
const auto accountId = account->id();
|
|
||||||
const auto accountKey = credentials->keychainKey(accountUrl, accountUser, accountId);
|
|
||||||
|
|
||||||
const auto message = QString(QStringLiteral("ACCOUNT_KEYCHAIN_NAME:") + accountKey);
|
const auto message = QString(QStringLiteral("ACCOUNT_DETAILS:") +
|
||||||
|
accountUser + ":" +
|
||||||
|
accountUrl + ":" +
|
||||||
|
accountPassword);
|
||||||
sendMessage(message);
|
sendMessage(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ private slots:
|
||||||
|
|
||||||
void parseReceivedLine(const QString &receivedLine);
|
void parseReceivedLine(const QString &receivedLine);
|
||||||
void requestFileProviderDomainInfo() const;
|
void requestFileProviderDomainInfo() const;
|
||||||
void sendAccountKeychainEntryKey() const;
|
void sendAccountDetails() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static AccountStatePtr accountStateFromFileProviderDomainIdentifier(const QString &domainIdentifier);
|
static AccountStatePtr accountStateFromFileProviderDomainIdentifier(const QString &domainIdentifier);
|
||||||
|
|
Loading…
Reference in a new issue