From fdc24b26ed8aeb26d36f82a9c8918ee5c77491c4 Mon Sep 17 00:00:00 2001 From: Damiano Lombardi Date: Wed, 11 Dec 2024 17:07:27 +0100 Subject: [PATCH] Set additional HTTP headers for WCS provider (#59635) * Set additional HTTP headers for WCS provider Same way as done for WMS Fixes partially #17823 (WFS still missing) * Move qgsauthorizationsettings.h to core/auth * qgsauthorizationsettings.h SIP_NO_FILE * Add class documentation * Add CORE_EXPORT * switcht to class * Move implementation to cpp file * fix indentation --------- Co-authored-by: Denis Rouzaud --- src/core/CMakeLists.txt | 2 + src/core/auth/qgsauthorizationsettings.cpp | 48 +++++++++++++++ .../auth}/qgsauthorizationsettings.h | 50 +++++++--------- src/gui/qgsowssourceselect.cpp | 4 +- .../wcs/qgswcsdataitemguiprovider.cpp | 4 +- src/providers/wcs/qgswcsprovider.cpp | 4 +- src/providers/wcs/qgswcsprovider.h | 49 ++-------------- src/providers/wms/qgswmscapabilities.cpp | 4 +- src/providers/wms/qgswmscapabilities.h | 58 ++----------------- src/providers/wms/qgswmsprovider.cpp | 4 +- src/providers/wms/qgswmsprovider.h | 6 +- 11 files changed, 95 insertions(+), 138 deletions(-) create mode 100644 src/core/auth/qgsauthorizationsettings.cpp rename src/{providers/wfs => core/auth}/qgsauthorizationsettings.h (57%) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index f0236b7b879a..75d9788205bd 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -212,6 +212,7 @@ set(QGIS_CORE_SRCS auth/qgsauthmethod.cpp auth/qgsauthmethodmetadata.cpp auth/qgsauthmethodregistry.cpp + auth/qgsauthorizationsettings.cpp auth/qgsauthconfigurationstoragesqlite.cpp auth/qgsauthconfigurationstoragedb.cpp @@ -1389,6 +1390,7 @@ set(QGIS_CORE_HDRS auth/qgsauthmethod.h auth/qgsauthmethodmetadata.h auth/qgsauthmethodregistry.h + auth/qgsauthorizationsettings.h auth/qgsauthconfigurationstoragesqlite.h auth/qgsauthconfigurationstoragedb.h diff --git a/src/core/auth/qgsauthorizationsettings.cpp b/src/core/auth/qgsauthorizationsettings.cpp new file mode 100644 index 000000000000..2e20204642fb --- /dev/null +++ b/src/core/auth/qgsauthorizationsettings.cpp @@ -0,0 +1,48 @@ +/*************************************************************************** + qgsauthorizationsettings.cpp + --------------------- + begin : December 2024 + copyright : (C) 2024 by Damiano Lombardi + email : damiano at opengis.ch + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "qgsauthorizationsettings.h" + +QgsAuthorizationSettings::QgsAuthorizationSettings( const QString &userName, const QString &password, const QgsHttpHeaders &httpHeaders, const QString &authcfg ) + : mUserName( userName ) + , mPassword( password ) + , mHttpHeaders( httpHeaders ) + , mAuthCfg( authcfg ) +{} + +bool QgsAuthorizationSettings::setAuthorization( QNetworkRequest &request ) const +{ + if ( !mAuthCfg.isEmpty() ) // must be non-empty value + { + return QgsApplication::authManager()->updateNetworkRequest( request, mAuthCfg ); + } + else if ( !mUserName.isEmpty() || !mPassword.isEmpty() ) + { + request.setRawHeader( "Authorization", "Basic " + QStringLiteral( "%1:%2" ).arg( mUserName, mPassword ).toUtf8().toBase64() ); + } + + mHttpHeaders.updateNetworkRequest( request ); + + return true; +} + +bool QgsAuthorizationSettings::setAuthorizationReply( QNetworkReply *reply ) const +{ + if ( !mAuthCfg.isEmpty() ) + { + return QgsApplication::authManager()->updateNetworkReply( reply, mAuthCfg ); + } + return true; +} diff --git a/src/providers/wfs/qgsauthorizationsettings.h b/src/core/auth/qgsauthorizationsettings.h similarity index 57% rename from src/providers/wfs/qgsauthorizationsettings.h rename to src/core/auth/qgsauthorizationsettings.h index a0343381fd7f..671ba53e5398 100644 --- a/src/providers/wfs/qgsauthorizationsettings.h +++ b/src/core/auth/qgsauthorizationsettings.h @@ -18,43 +18,32 @@ #include "qgsauthmanager.h" #include "qgsapplication.h" +#include "qgshttpheaders.h" #include #include #include -// TODO: merge with QgsWmsAuthorization? -struct QgsAuthorizationSettings +#define SIP_NO_FILE + +/** + * \ingroup core + * \class QgsAuthorizationSettings + * \brief Utility class that contains authorization information. + * \since QGIS 3.42 + */ +class CORE_EXPORT QgsAuthorizationSettings { - QgsAuthorizationSettings( const QString &userName = QString(), const QString &password = QString(), const QString &authcfg = QString() ) - : mUserName( userName ) - , mPassword( password ) - , mAuthCfg( authcfg ) - {} + public: + + //! Constructor for QgsAuthorizationSettings. + QgsAuthorizationSettings( const QString &userName = QString(), const QString &password = QString(), const QgsHttpHeaders &httpHeaders = QgsHttpHeaders(), const QString &authcfg = QString() ); - //! update authorization for request - bool setAuthorization( QNetworkRequest &request ) const - { - if ( !mAuthCfg.isEmpty() ) // must be non-empty value - { - return QgsApplication::authManager()->updateNetworkRequest( request, mAuthCfg ); - } - else if ( !mUserName.isNull() || !mPassword.isNull() ) // allow empty values - { - request.setRawHeader( "Authorization", "Basic " + QStringLiteral( "%1:%2" ).arg( mUserName, mPassword ).toLatin1().toBase64() ); - } - return true; - } + //! Update authorization for request + bool setAuthorization( QNetworkRequest &request ) const; - //! update authorization for reply - bool setAuthorizationReply( QNetworkReply *reply ) const - { - if ( !mAuthCfg.isEmpty() ) - { - return QgsApplication::authManager()->updateNetworkReply( reply, mAuthCfg ); - } - return true; - } + //! Update authorization for reply + bool setAuthorizationReply( QNetworkReply *reply ) const; //! Username for basic http authentication QString mUserName; @@ -62,6 +51,9 @@ struct QgsAuthorizationSettings //! Password for basic http authentication QString mPassword; + //! headers for http requests + QgsHttpHeaders mHttpHeaders; + //! Authentication configuration ID QString mAuthCfg; }; diff --git a/src/gui/qgsowssourceselect.cpp b/src/gui/qgsowssourceselect.cpp index 54a2b171de38..cbbaf3ef8084 100644 --- a/src/gui/qgsowssourceselect.cpp +++ b/src/gui/qgsowssourceselect.cpp @@ -267,7 +267,7 @@ QgsNewHttpConnection::ConnectionType connectionTypeFromServiceString( const QStr void QgsOWSSourceSelect::mNewButton_clicked() { const QgsNewHttpConnection::ConnectionType type = connectionTypeFromServiceString( mService ); - QgsNewHttpConnection *nc = new QgsNewHttpConnection( this, type, mService.toUpper() ); + QgsNewHttpConnection *nc = new QgsNewHttpConnection( this, type, mService.toUpper(), QString(), QgsNewHttpConnection::FlagShowHttpSettings ); if ( nc->exec() ) { @@ -281,7 +281,7 @@ void QgsOWSSourceSelect::mNewButton_clicked() void QgsOWSSourceSelect::mEditButton_clicked() { const QgsNewHttpConnection::ConnectionType type = connectionTypeFromServiceString( mService ); - QgsNewHttpConnection *nc = new QgsNewHttpConnection( this, type, mService.toUpper(), mConnectionsComboBox->currentText() ); + QgsNewHttpConnection *nc = new QgsNewHttpConnection( this, type, mService.toUpper(), mConnectionsComboBox->currentText(), QgsNewHttpConnection::FlagShowHttpSettings ); if ( nc->exec() ) { diff --git a/src/providers/wcs/qgswcsdataitemguiprovider.cpp b/src/providers/wcs/qgswcsdataitemguiprovider.cpp index 8e8e32659463..577c67c85e57 100644 --- a/src/providers/wcs/qgswcsdataitemguiprovider.cpp +++ b/src/providers/wcs/qgswcsdataitemguiprovider.cpp @@ -72,7 +72,7 @@ void QgsWcsDataItemGuiProvider::populateContextMenu( QgsDataItem *item, QMenu *m void QgsWcsDataItemGuiProvider::newConnection( QgsDataItem *item ) { - QgsNewHttpConnection nc( nullptr, QgsNewHttpConnection::ConnectionWcs, QStringLiteral( "WCS" ) ); + QgsNewHttpConnection nc( nullptr, QgsNewHttpConnection::ConnectionWcs, QStringLiteral( "WCS" ), QString(), QgsNewHttpConnection::FlagShowHttpSettings ); if ( nc.exec() ) { @@ -82,7 +82,7 @@ void QgsWcsDataItemGuiProvider::newConnection( QgsDataItem *item ) void QgsWcsDataItemGuiProvider::editConnection( QgsDataItem *item ) { - QgsNewHttpConnection nc( nullptr, QgsNewHttpConnection::ConnectionWcs, QStringLiteral( "WCS" ), item->name() ); + QgsNewHttpConnection nc( nullptr, QgsNewHttpConnection::ConnectionWcs, QStringLiteral( "WCS" ), item->name(), QgsNewHttpConnection::FlagShowHttpSettings ); if ( nc.exec() ) { diff --git a/src/providers/wcs/qgswcsprovider.cpp b/src/providers/wcs/qgswcsprovider.cpp index 91c8dc9b5649..078b26895abb 100644 --- a/src/providers/wcs/qgswcsprovider.cpp +++ b/src/providers/wcs/qgswcsprovider.cpp @@ -436,6 +436,8 @@ bool QgsWcsProvider::parseUri( const QString &uriString ) } QgsDebugMsgLevel( "set authcfg to " + mAuth.mAuthCfg, 2 ); + mAuth.mHttpHeaders = uri.httpHeaders(); + mIdentifier = uri.param( QStringLiteral( "identifier" ) ); mTime = uri.param( QStringLiteral( "time" ) ); @@ -1648,7 +1650,7 @@ QgsWcsProvider *QgsWcsProviderMetadata::createProvider( const QString &uri, cons int QgsWcsDownloadHandler::sErrors = 0; -QgsWcsDownloadHandler::QgsWcsDownloadHandler( const QUrl &url, QgsWcsAuthorization &auth, QNetworkRequest::CacheLoadControl cacheLoadControl, QByteArray &cachedData, const QString &wcsVersion, QgsError &cachedError, QgsRasterBlockFeedback *feedback ) +QgsWcsDownloadHandler::QgsWcsDownloadHandler( const QUrl &url, QgsAuthorizationSettings &auth, QNetworkRequest::CacheLoadControl cacheLoadControl, QByteArray &cachedData, const QString &wcsVersion, QgsError &cachedError, QgsRasterBlockFeedback *feedback ) : mAuth( auth ) , mEventLoop( new QEventLoop ) , mCachedData( cachedData ) diff --git a/src/providers/wcs/qgswcsprovider.h b/src/providers/wcs/qgswcsprovider.h index 748f99f20a56..134445741bd5 100644 --- a/src/providers/wcs/qgswcsprovider.h +++ b/src/providers/wcs/qgswcsprovider.h @@ -31,6 +31,7 @@ #include "qgscoordinatetransform.h" #include "qgsogrutils.h" #include "qgsapplication.h" +#include "qgsauthorizationsettings.h" #include "qgsprovidermetadata.h" @@ -53,48 +54,6 @@ class QNetworkRequest; #include #include "cpl_conv.h" -// TODO: merge with QgsWmsAuthorization? -struct QgsWcsAuthorization -{ - QgsWcsAuthorization( const QString &userName = QString(), const QString &password = QString(), const QString &authcfg = QString() ) - : mUserName( userName ) - , mPassword( password ) - , mAuthCfg( authcfg ) - {} - - //! Sets authorization header - bool setAuthorization( QNetworkRequest &request ) const - { - if ( !mAuthCfg.isEmpty() ) - { - return QgsApplication::authManager()->updateNetworkRequest( request, mAuthCfg ); - } - else if ( !mUserName.isNull() || !mPassword.isNull() ) - { - request.setRawHeader( "Authorization", "Basic " + QStringLiteral( "%1:%2" ).arg( mUserName, mPassword ).toLatin1().toBase64() ); - } - return true; - } - - //! Sets authorization reply - bool setAuthorizationReply( QNetworkReply *reply ) const - { - if ( !mAuthCfg.isEmpty() ) - { - return QgsApplication::authManager()->updateNetworkReply( reply, mAuthCfg ); - } - return true; - } - - //! Username for basic http authentication - QString mUserName; - - //! Password for basic http authentication - QString mPassword; - - //! Authentication configuration ID - QString mAuthCfg; -}; /** * @@ -384,7 +343,7 @@ class QgsWcsProvider final : public QgsRasterDataProvider, QgsGdalProviderBase //QMap mLayerParentNames; //! http authorization details - mutable QgsWcsAuthorization mAuth; + mutable QgsAuthorizationSettings mAuth; //! whether to use hrefs from GetCapabilities (default) or // the given base urls for GetMap and GetFeatureInfo @@ -413,7 +372,7 @@ class QgsWcsDownloadHandler : public QObject { Q_OBJECT public: - QgsWcsDownloadHandler( const QUrl &url, QgsWcsAuthorization &auth, QNetworkRequest::CacheLoadControl cacheLoadControl, QByteArray &cachedData, const QString &wcsVersion, QgsError &cachedError, QgsRasterBlockFeedback *feedback ); + QgsWcsDownloadHandler( const QUrl &url, QgsAuthorizationSettings &auth, QNetworkRequest::CacheLoadControl cacheLoadControl, QByteArray &cachedData, const QString &wcsVersion, QgsError &cachedError, QgsRasterBlockFeedback *feedback ); ~QgsWcsDownloadHandler() override; void blockingDownload(); @@ -426,7 +385,7 @@ class QgsWcsDownloadHandler : public QObject protected: void finish() { QMetaObject::invokeMethod( mEventLoop, "quit", Qt::QueuedConnection ); } - QgsWcsAuthorization &mAuth; + QgsAuthorizationSettings &mAuth; QEventLoop *mEventLoop = nullptr; QNetworkReply *mCacheReply = nullptr; diff --git a/src/providers/wms/qgswmscapabilities.cpp b/src/providers/wms/qgswmscapabilities.cpp index eff46561e817..20a9ceab977b 100644 --- a/src/providers/wms/qgswmscapabilities.cpp +++ b/src/providers/wms/qgswmscapabilities.cpp @@ -2437,7 +2437,7 @@ QgsWmsCapabilitiesDownload::QgsWmsCapabilitiesDownload( bool forceRefresh, QObje { } -QgsWmsCapabilitiesDownload::QgsWmsCapabilitiesDownload( const QString &baseUrl, const QgsWmsAuthorization &auth, bool forceRefresh, QObject *parent ) +QgsWmsCapabilitiesDownload::QgsWmsCapabilitiesDownload( const QString &baseUrl, const QgsAuthorizationSettings &auth, bool forceRefresh, QObject *parent ) : QObject( parent ) , mBaseUrl( baseUrl ) , mAuth( auth ) @@ -2461,7 +2461,7 @@ void QgsWmsCapabilitiesDownload::setForceRefresh( bool forceRefresh ) mForceRefresh = forceRefresh; } -bool QgsWmsCapabilitiesDownload::downloadCapabilities( const QString &baseUrl, const QgsWmsAuthorization &auth ) +bool QgsWmsCapabilitiesDownload::downloadCapabilities( const QString &baseUrl, const QgsAuthorizationSettings &auth ) { mBaseUrl = baseUrl; mAuth = auth; diff --git a/src/providers/wms/qgswmscapabilities.h b/src/providers/wms/qgswmscapabilities.h index 28f399c8da4d..cb6648ae6534 100644 --- a/src/providers/wms/qgswmscapabilities.h +++ b/src/providers/wms/qgswmscapabilities.h @@ -30,6 +30,7 @@ #include "qgstemporalutils.h" #include "qgshttpheaders.h" #include "qgscoordinatetransformcontext.h" +#include "qgsauthorizationsettings.h" class QNetworkReply; @@ -686,53 +687,6 @@ struct QgsWmsParserSettings bool invertAxisOrientation; }; -struct QgsWmsAuthorization -{ - QgsWmsAuthorization( const QString &userName = QString(), const QString &password = QString(), const QgsHttpHeaders &httpHeaders = QgsHttpHeaders(), const QString &authcfg = QString() ) - : mUserName( userName ) - , mPassword( password ) - , mHttpHeaders( httpHeaders ) - , mAuthCfg( authcfg ) - {} - - bool setAuthorization( QNetworkRequest &request ) const - { - if ( !mAuthCfg.isEmpty() ) - { - return QgsApplication::authManager()->updateNetworkRequest( request, mAuthCfg ); - } - else if ( !mUserName.isEmpty() || !mPassword.isEmpty() ) - { - request.setRawHeader( "Authorization", "Basic " + QStringLiteral( "%1:%2" ).arg( mUserName, mPassword ).toUtf8().toBase64() ); - } - - mHttpHeaders.updateNetworkRequest( request ); - - return true; - } - //! Sets authorization reply - bool setAuthorizationReply( QNetworkReply *reply ) const - { - if ( !mAuthCfg.isEmpty() ) - { - return QgsApplication::authManager()->updateNetworkReply( reply, mAuthCfg ); - } - return true; - } - - //! Username for basic http authentication - QString mUserName; - - //! Password for basic http authentication - QString mPassword; - - //! headers for http requests - QgsHttpHeaders mHttpHeaders; - - //! Authentication configuration ID - QString mAuthCfg; -}; - //! URI that gets passed to provider class QgsWmsSettings @@ -741,7 +695,7 @@ class QgsWmsSettings bool parseUri( const QString &uriString ); QString baseUrl() const { return mBaseUrl; } - QgsWmsAuthorization authorization() const { return mAuth; } + QgsAuthorizationSettings authorization() const { return mAuth; } QgsWmsParserSettings parserSettings() const { return mParserSettings; } @@ -861,7 +815,7 @@ class QgsWmsSettings //! URL part of URI (httpuri) QString mBaseUrl; - QgsWmsAuthorization mAuth; + QgsAuthorizationSettings mAuth; bool mIgnoreGetMapUrl; bool mIgnoreGetFeatureInfoUrl; @@ -1078,13 +1032,13 @@ class QgsWmsCapabilitiesDownload : public QObject public: explicit QgsWmsCapabilitiesDownload( bool forceRefresh, QObject *parent = nullptr ); - QgsWmsCapabilitiesDownload( const QString &baseUrl, const QgsWmsAuthorization &auth, bool forceRefresh, QObject *parent = nullptr ); + QgsWmsCapabilitiesDownload( const QString &baseUrl, const QgsAuthorizationSettings &auth, bool forceRefresh, QObject *parent = nullptr ); ~QgsWmsCapabilitiesDownload() override; bool downloadCapabilities(); - bool downloadCapabilities( const QString &baseUrl, const QgsWmsAuthorization &auth ); + bool downloadCapabilities( const QString &baseUrl, const QgsAuthorizationSettings &auth ); /** * Returns the download refresh state. @@ -1124,7 +1078,7 @@ class QgsWmsCapabilitiesDownload : public QObject //! URL part of URI (httpuri) QString mBaseUrl; - QgsWmsAuthorization mAuth; + QgsAuthorizationSettings mAuth; //! The reply to the capabilities request QNetworkReply *mCapabilitiesReply = nullptr; diff --git a/src/providers/wms/qgswmsprovider.cpp b/src/providers/wms/qgswmsprovider.cpp index 850bc199b384..bff0e2cb9319 100644 --- a/src/providers/wms/qgswmsprovider.cpp +++ b/src/providers/wms/qgswmsprovider.cpp @@ -4238,7 +4238,7 @@ QgsProviderMetadata::ProviderCapabilities QgsWmsProviderMetadata::providerCapabi // ----------------- -QgsWmsImageDownloadHandler::QgsWmsImageDownloadHandler( const QString &providerUri, const QUrl &url, const QgsWmsAuthorization &auth, QImage *image, QgsRasterBlockFeedback *feedback ) +QgsWmsImageDownloadHandler::QgsWmsImageDownloadHandler( const QString &providerUri, const QUrl &url, const QgsAuthorizationSettings &auth, QImage *image, QgsRasterBlockFeedback *feedback ) : mProviderUri( providerUri ) , mCachedImage( image ) , mEventLoop( new QEventLoop ) @@ -4393,7 +4393,7 @@ void QgsWmsImageDownloadHandler::canceled() // ---------- -QgsWmsTiledImageDownloadHandler::QgsWmsTiledImageDownloadHandler( const QString &providerUri, const QgsWmsAuthorization &auth, int tileReqNo, const QgsWmsProvider::TileRequests &requests, QImage *image, const QgsRectangle &viewExtent, double sourceResolution, bool smoothPixmapTransform, bool resamplingEnabled, QgsRasterBlockFeedback *feedback ) +QgsWmsTiledImageDownloadHandler::QgsWmsTiledImageDownloadHandler( const QString &providerUri, const QgsAuthorizationSettings &auth, int tileReqNo, const QgsWmsProvider::TileRequests &requests, QImage *image, const QgsRectangle &viewExtent, double sourceResolution, bool smoothPixmapTransform, bool resamplingEnabled, QgsRasterBlockFeedback *feedback ) : mProviderUri( providerUri ) , mAuth( auth ) , mImage( image ) diff --git a/src/providers/wms/qgswmsprovider.h b/src/providers/wms/qgswmsprovider.h index 214976106dc0..0197a845c2dd 100644 --- a/src/providers/wms/qgswmsprovider.h +++ b/src/providers/wms/qgswmsprovider.h @@ -595,7 +595,7 @@ class QgsWmsImageDownloadHandler : public QObject { Q_OBJECT public: - QgsWmsImageDownloadHandler( const QString &providerUri, const QUrl &url, const QgsWmsAuthorization &auth, QImage *image, QgsRasterBlockFeedback *feedback ); + QgsWmsImageDownloadHandler( const QString &providerUri, const QUrl &url, const QgsAuthorizationSettings &auth, QImage *image, QgsRasterBlockFeedback *feedback ); ~QgsWmsImageDownloadHandler() override; void downloadBlocking(); @@ -624,7 +624,7 @@ class QgsWmsTiledImageDownloadHandler : public QObject { Q_OBJECT public: - QgsWmsTiledImageDownloadHandler( const QString &providerUri, const QgsWmsAuthorization &auth, int reqNo, const QgsWmsProvider::TileRequests &requests, QImage *image, const QgsRectangle &viewExtent, double sourceResolution, bool smoothPixmapTransform, bool resamplingEnabled, QgsRasterBlockFeedback *feedback ); + QgsWmsTiledImageDownloadHandler( const QString &providerUri, const QgsAuthorizationSettings &auth, int reqNo, const QgsWmsProvider::TileRequests &requests, QImage *image, const QgsRectangle &viewExtent, double sourceResolution, bool smoothPixmapTransform, bool resamplingEnabled, QgsRasterBlockFeedback *feedback ); ~QgsWmsTiledImageDownloadHandler() override; void downloadBlocking(); @@ -652,7 +652,7 @@ class QgsWmsTiledImageDownloadHandler : public QObject QString mProviderUri; QString mBaseUrl; - QgsWmsAuthorization mAuth; + QgsAuthorizationSettings mAuth; QImage *mImage = nullptr; QgsRectangle mViewExtent;