From 907b019bb56c9660fdc2edd97c18a6ddde68a4e5 Mon Sep 17 00:00:00 2001 From: Larry Shaffer Date: Mon, 21 Sep 2015 06:16:33 -0600 Subject: [PATCH] [auth system] Data source integration for OWS connections --- python/core/qgsgml.sip | 3 +- src/core/qgsgml.cpp | 17 +- src/core/qgsgml.h | 8 +- src/core/qgsowsconnection.cpp | 7 + src/gui/qgsnewhttpconnection.cpp | 21 +- src/gui/qgsnewhttpconnection.h | 3 + src/providers/ows/CMakeLists.txt | 2 + src/providers/wcs/CMakeLists.txt | 9 +- src/providers/wcs/qgswcscapabilities.cpp | 25 ++- src/providers/wcs/qgswcscapabilities.h | 2 +- src/providers/wcs/qgswcsprovider.cpp | 23 ++- src/providers/wcs/qgswcsprovider.h | 20 +- src/providers/wfs/CMakeLists.txt | 3 + src/providers/wfs/qgswfscapabilities.cpp | 35 +++- src/providers/wfs/qgswfscapabilities.h | 2 +- src/providers/wfs/qgswfsprovider.cpp | 35 +++- src/providers/wfs/qgswfsprovider.h | 19 +- src/providers/wms/CMakeLists.txt | 10 +- src/providers/wms/qgswmscapabilities.cpp | 22 +- src/providers/wms/qgswmscapabilities.h | 17 +- src/providers/wms/qgswmsconnection.cpp | 6 + src/ui/qgsnewhttpconnectionbase.ui | 249 +++++++++++++---------- 22 files changed, 391 insertions(+), 147 deletions(-) diff --git a/python/core/qgsgml.sip b/python/core/qgsgml.sip index 994bf52dfbe..7e3f9856652 100644 --- a/python/core/qgsgml.sip +++ b/python/core/qgsgml.sip @@ -19,9 +19,10 @@ class QgsGml: QObject * @param extent retrieved extents * @param userName username for authentication * @param password password for authentication + * @param authcfg authentication configuration id * @return 0 in case of success */ - int getFeatures( const QString& uri, QGis::WkbType* wkbType, QgsRectangle* extent = 0, const QString& userName = QString(), const QString& password = QString() ) /PyName=getFeaturesUri/; + int getFeatures( const QString& uri, QGis::WkbType* wkbType, QgsRectangle* extent = 0, const QString& userName = QString(), const QString& password = QString(), const QString& authcfg = QString() ) /PyName=getFeaturesUri/; /** Read from GML data. Constructor uri param is ignored * Supports only UTF-8, UTF-16, ISO-8859-1, ISO-8859-1 XML encodings. diff --git a/src/core/qgsgml.cpp b/src/core/qgsgml.cpp index c0d11c9fca3..a3c362b8182 100644 --- a/src/core/qgsgml.cpp +++ b/src/core/qgsgml.cpp @@ -13,6 +13,7 @@ * * ***************************************************************************/ #include "qgsgml.h" +#include "qgsauthmanager.h" #include "qgsrectangle.h" #include "qgscoordinatereferencesystem.h" #include "qgsgeometry.h" @@ -69,7 +70,7 @@ QgsGml::~QgsGml() { } -int QgsGml::getFeatures( const QString& uri, QGis::WkbType* wkbType, QgsRectangle* extent, const QString& userName, const QString& password ) +int QgsGml::getFeatures( const QString& uri, QGis::WkbType* wkbType, QgsRectangle* extent, const QString& userName, const QString& password , const QString& authcfg ) { mUri = uri; mWkbType = wkbType; @@ -83,7 +84,19 @@ int QgsGml::getFeatures( const QString& uri, QGis::WkbType* wkbType, QgsRectangl mExtent.setMinimal(); QNetworkRequest request( mUri ); - if ( !userName.isNull() || !password.isNull() ) + if ( !authcfg.isEmpty() ) + { + if ( !QgsAuthManager::instance()->updateNetworkRequest( request, authcfg ) ) + { + QgsMessageLog::logMessage( + tr( "GML Getfeature network request update failed for authcfg %1" ).arg( authcfg ), + tr( "Network" ), + QgsMessageLog::CRITICAL + ); + return 1; + } + } + else if ( !userName.isNull() || !password.isNull() ) { request.setRawHeader( "Authorization", "Basic " + QString( "%1:%2" ).arg( userName ).arg( password ).toAscii().toBase64() ); } diff --git a/src/core/qgsgml.h b/src/core/qgsgml.h index 49c1c56cf70..ab463cb6e38 100644 --- a/src/core/qgsgml.h +++ b/src/core/qgsgml.h @@ -56,9 +56,15 @@ class CORE_EXPORT QgsGml : public QObject * @param extent retrieved extents * @param userName username for authentication * @param password password for authentication + * @param authcfg authentication configuration id * @return 0 in case of success */ - int getFeatures( const QString& uri, QGis::WkbType* wkbType, QgsRectangle* extent = 0, const QString& userName = QString(), const QString& password = QString() ); + int getFeatures( const QString& uri, + QGis::WkbType* wkbType, + QgsRectangle* extent = 0, + const QString& userName = QString(), + const QString& password = QString(), + const QString& authcfg = QString() ); /** Read from GML data. Constructor uri param is ignored * Supports only UTF-8, UTF-16, ISO-8859-1, ISO-8859-1 XML encodings. diff --git a/src/core/qgsowsconnection.cpp b/src/core/qgsowsconnection.cpp index d6550b0a243..c1da4ca79b6 100644 --- a/src/core/qgsowsconnection.cpp +++ b/src/core/qgsowsconnection.cpp @@ -61,6 +61,13 @@ QgsOWSConnection::QgsOWSConnection( const QString & theService, const QString & mUri.setParam( "password", password ); } + QString authcfg = settings.value( credentialsKey + "/authcfg" ).toString(); + if ( !authcfg.isEmpty() ) + { + mUri.setParam( "authcfg", authcfg ); + } + mConnectionInfo.append( ",authcfg=" + authcfg ); + bool ignoreGetMap = settings.value( key + "/ignoreGetMapURI", false ).toBool(); bool ignoreGetFeatureInfo = settings.value( key + "/ignoreGetFeatureInfoURI", false ).toBool(); bool ignoreAxisOrientation = settings.value( key + "/ignoreAxisOrientation", false ).toBool(); diff --git a/src/gui/qgsnewhttpconnection.cpp b/src/gui/qgsnewhttpconnection.cpp index 9d12e2e0598..24df1494247 100644 --- a/src/gui/qgsnewhttpconnection.cpp +++ b/src/gui/qgsnewhttpconnection.cpp @@ -23,10 +23,11 @@ #include QgsNewHttpConnection::QgsNewHttpConnection( - QWidget *parent, const QString& baseKey, const QString& connName, Qt::WindowFlags fl ): - QDialog( parent, fl ), - mBaseKey( baseKey ), - mOriginalConnName( connName ) + QWidget *parent, const QString& baseKey, const QString& connName, Qt::WindowFlags fl ) + : QDialog( parent, fl ) + , mBaseKey( baseKey ) + , mOriginalConnName( connName ) + , mAuthConfigSelect( 0 ) { setupUi( this ); @@ -49,6 +50,9 @@ QgsNewHttpConnection::QgsNewHttpConnection( cmbDpiMode->addItem( tr( "UMN" ) ); cmbDpiMode->addItem( tr( "GeoServer" ) ); + mAuthConfigSelect = new QgsAuthConfigSelect( this ); + tabAuth->insertTab( 1, mAuthConfigSelect, tr( "Configurations" ) ); + if ( !connName.isEmpty() ) { // populate the dialog with the information stored for the connection @@ -92,6 +96,13 @@ QgsNewHttpConnection::QgsNewHttpConnection( txtUserName->setText( settings.value( credentialsKey + "/username" ).toString() ); txtPassword->setText( settings.value( credentialsKey + "/password" ).toString() ); + + QString authcfg = settings.value( credentialsKey + "/authcfg" ).toString(); + mAuthConfigSelect->setConfigId( authcfg ); + if ( !authcfg.isEmpty() ) + { + tabAuth->setCurrentIndex( tabAuth->indexOf( mAuthConfigSelect ) ); + } } if ( mBaseKey != "/Qgis/connections-wms/" ) @@ -247,6 +258,8 @@ void QgsNewHttpConnection::accept() settings.setValue( credentialsKey + "/username", txtUserName->text() ); settings.setValue( credentialsKey + "/password", txtPassword->text() ); + settings.setValue( credentialsKey + "/authcfg", mAuthConfigSelect->configId() ); + settings.setValue( mBaseKey + "/selected", txtName->text() ); QDialog::accept(); diff --git a/src/gui/qgsnewhttpconnection.h b/src/gui/qgsnewhttpconnection.h index 15742677d0e..5075c99264f 100644 --- a/src/gui/qgsnewhttpconnection.h +++ b/src/gui/qgsnewhttpconnection.h @@ -19,6 +19,8 @@ #include "ui_qgsnewhttpconnectionbase.h" #include "qgisgui.h" #include "qgscontexthelp.h" +#include "qgsauthconfigselect.h" + /*! * \brief Dialog to allow the user to configure and save connection * information for an HTTP Server for WMS, etc. @@ -46,6 +48,7 @@ class GUI_EXPORT QgsNewHttpConnection : public QDialog, private Ui::QgsNewHttpCo QString mBaseKey; QString mCredentialsBaseKey; QString mOriginalConnName; //store initial name to delete entry in case of rename + QgsAuthConfigSelect * mAuthConfigSelect; }; #endif // QGSNEWHTTPCONNECTION_H diff --git a/src/providers/ows/CMakeLists.txt b/src/providers/ows/CMakeLists.txt index 763bd4b0577..c174eb29d97 100644 --- a/src/providers/ows/CMakeLists.txt +++ b/src/providers/ows/CMakeLists.txt @@ -9,7 +9,9 @@ SET(OWS_MOC_HDRS INCLUDE_DIRECTORIES ( ../../core + ../../core/auth ../../gui + ../../gui/auth ${CMAKE_CURRENT_BINARY_DIR}/../../ui ) diff --git a/src/providers/wcs/CMakeLists.txt b/src/providers/wcs/CMakeLists.txt index 9a742ae986b..93a66c80c94 100644 --- a/src/providers/wcs/CMakeLists.txt +++ b/src/providers/wcs/CMakeLists.txt @@ -16,10 +16,17 @@ SET (WCS_MOC_HDRS QT4_WRAP_CPP (WCS_MOC_SRCS ${WCS_MOC_HDRS}) -INCLUDE_DIRECTORIES( . ../../core ../../core/raster ../../gui +INCLUDE_DIRECTORIES( + . + ../../core + ../../core/auth + ../../core/raster + ../../gui + ../../gui/auth ../gdal ${CMAKE_CURRENT_BINARY_DIR}/../../ui ${GDAL_INCLUDE_DIR} + ${QCA_INCLUDE_DIR} ) ADD_LIBRARY(wcsprovider MODULE ${WCS_SRCS} ${WCS_MOC_SRCS}) diff --git a/src/providers/wcs/qgswcscapabilities.cpp b/src/providers/wcs/qgswcscapabilities.cpp index 68f04d62ff8..296c3888c2c 100644 --- a/src/providers/wcs/qgswcscapabilities.cpp +++ b/src/providers/wcs/qgswcscapabilities.cpp @@ -26,6 +26,7 @@ #include +#include "qgsauthmanager.h" #include "qgscoordinatetransform.h" #include "qgsdatasourceuri.h" #include "qgsrasterlayer.h" @@ -159,7 +160,12 @@ bool QgsWcsCapabilities::sendRequest( QString const & url ) QgsDebugMsg( "url = " + url ); mError = ""; QNetworkRequest request( url ); - setAuthorization( request ); + if ( !setAuthorization( request ) ) + { + mError = tr( "Download of capabilities failed: network request update failed for authentication config" ); + QgsMessageLog::logMessage( mError, tr( "WCS" ) ); + return false; + } request.setAttribute( QNetworkRequest::CacheSaveControlAttribute, true ); request.setAttribute( QNetworkRequest::CacheLoadControlAttribute, mCacheLoadControl ); QgsDebugMsg( QString( "mCacheLoadControl = %1" ).arg( mCacheLoadControl ) ); @@ -359,7 +365,13 @@ void QgsWcsCapabilities::capabilitiesReplyFinished() emit statusChanged( tr( "Capabilities request redirected." ) ); QNetworkRequest request( redirect.toUrl() ); - setAuthorization( request ); + if ( !setAuthorization( request ) ) + { + mCapabilitiesResponse.clear(); + mError = tr( "Download of capabilities failed: network request update failed for authentication config" ); + QgsMessageLog::logMessage( mError, tr( "WCS" ) ); + return; + } request.setAttribute( QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferNetwork ); request.setAttribute( QNetworkRequest::CacheSaveControlAttribute, true ); @@ -1162,14 +1174,19 @@ QString QgsWcsCapabilities::lastErrorFormat() return mErrorFormat; } -void QgsWcsCapabilities::setAuthorization( QNetworkRequest &request ) const +bool QgsWcsCapabilities::setAuthorization( QNetworkRequest &request ) const { QgsDebugMsg( "entered" ); - if ( mUri.hasParam( "username" ) && mUri.hasParam( "password" ) ) + if ( mUri.hasParam( "authcfg" ) && !mUri.param( "authcfg" ).isEmpty() ) + { + return QgsAuthManager::instance()->updateNetworkRequest( request, mUri.param( "authcfg" ) ); + } + else if ( mUri.hasParam( "username" ) && mUri.hasParam( "password" ) ) { QgsDebugMsg( "setAuthorization " + mUri.param( "username" ) ); request.setRawHeader( "Authorization", "Basic " + QString( "%1:%2" ).arg( mUri.param( "username" ) ).arg( mUri.param( "password" ) ).toAscii().toBase64() ); } + return true; } void QgsWcsCapabilities::showMessageBox( const QString& title, const QString& text ) diff --git a/src/providers/wcs/qgswcscapabilities.h b/src/providers/wcs/qgswcscapabilities.h index 2421aa7589e..094dea51b87 100644 --- a/src/providers/wcs/qgswcscapabilities.h +++ b/src/providers/wcs/qgswcscapabilities.h @@ -153,7 +153,7 @@ class QgsWcsCapabilities : public QObject bool parseDescribeCoverageDom11( QByteArray const &xml, QgsWcsCoverageSummary *coverage ); //! set authorization header - void setAuthorization( QNetworkRequest &request ) const; + bool setAuthorization( QNetworkRequest &request ) const; QString version() const { return mCapabilities.version; } diff --git a/src/providers/wcs/qgswcsprovider.cpp b/src/providers/wcs/qgswcsprovider.cpp index 96154cf275d..107a6de1fd7 100644 --- a/src/providers/wcs/qgswcsprovider.cpp +++ b/src/providers/wcs/qgswcsprovider.cpp @@ -408,6 +408,12 @@ bool QgsWcsProvider::parseUri( QString uriString ) mAuth.mPassword = uri.param( "password" ); QgsDebugMsg( "set password to " + mAuth.mPassword ); + if ( uri.hasParam( "authcfg" ) ) + { + mAuth.mAuthCfg = uri.param( "authcfg" ); + } + QgsDebugMsg( "set authcfg to " + mAuth.mAuthCfg ); + mIdentifier = uri.param( "identifier" ); mTime = uri.param( "time" ); @@ -1667,6 +1673,7 @@ int QgsWcsDownloadHandler::sErrors = 0; QgsWcsDownloadHandler::QgsWcsDownloadHandler( const QUrl& url, QgsWcsAuthorization& auth, QNetworkRequest::CacheLoadControl cacheLoadControl, QByteArray& cachedData, const QString& wcsVersion, QgsError& cachedError ) : mNAM( new QgsNetworkAccessManager ) + , mAuth( auth ) , mEventLoop( new QEventLoop ) , mCachedData( cachedData ) , mWcsVersion( wcsVersion ) @@ -1675,7 +1682,12 @@ QgsWcsDownloadHandler::QgsWcsDownloadHandler( const QUrl& url, QgsWcsAuthorizati mNAM->setupDefaultProxyAndCache(); QNetworkRequest request( url ); - auth.setAuthorization( request ); + if ( !mAuth.setAuthorization( request ) ) + { + QgsMessageLog::logMessage( tr( "Network request update failed for authentication config" ), + tr( "WCS" ) ); + return; + } request.setAttribute( QNetworkRequest::CacheSaveControlAttribute, true ); request.setAttribute( QNetworkRequest::CacheLoadControlAttribute, cacheLoadControl ); @@ -1708,7 +1720,14 @@ void QgsWcsDownloadHandler::cacheReplyFinished() mCacheReply->deleteLater(); QgsDebugMsg( QString( "redirected getmap: %1" ).arg( redirect.toString() ) ); - mCacheReply = mNAM->get( QNetworkRequest( redirect.toUrl() ) ); + QNetworkRequest request( redirect.toUrl() ); + if ( !mAuth.setAuthorization( request ) ) + { + QgsMessageLog::logMessage( tr( "Network request update failed for authentication config" ), + tr( "WCS" ) ); + return; + } + mCacheReply = mNAM->get( request ); connect( mCacheReply, SIGNAL( finished() ), this, SLOT( cacheReplyFinished() ) ); connect( mCacheReply, SIGNAL( downloadProgress( qint64, qint64 ) ), this, SLOT( cacheReplyProgress( qint64, qint64 ) ) ); diff --git a/src/providers/wcs/qgswcsprovider.h b/src/providers/wcs/qgswcsprovider.h index e2f793effff..23a124cf14e 100644 --- a/src/providers/wcs/qgswcsprovider.h +++ b/src/providers/wcs/qgswcsprovider.h @@ -24,6 +24,7 @@ #include "qgserror.h" #include "qgswcscapabilities.h" +#include "qgsauthmanager.h" #include "qgsrasterdataprovider.h" #include "qgsgdalproviderbase.h" #include "qgsrectangle.h" @@ -50,15 +51,24 @@ class QNetworkRequest; // TODO: merge with QgsWmsAuthorization? struct QgsWcsAuthorization { - QgsWcsAuthorization( const QString& userName = QString(), const QString& password = QString() ) : mUserName( userName ), mPassword( password ) {} + QgsWcsAuthorization( const QString& userName = QString(), const QString& password = QString(), const QString& authcfg = QString() ) + : mUserName( userName ) + , mPassword( password ) + , mAuthCfg( authcfg ) + {} //! set authorization header - void setAuthorization( QNetworkRequest &request ) const + bool setAuthorization( QNetworkRequest &request ) const { - if ( !mUserName.isNull() || !mPassword.isNull() ) + if ( !mAuthCfg.isEmpty() ) + { + return QgsAuthManager::instance()->updateNetworkRequest( request, mAuthCfg ); + } + else if ( !mUserName.isNull() || !mPassword.isNull() ) { request.setRawHeader( "Authorization", "Basic " + QString( "%1:%2" ).arg( mUserName ).arg( mPassword ).toAscii().toBase64() ); } + return true; } //! Username for basic http authentication @@ -66,6 +76,9 @@ struct QgsWcsAuthorization //! Password for basic http authentication QString mPassword; + + //! Authentication configuration ID + QString mAuthCfg; }; /** @@ -424,6 +437,7 @@ class QgsWcsDownloadHandler : public QObject void finish() { QMetaObject::invokeMethod( mEventLoop, "quit", Qt::QueuedConnection ); } QgsNetworkAccessManager* mNAM; + QgsWcsAuthorization& mAuth; QEventLoop* mEventLoop; QNetworkReply* mCacheReply; diff --git a/src/providers/wfs/CMakeLists.txt b/src/providers/wfs/CMakeLists.txt index 9de6ad01db6..c04bd706bb8 100644 --- a/src/providers/wfs/CMakeLists.txt +++ b/src/providers/wfs/CMakeLists.txt @@ -25,13 +25,16 @@ QT4_WRAP_CPP(WFS_MOC_SRCS ${WFS_MOC_HDRS}) INCLUDE_DIRECTORIES ( ../../core + ../../core/auth ../../core/geometry ../../gui + ../../gui/auth ${CMAKE_CURRENT_BINARY_DIR}/../../ui ${GEOS_INCLUDE_DIR} ${GEOS_INCLUDE_DIR}/geos ${EXPAT_INCLUDE_DIR} ${QSCINTILLA_INCLUDE_DIR} + ${QCA_INCLUDE_DIR} ) ADD_LIBRARY (wfsprovider MODULE ${WFS_SRCS} ${WFS_MOC_SRCS}) diff --git a/src/providers/wfs/qgswfscapabilities.cpp b/src/providers/wfs/qgswfscapabilities.cpp index 17b550b82d9..c3081ff0145 100644 --- a/src/providers/wfs/qgswfscapabilities.cpp +++ b/src/providers/wfs/qgswfscapabilities.cpp @@ -13,6 +13,7 @@ * * ***************************************************************************/ #include "qgswfscapabilities.h" +#include "qgsauthmanager.h" #include "qgsexpression.h" #include "qgslogger.h" #include "qgsmessagelog.h" @@ -141,18 +142,27 @@ QString QgsWFSCapabilities::uriGetFeature( QString typeName, QString crsString, uri += "&username=" + mUri.param( "username" ); uri += "&password=" + mUri.param( "password" ); } + if ( mUri.hasParam( "authcfg" ) ) + { + uri += "&authcfg=" + mUri.param( "authcfg" ); + } QgsDebugMsg( uri ); return uri; } -void QgsWFSCapabilities::setAuthorization( QNetworkRequest &request ) const +bool QgsWFSCapabilities::setAuthorization( QNetworkRequest &request ) const { QgsDebugMsg( "entered" ); - if ( mUri.hasParam( "username" ) && mUri.hasParam( "password" ) ) + if ( mUri.hasParam( "authcfg" ) && !mUri.param( "authcfg" ).isEmpty() ) + { + return QgsAuthManager::instance()->updateNetworkRequest( request, mUri.param( "authcfg" ) ); + } + else if ( mUri.hasParam( "username" ) && mUri.hasParam( "password" ) ) { QgsDebugMsg( "setAuthorization " + mUri.param( "username" ) ); request.setRawHeader( "Authorization", "Basic " + QString( "%1:%2" ).arg( mUri.param( "username" ) ).arg( mUri.param( "password" ) ).toAscii().toBase64() ); } + return true; } void QgsWFSCapabilities::requestCapabilities() @@ -161,7 +171,15 @@ void QgsWFSCapabilities::requestCapabilities() mErrorMessage.clear(); QNetworkRequest request( uriGetCapabilities() ); - setAuthorization( request ); + if ( !setAuthorization( request ) ) + { + mErrorCode = QgsWFSCapabilities::NetworkError; + mErrorMessage = tr( "Download of capabilities failed: network request update failed for authentication config" ); + QgsMessageLog::logMessage( mErrorMessage, tr( "WFS" ) ); + emit gotCapabilities(); + return; + } + request.setAttribute( QNetworkRequest::CacheSaveControlAttribute, true ); mCapabilitiesReply = QgsNetworkAccessManager::instance()->get( request ); connect( mCapabilitiesReply, SIGNAL( finished() ), this, SLOT( capabilitiesReplyFinished() ) ); @@ -188,7 +206,16 @@ void QgsWFSCapabilities::capabilitiesReplyFinished() { QgsDebugMsg( "redirecting to " + redirect.toUrl().toString() ); QNetworkRequest request( redirect.toUrl() ); - setAuthorization( request ); + if ( !setAuthorization( request ) ) + { + mCaps.clear(); + mErrorCode = QgsWFSCapabilities::NetworkError; + mErrorMessage = tr( "Download of capabilities failed: network request update failed for authentication config" ); + QgsMessageLog::logMessage( mErrorMessage, tr( "WFS" ) ); + emit gotCapabilities(); + return; + } + request.setAttribute( QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferNetwork ); request.setAttribute( QNetworkRequest::CacheSaveControlAttribute, true ); diff --git a/src/providers/wfs/qgswfscapabilities.h b/src/providers/wfs/qgswfscapabilities.h index 1a434a0c7f9..b0a353bd468 100644 --- a/src/providers/wfs/qgswfscapabilities.h +++ b/src/providers/wfs/qgswfscapabilities.h @@ -74,7 +74,7 @@ class QgsWFSCapabilities : public QObject GetCapabilities capabilities() { return mCaps; } //! set authorization header - void setAuthorization( QNetworkRequest &request ) const; + bool setAuthorization( QNetworkRequest &request ) const; signals: void gotCapabilities(); diff --git a/src/providers/wfs/qgswfsprovider.cpp b/src/providers/wfs/qgswfsprovider.cpp index 0d2b62a78f6..f65537acc20 100644 --- a/src/providers/wfs/qgswfsprovider.cpp +++ b/src/providers/wfs/qgswfsprovider.cpp @@ -99,6 +99,7 @@ QgsWFSProvider::QgsWFSProvider( const QString& uri ) mAuth.mUserName = parameterFromUrl( "username" ); mAuth.mPassword = parameterFromUrl( "password" ); + mAuth.mAuthCfg = parameterFromUrl( "authcfg" ); //fetch attributes of layer and type of its geometry attribute //WBC 111221: extracting geometry type here instead of getFeature allows successful @@ -706,8 +707,14 @@ int QgsWFSProvider::getFeatureGET( const QString& uri, const QString& geometryAt QUrl getFeatureUrl( uri ); getFeatureUrl.removeQueryItem( "username" ); getFeatureUrl.removeQueryItem( "password" ); + getFeatureUrl.removeQueryItem( "authcfg" ); QgsRectangle extent; - if ( dataReader.getFeatures( getFeatureUrl.toString(), &mWKBType, mCached ? &mExtent : &extent, mAuth.mUserName, mAuth.mPassword ) != 0 ) + if ( dataReader.getFeatures( getFeatureUrl.toString(), + &mWKBType, + mCached ? &mExtent : &extent, + mAuth.mUserName, + mAuth.mPassword, + mAuth.mAuthCfg ) != 0 ) { QgsDebugMsg( "getWFSData returned with error" ); return 1; @@ -778,11 +785,17 @@ int QgsWFSProvider::describeFeatureTypeGET( const QString& uri, QString& geometr QUrl describeFeatureUrl( uri ); describeFeatureUrl.removeQueryItem( "username" ); describeFeatureUrl.removeQueryItem( "password" ); + describeFeatureUrl.removeQueryItem( "authcfg" ); describeFeatureUrl.removeQueryItem( "SRSNAME" ); describeFeatureUrl.removeQueryItem( "REQUEST" ); describeFeatureUrl.addQueryItem( "REQUEST", "DescribeFeatureType" ); QNetworkRequest request( describeFeatureUrl.toString() ); - mAuth.setAuthorization( request ); + if ( !mAuth.setAuthorization( request ) ) + { + QgsMessageLog::logMessage( tr( "Network request update failed for authentication config" ), + tr( "WFS" ) ); + return 1; + } QNetworkReply* reply = QgsNetworkAccessManager::instance()->get( request ); connect( reply, SIGNAL( finished() ), this, SLOT( networkRequestFinished() ) ); @@ -1366,6 +1379,7 @@ bool QgsWFSProvider::sendTransactionDocument( const QDomDocument& doc, QDomDocum QUrl typeDetectionUri( dataSourceUri() ); typeDetectionUri.removeQueryItem( "username" ); typeDetectionUri.removeQueryItem( "password" ); + typeDetectionUri.removeQueryItem( "authcfg" ); typeDetectionUri.removeQueryItem( "REQUEST" ); typeDetectionUri.removeQueryItem( "TYPENAME" ); typeDetectionUri.removeQueryItem( "BBOX" ); @@ -1377,7 +1391,13 @@ bool QgsWFSProvider::sendTransactionDocument( const QDomDocument& doc, QDomDocum QString serverUrl = typeDetectionUri.toString(); QNetworkRequest request( serverUrl ); - mAuth.setAuthorization( request ); + if ( !mAuth.setAuthorization( request ) ) + { + QgsMessageLog::logMessage( tr( "Network request update failed for authentication config" ), + tr( "WFS" ) ); + return false; + } + request.setHeader( QNetworkRequest::ContentTypeHeader, "text/xml" ); QNetworkReply* reply = QgsNetworkAccessManager::instance()->post( request, doc.toByteArray( -1 ) ); @@ -1507,8 +1527,15 @@ void QgsWFSProvider::getLayerCapabilities() QUrl getCapabilitiesUrl( uri ); getCapabilitiesUrl.removeQueryItem( "username" ); getCapabilitiesUrl.removeQueryItem( "password" ); + getCapabilitiesUrl.removeQueryItem( "authcfg" ); QNetworkRequest request( getCapabilitiesUrl.toString() ); - mAuth.setAuthorization( request ); + if ( !mAuth.setAuthorization( request ) ) + { + mCapabilities = 0; + QgsMessageLog::logMessage( tr( "Network request update failed for authentication config" ), + tr( "WFS" ) ); + return; + } QNetworkReply* reply = QgsNetworkAccessManager::instance()->get( request ); connect( reply, SIGNAL( finished() ), this, SLOT( networkRequestFinished() ) ); diff --git a/src/providers/wfs/qgswfsprovider.h b/src/providers/wfs/qgswfsprovider.h index 7401494652b..9d2fb2cf9b2 100644 --- a/src/providers/wfs/qgswfsprovider.h +++ b/src/providers/wfs/qgswfsprovider.h @@ -20,6 +20,7 @@ #include #include "qgis.h" +#include "qgsauthmanager.h" #include "qgsrectangle.h" #include "qgscoordinatereferencesystem.h" #include "qgsvectordataprovider.h" @@ -35,15 +36,24 @@ class QgsSpatialIndex; // TODO: merge with QgsWmsAuthorization? struct QgsWFSAuthorization { - QgsWFSAuthorization( const QString& userName = QString(), const QString& password = QString() ) : mUserName( userName ), mPassword( password ) {} + QgsWFSAuthorization( const QString& userName = QString(), const QString& password = QString(), const QString& authcfg = QString() ) + : mUserName( userName ) + , mPassword( password ) + , mAuthCfg( authcfg ) + {} //! set authorization header - void setAuthorization( QNetworkRequest &request ) const + bool setAuthorization( QNetworkRequest &request ) const { - if ( !mUserName.isNull() || !mPassword.isNull() ) + if ( !mAuthCfg.isEmpty() ) + { + return QgsAuthManager::instance()->updateNetworkRequest( request, mAuthCfg ); + } + else if ( !mUserName.isNull() || !mPassword.isNull() ) { request.setRawHeader( "Authorization", "Basic " + QString( "%1:%2" ).arg( mUserName ).arg( mPassword ).toAscii().toBase64() ); } + return true; } //! Username for basic http authentication @@ -51,6 +61,9 @@ struct QgsWFSAuthorization //! Password for basic http authentication QString mPassword; + + //! Authentication configuration ID + QString mAuthCfg; }; /** A provider reading features from a WFS server*/ diff --git a/src/providers/wms/CMakeLists.txt b/src/providers/wms/CMakeLists.txt index 5dda3afbd9c..5ee047d594e 100644 --- a/src/providers/wms/CMakeLists.txt +++ b/src/providers/wms/CMakeLists.txt @@ -24,11 +24,19 @@ SET (WMS_MOC_HDRS QT4_WRAP_CPP (WMS_MOC_SRCS ${WMS_MOC_HDRS}) -INCLUDE_DIRECTORIES( . ../../core ../../core/geometry ../../core/raster ../../gui +INCLUDE_DIRECTORIES( + . + ../../core + ../../core/auth + ../../core/geometry + ../../core/raster + ../../gui + ../../gui/auth ${CMAKE_CURRENT_BINARY_DIR}/../../ui ${GDAL_INCLUDE_DIR} ${GEOS_INCLUDE_DIR} ${QT_QTSCRIPT_INCLUDE_DIR} + ${QCA_INCLUDE_DIR} ) ADD_LIBRARY(wmsprovider MODULE ${WMS_SRCS} ${WMS_MOC_SRCS}) diff --git a/src/providers/wms/qgswmscapabilities.cpp b/src/providers/wms/qgswmscapabilities.cpp index 600ee910665..a1de2545a6f 100644 --- a/src/providers/wms/qgswmscapabilities.cpp +++ b/src/providers/wms/qgswmscapabilities.cpp @@ -44,6 +44,12 @@ bool QgsWmsSettings::parseUri( QString uriString ) mAuth.mPassword = uri.param( "password" ); QgsDebugMsg( "set password to " + mAuth.mPassword ); + if ( uri.hasParam( "authcfg" ) ) + { + mAuth.mAuthCfg = uri.param( "authcfg" ); + } + QgsDebugMsg( "set authcfg to " + mAuth.mAuthCfg ); + mAuth.mReferer = uri.param( "referer" ); QgsDebugMsg( "set referer to " + mAuth.mReferer ); @@ -1911,7 +1917,12 @@ bool QgsWmsCapabilitiesDownload::downloadCapabilities() mError.clear(); QNetworkRequest request( url ); - mAuth.setAuthorization( request ); + if ( !mAuth.setAuthorization( request ) ) + { + mError = tr( "Download of capabilities failed: network request update failed for authentication config" ); + QgsMessageLog::logMessage( mError, tr( "WMS" ) ); + return false; + } request.setAttribute( QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferNetwork ); request.setAttribute( QNetworkRequest::CacheSaveControlAttribute, true ); @@ -1995,7 +2006,14 @@ void QgsWmsCapabilitiesDownload::capabilitiesReplyFinished() else { QNetworkRequest request( toUrl ); - mAuth.setAuthorization( request ); + if ( !mAuth.setAuthorization( request ) ) + { + mHttpCapabilitiesResponse.clear(); + mError = tr( "Download of capabilities failed: network request update failed for authentication config" ); + QgsMessageLog::logMessage( mError, tr( "WMS" ) ); + emit downloadFinished(); + return; + } request.setAttribute( QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferNetwork ); request.setAttribute( QNetworkRequest::CacheSaveControlAttribute, true ); diff --git a/src/providers/wms/qgswmscapabilities.h b/src/providers/wms/qgswmscapabilities.h index 14d74428754..3f1fbc206d7 100644 --- a/src/providers/wms/qgswmscapabilities.h +++ b/src/providers/wms/qgswmscapabilities.h @@ -7,6 +7,7 @@ #include #include +#include "qgsauthmanager.h" #include "qgsraster.h" #include "qgsrectangle.h" @@ -434,12 +435,16 @@ struct QgsWmsParserSettings struct QgsWmsAuthorization { - QgsWmsAuthorization( const QString& userName = QString(), const QString& password = QString(), const QString& referer = QString() ) - : mUserName( userName ), mPassword( password ), mReferer( referer ) {} + QgsWmsAuthorization( const QString& userName = QString(), const QString& password = QString(), const QString& referer = QString(), const QString& authcfg = QString() ) + : mUserName( userName ), mPassword( password ), mReferer( referer ), mAuthCfg( authcfg ) {} - void setAuthorization( QNetworkRequest &request ) const + bool setAuthorization( QNetworkRequest &request ) const { - if ( !mUserName.isNull() || !mPassword.isNull() ) + if ( !mAuthCfg.isEmpty() ) + { + return QgsAuthManager::instance()->updateNetworkRequest( request, mAuthCfg ); + } + else if ( !mUserName.isNull() || !mPassword.isNull() ) { request.setRawHeader( "Authorization", "Basic " + QString( "%1:%2" ).arg( mUserName ).arg( mPassword ).toAscii().toBase64() ); } @@ -448,6 +453,7 @@ struct QgsWmsAuthorization { request.setRawHeader( "Referer", QString( "%1" ).arg( mReferer ).toAscii() ); } + return true; } //! Username for basic http authentication @@ -459,7 +465,8 @@ struct QgsWmsAuthorization //! Referer for http requests QString mReferer; - + //! Authentication configuration ID + QString mAuthCfg; }; diff --git a/src/providers/wms/qgswmsconnection.cpp b/src/providers/wms/qgswmsconnection.cpp index 723ca7abb5e..bb346ac5057 100644 --- a/src/providers/wms/qgswmsconnection.cpp +++ b/src/providers/wms/qgswmsconnection.cpp @@ -59,6 +59,12 @@ QgsWMSConnection::QgsWMSConnection( QString theConnName ) : mUri.setParam( "password", password ); } + QString authcfg = settings.value( credentialsKey + "/authcfg" ).toString(); + if ( !authcfg.isEmpty() ) + { + mUri.setParam( "authcfg", authcfg ); + } + QString referer = settings.value( key + "/referer" ).toString(); if ( !referer.isEmpty() ) { diff --git a/src/ui/qgsnewhttpconnectionbase.ui b/src/ui/qgsnewhttpconnectionbase.ui index 6c4e69341e0..8acaf6bc083 100644 --- a/src/ui/qgsnewhttpconnectionbase.ui +++ b/src/ui/qgsnewhttpconnectionbase.ui @@ -6,8 +6,8 @@ 0 0 - 475 - 463 + 526 + 721 @@ -27,13 +27,111 @@ - + Connection details - + + + + + 0 + 0 + + + + 0 + + + + Authentication + + + + + + &User name + + + txtUserName + + + + + + + + + + + 0 + 0 + + + + If the service requires basic authentication, enter a user name and optional password + + + Qt::PlainText + + + true + + + + + + + Password + + + txtPassword + + + + + + + QLineEdit::Password + + + + + + + Qt::Vertical + + + + 0 + 0 + + + + + + + + + + + + + 0 + 0 + + + + Name of the new connection + + + true + + + + DPI-Mode @@ -56,45 +154,6 @@ - - - - - 0 - 0 - - - - If the service requires basic authentication, enter a user name and optional password - - - Qt::PlainText - - - true - - - - - - - Password - - - txtPassword - - - - - - - &User name - - - txtUserName - - - @@ -111,22 +170,6 @@ - - - - - 0 - 0 - - - - Name of the new connection - - - true - - - @@ -134,55 +177,10 @@ - - - - - - - QLineEdit::Password - - - - - - - Ignore GetFeatureInfo URI reported in capabilities - - - - - - - Ignore GetMap/GetTile URI reported in capabilities - - - - - - - Ignore axis orientation (WMS 1.3/WMTS) - - - - - - - Invert axis orientation - - - - - - - Smooth pixmap transform - - - - + - + Referer @@ -192,8 +190,43 @@ - - + + + + + + + Smooth pixmap transform + + + + + + + Invert axis orientation + + + + + + + Ignore axis orientation (WMS 1.3/WMTS) + + + + + + + Ignore GetMap/GetTile URI reported in capabilities + + + + + + + Ignore GetFeatureInfo URI reported in capabilities + +