Skip to content

Commit

Permalink
Add QSettings version of credential store and adjust CI to use it
Browse files Browse the repository at this point in the history
  • Loading branch information
tomasMizera committed Feb 13, 2025
1 parent 7b4d33a commit 0277a90
Show file tree
Hide file tree
Showing 13 changed files with 114 additions and 17 deletions.
1 change: 1 addition & 0 deletions .github/workflows/android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ jobs:
-DQT_ANDROID_SIGN_APK=Yes \
-DQT_ANDROID_SIGN_AAB=Yes \
-DUSE_MM_SERVER_API_KEY=Yes \
-DUSE_KEYCHAIN=No \
-DCMAKE_TOOLCHAIN_FILE=$QT_BASE/android_arm64_v8a/lib/cmake/Qt6/qt.toolchain.cmake \
-GNinja \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/ios.yml
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ jobs:
-DQT_HOST_PATH=${{ github.workspace }}/Qt/${{ env.QT_VERSION }}/macos \
-DIOS=TRUE \
-DUSE_MM_SERVER_API_KEY=TRUE \
-DUSE_KEYCHAIN=No \
-DCMAKE_INSTALL_PREFIX:PATH=../install-Input \
-DINPUT_SDK_PATH=${{ github.workspace }}/input-sdk/arm64-ios \
-G "Xcode" \
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -142,13 +142,13 @@ jobs:
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_PREFIX_PATH=${{ github.workspace }}/Qt/${{ env.QT_VERSION }}/gcc_64 \
-DUSE_SERVER_API_KEY=TRUE \
-DUSE_KEYCHAIN=No \
-DINPUT_SDK_PATH=${{ github.workspace }}/input-sdk/x64-linux \
-DQGIS_QUICK_DATA_PATH=${{ github.workspace }}/input/app/android/assets/qgis-data \
-DUSE_MM_SERVER_API_KEY=TRUE \
-DCOVERAGE=TRUE \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
-DENABLE_TESTS=TRUE \
-DUSE_INSECURE_KEYCHAIN_FALLBACK=TRUE \
-GNinja \
-S ../input
Expand Down Expand Up @@ -192,6 +192,7 @@ jobs:
-DINPUT_SDK_PATH=${{ github.workspace }}/input-sdk/x64-linux \
-DQGIS_QUICK_DATA_PATH=${{ github.workspace }}/input/app/android/assets/qgis-data \
-DUSE_MM_SERVER_API_KEY=TRUE \
-DUSE_KEYCHAIN=No \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
-GNinja \
-S ../input
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -141,12 +141,12 @@ jobs:
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_PREFIX_PATH=${{ github.workspace }}/Qt/${{ env.QT_VERSION }}/macos \
-DUSE_SERVER_API_KEY=TRUE \
-DUSE_KEYCHAIN=No \
-DINPUT_SDK_PATH=${{ github.workspace }}/input-sdk/x64-osx \
-DQGIS_QUICK_DATA_PATH=${{ github.workspace }}/input/app/android/assets/qgis-data \
-DCOVERAGE=TRUE \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
-DENABLE_TESTS=TRUE \
-DUSE_INSECURE_KEYCHAIN_FALLBACK=TRUE \
-GNinja \
-S ../input
Expand Down Expand Up @@ -174,6 +174,7 @@ jobs:
-DCMAKE_INSTALL_PREFIX:PATH=../install-Input \
-DUSE_SERVER_API_KEY=TRUE \
-DUSE_MM_SERVER_API_KEY=TRUE \
-DUSE_KEYCHAIN=No \
-DINPUT_SDK_PATH=${{ github.workspace }}/input-sdk/x64-osx \
-DQGIS_QUICK_DATA_PATH=${{ github.workspace }}/input/app/android/assets/qgis-data \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/macos_arm64.yml
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ jobs:
-DCMAKE_INSTALL_PREFIX:PATH=../install-Input \
-DUSE_SERVER_API_KEY=TRUE \
-DUSE_MM_SERVER_API_KEY=TRUE \
-DUSE_KEYCHAIN=No \
-DINPUT_SDK_PATH=${{ github.workspace }}/input-sdk/arm64-osx \
-DQGIS_QUICK_DATA_PATH=${{ github.workspace }}/input/app/android/assets/qgis-data \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/win.yml
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ jobs:
-DCMAKE_INSTALL_PREFIX:PATH=${{ steps.vars.outputs.WORKSPACE_DIR }}/install-Input ^
-DINPUT_SDK_PATH:PATH=${{ steps.vars.outputs.WORKSPACE_DIR }}/input-sdk/x64-windows ^
-DUSE_MM_SERVER_API_KEY=TRUE ^
-DUSE_KEYCHAIN=No ^
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache ^
-G "NMake Makefiles" ^
-S ${{ steps.vars.outputs.WORKSPACE_DIR }}/input ^
Expand Down
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -143,11 +143,11 @@ set(HAVE_BLUETOOTH
CACHE BOOL "Building with bluetooth position provider"
)

