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 );
369 mPluginPath = pluginPath;
370 mAuthDatabaseConnectionUri = authDatabasePath;
379 QgsDebugError( QStringLiteral(
"Authentication system DISABLED: QCA's qca-ossl (OpenSSL) plugin is missing" ) );
381 return mAuthDisabled;
388 return tr(
"Authentication system is DISABLED:\n%1" ).arg( mAuthDisabledMessage );
392const QString QgsAuthManager::sqliteDatabasePath()
const
400 QString path = mAuthDatabaseConnectionUri;
401 if ( path.startsWith( QStringLiteral(
"QSQLITE://" ), Qt::CaseSensitivity::CaseInsensitive ) )
403 path = path.mid( 10 );
405 else if ( path.startsWith( QStringLiteral(
"QSPATIALITE://" ), Qt::CaseSensitivity::CaseInsensitive ) )
407 path = path.mid( 14 );
410 return QDir::cleanPath( path );
415 return sqliteDatabasePath();
422 QMutexLocker locker( mMasterPasswordMutex.get() );
426 if ( mScheduledDbErase )
429 if ( mMasterPass.isEmpty() )
431 QgsDebugMsgLevel( QStringLiteral(
"Master password is not yet set by user" ), 2 );
432 if ( !masterPasswordInput() )
434 QgsDebugMsgLevel( QStringLiteral(
"Master password input canceled by user" ), 2 );
448 QgsDebugMsgLevel( QStringLiteral(
"Master password is set and verified" ), 2 );
456 QMutexLocker locker( mMutex.get() );
460 if ( mScheduledDbErase )
464 QString prevpass = QString( mMasterPass );
468 mMasterPass = prevpass;
469 const char *err = QT_TR_NOOP(
"Master password set: FAILED to verify, reset to previous" );
475 QgsDebugMsgLevel( QStringLiteral(
"Master password set: SUCCESS%1" ).arg( verify ?
" and verified" :
"" ), 2 );
487 if ( !masterPasswordRowsInDb( &rows ) )
489 const char *err = QT_TR_NOOP(
"Master password: FAILED to access database" );
497 QgsDebugMsgLevel( QStringLiteral(
"Master password: %1 rows in database" ).arg( rows ), 2 );
501 const char *err = QT_TR_NOOP(
"Master password: FAILED to find just one master password record in database" );
508 else if ( rows == 1 )
510 if ( !masterPasswordCheckAgainstDb( compare ) )
512 if ( compare.isNull() )
514 const char *err = QT_TR_NOOP(
"Master password: FAILED to verify against hash in database" );
523 if ( mPassTries >= 5 )
525 mAuthDisabled =
true;
526 const char *err = QT_TR_NOOP(
"Master password: failed 5 times authentication system DISABLED" );
534 QgsDebugMsgLevel( QStringLiteral(
"Master password: verified against hash in database" ), 2 );
535 if ( compare.isNull() )
539 else if ( compare.isNull() )
541 if ( !masterPasswordStoreInDb() )
543 const char *err = QT_TR_NOOP(
"Master password: hash FAILED to be stored in database" );
552 QgsDebugMsgLevel( QStringLiteral(
"Master password: hash stored in database" ), 2 );
555 if ( !masterPasswordCheckAgainstDb() )
557 const char *err = QT_TR_NOOP(
"Master password: FAILED to verify against hash in database" );
567 QgsDebugMsgLevel( QStringLiteral(
"Master password: verified against hash in database" ), 2 );
579 return !mMasterPass.isEmpty();
586 return mMasterPass == pass;
590 bool keepbackup, QString *backuppath )
606 QgsDebugMsgLevel( QStringLiteral(
"Master password reset: backed up current database" ), 2 );
609 QString prevpass = QString( mMasterPass );
610 QString prevciv = QString( masterPasswordCiv() );
616 if ( ok && !masterPasswordClearDb() )
619 const char *err = QT_TR_NOOP(
"Master password reset FAILED: could not clear current password from database" );
625 QgsDebugMsgLevel( QStringLiteral(
"Master password reset: cleared current password from database" ), 2 );
632 if ( ok && !masterPasswordStoreInDb() )
635 const char *err = QT_TR_NOOP(
"Master password reset FAILED: could not store new password in database" );
641 QgsDebugMsgLevel( QStringLiteral(
"Master password reset: stored new password in database" ), 2 );
648 const char *err = QT_TR_NOOP(
"Master password reset FAILED: could not verify new password in database" );
654 if ( ok && !reencryptAllAuthenticationConfigs( prevpass, prevciv ) )
657 const char *err = QT_TR_NOOP(
"Master password reset FAILED: could not re-encrypt configs in database" );
663 QgsDebugMsgLevel( QStringLiteral(
"Master password reset: re-encrypted configs in database" ), 2 );
667 if ( ok && !verifyPasswordCanDecryptConfigs() )
670 const char *err = QT_TR_NOOP(
"Master password reset FAILED: could not verify password can decrypt re-encrypted configs" );
675 if ( ok && !reencryptAllAuthenticationSettings( prevpass, prevciv ) )
678 const char *err = QT_TR_NOOP(
"Master password reset FAILED: could not re-encrypt settings in database" );
683 if ( ok && !reencryptAllAuthenticationIdentities( prevpass, prevciv ) )
686 const char *err = QT_TR_NOOP(
"Master password reset FAILED: could not re-encrypt identities in database" );
695 QString errdbbackup( dbbackup );
696 errdbbackup.replace( QLatin1String(
".db" ), QLatin1String(
"_ERROR.db" ) );
697 QFile::rename( sqliteDatabasePath(), errdbbackup );
698 QgsDebugError( QStringLiteral(
"Master password reset FAILED: backed up failed db at %1" ).arg( errdbbackup ) );
700 QFile::rename( dbbackup, sqliteDatabasePath() );
701 mMasterPass = prevpass;
702 QgsDebugError( QStringLiteral(
"Master password reset FAILED: reinstated previous password and database" ) );
706 *backuppath = errdbbackup;
712 if ( !keepbackup && !QFile::remove( dbbackup ) )
714 const char *err = QT_TR_NOOP(
"Master password reset: could not remove old database backup" );
722 QgsDebugMsgLevel( QStringLiteral(
"Master password reset: backed up previous db at %1" ).arg( dbbackup ), 2 );
724 *backuppath = dbbackup;
736 mScheduledDbErase = scheduleErase;
738 mScheduledDbEraseRequestEmitted =
false;
739 mScheduledDbEraseRequestCount = 0;
743 if ( !mScheduledDbEraseTimer )
745 mScheduledDbEraseTimer =
new QTimer(
this );
746 connect( mScheduledDbEraseTimer, &QTimer::timeout,
this, &QgsAuthManager::tryToStartDbErase );
747 mScheduledDbEraseTimer->start( mScheduledDbEraseRequestWait * 1000 );
749 else if ( !mScheduledDbEraseTimer->isActive() )
751 mScheduledDbEraseTimer->start();
756 if ( mScheduledDbEraseTimer && mScheduledDbEraseTimer->isActive() )
757 mScheduledDbEraseTimer->stop();
766 qDeleteAll( mAuthMethods );
767 mAuthMethods.clear();
769 for (
const auto &authMethodKey : methods )
774 return !mAuthMethods.isEmpty();
786#ifndef __clang_analyzer__
789 QTimer::singleShot( 3, &loop, &QEventLoop::quit );
796 for (
int i = 0; i < len; i++ )
798 switch ( QRandomGenerator::system()->generate() % 2 )
801 id +=
static_cast<char>(
'0' + QRandomGenerator::system()->generate() % 10 );
804 id +=
static_cast<char>(
'a' + QRandomGenerator::system()->generate() % 26 );
808 if ( !configids.contains(
id ) )
813 QgsDebugMsgLevel( QStringLiteral(
"Generated unique ID: %1" ).arg(
id ), 2 );
826 const char *err = QT_TR_NOOP(
"Config ID is empty" );
832 return !configids.contains(
id );
837 const thread_local QRegularExpression authCfgRegExp( AUTH_CFG_REGEX );
838 return txt.indexOf( authCfgRegExp ) != -1;
845 QMutexLocker locker( mMutex.get() );
846 QStringList providerAuthMethodsKeys;
847 if ( !dataprovider.isEmpty() )
864 if ( providerAuthMethodsKeys.isEmpty() || providerAuthMethodsKeys.contains( config.method() ) )
867 if ( baseConfigs.contains( config.id() ) )
874 baseConfigs.insert( config.id(), config );
880 if ( storages.empty() )
883 QgsDebugError( QStringLiteral(
"No credentials storages found" ) );
902 if ( !
configIds.contains( config.id() ) )
904 mConfigAuthMethods.insert( config.id(), config.method() );
905 QgsDebugMsgLevel( QStringLiteral(
"Stored auth config/methods:\n%1 %2" ).arg( config.id(), config.method() ), 2 );
911 QgsDebugMsgLevel( QStringLiteral(
"A config with same id %1 was already added, skipping from %2" ).arg( config.id(), storage->
name() ), 2 );
924 if ( !mConfigAuthMethods.contains( authcfg ) )
926 QgsDebugError( QStringLiteral(
"No config auth method found in database for authcfg: %1" ).arg( authcfg ) );
930 QString authMethodKey = mConfigAuthMethods.value( authcfg );
942 return mConfigAuthMethods.value( authcfg, QString() );
957 if ( !mAuthMethods.contains( authMethodKey ) )
959 QgsDebugError( QStringLiteral(
"No auth method registered for auth method key: %1" ).arg( authMethodKey ) );
963 return mAuthMethods.value( authMethodKey );
970 if ( !mAuthMethods.contains( authMethodKey ) )
972 QgsDebugError( QStringLiteral(
"No auth method registered for auth method key: %1" ).arg( authMethodKey ) );
984 if ( dataprovider.isEmpty() )
990 QgsAuthMethodsMap::const_iterator i = mAuthMethods.constBegin();
991 while ( i != mAuthMethods.constEnd() )
994 && ( i.value()->supportedDataProviders().contains( QStringLiteral(
"all" ) )
995 || i.value()->supportedDataProviders().contains( dataprovider ) ) )
997 filteredmap.insert( i.key(), i.value() );
1005QWidget *QgsAuthManager::authMethodEditWidget(
const QString &authMethodKey, QWidget *parent )
1011 return method->editWidget( parent );
1036 QMutexLocker locker( mMutex.get() );
1043 const char *err = QT_TR_NOOP(
"Store config: FAILED because config is invalid" );
1049 QString uid = config.
id();
1050 bool passedinID = !uid.isEmpty();
1051 if ( uid.isEmpty() )
1059 const char *err = QT_TR_NOOP(
"Store config: FAILED because pre-defined config ID %1 is not unique" );
1067 const char *err = QT_TR_NOOP(
"Store config: FAILED because pre-defined config ID %1 could not be removed" );
1076 if ( configstring.isEmpty() )
1078 const char *err = QT_TR_NOOP(
"Store config: FAILED because config string is empty" );
1086 if ( defaultStorage->isEncrypted() )
1093 configCopy.
setId( uid );
1094 if ( !defaultStorage->storeMethodConfig( configCopy, configstring ) )
1108 config.
setId( uid );
1112 QgsDebugMsgLevel( QStringLiteral(
"Store config SUCCESS for authcfg: %1" ).arg( uid ), 2 );
1120 QMutexLocker locker( mMutex.get() );
1125 if ( !config.
isValid(
true ) )
1127 const char *err = QT_TR_NOOP(
"Update config: FAILED because config is invalid" );
1134 if ( configstring.isEmpty() )
1136 const char *err = QT_TR_NOOP(
"Update config: FAILED because config is empty" );
1167 if ( storages.empty() )
1178 QgsDebugMsgLevel( QStringLiteral(
"Update config SUCCESS for authcfg: %1" ).arg( config.
id() ), 2 );
1193 QMutexLocker locker( mMutex.get() );
1205 if ( ! config.
isValid(
true ) || ( full && payload.isEmpty() ) )
1228 QgsDebugError( QStringLiteral(
"Update of authcfg %1 FAILED for auth method %2" ).arg( authcfg, authMethodKey ) );
1231 QgsDebugMsgLevel( QStringLiteral(
"Load %1 config SUCCESS for authcfg: %2" ).arg( full ?
"full" :
"base", authcfg ), 2 );
1236 if ( storages.empty() )
1252 QMutexLocker locker( mMutex.get() );
1256 if ( authcfg.isEmpty() )
1275 QgsDebugMsgLevel( QStringLiteral(
"REMOVED config for authcfg: %1" ).arg( authcfg ), 2 );
1282 if ( storages.empty() )
1299 if ( filename.isEmpty() )
1302 QDomDocument document( QStringLiteral(
"qgis_authentication" ) );
1303 QDomElement root = document.createElement( QStringLiteral(
"qgis_authentication" ) );
1304 document.appendChild( root );
1307 if ( !password.isEmpty() )
1312 root.setAttribute( QStringLiteral(
"salt" ), salt );
1313 root.setAttribute( QStringLiteral(
"hash" ), hash );
1314 root.setAttribute( QStringLiteral(
"civ" ), civ );
1317 QDomElement configurations = document.createElement( QStringLiteral(
"configurations" ) );
1318 for (
const QString &authcfg : authcfgs )
1325 authMethodConfig.
writeXml( configurations, document );
1328 if ( !password.isEmpty() )
1330 QString configurationsString;
1331 QTextStream ts( &configurationsString );
1332#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
1333 ts.setCodec(
"UTF-8" );
1335 configurations.save( ts, 2 );
1336 root.appendChild( document.createTextNode(
QgsAuthCrypto::encrypt( password, civ, configurationsString ) ) );
1340 root.appendChild( configurations );
1343 QFile file( filename );
1344 if ( !file.open( QFile::WriteOnly | QIODevice::Truncate ) )
1347 QTextStream ts( &file );
1348#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
1349 ts.setCodec(
"UTF-8" );
1351 document.save( ts, 2 );
1360 QFile file( filename );
1361 if ( !file.open( QFile::ReadOnly ) )
1366 QDomDocument document( QStringLiteral(
"qgis_authentication" ) );
1367 if ( !document.setContent( &file ) )
1374 QDomElement root = document.documentElement();
1375 if ( root.tagName() != QLatin1String(
"qgis_authentication" ) )
1380 QDomElement configurations;
1381 if ( root.hasAttribute( QStringLiteral(
"salt" ) ) )
1383 QString salt = root.attribute( QStringLiteral(
"salt" ) );
1384 QString hash = root.attribute( QStringLiteral(
"hash" ) );
1385 QString civ = root.attribute( QStringLiteral(
"civ" ) );
1390 configurations = document.firstChild().toElement();
1394 configurations = root.firstChildElement( QStringLiteral(
"configurations" ) );
1397 QDomElement configuration = configurations.firstChildElement();
1398 while ( !configuration.isNull() )
1401 authMethodConfig.
readXml( configuration );
1404 configuration = configuration.nextSiblingElement();
1413 QMutexLocker locker( mMutex.get() );
1419 if ( defaultStorage->clearMethodConfigs() )
1423 QgsDebugMsgLevel( QStringLiteral(
"REMOVED all configs from the default storage" ), 2 );
1428 QgsDebugMsgLevel( QStringLiteral(
"FAILED to remove all configs from the default storage" ), 2 );
1444 QMutexLocker locker( mMutex.get() );
1446 if ( sqliteDatabasePath().isEmpty() )
1448 const char *err = QT_TR_NOOP(
"The authentication database is not filesystem-based" );
1454 if ( !QFile::exists( sqliteDatabasePath() ) )
1456 const char *err = QT_TR_NOOP(
"No authentication database found" );
1466 if ( authConn.isValid() && authConn.isOpen() )
1470 QString datestamp( QDateTime::currentDateTime().toString( QStringLiteral(
"yyyy-MM-dd-hhmmss" ) ) );
1471 QString dbbackup( sqliteDatabasePath() );
1472 dbbackup.replace( QLatin1String(
".db" ), QStringLiteral(
"_%1.db" ).arg( datestamp ) );
1474 if ( !QFile::copy( sqliteDatabasePath(), dbbackup ) )
1476 const char *err = QT_TR_NOOP(
"Could not back up authentication database" );
1483 *backuppath = dbbackup;
1485 QgsDebugMsgLevel( QStringLiteral(
"Backed up auth database at %1" ).arg( dbbackup ), 2 );
1493 QMutexLocker locker( mMutex.get() );
1504 if ( backuppath && !dbbackup.isEmpty() )
1505 *backuppath = dbbackup;
1509 if ( defaultStorage->erase() )
1511 mMasterPass = QString();
1539 const QString &dataprovider )
1551 QgsDebugError( QStringLiteral(
"Network request updating not supported by authcfg: %1" ).arg( authcfg ) );
1566 const QString &dataprovider )
1578 QgsDebugMsgLevel( QStringLiteral(
"Network reply updating not supported by authcfg: %1" ).arg( authcfg ), 3 );
1594 const QString &dataprovider )
1606 QgsDebugError( QStringLiteral(
"Data source URI updating not supported by authcfg: %1" ).arg( authcfg ) );
1633 QgsDebugError( QStringLiteral(
"Proxy updating not supported by authcfg: %1" ).arg( authcfg ) );
1642 QgsDebugMsgLevel( QStringLiteral(
"Proxy updated successfully from authcfg: %1" ).arg( authcfg ), 2 );
1653 QMutexLocker locker( mMutex.get() );
1654 if ( key.isEmpty() )
1657 QString storeval( value.toString() );
1680 if ( !defaultStorage->storeAuthSetting( key, storeval ) )
1698 QMutexLocker locker( mMutex.get() );
1699 if ( key.isEmpty() )
1705 QVariant value = defaultValue;
1713 if ( !storeval.isEmpty() )
1724 if ( storages.empty() )
1736 QMutexLocker locker( mMutex.get() );
1737 if ( key.isEmpty() )
1751 if ( storages.empty() )
1763 QMutexLocker locker( mMutex.get() );
1764 if ( key.isEmpty() )
1791 if ( storages.empty() )
1806 QMutexLocker locker( mMutex.get() );
1812 mCustomConfigByHostCache.clear();
1813 mHasCheckedIfCustomConfigByHostExists =
false;
1816 QgsDebugError( QStringLiteral(
"Init of SSL caches FAILED" ) );
1824 QMutexLocker locker( mMutex.get() );
1825 if ( cert.isNull() )
1827 QgsDebugError( QStringLiteral(
"Passed certificate is null" ) );
1832 QgsDebugError( QStringLiteral(
"Passed private key is null" ) );
1844 QgsDebugError( QStringLiteral(
"Store certificate identity: FAILED to remove pre-existing certificate identity %1" ).arg(
id ) );
1852 if ( !defaultStorage->storeCertIdentity( cert, keypem ) )
1870 QMutexLocker locker( mMutex.get() );
1872 QSslCertificate cert;
1883 if ( !cert.isNull() )
1889 if ( storages.empty() )
1901 QMutexLocker locker( mMutex.get() );
1902 QPair<QSslCertificate, QSslKey> bundle;
1917 if ( encryptedBundle.first.isNull() )
1919 QgsDebugError( QStringLiteral(
"Certificate identity bundle is null for id: %1" ).arg(
id ) );
1922 QSslKey key(
QgsAuthCrypto::decrypt( mMasterPass, masterPasswordCiv(), encryptedBundle.second ).toLatin1(),
1923 QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey );
1926 QgsDebugError( QStringLiteral(
"Certificate identity bundle: FAILED to create private key" ) );
1929 bundle = qMakePair( encryptedBundle.first, key );
1934 if ( storages.empty() )
1947 QMutexLocker locker( mMutex.get() );
1951 return QStringList() << QString( bundle.first.toPem() ) << QString( bundle.second.toPem() );
1953 return QStringList();
1960 QMutexLocker locker( mMutex.get() );
1961 QList<QSslCertificate> certs;
1968 const QList<QSslCertificate> storageCerts = storage->
certIdentities();
1970 for (
const QSslCertificate &cert : std::as_const( storageCerts ) )
1972 if ( !certs.contains( cert ) )
1974 certs.append( cert );
1983 if ( storages.empty() )
1995 QMutexLocker locker( mMutex.get() );
2009 for (
const QString &
id : std::as_const( storageIds ) )
2011 if ( !ids.contains(
id ) )
2029 QMutexLocker locker( mMutex.get() );
2044 if ( storages.empty() )
2056 QMutexLocker locker( mMutex.get() );
2059 QgsDebugError( QStringLiteral(
"Passed bundle ID is empty" ) );
2079 if ( storages.empty() )
2092 QMutexLocker locker( mMutex.get() );
2104 QgsDebugError( QStringLiteral(
"Store SSL certificate custom config: FAILED to remove pre-existing config %1" ).arg(
id ) );
2110 if ( !defaultStorage->storeSslCertCustomConfig( config ) )
2123 mCustomConfigByHostCache.clear();
2132 QMutexLocker locker( mMutex.get() );
2135 if (
id.isEmpty() || hostport.isEmpty() )
2137 QgsDebugError( QStringLiteral(
"Passed config ID or host:port is empty" ) );
2161 if ( storages.empty() )
2175 if ( hostport.isEmpty() )
2180 QMutexLocker locker( mMutex.get() );
2182 if ( mCustomConfigByHostCache.contains( hostport ) )
2183 return mCustomConfigByHostCache.value( hostport );
2193 mCustomConfigByHostCache.insert( hostport, config );
2198 if ( storages.empty() )
2210 QMutexLocker locker( mMutex.get() );
2211 QList<QgsAuthConfigSslServer> configs;
2222 for (
const auto &config : std::as_const( storageConfigs ) )
2225 const QString hostPort = config.sslHostPort();
2226 const QString shaHostPort( QStringLiteral(
"%1:%2" ).arg(
id, hostPort ) );
2227 if ( ! ids.contains( shaHostPort ) )
2229 ids.append( shaHostPort );
2230 configs.append( config );
2239 if ( storages.empty() )
2251 QMutexLocker locker( mMutex.get() );
2252 if (
id.isEmpty() || hostPort.isEmpty() )
2254 QgsDebugError( QStringLiteral(
"Passed config ID or host:port is empty" ) );
2269 if ( storages.empty() )
2281 QMutexLocker locker( mMutex.get() );
2282 if (
id.isEmpty() || hostport.isEmpty() )
2284 QgsDebugError( QStringLiteral(
"Passed config ID or host:port is empty" ) );
2288 mCustomConfigByHostCache.clear();
2302 const QString shaHostPort( QStringLiteral(
"%1:%2" ).arg(
id, hostport ) );
2303 if ( mIgnoredSslErrorsCache.contains( shaHostPort ) )
2305 mIgnoredSslErrorsCache.remove( shaHostPort );
2311 if ( storages.empty() )
2324 QMutexLocker locker( mMutex.get() );
2325 if ( !mIgnoredSslErrorsCache.isEmpty() )
2327 QgsDebugMsgLevel( QStringLiteral(
"Ignored SSL errors cache items:" ), 1 );
2328 QHash<QString, QSet<QSslError::SslError> >::const_iterator i = mIgnoredSslErrorsCache.constBegin();
2329 while ( i != mIgnoredSslErrorsCache.constEnd() )
2332 for (
auto err : i.value() )
2336 QgsDebugMsgLevel( QStringLiteral(
"%1 = %2" ).arg( i.key(), errs.join(
", " ) ), 1 );
2350 QMutexLocker locker( mMutex.get() );
2357 QString shahostport( QStringLiteral(
"%1:%2" )
2360 if ( mIgnoredSslErrorsCache.contains( shahostport ) )
2362 mIgnoredSslErrorsCache.remove( shahostport );
2365 if ( !errenums.isEmpty() )
2367 mIgnoredSslErrorsCache.insert( shahostport, QSet<QSslError::SslError>( errenums.begin(), errenums.end() ) );
2368 QgsDebugMsgLevel( QStringLiteral(
"Update of ignored SSL errors cache SUCCEEDED for sha:host:port = %1" ).arg( shahostport ), 2 );
2373 QgsDebugMsgLevel( QStringLiteral(
"No ignored SSL errors to cache for sha:host:port = %1" ).arg( shahostport ), 2 );
2381 QMutexLocker locker( mMutex.get() );
2382 const thread_local QRegularExpression rx( QRegularExpression::anchoredPattern(
"\\S+:\\S+:\\d+" ) );
2383 if ( !rx.match( shahostport ).hasMatch() )
2385 QgsDebugError(
"Passed shahostport does not match \\S+:\\S+:\\d+, "
2386 "e.g. 74a4ef5ea94512a43769b744cda0ca5049a72491:www.example.com:443" );
2390 if ( mIgnoredSslErrorsCache.contains( shahostport ) )
2392 mIgnoredSslErrorsCache.remove( shahostport );
2395 if ( errors.isEmpty() )
2397 QgsDebugError( QStringLiteral(
"Passed errors list empty" ) );
2401 QSet<QSslError::SslError> errs;
2402 for (
const auto &error : errors )
2404 if ( error.error() == QSslError::NoError )
2407 errs.insert( error.error() );
2410 if ( errs.isEmpty() )
2412 QgsDebugError( QStringLiteral(
"Passed errors list does not contain errors" ) );
2416 mIgnoredSslErrorsCache.insert( shahostport, errs );
2418 QgsDebugMsgLevel( QStringLiteral(
"Update of ignored SSL errors cache SUCCEEDED for sha:host:port = %1" ).arg( shahostport ), 2 );
2427 QMutexLocker locker( mMutex.get() );
2428 QHash<QString, QSet<QSslError::SslError> > prevcache( mIgnoredSslErrorsCache );
2429 QHash<QString, QSet<QSslError::SslError> > nextcache;
2439 for (
const auto &config : std::as_const( customConfigs ) )
2442 if ( ! ids.contains( shaHostPort ) )
2444 ids.append( shaHostPort );
2445 if ( !config.sslIgnoredErrorEnums().isEmpty() )
2447 nextcache.insert( shaHostPort, QSet<QSslError::SslError>( config.sslIgnoredErrorEnums().cbegin(), config.sslIgnoredErrorEnums().cend() ) );
2449 if ( prevcache.contains( shaHostPort ) )
2451 prevcache.remove( shaHostPort );
2461 if ( !prevcache.isEmpty() )
2464 QHash<QString, QSet<QSslError::SslError> >::const_iterator i = prevcache.constBegin();
2465 while ( i != prevcache.constEnd() )
2467 nextcache.insert( i.key(), i.value() );
2472 if ( nextcache != mIgnoredSslErrorsCache )
2474 mIgnoredSslErrorsCache.clear();
2475 mIgnoredSslErrorsCache = nextcache;
2476 QgsDebugMsgLevel( QStringLiteral(
"Rebuild of ignored SSL errors cache SUCCEEDED" ), 2 );
2481 QgsDebugMsgLevel( QStringLiteral(
"Rebuild of ignored SSL errors cache SAME AS BEFORE" ), 2 );
2490 QMutexLocker locker( mMutex.get() );
2491 if ( certs.isEmpty() )
2493 QgsDebugError( QStringLiteral(
"Passed certificate list has no certs" ) );
2497 for (
const auto &cert : certs )
2509 QMutexLocker locker( mMutex.get() );
2512 if ( cert.isNull() )
2514 QgsDebugError( QStringLiteral(
"Passed certificate is null" ) );
2520 QgsDebugError( QStringLiteral(
"Store certificate authority: FAILED to remove pre-existing certificate authority" ) );
2526 return defaultStorage->storeCertAuthority( cert );
2541 QMutexLocker locker( mMutex.get() );
2542 QSslCertificate emptycert;
2543 QSslCertificate cert;
2553 if ( !cert.isNull() )
2559 if ( storages.empty() )
2572 QMutexLocker locker( mMutex.get() );
2573 if ( cert.isNull() )
2575 QgsDebugError( QStringLiteral(
"Passed certificate is null" ) );
2590 if ( storages.empty() )
2602 QMutexLocker locker( mMutex.get() );
2603 if ( cert.isNull() )
2605 QgsDebugError( QStringLiteral(
"Passed certificate is null" ) );
2632 if ( storages.empty() )
2642 return QSslConfiguration::systemCaCertificates();
2649 QMutexLocker locker( mMutex.get() );
2650 QList<QSslCertificate> certs;
2651 QList<QSslCertificate> filecerts;
2660 QString cafile( cafileval.toString() );
2661 if ( !cafile.isEmpty() && QFile::exists( cafile ) )
2666 for (
const auto &cert : std::as_const( filecerts ) )
2668 if ( !allowinvalid.toBool() && ( cert.isBlacklisted()
2670 || cert.expiryDate() <= QDateTime::currentDateTime()
2671 || cert.effectiveDate() > QDateTime::currentDateTime() ) )
2688 QMutexLocker locker( mMutex.get() );
2693 QList<QSslCertificate> certs;
2697 const QList<QSslCertificate> storageCerts = storage->
caCerts();
2699 for (
const QSslCertificate &cert : std::as_const( storageCerts ) )
2701 if ( !certs.contains( cert ) )
2703 certs.append( cert );
2712 if ( storages.empty() )
2724 QMutexLocker locker( mMutex.get() );
2732 QMutexLocker locker( mMutex.get() );
2733 mCaCertsCache.clear();
2739 bool res = !mCaCertsCache.isEmpty();
2741 QgsDebugError( QStringLiteral(
"Rebuild of CA certs cache FAILED" ) );
2749 QMutexLocker locker( mMutex.get() );
2750 if ( cert.isNull() )
2752 QgsDebugError( QStringLiteral(
"Passed certificate is null." ) );
2769 return defaultStorage->storeCertTrustPolicy( cert, policy );
2782 QMutexLocker locker( mMutex.get() );
2783 if ( cert.isNull() )
2785 QgsDebugError( QStringLiteral(
"Passed certificate is null" ) );
2801 if ( storages.empty() )
2813 QMutexLocker locker( mMutex.get() );
2814 if ( certs.empty() )
2816 QgsDebugError( QStringLiteral(
"Passed certificate list has no certs" ) );
2820 for (
const auto &cert : certs )
2832 QMutexLocker locker( mMutex.get() );
2833 if ( cert.isNull() )
2835 QgsDebugError( QStringLiteral(
"Passed certificate is null" ) );
2861 if ( storages.empty() )
2873 QMutexLocker locker( mMutex.get() );
2874 if ( cert.isNull() )
2884 if ( trustedids.contains(
id ) )
2888 else if ( untrustedids.contains(
id ) )
2904 return storeAuthSetting( QStringLiteral(
"certdefaulttrust" ),
static_cast< int >( policy ) );
2911 QMutexLocker locker( mMutex.get() );
2912 QVariant policy(
authSetting( QStringLiteral(
"certdefaulttrust" ) ) );
2924 QMutexLocker locker( mMutex.get() );
2925 mCertTrustCache.clear();
2936 for (
auto it = trustedCerts.cbegin(); it != trustedCerts.cend(); ++it )
2938 const QString
id { it.key( )};
2939 if ( ! ids.contains(
id ) )
2960 if ( ! storages.empty() )
2962 QgsDebugMsgLevel( QStringLiteral(
"Rebuild of cert trust policy cache SUCCEEDED" ), 2 );
2976 QMutexLocker locker( mMutex.get() );
2980 const QList<QPair<QgsAuthCertUtils::CaCertSource, QSslCertificate> > &certpairs( mCaCertsCache.values() );
2982 QList<QSslCertificate> trustedcerts;
2983 for (
int i = 0; i < certpairs.size(); ++i )
2985 QSslCertificate cert( certpairs.at( i ).second );
2987 if ( trustedids.contains( certid ) )
2990 trustedcerts.append( cert );
2996 trustedcerts.append( cert );
3001 QSslConfiguration sslconfig( QSslConfiguration::defaultConfiguration() );
3002 sslconfig.setCaCertificates( trustedcerts );
3003 QSslConfiguration::setDefaultConfiguration( sslconfig );
3005 return trustedcerts;
3012 QMutexLocker locker( mMutex.get() );
3013 if ( trustedCAs.isEmpty() )
3015 if ( mTrustedCaCertsCache.isEmpty() )
3022 const QList<QPair<QgsAuthCertUtils::CaCertSource, QSslCertificate> > &certpairs( mCaCertsCache.values() );
3024 QList<QSslCertificate> untrustedCAs;
3025 for (
int i = 0; i < certpairs.size(); ++i )
3027 QSslCertificate cert( certpairs.at( i ).second );
3028 if ( !trustedCAs.contains( cert ) )
3030 untrustedCAs.append( cert );
3033 return untrustedCAs;
3040 QMutexLocker locker( mMutex.get() );
3042 QgsDebugMsgLevel( QStringLiteral(
"Rebuilt trusted cert authorities cache" ), 2 );
3051 QMutexLocker locker( mMutex.get() );
3059 QMutexLocker locker( mMutex.get() );
3062 return passwordHelperWrite( mMasterPass );
3080 for (
const auto &authcfg : ids )
3100void QgsAuthManager::writeToConsole(
const QString &message,
3116 msg += QLatin1String(
"WARNING: " );
3119 msg += QLatin1String(
"ERROR: " );
3126 QTextStream out( stdout, QIODevice::WriteOnly );
3127 out << msg << Qt::endl;
3130void QgsAuthManager::tryToStartDbErase()
3134 ++mScheduledDbEraseRequestCount;
3136 int trycutoff = 90 / ( mScheduledDbEraseRequestWait ? mScheduledDbEraseRequestWait : 3 );
3137 if ( mScheduledDbEraseRequestCount >= trycutoff )
3140 QgsDebugMsgLevel( QStringLiteral(
"authDatabaseEraseRequest emitting/scheduling canceled" ), 2 );
3145 QgsDebugMsgLevel( QStringLiteral(
"authDatabaseEraseRequest attempt (%1 of %2)" )
3146 .arg( mScheduledDbEraseRequestCount ).arg( trycutoff ), 2 );
3152 mScheduledDbEraseRequestEmitted =
true;
3157 QgsDebugMsgLevel( QStringLiteral(
"authDatabaseEraseRequest emitted" ), 2 );
3160 QgsDebugMsgLevel( QStringLiteral(
"authDatabaseEraseRequest emit skipped" ), 2 );
3166 QMutexLocker locker( mMutex.get() );
3168 QMapIterator<QThread *, QMetaObject::Connection> iterator( mConnectedThreads );
3169 while ( iterator.hasNext() )
3172 QThread::disconnect( iterator.value() );
3183 qDeleteAll( mAuthMethods );
3188 if ( authConn.isValid() && authConn.isOpen() )
3191 delete mScheduledDbEraseTimer;
3192 mScheduledDbEraseTimer =
nullptr;
3193 QSqlDatabase::removeDatabase( QStringLiteral(
"authentication.configs" ) );
3198 QMutexLocker locker( mMutex.get() );
3199 if ( ! mAuthConfigurationStorageRegistry )
3201 mAuthConfigurationStorageRegistry = std::make_unique<QgsAuthConfigurationStorageRegistry>();
3203 return mAuthConfigurationStorageRegistry.get();
3207QString QgsAuthManager::passwordHelperName()
const
3209 return tr(
"Password Helper" );
3213void QgsAuthManager::passwordHelperLog(
const QString &msg )
const
3229 QKeychain::DeletePasswordJob job( AUTH_PASSWORD_HELPER_FOLDER_NAME );
3232 job.setAutoDelete(
false );
3233 job.setKey( authPasswordHelperKeyName() );
3235 connect( &job, &QKeychain::Job::finished, &loop, &QEventLoop::quit );
3240 mPasswordHelperErrorCode = job.error();
3241 mPasswordHelperErrorMessage = tr(
"Delete password failed: %1." ).arg( job.errorString() );
3252 passwordHelperProcessError();
3256QString QgsAuthManager::passwordHelperRead()
3263 QKeychain::ReadPasswordJob job( AUTH_PASSWORD_HELPER_FOLDER_NAME );
3266 job.setAutoDelete(
false );
3267 job.setKey( authPasswordHelperKeyName() );
3269 connect( &job, &QKeychain::Job::finished, &loop, &QEventLoop::quit );
3274 mPasswordHelperErrorCode = job.error();
3281 password = job.textData();
3283 if ( password.isEmpty() )
3285 mPasswordHelperErrorCode = QKeychain::EntryNotFound;
3296 passwordHelperProcessError();
3300bool QgsAuthManager::passwordHelperWrite(
const QString &password )
3304 Q_ASSERT( !password.isEmpty() );
3307 QKeychain::WritePasswordJob job( AUTH_PASSWORD_HELPER_FOLDER_NAME );
3310 job.setAutoDelete(
false );
3311 job.setKey( authPasswordHelperKeyName() );
3312 job.setTextData( password );
3314 connect( &job, &QKeychain::Job::finished, &loop, &QEventLoop::quit );
3319 mPasswordHelperErrorCode = job.error();
3327 passwordHelperClearErrors();
3332 passwordHelperProcessError();
3347 emit
messageLog( enabled ? tr(
"Your %1 will be <b>used from now</b> on to store and retrieve the master password." )
3349 tr(
"Your %1 will <b>not be used anymore</b> to store and retrieve the master password." )
3366void QgsAuthManager::passwordHelperClearErrors()
3368 mPasswordHelperErrorCode = QKeychain::NoError;
3369 mPasswordHelperErrorMessage.clear();
3372void QgsAuthManager::passwordHelperProcessError()
3376 if ( mPasswordHelperErrorCode == QKeychain::AccessDenied ||
3377 mPasswordHelperErrorCode == QKeychain::AccessDeniedByUser ||
3378 mPasswordHelperErrorCode == QKeychain::NoBackendAvailable ||
3379 mPasswordHelperErrorCode == QKeychain::NotImplemented )
3385 mPasswordHelperErrorMessage = tr(
"There was an error and integration with your %1 system has been disabled. "
3386 "You can re-enable it at any time through the \"Utilities\" menu "
3387 "in the Authentication pane of the options dialog. %2" )
3390 if ( mPasswordHelperErrorCode != QKeychain::NoError )
3396 passwordHelperClearErrors();
3400bool QgsAuthManager::masterPasswordInput()
3408 bool storedPasswordIsValid =
false;
3414 pass = passwordHelperRead();
3415 if ( ! pass.isEmpty() && ( mPasswordHelperErrorCode == QKeychain::NoError ) )
3421 storedPasswordIsValid =
true;
3437 if ( ok && !pass.isEmpty() && mMasterPass != pass )
3442 if ( passwordHelperWrite( pass ) )
3456bool QgsAuthManager::masterPasswordRowsInDb(
int *rows )
const
3465 QMutexLocker locker( mMutex.get() );
3483 if ( storages.empty() )
3500 if ( !masterPasswordRowsInDb( &rows ) )
3502 const char *err = QT_TR_NOOP(
"Master password: FAILED to access database" );
3508 return ( rows == 1 );
3511bool QgsAuthManager::masterPasswordCheckAgainstDb(
const QString &compare )
const
3523 const QList<QgsAuthConfigurationStorage::MasterPasswordConfig> passwords { defaultStorage->masterPasswords( ) };
3524 if ( passwords.size() == 0 )
3547bool QgsAuthManager::masterPasswordStoreInDb()
const
3554 QString salt, hash, civ;
3562 return defaultStorage->storeMasterPassword( { salt, civ, hash } );
3578bool QgsAuthManager::masterPasswordClearDb()
3590 return defaultStorage->clearMasterPasswords();
3607const QString QgsAuthManager::masterPasswordCiv()
const
3618 const QList<QgsAuthConfigurationStorage::MasterPasswordConfig> passwords { defaultStorage->masterPasswords( ) };
3619 if ( passwords.size() == 0 )
3624 return passwords.first().civ;
3644 QStringList configKeys = QStringList();
3658 for (
auto it = configs.cbegin(); it != configs.cend(); ++it )
3660 if ( !configKeys.contains( it.key() ) )
3662 configKeys.append( it.key() );
3680bool QgsAuthManager::verifyPasswordCanDecryptConfigs()
const
3703 for (
auto it = configs.cbegin(); it != configs.cend(); ++it )
3705 QString configstring(
QgsAuthCrypto::decrypt( mMasterPass, masterPasswordCiv(), it.value().config( QStringLiteral(
"encrypted_payload" ) ) ) );
3706 if ( configstring.isEmpty() )
3708 QgsDebugError( QStringLiteral(
"Verify password can decrypt configs FAILED, could not decrypt a config (id: %1) from storage %2" )
3709 .arg( it.key(), storage->
name() ) );
3723 if ( storages.empty() )
3732bool QgsAuthManager::reencryptAllAuthenticationConfigs(
const QString &prevpass,
const QString &prevciv )
3741 for (
const auto &configid : ids )
3743 res = res && reencryptAuthenticationConfig( configid, prevpass, prevciv );
3748bool QgsAuthManager::reencryptAuthenticationConfig(
const QString &authcfg,
const QString &prevpass,
const QString &prevciv )
3773 if ( payload.isEmpty() || ! config.
isValid(
true ) )
3775 QgsDebugError( QStringLiteral(
"Reencrypt FAILED, could not find config (id: %1)" ).arg( authcfg ) );
3780 if ( configstring.isEmpty() )
3782 QgsDebugError( QStringLiteral(
"Reencrypt FAILED, could not decrypt config (id: %1)" ).arg( authcfg ) );
3804 if ( storages.empty() )
3816bool QgsAuthManager::reencryptAllAuthenticationSettings(
const QString &prevpass,
const QString &prevciv )
3821 Q_UNUSED( prevpass )
3834 QStringList encryptedsettings;
3835 encryptedsettings <<
"";
3837 for (
const auto & sett, std::as_const( encryptedsettings ) )
3844 QSqlQuery query( authDbConnection() );
3846 query.prepare( QStringLiteral(
"SELECT value FROM %1 "
3847 "WHERE setting = :setting" ).arg( authDbSettingsTable() ) );
3849 query.bindValue(
":setting", sett );
3851 if ( !authDbQuery( &query ) )
3854 if ( !query.isActive() || !query.isSelect() )
3856 QgsDebugError( QStringLiteral(
"Reencrypt FAILED, query not active or a select operation for setting: %2" ).arg( sett ) );
3860 if ( query.first() )
3866 query.prepare( QStringLiteral(
"UPDATE %1 "
3867 "SET value = :value "
3868 "WHERE setting = :setting" ).arg( authDbSettingsTable() ) );
3870 query.bindValue(
":setting", sett );
3873 if ( !authDbStartTransaction() )
3876 if ( !authDbQuery( &query ) )
3879 if ( !authDbCommit() )
3882 QgsDebugMsgLevel( QStringLiteral(
"Reencrypt SUCCESS for setting: %2" ).arg( sett ), 2 );
3887 QgsDebugError( QStringLiteral(
"Reencrypt FAILED, could not find in db setting: %2" ).arg( sett ) );
3893 QgsDebugError( QStringLiteral(
"Select contains more than one for setting: %1" ).arg( sett ) );
3904bool QgsAuthManager::reencryptAllAuthenticationIdentities(
const QString &prevpass,
const QString &prevciv )
3913 for (
const auto &identid : ids )
3915 res = res && reencryptAuthenticationIdentity( identid, prevpass, prevciv );
3920bool QgsAuthManager::reencryptAuthenticationIdentity(
3921 const QString &identid,
3922 const QString &prevpass,
3923 const QString &prevciv )
3951 if ( keystring.isEmpty() )
3953 QgsDebugError( QStringLiteral(
"Reencrypt FAILED, could not decrypt identity id: %1" ).arg( identid ) );
3969 if ( storages.empty() )
3985 for (
const auto &cert : certs )
3988 QPair<QgsAuthCertUtils::CaCertSource, QSslCertificate>( source, cert ) );
3992QString QgsAuthManager::authPasswordHelperKeyName()
const
3996 QString dbProfilePath;
4002 const QFileInfo info( mAuthDatabaseConnectionUri );
4003 dbProfilePath = info.dir().dirName();
4007 dbProfilePath = QCryptographicHash::hash( ( mAuthDatabaseConnectionUri.toUtf8() ), QCryptographicHash::Md5 ).toHex();
4011 return AUTH_PASSWORD_HELPER_KEY_NAME_BASE + ( dbProfilePath.compare( QLatin1String(
"default" ), Qt::CaseInsensitive ) == 0 ? QString() : dbProfilePath );
4020 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.