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"> <ui version="4.0">
<class>PasswordDialog</class> <class>PasswordDialog</class>
<widget class="QDialog" name="PasswordDialog"> <widget class="QDialog" name="PasswordDialog">
@ -6,32 +7,45 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>338</width> <width>338</width>
<height>230</height> <height>229</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>Authentication Required</string> <string>Authentication Required</string>
</property> </property>
<layout class="QGridLayout"> <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> <number>9</number>
</property> </property>
<property name="spacing"> <property name="spacing">
<number>6</number> <number>6</number>
</property> </property>
<item row="5" column="1" > <item row="8" column="1" colspan="2">
<widget class="QLabel" name="label_3" > <spacer>
<property name="text" > <property name="orientation">
<string>Password </string> <enum>Qt::Vertical</enum>
</property> </property>
</widget> <property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item> </item>
<item row="5" column="2" > <item row="7" column="2">
<widget class="QLineEdit" name="password_le"> <widget class="QLineEdit" name="password_le">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy> <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<hsizetype>5</hsizetype>
<vsizetype>0</vsizetype>
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
@ -41,38 +55,50 @@
</property> </property>
</widget> </widget>
</item> </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"> <widget class="QLineEdit" name="user_le">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy> <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<hsizetype>5</hsizetype>
<vsizetype>0</vsizetype>
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="0" > <item row="9" column="0" colspan="4">
<spacer> <widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
<property name="sizeType" > <property name="standardButtons">
<enum>QSizePolicy::Expanding</enum> <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property> </property>
<property name="sizeHint" > </widget>
<size>
<width>10</width>
<height>20</height>
</size>
</property>
</spacer>
</item> </item>
<item row="4" column="1" > <item row="0" column="0" rowspan="2" colspan="4">
<widget class="QLabel" name="label" > <widget class="QLabel" name="realm_label">
<property name="text"> <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> </property>
</widget> </widget>
</item> </item>
@ -82,22 +108,88 @@
<enum>Qt::Vertical</enum> <enum>Qt::Vertical</enum>
</property> </property>
<property name="sizeType"> <property name="sizeType">
<enum>QSizePolicy::Expanding</enum> <enum>QSizePolicy::Fixed</enum>
</property> </property>
<property name="sizeHint" > <property name="sizeHint" stdset="0">
<size> <size>
<width>20</width> <width>20</width>
<height>0</height> <height>16</height>
</size> </size>
</property> </property>
</spacer> </spacer>
</item> </item>
<item row="4" column="3" > <item row="6" column="0">
<spacer> <spacer>
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </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> <size>
<width>40</width> <width>40</width>
<height>20</height> <height>20</height>
@ -105,16 +197,6 @@
</property> </property>
</spacer> </spacer>
</item> </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"> <item row="2" column="0" colspan="4">
<widget class="QLabel" name="where_label"> <widget class="QLabel" name="where_label">
<property name="text"> <property name="text">
@ -128,28 +210,18 @@
</property> </property>
</widget> </widget>
</item> </item>
<item rowspan="2" row="0" column="0" colspan="4" > <item row="5" column="1" colspan="2">
<widget class="QLabel" name="realm_label" > <spacer name="verticalSpacer">
<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>
<property name="orientation"> <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Vertical</enum>
</property> </property>
<property name="sizeHint" > <property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size> <size>
<width>20</width> <width>20</width>
<height>0</height> <height>10</height>
</size> </size>
</property> </property>
</spacer> </spacer>

View File

@ -54,13 +54,20 @@ public:
setupUi (this); 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) { if (proxy) {
where_label->setText (QString::fromUtf8 ("<b>Proxy:</b> ") + where); where_label->setText (tr ("<b>Proxy:</b> ") + where);
} else { } 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 ()) { if (QDialog::exec ()) {
@ -78,23 +85,30 @@ public:
// AuthenticationHandler implementation // AuthenticationHandler implementation
AuthenticationHandler::AuthenticationHandler () AuthenticationHandler::AuthenticationHandler ()
: QObject (0) : QObject (0), m_retry (0), m_proxy_retry (0)
{ {
// .. nothing yet .. // .. nothing yet ..
} }
void
AuthenticationHandler::reset ()
{
m_retry = 0;
m_proxy_retry = 0;
}
void void
AuthenticationHandler::authenticationRequired (QNetworkReply *reply, QAuthenticator *auth) AuthenticationHandler::authenticationRequired (QNetworkReply *reply, QAuthenticator *auth)
{ {
PasswordDialog pw_dialog (0 /*no parent*/); 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 void
AuthenticationHandler::proxyAuthenticationRequired (const QNetworkProxy &proxy, QAuthenticator *auth) AuthenticationHandler::proxyAuthenticationRequired (const QNetworkProxy &proxy, QAuthenticator *auth)
{ {
PasswordDialog pw_dialog (0 /*no parent*/); 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; delete mp_buffer;
mp_buffer = 0; mp_buffer = 0;
// reset the retry counters -> this way we can detect authentication failures
s_auth_handler->reset ();
QNetworkRequest request (url); QNetworkRequest request (url);
if (tl::verbosity() >= 30) { if (tl::verbosity() >= 30) {
tl::info << "HTTP request URL: " << url.toString ().toUtf8 ().constData (); 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) { if (mp_reply->error () != QNetworkReply::NoError) {
// throw an error // throw an error
std::string em = tl::to_string (mp_reply->attribute (QNetworkRequest::HttpReasonPhraseAttribute).toString ()); std::string em = tl::to_string (mp_reply->attribute (QNetworkRequest::HttpReasonPhraseAttribute).toString ());
if (tl::verbosity() >= 30) { if (tl::verbosity() >= 30) {
tl::info << "HTTP response error: " << em; tl::info << "HTTP response error: " << em;
} }
int ec = mp_reply->attribute (QNetworkRequest::HttpStatusCodeAttribute).toInt (); int ec = mp_reply->attribute (QNetworkRequest::HttpStatusCodeAttribute).toInt ();
if (ec == 0) { 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")); em = tl::to_string (QObject::tr ("Network API error"));
} }
ec = int (mp_reply->error ());
}
throw HttpErrorException (em, ec, m_url); throw HttpErrorException (em, ec, m_url);
} }
QByteArray data = mp_reply->read (n); QByteArray data = mp_reply->read (n);

View File

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