Skip to content
Permalink
Browse files

Merge pull request #5253 from boundlessgeo/auth_proxy

[auth][feature][needs-docs] Proxy authentication integration with QGIS authentication system
  • Loading branch information
elpaso committed Sep 27, 2017
2 parents 6ce8b4c + 385cca6 commit 829702bd24c65511f8a3e37ee18c21cb216d4fe4
@@ -359,6 +359,17 @@ Get list of authentication ids from database
:rtype: bool
%End

bool updateNetworkProxy( QNetworkProxy &proxy /In,Out/, const QString &authcfg,
const QString &dataprovider = QString() );
%Docstring
Provider call to update a QNetworkProxy with an authentication config
\param proxy the QNetworkProxy
\param authcfg Associated authentication config id
\param dataprovider Provider key filter, offering logic branching in authentication method
:return: Whether operation succeeded
:rtype: bool
%End


bool storeAuthSetting( const QString &key, const QVariant &value, bool encrypt = false );
%Docstring
@@ -28,6 +28,7 @@ class QgsAuthMethod : QObject
NetworkReply,
DataSourceUri,
GenericDataSourceUri,
NetworkProxy,
All
};
typedef QFlags<QgsAuthMethod::Expansion> Expansions;
@@ -110,6 +111,18 @@ Increment this if method is significantly updated, allow updater code to be writ
:rtype: bool
%End

virtual bool updateNetworkProxy( QNetworkProxy &proxy, const QString &authcfg,
const QString &dataprovider = QString() );
%Docstring
Update proxy settings with authentication components
\param proxy
\param authcfg Authentication configuration ID
\param dataprovider Textual key for a data provider, e.g. 'proxy', that allows
for custom updater code specific to the provider
:return: Whether the update succeeded
:rtype: bool
%End

