2023-11-21 12:38:01 +03:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2022 by Claudio Cambra <claudio.cambra@nextcloud.com>
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful, but
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
|
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
|
|
* for more details.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "fileproviderxpc.h"
|
|
|
|
|
|
|
|
#include <QLoggingCategory>
|
|
|
|
|
2023-12-27 12:22:16 +03:00
|
|
|
#include "gui/accountmanager.h"
|
2024-01-02 12:04:45 +03:00
|
|
|
#include "gui/macOS/fileproviderdomainmanager.h"
|
2023-12-27 13:58:07 +03:00
|
|
|
#include "gui/macOS/fileproviderxpc_mac_utils.h"
|
2023-11-22 14:45:48 +03:00
|
|
|
|
2024-01-02 11:02:53 +03:00
|
|
|
namespace OCC::Mac {
|
2023-11-21 12:38:01 +03:00
|
|
|
|
|
|
|
Q_LOGGING_CATEGORY(lcFileProviderXPC, "nextcloud.gui.macos.fileprovider.xpc", QtInfoMsg)
|
|
|
|
|
2023-12-27 13:42:34 +03:00
|
|
|
FileProviderXPC::FileProviderXPC(QObject *parent)
|
|
|
|
: QObject{parent}
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2023-12-27 14:10:37 +03:00
|
|
|
void FileProviderXPC::connectToExtensions()
|
2023-12-27 13:42:34 +03:00
|
|
|
{
|
|
|
|
qCInfo(lcFileProviderXPC) << "Starting file provider XPC";
|
2023-12-27 13:58:07 +03:00
|
|
|
const auto managers = FileProviderXPCUtils::getDomainManagers();
|
2024-01-23 13:05:40 +03:00
|
|
|
const auto fpServices = FileProviderXPCUtils::getFileProviderServices(managers);
|
2023-12-27 13:58:07 +03:00
|
|
|
const auto connections = FileProviderXPCUtils::connectToFileProviderServices(fpServices);
|
2024-01-02 11:28:26 +03:00
|
|
|
_clientCommServices = FileProviderXPCUtils::processClientCommunicationConnections(connections);
|
2023-12-27 14:10:37 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void FileProviderXPC::configureExtensions()
|
|
|
|
{
|
2024-01-02 11:28:26 +03:00
|
|
|
for (const auto &extensionNcAccount : _clientCommServices.keys()) {
|
2023-12-27 12:22:16 +03:00
|
|
|
qCInfo(lcFileProviderXPC) << "Sending message to client communication service";
|
2024-01-02 11:28:26 +03:00
|
|
|
authenticateExtension(extensionNcAccount);
|
2024-01-02 10:49:20 +03:00
|
|
|
}
|
|
|
|
}
|
2023-12-27 12:22:16 +03:00
|
|
|
|
2024-01-02 10:49:20 +03:00
|
|
|
void FileProviderXPC::authenticateExtension(const QString &extensionAccountId) const
|
|
|
|
{
|
2024-01-02 12:04:45 +03:00
|
|
|
const auto accountState = FileProviderDomainManager::accountStateFromFileProviderDomainIdentifier(extensionAccountId);
|
2024-01-02 10:49:20 +03:00
|
|
|
if (!accountState) {
|
|
|
|
qCWarning(lcFileProviderXPC) << "Account state is null for received account"
|
|
|
|
<< extensionAccountId;
|
|
|
|
return;
|
2023-12-05 17:39:05 +03:00
|
|
|
}
|
2024-01-02 10:49:20 +03:00
|
|
|
|
2024-01-02 10:56:59 +03:00
|
|
|
connect(accountState.data(), &AccountState::stateChanged, this, &FileProviderXPC::slotAccountStateChanged, Qt::UniqueConnection);
|
|
|
|
|
2024-01-02 10:49:20 +03:00
|
|
|
const auto account = accountState->account();
|
|
|
|
const auto credentials = account->credentials();
|
|
|
|
NSString *const user = credentials->user().toNSString();
|
|
|
|
NSString *const serverUrl = account->url().toString().toNSString();
|
|
|
|
NSString *const password = credentials->password().toNSString();
|
|
|
|
|
2024-01-02 11:28:26 +03:00
|
|
|
const auto clientCommService = (NSObject<ClientCommunicationProtocol> *)_clientCommServices.value(extensionAccountId);
|
2024-01-02 10:49:20 +03:00
|
|
|
[clientCommService configureAccountWithUser:user
|
|
|
|
serverUrl:serverUrl
|
|
|
|
password:password];
|
2023-11-22 14:45:48 +03:00
|
|
|
}
|
|
|
|
|
2024-01-02 10:49:20 +03:00
|
|
|
void FileProviderXPC::unauthenticateExtension(const QString &extensionAccountId) const
|
2024-01-02 10:28:28 +03:00
|
|
|
{
|
|
|
|
qCInfo(lcFileProviderXPC) << "Unauthenticating extension" << extensionAccountId;
|
2024-01-02 11:28:26 +03:00
|
|
|
const auto clientCommService = (NSObject<ClientCommunicationProtocol> *)_clientCommServices.value(extensionAccountId);
|
2024-01-02 10:28:28 +03:00
|
|
|
[clientCommService removeAccountConfig];
|
|
|
|
}
|
|
|
|
|
2024-01-02 10:56:59 +03:00
|
|
|
void FileProviderXPC::slotAccountStateChanged(const AccountState::State state) const
|
|
|
|
{
|
2024-01-02 11:30:59 +03:00
|
|
|
const auto slotSender = dynamic_cast<AccountState*>(sender());
|
|
|
|
Q_ASSERT(slotSender);
|
|
|
|
const auto extensionAccountId = slotSender->account()->userIdAtHostWithPort();
|
2024-01-02 10:56:59 +03:00
|
|
|
|
|
|
|
switch(state) {
|
|
|
|
case AccountState::Disconnected:
|
|
|
|
case AccountState::ConfigurationError:
|
|
|
|
case AccountState::NetworkError:
|
|
|
|
case AccountState::ServiceUnavailable:
|
|
|
|
case AccountState::MaintenanceMode:
|
|
|
|
// Do nothing, File Provider will by itself figure out connection issue
|
|
|
|
break;
|
|
|
|
case AccountState::SignedOut:
|
|
|
|
case AccountState::AskingCredentials:
|
|
|
|
case AccountState::RedirectDetected:
|
|
|
|
// Notify File Provider that it should show the not authenticated message
|
|
|
|
unauthenticateExtension(extensionAccountId);
|
|
|
|
break;
|
|
|
|
case AccountState::Connected:
|
|
|
|
// Provide credentials
|
|
|
|
authenticateExtension(extensionAccountId);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2024-01-02 15:11:33 +03:00
|
|
|
void FileProviderXPC::createDebugArchiveForExtension(const QString &extensionAccountId, const QString &filename) const
|
|
|
|
{
|
2024-01-03 12:16:10 +03:00
|
|
|
qCInfo(lcFileProviderXPC) << "Creating debug archive for extension" << extensionAccountId << "at" << filename;
|
|
|
|
// You need to fetch the contents from the extension and then create the archive from the client side.
|
|
|
|
// The extension is not allowed to ask for permission to write into the file system as it is not a user facing process.
|
2024-01-02 15:11:33 +03:00
|
|
|
const auto clientCommService = (NSObject<ClientCommunicationProtocol> *)_clientCommServices.value(extensionAccountId);
|
2024-01-03 12:16:10 +03:00
|
|
|
const auto group = dispatch_group_create();
|
|
|
|
__block NSString *rcvdDebugLogString;
|
|
|
|
dispatch_group_enter(group);
|
|
|
|
[clientCommService createDebugLogStringWithCompletionHandler:^(NSString *const debugLogString, NSError *const error) {
|
|
|
|
if (error != nil) {
|
|
|
|
qCWarning(lcFileProviderXPC) << "Error getting debug log string" << error.localizedDescription;
|
|
|
|
dispatch_group_leave(group);
|
|
|
|
return;
|
|
|
|
} else if (debugLogString == nil) {
|
|
|
|
qCWarning(lcFileProviderXPC) << "Debug log string is nil";
|
|
|
|
dispatch_group_leave(group);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
rcvdDebugLogString = [NSString stringWithString:debugLogString];
|
|
|
|
[rcvdDebugLogString retain];
|
|
|
|
dispatch_group_leave(group);
|
|
|
|
}];
|
|
|
|
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
|
|
|
|
|
|
|
|
QFile debugLogFile(filename);
|
|
|
|
if (debugLogFile.open(QIODevice::WriteOnly)) {
|
|
|
|
debugLogFile.write(rcvdDebugLogString.UTF8String);
|
|
|
|
debugLogFile.close();
|
|
|
|
qCInfo(lcFileProviderXPC) << "Debug log file written to" << filename;
|
|
|
|
} else {
|
|
|
|
qCWarning(lcFileProviderXPC) << "Could not open debug log file" << filename;
|
|
|
|
}
|
2024-01-02 15:11:33 +03:00
|
|
|
}
|
2024-01-02 10:56:59 +03:00
|
|
|
|
2024-01-02 11:02:53 +03:00
|
|
|
} // namespace OCC::Mac
|