Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[FEATURE] Add new authentication method that supports a HTTP header
- Loading branch information
1 parent
deba02b
commit 6b840a4
Showing
7 changed files
with
495 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
set(AUTH_APIHEADER_SRCS | ||
core/qgsauthapiheadermethod.cpp | ||
) | ||
|
||
set(AUTH_APIHEADER_HDRS | ||
core/qgsauthapiheadermethod.h | ||
) | ||
|
||
set(AUTH_APIHEADER_UIS_H "") | ||
|
||
if (WITH_GUI) | ||
set(AUTH_APIHEADER_SRCS ${AUTH_APIHEADER_SRCS} | ||
gui/qgsauthapiheaderedit.cpp | ||
) | ||
set(AUTH_APIHEADER_HDRS ${AUTH_APIHEADER_HDRS} | ||
gui/qgsauthapiheaderedit.h | ||
) | ||
set(AUTH_APIHEADER_UIS gui/qgsauthapiheaderedit.ui) | ||
if (WITH_QT6) | ||
QT6_WRAP_UI(AUTH_APIHEADER_UIS_H ${AUTH_APIHEADER_UIS}) | ||
else() | ||
QT5_WRAP_UI(AUTH_APIHEADER_UIS_H ${AUTH_APIHEADER_UIS}) | ||
endif() | ||
endif() | ||
|
||
|
||
# static library | ||
add_library(authmethod_apiheader_a STATIC ${AUTH_APIHEADER_SRCS} ${AUTH_APIHEADER_HDRS} ${AUTH_APIHEADER_UIS_H}) | ||
|
||
target_include_directories(authmethod_apiheader_a PUBLIC ${CMAKE_SOURCE_DIR}/src/auth/apiheader/core) | ||
|
||
# require c++17 | ||
target_compile_features(authmethod_apiheader_a PRIVATE cxx_std_17) | ||
|
||
target_link_libraries(authmethod_apiheader_a qgis_core) | ||
|
||
if (WITH_GUI) | ||
target_include_directories(authmethod_apiheader_a PRIVATE | ||
${CMAKE_SOURCE_DIR}/src/auth/apiheader/gui | ||
${CMAKE_BINARY_DIR}/src/auth/apiheader | ||
) | ||
target_link_libraries (authmethod_apiheader_a qgis_gui) | ||
endif() | ||
|
||
target_compile_definitions(authmethod_apiheader_a PRIVATE "-DQT_NO_FOREACH") | ||
|
||
if (FORCE_STATIC_LIBS) | ||
# for (external) mobile apps to be able to pick up provider for linking | ||
install (TARGETS authmethod_apiheader_a ARCHIVE DESTINATION ${QGIS_PLUGIN_DIR}) | ||
else() | ||
# dynamically loaded module | ||
add_library(authmethod_apiheader MODULE ${AUTH_APIHEADER_SRCS} ${AUTH_APIHEADER_HDRS} ${AUTH_APIHEADER_UIS_H}) | ||
|
||
# require c++17 | ||
target_compile_features(authmethod_apiheader PRIVATE cxx_std_17) | ||
|
||
target_link_libraries(authmethod_apiheader qgis_core) | ||
|
||
if (WITH_GUI) | ||
target_include_directories(authmethod_apiheader PRIVATE | ||
${CMAKE_SOURCE_DIR}/src/auth/apiheader/gui | ||
${CMAKE_BINARY_DIR}/src/auth/apiheader | ||
) | ||
target_link_libraries (authmethod_apiheader qgis_gui) | ||
add_dependencies(authmethod_apiheader ui) | ||
endif() | ||
|
||
target_compile_definitions(authmethod_apiheader PRIVATE "-DQT_NO_FOREACH") | ||
|
||
install (TARGETS authmethod_apiheader | ||
RUNTIME DESTINATION ${QGIS_PLUGIN_DIR} | ||
LIBRARY DESTINATION ${QGIS_PLUGIN_DIR} | ||
) | ||
endif() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
/*************************************************************************** | ||
qgsauthapiheadermethod.cpp | ||
-------------------------- | ||
begin : October 2021 | ||
copyright : (C) 2021 by Nyall Dawson | ||
author : Nyall Dawson | ||
email : nyall dot dawson at gmail dot com | ||
*************************************************************************** | ||
* * | ||
* 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 "qgsauthapiheadermethod.h" | ||
|
||
#include "qgsauthmanager.h" | ||
#include "qgslogger.h" | ||
#include "qgsapplication.h" | ||
|
||
#ifdef HAVE_GUI | ||
#include "qgsauthapiheaderedit.h" | ||
#endif | ||
|
||
#include <QNetworkProxy> | ||
#include <QMutexLocker> | ||
#include <QUuid> | ||
|
||
const QString QgsAuthApiHeaderMethod::AUTH_METHOD_KEY = QStringLiteral( "APIHeader" ); | ||
const QString QgsAuthApiHeaderMethod::AUTH_METHOD_DESCRIPTION = QStringLiteral( "API Header" ); | ||
const QString QgsAuthApiHeaderMethod::AUTH_METHOD_DISPLAY_DESCRIPTION = tr( "API Header" ); | ||
|
||
QMap<QString, QgsAuthMethodConfig> QgsAuthApiHeaderMethod::sAuthConfigCache = QMap<QString, QgsAuthMethodConfig>(); | ||
|
||
|
||
QgsAuthApiHeaderMethod::QgsAuthApiHeaderMethod() | ||
{ | ||
setVersion( 2 ); | ||
setExpansions( QgsAuthMethod::NetworkRequest ); | ||
setDataProviders( QStringList() | ||
<< QStringLiteral( "wms" ) ); | ||
} | ||
|
||
QString QgsAuthApiHeaderMethod::key() const | ||
{ | ||
return AUTH_METHOD_KEY; | ||
} | ||
|
||
QString QgsAuthApiHeaderMethod::description() const | ||
{ | ||
return AUTH_METHOD_DESCRIPTION; | ||
} | ||
|
||
QString QgsAuthApiHeaderMethod::displayDescription() const | ||
{ | ||
return AUTH_METHOD_DISPLAY_DESCRIPTION; | ||
} | ||
|
||
bool QgsAuthApiHeaderMethod::updateNetworkRequest( QNetworkRequest &request, const QString &authcfg, | ||
const QString &dataprovider ) | ||
{ | ||
Q_UNUSED( dataprovider ) | ||
const QgsAuthMethodConfig mconfig = getMethodConfig( authcfg ); | ||
if ( !mconfig.isValid() ) | ||
{ | ||
QgsDebugMsg( QStringLiteral( "Update request config FAILED for authcfg: %1: config invalid" ).arg( authcfg ) ); | ||
return false; | ||
} | ||
|
||
const QString headerKey = mconfig.config( QStringLiteral( "headerKey" ) ); | ||
const QString headerValue = mconfig.config( QStringLiteral( "headerValue" ) ); | ||
|
||
if ( !headerKey.isEmpty() && !headerValue.isEmpty() ) | ||
{ | ||
request.setRawHeader( QStringLiteral( "%1" ).arg( headerKey ).toLocal8Bit(), QStringLiteral( "%1" ).arg( headerValue ).toLocal8Bit() ); | ||
} | ||
return true; | ||
} | ||
|
||
void QgsAuthApiHeaderMethod::clearCachedConfig( const QString &authcfg ) | ||
{ | ||
removeMethodConfig( authcfg ); | ||
} | ||
|
||
void QgsAuthApiHeaderMethod::updateMethodConfig( QgsAuthMethodConfig &mconfig ) | ||
{ | ||
if ( mconfig.hasConfig( QStringLiteral( "oldconfigstyle" ) ) ) | ||
{ | ||
QgsDebugMsg( QStringLiteral( "Updating old style auth method config" ) ); | ||
} | ||
|
||
// NOTE: add updates as method version() increases due to config storage changes | ||
} | ||
|
||
QgsAuthMethodConfig QgsAuthApiHeaderMethod::getMethodConfig( const QString &authcfg, bool fullconfig ) | ||
{ | ||
const QMutexLocker locker( &mMutex ); | ||
QgsAuthMethodConfig mconfig; | ||
|
||
// check if it is cached | ||
if ( sAuthConfigCache.contains( authcfg ) ) | ||
{ | ||
mconfig = sAuthConfigCache.value( authcfg ); | ||
QgsDebugMsg( QStringLiteral( "Retrieved config for authcfg: %1" ).arg( authcfg ) ); | ||
return mconfig; | ||
} | ||
|
||
// else build basic bundle | ||
if ( !QgsApplication::authManager()->loadAuthenticationConfig( authcfg, mconfig, fullconfig ) ) | ||
{ | ||
QgsDebugMsg( QStringLiteral( "Retrieve config FAILED for authcfg: %1" ).arg( authcfg ) ); | ||
return QgsAuthMethodConfig(); | ||
} | ||
|
||
// cache bundle | ||
putMethodConfig( authcfg, mconfig ); | ||
|
||
return mconfig; | ||
} | ||
|
||
void QgsAuthApiHeaderMethod::putMethodConfig( const QString &authcfg, const QgsAuthMethodConfig &mconfig ) | ||
{ | ||
const QMutexLocker locker( &mMutex ); | ||
QgsDebugMsg( QStringLiteral( "Putting token config for authcfg: %1" ).arg( authcfg ) ); | ||
sAuthConfigCache.insert( authcfg, mconfig ); | ||
} | ||
|
||
void QgsAuthApiHeaderMethod::removeMethodConfig( const QString &authcfg ) | ||
{ | ||
const QMutexLocker locker( &mMutex ); | ||
if ( sAuthConfigCache.contains( authcfg ) ) | ||
{ | ||
sAuthConfigCache.remove( authcfg ); | ||
QgsDebugMsg( QStringLiteral( "Removed token config for authcfg: %1" ).arg( authcfg ) ); | ||
} | ||
} | ||
|
||
#ifdef HAVE_GUI | ||
QWidget *QgsAuthApiHeaderMethod::editWidget( QWidget *parent ) const | ||
{ | ||
return new QgsAuthApiHeaderEdit( parent ); | ||
} | ||
#endif | ||
|
||
////////////////////////////////////////////// | ||
// Plugin externals | ||
////////////////////////////////////////////// | ||
|
||
|
||
#ifndef HAVE_STATIC_PROVIDERS | ||
QGISEXTERN QgsAuthMethodMetadata *authMethodMetadataFactory() | ||
{ | ||
return new QgsAuthApiHeaderMethodMetadata(); | ||
} | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
/*************************************************************************** | ||
qgsauthapiheadermethod.h | ||
--------------------- | ||
begin : October 2021 | ||
copyright : (C) 2021 by Nyall Dawson | ||
email : nyall dot dawson at gmail dot com | ||
*************************************************************************** | ||
* * | ||
* 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. * | ||
* * | ||
***************************************************************************/ | ||
|
||
#ifndef QGSAUTHAPIHEADERMETHOD_H | ||
#define QGSAUTHAPIHEADERMETHOD_H | ||
|
||
#include <QObject> | ||
#include <QMutex> | ||
|
||
#include "qgsauthconfig.h" | ||
#include "qgsauthmethod.h" | ||
#include "qgsauthmethodmetadata.h" | ||
|
||
|
||
class QgsAuthApiHeaderMethod : public QgsAuthMethod | ||
{ | ||
Q_OBJECT | ||
|
||
public: | ||
|
||
static const QString AUTH_METHOD_KEY; | ||
static const QString AUTH_METHOD_DESCRIPTION; | ||
static const QString AUTH_METHOD_DISPLAY_DESCRIPTION; | ||
|
||
explicit QgsAuthApiHeaderMethod(); | ||
|
||
// QgsAuthMethod interface | ||
QString key() const override; | ||
|
||
QString description() const override; | ||
|
||
QString displayDescription() const override; | ||
|
||
bool updateNetworkRequest( QNetworkRequest &request, const QString &authcfg, | ||
const QString &dataprovider = QString() ) override; | ||
|
||
void clearCachedConfig( const QString &authcfg ) override; | ||
void updateMethodConfig( QgsAuthMethodConfig &mconfig ) override; | ||
|
||
#ifdef HAVE_GUI | ||
QWidget *editWidget( QWidget *parent )const override; | ||
#endif | ||
|
||
private: | ||
QgsAuthMethodConfig getMethodConfig( const QString &authcfg, bool fullconfig = true ); | ||
|
||
void putMethodConfig( const QString &authcfg, const QgsAuthMethodConfig &mconfig ); | ||
|
||
void removeMethodConfig( const QString &authcfg ); | ||
|
||
static QMap<QString, QgsAuthMethodConfig> sAuthConfigCache; | ||
|
||
}; | ||
|
||
|
||
class QgsAuthApiHeaderMethodMetadata : public QgsAuthMethodMetadata | ||
{ | ||
public: | ||
QgsAuthApiHeaderMethodMetadata() | ||
: QgsAuthMethodMetadata( QgsAuthApiHeaderMethod::AUTH_METHOD_KEY, QgsAuthApiHeaderMethod::AUTH_METHOD_DESCRIPTION ) | ||
{} | ||
QgsAuthApiHeaderMethod *createAuthMethod() const override {return new QgsAuthApiHeaderMethod;} | ||
//QStringList supportedDataProviders() const override; | ||
}; | ||
|
||
#endif // QGSAUTHAPIHEADERMETHOD_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
/*************************************************************************** | ||
qgsauthapiheaderedit.cpp | ||
------------------------ | ||
begin : October 2021 | ||
copyright : (C) 2021 by Nyall Dawson | ||
author : Nyall Dawson | ||
email : nyall dot dawson at gmail dot com | ||
*************************************************************************** | ||
* * | ||
* 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 "qgsauthapiheaderedit.h" | ||
#include "ui_qgsauthapiheaderedit.h" | ||
|
||
|
||
QgsAuthApiHeaderEdit::QgsAuthApiHeaderEdit( QWidget *parent ) | ||
: QgsAuthMethodEdit( parent ) | ||
{ | ||
setupUi( this ); | ||
connect( headerKeyEdit, &QLineEdit::textChanged, this, &QgsAuthApiHeaderEdit::textChanged ); | ||
} | ||
|
||
bool QgsAuthApiHeaderEdit::validateConfig() | ||
{ | ||
const bool curvalid = !headerKeyEdit->text().isEmpty(); | ||
if ( mValid != curvalid ) | ||
{ | ||
mValid = curvalid; | ||
emit validityChanged( curvalid ); | ||
} | ||
return curvalid; | ||
} | ||
|
||
QgsStringMap QgsAuthApiHeaderEdit::configMap() const | ||
{ | ||
QgsStringMap config; | ||
config.insert( QStringLiteral( "headerKey" ), headerKeyEdit->text() ); | ||
config.insert( QStringLiteral( "headerValue" ), headerValueEdit->toPlainText() ); | ||
|
||
return config; | ||
} | ||
|
||
void QgsAuthApiHeaderEdit::loadConfig( const QgsStringMap &configmap ) | ||
{ | ||
clearConfig(); | ||
|
||
mConfigMap = configmap; | ||
headerKeyEdit->setText( configmap.value( QStringLiteral( "headerKey" ) ) ); | ||
headerValueEdit->setPlainText( configmap.value( QStringLiteral( "headerValue" ) ) ); | ||
|
||
validateConfig(); | ||
} | ||
|
||
void QgsAuthApiHeaderEdit::resetConfig() | ||
{ | ||
loadConfig( mConfigMap ); | ||
} | ||
|
||
void QgsAuthApiHeaderEdit::clearConfig() | ||
{ | ||
headerKeyEdit->clear(); | ||
headerValueEdit->clear(); | ||
} | ||
|
||
void QgsAuthApiHeaderEdit::textChanged( const QString &txt ) | ||
{ | ||
Q_UNUSED( txt ) | ||
validateConfig(); | ||
} |
Oops, something went wrong.