Fixed #66 (Authentication dialog should indicate retry)

This commit is contained in:
Matthias Koefferlein 2018-01-24 22:08:13 +01:00
parent 04b4c21e82
commit aab425a58c
3 changed files with 217 additions and 99 deletions

View File

@ -1,3 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PasswordDialog</class>
<widget class="QDialog" name="PasswordDialog">
@ -6,32 +7,45 @@
<x>0</x>
<y>0</y>
<width>338</width>
<height>230</height>
<height>229</height>
</rect>
</property>
<property name="windowTitle">
<string>Authentication Required</string>
</property>
<layout class="QGridLayout">
<property name="margin" >
<property name="leftMargin">
<number>9</number>
</property>
<property name="topMargin">
<number>9</number>
</property>
<property name="rightMargin">
<number>9</number>
</property>
<property name="bottomMargin">
<number>9</number>
</property>
<property name="spacing">
<number>6</number>
</property>
<item row="5" column="1" >
<widget class="QLabel" name="label_3" >
<property name="text" >
<string>Password </string>
<item row="8" column="1" colspan="2">
<spacer>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item row="5" column="2" >
<item row="7" column="2">
<widget class="QLineEdit" name="password_le">
<property name="sizePolicy">
<sizepolicy>
<hsizetype>5</hsizetype>
<vsizetype>0</vsizetype>
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
@ -41,38 +55,50 @@
</property>
</widget>
</item>
<item row="4" column="2" >
<item row="6" column="1">
<widget class="QLabel" name="label">
<property name="text">
<string>User</string>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Password </string>
</property>
</widget>
</item>
<item row="6" column="2">
<widget class="QLineEdit" name="user_le">
<property name="sizePolicy">
<sizepolicy>
<hsizetype>5</hsizetype>
<vsizetype>0</vsizetype>
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="4" column="0" >
<spacer>
<item row="9" column="0" colspan="4">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType" >
<enum>QSizePolicy::Expanding</enum>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
<property name="sizeHint" >
<size>
<width>10</width>
<height>20</height>
</size>
</property>
</spacer>
</widget>
</item>
<item row="4" column="1" >
<widget class="QLabel" name="label" >
<item row="0" column="0" rowspan="2" colspan="4">
<widget class="QLabel" name="realm_label">
<property name="text">
<string>User</string>
<string>-</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
</widget>
</item>
@ -82,22 +108,88 @@
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" >
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
<height>16</height>
</size>
</property>
</spacer>
</item>
<item row="4" column="3" >
<item row="6" column="0">
<spacer>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>10</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="4" column="1" colspan="3">
<widget class="QLabel" name="attempt_label">
<property name="palette">
<palette>
<active>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>190</red>
<green>190</green>
<blue>190</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string># of attempt</string>
</property>
</widget>
</item>
<item row="6" column="3">
<spacer>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
@ -105,16 +197,6 @@
</property>
</spacer>
</item>
<item row="7" column="0" colspan="4" >
<widget class="QDialogButtonBox" name="buttonBox" >
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons" >
<set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
<item row="2" column="0" colspan="4">
<widget class="QLabel" name="where_label">
<property name="text">
@ -128,28 +210,18 @@
</property>
</widget>
</item>
<item rowspan="2" row="0" column="0" colspan="4" >
<widget class="QLabel" name="realm_label" >
<property name="text" >
<string>-</string>
</property>
<property name="alignment" >
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="wordWrap" >
<bool>false</bool>
</property>
</widget>
</item>
<item row="6" column="1" colspan="2" >
<spacer>
<item row="5" column="1" colspan="2">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" >
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
<height>10</height>
</size>
</property>
</spacer>

View File

