mirror of
https://github.com/martinrotter/rssguard.git
synced 2025-02-03 02:37:46 +01:00
Fixed #132.
This commit is contained in:
parent
796bc43dd6
commit
7861641612
@ -25,6 +25,9 @@ CREATE TABLE IF NOT EXISTS TtRssAccounts (
|
||||
id INTEGER,
|
||||
username TEXT NOT NULL,
|
||||
password TEXT,
|
||||
auth_protected INTEGER(1) NOT NULL CHECK (auth_protected >= 0 AND auth_protected <= 1) DEFAULT 0,
|
||||
auth_username TEXT,
|
||||
auth_password TEXT,
|
||||
url TEXT NOT NULL,
|
||||
|
||||
FOREIGN KEY (id) REFERENCES Accounts (id)
|
||||
|
@ -19,6 +19,9 @@ CREATE TABLE IF NOT EXISTS TtRssAccounts (
|
||||
id INTEGER,
|
||||
username TEXT NOT NULL,
|
||||
password TEXT,
|
||||
auth_protected INTEGER(1) NOT NULL CHECK (auth_protected >= 0 AND auth_protected <= 1) DEFAULT 0,
|
||||
auth_username TEXT,
|
||||
auth_password TEXT,
|
||||
url TEXT NOT NULL,
|
||||
|
||||
FOREIGN KEY (id) REFERENCES Accounts (id)
|
||||
|
@ -11,6 +11,9 @@ CREATE TABLE TtRssAccounts (
|
||||
id INTEGER,
|
||||
username TEXT NOT NULL,
|
||||
password TEXT,
|
||||
auth_protected INTEGER(1) NOT NULL CHECK (auth_protected >= 0 AND auth_protected <= 1) DEFAULT 0,
|
||||
auth_username TEXT,
|
||||
auth_password TEXT,
|
||||
url TEXT NOT NULL,
|
||||
|
||||
FOREIGN KEY (id) REFERENCES Accounts (id)
|
||||
|
@ -11,6 +11,9 @@ CREATE TABLE TtRssAccounts (
|
||||
id INTEGER,
|
||||
username TEXT NOT NULL,
|
||||
password TEXT,
|
||||
auth_protected INTEGER(1) NOT NULL CHECK (auth_protected >= 0 AND auth_protected <= 1) DEFAULT 0,
|
||||
auth_username TEXT,
|
||||
auth_password TEXT,
|
||||
url TEXT NOT NULL,
|
||||
|
||||
FOREIGN KEY (id) REFERENCES Accounts (id)
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
Fixed:
|
||||
<ul>
|
||||
<li>Tiny Tiny RSS plugin now supports HTTP authentication (Basic, NTLM, Digest). (bug #132)
|
||||
<li>Fixed bug with updating feed. (bug #131)</li>
|
||||
<li>Solved problem when user selects HUGE number of individual messages and marks them read/unread. Reselecting them after change may cause RSS Guard to hang.</li>
|
||||
<li>Better info in popup notification when many feeds are updated.</li>
|
||||
|
@ -128,6 +128,9 @@ void FeedsView::loadExpandedStates() {
|
||||
setExpanded(model()->mapFromSource(sourceModel()->indexForItem(item)),
|
||||
settings->value(GROUP(Categories), setting_name, item->childCount() > 0).toBool());
|
||||
}
|
||||
|
||||
sortByColumn(qApp->settings()->value(GROUP(GUI), SETTING(GUI::DefaultSortColumnFeeds)).toInt(),
|
||||
static_cast<Qt::SortOrder>(qApp->settings()->value(GROUP(GUI), SETTING(GUI::DefaultSortOrderFeeds)).toInt()));
|
||||
}
|
||||
|
||||
void FeedsView::expandCollapseCurrentItem() {
|
||||
@ -407,9 +410,6 @@ void FeedsView::setupAppearance() {
|
||||
setItemDelegate(new StyledItemDelegateWithoutFocus(this));
|
||||
header()->setStretchLastSection(false);
|
||||
header()->setSortIndicatorShown(false);
|
||||
|
||||
sortByColumn(qApp->settings()->value(GROUP(GUI), SETTING(GUI::DefaultSortColumnFeeds)).toInt(),
|
||||
static_cast<Qt::SortOrder>(qApp->settings()->value(GROUP(GUI), SETTING(GUI::DefaultSortOrderFeeds)).toInt()));
|
||||
}
|
||||
|
||||
void FeedsView::selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) {
|
||||
|
@ -25,6 +25,7 @@
|
||||
Downloader::Downloader(QObject *parent)
|
||||
: QObject(parent), m_activeReply(NULL), m_downloadManager(new SilentNetworkAccessManager(this)),
|
||||
m_timer(new QTimer(this)), m_customHeaders(QHash<QByteArray, QByteArray>()), m_inputData(QByteArray()),
|
||||
m_targetProtected(false), m_targetUsername(QString()), m_targetPassword(QString()),
|
||||
m_lastOutputData(QByteArray()), m_lastOutputError(QNetworkReply::NoError), m_lastContentType(QVariant()) {
|
||||
|
||||
m_timer->setInterval(DOWNLOAD_TIMEOUT);
|
||||
@ -37,17 +38,11 @@ Downloader::~Downloader() {
|
||||
m_downloadManager->deleteLater();
|
||||
}
|
||||
|
||||
void Downloader::downloadFile(const QString &url, int timeout, bool protected_contents, const QString &username, const QString &password) {
|
||||
void Downloader::downloadFile(const QString &url, int timeout, bool protected_contents, const QString &username,
|
||||
const QString &password) {
|
||||
QNetworkRequest request;
|
||||
QObject originatingObject;
|
||||
QString non_const_url = url;
|
||||
|
||||
// Set credential information as originating object.
|
||||
originatingObject.setProperty("protected", protected_contents);
|
||||
originatingObject.setProperty("username", username);
|
||||
originatingObject.setProperty("password", password);
|
||||
request.setOriginatingObject(&originatingObject);
|
||||
|
||||
foreach (const QByteArray &header_name, m_customHeaders.keys()) {
|
||||
request.setRawHeader(header_name, m_customHeaders.value(header_name));
|
||||
}
|
||||
@ -63,10 +58,15 @@ void Downloader::downloadFile(const QString &url, int timeout, bool protected_co
|
||||
request.setUrl(non_const_url);
|
||||
}
|
||||
|
||||
m_targetProtected = protected_contents;
|
||||
m_targetUsername = username;
|
||||
m_targetPassword = password;
|
||||
|
||||
runGetRequest(request);
|
||||
}
|
||||
|
||||
void Downloader::uploadData(const QString &url, const QByteArray &data, int timeout) {
|
||||
void Downloader::uploadData(const QString &url, const QByteArray &data, int timeout,
|
||||
bool protected_contents, const QString &username, const QString &password) {
|
||||
QNetworkRequest request;
|
||||
QString non_const_url = url;
|
||||
|
||||
@ -87,6 +87,10 @@ void Downloader::uploadData(const QString &url, const QByteArray &data, int time
|
||||
request.setUrl(non_const_url);
|
||||
}
|
||||
|
||||
m_targetProtected = protected_contents;
|
||||
m_targetUsername = username;
|
||||
m_targetPassword = password;
|
||||
|
||||
runPostRequest(request, m_inputData);
|
||||
}
|
||||
|
||||
@ -154,6 +158,10 @@ void Downloader::runPostRequest(const QNetworkRequest &request, const QByteArray
|
||||
m_timer->start();
|
||||
m_activeReply = m_downloadManager->post(request, data);
|
||||
|
||||
m_activeReply->setProperty("protected", m_targetProtected);
|
||||
m_activeReply->setProperty("username", m_targetUsername);
|
||||
m_activeReply->setProperty("password", m_targetPassword);
|
||||
|
||||
connect(m_activeReply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(progressInternal(qint64,qint64)));
|
||||
connect(m_activeReply, SIGNAL(finished()), this, SLOT(finished()));
|
||||
}
|
||||
@ -162,6 +170,10 @@ void Downloader::runGetRequest(const QNetworkRequest &request) {
|
||||
m_timer->start();
|
||||
m_activeReply = m_downloadManager->get(request);
|
||||
|
||||
m_activeReply->setProperty("protected", m_targetProtected);
|
||||
m_activeReply->setProperty("username", m_targetUsername);
|
||||
m_activeReply->setProperty("password", m_targetPassword);
|
||||
|
||||
connect(m_activeReply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(progressInternal(qint64,qint64)));
|
||||
connect(m_activeReply, SIGNAL(finished()), this, SLOT(finished()));
|
||||
}
|
||||
|
@ -52,7 +52,8 @@ class Downloader : public QObject {
|
||||
// Performs asynchronous upload of given data as HTTP POST.
|
||||
// User needs to setup "Content-Encoding" header which
|
||||
// matches encoding of the data.
|
||||
void uploadData(const QString &url, const QByteArray &data, int timeout = DOWNLOAD_TIMEOUT);
|
||||
void uploadData(const QString &url, const QByteArray &data, int timeout = DOWNLOAD_TIMEOUT,
|
||||
bool protected_contents = false, const QString &username = QString(), const QString &password = QString());
|
||||
|
||||
signals:
|
||||
// Emitted when new progress is known.
|
||||
@ -80,6 +81,10 @@ class Downloader : public QObject {
|
||||
QHash<QByteArray, QByteArray> m_customHeaders;
|
||||
QByteArray m_inputData;
|
||||
|
||||
bool m_targetProtected;
|
||||
QString m_targetUsername;
|
||||
QString m_targetPassword;
|
||||
|
||||
// Response data.
|
||||
QByteArray m_lastOutputData;
|
||||
QNetworkReply::NetworkError m_lastOutputError;
|
||||
|
@ -149,7 +149,8 @@ QNetworkReply::NetworkError NetworkFactory::downloadIcon(const QList<QString> &u
|
||||
}
|
||||
|
||||
NetworkResult NetworkFactory::uploadData(const QString &url, int timeout, const QByteArray &input_data,
|
||||
const QString &input_content_type, QByteArray &output) {
|
||||
const QString &input_content_type, QByteArray &output,
|
||||
bool protected_contents, const QString &username, const QString &password) {
|
||||
Downloader downloader;
|
||||
QEventLoop loop;
|
||||
NetworkResult result;
|
||||
@ -159,7 +160,7 @@ NetworkResult NetworkFactory::uploadData(const QString &url, int timeout, const
|
||||
// We need to quit event loop when the download finishes.
|
||||
QObject::connect(&downloader, SIGNAL(completed(QNetworkReply::NetworkError)), &loop, SLOT(quit()));
|
||||
|
||||
downloader.uploadData(url, input_data, timeout);
|
||||
downloader.uploadData(url, input_data, timeout, protected_contents, username, password);
|
||||
loop.exec();
|
||||
output = downloader.lastOutputData();
|
||||
result.first = downloader.lastOutputError();
|
||||
|
@ -44,7 +44,9 @@ class NetworkFactory {
|
||||
static QNetworkReply::NetworkError downloadIcon(const QList<QString> &urls, int timeout, QIcon &output);
|
||||
|
||||
static NetworkResult uploadData(const QString &url, int timeout, const QByteArray &input_data,
|
||||
const QString &input_content_type, QByteArray &output);
|
||||
const QString &input_content_type, QByteArray &output,
|
||||
bool protected_contents = false, const QString &username = QString(),
|
||||
const QString &password = QString());
|
||||
|
||||
static NetworkResult downloadFeedFile(const QString &url, int timeout, QByteArray &output,
|
||||
bool protected_contents = false, const QString &username = QString(),
|
||||
|
12
src/network-web/silentnetworkaccessmanager.cpp
Normal file → Executable file
12
src/network-web/silentnetworkaccessmanager.cpp
Normal file → Executable file
@ -44,20 +44,20 @@ SilentNetworkAccessManager *SilentNetworkAccessManager::instance() {
|
||||
}
|
||||
|
||||
void SilentNetworkAccessManager::onAuthenticationRequired(QNetworkReply *reply, QAuthenticator *authenticator) {
|
||||
QObject *originating_object = reply->request().originatingObject();
|
||||
QList<QString> keys = authenticator->options().keys();
|
||||
|
||||
if (originating_object->property("protected").toBool()) {
|
||||
if (reply->property("protected").toBool()) {
|
||||
// This feed contains authentication information, it is good.
|
||||
authenticator->setUser(originating_object->property("username").toString());
|
||||
authenticator->setPassword(originating_object->property("password").toString());
|
||||
authenticator->setUser(reply->property("username").toString());
|
||||
authenticator->setPassword(reply->property("password").toString());
|
||||
reply->setProperty("authentication-given", true);
|
||||
|
||||
qDebug("Feed '%s' requested authentication and got it.", qPrintable(reply->url().toString()));
|
||||
qDebug("Item '%s' requested authentication and got it.", qPrintable(reply->url().toString()));
|
||||
}
|
||||
else {
|
||||
reply->setProperty("authentication-given", false);
|
||||
|
||||
// Authentication is required but this feed does not contain it.
|
||||
qWarning("Feed '%s' requested authentication but username/password is not available.", qPrintable(reply->url().toString()));
|
||||
qWarning("Item '%s' requested authentication but username/password is not available.", qPrintable(reply->url().toString()));
|
||||
}
|
||||
}
|
||||
|
@ -238,7 +238,7 @@
|
||||
<string>Some feeds require authentication, including GMail feeds. BASIC, NTLM-2 and DIGEST-MD5 authentication schemes are supported.</string>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Requires authentication</string>
|
||||
<string>Requires HTTP authentication</string>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>false</bool>
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "services/tt-rss/ttrssserviceroot.h"
|
||||
#include "services/tt-rss/network/ttrssnetworkfactory.h"
|
||||
#include "miscellaneous/iconfactory.h"
|
||||
#include "network-web/networkfactory.h"
|
||||
|
||||
|
||||
FormEditAccount::FormEditAccount(QWidget *parent)
|
||||
@ -32,6 +33,8 @@ FormEditAccount::FormEditAccount(QWidget *parent)
|
||||
setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog | Qt::WindowSystemMenuHint);
|
||||
setWindowIcon(qApp->icons()->fromTheme(QSL("application-ttrss")));
|
||||
|
||||
m_ui->m_txtHttpUsername->lineEdit()->setPlaceholderText(tr("HTTP authentication username"));
|
||||
m_ui->m_txtHttpPassword->lineEdit()->setPlaceholderText(tr("HTTP authentication password"));
|
||||
m_ui->m_txtPassword->lineEdit()->setPlaceholderText(tr("Password for your TT-RSS account"));
|
||||
m_ui->m_txtUsername->lineEdit()->setPlaceholderText(tr("Username for your TT-RSS account"));
|
||||
m_ui->m_txtUrl->lineEdit()->setPlaceholderText(tr("FULL URL of your TT-RSS instance WITH trailing \"/api/\" string"));
|
||||
@ -50,17 +53,25 @@ FormEditAccount::FormEditAccount(QWidget *parent)
|
||||
connect(m_ui->m_buttonBox, SIGNAL(rejected()), this, SLOT(onClickedCancel()));
|
||||
connect(m_ui->m_txtPassword->lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(onPasswordChanged()));
|
||||
connect(m_ui->m_txtUsername->lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(onUsernameChanged()));
|
||||
connect(m_ui->m_txtHttpPassword->lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(onHttpPasswordChanged()));
|
||||
connect(m_ui->m_txtHttpUsername->lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(onHttpUsernameChanged()));
|
||||
connect(m_ui->m_txtUrl->lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(onUrlChanged()));
|
||||
connect(m_ui->m_txtPassword->lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(checkOkButton()));
|
||||
connect(m_ui->m_txtUsername->lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(checkOkButton()));
|
||||
connect(m_ui->m_txtUrl->lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(checkOkButton()));
|
||||
connect(m_ui->m_btnTestSetup, SIGNAL(clicked()), this, SLOT(performTest()));
|
||||
connect(m_ui->m_gbHttpAuthentication, SIGNAL(toggled(bool)), this, SLOT(onHttpPasswordChanged()));
|
||||
connect(m_ui->m_gbHttpAuthentication, SIGNAL(toggled(bool)), this, SLOT(onHttpUsernameChanged()));
|
||||
connect(m_ui->m_checkShowHttpPassword, SIGNAL(toggled(bool)), this, SLOT(displayHttpPassword(bool)));
|
||||
|
||||
onPasswordChanged();
|
||||
onUsernameChanged();
|
||||
onUrlChanged();
|
||||
onHttpPasswordChanged();
|
||||
onHttpUsernameChanged();
|
||||
checkOkButton();
|
||||
displayPassword(false);
|
||||
displayHttpPassword(false);
|
||||
}
|
||||
|
||||
FormEditAccount::~FormEditAccount() {
|
||||
@ -77,6 +88,9 @@ void FormEditAccount::execForEdit(TtRssServiceRoot *existing_root) {
|
||||
setWindowTitle(tr("Edit existing Tiny Tiny RSS account"));
|
||||
m_editableRoot = existing_root;
|
||||
|
||||
m_ui->m_gbHttpAuthentication->setChecked(existing_root->network()->authIsUsed());
|
||||
m_ui->m_txtHttpPassword->lineEdit()->setText(existing_root->network()->authPassword());
|
||||
m_ui->m_txtHttpUsername->lineEdit()->setText(existing_root->network()->authUsername());
|
||||
m_ui->m_txtUsername->lineEdit()->setText(existing_root->network()->username());
|
||||
m_ui->m_txtPassword->lineEdit()->setText(existing_root->network()->password());
|
||||
m_ui->m_txtUrl->lineEdit()->setText(existing_root->network()->url());
|
||||
@ -88,12 +102,19 @@ void FormEditAccount::displayPassword(bool display) {
|
||||
m_ui->m_txtPassword->lineEdit()->setEchoMode(display ? QLineEdit::Normal : QLineEdit::Password);
|
||||
}
|
||||
|
||||
void FormEditAccount::displayHttpPassword(bool display) {
|
||||
m_ui->m_txtHttpPassword->lineEdit()->setEchoMode(display ? QLineEdit::Normal : QLineEdit::Password);
|
||||
}
|
||||
|
||||
void FormEditAccount::performTest() {
|
||||
TtRssNetworkFactory factory;
|
||||
|
||||
factory.setUsername(m_ui->m_txtUsername->lineEdit()->text());
|
||||
factory.setPassword(m_ui->m_txtPassword->lineEdit()->text());
|
||||
factory.setUrl(m_ui->m_txtUrl->lineEdit()->text());
|
||||
factory.setAuthIsUsed(m_ui->m_gbHttpAuthentication->isChecked());
|
||||
factory.setAuthUsername(m_ui->m_txtHttpUsername->lineEdit()->text());
|
||||
factory.setAuthPassword(m_ui->m_txtHttpPassword->lineEdit()->text());
|
||||
|
||||
TtRssLoginResponse result = factory.login();
|
||||
|
||||
@ -132,8 +153,8 @@ void FormEditAccount::performTest() {
|
||||
}
|
||||
else {
|
||||
m_ui->m_lblTestResult->setStatus(WidgetWithStatus::Error,
|
||||
tr("Network error, have you entered correct Tiny Tiny RSS API endpoint?"),
|
||||
tr("Network error, have you entered correct Tiny Tiny RSS API endpoint?"));
|
||||
tr("Network error: '%1'.").arg(NetworkFactory::networkErrorText(factory.lastError())),
|
||||
tr("Network error, have you entered correct Tiny Tiny RSS API endpoint and password?"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -150,15 +171,18 @@ void FormEditAccount::onClickedOk() {
|
||||
m_editableRoot->network()->setUrl(m_ui->m_txtUrl->lineEdit()->text());
|
||||
m_editableRoot->network()->setUsername(m_ui->m_txtUsername->lineEdit()->text());
|
||||
m_editableRoot->network()->setPassword(m_ui->m_txtPassword->lineEdit()->text());
|
||||
m_editableRoot->network()->setAuthIsUsed(m_ui->m_gbHttpAuthentication->isChecked());
|
||||
m_editableRoot->network()->setAuthUsername(m_ui->m_txtHttpUsername->lineEdit()->text());
|
||||
m_editableRoot->network()->setAuthPassword(m_ui->m_txtHttpPassword->lineEdit()->text());
|
||||
m_editableRoot->saveAccountDataToDatabase();
|
||||
|
||||
accept();
|
||||
|
||||
if (editing_account) {
|
||||
m_editableRoot->network()->logout();
|
||||
m_editableRoot->completelyRemoveAllData();
|
||||
m_editableRoot->syncIn();
|
||||
}
|
||||
|
||||
accept();
|
||||
}
|
||||
|
||||
void FormEditAccount::onClickedCancel() {
|
||||
@ -187,6 +211,28 @@ void FormEditAccount::onPasswordChanged() {
|
||||
}
|
||||
}
|
||||
|
||||
void FormEditAccount::onHttpUsernameChanged() {
|
||||
bool is_username_ok = !m_ui->m_gbHttpAuthentication->isChecked() || !m_ui->m_txtHttpUsername->lineEdit()->text().isEmpty();
|
||||
|
||||
m_ui->m_txtHttpUsername->setStatus(is_username_ok ?
|
||||
LineEditWithStatus::Ok :
|
||||
LineEditWithStatus::Warning,
|
||||
is_username_ok ?
|
||||
tr("Username is ok or it is not needed.") :
|
||||
tr("Username is empty."));
|
||||
}
|
||||
|
||||
void FormEditAccount::onHttpPasswordChanged() {
|
||||
bool is_username_ok = !m_ui->m_gbHttpAuthentication->isChecked() || !m_ui->m_txtHttpPassword->lineEdit()->text().isEmpty();
|
||||
|
||||
m_ui->m_txtHttpPassword->setStatus(is_username_ok ?
|
||||
LineEditWithStatus::Ok :
|
||||
LineEditWithStatus::Warning,
|
||||
is_username_ok ?
|
||||
tr("Password is ok or it is not needed.") :
|
||||
tr("Password is empty."));
|
||||
}
|
||||
|
||||
void FormEditAccount::onUrlChanged() {
|
||||
QString url = m_ui->m_txtUrl->lineEdit()->text();
|
||||
|
||||
|
@ -42,12 +42,15 @@ class FormEditAccount : public QDialog {
|
||||
|
||||
private slots:
|
||||
void displayPassword(bool display);
|
||||
void displayHttpPassword(bool display);
|
||||
void performTest();
|
||||
void onClickedOk();
|
||||
void onClickedCancel();
|
||||
|
||||
void onUsernameChanged();
|
||||
void onPasswordChanged();
|
||||
void onHttpUsernameChanged();
|
||||
void onHttpPasswordChanged();
|
||||
void onUrlChanged();
|
||||
void checkOkButton();
|
||||
|
||||
|
@ -7,106 +7,132 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>465</width>
|
||||
<height>235</height>
|
||||
<height>304</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="2" column="0">
|
||||
<widget class="QPushButton" name="m_btnTestSetup">
|
||||
<property name="text">
|
||||
<string>&Test setup</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="LabelWithStatus" name="m_lblTestResult" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="layoutDirection">
|
||||
<enum>Qt::RightToLeft</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QGroupBox" name="m_gbAuthentication">
|
||||
<property name="toolTip">
|
||||
<string>Some feeds require authentication, including GMail feeds. BASIC, NTLM-2 and DIGEST-MD5 authentication schemes are supported.</string>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Authentication</string>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Username</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>m_txtUsername</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Password</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>m_txtPassword</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="LineEditWithStatus" name="m_txtPassword" native="true"/>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="LineEditWithStatus" name="m_txtUsername" native="true"/>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="m_checkShowPassword">
|
||||
<property name="text">
|
||||
<string>Show password</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="m_lblTitle">
|
||||
<property name="text">
|
||||
<string>URL</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>m_txtUrl</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="LineEditWithStatus" name="m_txtUrl" native="true"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QGroupBox" name="m_gbAuthentication">
|
||||
<property name="toolTip">
|
||||
<string>Some feeds require authentication, including GMail feeds. BASIC, NTLM-2 and DIGEST-MD5 authentication schemes are supported.</string>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Authentication</string>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Username</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>m_txtUsername</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Password</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>m_txtPassword</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="LineEditWithStatus" name="m_txtPassword" native="true"/>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="LineEditWithStatus" name="m_txtUsername" native="true"/>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="m_checkShowPassword">
|
||||
<property name="text">
|
||||
<string>Show password</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QGroupBox" name="m_gbHttpAuthentication">
|
||||
<property name="toolTip">
|
||||
<string>Some feeds require authentication, including GMail feeds. BASIC, NTLM-2 and DIGEST-MD5 authentication schemes are supported.</string>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Requires HTTP authentication</string>
|
||||
</property>
|
||||
<property name="flat">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout_3">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Username</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>m_txtUsername</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="LineEditWithStatus" name="m_txtHttpUsername" native="true"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Password</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>m_txtPassword</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="LineEditWithStatus" name="m_txtHttpPassword" native="true"/>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="m_checkShowHttpPassword">
|
||||
<property name="text">
|
||||
<string>Show password</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="LabelWithStatus" name="m_lblTestResult" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="layoutDirection">
|
||||
<enum>Qt::RightToLeft</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="2">
|
||||
<widget class="QDialogButtonBox" name="m_buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
@ -116,6 +142,30 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="m_lblTitle">
|
||||
<property name="text">
|
||||
<string>URL</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>m_txtUrl</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="LineEditWithStatus" name="m_txtUrl" native="true"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QPushButton" name="m_btnTestSetup">
|
||||
<property name="text">
|
||||
<string>&Test setup</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
@ -132,9 +182,6 @@
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>m_btnTestSetup</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
@ -31,7 +31,8 @@
|
||||
|
||||
|
||||
TtRssNetworkFactory::TtRssNetworkFactory()
|
||||
: m_url(QString()), m_username(QString()), m_password(QString()), m_sessionId(QString()),
|
||||
: m_url(QString()), m_username(QString()), m_password(QString()), m_authIsUsed(false),
|
||||
m_authUsername(QString()), m_authPassword(QString()), m_sessionId(QString()),
|
||||
m_lastLoginTime(QDateTime()), m_lastError(QNetworkReply::NoError) {
|
||||
}
|
||||
|
||||
@ -81,7 +82,8 @@ TtRssLoginResponse TtRssNetworkFactory::login() {
|
||||
json["password"] = m_password;
|
||||
|
||||
QByteArray result_raw;
|
||||
NetworkResult network_reply = NetworkFactory::uploadData(m_url, DOWNLOAD_TIMEOUT, QtJson::serialize(json), CONTENT_TYPE, result_raw);
|
||||
NetworkResult network_reply = NetworkFactory::uploadData(m_url, DOWNLOAD_TIMEOUT, QtJson::serialize(json), CONTENT_TYPE, result_raw,
|
||||
m_authIsUsed, m_authUsername, m_authPassword);
|
||||
TtRssLoginResponse login_response(QString::fromUtf8(result_raw));
|
||||
|
||||
if (network_reply.first == QNetworkReply::NoError) {
|
||||
@ -101,7 +103,8 @@ TtRssResponse TtRssNetworkFactory::logout() {
|
||||
json["sid"] = m_sessionId;
|
||||
|
||||
QByteArray result_raw;
|
||||
NetworkResult network_reply = NetworkFactory::uploadData(m_url, DOWNLOAD_TIMEOUT, QtJson::serialize(json), CONTENT_TYPE, result_raw);
|
||||
NetworkResult network_reply = NetworkFactory::uploadData(m_url, DOWNLOAD_TIMEOUT, QtJson::serialize(json), CONTENT_TYPE, result_raw,
|
||||
m_authIsUsed, m_authUsername, m_authPassword);
|
||||
|
||||
m_lastError = network_reply.first;
|
||||
|
||||
@ -124,7 +127,8 @@ TtRssGetFeedsCategoriesResponse TtRssNetworkFactory::getFeedsCategories() {
|
||||
json["include_empty"] = false;
|
||||
|
||||
QByteArray result_raw;
|
||||
NetworkResult network_reply = NetworkFactory::uploadData(m_url, DOWNLOAD_TIMEOUT, QtJson::serialize(json), CONTENT_TYPE, result_raw);
|
||||
NetworkResult network_reply = NetworkFactory::uploadData(m_url, DOWNLOAD_TIMEOUT, QtJson::serialize(json), CONTENT_TYPE, result_raw,
|
||||
m_authIsUsed, m_authUsername, m_authPassword);
|
||||
TtRssGetFeedsCategoriesResponse result(QString::fromUtf8(result_raw));
|
||||
|
||||
if (result.isNotLoggedIn()) {
|
||||
@ -132,7 +136,8 @@ TtRssGetFeedsCategoriesResponse TtRssNetworkFactory::getFeedsCategories() {
|
||||
login();
|
||||
json["sid"] = m_sessionId;
|
||||
|
||||
network_reply = NetworkFactory::uploadData(m_url, DOWNLOAD_TIMEOUT, QtJson::serialize(json), CONTENT_TYPE, result_raw);
|
||||
network_reply = NetworkFactory::uploadData(m_url, DOWNLOAD_TIMEOUT, QtJson::serialize(json), CONTENT_TYPE, result_raw,
|
||||
m_authIsUsed, m_authUsername, m_authPassword);
|
||||
result = TtRssGetFeedsCategoriesResponse(QString::fromUtf8(result_raw));
|
||||
}
|
||||
|
||||
@ -155,7 +160,8 @@ TtRssGetHeadlinesResponse TtRssNetworkFactory::getHeadlines(int feed_id, bool fo
|
||||
json["sanitize"] = sanitize;
|
||||
|
||||
QByteArray result_raw;
|
||||
NetworkResult network_reply = NetworkFactory::uploadData(m_url, DOWNLOAD_TIMEOUT, QtJson::serialize(json), CONTENT_TYPE, result_raw);
|
||||
NetworkResult network_reply = NetworkFactory::uploadData(m_url, DOWNLOAD_TIMEOUT, QtJson::serialize(json), CONTENT_TYPE, result_raw,
|
||||
m_authIsUsed, m_authUsername, m_authPassword);
|
||||
TtRssGetHeadlinesResponse result(QString::fromUtf8(result_raw));
|
||||
|
||||
if (result.isNotLoggedIn()) {
|
||||
@ -163,7 +169,8 @@ TtRssGetHeadlinesResponse TtRssNetworkFactory::getHeadlines(int feed_id, bool fo
|
||||
login();
|
||||
json["sid"] = m_sessionId;
|
||||
|
||||
network_reply = NetworkFactory::uploadData(m_url, DOWNLOAD_TIMEOUT, QtJson::serialize(json), CONTENT_TYPE, result_raw);
|
||||
network_reply = NetworkFactory::uploadData(m_url, DOWNLOAD_TIMEOUT, QtJson::serialize(json), CONTENT_TYPE, result_raw,
|
||||
m_authIsUsed, m_authUsername, m_authPassword);
|
||||
result = TtRssGetHeadlinesResponse(QString::fromUtf8(result_raw));
|
||||
}
|
||||
|
||||
@ -182,7 +189,8 @@ TtRssUpdateArticleResponse TtRssNetworkFactory::updateArticles(const QStringList
|
||||
json["field"] = (int) field;
|
||||
|
||||
QByteArray result_raw;
|
||||
NetworkResult network_reply = NetworkFactory::uploadData(m_url, DOWNLOAD_TIMEOUT, QtJson::serialize(json), CONTENT_TYPE, result_raw);
|
||||
NetworkResult network_reply = NetworkFactory::uploadData(m_url, DOWNLOAD_TIMEOUT, QtJson::serialize(json), CONTENT_TYPE, result_raw,
|
||||
m_authIsUsed, m_authUsername, m_authPassword);
|
||||
TtRssUpdateArticleResponse result(QString::fromUtf8(result_raw));
|
||||
|
||||
if (result.isNotLoggedIn()) {
|
||||
@ -190,13 +198,38 @@ TtRssUpdateArticleResponse TtRssNetworkFactory::updateArticles(const QStringList
|
||||
login();
|
||||
json["sid"] = m_sessionId;
|
||||
|
||||
network_reply = NetworkFactory::uploadData(m_url, DOWNLOAD_TIMEOUT, QtJson::serialize(json), CONTENT_TYPE, result_raw);
|
||||
network_reply = NetworkFactory::uploadData(m_url, DOWNLOAD_TIMEOUT, QtJson::serialize(json), CONTENT_TYPE, result_raw,
|
||||
m_authIsUsed, m_authUsername, m_authPassword);
|
||||
result = TtRssUpdateArticleResponse(QString::fromUtf8(result_raw));
|
||||
}
|
||||
|
||||
m_lastError = network_reply.first;
|
||||
return result;
|
||||
}
|
||||
bool TtRssNetworkFactory::authIsUsed() const
|
||||
{
|
||||
return m_authIsUsed;
|
||||
}
|
||||
|
||||
void TtRssNetworkFactory::setAuthIsUsed(bool auth_is_used) {
|
||||
m_authIsUsed = auth_is_used;
|
||||
}
|
||||
|
||||
QString TtRssNetworkFactory::authUsername() const {
|
||||
return m_authUsername;
|
||||
}
|
||||
|
||||
void TtRssNetworkFactory::setAuthUsername(const QString &auth_username) {
|
||||
m_authUsername = auth_username;
|
||||
}
|
||||
|
||||
QString TtRssNetworkFactory::authPassword() const {
|
||||
return m_authPassword;
|
||||
}
|
||||
|
||||
void TtRssNetworkFactory::setAuthPassword(const QString &auth_password) {
|
||||
m_authPassword = auth_password;
|
||||
}
|
||||
|
||||
TtRssResponse::TtRssResponse(const QString &raw_content) {
|
||||
m_rawContent = QtJson::parse(raw_content).toMap();
|
||||
|
@ -111,6 +111,15 @@ class TtRssNetworkFactory {
|
||||
QString password() const;
|
||||
void setPassword(const QString &password);
|
||||
|
||||
bool authIsUsed() const;
|
||||
void setAuthIsUsed(bool auth_is_used);
|
||||
|
||||
QString authUsername() const;
|
||||
void setAuthUsername(const QString &auth_username);
|
||||
|
||||
QString authPassword() const;
|
||||
void setAuthPassword(const QString &auth_password);
|
||||
|
||||
// Metadata.
|
||||
QDateTime lastLoginTime() const;
|
||||
|
||||
@ -139,6 +148,9 @@ class TtRssNetworkFactory {
|
||||
QString m_url;
|
||||
QString m_username;
|
||||
QString m_password;
|
||||
bool m_authIsUsed;
|
||||
QString m_authUsername;
|
||||
QString m_authPassword;
|
||||
QString m_sessionId;
|
||||
QDateTime m_lastLoginTime;
|
||||
QNetworkReply::NetworkError m_lastError;
|
||||
|
@ -96,6 +96,7 @@ int TtRssFeed::update() {
|
||||
|
||||
if (serviceRoot()->network()->lastError() != QNetworkReply::NoError) {
|
||||
setStatus(Feed::Error);
|
||||
serviceRoot()->itemChanged(QList<RootItem*>() << this);
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "definitions/definitions.h"
|
||||
#include "miscellaneous/application.h"
|
||||
#include "miscellaneous/iconfactory.h"
|
||||
#include "miscellaneous/textfactory.h"
|
||||
#include "gui/dialogs/formmain.h"
|
||||
#include "services/tt-rss/gui/formeditaccount.h"
|
||||
#include "services/tt-rss/ttrssserviceroot.h"
|
||||
@ -79,14 +80,19 @@ QList<ServiceRoot*> TtRssServiceEntryPoint::initializeSubtree() {
|
||||
QSqlQuery query(database);
|
||||
QList<ServiceRoot*> roots;
|
||||
|
||||
if (query.exec("SELECT id, username, password, url FROM TtRssAccounts;")) {
|
||||
if (query.exec("SELECT * FROM TtRssAccounts;")) {
|
||||
while (query.next()) {
|
||||
TtRssServiceRoot *root = new TtRssServiceRoot();
|
||||
root->setId(query.value(0).toInt());
|
||||
root->setAccountId(query.value(0).toInt());
|
||||
root->network()->setUsername(query.value(1).toString());
|
||||
root->network()->setPassword(query.value(2).toString());
|
||||
root->network()->setUrl(query.value(3).toString());
|
||||
root->network()->setPassword(TextFactory::decrypt(query.value(2).toString()));
|
||||
|
||||
root->network()->setAuthIsUsed(query.value(3).toBool());
|
||||
root->network()->setAuthUsername(query.value(4).toString());
|
||||
root->network()->setAuthPassword(TextFactory::decrypt(query.value(5).toString()));
|
||||
|
||||
root->network()->setUrl(query.value(6).toString());
|
||||
root->updateTitle();
|
||||
roots.append(root);
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include "miscellaneous/application.h"
|
||||
#include "miscellaneous/settings.h"
|
||||
#include "miscellaneous/textfactory.h"
|
||||
#include "gui/dialogs/formmain.h"
|
||||
#include "network-web/networkfactory.h"
|
||||
#include "services/tt-rss/ttrssserviceentrypoint.h"
|
||||
@ -424,12 +425,16 @@ void TtRssServiceRoot::saveAccountDataToDatabase() {
|
||||
QSqlQuery query(database);
|
||||
|
||||
query.prepare("UPDATE TtRssAccounts "
|
||||
"SET username = :username, password = :password, url = :url "
|
||||
"SET username = :username, password = :password, url = :url, auth_protected = :auth_protected, "
|
||||
"auth_username = :auth_username, auth_password = :auth_password "
|
||||
"WHERE id = :id;");
|
||||
query.bindValue(":username", m_network->username());
|
||||
query.bindValue(":password", m_network->password());
|
||||
query.bindValue(":url", m_network->url());
|
||||
query.bindValue(":id", accountId());
|
||||
query.bindValue(QSL(":username"), m_network->username());
|
||||
query.bindValue(QSL(":password"), TextFactory::encrypt(m_network->password()));
|
||||
query.bindValue(QSL(":url"), m_network->url());
|
||||
query.bindValue(QSL(":auth_protected"), m_network->authIsUsed());
|
||||
query.bindValue(QSL(":auth_username"), m_network->authUsername());
|
||||
query.bindValue(QSL(":auth_password"), TextFactory::encrypt(m_network->authPassword()));
|
||||
query.bindValue(QSL(":id"), accountId());
|
||||
|
||||
if (query.exec()) {
|
||||
updateTitle();
|
||||
|
Loading…
x
Reference in New Issue
Block a user