set(USE_INSECURE_KEYCHAIN_FALLBACK
set(USE_KEYCHAIN
FALSE
CACHE
BOOL
"Wheter to use insecure credential store if keychain is not available. Useful in CI"
"Wheter to use keychains/wallets to store credentials. If false, we use QSettings"
)

set(QT6_VERSION
Expand Down
9 changes: 8 additions & 1 deletion core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ set(MM_CORE_SRCS
project.cpp
geodiffutils.cpp
projectchecksumcache.cpp
credentialstore.cpp
)

set(MM_CORE_HDRS
Expand Down Expand Up @@ -52,6 +51,14 @@ else ()
)
endif ()

if (USE_KEYCHAIN)
set(MM_CORE_SRCS ${MM_CORE_SRCS} credentialstorekeychain.cpp)
message(STATUS "Using QtKeychain to store credentials.")
else()
set(MM_CORE_SRCS ${MM_CORE_SRCS} credentialstoreplaintext.cpp)
message(STATUS "Using QSettings to store credentials.")
endif()

add_library(mm_core OBJECT ${MM_CORE_SRCS} ${MM_CORE_HDRS})
target_include_directories(mm_core PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(mm_core PRIVATE Qt6::Core Qt6::Network Geodiff::Geodiff)
Expand Down
6 changes: 6 additions & 0 deletions core/credentialstore.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@

#include <qt6keychain/keychain.h>

/**
* \brief The CredentialStore class stores user credentials either to QtKeychain
* or QSettings, according to USE_KEYCHAIN cmake flag.
*
* \note Read and write operations are async when QtKeychain is used
*/
class CredentialStore : public QObject
{
Q_OBJECT
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ void CredentialStore::writeAuthData
mWriteJob->start();

//
// 3. Clear any previous data from QSettings (migration from the previous insecure QSettings)
// 3. Clear any previous data from QSettings (migration from the previous QSettings)
//

// TODO: pass
Expand Down
83 changes: 83 additions & 0 deletions core/credentialstoreplaintext.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/***************************************************************************
* *
* 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 "credentialstore.h"
#include "coreutils.h"

#include <QSettings>

const QString CredentialStore::KEYCHAIN_GROUP = QStringLiteral( "Input/" );
const QString CredentialStore::KEYCHAIN_ENTRY_CREDENTIALS = QStringLiteral( "" ); // unused
const QString CredentialStore::KEYCHAIN_ENTRY_TOKEN = QStringLiteral( "" ); // unused

const QString CredentialStore::KEY_USERNAME = QStringLiteral( "username" );
const QString CredentialStore::KEY_PASSWORD = QStringLiteral( "password" );
const QString CredentialStore::KEY_USERID = QStringLiteral( "userId" );
const QString CredentialStore::KEY_TOKEN = QStringLiteral( "token" );
const QString CredentialStore::KEY_EXPIRE = QStringLiteral( "expire" );

//
// We store credentials in QSettings and read them in synchronous operation
//

CredentialStore::CredentialStore( QObject *parent )
: QObject( parent )
{
// mWriteJob and mReadJob are unused
}

void CredentialStore::writeAuthData
( const QString &username,
const QString &password,
int userId,
const QString &token,
const QDateTime &tokenExpiration )
{
QSettings settings;
settings.beginGroup( KEYCHAIN_GROUP );

settings.setValue( KEY_USERNAME, username );
settings.setValue( KEY_PASSWORD, password );
settings.setValue( KEY_USERID, userId );
settings.setValue( KEY_TOKEN, token );
settings.setValue( KEY_EXPIRE, tokenExpiration );

settings.endGroup();
}

void CredentialStore::readAuthData()
{
QString username, password;
int userid = -1;
QByteArray token;
QDateTime tokenExpiration;

QSettings settings;
settings.beginGroup( KEYCHAIN_GROUP );

username = settings.value( KEY_USERNAME ).toString();
password = settings.value( KEY_PASSWORD ).toString();
userid = settings.value( KEY_USERID ).toInt();
token = settings.value( KEY_TOKEN ).toByteArray();
tokenExpiration = settings.value( KEY_EXPIRE ).toDateTime();

settings.endGroup();

emit authDataRead( username, password, userid, token, tokenExpiration );
}

void CredentialStore::readKeyRecursively( const QString &key )
{
// no op
}

void CredentialStore::finishReadingOperation()
{
// no op
}
12 changes: 6 additions & 6 deletions core/merginapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,6 @@ MerginApi::MerginApi( LocalProjectsManager &localProjects, QObject *parent )
QSettings cache;
if ( cache.contains( QStringLiteral( "Input/apiRoot" ) ) )
{
QObject::connect( mUserAuth, &MerginUserAuth::credentialsLoaded, this, [this]()
{
QObject::connect( this, &MerginApi::pingMerginFinished, this, &MerginApi::getUserInfo, Qt::SingleShotConnection );
QObject::connect( this, &MerginApi::userInfoReplyFinished, this, &MerginApi::getWorkspaceInfo, Qt::SingleShotConnection );
} );

loadCache();
}
else
Expand Down Expand Up @@ -111,6 +105,12 @@ MerginApi::MerginApi( LocalProjectsManager &localProjects, QObject *parent )

getServerConfig();
pingMergin();

if ( mUserAuth->hasAuthData() )
{
QObject::connect( this, &MerginApi::pingMerginFinished, this, &MerginApi::getUserInfo, Qt::SingleShotConnection );
QObject::connect( this, &MerginApi::userInfoReplyFinished, this, &MerginApi::getWorkspaceInfo, Qt::SingleShotConnection );
}
}

void MerginApi::loadCache()
Expand Down
5 changes: 0 additions & 5 deletions core/merginuserauth.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,6 @@

MerginUserAuth::MerginUserAuth( QObject *parent )
: QObject( parent )
, mUsername( "" )
, mPassword( "" )
, mUserId( -1 )
, mAuthToken()
, mTokenExpiration()
, mCredentialStore( new CredentialStore( this ) )
{
clear();
Expand Down

0 comments on commit 0277a90

Please sign in to comment.