21#include <QMutexLocker>
24#include <QSqlDatabase>
33#include <QDomDocument>
34#include <QRegularExpression>
35#include <QCoreApplication>
36#include <QRandomGenerator>
41#include <QSslConfiguration>
54#include "moc_qgsauthmanager.cpp"
63const QString QgsAuthManager::AUTH_CONFIG_TABLE = QStringLiteral(
"auth_configs" );
64const QString QgsAuthManager::AUTH_SERVERS_TABLE = QStringLiteral(
"auth_servers" );
66const QString QgsAuthManager::AUTH_CFG_REGEX = QStringLiteral(
"authcfg=([a-z]|[A-Z]|[0-9]){7}" );
69const QLatin1String QgsAuthManager::AUTH_PASSWORD_HELPER_KEY_NAME_BASE(
"QGIS-Master-Password" );
70const QLatin1String QgsAuthManager::AUTH_PASSWORD_HELPER_FOLDER_NAME(
"QGIS" );
76#elif defined(Q_OS_WIN)
78#elif defined(Q_OS_LINUX)
87 QMutexLocker locker( &sMutex );
98 mMutex = std::make_unique<QRecursiveMutex>();
99 mMasterPasswordMutex = std::make_unique<QRecursiveMutex>();
101 this, &QgsAuthManager::writeToConsole );
115 QMutexLocker locker( mMutex.get() );
120 return storage->authDatabaseConnection();
134 const QList<QgsAuthConfigurationStorage *> storages { storageRegistry->
readyStorages() };
137 if (
auto dbStorage = qobject_cast<QgsAuthConfigurationStorageDb *>( storage ) )
141 return dbStorage->quotedQualifiedIdentifier( dbStorage->methodConfigTableName() );
154 const auto drivers { QSqlDatabase::drivers() };
155 for (
const QString &driver : std::as_const( drivers ) )
157 if ( driver != ( QStringLiteral(
"QSQLITE" ) ) && driver != ( QStringLiteral(
"QSPATIALITE" ) ) && uri.startsWith( driver ) )
167 return mAuthDatabaseConnectionUri;
172 QRegularExpression re( QStringLiteral(
"password=(.*)" ) );
173 QString uri = mAuthDatabaseConnectionUri;
174 return uri.replace( re, QStringLiteral(
"password=*****" ) );
180 mAuthDatabaseConnectionUri = authDatabasePath.startsWith( QLatin1String(
"QSQLITE://" ) ) ? authDatabasePath : QStringLiteral(
"QSQLITE://" ) + authDatabasePath;
181 return initPrivate( pluginPath );
186 static QRecursiveMutex sInitializationMutex;
187 static bool sInitialized =
false;
189 sInitializationMutex.lock();
192 sInitializationMutex.unlock();
193 return mLazyInitResult;
196 mLazyInitResult =
const_cast< QgsAuthManager *
>( this )->initPrivate( mPluginPath );
198 sInitializationMutex.unlock();
200 return mLazyInitResult;
203bool QgsAuthManager::initPrivate(
const QString &pluginPath )
212 mQcaInitializer = std::make_unique<QCA::Initializer>( QCA::Practical, 256 );
215 QCA::scanForPlugins();
217 QgsDebugMsgLevel( QStringLiteral(
"QCA Plugin Diagnostics Context: %1" ).arg( QCA::pluginDiagnosticText() ), 2 );
218 QStringList capabilities;
220 capabilities = QCA::supportedFeatures();
221 QgsDebugMsgLevel( QStringLiteral(
"QCA supports: %1" ).arg( capabilities.join(
"," ) ), 2 );
224 if ( !QCA::isSupported(
"cert", QStringLiteral(
"qca-ossl" ) ) )
226 mAuthDisabled =
true;
227 mAuthDisabledMessage = tr(
"QCA's OpenSSL plugin (qca-ossl) is missing" );
231 QgsDebugMsgLevel( QStringLiteral(
"Prioritizing qca-ossl over all other QCA providers..." ), 2 );
232 const QCA::ProviderList provds = QCA::providers();
234 for ( QCA::Provider *p : provds )
236 QString pn = p->name();
238 if ( pn != QLatin1String(
"qca-ossl" ) )
240 pr = QCA::providerPriority( pn ) + 1;
242 QCA::setProviderPriority( pn, pr );
243 prlist << QStringLiteral(
"%1:%2" ).arg( pn ).arg( QCA::providerPriority( pn ) );
245 QgsDebugMsgLevel( QStringLiteral(
"QCA provider priorities: %1" ).arg( prlist.join(
", " ) ), 2 );
252 QgsDebugMsgLevel( QStringLiteral(
"Authentication methods found: %1" ).arg( methods.join(
", " ) ), 2 );
254 if ( methods.isEmpty() )
256 mAuthDisabled =
true;
257 mAuthDisabledMessage = tr(
"No authentication method plugins found" );
263 mAuthDisabled =
true;
264 mAuthDisabledMessage = tr(
"No authentication method plugins could be loaded" );
268 QgsDebugMsgLevel( QStringLiteral(
"Auth database URI: %1" ).arg( mAuthDatabaseConnectionUri ), 2 );
271 const QString sqliteDbPath { sqliteDatabasePath() };
272 if ( ! sqliteDbPath.isEmpty() )
276 else if ( ! mAuthDatabaseConnectionUri.isEmpty() )
299 const QString err = tr(
"Failed to initialize storage %1: %2" ).arg( storage->
name(), storage->
lastError() );
317 const char *passenv =
"QGIS_AUTH_PASSWORD_FILE";
320 QString passpath( getenv( passenv ) );
330 QFile passfile( passpath );
331 if ( passfile.exists() && passfile.open( QIODevice::ReadOnly | QIODevice::Text ) )
333 QTextStream passin( &passfile );
334 while ( !passin.atEnd() )
336 masterpass = passin.readLine();
341 if ( !masterpass.isEmpty() )
345 QgsDebugMsgLevel( QStringLiteral(
"Authentication master password set from QGIS_AUTH_PASSWORD_FILE" ), 2 );
349 QgsDebugError(
"QGIS_AUTH_PASSWORD_FILE set, but FAILED to set password using: " + passpath );
355 QgsDebugError(
"QGIS_AUTH_PASSWORD_FILE set, but FAILED to read password from: " + passpath );
365 mPluginPath = pluginPath;
366 mAuthDatabaseConnectionUri = authDatabasePath;
375 QgsDebugError( QStringLiteral(
"Authentication system DISABLED: QCA's qca-ossl (OpenSSL) plugin is missing" ) );
377 return mAuthDisabled;
384 return tr(
"Authentication system is DISABLED:\n%1" ).arg( mAuthDisabledMessage );
388const QString QgsAuthManager::sqliteDatabasePath()
const
396 QString path = mAuthDatabaseConnectionUri;
397 if ( path.startsWith( QStringLiteral(
"QSQLITE://" ), Qt::CaseSensitivity::CaseInsensitive ) )
399 path = path.mid( 10 );
401 else if ( path.startsWith( QStringLiteral(
"QSPATIALITE://" ), Qt::CaseSensitivity::CaseInsensitive ) )
403 path = path.mid( 14 );
406 return QDir::cleanPath( path );
411 return sqliteDatabasePath();
418 QMutexLocker locker( mMasterPasswordMutex.get() );
422 if ( mScheduledDbErase )
425 if ( mMasterPass.isEmpty() )
427 QgsDebugMsgLevel( QStringLiteral(
"Master password is not yet set by user" ), 2 );
428 if ( !masterPasswordInput() )
430 QgsDebugMsgLevel( QStringLiteral(
"Master password input canceled by user" ), 2 );
444 QgsDebugMsgLevel( QStringLiteral(
"Master password is set and verified" ), 2 );
452 QMutexLocker locker( mMutex.get() );
456 if ( mScheduledDbErase )
460 QString prevpass = QString( mMasterPass );
464 mMasterPass = prevpass;
465 const char *err = QT_TR_NOOP(
"Master password set: FAILED to verify, reset to previous" );
471 QgsDebugMsgLevel( QStringLiteral(
"Master password set: SUCCESS%1" ).arg( verify ?
" and verified" :
"" ), 2 );
483 if ( !masterPasswordRowsInDb( &rows ) )
485 const char *err = QT_TR_NOOP(
"Master password: FAILED to access database" );
493 QgsDebugMsgLevel( QStringLiteral(
"Master password: %1 rows in database" ).arg( rows ), 2 );
497 const char *err = QT_TR_NOOP(
"Master password: FAILED to find just one master password record in database" );
504 else if ( rows == 1 )
506 if ( !masterPasswordCheckAgainstDb( compare ) )
508 if ( compare.isNull() )
510 const char *err = QT_TR_NOOP(
"Master password: FAILED to verify against hash in database" );
519 if ( mPassTries >= 5 )
521 mAuthDisabled =
true;
522 const char *err = QT_TR_NOOP(
"Master password: failed 5 times authentication system DISABLED" );
530 QgsDebugMsgLevel( QStringLiteral(
"Master password: verified against hash in database" ), 2 );
531 if ( compare.isNull() )
535 else if ( compare.isNull() )
537 if ( !masterPasswordStoreInDb() )
539 const char *err = QT_TR_NOOP(
"Master password: hash FAILED to be stored in database" );
548 QgsDebugMsgLevel( QStringLiteral(
"Master password: hash stored in database" ), 2 );
551 if ( !masterPasswordCheckAgainstDb() )
553 const char *err = QT_TR_NOOP(
"Master password: FAILED to verify against hash in database" );
563 QgsDebugMsgLevel( QStringLiteral(
"Master password: verified against hash in database" ), 2 );
575 return !mMasterPass.isEmpty();
582 return mMasterPass == pass;
586 bool keepbackup, QString *backuppath )
602 QgsDebugMsgLevel( QStringLiteral(
"Master password reset: backed up current database" ), 2 );
605 QString prevpass = QString( mMasterPass );
606 QString prevciv = QString( masterPasswordCiv() );
612 if ( ok && !masterPasswordClearDb() )
615 const char *err = QT_TR_NOOP(
"Master password reset FAILED: could not clear current password from database" );
621 QgsDebugMsgLevel( QStringLiteral(
"Master password reset: cleared current password from database" ), 2 );
628 if ( ok && !masterPasswordStoreInDb() )
631 const char *err = QT_TR_NOOP(
"Master password reset FAILED: could not store new password in database" );
637 QgsDebugMsgLevel( QStringLiteral(
"Master password reset: stored new password in database" ), 2 );
644 const char *err = QT_TR_NOOP(
"Master password reset FAILED: could not verify new password in database" );
650 if ( ok && !reencryptAllAuthenticationConfigs( prevpass, prevciv ) )
653 const char *err = QT_TR_NOOP(
"Master password reset FAILED: could not re-encrypt configs in database" );
659 QgsDebugMsgLevel( QStringLiteral(
"Master password reset: re-encrypted configs in database" ), 2 );
663 if ( ok && !verifyPasswordCanDecryptConfigs() )
666 const char *err = QT_TR_NOOP(
"Master password reset FAILED: could not verify password can decrypt re-encrypted configs" );
671 if ( ok && !reencryptAllAuthenticationSettings( prevpass, prevciv ) )
674 const char *err = QT_TR_NOOP(
"Master password reset FAILED: could not re-encrypt settings in database" );
679 if ( ok && !reencryptAllAuthenticationIdentities( prevpass, prevciv ) )
682 const char *err = QT_TR_NOOP(
"Master password reset FAILED: could not re-encrypt identities in database" );
691 QString errdbbackup( dbbackup );
692 errdbbackup.replace( QLatin1String(
".db" ), QLatin1String(
"_ERROR.db" ) );
693 QFile::rename( sqliteDatabasePath(), errdbbackup );
694 QgsDebugError( QStringLiteral(
"Master password reset FAILED: backed up failed db at %1" ).arg( errdbbackup ) );
696 QFile::rename( dbbackup, sqliteDatabasePath() );
697 mMasterPass = prevpass;
698 QgsDebugError( QStringLiteral(
"Master password reset FAILED: reinstated previous password and database" ) );
702 *backuppath = errdbbackup;
708 if ( !keepbackup && !QFile::remove( dbbackup ) )
710 const char *err = QT_TR_NOOP(
"Master password reset: could not remove old database backup" );
718 QgsDebugMsgLevel( QStringLiteral(
"Master password reset: backed up previous db at %1" ).arg( dbbackup ), 2 );
720 *backuppath = dbbackup;
732 mScheduledDbErase = scheduleErase;
734 mScheduledDbEraseRequestEmitted =
false;
735 mScheduledDbEraseRequestCount = 0;
739 if ( !mScheduledDbEraseTimer )
741 mScheduledDbEraseTimer =
new QTimer(
this );
742 connect( mScheduledDbEraseTimer, &QTimer::timeout,
this, &QgsAuthManager::tryToStartDbErase );
743 mScheduledDbEraseTimer->start( mScheduledDbEraseRequestWait * 1000 );
745 else if ( !mScheduledDbEraseTimer->isActive() )
747 mScheduledDbEraseTimer->start();
752 if ( mScheduledDbEraseTimer && mScheduledDbEraseTimer->isActive() )
753 mScheduledDbEraseTimer->stop();
762 qDeleteAll( mAuthMethods );
763 mAuthMethods.clear();
765 for (
const auto &authMethodKey : methods )
770 return !mAuthMethods.isEmpty();
782#ifndef __clang_analyzer__
785 QTimer::singleShot( 3, &loop, &QEventLoop::quit );
792 for (
int i = 0; i < len; i++ )
794 switch ( QRandomGenerator::system()->generate() % 2 )
797 id +=
static_cast<char>(
'0' + QRandomGenerator::system()->generate() % 10 );
800 id +=
static_cast<char>(
'a' + QRandomGenerator::system()->generate() % 26 );
804 if ( !configids.contains(
id ) )
809 QgsDebugMsgLevel( QStringLiteral(
"Generated unique ID: %1" ).arg(
id ), 2 );
822 const char *err = QT_TR_NOOP(
"Config ID is empty" );
828 return !configids.contains(
id );
833 const thread_local QRegularExpression authCfgRegExp( AUTH_CFG_REGEX );
834 return txt.indexOf( authCfgRegExp ) != -1;
841 QMutexLocker locker( mMutex.get() );
842 QStringList providerAuthMethodsKeys;
843 if ( !dataprovider.isEmpty() )
860 if ( providerAuthMethodsKeys.isEmpty() || providerAuthMethodsKeys.contains( config.method() ) )
863 if ( baseConfigs.contains( config.id() ) )
870 baseConfigs.insert( config.id(), config );
876 if ( storages.empty() )
879 QgsDebugError( QStringLiteral(
"No credentials storages found" ) );
898 if ( !
configIds.contains( config.id() ) )
900 mConfigAuthMethods.insert( config.id(), config.method() );
901 QgsDebugMsgLevel( QStringLiteral(
"Stored auth config/methods:\n%1 %2" ).arg( config.id(), config.method() ), 2 );
907 QgsDebugMsgLevel( QStringLiteral(
"A config with same id %1 was already added, skipping from %2" ).arg( config.id(), storage->
name() ), 2 );
920 if ( !mConfigAuthMethods.contains( authcfg ) )
922 QgsDebugError( QStringLiteral(
"No config auth method found in database for authcfg: %1" ).arg( authcfg ) );
926 QString authMethodKey = mConfigAuthMethods.value( authcfg );
938 return mConfigAuthMethods.value( authcfg, QString() );
953 if ( !mAuthMethods.contains( authMethodKey ) )
955 QgsDebugError( QStringLiteral(
"No auth method registered for auth method key: %1" ).arg( authMethodKey ) );
959 return mAuthMethods.value( authMethodKey );
966 if ( !mAuthMethods.contains( authMethodKey ) )
968 QgsDebugError( QStringLiteral(
"No auth method registered for auth method key: %1" ).arg( authMethodKey ) );
980 if ( dataprovider.isEmpty() )
986 QgsAuthMethodsMap::const_iterator i = mAuthMethods.constBegin();
987 while ( i != mAuthMethods.constEnd() )
990 && ( i.value()->supportedDataProviders().contains( QStringLiteral(
"all" ) )
991 || i.value()->supportedDataProviders().contains( dataprovider ) ) )
993 filteredmap.insert( i.key(), i.value() );
1001QWidget *QgsAuthManager::authMethodEditWidget(
const QString &authMethodKey, QWidget *parent )
1007 return method->editWidget( parent );
1032 QMutexLocker locker( mMutex.get() );
1039 const char *err = QT_TR_NOOP(
"Store config: FAILED because config is invalid" );
1045 QString uid = config.
id();
1046 bool passedinID = !uid.isEmpty();
1047 if ( uid.isEmpty() )
1055 const char *err = QT_TR_NOOP(
"Store config: FAILED because pre-defined config ID %1 is not unique" );
1063 const char *err = QT_TR_NOOP(
"Store config: FAILED because pre-defined config ID %1 could not be removed" );
1072 if ( configstring.isEmpty() )
1074 const char *err = QT_TR_NOOP(
"Store config: FAILED because config string is empty" );
1082 if ( defaultStorage->isEncrypted() )
1089 configCopy.
setId( uid );
1090 if ( !defaultStorage->storeMethodConfig( configCopy, configstring ) )
1104 config.
setId( uid );
1108 QgsDebugMsgLevel( QStringLiteral(
"Store config SUCCESS for authcfg: %1" ).arg( uid ), 2 );
1116 QMutexLocker locker( mMutex.get() );
1121 if ( !config.
isValid(
true ) )
1123 const char *err = QT_TR_NOOP(
"Update config: FAILED because config is invalid" );
1130 if ( configstring.isEmpty() )
1132 const char *err = QT_TR_NOOP(
"Update config: FAILED because config is empty" );
1163 if ( storages.empty() )
1174 QgsDebugMsgLevel( QStringLiteral(
"Update config SUCCESS for authcfg: %1" ).arg( config.
id() ), 2 );
1189 QMutexLocker locker( mMutex.get() );
1201 if ( ! config.
isValid(
true ) || ( full && payload.isEmpty() ) )
1224 QgsDebugError( QStringLiteral(
"Update of authcfg %1 FAILED for auth method %2" ).arg( authcfg, authMethodKey ) );
1227 QgsDebugMsgLevel( QStringLiteral(
"Load %1 config SUCCESS for authcfg: %2" ).arg( full ?
"full" :
"base", authcfg ), 2 );
1232 if ( storages.empty() )
1248 QMutexLocker locker( mMutex.get() );
1252 if ( authcfg.isEmpty() )
1271 QgsDebugMsgLevel( QStringLiteral(
"REMOVED config for authcfg: %1" ).arg( authcfg ), 2 );
1278 if ( storages.empty() )
1295 if ( filename.isEmpty() )
1298 QDomDocument document( QStringLiteral(
"qgis_authentication" ) );
1299 QDomElement root = document.createElement( QStringLiteral(
"qgis_authentication" ) );
1300 document.appendChild( root );
1303 if ( !password.isEmpty() )
1308 root.setAttribute( QStringLiteral(
"salt" ), salt );
1309 root.setAttribute( QStringLiteral(
"hash" ), hash );
1310 root.setAttribute( QStringLiteral(
"civ" ), civ );
1313 QDomElement configurations = document.createElement( QStringLiteral(
"configurations" ) );
1314 for (
const QString &authcfg : authcfgs )
1321 authMethodConfig.
writeXml( configurations, document );
1324 if ( !password.isEmpty() )
1326 QString configurationsString;
1327 QTextStream ts( &configurationsString );
1328#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
1329 ts.setCodec(
"UTF-8" );
1331 configurations.save( ts, 2 );
1332 root.appendChild( document.createTextNode(
QgsAuthCrypto::encrypt( password, civ, configurationsString ) ) );
1336 root.appendChild( configurations );
1339 QFile file( filename );
1340 if ( !file.open( QFile::WriteOnly | QIODevice::Truncate ) )
1343 QTextStream ts( &file );
1344#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
1345 ts.setCodec(
"UTF-8" );
1347 document.save( ts, 2 );
1356 QFile file( filename );
1357 if ( !file.open( QFile::ReadOnly ) )
1362 QDomDocument document( QStringLiteral(
"qgis_authentication" ) );
1363 if ( !document.setContent( &file ) )
1370 QDomElement root = document.documentElement();
1371 if ( root.tagName() != QLatin1String(
"qgis_authentication" ) )
1376 QDomElement configurations;
1377 if ( root.hasAttribute( QStringLiteral(
"salt" ) ) )
1379 QString salt = root.attribute( QStringLiteral(
"salt" ) );
1380 QString hash = root.attribute( QStringLiteral(
"hash" ) );
1381 QString civ = root.attribute( QStringLiteral(
"civ" ) );
1386 configurations = document.firstChild().toElement();
1390 configurations = root.firstChildElement( QStringLiteral(
"configurations" ) );
1393 QDomElement configuration = configurations.firstChildElement();
1394 while ( !configuration.isNull() )
1397 authMethodConfig.
readXml( configuration );
1400 configuration = configuration.nextSiblingElement();
1409 QMutexLocker locker( mMutex.get() );
1415 if ( defaultStorage->clearMethodConfigs() )
1419 QgsDebugMsgLevel( QStringLiteral(
"REMOVED all configs from the default storage" ), 2 );
1424 QgsDebugMsgLevel( QStringLiteral(
"FAILED to remove all configs from the default storage" ), 2 );
1440 QMutexLocker locker( mMutex.get() );
1442 if ( sqliteDatabasePath().isEmpty() )
1444 const char *err = QT_TR_NOOP(
"The authentication database is not filesystem-based" );
1450 if ( !QFile::exists( sqliteDatabasePath() ) )
1452 const char *err = QT_TR_NOOP(
"No authentication database found" );
1462 if ( authConn.isValid() && authConn.isOpen() )
1466 QString datestamp( QDateTime::currentDateTime().toString( QStringLiteral(
"yyyy-MM-dd-hhmmss" ) ) );
1467 QString dbbackup( sqliteDatabasePath() );
1468 dbbackup.replace( QLatin1String(
".db" ), QStringLiteral(
"_%1.db" ).arg( datestamp ) );
1470 if ( !QFile::copy( sqliteDatabasePath(), dbbackup ) )
1472 const char *err = QT_TR_NOOP(
"Could not back up authentication database" );
1479 *backuppath = dbbackup;
1481 QgsDebugMsgLevel( QStringLiteral(
"Backed up auth database at %1" ).arg( dbbackup ), 2 );
1489 QMutexLocker locker( mMutex.get() );
1500 if ( backuppath && !dbbackup.isEmpty() )
1501 *backuppath = dbbackup;
1505 if ( defaultStorage->erase() )
1507 mMasterPass = QString();
1535 const QString &dataprovider )
1547 QgsDebugError( QStringLiteral(
"Network request updating not supported by authcfg: %1" ).arg( authcfg ) );
1562 const QString &dataprovider )
1574 QgsDebugMsgLevel( QStringLiteral(
"Network reply updating not supported by authcfg: %1" ).arg( authcfg ), 3 );
1590 const QString &dataprovider )
1602 QgsDebugError( QStringLiteral(
"Data source URI updating not supported by authcfg: %1" ).arg( authcfg ) );
1629 QgsDebugError( QStringLiteral(
"Proxy updating not supported by authcfg: %1" ).arg( authcfg ) );
1638 QgsDebugMsgLevel( QStringLiteral(
"Proxy updated successfully from authcfg: %1" ).arg( authcfg ), 2 );
1649 QMutexLocker locker( mMutex.get() );
1650 if ( key.isEmpty() )
1653 QString storeval( value.toString() );
1676 if ( !defaultStorage->storeAuthSetting( key, storeval ) )
1694 QMutexLocker locker( mMutex.get() );
1695 if ( key.isEmpty() )
1701 QVariant value = defaultValue;
1709 if ( !storeval.isEmpty() )
1720 if ( storages.empty() )
1732 QMutexLocker locker( mMutex.get() );
1733 if ( key.isEmpty() )
1747 if ( storages.empty() )
1759 QMutexLocker locker( mMutex.get() );
1760 if ( key.isEmpty() )
1787 if ( storages.empty() )
1802 QMutexLocker locker( mMutex.get() );
1808 mCustomConfigByHostCache.clear();
1809 mHasCheckedIfCustomConfigByHostExists =
false;
1812 QgsDebugError( QStringLiteral(
"Init of SSL caches FAILED" ) );
1820 QMutexLocker locker( mMutex.get() );
1821 if ( cert.isNull() )
1823 QgsDebugError( QStringLiteral(
"Passed certificate is null" ) );
1828 QgsDebugError( QStringLiteral(
"Passed private key is null" ) );
1840 QgsDebugError( QStringLiteral(
"Store certificate identity: FAILED to remove pre-existing certificate identity %1" ).arg(
id ) );
1848 if ( !defaultStorage->storeCertIdentity( cert, keypem ) )
1866 QMutexLocker locker( mMutex.get() );
1868 QSslCertificate cert;
1879 if ( !cert.isNull() )
1885 if ( storages.empty() )
1897 QMutexLocker locker( mMutex.get() );
1898 QPair<QSslCertificate, QSslKey> bundle;
1913 if ( encryptedBundle.first.isNull() )
1915 QgsDebugError( QStringLiteral(
"Certificate identity bundle is null for id: %1" ).arg(
id ) );
1918 QSslKey key(
QgsAuthCrypto::decrypt( mMasterPass, masterPasswordCiv(), encryptedBundle.second ).toLatin1(),
1919 QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey );
1922 QgsDebugError( QStringLiteral(
"Certificate identity bundle: FAILED to create private key" ) );
1925 bundle = qMakePair( encryptedBundle.first, key );
1930 if ( storages.empty() )
1943 QMutexLocker locker( mMutex.get() );
1947 return QStringList() << QString( bundle.first.toPem() ) << QString( bundle.second.toPem() );
1949 return QStringList();
1956 QMutexLocker locker( mMutex.get() );
1957 QList<QSslCertificate> certs;
1964 const QList<QSslCertificate> storageCerts = storage->
certIdentities();
1966 for (
const QSslCertificate &cert : std::as_const( storageCerts ) )
1968 if ( !certs.contains( cert ) )
1970 certs.append( cert );
1979 if ( storages.empty() )
1991 QMutexLocker locker( mMutex.get() );
2005 for (
const QString &
id : std::as_const( storageIds ) )
2007 if ( !ids.contains(
id ) )
2025 QMutexLocker locker( mMutex.get() );
2040 if ( storages.empty() )
2052 QMutexLocker locker( mMutex.get() );
2055 QgsDebugError( QStringLiteral(
"Passed bundle ID is empty" ) );
2075 if ( storages.empty() )
2088 QMutexLocker locker( mMutex.get() );
2100 QgsDebugError( QStringLiteral(
"Store SSL certificate custom config: FAILED to remove pre-existing config %1" ).arg(
id ) );
2106 if ( !defaultStorage->storeSslCertCustomConfig( config ) )
2119 mCustomConfigByHostCache.clear();
2128 QMutexLocker locker( mMutex.get() );
2131 if (
id.isEmpty() || hostport.isEmpty() )
2133 QgsDebugError( QStringLiteral(
"Passed config ID or host:port is empty" ) );
2157 if ( storages.empty() )
2171 if ( hostport.isEmpty() )
2176 QMutexLocker locker( mMutex.get() );
2178 if ( mCustomConfigByHostCache.contains( hostport ) )
2179 return mCustomConfigByHostCache.value( hostport );
2189 mCustomConfigByHostCache.insert( hostport, config );
2194 if ( storages.empty() )
2206 QMutexLocker locker( mMutex.get() );
2207 QList<QgsAuthConfigSslServer> configs;
2218 for (
const auto &config : std::as_const( storageConfigs ) )
2221 const QString hostPort = config.sslHostPort();
2222 const QString shaHostPort( QStringLiteral(
"%1:%2" ).arg(
id, hostPort ) );
2223 if ( ! ids.contains( shaHostPort ) )
2225 ids.append( shaHostPort );
2226 configs.append( config );
2233 configs.append( storageConfigs );
2236 if ( storages.empty() )
2248 QMutexLocker locker( mMutex.get() );
2249 if (
id.isEmpty() || hostPort.isEmpty() )
2251 QgsDebugError( QStringLiteral(
"Passed config ID or host:port is empty" ) );
2266 if ( storages.empty() )
2278 QMutexLocker locker( mMutex.get() );
2279 if (
id.isEmpty() || hostport.isEmpty() )
2281 QgsDebugError( QStringLiteral(
"Passed config ID or host:port is empty" ) );
2285 mCustomConfigByHostCache.clear();
2299 const QString shaHostPort( QStringLiteral(
"%1:%2" ).arg(
id, hostport ) );
2300 if ( mIgnoredSslErrorsCache.contains( shaHostPort ) )
2302 mIgnoredSslErrorsCache.remove( shaHostPort );
2308 if ( storages.empty() )
2321 QMutexLocker locker( mMutex.get() );
2322 if ( !mIgnoredSslErrorsCache.isEmpty() )
2324 QgsDebugMsgLevel( QStringLiteral(
"Ignored SSL errors cache items:" ), 1 );
2325 QHash<QString, QSet<QSslError::SslError> >::const_iterator i = mIgnoredSslErrorsCache.constBegin();
2326 while ( i != mIgnoredSslErrorsCache.constEnd() )
2329 for (
auto err : i.value() )
2333 QgsDebugMsgLevel( QStringLiteral(
"%1 = %2" ).arg( i.key(), errs.join(
", " ) ), 1 );
2347 QMutexLocker locker( mMutex.get() );
2354 QString shahostport( QStringLiteral(
"%1:%2" )
2357 if ( mIgnoredSslErrorsCache.contains( shahostport ) )
2359 mIgnoredSslErrorsCache.remove( shahostport );
2362 if ( !errenums.isEmpty() )
2364 mIgnoredSslErrorsCache.insert( shahostport, QSet<QSslError::SslError>( errenums.begin(), errenums.end() ) );
2365 QgsDebugMsgLevel( QStringLiteral(
"Update of ignored SSL errors cache SUCCEEDED for sha:host:port = %1" ).arg( shahostport ), 2 );
2370 QgsDebugMsgLevel( QStringLiteral(
"No ignored SSL errors to cache for sha:host:port = %1" ).arg( shahostport ), 2 );
2378 QMutexLocker locker( mMutex.get() );
2379 const thread_local QRegularExpression rx( QRegularExpression::anchoredPattern(
"\\S+:\\S+:\\d+" ) );
2380 if ( !rx.match( shahostport ).hasMatch() )
2382 QgsDebugError(
"Passed shahostport does not match \\S+:\\S+:\\d+, "
2383 "e.g. 74a4ef5ea94512a43769b744cda0ca5049a72491:www.example.com:443" );
2387 if ( mIgnoredSslErrorsCache.contains( shahostport ) )
2389 mIgnoredSslErrorsCache.remove( shahostport );
2392 if ( errors.isEmpty() )
2394 QgsDebugError( QStringLiteral(
"Passed errors list empty" ) );
2398 QSet<QSslError::SslError> errs;
2399 for (
const auto &error : errors )
2401 if ( error.error() == QSslError::NoError )
2404 errs.insert( error.error() );
2407 if ( errs.isEmpty() )
2409 QgsDebugError( QStringLiteral(
"Passed errors list does not contain errors" ) );
2413 mIgnoredSslErrorsCache.insert( shahostport, errs );
2415 QgsDebugMsgLevel( QStringLiteral(
"Update of ignored SSL errors cache SUCCEEDED for sha:host:port = %1" ).arg( shahostport ), 2 );
2424 QMutexLocker locker( mMutex.get() );
2425 QHash<QString, QSet<QSslError::SslError> > prevcache( mIgnoredSslErrorsCache );
2426 QHash<QString, QSet<QSslError::SslError> > nextcache;
2436 for (
const auto &config : std::as_const( customConfigs ) )
2439 if ( ! ids.contains( shaHostPort ) )
2441 ids.append( shaHostPort );
2442 if ( !config.sslIgnoredErrorEnums().isEmpty() )
2444 nextcache.insert( config.sslHostPort(), QSet<QSslError::SslError>( config.sslIgnoredErrorEnums().cbegin(), config.sslIgnoredErrorEnums().cend() ) );
2446 if ( prevcache.contains( config.sslHostPort() ) )
2448 prevcache.remove( config.sslHostPort() );
2458 if ( !prevcache.isEmpty() )
2461 QHash<QString, QSet<QSslError::SslError> >::const_iterator i = prevcache.constBegin();
2462 while ( i != prevcache.constEnd() )
2464 nextcache.insert( i.key(), i.value() );
2469 if ( nextcache != mIgnoredSslErrorsCache )
2471 mIgnoredSslErrorsCache.clear();
2472 mIgnoredSslErrorsCache = nextcache;
2473 QgsDebugMsgLevel( QStringLiteral(
"Rebuild of ignored SSL errors cache SUCCEEDED" ), 2 );
2478 QgsDebugMsgLevel( QStringLiteral(
"Rebuild of ignored SSL errors cache SAME AS BEFORE" ), 2 );
2487 QMutexLocker locker( mMutex.get() );
2488 if ( certs.isEmpty() )
2490 QgsDebugError( QStringLiteral(
"Passed certificate list has no certs" ) );
2494 for (
const auto &cert : certs )
2506 QMutexLocker locker( mMutex.get() );
2509 if ( cert.isNull() )
2511 QgsDebugError( QStringLiteral(
"Passed certificate is null" ) );
2517 QgsDebugError( QStringLiteral(
"Store certificate authority: FAILED to remove pre-existing certificate authority" ) );
2523 return defaultStorage->storeCertAuthority( cert );
2538 QMutexLocker locker( mMutex.get() );
2539 QSslCertificate emptycert;
2540 QSslCertificate cert;
2550 if ( !cert.isNull() )
2556 if ( storages.empty() )
2569 QMutexLocker locker( mMutex.get() );
2570 if ( cert.isNull() )
2572 QgsDebugError( QStringLiteral(
"Passed certificate is null" ) );
2587 if ( storages.empty() )
2599 QMutexLocker locker( mMutex.get() );
2600 if ( cert.isNull() )
2602 QgsDebugError( QStringLiteral(
"Passed certificate is null" ) );
2629 if ( storages.empty() )
2639 return QSslConfiguration::systemCaCertificates();
2646 QMutexLocker locker( mMutex.get() );
2647 QList<QSslCertificate> certs;
2648 QList<QSslCertificate> filecerts;
2657 QString cafile( cafileval.toString() );
2658 if ( !cafile.isEmpty() && QFile::exists( cafile ) )
2663 for (
const auto &cert : std::as_const( filecerts ) )
2665 if ( !allowinvalid.toBool() && ( cert.isBlacklisted()
2667 || cert.expiryDate() <= QDateTime::currentDateTime()
2668 || cert.effectiveDate() > QDateTime::currentDateTime() ) )
2685 QMutexLocker locker( mMutex.get() );
2690 QList<QSslCertificate> certs;
2694 const QList<QSslCertificate> storageCerts = storage->
caCerts();
2696 for (
const QSslCertificate &cert : std::as_const( storageCerts ) )
2698 if ( !certs.contains( cert ) )
2700 certs.append( cert );
2709 if ( storages.empty() )
2721 QMutexLocker locker( mMutex.get() );
2729 QMutexLocker locker( mMutex.get() );
2730 mCaCertsCache.clear();
2736 bool res = !mCaCertsCache.isEmpty();
2738 QgsDebugError( QStringLiteral(
"Rebuild of CA certs cache FAILED" ) );
2746 QMutexLocker locker( mMutex.get() );
2747 if ( cert.isNull() )
2749 QgsDebugError( QStringLiteral(
"Passed certificate is null." ) );
2766 return defaultStorage->storeCertTrustPolicy( cert, policy );
2779 QMutexLocker locker( mMutex.get() );
2780 if ( cert.isNull() )
2782 QgsDebugError( QStringLiteral(
"Passed certificate is null" ) );
2798 if ( storages.empty() )
2810 QMutexLocker locker( mMutex.get() );
2811 if ( certs.empty() )
2813 QgsDebugError( QStringLiteral(
"Passed certificate list has no certs" ) );
2817 for (
const auto &cert : certs )
2829 QMutexLocker locker( mMutex.get() );
2830 if ( cert.isNull() )
2832 QgsDebugError( QStringLiteral(
"Passed certificate is null" ) );
2858 if ( storages.empty() )
2870 QMutexLocker locker( mMutex.get() );
2871 if ( cert.isNull() )
2881 if ( trustedids.contains(
id ) )
2885 else if ( untrustedids.contains(
id ) )
2901 return storeAuthSetting( QStringLiteral(
"certdefaulttrust" ),
static_cast< int >( policy ) );
2908 QMutexLocker locker( mMutex.get() );
2909 QVariant policy(
authSetting( QStringLiteral(
"certdefaulttrust" ) ) );
2921 QMutexLocker locker( mMutex.get() );
2922 mCertTrustCache.clear();
2933 for (
auto it = trustedCerts.cbegin(); it != trustedCerts.cend(); ++it )
2935 const QString
id { it.key( )};
2936 if ( ! ids.contains(
id ) )
2957 if ( ! storages.empty() )
2959 QgsDebugMsgLevel( QStringLiteral(
"Rebuild of cert trust policy cache SUCCEEDED" ), 2 );
2973 QMutexLocker locker( mMutex.get() );
2977 const QList<QPair<QgsAuthCertUtils::CaCertSource, QSslCertificate> > &certpairs( mCaCertsCache.values() );
2979 QList<QSslCertificate> trustedcerts;
2980 for (
int i = 0; i < certpairs.size(); ++i )
2982 QSslCertificate cert( certpairs.at( i ).second );
2984 if ( trustedids.contains( certid ) )
2987 trustedcerts.append( cert );
2993 trustedcerts.append( cert );
2998 QSslConfiguration sslconfig( QSslConfiguration::defaultConfiguration() );
2999 sslconfig.setCaCertificates( trustedcerts );
3000 QSslConfiguration::setDefaultConfiguration( sslconfig );
3002 return trustedcerts;
3009 QMutexLocker locker( mMutex.get() );
3010 if ( trustedCAs.isEmpty() )
3012 if ( mTrustedCaCertsCache.isEmpty() )
3019 const QList<QPair<QgsAuthCertUtils::CaCertSource, QSslCertificate> > &certpairs( mCaCertsCache.values() );
3021 QList<QSslCertificate> untrustedCAs;
3022 for (
int i = 0; i < certpairs.size(); ++i )
3024 QSslCertificate cert( certpairs.at( i ).second );
3025 if ( !trustedCAs.contains( cert ) )
3027 untrustedCAs.append( cert );
3030 return untrustedCAs;
3037 QMutexLocker locker( mMutex.get() );
3039 QgsDebugMsgLevel( QStringLiteral(
"Rebuilt trusted cert authorities cache" ), 2 );
3048 QMutexLocker locker( mMutex.get() );
3056 QMutexLocker locker( mMutex.get() );
3059 return passwordHelperWrite( mMasterPass );
3077 for (
const auto &authcfg : ids )
3097void QgsAuthManager::writeToConsole(
const QString &message,
3113 msg += QLatin1String(
"WARNING: " );
3116 msg += QLatin1String(
"ERROR: " );
3123 QTextStream out( stdout, QIODevice::WriteOnly );
3124 out << msg << Qt::endl;
3127void QgsAuthManager::tryToStartDbErase()
3131 ++mScheduledDbEraseRequestCount;
3133 int trycutoff = 90 / ( mScheduledDbEraseRequestWait ? mScheduledDbEraseRequestWait : 3 );
3134 if ( mScheduledDbEraseRequestCount >= trycutoff )
3137 QgsDebugMsgLevel( QStringLiteral(
"authDatabaseEraseRequest emitting/scheduling canceled" ), 2 );
3142 QgsDebugMsgLevel( QStringLiteral(
"authDatabaseEraseRequest attempt (%1 of %2)" )
3143 .arg( mScheduledDbEraseRequestCount ).arg( trycutoff ), 2 );
3149 mScheduledDbEraseRequestEmitted =
true;
3154 QgsDebugMsgLevel( QStringLiteral(
"authDatabaseEraseRequest emitted" ), 2 );
3157 QgsDebugMsgLevel( QStringLiteral(
"authDatabaseEraseRequest emit skipped" ), 2 );
3163 QMutexLocker locker( mMutex.get() );
3165 QMapIterator<QThread *, QMetaObject::Connection> iterator( mConnectedThreads );
3166 while ( iterator.hasNext() )
3169 QThread::disconnect( iterator.value() );
3180 qDeleteAll( mAuthMethods );
3185 if ( authConn.isValid() && authConn.isOpen() )
3188 delete mScheduledDbEraseTimer;
3189 mScheduledDbEraseTimer =
nullptr;
3190 QSqlDatabase::removeDatabase( QStringLiteral(
"authentication.configs" ) );
3195 QMutexLocker locker( mMutex.get() );
3196 if ( ! mAuthConfigurationStorageRegistry )
3198 mAuthConfigurationStorageRegistry = std::make_unique<QgsAuthConfigurationStorageRegistry>();
3200 return mAuthConfigurationStorageRegistry.get();
3204QString QgsAuthManager::passwordHelperName()
const
3206 return tr(
"Password Helper" );
3210void QgsAuthManager::passwordHelperLog(
const QString &msg )
const
3226 QKeychain::DeletePasswordJob job( AUTH_PASSWORD_HELPER_FOLDER_NAME );
3229 job.setAutoDelete(
false );
3230 job.setKey( authPasswordHelperKeyName() );
3232 connect( &job, &QKeychain::Job::finished, &loop, &QEventLoop::quit );
3237 mPasswordHelperErrorCode = job.error();
3238 mPasswordHelperErrorMessage = tr(
"Delete password failed: %1." ).arg( job.errorString() );
3249 passwordHelperProcessError();
3253QString QgsAuthManager::passwordHelperRead()
3260 QKeychain::ReadPasswordJob job( AUTH_PASSWORD_HELPER_FOLDER_NAME );
3263 job.setAutoDelete(
false );
3264 job.setKey( authPasswordHelperKeyName() );
3266 connect( &job, &QKeychain::Job::finished, &loop, &QEventLoop::quit );
3271 mPasswordHelperErrorCode = job.error();
3278 password = job.textData();
3280 if ( password.isEmpty() )
3282 mPasswordHelperErrorCode = QKeychain::EntryNotFound;
3293 passwordHelperProcessError();
3297bool QgsAuthManager::passwordHelperWrite(
const QString &password )
3301 Q_ASSERT( !password.isEmpty() );
3304 QKeychain::WritePasswordJob job( AUTH_PASSWORD_HELPER_FOLDER_NAME );
3307 job.setAutoDelete(
false );
3308 job.setKey( authPasswordHelperKeyName() );
3309 job.setTextData( password );
3311 connect( &job, &QKeychain::Job::finished, &loop, &QEventLoop::quit );
3316 mPasswordHelperErrorCode = job.error();
3324 passwordHelperClearErrors();
3329 passwordHelperProcessError();
3344 emit
messageLog( enabled ? tr(
"Your %1 will be <b>used from now</b> on to store and retrieve the master password." )
3346 tr(
"Your %1 will <b>not be used anymore</b> to store and retrieve the master password." )
3363void QgsAuthManager::passwordHelperClearErrors()
3365 mPasswordHelperErrorCode = QKeychain::NoError;
3366 mPasswordHelperErrorMessage.clear();
3369void QgsAuthManager::passwordHelperProcessError()
3373 if ( mPasswordHelperErrorCode == QKeychain::AccessDenied ||
3374 mPasswordHelperErrorCode == QKeychain::AccessDeniedByUser ||
3375 mPasswordHelperErrorCode == QKeychain::NoBackendAvailable ||
3376 mPasswordHelperErrorCode == QKeychain::NotImplemented )
3382 mPasswordHelperErrorMessage = tr(
"There was an error and integration with your %1 system has been disabled. "
3383 "You can re-enable it at any time through the \"Utilities\" menu "
3384 "in the Authentication pane of the options dialog. %2" )
3387 if ( mPasswordHelperErrorCode != QKeychain::NoError )
3393 passwordHelperClearErrors();
3397bool QgsAuthManager::masterPasswordInput()
3405 bool storedPasswordIsValid =
false;
3411 pass = passwordHelperRead();
3412 if ( ! pass.isEmpty() && ( mPasswordHelperErrorCode == QKeychain::NoError ) )
3418 storedPasswordIsValid =
true;
3434 if ( ok && !pass.isEmpty() && mMasterPass != pass )
3439 if ( passwordHelperWrite( pass ) )
3453bool QgsAuthManager::masterPasswordRowsInDb(
int *rows )
const
3462 QMutexLocker locker( mMutex.get() );
3480 if ( storages.empty() )
3497 if ( !masterPasswordRowsInDb( &rows ) )
3499 const char *err = QT_TR_NOOP(
"Master password: FAILED to access database" );
3505 return ( rows == 1 );
3508bool QgsAuthManager::masterPasswordCheckAgainstDb(
const QString &compare )
const
3520 const QList<QgsAuthConfigurationStorage::MasterPasswordConfig> passwords { defaultStorage->masterPasswords( ) };
3521 if ( passwords.size() == 0 )
3544bool QgsAuthManager::masterPasswordStoreInDb()
const
3551 QString salt, hash, civ;
3559 return defaultStorage->storeMasterPassword( { salt, civ, hash } );
3575bool QgsAuthManager::masterPasswordClearDb()
3587 return defaultStorage->clearMasterPasswords();
3604const QString QgsAuthManager::masterPasswordCiv()
const
3615 const QList<QgsAuthConfigurationStorage::MasterPasswordConfig> passwords { defaultStorage->masterPasswords( ) };
3616 if ( passwords.size() == 0 )
3621 return passwords.first().civ;
3641 QStringList configKeys = QStringList();
3655 for (
auto it = configs.cbegin(); it != configs.cend(); ++it )
3657 if ( !configKeys.contains( it.key() ) )
3659 configKeys.append( it.key() );
3677bool QgsAuthManager::verifyPasswordCanDecryptConfigs()
const
3700 for (
auto it = configs.cbegin(); it != configs.cend(); ++it )
3702 QString configstring(
QgsAuthCrypto::decrypt( mMasterPass, masterPasswordCiv(), it.value().config( QStringLiteral(
"encrypted_payload" ) ) ) );
3703 if ( configstring.isEmpty() )
3705 QgsDebugError( QStringLiteral(
"Verify password can decrypt configs FAILED, could not decrypt a config (id: %1) from storage %2" )
3706 .arg( it.key(), storage->
name() ) );
3720 if ( storages.empty() )
3729bool QgsAuthManager::reencryptAllAuthenticationConfigs(
const QString &prevpass,
const QString &prevciv )
3738 for (
const auto &configid : ids )
3740 res = res && reencryptAuthenticationConfig( configid, prevpass, prevciv );
3745bool QgsAuthManager::reencryptAuthenticationConfig(
const QString &authcfg,
const QString &prevpass,
const QString &prevciv )
3770 if ( payload.isEmpty() || ! config.
isValid(
true ) )
3772 QgsDebugError( QStringLiteral(
"Reencrypt FAILED, could not find config (id: %1)" ).arg( authcfg ) );
3777 if ( configstring.isEmpty() )
3779 QgsDebugError( QStringLiteral(
"Reencrypt FAILED, could not decrypt config (id: %1)" ).arg( authcfg ) );
3801 if ( storages.empty() )
3813bool QgsAuthManager::reencryptAllAuthenticationSettings(
const QString &prevpass,
const QString &prevciv )
3818 Q_UNUSED( prevpass )
3831 QStringList encryptedsettings;
3832 encryptedsettings <<
"";
3834 for (
const auto & sett, std::as_const( encryptedsettings ) )
3841 QSqlQuery query( authDbConnection() );
3843 query.prepare( QStringLiteral(
"SELECT value FROM %1 "
3844 "WHERE setting = :setting" ).arg( authDbSettingsTable() ) );
3846 query.bindValue(
":setting", sett );
3848 if ( !authDbQuery( &query ) )
3851 if ( !query.isActive() || !query.isSelect() )
3853 QgsDebugError( QStringLiteral(
"Reencrypt FAILED, query not active or a select operation for setting: %2" ).arg( sett ) );
3857 if ( query.first() )
3863 query.prepare( QStringLiteral(
"UPDATE %1 "
3864 "SET value = :value "
3865 "WHERE setting = :setting" ).arg( authDbSettingsTable() ) );
3867 query.bindValue(
":setting", sett );
3870 if ( !authDbStartTransaction() )
3873 if ( !authDbQuery( &query ) )
3876 if ( !authDbCommit() )
3879 QgsDebugMsgLevel( QStringLiteral(
"Reencrypt SUCCESS for setting: %2" ).arg( sett ), 2 );
3884 QgsDebugError( QStringLiteral(
"Reencrypt FAILED, could not find in db setting: %2" ).arg( sett ) );
3890 QgsDebugError( QStringLiteral(
"Select contains more than one for setting: %1" ).arg( sett ) );
3901bool QgsAuthManager::reencryptAllAuthenticationIdentities(
const QString &prevpass,
const QString &prevciv )
3910 for (
const auto &identid : ids )
3912 res = res && reencryptAuthenticationIdentity( identid, prevpass, prevciv );
3917bool QgsAuthManager::reencryptAuthenticationIdentity(
3918 const QString &identid,
3919 const QString &prevpass,
3920 const QString &prevciv )
3948 if ( keystring.isEmpty() )
3950 QgsDebugError( QStringLiteral(
"Reencrypt FAILED, could not decrypt identity id: %1" ).arg( identid ) );
3966 if ( storages.empty() )
3982 for (
const auto &cert : certs )
3985 QPair<QgsAuthCertUtils::CaCertSource, QSslCertificate>( source, cert ) );
3989QString QgsAuthManager::authPasswordHelperKeyName()
const
3993 QString dbProfilePath;
3999 const QFileInfo info( mAuthDatabaseConnectionUri );
4000 dbProfilePath = info.dir().dirName();
4004 dbProfilePath = QCryptographicHash::hash( ( mAuthDatabaseConnectionUri.toUtf8() ), QCryptographicHash::Md5 ).toHex();
4008 return AUTH_PASSWORD_HELPER_KEY_NAME_BASE + ( dbProfilePath.compare( QLatin1String(
"default" ), Qt::CaseInsensitive ) == 0 ? QString() : dbProfilePath );
4017 if ( qobject_cast<QgsAuthConfigurationStorageDb *>( storage ) )
MessageLevel
Level for messages This will be used both for message log and message bar in application.
@ Warning
Warning message.
@ Critical
Critical/error message.
@ Info
Information message.
AuthConfigurationStorageCapability
Authentication configuration storage capabilities.
@ CreateSetting
Can create a new authentication setting.
@ CreateConfiguration
Can create a new authentication configuration.
@ ClearStorage
Can clear all configurations from storage.
@ DeleteCertificateAuthority
Can delete a certificate authority.
@ DeleteSslCertificateCustomConfig
Can delete a SSL certificate custom config.
@ DeleteSetting
Can delete the authentication setting.
@ ReadSslCertificateCustomConfig
Can read a SSL certificate custom config.
@ DeleteMasterPassword
Can delete the master password.
@ CreateSslCertificateCustomConfig
Can create a new SSL certificate custom config.
@ ReadCertificateTrustPolicy
Can read a certificate trust policy.
@ ReadConfiguration
Can read an authentication configuration.
@ UpdateConfiguration
Can update an authentication configuration.
@ ReadCertificateAuthority
Can read a certificate authority.
@ CreateCertificateAuthority
Can create a new certificate authority.
@ DeleteConfiguration
Can deleet an authentication configuration.
@ ReadSetting
Can read the authentication settings.
@ CreateCertificateIdentity
Can create a new certificate identity.
@ ReadCertificateIdentity
Can read a certificate identity.
@ CreateCertificateTrustPolicy
Can create a new certificate trust policy.
@ ReadMasterPassword
Can read the master password.
@ CreateMasterPassword
Can create a new master password.
@ DeleteCertificateTrustPolicy
Can delete a certificate trust policy.
static QString sslErrorEnumString(QSslError::SslError errenum)
Gets short strings describing an SSL error.
static QString shaHexForCert(const QSslCertificate &cert, bool formatted=false)
Gets the sha1 hash for certificate.
CertTrustPolicy
Type of certificate trust policy.
static QMap< QString, QSslCertificate > mapDigestToCerts(const QList< QSslCertificate > &certs)
Map certificate sha1 to certificate as simple cache.
static QByteArray certsToPemText(const QList< QSslCertificate > &certs)
certsToPemText dump a list of QSslCertificates to PEM text
static bool certIsViable(const QSslCertificate &cert)
certIsViable checks for viability errors of cert and whether it is NULL
static QList< QSslCertificate > certsFromFile(const QString &certspath)
Returns a list of concatenated certs from a PEM or DER formatted file.
static bool certificateIsAuthorityOrIssuer(const QSslCertificate &cert)
Gets whether a certificate is an Authority or can at least sign other certificates.
CaCertSource
Type of CA certificate source.
Configuration container for SSL server connection exceptions or overrides.
bool isNull() const
Whether configuration is null (missing components)
const QList< QSslError::SslError > sslIgnoredErrorEnums() const
SSL server errors (as enum list) to ignore in connections.
const QSslCertificate sslCertificate() const
Server certificate object.
const QString sslHostPort() const
Server host:port string.
QSqlDatabase based implementation of QgsAuthConfigurationStorage.
bool removeCertTrustPolicy(const QSslCertificate &cert) override
Remove certificate trust policy.
const QgsAuthConfigSslServer loadSslCertCustomConfigByHost(const QString &hostport) const override
Loads an SSL certificate custom config by hostport (host:port)
QString loadAuthSetting(const QString &key) const override
Load an authentication setting from the storage.
bool removeAuthSetting(const QString &key) override
Remove an authentication setting from the storage.
const QMap< QString, QgsAuthCertUtils::CertTrustPolicy > caCertsPolicy() const override
Returns the map of CA certificates hashes in the storages and their trust policy.
QgsAuthCertUtils::CertTrustPolicy loadCertTrustPolicy(const QSslCertificate &cert) const override
Load certificate trust policy.
bool sslCertCustomConfigExists(const QString &id, const QString &hostport) override
Check if SSL certificate custom config exists.
bool removeCertIdentity(const QSslCertificate &cert) override
Remove a certificate identity from the storage.
const QPair< QSslCertificate, QString > loadCertIdentityBundle(const QString &id) const override
Returns a certificate identity bundle by id (sha hash).
const QList< QgsAuthConfigurationStorage::MasterPasswordConfig > masterPasswords() const override
Returns the list of (encrypted) master passwords stored in the database.
bool methodConfigExists(const QString &id) const override
Check if an authentication configuration exists in the storage.
QStringList certIdentityIds() const override
certIdentityIds get list of certificate identity ids from database
bool initialize() override
Initializes the storage.
bool storeMethodConfig(const QgsAuthMethodConfig &mconfig, const QString &payload) override
Store an authentication config in the database.
bool removeCertAuthority(const QSslCertificate &cert) override
Remove a certificate authority.
const QSslCertificate loadCertIdentity(const QString &id) const override
certIdentity get a certificate identity by id (sha hash)
const QList< QgsAuthConfigSslServer > sslCertCustomConfigs() const override
sslCertCustomConfigs get SSL certificate custom configs
QgsAuthMethodConfigsMap authMethodConfigs(const QStringList &allowedMethods=QStringList()) const override
Returns a mapping of authentication configurations available from this storage.
const QList< QSslCertificate > caCerts() const override
Returns the list of CA certificates in the storage.
bool certTrustPolicyExists(const QSslCertificate &cert) const override
Check if certificate trust policy exists.
const QSslCertificate loadCertAuthority(const QString &id) const override
certAuthority get a certificate authority by id (sha hash)
bool removeMethodConfig(const QString &id) override
Removes the authentication configuration with the specified id.
QgsAuthMethodConfigsMap authMethodConfigsWithPayload() const override
Returns a mapping of authentication configurations available from this storage.
bool certIdentityExists(const QString &id) const override
Check if the certificate identity exists.
bool certAuthorityExists(const QSslCertificate &cert) const override
Check if a certificate authority exists.
QgsAuthMethodConfig loadMethodConfig(const QString &id, QString &payload, bool full=false) const override
Load an authentication configuration from the database.
bool storeCertIdentity(const QSslCertificate &cert, const QString &keyPem) override
Store a certificate identity in the storage.
bool removeSslCertCustomConfig(const QString &id, const QString &hostport) override
Remove an SSL certificate custom config.
const QList< QSslCertificate > certIdentities() const override
certIdentities get certificate identities
QString name() const override
Returns a human readable localized short name of the storage implementation (e.g "SQLite").
bool authSettingExists(const QString &key) const override
Check if an authentication setting exists in the storage.
const QgsAuthConfigSslServer loadSslCertCustomConfig(const QString &id, const QString &hostport) const override
Loads an SSL certificate custom config by id (sha hash) and hostport (host:port)
Registry for authentication configuration storages.
QgsAuthConfigurationStorage * firstReadyStorageWithCapability(Qgis::AuthConfigurationStorageCapability capability) const
Returns the first ready (and enabled) authentication configuration storage which has the required cap...
QList< QgsAuthConfigurationStorage * > storages() const
Returns the list of all registered authentication configuration storages.
QList< QgsAuthConfigurationStorage * > readyStoragesWithCapability(Qgis::AuthConfigurationStorageCapability capability) const
Returns the list of all ready (and enabled) authentication configuration storage with the required ca...
QList< QgsAuthConfigurationStorage * > readyStorages() const
Returns the list of all ready (and enabled) authentication configuration storage.
bool addStorage(QgsAuthConfigurationStorage *storage)
Add an authentication configuration storage to the registry.
Abstract class that defines the interface for all authentication configuration storage implementation...
virtual void setReadOnly(bool readOnly)
Utility method to unset all editing capabilities.
void methodConfigChanged()
Emitted when the storage method config table was changed.
Qgis::AuthConfigurationStorageCapabilities capabilities() const
Returns the capabilities of the storage.
bool isEnabled() const
Returns true if the storage is enabled.
bool isEncrypted() const
Returns true if the storage is encrypted.
void messageLog(const QString &message, const QString &tag=QStringLiteral("Authentication"), Qgis::MessageLevel level=Qgis::MessageLevel::Info)
Custom logging signal to relay to console output and QgsMessageLog.
virtual QString lastError() const
Returns the last error message.
static void passwordKeyHash(const QString &pass, QString *salt, QString *hash, QString *cipheriv=nullptr)
Generate SHA256 hash for master password, with iterations and salt.
static const QString encrypt(const QString &pass, const QString &cipheriv, const QString &text)
Encrypt data using master password.
static bool verifyPasswordKeyHash(const QString &pass, const QString &salt, const QString &hash, QString *hashderived=nullptr)
Verify existing master password hash to a re-generated one.
static const QString decrypt(const QString &pass, const QString &cipheriv, const QString &text)
Decrypt data using master password.
Singleton offering an interface to manage the authentication configuration database and to utilize co...
bool storeAuthSetting(const QString &key, const QVariant &value, bool encrypt=false)
Store an authentication setting (stored as string via QVariant( value ).toString() )
bool setDefaultCertTrustPolicy(QgsAuthCertUtils::CertTrustPolicy policy)
Sets the default certificate trust policy preferred by user.
void clearAllCachedConfigs()
Clear all authentication configs from authentication method caches.
const QSslCertificate certIdentity(const QString &id)
certIdentity get a certificate identity by id (sha hash)
const QStringList certIdentityBundleToPem(const QString &id)
certIdentityBundleToPem get a certificate identity bundle by id (sha hash) returned as PEM text
bool updateIgnoredSslErrorsCache(const QString &shahostport, const QList< QSslError > &errors)
Update ignored SSL error cache with possible ignored SSL errors, using sha:host:port key.
bool verifyMasterPassword(const QString &compare=QString())
Verify the supplied master password against any existing hash in authentication database.
bool updateIgnoredSslErrorsCacheFromConfig(const QgsAuthConfigSslServer &config)
Update ignored SSL error cache with possible ignored SSL errors, using server config.
const QString disabledMessage() const
Standard message for when QCA's qca-ossl plugin is missing and system is disabled.
const QList< QSslCertificate > trustedCaCertsCache()
trustedCaCertsCache cache of trusted certificate authorities, ready for network connections
QgsAuthMethod * configAuthMethod(const QString &authcfg)
Gets authentication method from the config/provider cache.
static bool isFilesystemBasedDatabase(const QString &uri)
Returns the true if the uri is a filesystem-based database (SQLite).
bool storeCertIdentity(const QSslCertificate &cert, const QSslKey &key)
Store a certificate identity.
QgsAuthMethodsMap authMethodsMap(const QString &dataprovider=QString())
Gets available authentication methods mapped to their key.
bool rebuildIgnoredSslErrorCache()
Rebuild ignoredSSL error cache.
bool initSslCaches()
Initialize various SSL authentication caches.
const QList< QSslCertificate > extraFileCAs()
extraFileCAs extra file-based certificate authorities
bool removeAuthSetting(const QString &key)
Remove an authentication setting.
bool storeCertTrustPolicy(const QSslCertificate &cert, QgsAuthCertUtils::CertTrustPolicy policy)
Store user trust value for a certificate.
bool rebuildCaCertsCache()
Rebuild certificate authority cache.
bool scheduledAuthDatabaseErase()
Whether there is a scheduled opitonal erase of authentication database.
bool eraseAuthenticationDatabase(bool backup, QString *backuppath=nullptr)
Erase all rows from all tables in authentication database.
static bool passwordHelperEnabled()
Password helper enabled getter.
void passwordHelperMessageLog(const QString &message, const QString &tag=QgsAuthManager::AUTH_MAN_TAG, Qgis::MessageLevel level=Qgis::MessageLevel::Info)
Custom logging signal to inform the user about master password <-> password manager interactions.
bool exportAuthenticationConfigsToXml(const QString &filename, const QStringList &authcfgs, const QString &password=QString())
Export authentication configurations to an XML file.
Q_DECL_DEPRECATED bool init(const QString &pluginPath=QString(), const QString &authDatabasePath=QString())
init initialize QCA, prioritize qca-ossl plugin and optionally set up the authentication database
void authDatabaseChanged()
Emitted when the authentication db is significantly changed, e.g. large record removal,...
void setPasswordHelperEnabled(bool enabled)
Password helper enabled setter.
void setScheduledAuthDatabaseErase(bool scheduleErase)
Schedule an optional erase of authentication database, starting when mutex is lockable.
const QList< QgsAuthConfigSslServer > sslCertCustomConfigs()
sslCertCustomConfigs get SSL certificate custom configs
const QList< QSslCertificate > untrustedCaCerts(QList< QSslCertificate > trustedCAs=QList< QSslCertificate >())
untrustedCaCerts get list of untrusted certificate authorities
const QString uniqueConfigId() const
Gets a unique generated 7-character string to assign to as config id.
const QPair< QSslCertificate, QSslKey > certIdentityBundle(const QString &id)
Gets a certificate identity bundle by id (sha hash).
bool isDisabled() const
Whether QCA has the qca-ossl plugin, which a base run-time requirement.
QVariant authSetting(const QString &key, const QVariant &defaultValue=QVariant(), bool decrypt=false)
authSetting get an authentication setting (retrieved as string and returned as QVariant( QString ))
static const QString AUTH_MAN_TAG
The display name of the Authentication Manager.
QgsAuthCertUtils::CertTrustPolicy defaultCertTrustPolicy()
Gets the default certificate trust policy preferred by user.
const QByteArray trustedCaCertsPemText()
trustedCaCertsPemText get concatenated string of all trusted CA certificates
static bool hasConfigId(const QString &txt)
Returns whether a string includes an authcfg ID token.
bool removeAllAuthenticationConfigs()
Clear all authentication configs from table in database and from provider caches.
QgsAuthCertUtils::CertTrustPolicy certificateTrustPolicy(const QSslCertificate &cert)
certificateTrustPolicy get trust policy for a particular certificate cert
static bool passwordHelperLoggingEnabled()
Password helper logging enabled getter.
QgsAuthConfigurationStorageRegistry * authConfigurationStorageRegistry() const
Returns the authentication configuration storage registry.
bool rebuildCertTrustCache()
Rebuild certificate authority cache.
Q_DECL_DEPRECATED const QString authenticationDatabasePath() const
The standard authentication database file in ~/.qgis3/ or defined location.
static const QList< QSslCertificate > systemRootCAs()
systemRootCAs get root system certificate authorities
bool removeCertAuthority(const QSslCertificate &cert)
Remove a certificate authority.
const QList< QSslCertificate > trustedCaCerts(bool includeinvalid=false)
trustedCaCerts get list of all trusted CA certificates
bool existsCertAuthority(const QSslCertificate &cert)
Check if a certificate authority exists.
const QMap< QString, QSslCertificate > mappedDatabaseCAs()
mappedDatabaseCAs get sha1-mapped database-stored certificate authorities
bool importAuthenticationConfigsFromXml(const QString &filename, const QString &password=QString(), bool overwrite=false)
Import authentication configurations from an XML file.
bool configIdUnique(const QString &id) const
Verify if provided authentication id is unique.
QStringList configIds() const
Gets list of authentication ids from database.
QString authManTag() const
Simple text tag describing authentication system for message logs.
bool loadAuthenticationConfig(const QString &authcfg, QgsAuthMethodConfig &mconfig, bool full=false)
Load an authentication config from the database into subclass.
QgsAuthCertUtils::CertTrustPolicy certTrustPolicy(const QSslCertificate &cert)
certTrustPolicy get whether certificate cert is trusted by user
bool masterPasswordHashInDatabase() const
Verify a password hash existing in authentication database.
Q_DECL_DEPRECATED void messageOut(const QString &message, const QString &tag=QgsAuthManager::AUTH_MAN_TAG, QgsAuthManager::MessageLevel level=QgsAuthManager::INFO) const
Custom logging signal to relay to console output and QgsMessageLog.
QgsAuthConfigurationStorageDb * defaultDbStorage() const
Transitional proxy to the first ready storage of database type.
bool updateNetworkProxy(QNetworkProxy &proxy, const QString &authcfg, const QString &dataprovider=QString())
Provider call to update a QNetworkProxy with an authentication config.
const QSslCertificate certAuthority(const QString &id)
Gets a certificate authority by id (sha hash)
void passwordHelperSuccess()
Signals emitted on password helper success, mainly used in the tests to exit main application loop.
bool registerCoreAuthMethods()
Instantiate and register existing C++ core authentication methods from plugins.
bool passwordHelperDelete()
Delete master password from wallet.
~QgsAuthManager() override
void dumpIgnoredSslErrorsCache_()
Utility function to dump the cache for debug purposes.
const QList< QSslCertificate > databaseCAs()
databaseCAs get database-stored certificate authorities
void messageLog(const QString &message, const QString &tag=QgsAuthManager::AUTH_MAN_TAG, Qgis::MessageLevel level=Qgis::MessageLevel::Info) const
Custom logging signal to relay to console output and QgsMessageLog.
bool backupAuthenticationDatabase(QString *backuppath=nullptr)
Close connection to current authentication database and back it up.
void authDatabaseEraseRequested()
Emitted when a user has indicated they may want to erase the authentication db.
void passwordHelperFailure()
Signals emitted on password helper failure, mainly used in the tests to exit main application loop.
bool existsSslCertCustomConfig(const QString &id, const QString &hostport)
Check if SSL certificate custom config exists.
bool existsAuthSetting(const QString &key)
Check if an authentication setting exists.
void clearCachedConfig(const QString &authcfg)
Clear an authentication config from its associated authentication method cache.
void clearMasterPassword()
Clear supplied master password.
bool updateNetworkRequest(QNetworkRequest &request, const QString &authcfg, const QString &dataprovider=QString())
Provider call to update a QNetworkRequest with an authentication config.
const QList< QSslCertificate > certIdentities()
certIdentities get certificate identities
bool storeCertAuthority(const QSslCertificate &cert)
Store a certificate authority.
QStringList certIdentityIds() const
certIdentityIds get list of certificate identity ids from database
bool removeCertTrustPolicies(const QList< QSslCertificate > &certs)
Remove a group certificate authorities.
QgsAuthMethod * authMethod(const QString &authMethodKey)
Gets authentication method from the config/provider cache via its key.
bool updateDataSourceUriItems(QStringList &connectionItems, const QString &authcfg, const QString &dataprovider=QString())
Provider call to update a QgsDataSourceUri with an authentication config.
void setup(const QString &pluginPath=QString(), const QString &authDatabasePath=QString())
Sets up the authentication manager configuration.
static QgsAuthManager * instance()
Enforce singleton pattern.
Q_DECL_DEPRECATED QSqlDatabase authDatabaseConnection() const
Sets up the application instance of the authentication database connection.
void updateConfigAuthMethods()
Sync the confg/authentication method cache with what is in database.
bool storeSslCertCustomConfig(const QgsAuthConfigSslServer &config)
Store an SSL certificate custom config.
static void setPasswordHelperLoggingEnabled(bool enabled)
Password helper logging enabled setter.
bool ensureInitialized() const
Performs lazy initialization of the authentication framework, if it has not already been done.
const QgsAuthConfigSslServer sslCertCustomConfigByHost(const QString &hostport)
sslCertCustomConfigByHost get an SSL certificate custom config by hostport (host:port)
bool updateAuthenticationConfig(const QgsAuthMethodConfig &config)
Update an authentication config in the database.
bool existsCertIdentity(const QString &id)
Check if a certificate identity exists.
const QString authenticationDatabaseUri() const
Returns the authentication database connection URI.
bool resetMasterPassword(const QString &newpass, const QString &oldpass, bool keepbackup, QString *backuppath=nullptr)
Reset the master password to a new one, then re-encrypt all previous configs in a new database file,...
QStringList authMethodsKeys(const QString &dataprovider=QString())
Gets keys of supported authentication methods.
bool passwordHelperSync()
Store the password manager into the wallet.
bool masterPasswordIsSet() const
Whether master password has be input and verified, i.e. authentication database is accessible.
const QString methodConfigTableName() const
Returns the database table from the first ready storage that stores authentication configs,...
void masterPasswordVerified(bool verified)
Emitted when a password has been verify (or not)
bool setMasterPassword(bool verify=false)
Main call to initially set or continually check master password is set.
bool storeCertAuthorities(const QList< QSslCertificate > &certs)
Store multiple certificate authorities.
bool removeSslCertCustomConfig(const QString &id, const QString &hostport)
Remove an SSL certificate custom config.
static const QString AUTH_PASSWORD_HELPER_DISPLAY_NAME
The display name of the password helper (platform dependent)
bool updateNetworkReply(QNetworkReply *reply, const QString &authcfg, const QString &dataprovider=QString())
Provider call to update a QNetworkReply with an authentication config (used to skip known SSL errors,...
bool rebuildTrustedCaCertsCache()
Rebuild trusted certificate authorities cache.
const QgsAuthMethodMetadata * authMethodMetadata(const QString &authMethodKey)
Gets authentication method metadata via its key.
bool removeAuthenticationConfig(const QString &authcfg)
Remove an authentication config in the database.
bool removeCertTrustPolicy(const QSslCertificate &cert)
Remove a certificate authority.
const QString authenticationDatabaseUriStripped() const
Returns the authentication database connection URI with the password stripped.
QgsAuthMethod::Expansions supportedAuthMethodExpansions(const QString &authcfg)
Gets supported authentication method expansion(s), e.g.
const QgsAuthConfigSslServer sslCertCustomConfig(const QString &id, const QString &hostport)
sslCertCustomConfig get an SSL certificate custom config by id (sha hash) and hostport (host:port)
QgsAuthMethodConfigsMap availableAuthMethodConfigs(const QString &dataprovider=QString())
Gets mapping of authentication config ids and their base configs (not decrypted data)
bool masterPasswordSame(const QString &password) const
Check whether supplied password is the same as the one already set.
bool storeAuthenticationConfig(QgsAuthMethodConfig &mconfig, bool overwrite=false)
Store an authentication config in the database.
bool removeCertIdentity(const QString &id)
Remove a certificate identity.
QString configAuthMethodKey(const QString &authcfg) const
Gets key of authentication method associated with config ID.
Configuration storage class for authentication method configurations.
bool isValid(bool validateid=false) const
Whether the configuration is valid.
bool readXml(const QDomElement &element)
from a DOM element.
const QString configString() const
The extended configuration, as stored and retrieved from the authentication database.
const QString id() const
Gets 'authcfg' 7-character alphanumeric ID of the config.
void loadConfigString(const QString &configstr)
Load existing extended configuration.
bool writeXml(QDomElement &parentElement, QDomDocument &document)
Stores the configuration in a DOM.
void setId(const QString &id)
Sets auth config ID.
A registry / canonical manager of authentication methods.
const QgsAuthMethodMetadata * authMethodMetadata(const QString &authMethodKey) const
Returns metadata of the auth method or nullptr if not found.
static QgsAuthMethodRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
QStringList authMethodList() const
Returns list of available auth methods by their keys.
QgsAuthMethod * createAuthMethod(const QString &authMethodKey)
Create an instance of the auth method.
Abstract base class for authentication method plugins.
virtual bool updateNetworkProxy(QNetworkProxy &proxy, const QString &authcfg, const QString &dataprovider=QString())
Update proxy settings with authentication components.
virtual bool updateNetworkRequest(QNetworkRequest &request, const QString &authcfg, const QString &dataprovider=QString())
Update a network request with authentication components.
QgsAuthMethod::Expansions supportedExpansions() const
Flags that represent the update points (where authentication configurations are expanded) supported b...
virtual void clearCachedConfig(const QString &authcfg)=0
Clear any cached configuration.
virtual void updateMethodConfig(QgsAuthMethodConfig &mconfig)=0
Update an authentication configuration in place.
virtual bool updateNetworkReply(QNetworkReply *reply, const QString &authcfg, const QString &dataprovider=QString())
Update a network reply with authentication components.
virtual bool updateDataSourceUriItems(QStringList &connectionItems, const QString &authcfg, const QString &dataprovider=QString())
Update data source connection items with authentication components.
QFlags< Expansion > Expansions
static QgsCredentials * instance()
retrieves instance
bool getMasterPassword(QString &password, bool stored=false)
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
Custom exception class which is raised when an operation is not supported.
Scoped object for logging of the runtime for a single operation or group of operations.
This class is a composition of two QSettings instances:
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
#define Q_NOWARN_DEPRECATED_POP
#define Q_NOWARN_DEPRECATED_PUSH
QHash< QString, QgsAuthMethodConfig > QgsAuthMethodConfigsMap
QHash< QString, QgsAuthMethod * > QgsAuthMethodsMap
#define QgsDebugMsgLevel(str, level)
#define QgsDebugError(str)
Structure that holds the (encrypted) master password elements.