@ -54,13 +54,20 @@ public:
setupUi (this);
}
bool exec_auth (bool proxy, const QString &where, QAuthenticator *auth)
bool exec_auth (bool proxy, int attempt, const QString &where, QAuthenticator *auth)
{
realm_label->setText (QString::fromUtf8 ("<b>Realm:</b> ") + auth->realm ());
realm_label->setText (tr ("<b>Realm:</b> ") + auth->realm ());
if (proxy) {
where_label->setText (QString::fromUtf8 ("<b>Proxy:</b> ") + where);
where_label->setText (tr ("<b>Proxy:</b> ") + where);
} else {
where_label->setText (QString::fromUtf8 ("<b>URL:</b> ") + where);
where_label->setText (tr ("<b>URL:</b> ") + where);
}
if (attempt > 1) {
attempt_label->setText (tr ("Authentication failed - please try again"));
attempt_label->show ();
} else {
attempt_label->hide ();
}
if (QDialog::exec ()) {
@ -78,23 +85,30 @@ public:
// AuthenticationHandler implementation
AuthenticationHandler::AuthenticationHandler ()
: QObject (0)
: QObject (0), m_retry (0), m_proxy_retry (0)
{
// .. nothing yet ..
}
void
AuthenticationHandler::reset ()
{
m_retry = 0;
m_proxy_retry = 0;
}
void
AuthenticationHandler::authenticationRequired (QNetworkReply *reply, QAuthenticator *auth)
{
PasswordDialog pw_dialog (0 /*no parent*/);
pw_dialog.exec_auth (false, reply->url ().toString (), auth);
pw_dialog.exec_auth (false, ++m_retry, reply->url ().toString (), auth);
}
void
AuthenticationHandler::proxyAuthenticationRequired (const QNetworkProxy &proxy, QAuthenticator *auth)
{
PasswordDialog pw_dialog (0 /*no parent*/);
pw_dialog.exec_auth (true, proxy.hostName (), auth);
pw_dialog.exec_auth (true, ++m_proxy_retry, proxy.hostName (), auth);
}
// ---------------------------------------------------------------
@ -176,6 +190,9 @@ InputHttpStream::issue_request (const QUrl &url)
delete mp_buffer;
mp_buffer = 0;
// reset the retry counters -> this way we can detect authentication failures
s_auth_handler->reset ();
QNetworkRequest request (url);
if (tl::verbosity() >= 30) {
tl::info << "HTTP request URL: " << url.toString ().toUtf8 ().constData ();
@ -230,17 +247,42 @@ InputHttpStream::read (char *b, size_t n)
}
if (mp_reply->error () != QNetworkReply::NoError) {
// throw an error
std::string em = tl::to_string (mp_reply->attribute (QNetworkRequest::HttpReasonPhraseAttribute).toString ());
if (tl::verbosity() >= 30) {
tl::info << "HTTP response error: " << em;
}
int ec = mp_reply->attribute (QNetworkRequest::HttpStatusCodeAttribute).toInt ();
if (ec == 0) {
ec = int (mp_reply->error ());
switch (mp_reply->error ()) {
case QNetworkReply::ConnectionRefusedError:
em = tl::to_string (QObject::tr ("Connection refused"));
break;
case QNetworkReply::RemoteHostClosedError:
em = tl::to_string (QObject::tr ("Remote host closed connection"));
break;
case QNetworkReply::HostNotFoundError:
em = tl::to_string (QObject::tr ("Host not found"));
break;
case QNetworkReply::TimeoutError:
em = tl::to_string (QObject::tr ("Timeout"));
break;
case QNetworkReply::ContentAccessDenied:
em = tl::to_string (QObject::tr ("Access denied"));
break;
case QNetworkReply::ContentNotFoundError:
em = tl::to_string (QObject::tr ("Content not found"));
break;
default:
em = tl::to_string (QObject::tr ("Network API error"));
}
ec = int (mp_reply->error ());
}
throw HttpErrorException (em, ec, m_url);
}
QByteArray data = mp_reply->read (n);

View File

@ -60,6 +60,10 @@ public:
public slots:
void authenticationRequired (QNetworkReply *, QAuthenticator *);
void proxyAuthenticationRequired (const QNetworkProxy &, QAuthenticator *);
void reset ();
private:
int m_retry, m_proxy_retry;
};
/**