Skip to content

Commit

Permalink
fix interactive network authentication
Browse files Browse the repository at this point in the history
  • Loading branch information
jef-n committed Jun 22, 2014
1 parent 91b1435 commit 0d360d4
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 27 deletions.
7 changes: 7 additions & 0 deletions python/core/qgscredentials.sip
Expand Up @@ -21,12 +21,19 @@ class QgsCredentials
* @note added in 2.4
*/
void lock();

/**
* Unlock the instance after being locked.
* @note added in 2.4
*/
void unlock();

/**
* Return pointer to mutex
* @note added in 2.4
*/
QMutex *mutex();

protected:
QgsCredentials();

Expand Down
89 changes: 72 additions & 17 deletions src/app/qgisapp.cpp
Expand Up @@ -9761,7 +9761,8 @@ void QgisApp::namSetup()
connect( nam, SIGNAL( proxyAuthenticationRequired( const QNetworkProxy &, QAuthenticator * ) ),
this, SLOT( namProxyAuthenticationRequired( const QNetworkProxy &, QAuthenticator * ) ) );

connect( nam, SIGNAL( requestTimedOut( QNetworkReply* ) ), this, SLOT( namRequestTimedOut( QNetworkReply* ) ) );
connect( nam, SIGNAL( requestTimedOut( QNetworkReply* ) ),
this, SLOT( namRequestTimedOut( QNetworkReply* ) ) );

