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,67 +1,132 @@
<ui version="4.0" >
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PasswordDialog</class>
<widget class="QDialog" name="PasswordDialog" >
<property name="geometry" >
<widget class="QDialog" name="PasswordDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>338</width>
<height>230</height>
<height>229</height>
</rect>
</property>
<property name="windowTitle" >
<property name="windowTitle">
<string>Authentication Required</string>
</property>
<layout class="QGridLayout" >
<property name="margin" >
<layout class="QGridLayout">
<property name="leftMargin">
<number>9</number>
</property>
<property name="spacing" >
<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" >
<widget class="QLineEdit" name="password_le" >
<property name="sizePolicy" >
<sizepolicy>
<hsizetype>5</hsizetype>
<vsizetype>0</vsizetype>
<item row="7" column="2">
<widget class="QLineEdit" name="password_le">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="echoMode" >
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
<item row="4" column="2" >
<widget class="QLineEdit" name="user_le" >
<property name="sizePolicy" >
<sizepolicy>
<hsizetype>5</hsizetype>
<vsizetype>0</vsizetype>
<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="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="4" column="0" >
<spacer>
<property name="orientation" >
<item row="9" column="0" colspan="4">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType" >
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
<item row="0" column="0" rowspan="2" 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="3" column="1" colspan="2">
<spacer>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>16</height>
</size>
</property>
</spacer>
</item>
<item row="6" column="0">
<spacer>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" >
<property name="sizeHint" stdset="0">
<size>
<width>10</width>
<height>20</height>
@ -69,35 +134,62 @@
</property>
</spacer>
</item>
<item row="4" column="1" >
<widget class="QLabel" name="label" >
<property name="text" >
<string>User</string>
<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="3" column="1" colspan="2" >
<item row="6" column="3">
<spacer>
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType" >
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" >
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item row="4" column="3" >
<spacer>
<property name="orientation" >
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
@ -105,51 +197,31 @@
</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" >
<item row="2" column="0" colspan="4">
<widget class="QLabel" name="where_label">
<property name="text">
<string>-</string>
</property>
<property name="alignment" >
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="wordWrap" >
<property name="wordWrap">
<bool>false</bool>
</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>
<property name="orientation" >
<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>
@ -169,11 +241,11 @@
<receiver>PasswordDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel" >
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel" >
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
@ -185,11 +257,11 @@
<receiver>PasswordDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel" >
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel" >
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>

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) {
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 ());
em = tl::to_string (QObject::tr ("Network API 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;
};
/**