File indexing completed on 2024-04-28 04:55:44
0001 /* 0002 This file is part of Choqok, the KDE micro-blogging client 0003 0004 SPDX-FileCopyrightText: 2008-2012 Mehrdad Momeny <mehrdad.momeny@gmail.com> 0005 0006 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0007 */ 0008 0009 #include "laconicaeditaccount.h" 0010 0011 #include <QJsonDocument> 0012 #include <QLineEdit> 0013 0014 #include <KIO/StoredTransferJob> 0015 #include <KJobWidgets> 0016 0017 #include "accountmanager.h" 0018 #include "choqoktools.h" 0019 0020 #include "gnusocialapiaccount.h" 0021 0022 #include "laconicadebug.h" 0023 #include "laconicamicroblog.h" 0024 0025 LaconicaEditAccountWidget::LaconicaEditAccountWidget(LaconicaMicroBlog *microblog, 0026 GNUSocialApiAccount *account, QWidget *parent) 0027 : ChoqokEditAccountWidget(account, parent), mAccount(account), progress(nullptr), isAuthenticated(false) 0028 { 0029 setupUi(this); 0030 // setAuthenticated(false); 0031 // oauthConsumerKey = "747d09d8e7b9417f5835f04510cb86ed";//Identi.ca tokens 0032 // oauthConsumerSecret = "57605f8507a041525a2d5c0abef15b20"; 0033 // connect(kcfg_authorize, SIGNAL(clicked(bool)), SLOT(authorizeUser())); 0034 // connect(kcfg_authMethod, SIGNAL(currentIndexChanged(int)), SLOT(slotAuthMethodChanged(int))); 0035 // slotAuthMethodChanged(kcfg_authMethod->currentIndex()); 0036 connect(kcfg_host, &QLineEdit::editingFinished, this, 0037 &LaconicaEditAccountWidget::slotCheckHostUrl); 0038 if (mAccount) { 0039 kcfg_alias->setText(mAccount->alias()); 0040 kcfg_host->setText(mAccount->host()); 0041 kcfg_api->setText(mAccount->api()); 0042 // kcfg_oauthUsername->setText( mAccount->username() ); 0043 kcfg_basicUsername->setText(mAccount->username()); 0044 kcfg_basicPassword->setText(mAccount->password()); 0045 kcfg_changeExclamationMark->setChecked(mAccount->isChangeExclamationMark()); 0046 kcfg_changeToString->setText(mAccount->changeExclamationMarkToText()); 0047 // if(mAccount->usingOAuth()){ 0048 // if( !mAccount->oauthConsumerKey().isEmpty() && 0049 // !mAccount->oauthConsumerSecret().isEmpty() && 0050 // !mAccount->oauthToken().isEmpty() && 0051 // !mAccount->oauthTokenSecret().isEmpty() ) { 0052 // setAuthenticated(true); 0053 // oauthConsumerKey = mAccount->oauthConsumerKey(); 0054 // oauthConsumerSecret = mAccount->oauthConsumerSecret(); 0055 // token = mAccount->oauthToken(); 0056 // tokenSecret = mAccount->oauthTokenSecret(); 0057 // } else { 0058 // setAuthenticated(false); 0059 // } 0060 // kcfg_authMethod->setCurrentIndex(0); 0061 // } else { 0062 // kcfg_authMethod->setCurrentIndex(1); 0063 // } 0064 } else { 0065 // kcfg_authMethod->setCurrentIndex(0); 0066 QString newAccountAlias = microblog->serviceName(); 0067 QString servName = newAccountAlias; 0068 int counter = 1; 0069 while (Choqok::AccountManager::self()->findAccount(newAccountAlias)) { 0070 newAccountAlias = QStringLiteral("%1%2").arg(servName).arg(counter); 0071 counter++; 0072 } 0073 setAccount(mAccount = new GNUSocialApiAccount(microblog, newAccountAlias)); 0074 kcfg_alias->setText(newAccountAlias); 0075 const QRegExp userRegExp(QLatin1String("([a-z0-9]){1,64}"), Qt::CaseInsensitive); 0076 QValidator *userVal = new QRegExpValidator(userRegExp, nullptr); 0077 kcfg_basicUsername->setValidator(userVal); 0078 } 0079 loadTimelinesTableState(); 0080 kcfg_alias->setFocus(Qt::OtherFocusReason); 0081 } 0082 0083 LaconicaEditAccountWidget::~LaconicaEditAccountWidget() 0084 { 0085 } 0086 0087 bool LaconicaEditAccountWidget::validateData() 0088 { 0089 // if( kcfg_authMethod->currentIndex()==0 ) {//OAuth 0090 // if(kcfg_alias->text().isEmpty() || kcfg_oauthUsername->text().isEmpty() || !isAuthenticated) 0091 // return false; 0092 // } else {//Basic 0093 if (kcfg_alias->text().isEmpty() || kcfg_basicUsername->text().isEmpty() || 0094 kcfg_basicPassword->text().isEmpty()) { 0095 return false; 0096 } 0097 // } 0098 return true; 0099 } 0100 0101 Choqok::Account *LaconicaEditAccountWidget::apply() 0102 { 0103 qCDebug(CHOQOK); 0104 /*if(kcfg_authMethod->currentIndex() == 0){ 0105 mAccount->setUsername( kcfg_oauthUsername->text() ); 0106 mAccount->setOauthToken( token ); 0107 mAccount->setOauthConsumerKey( oauthConsumerKey ); 0108 mAccount->setOauthConsumerSecret( oauthConsumerSecret ); 0109 mAccount->setOauthTokenSecret( tokenSecret ); 0110 mAccount->setUsingOAuth(true); 0111 } else*/ { 0112 mAccount->setUsername(kcfg_basicUsername->text()); 0113 mAccount->setPassword(kcfg_basicPassword->text()); 0114 mAccount->setUsingOAuth(false); 0115 } 0116 mAccount->setHost(kcfg_host->text()); 0117 mAccount->setApi(kcfg_api->text()); 0118 mAccount->setAlias(kcfg_alias->text()); 0119 mAccount->setChangeExclamationMark(kcfg_changeExclamationMark->isChecked()); 0120 mAccount->setChangeExclamationMarkToText(kcfg_changeToString->text()); 0121 saveTimelinesTableState(); 0122 setTextLimit(); 0123 mAccount->writeConfig(); 0124 return mAccount; 0125 } 0126 0127 // void LaconicaEditAccountWidget::authorizeUser() 0128 // { 0129 // qCDebug(CHOQOK); 0130 // slotCheckHostUrl(); 0131 // if(QUrl(kcfg_host->text()).host()!="identi.ca"){ 0132 // KMessageBox::sorry(this, i18n("Sorry, OAuth Method just works with Identi.ca server. You have to use basic authentication for other StatusNet servers.")); 0133 // kcfg_authMethod->setCurrentIndex(1); 0134 // return; 0135 // } 0136 // qoauth = new QOAuth::Interface(new KIO::Integration::AccessManager(this), this); 0137 // //TODO change this to have support for self hosted StatusNets 0138 // qoauth->setConsumerKey( oauthConsumerKey ); 0139 // qoauth->setConsumerSecret( oauthConsumerSecret ); 0140 // qoauth->setRequestTimeout( 10000 ); 0141 // 0142 // // send a request for an unauthorized token 0143 // QString oauthReqTokenUrl = QString("%1/%2/oauth/request_token").arg(kcfg_host->text()).arg(kcfg_api->text()); 0144 // // qCDebug(CHOQOK)<<oauthReqTokenUrl; 0145 // QOAuth::ParamMap params; 0146 // params.insert("oauth_callback", "oob"); 0147 // QOAuth::ParamMap reply = 0148 // qoauth->requestToken( oauthReqTokenUrl, QOAuth::GET, QOAuth::HMAC_SHA1, params ); 0149 // setAuthenticated(false); 0150 // kcfg_authorize->setIcon(QIcon::fromTheme("object-locked")); 0151 // 0152 // // if no error occurred, read the received token and token secret 0153 // if ( qoauth->error() == QOAuth::NoError ) { 0154 // token = reply.value( QOAuth::tokenParameterName() ); 0155 // tokenSecret = reply.value( QOAuth::tokenSecretParameterName() ); 0156 // qCDebug(CHOQOK)<<"token: "<<token; 0157 // QUrl url(QString("%1/%2/oauth/authorize").arg(kcfg_host->text()).arg(kcfg_api->text())); 0158 // url.addQueryItem( QOAuth::tokenParameterName(), token ); 0159 // url.addQueryItem( "oauth_token", token ); 0160 // Choqok::openUrl(url); 0161 // kcfg_authorize->setEnabled(false); 0162 // getPinCode(); 0163 // } else { 0164 // qCDebug(CHOQOK)<<"ERROR:" <<qoauth->error()<<Choqok::qoauthErrorText(qoauth->error()); 0165 // KMessageBox::detailedError(this, i18n("Authentication Error"), 0166 // Choqok::qoauthErrorText(qoauth->error())); 0167 // } 0168 // } 0169 // 0170 // void LaconicaEditAccountWidget::getPinCode() 0171 // { 0172 // isAuthenticated = false; 0173 // while(!isAuthenticated){ 0174 // QString verifier = KInputDialog::getText( i18n("Security code"), 0175 // i18nc("Security code received from StatusNet", 0176 // "Enter security code:")); 0177 // if(verifier.isEmpty()) 0178 // return; 0179 // QOAuth::ParamMap otherArgs; 0180 // otherArgs.insert( "oauth_verifier", verifier.toUtf8() ); 0181 // 0182 // QOAuth::ParamMap reply = 0183 // qoauth->accessToken( QString("%1/%2/oauth/access_token").arg(kcfg_host->text()).arg(kcfg_api->text()), 0184 // QOAuth::GET, token, tokenSecret, QOAuth::HMAC_SHA1, otherArgs ); 0185 // // if no error occurred, read the Access Token (and other arguments, if applicable) 0186 // if ( qoauth->error() == QOAuth::NoError ) { 0187 // sender()->deleteLater(); 0188 // kcfg_authorize->setEnabled(true); 0189 // token = reply.value( QOAuth::tokenParameterName() ); 0190 // tokenSecret = reply.value( QOAuth::tokenSecretParameterName() ); 0191 // qCDebug(CHOQOK)<<"token: "<<token; 0192 // setAuthenticated(true); 0193 // KMessageBox::information(this, i18n("Choqok is authorized successfully."), 0194 // i18n("Authorized")); 0195 // } else { 0196 // setAuthenticated(false); 0197 // qCDebug(CHOQOK)<<"ERROR: "<<qoauth->error()<<' '<<Choqok::qoauthErrorText(qoauth->error()); 0198 // KMessageBox::detailedError(this, i18n("Authentication Error"), 0199 // Choqok::qoauthErrorText(qoauth->error())); 0200 // } 0201 // } 0202 // } 0203 0204 void LaconicaEditAccountWidget::setTextLimit() 0205 { 0206 QString url = mAccount->host() + QLatin1Char('/') + mAccount->api() + QLatin1String("/statusnet/config.json"); 0207 KIO::StoredTransferJob *job = KIO::storedGet(QUrl(url), KIO::Reload, KIO::HideProgressInfo); 0208 job->exec(); 0209 if (job->error()) { 0210 qCCritical(CHOQOK) << "Job error:" << job->errorString(); 0211 return; 0212 } 0213 0214 const QJsonDocument json = QJsonDocument::fromJson(job->data()); 0215 if (!json.isNull()) { 0216 const QVariantMap siteInfos = json.toVariant().toMap()[QLatin1String("site")].toMap(); 0217 bool ok; 0218 mAccount->setPostCharLimit(siteInfos[QLatin1String("textlimit")].toUInt(&ok)); 0219 if (!ok) { 0220 qCDebug(CHOQOK) << "Cannot parse text limit value"; 0221 mAccount->setPostCharLimit(140); 0222 } 0223 } else { 0224 qCDebug(CHOQOK) << "Cannot parse JSON reply"; 0225 } 0226 } 0227 0228 void LaconicaEditAccountWidget::loadTimelinesTableState() 0229 { 0230 for (const QString &timeline: mAccount->microblog()->timelineNames()) { 0231 int newRow = timelinesTable->rowCount(); 0232 timelinesTable->insertRow(newRow); 0233 Choqok::TimelineInfo *info = mAccount->microblog()->timelineInfo(timeline); 0234 QTableWidgetItem *item = new QTableWidgetItem(info->name); 0235 item->setData(32, timeline); 0236 item->setToolTip(info->description); 0237 timelinesTable->setItem(newRow, 0, item); 0238 0239 QCheckBox *enable = new QCheckBox(timelinesTable); 0240 enable->setChecked(mAccount->timelineNames().contains(timeline)); 0241 timelinesTable->setCellWidget(newRow, 1, enable); 0242 } 0243 } 0244 0245 void LaconicaEditAccountWidget::saveTimelinesTableState() 0246 { 0247 QStringList timelines; 0248 int rowCount = timelinesTable->rowCount(); 0249 for (int i = 0; i < rowCount; ++i) { 0250 QCheckBox *enable = qobject_cast<QCheckBox *>(timelinesTable->cellWidget(i, 1)); 0251 if (enable && enable->isChecked()) { 0252 timelines << timelinesTable->item(i, 0)->data(32).toString(); 0253 } 0254 } 0255 timelines.removeDuplicates(); 0256 mAccount->setTimelineNames(timelines); 0257 } 0258 0259 // void LaconicaEditAccountWidget::slotAuthMethodChanged(int index) 0260 // { 0261 // if(index == 0){ 0262 // kcfg_BasicBox->hide(); 0263 // kcfg_OAuthBox->show(); 0264 // } else { 0265 // kcfg_BasicBox->show(); 0266 // kcfg_OAuthBox->hide(); 0267 // } 0268 // } 0269 0270 // void LaconicaEditAccountWidget::setAuthenticated(bool authenticated) 0271 // { 0272 // isAuthenticated = authenticated; 0273 // if(authenticated){ 0274 // kcfg_authorize->setIcon(QIcon::fromTheme("object-unlocked")); 0275 // kcfg_authenticateLed->on(); 0276 // kcfg_authenticateStatus->setText(i18n("Authenticated")); 0277 // } else { 0278 // kcfg_authorize->setIcon(QIcon::fromTheme("object-locked")); 0279 // kcfg_authenticateLed->off(); 0280 // kcfg_authenticateStatus->setText(i18n("Not Authenticated")); 0281 // } 0282 // } 0283 0284 void LaconicaEditAccountWidget::slotCheckHostUrl() 0285 { 0286 if (!kcfg_host->text().isEmpty() && !kcfg_host->text().startsWith(QLatin1String("http"), 0287 Qt::CaseInsensitive) && !kcfg_host->text().startsWith(QLatin1String("https"))) { 0288 kcfg_host->setText(kcfg_host->text().prepend(QLatin1String("https://"))); 0289 } 0290 } 0291 0292 #include "moc_laconicaeditaccount.cpp"