virtual void clearCachedConfig( const QString &authcfg ) = 0;
%Docstring
Clear any cached configuration. Called when the QgsAuthManager deletes an authentication configuration (authcfg).
@@ -630,8 +630,6 @@ QgisApp::QgisApp( QSplashScreen *splash, bool restorePlugins, bool skipVersionCh
connect( mUserProfileManager, &QgsUserProfileManager::profilesChanged, this, &QgisApp::refreshProfileMenu );
endProfile();

namSetup();

// load GUI: actions, menus, toolbars
profiler->beginGroup( QStringLiteral( "qgisapp" ) );
profiler->beginGroup( QStringLiteral( "startup" ) );
@@ -656,6 +654,10 @@ QgisApp::QgisApp( QSplashScreen *splash, bool restorePlugins, bool skipVersionCh
}
endProfile();

mTray = new QSystemTrayIcon();
mTray->setIcon( QIcon( QgsApplication::appIconPath() ) );
mTray->hide();

startProfile( QStringLiteral( "Initializing authentication" ) );
mSplash->showMessage( tr( "Initializing authentication" ), Qt::AlignHCenter | Qt::AlignBottom );
qApp->processEvents();
@@ -666,6 +668,9 @@ QgisApp::QgisApp( QSplashScreen *splash, bool restorePlugins, bool skipVersionCh
}
endProfile();

// Setup QgsNetworkAccessManager (this needs to happen after authentication, for proxy settings)
namSetup();

// Create the themes folder for the user
startProfile( QStringLiteral( "Creating theme folder" ) );
QgsApplication::createThemeFolder();
@@ -1156,11 +1161,6 @@ QgisApp::QgisApp( QSplashScreen *splash, bool restorePlugins, bool skipVersionCh
grabGesture( Qt::TapAndHoldGesture );
}


mTray = new QSystemTrayIcon();
mTray->setIcon( QIcon( QgsApplication::appIconPath() ) );
mTray->hide();

connect( QgsApplication::taskManager(), &QgsTaskManager::statusChanged, this, &QgisApp::onTaskCompleteShowNotify );

#ifdef Q_OS_WIN
@@ -28,6 +28,7 @@
#include "qgstolerance.h"
#include "qgsscaleutils.h"
#include "qgsnetworkaccessmanager.h"
#include "qgsauthconfigselect.h"
#include "qgsproject.h"
#include "qgsdualview.h"
#include "qgsrasterlayer.h"
@@ -307,6 +308,16 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WindowFlags fl, const QList<QgsOpti
// WMS/WMS-C default max retry in case of tile request errors
mDefaultTileMaxRetrySpinBox->setValue( mSettings->value( QStringLiteral( "/qgis/defaultTileMaxRetry" ), "3" ).toInt() );

// Proxy stored authentication configurations
mProxyAuthConfigSelect = new QgsAuthConfigSelect( this, QStringLiteral( "proxy" ) );
tabAuth->insertTab( 1, mProxyAuthConfigSelect, tr( "Configurations" ) );
QString authcfg = mSettings->value( QStringLiteral( "proxy/authcfg" ) ).toString();
mProxyAuthConfigSelect->setConfigId( authcfg );
if ( !authcfg.isEmpty() )
{
tabAuth->setCurrentIndex( tabAuth->indexOf( mProxyAuthConfigSelect ) );
}

//Web proxy settings
grpProxy->setChecked( mSettings->value( QStringLiteral( "proxy/proxyEnabled" ), "0" ).toBool() );
leProxyHost->setText( mSettings->value( QStringLiteral( "proxy/proxyHost" ), "" ).toString() );
@@ -1162,6 +1173,9 @@ void QgsOptions::saveOptions()
// WMS/WMS-C default max retry in case of tile request errors
mSettings->setValue( QStringLiteral( "/qgis/defaultTileMaxRetry" ), mDefaultTileMaxRetrySpinBox->value() );

// Proxy stored authentication configurations
mSettings->setValue( QStringLiteral( "proxy/authcfg" ), mProxyAuthConfigSelect->configId( ) );

//Web proxy settings
mSettings->setValue( QStringLiteral( "proxy/proxyEnabled" ), grpProxy->isChecked() );
mSettings->setValue( QStringLiteral( "proxy/proxyHost" ), leProxyHost->text() );
@@ -32,6 +32,7 @@
class QgsExpressionContext;
class QgsOptionsPageWidget;
class QgsLocatorOptionsWidget;
class QgsAuthConfigSelect;

/**
* \class QgsOptions
@@ -255,6 +256,7 @@ class APP_EXPORT QgsOptions : public QgsOptionsDialogBase, private Ui::QgsOption

QList< QgsOptionsPageWidget * > mAdditionalOptionWidgets;
QgsLocatorOptionsWidget *mLocatorOptionsWidget = nullptr;
QgsAuthConfigSelect *mProxyAuthConfigSelect = nullptr;

};

@@ -20,6 +20,8 @@
#include "qgsauthmanager.h"
#include "qgslogger.h"

#include <QNetworkProxy>

static const QString AUTH_METHOD_KEY = QStringLiteral( "Basic" );
static const QString AUTH_METHOD_DESCRIPTION = QStringLiteral( "Basic authentication" );

@@ -37,7 +39,8 @@ QgsAuthBasicMethod::QgsAuthBasicMethod()
<< QStringLiteral( "ows" )
<< QStringLiteral( "wfs" ) // convert to lowercase
<< QStringLiteral( "wcs" )
<< QStringLiteral( "wms" ) );
<< QStringLiteral( "wms" )
<< QStringLiteral( "proxy" ) );
}

QgsAuthBasicMethod::~QgsAuthBasicMethod()
@@ -126,6 +129,28 @@ bool QgsAuthBasicMethod::updateDataSourceUriItems( QStringList &connectionItems,
return true;
}

bool QgsAuthBasicMethod::updateNetworkProxy( QNetworkProxy &proxy, const QString &authcfg, const QString &dataprovider )
{
Q_UNUSED( dataprovider )

QgsAuthMethodConfig mconfig = getMethodConfig( authcfg );
if ( !mconfig.isValid() )
{
QgsDebugMsg( QString( "Update proxy config FAILED for authcfg: %1: config invalid" ).arg( authcfg ) );
return false;
}

QString username = mconfig.config( QStringLiteral( "username" ) );
QString password = mconfig.config( QStringLiteral( "password" ) );

if ( !username.isEmpty() )
{
proxy.setUser( username );
proxy.setPassword( password );
}
return true;
}

void QgsAuthBasicMethod::updateMethodConfig( QgsAuthMethodConfig &mconfig )
{
if ( mconfig.hasConfig( QStringLiteral( "oldconfigstyle" ) ) )
@@ -44,6 +44,10 @@ class QgsAuthBasicMethod : public QgsAuthMethod
bool updateDataSourceUriItems( QStringList &connectionItems, const QString &authcfg,
const QString &dataprovider = QString() ) override;


bool updateNetworkProxy( QNetworkProxy &proxy, const QString &authcfg,
const QString &dataprovider = QString() ) override;

void clearCachedConfig( const QString &authcfg ) override;

void updateMethodConfig( QgsAuthMethodConfig &mconfig ) override;
@@ -1457,6 +1457,32 @@ bool QgsAuthManager::updateDataSourceUriItems( QStringList &connectionItems, con
return false;
}

bool QgsAuthManager::updateNetworkProxy( QNetworkProxy &proxy, const QString &authcfg, const QString &dataprovider )
{
if ( isDisabled() )
return false;

QgsAuthMethod *authmethod = configAuthMethod( authcfg );
if ( authmethod )
{
if ( !( authmethod->supportedExpansions() & QgsAuthMethod::NetworkProxy ) )
{
QgsDebugMsg( QStringLiteral( "Proxy updating not supported by authcfg: %1" ).arg( authcfg ) );
return true;
}

if ( !authmethod->updateNetworkProxy( proxy, authcfg, dataprovider.toLower() ) )
{
authmethod->clearCachedConfig( authcfg );
return false;
}
QgsDebugMsg( QStringLiteral( "Proxy updated successfully from authcfg: %1" ).arg( authcfg ) );
return true;
}

return false;
}

bool QgsAuthManager::storeAuthSetting( const QString &key, const QVariant &value, bool encrypt )
{
if ( key.isEmpty() )
@@ -332,6 +332,16 @@ class CORE_EXPORT QgsAuthManager : public QObject
bool updateDataSourceUriItems( QStringList &connectionItems SIP_INOUT, const QString &authcfg,
const QString &dataprovider = QString() );

/**
* Provider call to update a QNetworkProxy with an authentication config
* \param proxy the QNetworkProxy
* \param authcfg Associated authentication config id
* \param dataprovider Provider key filter, offering logic branching in authentication method
* \returns Whether operation succeeded
*/
bool updateNetworkProxy( QNetworkProxy &proxy SIP_INOUT, const QString &authcfg,
const QString &dataprovider = QString() );

////////////////// Generic settings ///////////////////////

//! Store an authentication setting (stored as string via QVariant( value ).toString() )
@@ -51,7 +51,8 @@ class CORE_EXPORT QgsAuthMethod : public QObject
NetworkReply = 0x2,
DataSourceUri = 0x4,
GenericDataSourceUri = 0x8,
All = NetworkRequest | NetworkReply | DataSourceUri | GenericDataSourceUri
NetworkProxy = 0x16,
All = NetworkRequest | NetworkReply | DataSourceUri | GenericDataSourceUri | NetworkProxy
};
Q_DECLARE_FLAGS( Expansions, Expansion )

