fix interactive network authentication

This commit is contained in:
Juergen E. Fischer 2014-06-22 17:54:40 +02:00
parent 91b14352dd
commit 0d360d450a
7 changed files with 106 additions and 27 deletions

View File

@ -21,12 +21,19 @@ class QgsCredentials
* @note added in 2.4 * @note added in 2.4
*/ */
void lock(); void lock();
/** /**
* Unlock the instance after being locked. * Unlock the instance after being locked.
* @note added in 2.4 * @note added in 2.4
*/ */
void unlock(); void unlock();
/**
* Return pointer to mutex
* @note added in 2.4
*/
QMutex *mutex();
protected: protected:
QgsCredentials(); QgsCredentials();

View File

@ -9761,7 +9761,8 @@ void QgisApp::namSetup()
connect( nam, SIGNAL( proxyAuthenticationRequired( const QNetworkProxy &, QAuthenticator * ) ), connect( nam, SIGNAL( proxyAuthenticationRequired( const QNetworkProxy &, QAuthenticator * ) ),
this, SLOT( namProxyAuthenticationRequired( 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 #ifndef QT_NO_OPENSSL
connect( nam, SIGNAL( sslErrors( QNetworkReply *, const QList<QSslError> & ) ), connect( nam, SIGNAL( sslErrors( QNetworkReply *, const QList<QSslError> & ) ),
@ -9774,15 +9775,41 @@ void QgisApp::namAuthenticationRequired( QNetworkReply *reply, QAuthenticator *a
QString username = auth->user(); QString username = auth->user();
QString password = auth->password(); QString password = auth->password();
bool ok = QgsCredentials::instance()->get( QMutexLocker lock( QgsCredentials::instance()->mutex() );
QString( "%1 at %2" ).arg( auth->realm() ).arg( reply->url().host() ),
username, password,
tr( "Authentication required" ) );
if ( !ok )
return;
if ( reply->isFinished() ) do
return; {
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->setUser( username );
auth->setPassword( password ); auth->setPassword( password );
@ -9801,12 +9828,37 @@ void QgisApp::namProxyAuthenticationRequired( const QNetworkProxy &proxy, QAuthe
QString username = auth->user(); QString username = auth->user();
QString password = auth->password(); QString password = auth->password();
bool ok = QgsCredentials::instance()->get( QMutexLocker lock( QgsCredentials::instance()->mutex() );
QString( "proxy %1:%2 [%3]" ).arg( proxy.hostName() ).arg( proxy.port() ).arg( auth->realm() ),
username, password, do
tr( "Proxy authentication required" ) ); {
if ( !ok ) bool ok = QgsCredentials::instance()->get(
return; 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->setUser( username );
auth->setPassword( password ); auth->setPassword( password );
@ -9850,8 +9902,11 @@ void QgisApp::namSslErrors( QNetworkReply *reply, const QList<QSslError> &errors
void QgisApp::namRequestTimedOut( QNetworkReply *reply ) 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 ); QLabel *msgLabel = new QLabel( tr( "A network request timed out, any data received is likely incomplete." ) +
messageBar()->pushMessage( tr( "Network request timeout" ), tr( "A network request timed out, any data received is likely incomplete." ), QgsMessageBar::WARNING, messageTimeout() ); 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() void QgisApp::namUpdate()

View File

@ -738,7 +738,14 @@ void QgsIdentifyResultsDialog::addFeature( QgsRasterLayer *layer,
{ {
QgsIdentifyResultsWebViewItem *attrItem = new QgsIdentifyResultsWebViewItem( lstResults ); QgsIdentifyResultsWebViewItem *attrItem = new QgsIdentifyResultsWebViewItem( lstResults );
featItem->addChild( attrItem ); // before setHtml()! 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 else
{ {

View File

@ -54,9 +54,12 @@ bool QgsCredentials::get( QString realm, QString &username, QString &password, Q
username = credentials.first; username = credentials.first;
password = credentials.second; password = credentials.second;
QgsDebugMsg( QString( "retrieved realm:%1 username:%2 password:%3" ).arg( realm ).arg( username ).arg( password ) ); 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 ) ); QgsDebugMsg( QString( "requested realm:%1 username:%2 password:%3" ).arg( realm ).arg( username ).arg( password ) );
return true; return true;
@ -74,7 +77,6 @@ void QgsCredentials::put( QString realm, QString username, QString password )
mCredentialCache.insert( realm, QPair<QString, QString>( username, password ) ); mCredentialCache.insert( realm, QPair<QString, QString>( username, password ) );
} }
void QgsCredentials::lock() void QgsCredentials::lock()
{ {
mMutex.lock(); mMutex.lock();

View File

@ -53,12 +53,19 @@ class CORE_EXPORT QgsCredentials
* @note added in 2.4 * @note added in 2.4
*/ */
void lock(); void lock();
/** /**
* Unlock the instance after being locked. * Unlock the instance after being locked.
* @note added in 2.4 * @note added in 2.4
*/ */
void unlock(); void unlock();
/**
* Return pointer to mutex
* @note added in 2.4
*/
QMutex *mutex() { return &mMutex; }
protected: protected:
QgsCredentials(); QgsCredentials();

View File

@ -246,22 +246,23 @@ void QgsNetworkAccessManager::setupDefaultProxyAndCache()
if ( this != instance() ) if ( this != instance() )
{ {
Qt::ConnectionType connectionType = thread() == instance()->thread() ? Qt::AutoConnection : Qt::BlockingQueuedConnection;
connect( this, SIGNAL( authenticationRequired( QNetworkReply *, QAuthenticator * ) ), connect( this, SIGNAL( authenticationRequired( QNetworkReply *, QAuthenticator * ) ),
instance(), SIGNAL( authenticationRequired( QNetworkReply *, QAuthenticator * ) ), instance(), SIGNAL( authenticationRequired( QNetworkReply *, QAuthenticator * ) ),
Qt::BlockingQueuedConnection ); connectionType );
connect( this, SIGNAL( proxyAuthenticationRequired( const QNetworkProxy &, QAuthenticator * ) ), connect( this, SIGNAL( proxyAuthenticationRequired( const QNetworkProxy &, QAuthenticator * ) ),
instance(), SIGNAL( proxyAuthenticationRequired( const QNetworkProxy &, QAuthenticator * ) ), instance(), SIGNAL( proxyAuthenticationRequired( const QNetworkProxy &, QAuthenticator * ) ),
Qt::BlockingQueuedConnection ); connectionType );
connect( this, SIGNAL( requestTimedOut( QNetworkReply* ) ), connect( this, SIGNAL( requestTimedOut( QNetworkReply* ) ),
instance(), SIGNAL( requestTimedOut( QNetworkReply* ) ), instance(), SIGNAL( requestTimedOut( QNetworkReply* ) ) );
Qt::BlockingQueuedConnection );
#ifndef QT_NO_OPENSSL #ifndef QT_NO_OPENSSL
connect( this, SIGNAL( sslErrors( QNetworkReply *, const QList<QSslError> & ) ), connect( this, SIGNAL( sslErrors( QNetworkReply *, const QList<QSslError> & ) ),
instance(), SIGNAL( sslErrors( QNetworkReply *, const QList<QSslError> & ) ), instance(), SIGNAL( sslErrors( QNetworkReply *, const QList<QSslError> & ) ),
Qt::BlockingQueuedConnection ); connectionType );
#endif #endif
} }

View File

@ -439,7 +439,7 @@ void QgsWmsProvider::setFormatQueryItem( QUrl &url )
setQueryItem( url, "FORMAT", mSettings.mImageMimeType ); 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." ); QgsDebugMsg( "Entering." );