#ifndef QT_NO_OPENSSL
connect( nam, SIGNAL( sslErrors( QNetworkReply *, const QList<QSslError> & ) ),
Expand All @@ -9774,15 +9775,41 @@ void QgisApp::namAuthenticationRequired( QNetworkReply *reply, QAuthenticator *a
QString username = auth->user();
QString password = auth->password();

bool ok = QgsCredentials::instance()->get(
QString( "%1 at %2" ).arg( auth->realm() ).arg( reply->url().host() ),
username, password,
tr( "Authentication required" ) );
if ( !ok )
return;
QMutexLocker lock( QgsCredentials::instance()->mutex() );

if ( reply->isFinished() )
return;
do
{
bool ok = QgsCredentials::instance()->get(
QString( "%1 at %2" ).arg( auth->realm() ).arg( reply->url().host() ),
username, password,
tr( "Authentication required" ) );
if ( !ok )
return;

if ( reply->isFinished() )
return;

if ( auth->user() == username && password == auth->password() )
{
if ( !password.isNull() )
{
// credentials didn't change - stored ones probably wrong? clear password and retry
QgsCredentials::instance()->put(
QString( "%1 at %2" ).arg( auth->realm() ).arg( reply->url().host() ),
username, QString::null );
continue;
}
}
else
{
// save credentials
QgsCredentials::instance()->put(
QString( "%1 at %2" ).arg( auth->realm() ).arg( reply->url().host() ),
username, password
);
}
}
while ( 0 );

auth->setUser( username );
auth->setPassword( password );
Expand All @@ -9801,12 +9828,37 @@ void QgisApp::namProxyAuthenticationRequired( const QNetworkProxy &proxy, QAuthe
QString username = auth->user();
QString password = auth->password();

bool ok = QgsCredentials::instance()->get(
QString( "proxy %1:%2 [%3]" ).arg( proxy.hostName() ).arg( proxy.port() ).arg( auth->realm() ),
username, password,
tr( "Proxy authentication required" ) );
if ( !ok )
return;
QMutexLocker lock( QgsCredentials::instance()->mutex() );

do
{
bool ok = QgsCredentials::instance()->get(
QString( "proxy %1:%2 [%3]" ).arg( proxy.hostName() ).arg( proxy.port() ).arg( auth->realm() ),
username, password,
tr( "Proxy authentication required" ) );
if ( !ok )
return;

if ( auth->user() == username && password == auth->password() )
{
if ( !password.isNull() )
{
// credentials didn't change - stored ones probably wrong? clear password and retry
QgsCredentials::instance()->put(
QString( "proxy %1:%2 [%3]" ).arg( proxy.hostName() ).arg( proxy.port() ).arg( auth->realm() ),
username, QString::null );
continue;
}
}
else
{
QgsCredentials::instance()->put(
QString( "proxy %1:%2 [%3]" ).arg( proxy.hostName() ).arg( proxy.port() ).arg( auth->realm() ),
username, password
);
}
}
while ( 0 );

auth->setUser( username );
auth->setPassword( password );
Expand Down Expand Up @@ -9850,8 +9902,11 @@ void QgisApp::namSslErrors( QNetworkReply *reply, const QList<QSslError> &errors

void QgisApp::namRequestTimedOut( QNetworkReply *reply )
{
QgsMessageLog::logMessage( tr( "The request '%1' timed out. Any data received is likely incomplete." ).arg( reply->url().toString() ), QString::null, QgsMessageLog::WARNING );
messageBar()->pushMessage( tr( "Network request timeout" ), tr( "A network request timed out, any data received is likely incomplete." ), QgsMessageBar::WARNING, messageTimeout() );
QLabel *msgLabel = new QLabel( tr( "A network request timed out, any data received is likely incomplete." ) +
tr( " Please check the <a href=\"#messageLog\">message log</a> for further info." ), messageBar() );
msgLabel->setWordWrap( true );
connect( msgLabel, SIGNAL( linkActivated( QString ) ), mLogDock, SLOT( show() ) );
messageBar()->pushItem( new QgsMessageBarItem( msgLabel, QgsMessageBar::WARNING, messageTimeout() ) );
}

void QgisApp::namUpdate()
Expand Down
9 changes: 8 additions & 1 deletion src/app/qgsidentifyresultsdialog.cpp
Expand Up @@ -738,7 +738,14 @@ void QgsIdentifyResultsDialog::addFeature( QgsRasterLayer *layer,
{
QgsIdentifyResultsWebViewItem *attrItem = new QgsIdentifyResultsWebViewItem( lstResults );
featItem->addChild( attrItem ); // before setHtml()!
attrItem->setContent( attributes.begin().value().toUtf8(), currentFormat == QgsRaster::IdentifyFormatHtml ? "text/html" : "text/plain" );
if ( !attributes.isEmpty() )
{
attrItem->setContent( attributes.begin().value().toUtf8(), currentFormat == QgsRaster::IdentifyFormatHtml ? "text/html" : "text/plain" );
}
else
{
attrItem->setContent( tr( "No attributes." ).toUtf8(), "text/plain" );
}
}
else
{
Expand Down
8 changes: 5 additions & 3 deletions src/core/qgscredentials.cpp
Expand Up @@ -54,9 +54,12 @@ bool QgsCredentials::get( QString realm, QString &username, QString &password, Q
username = credentials.first;
password = credentials.second;
QgsDebugMsg( QString( "retrieved realm:%1 username:%2 password:%3" ).arg( realm ).arg( username ).arg( password ) );
return true;

if ( !password.isNull() )
return true;
}
else if ( request( realm, username, password, message ) )

if ( request( realm, username, password, message ) )
{
QgsDebugMsg( QString( "requested realm:%1 username:%2 password:%3" ).arg( realm ).arg( username ).arg( password ) );
return true;
Expand All @@ -74,7 +77,6 @@ void QgsCredentials::put( QString realm, QString username, QString password )
mCredentialCache.insert( realm, QPair<QString, QString>( username, password ) );
}


void QgsCredentials::lock()
{
mMutex.lock();
Expand Down
7 changes: 7 additions & 0 deletions src/core/qgscredentials.h
Expand Up @@ -53,12 +53,19 @@ class CORE_EXPORT QgsCredentials
* @note added in 2.4
*/
void lock();

/**
* Unlock the instance after being locked.
* @note added in 2.4
*/
void unlock();

/**
* Return pointer to mutex
* @note added in 2.4
*/
QMutex *mutex() { return &mMutex; }

protected:
QgsCredentials();

Expand Down
11 changes: 6 additions & 5 deletions src/core/qgsnetworkaccessmanager.cpp
Expand Up @@ -246,22 +246,23 @@ void QgsNetworkAccessManager::setupDefaultProxyAndCache()

if ( this != instance() )
{
Qt::ConnectionType connectionType = thread() == instance()->thread() ? Qt::AutoConnection : Qt::BlockingQueuedConnection;

connect( this, SIGNAL( authenticationRequired( QNetworkReply *, QAuthenticator * ) ),
instance(), SIGNAL( authenticationRequired( QNetworkReply *, QAuthenticator * ) ),
Qt::BlockingQueuedConnection );
connectionType );

connect( this, SIGNAL( proxyAuthenticationRequired( const QNetworkProxy &, QAuthenticator * ) ),
instance(), SIGNAL( proxyAuthenticationRequired( const QNetworkProxy &, QAuthenticator * ) ),
Qt::BlockingQueuedConnection );
connectionType );

connect( this, SIGNAL( requestTimedOut( QNetworkReply* ) ),
instance(), SIGNAL( requestTimedOut( QNetworkReply* ) ),
Qt::BlockingQueuedConnection );
instance(), SIGNAL( requestTimedOut( QNetworkReply* ) ) );

#ifndef QT_NO_OPENSSL
connect( this, SIGNAL( sslErrors( QNetworkReply *, const QList<QSslError> & ) ),
instance(), SIGNAL( sslErrors( QNetworkReply *, const QList<QSslError> & ) ),
Qt::BlockingQueuedConnection );
connectionType );
#endif
}

Expand Down
2 changes: 1 addition & 1 deletion src/providers/wms/qgswmsprovider.cpp
Expand Up @@ -439,7 +439,7 @@ void QgsWmsProvider::setFormatQueryItem( QUrl &url )
setQueryItem( url, "FORMAT", mSettings.mImageMimeType );
}

QImage *QgsWmsProvider::draw( QgsRectangle const &viewExtent, int pixelWidth, int pixelHeight )
QImage *QgsWmsProvider::draw( QgsRectangle const &viewExtent, int pixelWidth, int pixelHeight )
{
QgsDebugMsg( "Entering." );

Expand Down

0 comments on commit 0d360d4

Please sign in to comment.