@@ -126,6 +127,22 @@ class CORE_EXPORT QgsAuthMethod : public QObject
return true; // noop
}

/** Update proxy settings with authentication components
* \param proxy
* \param authcfg Authentication configuration ID
* \param dataprovider Textual key for a data provider, e.g. 'proxy', that allows
* for custom updater code specific to the provider
* \returns Whether the update succeeded
*/
virtual bool updateNetworkProxy( QNetworkProxy &proxy, const QString &authcfg,
const QString &dataprovider = QString() )
{
Q_UNUSED( proxy )
Q_UNUSED( authcfg )
Q_UNUSED( dataprovider )
return true; // noop
}

/** Clear any cached configuration. Called when the QgsAuthManager deletes an authentication configuration (authcfg).
* \note It is highly recommended that a cache of authentication components (per requested authcfg)
* be implemented, to avoid excessive queries on the auth database. Such a cache could be as
@@ -321,6 +321,7 @@ void QgsNetworkAccessManager::setupDefaultProxyAndCache()
//read type, host, port, user, passw from settings
QString proxyHost = settings.value( QStringLiteral( "proxy/proxyHost" ), "" ).toString();
int proxyPort = settings.value( QStringLiteral( "proxy/proxyPort" ), "" ).toString().toInt();

QString proxyUser = settings.value( QStringLiteral( "proxy/proxyUser" ), "" ).toString();
QString proxyPassword = settings.value( QStringLiteral( "proxy/proxyPassword" ), "" ).toString();

@@ -356,7 +357,7 @@ void QgsNetworkAccessManager::setupDefaultProxyAndCache()
{
proxyType = QNetworkProxy::FtpCachingProxy;
}
QgsDebugMsg( QString( "setting proxy %1 %2:%3 %4/%5" )
QgsDebugMsg( QStringLiteral( "setting proxy %1 %2:%3 %4/%5" )
.arg( proxyType )
.arg( proxyHost ).arg( proxyPort )
.arg( proxyUser, proxyPassword )
@@ -365,6 +366,14 @@ void QgsNetworkAccessManager::setupDefaultProxyAndCache()
}
}

// Setup network proxy authentication configuration
QString authcfg = settings.value( QStringLiteral( "proxy/authcfg" ), "" ).toString();
if ( !authcfg.isEmpty( ) )
{
QgsDebugMsg( QStringLiteral( "setting proxy from stored authentication configuration %1" ).arg( authcfg ) );
QgsAuthManager::instance()->updateNetworkProxy( proxy, authcfg );
}

setFallbackProxyAndExcludes( proxy, excludes );

QgsNetworkDiskCache *newcache = qobject_cast<QgsNetworkDiskCache *>( cache() );

0 comments on commit 829702b

Please sign in to comment.
You can’t perform that action at this time.