Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -506,10 +506,24 @@ if (LNX)
target_link_libraries(MerginMaps PUBLIC QGIS::Core)
endif ()

# required for QGIS authentication manager API
find_library(
QCA_OSSL_PLUGIN_LIB
NAMES qca-ossl
PATH_SUFFIXES lib/Qca/crypto
)

if (QCA_OSSL_PLUGIN_LIB)
message(STATUS "Found QCA OpenSSL Plugin: ${QCA_OSSL_PLUGIN_LIB}")
else ()
message(WARNING "Could not find 'qca-ossl'. Authentication might fail.")
endif ()

target_link_libraries(
MerginMaps
PUBLIC Qt6Keychain::Qt6Keychain
qca
${QCA_OSSL_PLUGIN_LIB}
GDAL::GDAL
PostgreSQL::PostgreSQL
Spatialite::Spatialite
Expand Down
20 changes: 20 additions & 0 deletions app/activeproject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
#include "qgslayertreelayer.h"
#include "qgslayertreegroup.h"
#include "qgsmapthemecollection.h"
#include "qgsauthmanager.h"
#include "qgsapplication.h"

#include "activeproject.h"
#include "coreutils.h"
Expand All @@ -25,6 +27,8 @@
#include "position/tracking/androidtrackingbroadcast.h"
#endif

const QString AUTH_CONFIG_FILENAME = QStringLiteral( "qgis_cfg.xml" );

const QString ActiveProject::LOADING_FLAG_FILE_PATH = QString( "%1/.input_loading_project" ).arg( QStandardPaths::standardLocations( QStandardPaths::TempLocation ).first() );
const int ActiveProject::LOADING_FLAG_FILE_EXPIRATION_MS = 5000;

Expand Down Expand Up @@ -155,6 +159,21 @@ bool ActiveProject::forceLoad( const QString &filePath, bool force )
emit projectWillBeReloaded();
mActiveLayer.resetActiveLayer();

// path to the authentication configuration file
const QDir projectDir = QFileInfo( filePath ).dir();
const QFileInfo cfgFile( projectDir.filePath( AUTH_CONFIG_FILENAME ) );
if ( cfgFile.exists() && cfgFile.isFile() )
{
// clear the authentication database before importing a new one, if it exists
QgsAuthManager *authMngr = QgsApplication::authManager();
authMngr->removeAllAuthenticationConfigs();

// import the new configuration, if it exists.
const QString projectId = MerginProjectMetadata::fromCachedJson( CoreUtils::getProjectMetadataPath( projectDir.path() ) ).projectId;
const bool ok = authMngr->importAuthenticationConfigsFromXml( cfgFile.path(), projectId, true );
CoreUtils::log( "Database authentication: ", QString( "QGIS auth imported: %1" ).arg( ok ? "true" : "false" ) );
}

res = mQgsProject->read( filePath );
if ( !res )
{
Expand Down Expand Up @@ -186,6 +205,7 @@ bool ActiveProject::forceLoad( const QString &filePath, bool force )
QString role = MerginProjectMetadata::fromCachedJson( CoreUtils::getProjectMetadataPath( mLocalProject.projectDir ) ).role;
setProjectRole( role );


updateMapTheme();
updateActiveLayer();
updateMapSettingsLayers();
Expand Down
10 changes: 10 additions & 0 deletions app/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "test/inputtests.h"
#endif
#include <qqml.h>
#include "qgsauthmanager.h"
#include <qgsmessagelog.h>
#include "qgsconfig.h"
#include "qgsproviderregistry.h"
Expand Down Expand Up @@ -155,6 +156,9 @@
#include "qgsapplication.h"
#include "activeproject.h"
#include "appsettings.h"
// required for QGIS authentication manager API
#include <QtPlugin>
Q_IMPORT_PLUGIN( opensslPlugin )

static QString getDataDir()
{
Expand Down Expand Up @@ -543,6 +547,12 @@ int main( int argc, char *argv[] )
LayerTreeFlatModelPixmapProvider *layerTreeFlatModelPixmapProvider( new LayerTreeFlatModelPixmapProvider );
LayerDetailLegendImageProvider *layerDetailLegendImageProvider( new LayerDetailLegendImageProvider );

// setting up the master password for authentication database retrieval
QgsAuthManager *authManager = QgsApplication::authManager();
authManager->setPasswordHelperEnabled( false );
authManager->setMasterPassword( QStringLiteral( "merginMaps" ) );


// build position kit, save active provider to QSettings and load previously active provider
PositionKit pk;
QObject::connect( &pk, &PositionKit::positionProviderChanged, as, [as]( AbstractPositionProvider * provider )
Expand Down
55 changes: 45 additions & 10 deletions app/test/testactiveproject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ void TestActiveProject::testProjectValidations()
QString projectFilename = "bad_layer.qgz";

AppSettings as;
ActiveLayer al;
ActiveProject activeProject( as, al, mApi->localProjectsManager() );
ActiveLayer activeLayer;
ActiveProject activeProject( as, activeLayer, mApi->localProjectsManager() );

QSignalSpy spyReportIssues( &activeProject, &ActiveProject::reportIssue );
QSignalSpy spyErrorsFound( &activeProject, &ActiveProject::loadingErrorFound );
Expand All @@ -61,8 +61,8 @@ void TestActiveProject::testProjectLoadFailure()
InputUtils::cpDir( TestUtils::testDataDir() + "/load_failure", projectdir );

AppSettings as;
ActiveLayer al;
ActiveProject activeProject( as, al, mApi->localProjectsManager() );
ActiveLayer activeLayer;
ActiveProject activeProject( as, activeLayer, mApi->localProjectsManager() );

mApi->localProjectsManager().addLocalProject( projectdir, projectname );

Expand All @@ -81,8 +81,8 @@ void TestActiveProject::testPositionTrackingFlag()
// the position tracking availability is correctly set

AppSettings as;
ActiveLayer al;
ActiveProject activeProject( as, al, mApi->localProjectsManager() );
ActiveLayer activeLayer;
ActiveProject activeProject( as, activeLayer, mApi->localProjectsManager() );

// project "planes" - tracking not enabled
QString projectDir = TestUtils::testDataDir() + "/planes/";
Expand Down Expand Up @@ -121,8 +121,8 @@ void TestActiveProject::testRecordingAllowed()
QString projectFilename = "tracking-project.qgz";

AppSettings as;
ActiveLayer al;
ActiveProject activeProject( as, al, mApi->localProjectsManager() );
ActiveLayer activeLayer;
ActiveProject activeProject( as, activeLayer, mApi->localProjectsManager() );

mApi->localProjectsManager().addLocalProject( projectDir, projectFilename );
QVERIFY( activeProject.load( projectDir + "/" + projectFilename ) );
Expand Down Expand Up @@ -169,8 +169,8 @@ void TestActiveProject::testRecordingAllowed()
void TestActiveProject::testLoadingFlagFileExpiration()
{
AppSettings as;
ActiveLayer al;
ActiveProject activeProject( as, al, mApi->localProjectsManager() );
ActiveLayer activeLayer;
ActiveProject activeProject( as, activeLayer, mApi->localProjectsManager() );

// project "planes" - tracking not enabled
QString projectDir = TestUtils::testDataDir() + "/planes/";
Expand All @@ -191,3 +191,38 @@ void TestActiveProject::testLoadingFlagFileExpiration()

QVERIFY( !flagFile.exists() );
}

void TestActiveProject::testLoadingAuthFileFromConfiguration()
{
AppSettings appSettings;
ActiveLayer activeLayer;
ActiveProject activeProject( appSettings, activeLayer, mApi->localProjectsManager() );
QString projectDir = TestUtils::testDataDir() + QStringLiteral( "/project_auth_file/" );
QString projectName = QStringLiteral( "auth-test.qgz" );
QString af = QDir( projectDir ).filePath( AUTH_CONFIG_FILENAME );

QgsApplication::initQgis();

QgsAuthManager *authManager = QgsApplication::authManager();

mApi->localProjectsManager().addLocalProject( projectDir, projectName );
activeProject.load( projectDir + projectName );

QSignalSpy spyLoadingStarted( &activeProject, &ActiveProject::loadingStarted );

// we expect the configuration import to fail as the password for the cfg xml is not the project's id
int count = authManager->configIds().count();
QCOMPARE( count, 0 );

authManager->removeAllAuthenticationConfigs();
QFileInfo cfgFile( af );
if ( cfgFile.exists() && cfgFile.isFile() )
{
// we still check that the configuration can be imported
bool ok = authManager->importAuthenticationConfigsFromXml( af, AUTH_CONFIG_PASSWORD, true );

QVERIFY2( ok, "Importing the authentication database from XML failed" );
count = authManager->configIds().count();
QCOMPARE( count, 1 );
}
}
6 changes: 6 additions & 0 deletions app/test/testactiveproject.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@

#include <QObject>
#include <merginapi.h>
#include <qgsapplication.h>
#include <qgsauthmanager.h>

const QString AUTH_CONFIG_FILENAME = "qgis_cfg.xml";
const QString AUTH_CONFIG_PASSWORD = "1234";

class TestActiveProject : public QObject
{
Expand All @@ -29,6 +34,7 @@ class TestActiveProject : public QObject
void testPositionTrackingFlag();
void testRecordingAllowed();
void testLoadingFlagFileExpiration();
void testLoadingAuthFileFromConfiguration();

private:
MerginApi *mApi;
Expand Down
Binary file not shown.
Binary file added test/test_data/project_auth_file/auth-test.qgz
Binary file not shown.
2 changes: 2 additions & 0 deletions test/test_data/project_auth_file/qgis_cfg.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<!DOCTYPE qgis_authentication>
<qgis_authentication civ="fce8ce72133e5d85b5af66d3046e5c78411f20bb3ebb47eb851d469350922773" salt="0bd55a8f76c40cdef3bc8897714175fa" hash="dfe957824c402c5853a7a0f1d0feaa58">21ce1cf53ab351eb229b3ae83f7384b76578dd93d76e3515904213a79dddd46b0ed3e05f5f906fa681e7714af0d0d9dd551735a31bae5ea96333cc9ebe2debc003eebf44e42c1ec5cd9c7214d8a7399dedfd2f89819661615013ec79fb3bce642138f593be11c64f4f1374b274e1b5c887f229190521e7d0a340f97f1a27c78d70f1e3ac28d9b605d0ae07a9832c03ea2778c0629cbbc8e932d5b36b941f6d4eabe0b4d734d10ce41464064da7e2ee14204064a1ddfa7ca9427ad3aa4fd0cc467bab98b12235a867ddc6542935db835b</qgis_authentication>
Loading