File indexing completed on 2024-04-28 04:55:46
0001 /* 0002 This file is part of Choqok, the KDE micro-blogging client 0003 0004 SPDX-FileCopyrightText: 2013 Andrea Scarpino <scarpino@kde.org> 0005 0006 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0007 */ 0008 0009 #include "pumpioeditaccountwidget.h" 0010 0011 #include <QCheckBox> 0012 #include <QInputDialog> 0013 #include <QJsonDocument> 0014 #include <QEventLoop> 0015 #include <QPushButton> 0016 #include <QUrl> 0017 0018 #include <KIO/AccessManager> 0019 #include <KIO/StoredTransferJob> 0020 #include <KMessageBox> 0021 0022 #include "choqoktools.h" 0023 #include "accountmanager.h" 0024 0025 #include "pumpioaccount.h" 0026 #include "pumpiodebug.h" 0027 #include "pumpiomicroblog.h" 0028 #include "pumpiooauth.h" 0029 0030 PumpIOEditAccountWidget::PumpIOEditAccountWidget(PumpIOMicroBlog *microblog, 0031 PumpIOAccount *account, 0032 QWidget *parent): 0033 ChoqokEditAccountWidget(account, parent) 0034 , m_account(account) 0035 { 0036 setupUi(this); 0037 0038 connect(kcfg_authorize, &QPushButton::clicked, this, &PumpIOEditAccountWidget::authorizeUser); 0039 0040 if (m_account) { 0041 kcfg_alias->setText(m_account->alias()); 0042 kcfg_webfingerid->setText(m_account->webfingerID()); 0043 setAuthenticated(!m_account->token().isEmpty() && !m_account->tokenSecret().isEmpty()); 0044 } else { 0045 setAuthenticated(false); 0046 QString newAccountAlias = microblog->serviceName(); 0047 const QString servName = newAccountAlias; 0048 int counter = 1; 0049 while (Choqok::AccountManager::self()->findAccount(newAccountAlias)) { 0050 newAccountAlias = QStringLiteral("%1%2").arg(servName).arg(counter); 0051 counter++; 0052 } 0053 m_account = new PumpIOAccount(microblog, newAccountAlias); 0054 setAccount(m_account); 0055 kcfg_alias->setText(newAccountAlias); 0056 } 0057 0058 loadTimelinesTable(); 0059 } 0060 0061 PumpIOEditAccountWidget::~PumpIOEditAccountWidget() 0062 { 0063 } 0064 0065 Choqok::Account *PumpIOEditAccountWidget::apply() 0066 { 0067 m_account->setAlias(kcfg_alias->text()); 0068 m_account->setUsername(kcfg_webfingerid->text().split(QLatin1Char('@'))[0]); 0069 m_account->setToken(m_account->oAuth()->token()); 0070 m_account->setTokenSecret(m_account->oAuth()->tokenSecret()); 0071 m_account->writeConfig(); 0072 saveTimelinesTable(); 0073 return m_account; 0074 } 0075 0076 void PumpIOEditAccountWidget::authorizeUser() 0077 { 0078 qCDebug(CHOQOK); 0079 if (kcfg_webfingerid->text().isEmpty() || !kcfg_webfingerid->text().contains(QLatin1Char('@'))) { 0080 return; 0081 } 0082 if (m_account->consumerKey().isEmpty() || m_account->consumerSecret().isEmpty()) { 0083 registerClient(); 0084 } 0085 0086 m_account->oAuth()->grant(); 0087 0088 connect(m_account->oAuth(), &QAbstractOAuth::authorizeWithBrowser, &Choqok::openUrl); 0089 connect(m_account->oAuth(), &QAbstractOAuth::statusChanged, this, &PumpIOEditAccountWidget::getPinCode); 0090 } 0091 0092 void PumpIOEditAccountWidget::getPinCode() 0093 { 0094 isAuthenticated = false; 0095 if (m_account->oAuth()->status() == QAbstractOAuth::Status::TemporaryCredentialsReceived) { 0096 QString verifier = QInputDialog::getText(this, i18n("PIN"), 0097 i18n("Enter the verifier code received from %1", m_account->host())); 0098 if (verifier.isEmpty()) { 0099 return; 0100 } 0101 0102 m_account->oAuth()->continueGrantWithVerifier(verifier); 0103 } else if (m_account->oAuth()->status() == QAbstractOAuth::Status::Granted) { 0104 setAuthenticated(true); 0105 KMessageBox::information(this, i18n("Choqok is authorized successfully."), i18n("Authorized")); 0106 } else { 0107 KMessageBox::detailedError(this, i18n("Authorization Error"), i18n("OAuth authorization error")); 0108 } 0109 } 0110 0111 bool PumpIOEditAccountWidget::validateData() 0112 { 0113 if (kcfg_alias->text().isEmpty() || kcfg_webfingerid->text().isEmpty() || 0114 !kcfg_webfingerid->text().contains(QLatin1Char('@')) || 0115 !isAuthenticated) { 0116 return false; 0117 } else { 0118 return true; 0119 } 0120 } 0121 0122 void PumpIOEditAccountWidget::setAuthenticated(bool authenticated) 0123 { 0124 isAuthenticated = authenticated; 0125 if (authenticated) { 0126 kcfg_authorize->setIcon(QIcon::fromTheme(QLatin1String("object-unlocked"))); 0127 kcfg_authenticateLed->on(); 0128 kcfg_authenticateStatus->setText(i18n("Authenticated")); 0129 } else { 0130 kcfg_authorize->setIcon(QIcon::fromTheme(QLatin1String("object-locked"))); 0131 kcfg_authenticateLed->off(); 0132 kcfg_authenticateStatus->setText(i18n("Not Authenticated")); 0133 } 0134 } 0135 0136 void PumpIOEditAccountWidget::loadTimelinesTable() 0137 { 0138 for (const QString &timeline: m_account->microblog()->timelineNames()) { 0139 int newRow = timelinesTable->rowCount(); 0140 timelinesTable->insertRow(newRow); 0141 timelinesTable->setItem(newRow, 0, new QTableWidgetItem(timeline)); 0142 0143 QCheckBox *enable = new QCheckBox(timelinesTable); 0144 enable->setChecked(m_account->timelineNames().contains(timeline)); 0145 timelinesTable->setCellWidget(newRow, 1, enable); 0146 } 0147 } 0148 0149 void PumpIOEditAccountWidget::registerClient() 0150 { 0151 if (kcfg_webfingerid->text().contains(QLatin1Char('@'))) { 0152 m_account->setHost(QLatin1String("https://") + kcfg_webfingerid->text().split(QLatin1Char('@'))[1]); 0153 0154 m_account->oAuth()->setTemporaryCredentialsUrl(QUrl(m_account->host() + QLatin1String("/oauth/request_token"))); 0155 m_account->oAuth()->setAuthorizationUrl(QUrl(m_account->host() + QLatin1String("/oauth/authorize"))); 0156 m_account->oAuth()->setTokenCredentialsUrl(QUrl(m_account->host() + QLatin1String("/oauth/access_token"))); 0157 0158 QUrl url(m_account->host() + QLatin1String("/api/client/register")); 0159 QByteArray data("{" 0160 " \"type\": \"client_associate\", " 0161 " \"application_type\": \"native\", " 0162 " \"application_name\": \"Choqok\" " 0163 "}"); 0164 KIO::StoredTransferJob *job = KIO::storedHttpPost(data, url, KIO::HideProgressInfo); 0165 if (!job) { 0166 qCDebug(CHOQOK) << "Cannot create an http POST request!"; 0167 return; 0168 } 0169 job->addMetaData(QLatin1String("content-type"), QLatin1String("Content-Type: application/json")); 0170 QEventLoop loop; 0171 connect(job, &KIO::StoredTransferJob::result, &loop, &QEventLoop::quit); 0172 job->start(); 0173 loop.exec(); 0174 0175 if (job->error()) { 0176 qCDebug(CHOQOK) << "An error occurred in Job"; 0177 return; 0178 } else { 0179 KIO::StoredTransferJob *stj = qobject_cast<KIO::StoredTransferJob *>(job); 0180 0181 const QJsonDocument json = QJsonDocument::fromJson(stj->data()); 0182 if (!json.isNull()) { 0183 const QVariantMap result = json.toVariant().toMap(); 0184 m_account->setConsumerKey(result[QLatin1String("client_id")].toString()); 0185 m_account->setConsumerSecret(result[QLatin1String("client_secret")].toString()); 0186 m_account->oAuth()->setClientIdentifier(m_account->consumerKey()); 0187 m_account->oAuth()->setClientSharedSecret(m_account->consumerSecret()); 0188 } else { 0189 qCDebug(CHOQOK) << "Cannot parse JSON reply"; 0190 } 0191 } 0192 } else { 0193 qCDebug(CHOQOK) << "webfingerID is not valid"; 0194 } 0195 } 0196 0197 void PumpIOEditAccountWidget::saveTimelinesTable() 0198 { 0199 QStringList timelines; 0200 for (int i = 0; i < timelinesTable->rowCount(); ++i) { 0201 QCheckBox *enable = qobject_cast<QCheckBox *>(timelinesTable->cellWidget(i, 1)); 0202 if (enable && enable->isChecked()) { 0203 timelines.append(timelinesTable->item(i, 0)->text()); 0204 } 0205 } 0206 m_account->setTimelineNames(timelines); 0207 } 0208 0209 #include "moc_pumpioeditaccountwidget.cpp"