File indexing completed on 2024-05-19 05:00:39
0001 /* 0002 * SPDX-FileCopyrightText: 2017 Elvis Angelaccio <elvis.angelaccio@kde.org> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 * 0006 */ 0007 0008 #include "kaccountsmanager.h" 0009 #include "gdrivedebug.h" 0010 #include "gdrivehelper.h" 0011 0012 #include <Accounts/Manager> 0013 #include <Accounts/Provider> 0014 #include <KAccounts/Core> 0015 #include <KAccounts/GetCredentialsJob> 0016 #include <KGAPI/Account> 0017 0018 #include <QProcess> 0019 #include <QStandardPaths> 0020 0021 using namespace KGAPI2; 0022 0023 KAccountsManager::KAccountsManager() 0024 { 0025 loadAccounts(); 0026 } 0027 0028 KAccountsManager::~KAccountsManager() 0029 { 0030 } 0031 0032 AccountPtr KAccountsManager::account(const QString &accountName) 0033 { 0034 const auto accounts = m_accounts.values(); 0035 for (const auto &account : accounts) { 0036 if (account->accountName() == accountName) { 0037 return account; 0038 } 0039 } 0040 0041 return AccountPtr(new Account()); 0042 } 0043 0044 AccountPtr KAccountsManager::createAccount() 0045 { 0046 if (QStandardPaths::findExecutable(QStringLiteral("kcmshell6")).isEmpty()) { 0047 return AccountPtr(new Account()); 0048 } 0049 0050 const auto oldAccounts = accounts(); 0051 0052 QProcess process; 0053 process.start(QStringLiteral("kcmshell6"), {QStringLiteral("kcm_kaccounts")}); 0054 qCDebug(GDRIVE) << "Waiting for kcmshell process..."; 0055 if (process.waitForFinished(-1)) { 0056 loadAccounts(); 0057 } 0058 0059 const auto newAccounts = accounts(); 0060 for (const auto &accountName : newAccounts) { 0061 if (oldAccounts.contains(accountName)) { 0062 continue; 0063 } 0064 0065 // The KCM allows to add more than one account, but we can return only one from here. 0066 // So we just return the first new account in the set. 0067 qCDebug(GDRIVE) << "New account successfully created:" << accountName; 0068 return account(accountName); 0069 } 0070 0071 // No accounts at all or no new account(s). 0072 qCDebug(GDRIVE) << "No new account created."; 0073 return AccountPtr(new Account()); 0074 } 0075 0076 AccountPtr KAccountsManager::refreshAccount(const AccountPtr &account) 0077 { 0078 const QString accountName = account->accountName(); 0079 for (auto it = m_accounts.constBegin(); it != m_accounts.constEnd(); ++it) { 0080 if (it.value()->accountName() != accountName) { 0081 continue; 0082 } 0083 0084 const auto id = it.key(); 0085 qCDebug(GDRIVE) << "Refreshing" << accountName; 0086 auto gapiAccount = getAccountCredentials(id, accountName); 0087 m_accounts.insert(id, gapiAccount); 0088 return gapiAccount; 0089 } 0090 0091 return {}; 0092 } 0093 0094 void KAccountsManager::removeAccount(const QString &accountName) 0095 { 0096 if (!accounts().contains(accountName)) { 0097 return; 0098 } 0099 0100 for (auto it = m_accounts.constBegin(); it != m_accounts.constEnd(); ++it) { 0101 if (it.value()->accountName() != accountName) { 0102 continue; 0103 } 0104 0105 auto manager = KAccounts::accountsManager(); 0106 auto account = Accounts::Account::fromId(manager, it.key()); 0107 Q_ASSERT(account->displayName() == accountName); 0108 qCDebug(GDRIVE) << "Going to remove account:" << account->displayName(); 0109 account->selectService(manager->service(QStringLiteral("google-drive"))); 0110 account->setEnabled(false); 0111 account->sync(); 0112 return; 0113 } 0114 } 0115 0116 QSet<QString> KAccountsManager::accounts() 0117 { 0118 auto accountNames = QSet<QString>(); 0119 0120 const auto accounts = m_accounts.values(); 0121 for (const auto &account : accounts) { 0122 accountNames << account->accountName(); 0123 } 0124 0125 return accountNames; 0126 } 0127 0128 void KAccountsManager::loadAccounts() 0129 { 0130 m_accounts.clear(); 0131 0132 auto manager = KAccounts::accountsManager(); 0133 const auto enabledIDs = manager->accountListEnabled(); 0134 for (const auto id : enabledIDs) { 0135 auto account = manager->account(id); 0136 if (account->providerName() != QLatin1String("google")) { 0137 continue; 0138 } 0139 qCDebug(GDRIVE) << "Found google-provided account:" << account->displayName(); 0140 const auto services = account->enabledServices(); 0141 for (const auto &service : services) { 0142 if (service.name() != QLatin1String("google-drive")) { 0143 continue; 0144 } 0145 qCDebug(GDRIVE) << account->displayName() << "supports gdrive!"; 0146 0147 auto gapiAccount = getAccountCredentials(id, account->displayName()); 0148 m_accounts.insert(id, gapiAccount); 0149 } 0150 } 0151 } 0152 0153 AccountPtr KAccountsManager::getAccountCredentials(Accounts::AccountId id, const QString &displayName) 0154 { 0155 auto job = new KAccounts::GetCredentialsJob(id, nullptr); 0156 job->exec(); 0157 if (job->error()) { 0158 qCWarning(GDRIVE) << "GetCredentialsJob failed:" << job->errorString(); 0159 } 0160 0161 auto gapiAccount = AccountPtr(new Account(displayName, 0162 job->credentialsData().value(QStringLiteral("AccessToken")).toString(), 0163 job->credentialsData().value(QStringLiteral("RefreshToken")).toString())); 0164 0165 const auto scopes = job->credentialsData().value(QStringLiteral("Scope")).toStringList(); 0166 for (const auto &scope : scopes) { 0167 gapiAccount->addScope(QUrl::fromUserInput(scope)); 0168 } 0169 0170 qCDebug(GDRIVE) << "Got account credentials for:" << gapiAccount->accountName() << ", accessToken:" << GDriveHelper::elideToken(gapiAccount->accessToken()) 0171 << ", refreshToken:" << GDriveHelper::elideToken(gapiAccount->refreshToken()); 0172 0173 return gapiAccount; 0174 }