Skip to content
Permalink
Browse files

Merge pull request #5644 from boundlessgeo/bd-2648-auth-thread-safety

[auth] Thread safe auth methods with recursive mutex
  • Loading branch information
elpaso committed Nov 16, 2017
2 parents 29c8f7c + 6f06597 commit d590e98c3f230bddcbdd179663e5b4eab907465c
@@ -151,6 +151,7 @@ Increment this if method is significantly updated, allow updater code to be writ
Non-public since this is an abstract base class
%End


static QString authMethodTag();
%Docstring
Tag signifying that this is an authentcation method (e.g. for use as title in message log panel output)
@@ -171,6 +172,7 @@ Set the support expansions (points in providers where the authentication is inje
Set list of data providers this auth method supports
%End


};
QFlags<QgsAuthMethod::Expansion> operator|(QgsAuthMethod::Expansion f1, QFlags<QgsAuthMethod::Expansion> f2);

@@ -44,6 +44,7 @@ QgsAuthBasicMethod::QgsAuthBasicMethod()
<< QStringLiteral( "wms" )
<< QStringLiteral( "ogr" )
<< QStringLiteral( "proxy" ) );

}

QString QgsAuthBasicMethod::key() const
@@ -65,7 +66,7 @@ bool QgsAuthBasicMethod::updateNetworkRequest( QNetworkRequest &request, const Q
const QString &dataprovider )
{
Q_UNUSED( dataprovider )

QMutexLocker locker( &mMutex );
QgsAuthMethodConfig mconfig = getMethodConfig( authcfg );
if ( !mconfig.isValid() )
{
@@ -86,6 +87,8 @@ bool QgsAuthBasicMethod::updateNetworkRequest( QNetworkRequest &request, const Q
bool QgsAuthBasicMethod::updateDataSourceUriItems( QStringList &connectionItems, const QString &authcfg,
const QString &dataprovider )
{
Q_UNUSED( dataprovider )
QMutexLocker locker( &mMutex );
QgsAuthMethodConfig mconfig = getMethodConfig( authcfg );
if ( !mconfig.isValid() )
{
@@ -277,6 +280,7 @@ bool QgsAuthBasicMethod::updateDataSourceUriItems( QStringList &connectionItems,
bool QgsAuthBasicMethod::updateNetworkProxy( QNetworkProxy &proxy, const QString &authcfg, const QString &dataprovider )
{
Q_UNUSED( dataprovider )
QMutexLocker locker( &mMutex );

QgsAuthMethodConfig mconfig = getMethodConfig( authcfg );
if ( !mconfig.isValid() )
@@ -298,6 +302,7 @@ bool QgsAuthBasicMethod::updateNetworkProxy( QNetworkProxy &proxy, const QString

void QgsAuthBasicMethod::updateMethodConfig( QgsAuthMethodConfig &mconfig )
{
QMutexLocker locker( &mMutex );
if ( mconfig.hasConfig( QStringLiteral( "oldconfigstyle" ) ) )
{
QgsDebugMsg( "Updating old style auth method config" );
@@ -319,7 +324,7 @@ void QgsAuthBasicMethod::clearCachedConfig( const QString &authcfg )

QgsAuthMethodConfig QgsAuthBasicMethod::getMethodConfig( const QString &authcfg, bool fullconfig )
{
QMutexLocker locker( &mConfigMutex );
QMutexLocker locker( &mMutex );
QgsAuthMethodConfig mconfig;

// check if it is cached
@@ -338,22 +343,21 @@ QgsAuthMethodConfig QgsAuthBasicMethod::getMethodConfig( const QString &authcfg,
}

// cache bundle
locker.unlock();
putMethodConfig( authcfg, mconfig );

return mconfig;
}

void QgsAuthBasicMethod::putMethodConfig( const QString &authcfg, const QgsAuthMethodConfig &mconfig )
{
QMutexLocker locker( &mConfigMutex );
QMutexLocker locker( &mMutex );
QgsDebugMsg( QString( "Putting basic config for authcfg: %1" ).arg( authcfg ) );
sAuthConfigCache.insert( authcfg, mconfig );
}

void QgsAuthBasicMethod::removeMethodConfig( const QString &authcfg )
{
QMutexLocker locker( &mConfigMutex );
QMutexLocker locker( &mMutex );
if ( sAuthConfigCache.contains( authcfg ) )
{
sAuthConfigCache.remove( authcfg );
@@ -63,7 +63,6 @@ class QgsAuthBasicMethod : public QgsAuthMethod

static QMap<QString, QgsAuthMethodConfig> sAuthConfigCache;

QMutex mConfigMutex;
};

#endif // QGSAUTHBASICMETHOD_H
@@ -52,7 +52,7 @@ QgsAuthIdentCertMethod::QgsAuthIdentCertMethod()

QgsAuthIdentCertMethod::~QgsAuthIdentCertMethod()
{
QMutexLocker locker( &mConfigMutex );
QMutexLocker locker( &mMutex );
qDeleteAll( sPkiConfigBundleCache );
sPkiConfigBundleCache.clear();
}
@@ -76,6 +76,7 @@ bool QgsAuthIdentCertMethod::updateNetworkRequest( QNetworkRequest &request, con
const QString &dataprovider )
{
Q_UNUSED( dataprovider )
QMutexLocker locker( &mMutex );

// TODO: is this too restrictive, to intercept only HTTPS connections?
if ( request.url().scheme().toLower() != QLatin1String( "https" ) )
@@ -110,6 +111,7 @@ bool QgsAuthIdentCertMethod::updateDataSourceUriItems( QStringList &connectionIt
const QString &dataprovider )
{
Q_UNUSED( dataprovider )
QMutexLocker locker( &mMutex );

QgsDebugMsg( QString( "Update URI items for authcfg: %1" ).arg( authcfg ) );

@@ -208,6 +210,7 @@ void QgsAuthIdentCertMethod::clearCachedConfig( const QString &authcfg )

void QgsAuthIdentCertMethod::updateMethodConfig( QgsAuthMethodConfig &mconfig )
{
QMutexLocker locker( &mMutex );
if ( mconfig.hasConfig( QStringLiteral( "oldconfigstyle" ) ) )
{
QgsDebugMsg( "Updating old style auth method config" );
@@ -222,7 +225,7 @@ void QgsAuthIdentCertMethod::updateMethodConfig( QgsAuthMethodConfig &mconfig )

QgsPkiConfigBundle *QgsAuthIdentCertMethod::getPkiConfigBundle( const QString &authcfg )
{
QMutexLocker locker( &mConfigMutex );
QMutexLocker locker( &mMutex );
QgsPkiConfigBundle *bundle = nullptr;

// check if it is cached
@@ -267,7 +270,6 @@ QgsPkiConfigBundle *QgsAuthIdentCertMethod::getPkiConfigBundle( const QString &a

bundle = new QgsPkiConfigBundle( mconfig, clientcert, clientkey );

locker.unlock();
// cache bundle
putPkiConfigBundle( authcfg, bundle );

@@ -276,14 +278,14 @@ QgsPkiConfigBundle *QgsAuthIdentCertMethod::getPkiConfigBundle( const QString &a

void QgsAuthIdentCertMethod::putPkiConfigBundle( const QString &authcfg, QgsPkiConfigBundle *pkibundle )
{
QMutexLocker locker( &mConfigMutex );
QMutexLocker locker( &mMutex );
QgsDebugMsg( QString( "Putting PKI bundle for authcfg %1" ).arg( authcfg ) );
sPkiConfigBundleCache.insert( authcfg, pkibundle );
}

void QgsAuthIdentCertMethod::removePkiConfigBundle( const QString &authcfg )
{
QMutexLocker locker( &mConfigMutex );
QMutexLocker locker( &mMutex );
if ( sPkiConfigBundleCache.contains( authcfg ) )
{
QgsPkiConfigBundle *pkibundle = sPkiConfigBundleCache.take( authcfg );
@@ -59,7 +59,6 @@ class QgsAuthIdentCertMethod : public QgsAuthMethod

static QMap<QString, QgsPkiConfigBundle *> sPkiConfigBundleCache;

QMutex mConfigMutex;
};

#endif // QGSAUTHIDENTCERTMETHOD_H
@@ -53,7 +53,7 @@ QgsAuthPkiPathsMethod::QgsAuthPkiPathsMethod()

QgsAuthPkiPathsMethod::~QgsAuthPkiPathsMethod()
{
QMutexLocker locker( &mConfigMutex );
QMutexLocker locker( &mMutex );
qDeleteAll( sPkiConfigBundleCache );
sPkiConfigBundleCache.clear();
}
@@ -77,6 +77,7 @@ bool QgsAuthPkiPathsMethod::updateNetworkRequest( QNetworkRequest &request, cons
const QString &dataprovider )
{
Q_UNUSED( dataprovider )
QMutexLocker locker( &mMutex );

// TODO: is this too restrictive, to intercept only HTTPS connections?
if ( request.url().scheme().toLower() != QLatin1String( "https" ) )
@@ -124,6 +125,7 @@ bool QgsAuthPkiPathsMethod::updateDataSourceUriItems( QStringList &connectionIte
const QString &dataprovider )
{
Q_UNUSED( dataprovider )
QMutexLocker locker( &mMutex );

QgsDebugMsg( QString( "Update URI items for authcfg: %1" ).arg( authcfg ) );

@@ -237,11 +239,13 @@ bool QgsAuthPkiPathsMethod::updateDataSourceUriItems( QStringList &connectionIte

void QgsAuthPkiPathsMethod::clearCachedConfig( const QString &authcfg )
{
QMutexLocker locker( &mMutex );
removePkiConfigBundle( authcfg );
}

void QgsAuthPkiPathsMethod::updateMethodConfig( QgsAuthMethodConfig &mconfig )
{
QMutexLocker locker( &mMutex );
if ( mconfig.hasConfig( QStringLiteral( "oldconfigstyle" ) ) )
{
QgsDebugMsg( "Updating old style auth method config" );
@@ -258,7 +262,7 @@ void QgsAuthPkiPathsMethod::updateMethodConfig( QgsAuthMethodConfig &mconfig )

QgsPkiConfigBundle *QgsAuthPkiPathsMethod::getPkiConfigBundle( const QString &authcfg )
{
QMutexLocker locker( &mConfigMutex );
QMutexLocker locker( &mMutex );
QgsPkiConfigBundle *bundle = nullptr;

// check if it is cached
@@ -301,7 +305,6 @@ QgsPkiConfigBundle *QgsAuthPkiPathsMethod::getPkiConfigBundle( const QString &au

bundle = new QgsPkiConfigBundle( mconfig, clientcert, clientkey, QgsAuthCertUtils::casFromFile( mconfig.config( QStringLiteral( "certpath" ) ) ) );

locker.unlock();
// cache bundle
putPkiConfigBundle( authcfg, bundle );

@@ -310,14 +313,14 @@ QgsPkiConfigBundle *QgsAuthPkiPathsMethod::getPkiConfigBundle( const QString &au

void QgsAuthPkiPathsMethod::putPkiConfigBundle( const QString &authcfg, QgsPkiConfigBundle *pkibundle )
{
QMutexLocker locker( &mConfigMutex );
QMutexLocker locker( &mMutex );
QgsDebugMsg( QString( "Putting PKI bundle for authcfg %1" ).arg( authcfg ) );
sPkiConfigBundleCache.insert( authcfg, pkibundle );
}

void QgsAuthPkiPathsMethod::removePkiConfigBundle( const QString &authcfg )
{
QMutexLocker locker( &mConfigMutex );
QMutexLocker locker( &mMutex );
if ( sPkiConfigBundleCache.contains( authcfg ) )
{
QgsPkiConfigBundle *pkibundle = sPkiConfigBundleCache.take( authcfg );
@@ -59,8 +59,6 @@ class QgsAuthPkiPathsMethod : public QgsAuthMethod

static QMap<QString, QgsPkiConfigBundle *> sPkiConfigBundleCache;

QMutex mConfigMutex;

};

#endif // QGSAUTHPKIPATHSMETHOD_H
@@ -53,7 +53,6 @@ QgsAuthPkcs12Method::QgsAuthPkcs12Method()

QgsAuthPkcs12Method::~QgsAuthPkcs12Method()
{
QMutexLocker locker( &mConfigMutex );
qDeleteAll( sPkiConfigBundleCache );
sPkiConfigBundleCache.clear();
}
@@ -77,6 +76,7 @@ bool QgsAuthPkcs12Method::updateNetworkRequest( QNetworkRequest &request, const
const QString &dataprovider )
{
Q_UNUSED( dataprovider )
QMutexLocker locker( &mMutex );

// TODO: is this too restrictive, to intercept only HTTPS connections?
if ( request.url().scheme().toLower() != QLatin1String( "https" ) )
@@ -124,6 +124,7 @@ bool QgsAuthPkcs12Method::updateDataSourceUriItems( QStringList &connectionItems
const QString &dataprovider )
{
Q_UNUSED( dataprovider )
QMutexLocker locker( &mMutex );

QgsDebugMsg( QString( "Update URI items for authcfg: %1" ).arg( authcfg ) );

@@ -237,11 +238,13 @@ bool QgsAuthPkcs12Method::updateDataSourceUriItems( QStringList &connectionItems

void QgsAuthPkcs12Method::clearCachedConfig( const QString &authcfg )
{
QMutexLocker locker( &mMutex );
removePkiConfigBundle( authcfg );
}

void QgsAuthPkcs12Method::updateMethodConfig( QgsAuthMethodConfig &mconfig )
{
QMutexLocker locker( &mMutex );
if ( mconfig.hasConfig( QStringLiteral( "oldconfigstyle" ) ) )
{
QgsDebugMsg( "Updating old style auth method config" );
@@ -257,7 +260,7 @@ void QgsAuthPkcs12Method::updateMethodConfig( QgsAuthMethodConfig &mconfig )

QgsPkiConfigBundle *QgsAuthPkcs12Method::getPkiConfigBundle( const QString &authcfg )
{
QMutexLocker locker( &mConfigMutex );
QMutexLocker locker( &mMutex );
QgsPkiConfigBundle *bundle = nullptr;

// check if it is cached
@@ -331,14 +334,14 @@ QgsPkiConfigBundle *QgsAuthPkcs12Method::getPkiConfigBundle( const QString &auth

void QgsAuthPkcs12Method::putPkiConfigBundle( const QString &authcfg, QgsPkiConfigBundle *pkibundle )
{
QMutexLocker locker( &mConfigMutex );
QMutexLocker locker( &mMutex );
QgsDebugMsg( QString( "Putting PKI bundle for authcfg %1" ).arg( authcfg ) );
sPkiConfigBundleCache.insert( authcfg, pkibundle );
}

void QgsAuthPkcs12Method::removePkiConfigBundle( const QString &authcfg )
{
QMutexLocker locker( &mConfigMutex );
QMutexLocker locker( &mMutex );
if ( sPkiConfigBundleCache.contains( authcfg ) )
{
QgsPkiConfigBundle *pkibundle = sPkiConfigBundleCache.take( authcfg );
@@ -60,7 +60,6 @@ class QgsAuthPkcs12Method : public QgsAuthMethod

static QMap<QString, QgsPkiConfigBundle *> sPkiConfigBundleCache;

QMutex mConfigMutex;
};

#endif // QGSAUTHPKCS12METHOD_H
@@ -23,6 +23,7 @@
#include <QNetworkRequest>
#include <QStringList>
#include <QUrl>
#include <QMutex>

#include "qgis_core.h"

@@ -174,8 +175,10 @@ class CORE_EXPORT QgsAuthMethod : public QObject
explicit QgsAuthMethod()
: mExpansions( QgsAuthMethod::Expansions( nullptr ) )
, mDataProviders( QStringList() )
, mMutex( QMutex::RecursionMode::Recursive )
{}


//! Tag signifying that this is an authentcation method (e.g. for use as title in message log panel output)
static QString authMethodTag() { return QObject::tr( "Authentication method" ); }

@@ -190,6 +193,8 @@ class CORE_EXPORT QgsAuthMethod : public QObject
QgsAuthMethod::Expansions mExpansions;
QStringList mDataProviders;
int mVersion = 0;
QMutex mMutex;

};
Q_DECLARE_OPERATORS_FOR_FLAGS( QgsAuthMethod::Expansions )

0 comments on commit d590e98

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