[auth] Code style, unique ptrs and documentation

This commit is contained in:
Alessandro Pasotti 2018-06-26 15:13:00 +02:00
parent e02845ae2f
commit ab0c58d86a
8 changed files with 379 additions and 241 deletions

View File

@ -57,6 +57,8 @@ IF(WITH_APIDOC)
${CMAKE_SOURCE_DIR}/src/core/3d
${CMAKE_SOURCE_DIR}/src/core/annotations
${CMAKE_SOURCE_DIR}/src/core/auth
${CMAKE_SOURCE_DIR}/src/auth
${CMAKE_SOURCE_DIR}/src/auth/oauth2
${CMAKE_SOURCE_DIR}/src/core/diagram
${CMAKE_SOURCE_DIR}/src/core/dxf
${CMAKE_SOURCE_DIR}/src/core/effects

View File

@ -42,3 +42,14 @@ Contains classes related to implementation of QGIS plugins.
The QgsQuick library is built on top of the CORE library and Qt Quick/QML framework. It adds reusable GUI Quick Components, mainly for mobile devices.
*/
*/
/** @defgroup auth_plugins Authentication plugins
The QGIS authentication manager uses authentication plugins to provide most common authentication methods.
*/

View File

@ -24,15 +24,7 @@
QgsAuthOAuth2Config::QgsAuthOAuth2Config( QObject *parent )
: QObject( parent )
, mVersion( 1 )
, mConfigType( Custom )
, mGrantFlow( AuthCode )
, mRedirectPort( 7070 )
, mPersistToken( false )
, mAccessMethod( Header )
, mRequestTimeout( 30 ) // in seconds
, mQueryPairs( QVariantMap() )
, mValid( false )
{
// internal signal bounces
@ -66,184 +58,203 @@ QgsAuthOAuth2Config::QgsAuthOAuth2Config( QObject *parent )
validateConfig();
}
QgsAuthOAuth2Config::~QgsAuthOAuth2Config()
{
}
void QgsAuthOAuth2Config::setId( const QString &value )
{
QString preval( mId );
mId = value;
if ( preval != value ) emit idChanged( mId );
if ( preval != value )
emit idChanged( mId );
}
void QgsAuthOAuth2Config::setVersion( int value )
{
int preval( mVersion );
mVersion = value;
if ( preval != value ) emit versionChanged( mVersion );
if ( preval != value )
emit versionChanged( mVersion );
}
void QgsAuthOAuth2Config::setConfigType( QgsAuthOAuth2Config::ConfigType value )
{
ConfigType preval( mConfigType );
mConfigType = value;
if ( preval != value ) emit configTypeChanged( mConfigType );
if ( preval != value )
emit configTypeChanged( mConfigType );
}
void QgsAuthOAuth2Config::setGrantFlow( QgsAuthOAuth2Config::GrantFlow value )
{
GrantFlow preval( mGrantFlow );
mGrantFlow = value;
if ( preval != value ) emit grantFlowChanged( mGrantFlow );
if ( preval != value )
emit grantFlowChanged( mGrantFlow );
}
void QgsAuthOAuth2Config::setName( const QString &value )
{
QString preval( mName );
mName = value;
if ( preval != value ) emit nameChanged( mName );
if ( preval != value )
emit nameChanged( mName );
}
void QgsAuthOAuth2Config::setDescription( const QString &value )
{
QString preval( mDescription );
mDescription = value;
if ( preval != value ) emit descriptionChanged( mDescription );
if ( preval != value )
emit descriptionChanged( mDescription );
}
void QgsAuthOAuth2Config::setRequestUrl( const QString &value )
{
QString preval( mRequestUrl );
mRequestUrl = value;
if ( preval != value ) emit requestUrlChanged( mRequestUrl );
if ( preval != value )
emit requestUrlChanged( mRequestUrl );
}
void QgsAuthOAuth2Config::setTokenUrl( const QString &value )
{
QString preval( mTokenUrl );
mTokenUrl = value;
if ( preval != value ) emit tokenUrlChanged( mTokenUrl );
if ( preval != value )
emit tokenUrlChanged( mTokenUrl );
}
void QgsAuthOAuth2Config::setRefreshTokenUrl( const QString &value )
{
QString preval( mRefreshTokenUrl );
mRefreshTokenUrl = value;
if ( preval != value ) emit refreshTokenUrlChanged( mRefreshTokenUrl );
if ( preval != value )
emit refreshTokenUrlChanged( mRefreshTokenUrl );
}
void QgsAuthOAuth2Config::setRedirectUrl( const QString &value )
{
QString preval( mRedirectURL );
mRedirectURL = value;
if ( preval != value ) emit redirectUrlChanged( mRedirectURL );
if ( preval != value )
emit redirectUrlChanged( mRedirectURL );
}
void QgsAuthOAuth2Config::setRedirectPort( int value )
{
int preval( mRedirectPort );
mRedirectPort = value;
if ( preval != value ) emit redirectPortChanged( mRedirectPort );
if ( preval != value )
emit redirectPortChanged( mRedirectPort );
}
void QgsAuthOAuth2Config::setClientId( const QString &value )
{
QString preval( mClientId );
mClientId = value;
if ( preval != value ) emit clientIdChanged( mClientId );
if ( preval != value )
emit clientIdChanged( mClientId );
}
void QgsAuthOAuth2Config::setClientSecret( const QString &value )
{
QString preval( mClientSecret );
mClientSecret = value;
if ( preval != value ) emit clientSecretChanged( mClientSecret );
if ( preval != value )
emit clientSecretChanged( mClientSecret );
}
void QgsAuthOAuth2Config::setUsername( const QString &value )
{
QString preval( mUsername );
mUsername = value;
if ( preval != value ) emit usernameChanged( mUsername );
if ( preval != value )
emit usernameChanged( mUsername );
}
void QgsAuthOAuth2Config::setPassword( const QString &value )
{
QString preval( mPassword );
mPassword = value;
if ( preval != value ) emit passwordChanged( mPassword );
if ( preval != value )
emit passwordChanged( mPassword );
}
void QgsAuthOAuth2Config::setScope( const QString &value )
{
QString preval( mScope );
mScope = value;
if ( preval != value ) emit scopeChanged( mScope );
if ( preval != value )
emit scopeChanged( mScope );
}
void QgsAuthOAuth2Config::setState( const QString &value )
{
QString preval( mState );
mState = value;
if ( preval != value ) emit stateChanged( mState );
if ( preval != value )
emit stateChanged( mState );
}
void QgsAuthOAuth2Config::setApiKey( const QString &value )
{
QString preval( mApiKey );
mApiKey = value;
if ( preval != value ) emit apiKeyChanged( mApiKey );
if ( preval != value )
emit apiKeyChanged( mApiKey );
}
void QgsAuthOAuth2Config::setPersistToken( bool persist )
{
bool preval( mPersistToken );
mPersistToken = persist;
if ( preval != persist ) emit persistTokenChanged( mPersistToken );
if ( preval != persist )
emit persistTokenChanged( mPersistToken );
}
void QgsAuthOAuth2Config::setAccessMethod( QgsAuthOAuth2Config::AccessMethod value )
{
AccessMethod preval( mAccessMethod );
mAccessMethod = value;
if ( preval != value ) emit accessMethodChanged( mAccessMethod );
if ( preval != value )
emit accessMethodChanged( mAccessMethod );
}
void QgsAuthOAuth2Config::setRequestTimeout( int value )
{
int preval( mRequestTimeout );
mRequestTimeout = value;
if ( preval != value ) emit requestTimeoutChanged( mRequestTimeout );
if ( preval != value )
emit requestTimeoutChanged( mRequestTimeout );
}
void QgsAuthOAuth2Config::setQueryPairs( const QVariantMap &pairs )
{
QVariantMap preval( mQueryPairs );
mQueryPairs = pairs;
if ( preval != pairs ) emit queryPairsChanged( mQueryPairs );
if ( preval != pairs )
emit queryPairsChanged( mQueryPairs );
}
void QgsAuthOAuth2Config::setToDefaults()
{
setId( QString::null );
setId( QString() );
setVersion( 1 );
setConfigType( QgsAuthOAuth2Config::Custom );
setGrantFlow( QgsAuthOAuth2Config::AuthCode );
setName( QString::null );
setDescription( QString::null );
setRequestUrl( QString::null );
setTokenUrl( QString::null );
setRefreshTokenUrl( QString::null );
setRedirectUrl( QString::null );
setName( QString() );
setDescription( QString() );
setRequestUrl( QString() );
setTokenUrl( QString() );
setRefreshTokenUrl( QString() );
setRedirectUrl( QString() );
setRedirectPort( 7070 );
setClientId( QString::null );
setClientSecret( QString::null );
setUsername( QString::null );
setPassword( QString::null );
setScope( QString::null );
setState( QString::null );
setApiKey( QString::null );
setClientId( QString() );
setClientSecret( QString() );
setUsername( QString() );
setPassword( QString() );
setScope( QString() );
setState( QString() );
setApiKey( QString() );
setPersistToken( false );
setAccessMethod( QgsAuthOAuth2Config::Header );
setRequestTimeout( 30 ); // in seconds
@ -313,7 +324,8 @@ void QgsAuthOAuth2Config::validateConfigId( bool needsId )
&& ( needsId ? !id().isEmpty() : true ) );
}
if ( mValid != oldvalid ) emit validityChanged( mValid );
if ( mValid != oldvalid )
emit validityChanged( mValid );
}
bool QgsAuthOAuth2Config::loadConfigTxt(
@ -322,19 +334,21 @@ bool QgsAuthOAuth2Config::loadConfigTxt(
QByteArray errStr;
bool res = false;
if ( format == JSON )
switch ( format )
{
QVariant variant = QJsonWrapper::parseJson( configtxt, &res, &errStr );
if ( !res )
case JSON:
{
QgsDebugMsg( QStringLiteral( "Error parsing JSON: %1" ).arg( QString( errStr ) ) );
return res;
QVariant variant = QJsonWrapper::parseJson( configtxt, &res, &errStr );
if ( !res )
{
QgsDebugMsg( QStringLiteral( "Error parsing JSON: %1" ).arg( QString( errStr ) ) );
return res;
}
QJsonWrapper::qvariant2qobject( variant.toMap(), this );
break;
}
QJsonWrapper::qvariant2qobject( variant.toMap(), this );
}
else
{
QgsDebugMsg( QStringLiteral( "Unsupported output format" ) );
default:
QgsDebugMsg( QStringLiteral( "Unsupported output format" ) );
}
return true;
}
@ -349,25 +363,29 @@ QByteArray QgsAuthOAuth2Config::saveConfigTxt(
if ( !isValid() )
{
QgsDebugMsg( QStringLiteral( "FAILED, config is not valid" ) );
if ( ok ) *ok = res;
if ( ok )
*ok = res;
return out;
}
if ( format == JSON )
switch ( format )
{
QVariantMap variant = QJsonWrapper::qobject2qvariant( this );
out = QJsonWrapper::toJson( variant, &res, &errStr, pretty );
if ( !res )
case JSON:
{
QgsDebugMsg( QStringLiteral( "Error serializing JSON: %1" ).arg( QString( errStr ) ) );
QVariantMap variant = QJsonWrapper::qobject2qvariant( this );
out = QJsonWrapper::toJson( variant, &res, &errStr, pretty );
if ( !res )
{
QgsDebugMsg( QStringLiteral( "Error serializing JSON: %1" ).arg( QString( errStr ) ) );
}
break;
}
}
else
{
QgsDebugMsg( QStringLiteral( "Unsupported output format" ) );
default:
QgsDebugMsg( QStringLiteral( "Unsupported output format" ) );
}
if ( ok ) *ok = res;
if ( ok )
*ok = res;
return out;
}
@ -411,20 +429,21 @@ QByteArray QgsAuthOAuth2Config::serializeFromVariant(
QByteArray errStr;
bool res = false;
if ( format == JSON )
switch ( format )
{
out = QJsonWrapper::toJson( variant, &res, &errStr, pretty );
if ( !res )
{
QgsDebugMsg( QStringLiteral( "Error serializing JSON: %1" ).arg( QString( errStr ) ) );
}
}
else
{
QgsDebugMsg( QStringLiteral( "Unsupported output format" ) );
case JSON:
out = QJsonWrapper::toJson( variant, &res, &errStr, pretty );
if ( !res )
{
QgsDebugMsg( QStringLiteral( "Error serializing JSON: %1" ).arg( QString( errStr ) ) );
}
break;
default:
QgsDebugMsg( QStringLiteral( "Unsupported output format" ) );
}
if ( ok ) *ok = res;
if ( ok )
*ok = res;
return out;
}
@ -438,36 +457,42 @@ QVariantMap QgsAuthOAuth2Config::variantFromSerialized(
QByteArray errStr;
bool res = false;
if ( format == JSON )
switch ( format )
{
QVariant var = QJsonWrapper::parseJson( serial, &res, &errStr );
if ( !res )
case JSON:
{
QgsDebugMsg( QStringLiteral( "Error parsing JSON to variant: %1" ).arg( QString( errStr ) ) );
if ( ok ) *ok = res;
return vmap;
}
QVariant var = QJsonWrapper::parseJson( serial, &res, &errStr );
if ( !res )
{
QgsDebugMsg( QStringLiteral( "Error parsing JSON to variant: %1" ).arg( QString( errStr ) ) );
if ( ok )
*ok = res;
return vmap;
}
if ( !var.isValid() || var.isNull() )
{
QgsDebugMsg( QStringLiteral( "Error parsing JSON to variant: %1" ).arg( "invalid or null" ) );
if ( ok ) *ok = res;
return vmap;
if ( var.isNull() )
{
QgsDebugMsg( QStringLiteral( "Error parsing JSON to variant: %1" ).arg( "invalid or null" ) );
if ( ok )
*ok = res;
return vmap;
}
vmap = var.toMap();
if ( vmap.isEmpty() )
{
QgsDebugMsg( QStringLiteral( "Error parsing JSON to variantmap: %1" ).arg( "map empty" ) );
if ( ok )
*ok = res;
return vmap;
}
break;
}
vmap = var.toMap();
if ( vmap.isEmpty() )
{
QgsDebugMsg( QStringLiteral( "Error parsing JSON to variantmap: %1" ).arg( "map empty" ) );
if ( ok ) *ok = res;
return vmap;
}
}
else
{
QgsDebugMsg( QStringLiteral( "Unsupported output format" ) );
default:
QgsDebugMsg( QStringLiteral( "Unsupported output format" ) );
}
if ( ok ) *ok = res;
if ( ok )
*ok = res;
return vmap;
}
@ -525,20 +550,21 @@ QList<QgsAuthOAuth2Config *> QgsAuthOAuth2Config::loadOAuth2Configs(
bool res = false;
QStringList namefilters;
if ( format == JSON )
switch ( format )
{
namefilters << QStringLiteral( "*.json" );
}
else
{
QgsDebugMsg( QStringLiteral( "Unsupported output format" ) );
if ( ok ) *ok = res;
return configs;
case JSON:
namefilters << QStringLiteral( "*.json" );
break;
default:
QgsDebugMsg( QStringLiteral( "Unsupported output format" ) );
if ( ok )
*ok = res;
return configs;
}
QDir configdir( configdirectory );
configdir.setNameFilters( namefilters );
QStringList configfiles = configdir.entryList( namefilters );
const QStringList configfiles = configdir.entryList( namefilters );
if ( configfiles.size() > 0 )
{
@ -553,10 +579,10 @@ QList<QgsAuthOAuth2Config *> QgsAuthOAuth2Config::loadOAuth2Configs(
}
// Add entries
Q_FOREACH ( const QString &configfile, configfiles )
for ( const auto &configfile : configfiles )
{
QByteArray configtxt;
QFile cfile( configdir.path() + QStringLiteral( "/" ) + configfile );
QFile cfile( configdir.path() + '/' + configfile );
if ( cfile.exists() )
{
bool ret = cfile.open( QIODevice::ReadOnly | QIODevice::Text );
@ -602,20 +628,21 @@ QgsStringMap QgsAuthOAuth2Config::mapOAuth2Configs(
bool res = false;
QStringList namefilters;
if ( format == JSON )
switch ( format )
{
namefilters << QStringLiteral( "*.json" );
}
else
{
QgsDebugMsg( QStringLiteral( "Unsupported output format" ) );
if ( ok ) *ok = res;
return configs;
case JSON:
namefilters << QStringLiteral( "*.json" );
break;
default:
QgsDebugMsg( QStringLiteral( "Unsupported output format" ) );
if ( ok )
*ok = res;
return configs;
}
QDir configdir( configdirectory );
configdir.setNameFilters( namefilters );
QStringList configfiles = configdir.entryList( namefilters );
const QStringList configfiles = configdir.entryList( namefilters );
if ( configfiles.size() > 0 )
{
@ -625,15 +652,16 @@ QgsStringMap QgsAuthOAuth2Config::mapOAuth2Configs(
else
{
QgsDebugMsg( QStringLiteral( "No config files found in: %1" ).arg( configdir.path() ) );
if ( ok ) *ok = res;
if ( ok )
*ok = res;
return configs;
}
// Add entries
Q_FOREACH ( const QString &configfile, configfiles )
for ( const auto &configfile : configfiles )
{
QByteArray configtxt;
QFile cfile( configdir.path() + QStringLiteral( "/" ) + configfile );
QFile cfile( configdir.path() + '/' + configfile );
if ( cfile.exists() )
{
bool ret = cfile.open( QIODevice::ReadOnly | QIODevice::Text );
@ -655,24 +683,22 @@ QgsStringMap QgsAuthOAuth2Config::mapOAuth2Configs(
}
// validate the config before caching it
QgsAuthOAuth2Config *config = new QgsAuthOAuth2Config( parent );
std::unique_ptr<QgsAuthOAuth2Config, std::function<void( QgsAuthOAuth2Config * )> > config( new QgsAuthOAuth2Config( parent ), []( QgsAuthOAuth2Config * cfg ) { cfg->deleteLater( );} );
if ( !config->loadConfigTxt( configtxt, format ) )
{
QgsDebugMsg( QStringLiteral( "FAILED to load config: %1" ).arg( configfile ) );
config->deleteLater();
continue;
}
if ( config->id().isEmpty() )
{
QgsDebugMsg( QStringLiteral( "NO ID SET for config: %1" ).arg( configfile ) );
config->deleteLater();
continue;
}
configs.insert( config->id(), configtxt );
config->deleteLater();
}
if ( ok ) *ok = true;
if ( ok )
*ok = true;
return configs;
}
@ -693,7 +719,7 @@ QgsStringMap QgsAuthOAuth2Config::mappedOAuth2ConfigsCache( QObject *parent, con
configdirs << extradir;
}
Q_FOREACH ( const QString &configdir, configdirs )
for ( const auto &configdir : qgis::as_const( configdirs ) )
{
QFileInfo configdirinfo( configdir );
if ( !configdirinfo.exists() || !configdirinfo.isDir() )

View File

@ -22,7 +22,10 @@
#include "qgis.h"
/**
* The QgsAuthOAuth2Config class stores the configuration for OAuth2 authentication plugin
* \ingroup auth_plugins
*/
class QgsAuthOAuth2Config : public QObject
{
Q_OBJECT
@ -30,15 +33,39 @@ class QgsAuthOAuth2Config : public QObject
Q_ENUMS( GrantFlow )
Q_ENUMS( ConfigFormat )
Q_ENUMS( AccessMethod )
Q_PROPERTY( QString id READ id WRITE setId NOTIFY idChanged )
Q_PROPERTY( int version READ version WRITE setVersion NOTIFY versionChanged )
Q_PROPERTY( ConfigType configType READ configType WRITE setConfigType NOTIFY configTypeChanged )
Q_PROPERTY( GrantFlow grantFlow READ grantFlow WRITE setGrantFlow NOTIFY grantFlowChanged )
Q_PROPERTY( QString name READ name WRITE setName NOTIFY nameChanged )
Q_PROPERTY( QString description READ description WRITE setDescription NOTIFY descriptionChanged )
Q_PROPERTY( QString requestUrl READ requestUrl WRITE setRequestUrl NOTIFY requestUrlChanged )
Q_PROPERTY( QString tokenUrl READ tokenUrl WRITE setTokenUrl NOTIFY tokenUrlChanged )
Q_PROPERTY( QString refreshTokenUrl READ refreshTokenUrl WRITE setRefreshTokenUrl NOTIFY refreshTokenUrlChanged )
Q_PROPERTY( QString redirectUrl READ redirectUrl WRITE setRedirectUrl NOTIFY redirectUrlChanged )
Q_PROPERTY( int redirectPort READ redirectPort WRITE setRedirectPort NOTIFY redirectPortChanged )
Q_PROPERTY( QString clientId READ clientId WRITE setClientId NOTIFY clientIdChanged )
Q_PROPERTY( QString clientSecret READ clientSecret WRITE setClientSecret NOTIFY clientSecretChanged )
Q_PROPERTY( QString username READ username WRITE setUsername NOTIFY usernameChanged )
Q_PROPERTY( QString password READ password WRITE setPassword NOTIFY passwordChanged )
Q_PROPERTY( QString scope READ scope WRITE setScope NOTIFY scopeChanged )
Q_PROPERTY( QString state READ state WRITE setState NOTIFY stateChanged )
Q_PROPERTY( QString apiKey READ apiKey WRITE setApiKey NOTIFY apiKeyChanged )
Q_PROPERTY( bool persistToken READ persistToken WRITE setPersistToken NOTIFY persistTokenChanged )
Q_PROPERTY( AccessMethod accessMethod READ accessMethod WRITE setAccessMethod NOTIFY accessMethodChanged )
Q_PROPERTY( int requestTimeout READ requestTimeout WRITE setRequestTimeout NOTIFY requestTimeoutChanged )
Q_PROPERTY( QVariantMap queryPairs READ queryPairs WRITE setQueryPairs NOTIFY queryPairsChanged )
public:
//! Configuration type
enum ConfigType
{
Predefined,
Custom,
};
//! OAuth2 grant flow
enum GrantFlow
{
AuthCode, //!< @see http://tools.ietf.org/html/rfc6749#section-4.1
@ -46,11 +73,13 @@ class QgsAuthOAuth2Config : public QObject
ResourceOwner, //!< @see http://tools.ietf.org/html/rfc6749#section-4.3
};
//! Configuration format for serialize/unserialize operations
enum ConfigFormat
{
JSON,
};
//! Access method
enum AccessMethod
{
Header,
@ -60,94 +89,70 @@ class QgsAuthOAuth2Config : public QObject
explicit QgsAuthOAuth2Config( QObject *parent = nullptr );
~QgsAuthOAuth2Config();
//! Unique ID
Q_PROPERTY( QString id READ id WRITE setId NOTIFY idChanged )
QString id() const { return mId; }
//! Increment this if method is significantly updated, allow updater code to be written
Q_PROPERTY( int version READ version WRITE setVersion NOTIFY versionChanged )
int version() const { return mVersion; }
//! Configuration type
Q_PROPERTY( ConfigType configType READ configType WRITE setConfigType NOTIFY configTypeChanged )
ConfigType configType() const { return mConfigType; }
//! Authorization flow
Q_PROPERTY( GrantFlow grantFlow READ grantFlow WRITE setGrantFlow NOTIFY grantFlowChanged )
GrantFlow grantFlow() const { return mGrantFlow; }
//! Configuration name
Q_PROPERTY( QString name READ name WRITE setName NOTIFY nameChanged )
QString name() const { return mName; }
//! Configuration description
Q_PROPERTY( QString description READ description WRITE setDescription NOTIFY descriptionChanged )
QString description() const { return mDescription; }
//!
Q_PROPERTY( QString requestUrl READ requestUrl WRITE setRequestUrl NOTIFY requestUrlChanged )
//! Request url
QString requestUrl() const { return mRequestUrl; }
//!
Q_PROPERTY( QString tokenUrl READ tokenUrl WRITE setTokenUrl NOTIFY tokenUrlChanged )
//! Token url
QString tokenUrl() const { return mTokenUrl; }
//!
Q_PROPERTY( QString refreshTokenUrl READ refreshTokenUrl WRITE setRefreshTokenUrl NOTIFY refreshTokenUrlChanged )
//! Refresh token url
QString refreshTokenUrl() const { return mRefreshTokenUrl; }
//!
Q_PROPERTY( QString redirectUrl READ redirectUrl WRITE setRedirectUrl NOTIFY redirectUrlChanged )
//! Redirect url
QString redirectUrl() const { return mRedirectURL; }
//!
Q_PROPERTY( int redirectPort READ redirectPort WRITE setRedirectPort NOTIFY redirectPortChanged )
//! Redirect port
int redirectPort() const { return mRedirectPort; }
//!
Q_PROPERTY( QString clientId READ clientId WRITE setClientId NOTIFY clientIdChanged )
//! Client id
QString clientId() const { return mClientId; }
//!
Q_PROPERTY( QString clientSecret READ clientSecret WRITE setClientSecret NOTIFY clientSecretChanged )
//! Client secret
QString clientSecret() const { return mClientSecret; }
//! Resource owner username
Q_PROPERTY( QString username READ username WRITE setUsername NOTIFY usernameChanged )
QString username() const { return mUsername; }
//! Resource owner password
Q_PROPERTY( QString password READ password WRITE setPassword NOTIFY passwordChanged )
QString password() const { return mPassword; }
//! Scope of authentication
Q_PROPERTY( QString scope READ scope WRITE setScope NOTIFY scopeChanged )
QString scope() const { return mScope; }
//! State passed with request
Q_PROPERTY( QString state READ state WRITE setState NOTIFY stateChanged )
QString state() const { return mState; }
//!
Q_PROPERTY( QString apiKey READ apiKey WRITE setApiKey NOTIFY apiKeyChanged )
//! API key
QString apiKey() const { return mApiKey; }
//!
Q_PROPERTY( bool persistToken READ persistToken WRITE setPersistToken NOTIFY persistTokenChanged )
//! Return true if the token is persistant
bool persistToken() const { return mPersistToken; }
//!
Q_PROPERTY( AccessMethod accessMethod READ accessMethod WRITE setAccessMethod NOTIFY accessMethodChanged )
//! Access method
AccessMethod accessMethod() const { return mAccessMethod; }
//!
Q_PROPERTY( int requestTimeout READ requestTimeout WRITE setRequestTimeout NOTIFY requestTimeoutChanged )
//! Request timeout
int requestTimeout() const { return mRequestTimeout; }
//!
Q_PROPERTY( QVariantMap queryPairs READ queryPairs WRITE setQueryPairs NOTIFY queryPairsChanged )
//! Query pairs
QVariantMap queryPairs() const { return mQueryPairs; }
//! Operator used to compare configs' equality
@ -159,7 +164,7 @@ class QgsAuthOAuth2Config : public QObject
//! Check whether config is valid, then return it
bool isValid() const;
//! @see http://tools.ietf.org/html/rfc6749 for required data per flow
//! \see http://tools.ietf.org/html/rfc6749 for required data per flow
void validateConfigId( bool needsId = false );
//! Load a string (e.g. JSON) of a config
@ -168,16 +173,29 @@ class QgsAuthOAuth2Config : public QObject
//! Save a config to a string (e.g. JSON)
QByteArray saveConfigTxt( ConfigFormat format = JSON, bool pretty = false, bool *ok = nullptr ) const;
//!
//! Return the configuration as a QVariant map
QVariantMap mappedProperties() const;
//!
/**
* Serialize the configuration \a variant according to \a format
* \param variant map where configuration is stored
* \param format output format
* \param pretty indentation in output
* \param ok is set to false in case something goes wrong, true otherwise
* \return serialized config
*/
static QByteArray serializeFromVariant( const QVariantMap &variant,
ConfigFormat format = JSON,
bool pretty = false,
bool *ok = nullptr );
//!
/**
* Unserialize the configuration in \a serial according to \a format
* \param serial serialized configuration
* \param format output format
* \param ok is set to false in case something goes wrong, true otherwise
* \return config map
*/
static QVariantMap variantFromSerialized( const QByteArray &serial,
ConfigFormat format = JSON,
bool *ok = nullptr );
@ -205,100 +223,145 @@ class QgsAuthOAuth2Config : public QObject
//! Load and parse standard directories of configs (e.g. JSON) to a mapped cache
static QgsStringMap mappedOAuth2ConfigsCache( QObject *parent, const QString &extradir = QString::null );
//!
//! Path where config is stored
static QString oauth2ConfigsPkgDataDir();
//!
//! Path where user settings are stored
static QString oauth2ConfigsUserSettingsDir();
//!
//! User readable name of the \a configtype
static QString configTypeString( ConfigType configtype );
//!
//! User readable name of the grant \a flow
static QString grantFlowString( GrantFlow flow );
//!
//! User readable name of the access \a method
static QString accessMethodString( AccessMethod method );
//!
//! Path of the token cache \a temporary directory
static QString tokenCacheDirectory( bool temporary = false );
//!
//! Path of the token cache file, with optional \a suffix
static QString tokenCacheFile( const QString &suffix = QString::null );
//!
//! Path of the token cache file, with optional \a suffix and \a temporary flag
static QString tokenCachePath( const QString &suffix = QString::null, bool temporary = false );
public slots:
//! Set the id to \a value
void setId( const QString &value );
//! Set version to \a value
void setVersion( int value );
//! Set config type to \a value
void setConfigType( ConfigType value );
//! Set grant flow to \a value
void setGrantFlow( GrantFlow value );
//! Set name to \a value
void setName( const QString &value );
//! Set description to \a value
void setDescription( const QString &value );
//! Set request url to \a value
void setRequestUrl( const QString &value );
//! Set token url to \a value
void setTokenUrl( const QString &value );
//! Set refresh token url to \a value
void setRefreshTokenUrl( const QString &value );
//! Set redirect url to \a value
void setRedirectUrl( const QString &value );
//! Set redirect port to \a value
void setRedirectPort( int value );
//! Set client id to \a value
void setClientId( const QString &value );
//! Set client secret to \a value
void setClientSecret( const QString &value );
//! Set username to \a value
void setUsername( const QString &value );
//! Set password to \a value
void setPassword( const QString &value );
//! Set scope to \a value
void setScope( const QString &value );
//! Set state to \a value
void setState( const QString &value );
//! Set api key to \a value
void setApiKey( const QString &value );
// advanced
//! Set persistent token flag to \a persist
void setPersistToken( bool persist );
//! Set access method to \a value
void setAccessMethod( AccessMethod value );
//! Set request timeout to \a value
void setRequestTimeout( int value );
//! Set query pairs to \a pairs
void setQueryPairs( const QVariantMap &pairs );
//! Reset configuration to defaults
void setToDefaults();
//! Validate configuration
void validateConfig();
signals:
//! Emitted when configuration has changed
void configChanged();
//! Emitted when configuration id has changed
void idChanged( const QString & );
//! Emitted when configuration version has changed
void versionChanged( int );
//! Emitted when configuration type has changed
void configTypeChanged( ConfigType );
//! Emitted when configuration grant flow has changed
void grantFlowChanged( GrantFlow );
//! Emitted when configuration grant flow has changed
void nameChanged( const QString & );
//! Emitted when configuration name has changed
void descriptionChanged( const QString & );
//! Emitted when configuration request urlhas changed
void requestUrlChanged( const QString & );
//! Emitted when configuration token url has changed
void tokenUrlChanged( const QString & );
//! Emitted when configuration refresh token url has changed
void refreshTokenUrlChanged( const QString & );
//! Emitted when configuration redirect url has changed
void redirectUrlChanged( const QString & );
//! Emitted when configuration redirect port has changed
void redirectPortChanged( int );
//! Emitted when configuration client id has changed
void clientIdChanged( const QString & );
//! Emitted when configuration client secret has changed
void clientSecretChanged( const QString & );
//! Emitted when configuration username has changed
void usernameChanged( const QString & );
//! Emitted when configuration password has changed
void passwordChanged( const QString & );
//! Emitted when configuration scope has changed
void scopeChanged( const QString & );
//! Emitted when configuration state has changed
void stateChanged( const QString & );
//! Emitted when configuration API key has changed
void apiKeyChanged( const QString & );
// advanced
//! Emitted when configuration persiste token flag has changed
void persistTokenChanged( bool );
//! Emitted when configuration access method has changed
void accessMethodChanged( AccessMethod );
//! Emitted when configuration request timeout has changed
void requestTimeoutChanged( int );
//! Emitted when configuration query pair has changed
void queryPairsChanged( const QVariantMap & );
//! Emitted when configuration validity has changed
void validityChanged( bool );
private:
QString mId;
int mVersion;
ConfigType mConfigType;
GrantFlow mGrantFlow;
int mVersion = 1;
ConfigType mConfigType = ConfigType::Custom;
GrantFlow mGrantFlow = GrantFlow::AuthCode;
QString mName;
QString mDescription;
QString mRequestUrl;
QString mTokenUrl;
QString mRefreshTokenUrl;
QString mRedirectURL;
int mRedirectPort;
int mRedirectPort = 7070;
QString mClientId;
QString mClientSecret;
QString mUsername;
@ -306,11 +369,11 @@ class QgsAuthOAuth2Config : public QObject
QString mScope;
QString mState;
QString mApiKey;
bool mPersistToken;
AccessMethod mAccessMethod;
int mRequestTimeout; // in seconds
bool mPersistToken = false;
AccessMethod mAccessMethod = AccessMethod::Header;
int mRequestTimeout = 30 ; // in seconds
QVariantMap mQueryPairs;
bool mValid;
bool mValid = false;
};
#endif // QGSAUTHOAUTH2CONFIG_H

View File

@ -27,13 +27,7 @@
QgsAuthOAuth2Edit::QgsAuthOAuth2Edit( QWidget *parent )
: QgsAuthMethodEdit( parent )
, mOAuthConfigCustom( nullptr )
, mDefinedConfigsCache( QgsStringMap() )
, mParentName( nullptr )
, mValid( false )
, mCurTab( 0 )
, mPrevPersistToken( false )
, btnTokenClear( nullptr )
{
setupUi( this );
@ -52,13 +46,9 @@ QgsAuthOAuth2Edit::QgsAuthOAuth2Edit( QWidget *parent )
setupConnections();
loadFromOAuthConfig( mOAuthConfigCustom );
loadFromOAuthConfig( mOAuthConfigCustom.get() );
}
QgsAuthOAuth2Edit::~QgsAuthOAuth2Edit()
{
deleteConfigObjs();
}
void QgsAuthOAuth2Edit::initGui()
{
@ -160,26 +150,26 @@ void QgsAuthOAuth2Edit::setupConnections()
connect( cmbbxGrantFlow, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ),
this, &QgsAuthOAuth2Edit::updateGrantFlow ); // also updates GUI
connect( pteDescription, &QPlainTextEdit::textChanged, this, &QgsAuthOAuth2Edit::descriptionChanged );
connect( leRequestUrl, &QLineEdit::textChanged, mOAuthConfigCustom, &QgsAuthOAuth2Config::setRequestUrl );
connect( leTokenUrl, &QLineEdit::textChanged, mOAuthConfigCustom, &QgsAuthOAuth2Config::setTokenUrl );
connect( leRefreshTokenUrl, &QLineEdit::textChanged, mOAuthConfigCustom, &QgsAuthOAuth2Config::setRefreshTokenUrl );
connect( leRedirectUrl, &QLineEdit::textChanged, mOAuthConfigCustom, &QgsAuthOAuth2Config::setRedirectUrl );
connect( leRequestUrl, &QLineEdit::textChanged, mOAuthConfigCustom.get(), &QgsAuthOAuth2Config::setRequestUrl );
connect( leTokenUrl, &QLineEdit::textChanged, mOAuthConfigCustom.get(), &QgsAuthOAuth2Config::setTokenUrl );
connect( leRefreshTokenUrl, &QLineEdit::textChanged, mOAuthConfigCustom.get(), &QgsAuthOAuth2Config::setRefreshTokenUrl );
connect( leRedirectUrl, &QLineEdit::textChanged, mOAuthConfigCustom.get(), &QgsAuthOAuth2Config::setRedirectUrl );
connect( spnbxRedirectPort, static_cast<void ( QSpinBox::* )( int )>( &QSpinBox::valueChanged ),
mOAuthConfigCustom, &QgsAuthOAuth2Config::setRedirectPort );
connect( leClientId, &QLineEdit::textChanged, mOAuthConfigCustom, &QgsAuthOAuth2Config::setClientId );
connect( leClientSecret, &QgsPasswordLineEdit::textChanged, mOAuthConfigCustom, &QgsAuthOAuth2Config::setClientSecret );
connect( leUsername, &QLineEdit::textChanged, mOAuthConfigCustom, &QgsAuthOAuth2Config::setUsername );
connect( lePassword, &QgsPasswordLineEdit::textChanged, mOAuthConfigCustom, &QgsAuthOAuth2Config::setPassword );
connect( leScope, &QLineEdit::textChanged, mOAuthConfigCustom, &QgsAuthOAuth2Config::setScope );
connect( leState, &QLineEdit::textChanged, mOAuthConfigCustom, &QgsAuthOAuth2Config::setState );
connect( leApiKey, &QLineEdit::textChanged, mOAuthConfigCustom, &QgsAuthOAuth2Config::setApiKey );
connect( chkbxTokenPersist, &QCheckBox::toggled, mOAuthConfigCustom, &QgsAuthOAuth2Config::setPersistToken );
mOAuthConfigCustom.get(), &QgsAuthOAuth2Config::setRedirectPort );
connect( leClientId, &QLineEdit::textChanged, mOAuthConfigCustom.get(), &QgsAuthOAuth2Config::setClientId );
connect( leClientSecret, &QgsPasswordLineEdit::textChanged, mOAuthConfigCustom.get(), &QgsAuthOAuth2Config::setClientSecret );
connect( leUsername, &QLineEdit::textChanged, mOAuthConfigCustom.get(), &QgsAuthOAuth2Config::setUsername );
connect( lePassword, &QgsPasswordLineEdit::textChanged, mOAuthConfigCustom.get(), &QgsAuthOAuth2Config::setPassword );
connect( leScope, &QLineEdit::textChanged, mOAuthConfigCustom.get(), &QgsAuthOAuth2Config::setScope );
connect( leState, &QLineEdit::textChanged, mOAuthConfigCustom.get(), &QgsAuthOAuth2Config::setState );
connect( leApiKey, &QLineEdit::textChanged, mOAuthConfigCustom.get(), &QgsAuthOAuth2Config::setApiKey );
connect( chkbxTokenPersist, &QCheckBox::toggled, mOAuthConfigCustom.get(), &QgsAuthOAuth2Config::setPersistToken );
connect( cmbbxAccessMethod, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ),
this, &QgsAuthOAuth2Edit::updateConfigAccessMethod );
connect( spnbxRequestTimeout, static_cast<void ( QSpinBox::* )( int )>( &QSpinBox::valueChanged ),
mOAuthConfigCustom, &QgsAuthOAuth2Config::setRequestTimeout );
mOAuthConfigCustom.get(), &QgsAuthOAuth2Config::setRequestTimeout );
connect( mOAuthConfigCustom, &QgsAuthOAuth2Config::validityChanged, this, &QgsAuthOAuth2Edit::configValidityChanged );
connect( mOAuthConfigCustom.get(), &QgsAuthOAuth2Config::validityChanged, this, &QgsAuthOAuth2Edit::configValidityChanged );
if ( mParentName )
{
@ -286,7 +276,7 @@ void QgsAuthOAuth2Edit::loadConfig( const QgsStringMap &configmap )
//###################### DO NOT LEAVE ME UNCOMMENTED #####################
// could only be loading defaults at this point
loadFromOAuthConfig( mOAuthConfigCustom );
loadFromOAuthConfig( mOAuthConfigCustom.get() );
mPrevPersistToken = mOAuthConfigCustom->persistToken();
}
@ -361,7 +351,7 @@ void QgsAuthOAuth2Edit::clearConfig()
// reload predefined table
loadDefinedConfigs();
loadFromOAuthConfig( mOAuthConfigCustom );
loadFromOAuthConfig( mOAuthConfigCustom.get() );
}
// slot
@ -571,16 +561,11 @@ void QgsAuthOAuth2Edit::getDefinedCustomDir()
void QgsAuthOAuth2Edit::initConfigObjs()
{
mOAuthConfigCustom = new QgsAuthOAuth2Config( this );
mOAuthConfigCustom = qgis::make_unique<QgsAuthOAuth2Config>( nullptr );
mOAuthConfigCustom->setConfigType( QgsAuthOAuth2Config::Custom );
mOAuthConfigCustom->setToDefaults();
}
void QgsAuthOAuth2Edit::deleteConfigObjs()
{
delete mOAuthConfigCustom;
mOAuthConfigCustom = nullptr;
}
bool QgsAuthOAuth2Edit::hasTokenCacheFile()
{
@ -710,14 +695,16 @@ void QgsAuthOAuth2Edit::updateGrantFlow( int indx )
lblRequestUrl->setVisible( !resowner );
leRequestUrl->setVisible( !resowner );
if ( resowner ) leRequestUrl->setText( QString() );
if ( resowner )
leRequestUrl->setText( QString() );
lblRedirectUrl->setVisible( !resowner );
frameRedirectUrl->setVisible( !resowner );
lblClientSecret->setVisible( !implicit );
leClientSecret->setVisible( !implicit );
if ( implicit ) leClientSecret->setText( QString() );
if ( implicit )
leClientSecret->setText( QString() );
leClientId->setPlaceholderText( resowner ? tr( "Optional" ) : tr( "Required" ) );
leClientSecret->setPlaceholderText( resowner ? tr( "Optional" ) : tr( "Required" ) );
@ -725,10 +712,12 @@ void QgsAuthOAuth2Edit::updateGrantFlow( int indx )
lblUsername->setVisible( resowner );
leUsername->setVisible( resowner );
if ( !resowner ) leUsername->setText( QString() );
if ( !resowner )
leUsername->setText( QString() );
lblPassword->setVisible( resowner );
lePassword->setVisible( resowner );
if ( !resowner ) lePassword->setText( QString() );
if ( !resowner )
lePassword->setText( QString() );
}
// slot
@ -762,7 +751,7 @@ void QgsAuthOAuth2Edit::exportOAuthConfig()
mOAuthConfigCustom->setName( mParentName->text() );
}
if ( !QgsAuthOAuth2Config::writeOAuth2Config( configpath, mOAuthConfigCustom,
if ( !QgsAuthOAuth2Config::writeOAuth2Config( configpath, mOAuthConfigCustom.get(),
QgsAuthOAuth2Config::JSON, true ) )
{
QgsDebugMsg( QStringLiteral( "FAILED to export OAuth2 config file" ) );

View File

@ -23,23 +23,39 @@
#include "qgsauthoauth2config.h"
/**
* The QgsAuthOAuth2Edit class allows editing of an OAuth2 authentication configuration
* \ingroup auth_plugins
*/
class QgsAuthOAuth2Edit : public QgsAuthMethodEdit, private Ui::QgsAuthOAuth2Edit
{
Q_OBJECT
public:
explicit QgsAuthOAuth2Edit( QWidget *parent = nullptr );
virtual ~QgsAuthOAuth2Edit();
virtual ~QgsAuthOAuth2Edit() = default;
/**
* Validate current configuration
* \return true if current configuration is valid
*/
bool validateConfig() override;
/**
* Current configuration
* \return current configuration map
*/
QgsStringMap configMap() const override;
public slots:
//! Load the configuration from \a configMap
void loadConfig( const QgsStringMap &configmap ) override;
//! Reset configuration to defaults
void resetConfig() override;
//! Clear configuration
void clearConfig() override;
private slots:
@ -91,7 +107,6 @@ class QgsAuthOAuth2Edit : public QgsAuthMethodEdit, private Ui::QgsAuthOAuth2Edi
QString parentConfigId() const;
void initConfigObjs();
void deleteConfigObjs();
bool hasTokenCacheFile();
@ -105,15 +120,15 @@ class QgsAuthOAuth2Edit : public QgsAuthMethodEdit, private Ui::QgsAuthOAuth2Edi
QString currentDefinedConfig() const { return mDefinedId; }
QgsAuthOAuth2Config *mOAuthConfigCustom;
std::unique_ptr<QgsAuthOAuth2Config> mOAuthConfigCustom;
QgsStringMap mDefinedConfigsCache;
QString mDefinedId;
QLineEdit *mParentName;
QLineEdit *mParentName = nullptr;
QgsStringMap mConfigMap;
bool mValid;
int mCurTab;
bool mPrevPersistToken;
QToolButton *btnTokenClear;
bool mValid = false;
int mCurTab = 0;
bool mPrevPersistToken = false;
QToolButton *btnTokenClear = nullptr;
};
#endif // QGSAUTHOAUTH2EDIT_H

View File

@ -27,6 +27,10 @@
class QgsO2;
/**
* The QgsAuthOAuth2Method class handles all network connection operation for the OAuth2 authentication plugin
* \ingroup auth_plugins
*/
class QgsAuthOAuth2Method : public QgsAuthMethod
{
Q_OBJECT
@ -35,35 +39,51 @@ class QgsAuthOAuth2Method : public QgsAuthMethod
explicit QgsAuthOAuth2Method();
~QgsAuthOAuth2Method();
// QgsAuthMethod interface
//! OAuth2 method key
QString key() const override;
//! OAuth2 method description
QString description() const override;
//! Human readable description
QString displayDescription() const override;
//! Update network \a request with given \a authcfg and optional \a dataprovider
bool updateNetworkRequest( QNetworkRequest &request, const QString &authcfg,
const QString &dataprovider = QString() ) override;
//! Update network \a reply with given \a authcfg and optional \a dataprovider
bool updateNetworkReply( QNetworkReply *reply, const QString &authcfg,
const QString &dataprovider ) override;
//! Update data source \a connectionItems with given \a authcfg and optional \a dataprovider
bool updateDataSourceUriItems( QStringList &connectionItems, const QString &authcfg,
const QString &dataprovider = QString() ) override;
//! Clear cached configuration for given \a authcfg
void clearCachedConfig( const QString &authcfg ) override;
//! Update OAuth2 method configuration with \a config
void updateMethodConfig( QgsAuthMethodConfig &mconfig ) override;
public slots:
//! Triggered when linked condition has changed
void onLinkedChanged();
//! Triggered when linking operation failed
void onLinkingFailed();
//! Triggered when linking operation succeeded
void onLinkingSucceeded();
//! Triggered when the browser needs to be opened at \a url
void onOpenBrowser( const QUrl &url );
//! Triggered on browser close
void onCloseBrowser();
//! Triggered on reply finished
void onReplyFinished();
//! Triggered on network error
void onNetworkError( QNetworkReply::NetworkError err );
//! Triggered on refresh finished
void onRefreshFinished( QNetworkReply::NetworkError err );
private:

View File

@ -29,15 +29,27 @@ class QgsO2: public O2
Q_OBJECT
public:
/**
* Construct QgsO2
* \param authcfg authentication configuration id
* \param oauth2config OAuth2 configuration
* \param parent
* \param manager QGIS network access manager instance
*/
explicit QgsO2( const QString &authcfg, QgsAuthOAuth2Config *oauth2config = nullptr,
QObject *parent = nullptr, QNetworkAccessManager *manager = nullptr );
~QgsO2();
//! Authentication configuration id
QString authcfg() const { return mAuthcfg; }
//! OAuth2 configuration
QgsAuthOAuth2Config *oauth2config() { return mOAuth2Config; }
public slots:
//! Clear all properties
void clearProperties();
private: