17#include <QCoreApplication>
19#include <QDomDocument>
24#include <QMutexLocker>
26#include <QRandomGenerator>
27#include <QRegularExpression>
29#include <QSqlDatabase>
39using namespace Qt::StringLiterals;
46#include <QSslConfiguration>
61#include "moc_qgsauthmanager.cpp"
72const QString QgsAuthManager::AUTH_CONFIG_TABLE = u
"auth_configs"_s;
73const QString QgsAuthManager::AUTH_SERVERS_TABLE = u
"auth_servers"_s;
75const QString QgsAuthManager::AUTH_CFG_REGEX = u
"authcfg=([a-z]|[A-Z]|[0-9]){7}"_s;
78const QLatin1String QgsAuthManager::AUTH_PASSWORD_HELPER_KEY_NAME_BASE(
"QGIS-Master-Password" );
79const QLatin1String QgsAuthManager::AUTH_PASSWORD_HELPER_FOLDER_NAME(
"QGIS" );
93#if defined( Q_OS_MAC )
95#elif defined( Q_OS_WIN )
97#elif defined( Q_OS_LINUX )
107 static QMutex sMutex;
108 QMutexLocker locker( &sMutex );
123 mMutex = std::make_unique<QRecursiveMutex>();
124 mMasterPasswordMutex = std::make_unique<QRecursiveMutex>();
141 QMutexLocker locker( mMutex.get() );
146 return storage->authDatabaseConnection();
151 return QSqlDatabase();
164 const QList<QgsAuthConfigurationStorage *> storages { storageRegistry->
readyStorages() };
167 if (
auto dbStorage = qobject_cast<QgsAuthConfigurationStorageDb *>( storage ) )
171 return dbStorage->quotedQualifiedIdentifier( dbStorage->methodConfigTableName() );
188 const auto drivers { QSqlDatabase::drivers() };
189 for (
const QString &driver : std::as_const( drivers ) )
191 if ( driver != ( u
"QSQLITE"_s ) && driver != ( u
"QSPATIALITE"_s ) && uri.startsWith( driver ) )
206 return mAuthDatabaseConnectionUri;
215 QRegularExpression re( u
"password=(.*)"_s );
216 QString uri = mAuthDatabaseConnectionUri;
217 return uri.replace( re, u
"password=*****"_s );
227 mAuthDatabaseConnectionUri = authDatabasePath.startsWith(
"QSQLITE://"_L1 ) ? authDatabasePath : u
"QSQLITE://"_s + authDatabasePath;
228 return initPrivate( pluginPath );
230 Q_UNUSED( pluginPath )
231 Q_UNUSED( authDatabasePath )
239 static QRecursiveMutex sInitializationMutex;
240 static bool sInitialized =
false;
242 sInitializationMutex.lock();
245 sInitializationMutex.unlock();
246 return mLazyInitResult;
249 mLazyInitResult =
const_cast< QgsAuthManager *
>( this )->initPrivate( mPluginPath );
251 sInitializationMutex.unlock();
253 return mLazyInitResult;
260static char *sPassFileEnv =
nullptr;
263bool QgsAuthManager::initPrivate(
const QString &pluginPath )
273 mQcaInitializer = std::make_unique<QCA::Initializer>( QCA::Practical, 256 );
276 QCA::scanForPlugins();
278 QgsDebugMsgLevel( u
"QCA Plugin Diagnostics Context: %1"_s.arg( QCA::pluginDiagnosticText() ), 2 );
279 QStringList capabilities;
281 capabilities = QCA::supportedFeatures();
282 QgsDebugMsgLevel( u
"QCA supports: %1"_s.arg( capabilities.join(
"," ) ), 2 );
285 if ( !QCA::isSupported(
"cert", u
"qca-ossl"_s ) )
287 mAuthDisabled =
true;
288 mAuthDisabledMessage = tr(
"QCA's OpenSSL plugin (qca-ossl) is missing" );
292 QgsDebugMsgLevel( u
"Prioritizing qca-ossl over all other QCA providers..."_s, 2 );
293 const QCA::ProviderList provds = QCA::providers();
295 for ( QCA::Provider *p : provds )
297 QString pn = p->name();
299 if ( pn !=
"qca-ossl"_L1 )
301 pr = QCA::providerPriority( pn ) + 1;
303 QCA::setProviderPriority( pn, pr );
304 prlist << u
"%1:%2"_s.arg( pn ).arg( QCA::providerPriority( pn ) );
306 QgsDebugMsgLevel( u
"QCA provider priorities: %1"_s.arg( prlist.join(
", " ) ), 2 );
313 QgsDebugMsgLevel( u
"Authentication methods found: %1"_s.arg( methods.join(
", " ) ), 2 );
315 if ( methods.isEmpty() )
317 mAuthDisabled =
true;
318 mAuthDisabledMessage = tr(
"No authentication method plugins found" );
324 mAuthDisabled =
true;
325 mAuthDisabledMessage = tr(
"No authentication method plugins could be loaded" );
329 QgsDebugMsgLevel( u
"Auth database URI: %1"_s.arg( mAuthDatabaseConnectionUri ), 2 );
333 if ( !sqliteDbPath.isEmpty() )
337 else if ( !mAuthDatabaseConnectionUri.isEmpty() )
341 QgsAuthConfigurationStorageDb *storage =
new QgsAuthConfigurationStorageDb( mAuthDatabaseConnectionUri );
351 for ( QgsAuthConfigurationStorage *storage : std::as_const( storages ) )
360 const QString err = tr(
"Failed to initialize storage %1: %2" ).arg( storage->
name(), storage->
lastError() );
380 QString passpath( sPassFileEnv );
381 free( sPassFileEnv );
382 sPassFileEnv =
nullptr;
385 QFile passfile( passpath );
386 if ( passfile.exists() && passfile.open( QIODevice::ReadOnly | QIODevice::Text ) )
388 QTextStream passin( &passfile );
389 while ( !passin.atEnd() )
391 masterpass = passin.readLine();
396 if ( !masterpass.isEmpty() )
400 QgsDebugMsgLevel( u
"Authentication master password set from QGIS_AUTH_PASSWORD_FILE"_s, 2 );
404 QgsDebugError(
"QGIS_AUTH_PASSWORD_FILE set, but FAILED to set password using: " + passpath );
410 QgsDebugError(
"QGIS_AUTH_PASSWORD_FILE set, but FAILED to read password from: " + passpath );
421 Q_UNUSED( pluginPath )
429 mPluginPath = pluginPath;
430 mAuthDatabaseConnectionUri = authDatabasePath;
432 const char *p = getenv(
"QGIS_AUTH_PASSWORD_FILE" );
435 sPassFileEnv = qstrdup( p );
440 putenv(
"QGIS_AUTH_PASSWORD_FILE" );
442 unsetenv(
"QGIS_AUTH_PASSWORD_FILE" );
446 Q_UNUSED( pluginPath )
447 Q_UNUSED( authDatabasePath )
451QString QgsAuthManager::generatePassword()
454 QRandomGenerator generator = QRandomGenerator::securelySeeded();
457 static const QString sPwChars = u
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()_-{}[]"_s;
458 for (
int i = 0; i < pw.size(); ++i )
460 pw[i] = sPwChars.at( generator.bounded( 0, sPwChars.length() ) );
475 QgsDebugError( u
"Authentication system DISABLED: QCA's qca-ossl (OpenSSL) plugin is missing"_s );
477 return mAuthDisabled;
488 return tr(
"Authentication system is DISABLED:\n%1" ).arg( mAuthDisabledMessage );
497 QMutexLocker locker( mMasterPasswordMutex.get() );
501 if ( mScheduledDbErase )
507 if ( !mMasterPass.isEmpty() )
513 const QString newPassword = generatePassword();
514 if ( passwordHelperWrite( newPassword ) )
516 mMasterPass = newPassword;
548 QString path = mAuthDatabaseConnectionUri;
549 if ( path.startsWith( u
"QSQLITE://"_s, Qt::CaseSensitivity::CaseInsensitive ) )
551 path = path.mid( 10 );
553 else if ( path.startsWith( u
"QSPATIALITE://"_s, Qt::CaseSensitivity::CaseInsensitive ) )
555 path = path.mid( 14 );
558 return QDir::cleanPath( path );
578 QMutexLocker locker( mMasterPasswordMutex.get() );
582 if ( mScheduledDbErase )
585 if ( mMasterPass.isEmpty() )
588 if ( !masterPasswordInput() )
617 QMutexLocker locker( mMutex.get() );
621 if ( mScheduledDbErase )
625 QString prevpass = QString( mMasterPass );
629 mMasterPass = prevpass;
630 const char *err = QT_TR_NOOP(
"Master password set: FAILED to verify, reset to previous" );
636 QgsDebugMsgLevel( u
"Master password set: SUCCESS%1"_s.arg( verify ?
" and verified" :
"" ), 2 );
654 if ( !masterPasswordRowsInDb( rows ) )
656 const char *err = QT_TR_NOOP(
"Master password: FAILED to access database" );
664 QgsDebugMsgLevel( u
"Master password: %1 rows in database"_s.arg( rows ), 2 );
668 const char *err = QT_TR_NOOP(
"Master password: FAILED to find just one master password record in database" );
675 else if ( rows == 1 )
677 if ( !masterPasswordCheckAgainstDb( compare ) )
679 if ( compare.isNull() )
681 const char *err = QT_TR_NOOP(
"Master password: FAILED to verify against hash in database" );
690 if ( mPassTries >= 5 )
692 mAuthDisabled =
true;
693 const char *err = QT_TR_NOOP(
"Master password: failed 5 times authentication system DISABLED" );
701 QgsDebugMsgLevel( u
"Master password: verified against hash in database"_s, 2 );
702 if ( compare.isNull() )
706 else if ( compare.isNull() )
708 if ( !masterPasswordStoreInDb() )
710 const char *err = QT_TR_NOOP(
"Master password: hash FAILED to be stored in database" );
722 if ( !masterPasswordCheckAgainstDb() )
724 const char *err = QT_TR_NOOP(
"Master password: FAILED to verify against hash in database" );
734 QgsDebugMsgLevel( u
"Master password: verified against hash in database"_s, 2 );
751 return !mMasterPass.isEmpty();
762 return mMasterPass == pass;
786 QgsDebugMsgLevel( u
"Master password reset: backed up current database"_s, 2 );
789 QString prevpass = QString( mMasterPass );
790 QString prevciv = QString( masterPasswordCiv() );
796 if ( ok && !masterPasswordClearDb() )
799 const char *err = QT_TR_NOOP(
"Master password reset FAILED: could not clear current password from database" );
805 QgsDebugMsgLevel( u
"Master password reset: cleared current password from database"_s, 2 );
812 if ( ok && !masterPasswordStoreInDb() )
815 const char *err = QT_TR_NOOP(
"Master password reset FAILED: could not store new password in database" );
821 QgsDebugMsgLevel( u
"Master password reset: stored new password in database"_s, 2 );
828 const char *err = QT_TR_NOOP(
"Master password reset FAILED: could not verify new password in database" );
834 if ( ok && !reencryptAllAuthenticationConfigs( prevpass, prevciv ) )
837 const char *err = QT_TR_NOOP(
"Master password reset FAILED: could not re-encrypt configs in database" );
843 QgsDebugMsgLevel( u
"Master password reset: re-encrypted configs in database"_s, 2 );
847 if ( ok && !verifyPasswordCanDecryptConfigs() )
850 const char *err = QT_TR_NOOP(
"Master password reset FAILED: could not verify password can decrypt re-encrypted configs" );
855 if ( ok && !reencryptAllAuthenticationSettings( prevpass, prevciv ) )
858 const char *err = QT_TR_NOOP(
"Master password reset FAILED: could not re-encrypt settings in database" );
863 if ( ok && !reencryptAllAuthenticationIdentities( prevpass, prevciv ) )
866 const char *err = QT_TR_NOOP(
"Master password reset FAILED: could not re-encrypt identities in database" );
874 const QString err = tr(
"Master password reset FAILED: could not sync password helper: %1" ).arg(
passwordHelperErrorMessage() );
883 QString errdbbackup( dbbackup );
884 errdbbackup.replace(
".db"_L1,
"_ERROR.db"_L1 );
886 QgsDebugError( u
"Master password reset FAILED: backed up failed db at %1"_s.arg( errdbbackup ) );
889 mMasterPass = prevpass;
890 QgsDebugError( u
"Master password reset FAILED: reinstated previous password and database"_s );
894 *backuppath = errdbbackup;
899 if ( !keepbackup && !QFile::remove( dbbackup ) )
901 const char *err = QT_TR_NOOP(
"Master password reset: could not remove old database backup" );
909 QgsDebugMsgLevel( u
"Master password reset: backed up previous db at %1"_s.arg( dbbackup ), 2 );
911 *backuppath = dbbackup;
922 Q_UNUSED( keepbackup )
923 Q_UNUSED( backuppath )
938 const QString existingPassword = passwordHelperRead( readOk );
947 Q_UNUSED( newPassword )
948 Q_UNUSED( keepBackup )
949 Q_UNUSED( backupPath )
959 mScheduledDbErase = scheduleErase;
961 mScheduledDbEraseRequestEmitted =
false;
962 mScheduledDbEraseRequestCount = 0;
966 if ( !mScheduledDbEraseTimer )
968 mScheduledDbEraseTimer = std::make_unique<QTimer>(
this );
969 connect( mScheduledDbEraseTimer.get(), &QTimer::timeout,
this, &QgsAuthManager::tryToStartDbErase );
970 mScheduledDbEraseTimer->start( mScheduledDbEraseRequestWait * 1000 );
972 else if ( !mScheduledDbEraseTimer->isActive() )
974 mScheduledDbEraseTimer->start();
979 if ( mScheduledDbEraseTimer && mScheduledDbEraseTimer->isActive() )
980 mScheduledDbEraseTimer->stop();
983 Q_UNUSED( scheduleErase )
993 qDeleteAll( mAuthMethods );
994 mAuthMethods.clear();
996 for (
const auto &authMethodKey : methods )
1001 return !mAuthMethods.isEmpty();
1017#ifndef __clang_analyzer__
1020 QTimer::singleShot( 3, &loop, &QEventLoop::quit );
1027 for (
int i = 0; i < len; i++ )
1029 switch ( QRandomGenerator::system()->generate() % 2 )
1032 id +=
static_cast<char>(
'0' + QRandomGenerator::system()->generate() % 10 );
1035 id +=
static_cast<char>(
'a' + QRandomGenerator::system()->generate() % 26 );
1039 if ( !configids.contains(
id ) )
1061 const char *err = QT_TR_NOOP(
"Config ID is empty" );
1067 return !configids.contains(
id );
1077 const thread_local QRegularExpression authCfgRegExp( AUTH_CFG_REGEX );
1078 return txt.indexOf( authCfgRegExp ) != -1;
1090 QMutexLocker locker( mMutex.get() );
1091 QStringList providerAuthMethodsKeys;
1092 if ( !dataprovider.isEmpty() )
1109 if ( providerAuthMethodsKeys.isEmpty() || providerAuthMethodsKeys.contains( config.method() ) )
1112 if ( baseConfigs.contains( config.id() ) )
1119 baseConfigs.insert( config.id(), config );
1125 if ( storages.empty() )
1134 Q_UNUSED( dataprovider )
1152 if ( !
configIds.contains( config.id() ) )
1154 mConfigAuthMethods.insert( config.id(), config.method() );
1155 QgsDebugMsgLevel( u
"Stored auth config/methods:\n%1 %2"_s.arg( config.id(), config.method() ), 2 );
1161 QgsDebugMsgLevel( u
"A config with same id %1 was already added, skipping from %2"_s.arg( config.id(), storage->
name() ), 2 );
1176 if ( !mConfigAuthMethods.contains( authcfg ) )
1178 QgsDebugError( u
"No config auth method found in database for authcfg: %1"_s.arg( authcfg ) );
1182 QString authMethodKey = mConfigAuthMethods.value( authcfg );
1199 return mConfigAuthMethods.value( authcfg, QString() );
1214 Q_UNUSED( dataprovider )
1215 return QStringList();
1224 if ( !mAuthMethods.contains( authMethodKey ) )
1226 QgsDebugError( u
"No auth method registered for auth method key: %1"_s.arg( authMethodKey ) );
1230 return mAuthMethods.value( authMethodKey );
1232 Q_UNUSED( authMethodKey )
1242 if ( !mAuthMethods.contains( authMethodKey ) )
1244 QgsDebugError( u
"No auth method registered for auth method key: %1"_s.arg( authMethodKey ) );
1250 Q_UNUSED( authMethodKey )
1261 if ( dataprovider.isEmpty() )
1263 return mAuthMethods;
1267 QgsAuthMethodsMap::const_iterator i = mAuthMethods.constBegin();
1268 while ( i != mAuthMethods.constEnd() )
1270 if ( i.value() && ( i.value()->supportedDataProviders().contains( u
"all"_s ) || i.value()->supportedDataProviders().contains( dataprovider ) ) )
1272 filteredmap.insert( i.key(), i.value() );
1278 Q_UNUSED( dataprovider )
1284QWidget *QgsAuthManager::authMethodEditWidget(
const QString &authMethodKey, QWidget *parent )
1290 return method->editWidget( parent );
1322 QMutexLocker locker( mMutex.get() );
1329 const char *err = QT_TR_NOOP(
"Store config: FAILED because config is invalid" );
1335 QString uid = config.
id();
1336 bool passedinID = !uid.isEmpty();
1337 if ( uid.isEmpty() )
1345 const char *err = QT_TR_NOOP(
"Store config: FAILED because pre-defined config ID %1 is not unique" );
1353 const char *err = QT_TR_NOOP(
"Store config: FAILED because pre-defined config ID %1 could not be removed" );
1362 if ( configstring.isEmpty() )
1364 const char *err = QT_TR_NOOP(
"Store config: FAILED because config string is empty" );
1372 if ( defaultStorage->isEncrypted() )
1379 configCopy.
setId( uid );
1380 if ( !defaultStorage->storeMethodConfig( configCopy, configstring ) )
1394 config.
setId( uid );
1398 QgsDebugMsgLevel( u
"Store config SUCCESS for authcfg: %1"_s.arg( uid ), 2 );
1402 Q_UNUSED( overwrite )
1412 QMutexLocker locker( mMutex.get() );
1417 if ( !config.
isValid(
true ) )
1419 const char *err = QT_TR_NOOP(
"Update config: FAILED because config is invalid" );
1426 if ( configstring.isEmpty() )
1428 const char *err = QT_TR_NOOP(
"Update config: FAILED because config is empty" );
1459 if ( storages.empty() )
1470 QgsDebugMsgLevel( u
"Update config SUCCESS for authcfg: %1"_s.arg( config.
id() ), 2 );
1490 QMutexLocker locker( mMutex.get() );
1502 if ( !config.
isValid(
true ) || ( full && payload.isEmpty() ) )
1512 QMap<QString, QVariant> storageSettings = storage->
settings();
1513 QString masterPassword;
1514 QString masterPwCiv;
1515 if ( storageSettings.contains(
"masterPassword" ) )
1517 masterPassword = storageSettings.value(
"masterPassword" ).toString();
1521 masterPassword = mMasterPass;
1523 if ( storageSettings.contains(
"masterPasswordCiv" ) )
1525 masterPwCiv = storageSettings.value(
"masterPasswordCiv" ).toString();
1529 masterPwCiv = masterPasswordCiv();
1544 QgsDebugError( u
"Update of authcfg %1 FAILED for auth method %2"_s.arg( authcfg, authMethodKey ) );
1547 QgsDebugMsgLevel( u
"Load %1 config SUCCESS for authcfg: %2"_s.arg( full ?
"full" :
"base", authcfg ), 2 );
1552 if ( storages.empty() )
1575 QMutexLocker locker( mMutex.get() );
1579 if ( authcfg.isEmpty() )
1605 if ( storages.empty() )
1627 if ( filename.isEmpty() )
1630 QDomDocument document( u
"qgis_authentication"_s );
1631 QDomElement root = document.createElement( u
"qgis_authentication"_s );
1632 document.appendChild( root );
1635 if ( !password.isEmpty() )
1640 root.setAttribute( u
"salt"_s, salt );
1641 root.setAttribute( u
"hash"_s, hash );
1642 root.setAttribute( u
"civ"_s, civ );
1645 QDomElement configurations = document.createElement( u
"configurations"_s );
1646 for (
const QString &authcfg : authcfgs )
1653 authMethodConfig.
writeXml( configurations, document );
1656 if ( !password.isEmpty() )
1658 QString configurationsString;
1659 QTextStream ts( &configurationsString );
1660 configurations.save( ts, 2 );
1661 root.appendChild( document.createTextNode(
QgsAuthCrypto::encrypt( password, civ, configurationsString ) ) );
1665 root.appendChild( configurations );
1668 QFile file( filename );
1669 if ( !file.open( QFile::WriteOnly | QIODevice::Truncate ) )
1672 QTextStream ts( &file );
1673 document.save( ts, 2 );
1677 Q_UNUSED( filename )
1678 Q_UNUSED( authcfgs )
1679 Q_UNUSED( password )
1689 QFile file( filename );
1690 if ( !file.open( QFile::ReadOnly ) )
1695 QDomDocument document( u
"qgis_authentication"_s );
1696 if ( !document.setContent( &file ) )
1703 QDomElement root = document.documentElement();
1704 if ( root.tagName() !=
"qgis_authentication"_L1 )
1709 QDomElement configurations;
1710 if ( root.hasAttribute( u
"salt"_s ) )
1712 QString salt = root.attribute( u
"salt"_s );
1713 QString hash = root.attribute( u
"hash"_s );
1714 QString civ = root.attribute( u
"civ"_s );
1719 configurations = document.firstChild().toElement();
1723 configurations = root.firstChildElement( u
"configurations"_s );
1726 QDomElement configuration = configurations.firstChildElement();
1727 while ( !configuration.isNull() )
1730 ( void ) authMethodConfig.
readXml( configuration );
1733 configuration = configuration.nextSiblingElement();
1737 Q_UNUSED( filename )
1738 Q_UNUSED( password )
1739 Q_UNUSED( overwrite )
1749 QMutexLocker locker( mMutex.get() );
1755 if ( defaultStorage->clearMethodConfigs() )
1764 QgsDebugMsgLevel( u
"FAILED to remove all configs from the default storage"_s, 2 );
1784 QMutexLocker locker( mMutex.get() );
1788 const char *err = QT_TR_NOOP(
"The authentication storage is not filesystem-based" );
1796 const char *err = QT_TR_NOOP(
"No authentication database file found" );
1806 if ( authConn.isValid() && authConn.isOpen() )
1810 QString datestamp( QDateTime::currentDateTime().toString( u
"yyyy-MM-dd-hhmmss"_s ) );
1812 dbbackup.replace(
".db"_L1, u
"_%1.db"_s.arg( datestamp ) );
1816 const char *err = QT_TR_NOOP(
"Could not back up authentication database" );
1823 *backuppath = dbbackup;
1828 Q_UNUSED( backuppath )
1838 QMutexLocker locker( mMutex.get() );
1849 if ( backuppath && !dbbackup.isEmpty() )
1850 *backuppath = dbbackup;
1854 if ( defaultStorage->erase() )
1856 mMasterPass = QString();
1883 Q_UNUSED( backuppath )
1901 QgsDebugError( u
"Network request updating not supported by authcfg: %1"_s.arg( authcfg ) );
1916 Q_UNUSED( dataprovider )
1934 QgsDebugMsgLevel( u
"Network reply updating not supported by authcfg: %1"_s.arg( authcfg ), 3 );
1950 Q_UNUSED( dataprovider )
1968 QgsDebugError( u
"Data source URI updating not supported by authcfg: %1"_s.arg( authcfg ) );
1982 Q_UNUSED( connectionItems )
1984 Q_UNUSED( dataprovider )
2002 QgsDebugError( u
"Proxy updating not supported by authcfg: %1"_s.arg( authcfg ) );
2011 QgsDebugMsgLevel( u
"Proxy updated successfully from authcfg: %1"_s.arg( authcfg ), 2 );
2019 Q_UNUSED( dataprovider )
2029 QMutexLocker locker( mMutex.get() );
2030 if ( key.isEmpty() )
2033 QString storeval( value.toString() );
2056 if ( !defaultStorage->storeAuthSetting( key, storeval ) )
2081 QMutexLocker locker( mMutex.get() );
2082 if ( key.isEmpty() )
2088 QVariant value = defaultValue;
2096 if ( !storeval.isEmpty() )
2107 if ( storages.empty() )
2115 Q_UNUSED( defaultValue )
2126 QMutexLocker locker( mMutex.get() );
2127 if ( key.isEmpty() )
2141 if ( storages.empty() )
2158 QMutexLocker locker( mMutex.get() );
2159 if ( key.isEmpty() )
2186 if ( storages.empty() )
2206 QMutexLocker locker( mMutex.get() );
2212 mCustomConfigByHostCache.clear();
2213 mHasCheckedIfCustomConfigByHostExists =
false;
2228 QMutexLocker locker( mMutex.get() );
2229 if ( cert.isNull() )
2243 QString id( QgsAuthCertUtils::shaHexForCert( cert ) );
2248 QgsDebugError( u
"Store certificate identity: FAILED to remove pre-existing certificate identity %1"_s.arg(
id ) );
2256 if ( !defaultStorage->storeCertIdentity( cert, keypem ) )
2280 QMutexLocker locker( mMutex.get() );
2282 QSslCertificate cert;
2293 if ( !cert.isNull() )
2299 if ( storages.empty() )
2307 return QSslCertificate();
2315 QMutexLocker locker( mMutex.get() );
2316 QPair<QSslCertificate, QSslKey> bundle;
2331 if ( encryptedBundle.first.isNull() )
2333 QgsDebugError( u
"Certificate identity bundle is null for id: %1"_s.arg(
id ) );
2336 QSslKey key(
QgsAuthCrypto::decrypt( mMasterPass, masterPasswordCiv(), encryptedBundle.second ).toLatin1(), QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey );
2339 QgsDebugError( u
"Certificate identity bundle: FAILED to create private key"_s );
2342 bundle = qMakePair( encryptedBundle.first, key );
2347 if ( storages.empty() )
2361 QMutexLocker locker( mMutex.get() );
2363 if ( QgsAuthCertUtils::certIsViable( bundle.first ) && !bundle.second.isNull() )
2365 return QStringList() << QString( bundle.first.toPem() ) << QString( bundle.second.toPem() );
2367 return QStringList();
2370 return QStringList();
2379 QMutexLocker locker( mMutex.get() );
2380 QList<QSslCertificate> certs;
2387 const QList<QSslCertificate> storageCerts = storage->
certIdentities();
2389 for (
const QSslCertificate &cert : std::as_const( storageCerts ) )
2391 if ( !certs.contains( cert ) )
2393 certs.append( cert );
2402 if ( storages.empty() )
2409 return QList<QSslCertificate>();
2418 QMutexLocker locker( mMutex.get() );
2432 for (
const QString &
id : std::as_const( storageIds ) )
2434 if ( !ids.contains(
id ) )
2447 return QStringList();
2456 QMutexLocker locker( mMutex.get() );
2471 if ( storages.empty() )
2488 QMutexLocker locker( mMutex.get() );
2511 if ( storages.empty() )
2529 QMutexLocker locker( mMutex.get() );
2537 const QString id( QgsAuthCertUtils::shaHexForCert( cert ) );
2541 QgsDebugError( u
"Store SSL certificate custom config: FAILED to remove pre-existing config %1"_s.arg(
id ) );
2547 if ( !defaultStorage->storeSslCertCustomConfig( config ) )
2560 mCustomConfigByHostCache.clear();
2574 QMutexLocker locker( mMutex.get() );
2577 if (
id.isEmpty() || hostport.isEmpty() )
2579 QgsDebugError( u
"Passed config ID or host:port is empty"_s );
2603 if ( storages.empty() )
2612 Q_UNUSED( hostport )
2623 if ( hostport.isEmpty() )
2628 QMutexLocker locker( mMutex.get() );
2630 if ( mCustomConfigByHostCache.contains( hostport ) )
2631 return mCustomConfigByHostCache.value( hostport );
2641 mCustomConfigByHostCache.insert( hostport, config );
2645 if ( storages.empty() )
2652 Q_UNUSED( hostport )
2662 QMutexLocker locker( mMutex.get() );
2663 QList<QgsAuthConfigSslServer> configs;
2674 for (
const auto &config : std::as_const( storageConfigs ) )
2676 const QString id( QgsAuthCertUtils::shaHexForCert( config.sslCertificate() ) );
2677 const QString hostPort = config.sslHostPort();
2678 const QString shaHostPort( u
"%1:%2"_s.arg(
id, hostPort ) );
2679 if ( !ids.contains( shaHostPort ) )
2681 ids.append( shaHostPort );
2682 configs.append( config );
2691 if ( storages.empty() )
2698 return QList<QgsAuthConfigSslServer>();
2707 QMutexLocker locker( mMutex.get() );
2708 if (
id.isEmpty() || hostPort.isEmpty() )
2710 QgsDebugError( u
"Passed config ID or host:port is empty"_s );
2725 if ( storages.empty() )
2733 Q_UNUSED( hostPort )
2743 QMutexLocker locker( mMutex.get() );
2744 if (
id.isEmpty() || hostport.isEmpty() )
2746 QgsDebugError( u
"Passed config ID or host:port is empty"_s );
2750 mCustomConfigByHostCache.clear();
2764 const QString shaHostPort( u
"%1:%2"_s.arg(
id, hostport ) );
2765 if ( mIgnoredSslErrorsCache.contains( shaHostPort ) )
2767 mIgnoredSslErrorsCache.remove( shaHostPort );
2773 if ( storages.empty() )
2781 Q_UNUSED( hostport )
2792 QMutexLocker locker( mMutex.get() );
2793 if ( !mIgnoredSslErrorsCache.isEmpty() )
2796 QHash<QString, QSet<QSslError::SslError> >::const_iterator i = mIgnoredSslErrorsCache.constBegin();
2797 while ( i != mIgnoredSslErrorsCache.constEnd() )
2800 for (
auto err : i.value() )
2802 errs << QgsAuthCertUtils::sslErrorEnumString( err );
2820 QMutexLocker locker( mMutex.get() );
2827 QString shahostport( u
"%1:%2"_s.arg( QgsAuthCertUtils::shaHexForCert( config.
sslCertificate() ).trimmed(), config.
sslHostPort().trimmed() ) );
2828 if ( mIgnoredSslErrorsCache.contains( shahostport ) )
2830 mIgnoredSslErrorsCache.remove( shahostport );
2833 if ( !errenums.isEmpty() )
2835 mIgnoredSslErrorsCache.insert( shahostport, QSet<QSslError::SslError>( errenums.begin(), errenums.end() ) );
2836 QgsDebugMsgLevel( u
"Update of ignored SSL errors cache SUCCEEDED for sha:host:port = %1"_s.arg( shahostport ), 2 );
2841 QgsDebugMsgLevel( u
"No ignored SSL errors to cache for sha:host:port = %1"_s.arg( shahostport ), 2 );
2854 QMutexLocker locker( mMutex.get() );
2855 const thread_local QRegularExpression rx( QRegularExpression::anchoredPattern(
"\\S+:\\S+:\\d+" ) );
2856 if ( !rx.match( shahostport ).hasMatch() )
2859 "Passed shahostport does not match \\S+:\\S+:\\d+, "
2860 "e.g. 74a4ef5ea94512a43769b744cda0ca5049a72491:www.example.com:443"
2865 if ( mIgnoredSslErrorsCache.contains( shahostport ) )
2867 mIgnoredSslErrorsCache.remove( shahostport );
2870 if ( errors.isEmpty() )
2876 QSet<QSslError::SslError> errs;
2877 for (
const auto &error : errors )
2879 if ( error.error() == QSslError::NoError )
2882 errs.insert( error.error() );
2885 if ( errs.isEmpty() )
2887 QgsDebugError( u
"Passed errors list does not contain errors"_s );
2891 mIgnoredSslErrorsCache.insert( shahostport, errs );
2893 QgsDebugMsgLevel( u
"Update of ignored SSL errors cache SUCCEEDED for sha:host:port = %1"_s.arg( shahostport ), 2 );
2897 Q_UNUSED( shahostport )
2908 QMutexLocker locker( mMutex.get() );
2909 QHash<QString, QSet<QSslError::SslError> > prevcache( mIgnoredSslErrorsCache );
2910 QHash<QString, QSet<QSslError::SslError> > nextcache;
2920 for (
const auto &config : std::as_const( customConfigs ) )
2922 const QString shaHostPort( u
"%1:%2"_s.arg( QgsAuthCertUtils::shaHexForCert( config.sslCertificate() ), config.sslHostPort() ) );
2923 if ( !ids.contains( shaHostPort ) )
2925 ids.append( shaHostPort );
2926 if ( !config.sslIgnoredErrorEnums().isEmpty() )
2928 nextcache.insert( shaHostPort, QSet<QSslError::SslError>( config.sslIgnoredErrorEnums().cbegin(), config.sslIgnoredErrorEnums().cend() ) );
2930 if ( prevcache.contains( shaHostPort ) )
2932 prevcache.remove( shaHostPort );
2942 if ( !prevcache.isEmpty() )
2945 QHash<QString, QSet<QSslError::SslError> >::const_iterator i = prevcache.constBegin();
2946 while ( i != prevcache.constEnd() )
2948 nextcache.insert( i.key(), i.value() );
2953 if ( nextcache != mIgnoredSslErrorsCache )
2955 mIgnoredSslErrorsCache.clear();
2956 mIgnoredSslErrorsCache = nextcache;
2962 QgsDebugMsgLevel( u
"Rebuild of ignored SSL errors cache SAME AS BEFORE"_s, 2 );
2975 QMutexLocker locker( mMutex.get() );
2976 if ( certs.isEmpty() )
2982 for (
const auto &cert : certs )
2999 QMutexLocker locker( mMutex.get() );
3002 if ( cert.isNull() )
3010 QgsDebugError( u
"Store certificate authority: FAILED to remove pre-existing certificate authority"_s );
3016 return defaultStorage->storeCertAuthority( cert );
3036 QMutexLocker locker( mMutex.get() );
3037 QSslCertificate emptycert;
3038 QSslCertificate cert;
3048 if ( !cert.isNull() )
3054 if ( storages.empty() )
3063 return QSslCertificate();
3072 QMutexLocker locker( mMutex.get() );
3073 if ( cert.isNull() )
3090 if ( storages.empty() )
3106 QMutexLocker locker( mMutex.get() );
3107 if ( cert.isNull() )
3135 if ( storages.empty() )
3150 return QSslConfiguration::systemCaCertificates();
3152 return QList<QSslCertificate>();
3161 QMutexLocker locker( mMutex.get() );
3162 QList<QSslCertificate> certs;
3163 QList<QSslCertificate> filecerts;
3172 QString cafile( cafileval.toString() );
3173 if ( !cafile.isEmpty() && QFile::exists( cafile ) )
3175 filecerts = QgsAuthCertUtils::certsFromFile( cafile );
3178 for (
const auto &cert : std::as_const( filecerts ) )
3180 if ( !allowinvalid.toBool() && ( cert.isBlacklisted() || cert.isNull() || cert.expiryDate() <= QDateTime::currentDateTime() || cert.effectiveDate() > QDateTime::currentDateTime() ) )
3185 if ( QgsAuthCertUtils::certificateIsAuthorityOrIssuer( cert ) )
3192 return QList<QSslCertificate>();
3201 QMutexLocker locker( mMutex.get() );
3206 QList<QSslCertificate> certs;
3210 const QList<QSslCertificate> storageCerts = storage->
caCerts();
3212 for (
const QSslCertificate &cert : std::as_const( storageCerts ) )
3214 if ( !certs.contains( cert ) )
3216 certs.append( cert );
3225 if ( storages.empty() )
3232 return QList<QSslCertificate>();
3240 QMutexLocker locker( mMutex.get() );
3241 return QgsAuthCertUtils::mapDigestToCerts(
databaseCAs() );
3249 QMutexLocker locker( mMutex.get() );
3250 mCaCertsCache.clear();
3256 bool res = !mCaCertsCache.isEmpty();
3270 QMutexLocker locker( mMutex.get() );
3271 if ( cert.isNull() )
3290 return defaultStorage->storeCertTrustPolicy( cert, policy );
3309 QMutexLocker locker( mMutex.get() );
3310 if ( cert.isNull() )
3328 if ( storages.empty() )
3345 QMutexLocker locker( mMutex.get() );
3346 if ( certs.empty() )
3352 for (
const auto &cert : certs )
3369 QMutexLocker locker( mMutex.get() );
3370 if ( cert.isNull() )
3398 if ( storages.empty() )
3415 QMutexLocker locker( mMutex.get() );
3416 if ( cert.isNull() )
3421 QString id( QgsAuthCertUtils::shaHexForCert( cert ) );
3426 if ( trustedids.contains(
id ) )
3430 else if ( untrustedids.contains(
id ) )
3451 return storeAuthSetting( u
"certdefaulttrust"_s,
static_cast< int >( policy ) );
3463 QMutexLocker locker( mMutex.get() );
3464 QVariant policy(
authSetting( u
"certdefaulttrust"_s ) );
3480 QMutexLocker locker( mMutex.get() );
3481 mCertTrustCache.clear();
3491 for (
auto it = trustedCerts.cbegin(); it != trustedCerts.cend(); ++it )
3493 const QString
id { it.key() };
3494 if ( !ids.contains(
id ) )
3515 if ( !storages.empty() )
3535 QMutexLocker locker( mMutex.get() );
3539 const QList<QPair<QgsAuthCertUtils::CaCertSource, QSslCertificate> > &certpairs( mCaCertsCache.values() );
3541 QList<QSslCertificate> trustedcerts;
3542 for (
int i = 0; i < certpairs.size(); ++i )
3544 QSslCertificate cert( certpairs.at( i ).second );
3545 QString certid( QgsAuthCertUtils::shaHexForCert( cert ) );
3546 if ( trustedids.contains( certid ) )
3549 trustedcerts.append( cert );
3553 if ( !includeinvalid && !QgsAuthCertUtils::certIsViable( cert ) )
3555 trustedcerts.append( cert );
3560 QSslConfiguration sslconfig( QSslConfiguration::defaultConfiguration() );
3561 sslconfig.setCaCertificates( trustedcerts );
3562 QSslConfiguration::setDefaultConfiguration( sslconfig );
3564 return trustedcerts;
3566 Q_UNUSED( includeinvalid )
3567 return QList<QSslCertificate>();
3576 QMutexLocker locker( mMutex.get() );
3577 if ( trustedCAs.isEmpty() )
3579 if ( mTrustedCaCertsCache.isEmpty() )
3586 const QList<QPair<QgsAuthCertUtils::CaCertSource, QSslCertificate> > &certpairs( mCaCertsCache.values() );
3588 QList<QSslCertificate> untrustedCAs;
3589 for (
int i = 0; i < certpairs.size(); ++i )
3591 QSslCertificate cert( certpairs.at( i ).second );
3592 if ( !trustedCAs.contains( cert ) )
3594 untrustedCAs.append( cert );
3597 return untrustedCAs;
3599 Q_UNUSED( trustedCAs )
3600 return QList<QSslCertificate>();
3609 QMutexLocker locker( mMutex.get() );
3624 QMutexLocker locker( mMutex.get() );
3627 return QByteArray();
3636 QMutexLocker locker( mMutex.get() );
3639 return passwordHelperWrite( mMasterPass );
3653 bool readOk =
false;
3654 const QString currentPass = passwordHelperRead( readOk );
3658 if ( !currentPass.isEmpty() && ( mPasswordHelperErrorCode == QKeychain::NoError ) )
3671#if defined( Q_OS_MAC )
3672 return titleCase ? QObject::tr(
"Keychain" ) : QObject::tr(
"keychain" );
3673#elif defined( Q_OS_WIN )
3674 return titleCase ? QObject::tr(
"Password Manager" ) : QObject::tr(
"password manager" );
3675#elif defined( Q_OS_LINUX )
3677 const QString desktopSession = qgetenv(
"DESKTOP_SESSION" );
3678 const QString currentDesktop = qgetenv(
"XDG_CURRENT_DESKTOP" );
3679 const QString gdmSession = qgetenv(
"GDMSESSION" );
3681 if ( desktopSession.contains(
"kde"_L1, Qt::CaseInsensitive ) || currentDesktop.contains(
"kde"_L1, Qt::CaseInsensitive ) || gdmSession.contains(
"kde"_L1, Qt::CaseInsensitive ) )
3683 return titleCase ? QObject::tr(
"Wallet" ) : QObject::tr(
"wallet" );
3686 return titleCase ? QObject::tr(
"Wallet/Key Ring" ) : QObject::tr(
"wallet/key ring" );
3688 return titleCase ? QObject::tr(
"Password Manager" ) : QObject::tr(
"password manager" );
3691 Q_UNUSED( titleCase )
3710 for (
const auto &authcfg : ids )
3735void QgsAuthManager::writeToConsole(
const QString &message,
const QString &tag,
Qgis::MessageLevel level )
3750 msg +=
"WARNING: "_L1;
3753 msg +=
"ERROR: "_L1;
3760 QTextStream out( stdout, QIODevice::WriteOnly );
3761 out << msg << Qt::endl;
3769void QgsAuthManager::tryToStartDbErase()
3774 ++mScheduledDbEraseRequestCount;
3776 int trycutoff = 90 / ( mScheduledDbEraseRequestWait ? mScheduledDbEraseRequestWait : 3 );
3777 if ( mScheduledDbEraseRequestCount >= trycutoff )
3780 QgsDebugMsgLevel( u
"authDatabaseEraseRequest emitting/scheduling canceled"_s, 2 );
3785 QgsDebugMsgLevel( u
"authDatabaseEraseRequest attempt (%1 of %2)"_s.arg( mScheduledDbEraseRequestCount ).arg( trycutoff ), 2 );
3791 mScheduledDbEraseRequestEmitted =
true;
3807 QMutexLocker locker( mMutex.get() );
3809 QMapIterator<QThread *, QMetaObject::Connection> iterator( mConnectedThreads );
3810 while ( iterator.hasNext() )
3813 QThread::disconnect( iterator.value() );
3824 qDeleteAll( mAuthMethods );
3829 if ( authConn.isValid() && authConn.isOpen() )
3833 QSqlDatabase::removeDatabase( u
"authentication.configs"_s );
3839 QMutexLocker locker( mMutex.get() );
3840 if ( !mAuthConfigurationStorageRegistry )
3842 mAuthConfigurationStorageRegistry = std::make_unique<QgsAuthConfigurationStorageRegistry>();
3844 return mAuthConfigurationStorageRegistry.get();
3848QString QgsAuthManager::passwordHelperName()
const
3851 return tr(
"Password Helper" );
3858void QgsAuthManager::passwordHelperLog(
const QString &msg )
const
3879 QKeychain::DeletePasswordJob job( AUTH_PASSWORD_HELPER_FOLDER_NAME );
3881 job.setAutoDelete(
false );
3882 job.setKey( authPasswordHelperKeyName() );
3884 connect( &job, &QKeychain::Job::finished, &loop, &QEventLoop::quit );
3889 mPasswordHelperErrorCode = job.error();
3890 mPasswordHelperErrorMessage = tr(
"Delete password failed: %1." ).arg( job.errorString() );
3901 passwordHelperProcessError();
3908QString QgsAuthManager::passwordHelperRead(
bool &ok )
3917 QKeychain::ReadPasswordJob job( AUTH_PASSWORD_HELPER_FOLDER_NAME );
3919 job.setAutoDelete(
false );
3920 job.setKey( authPasswordHelperKeyName() );
3922 connect( &job, &QKeychain::Job::finished, &loop, &QEventLoop::quit );
3927 mPasswordHelperErrorCode = job.error();
3928 mPasswordHelperErrorMessage = tr(
"Retrieving password from the %1 failed: %2." ).arg(
passwordHelperDisplayName(), job.errorString() );
3934 password = job.textData();
3936 if ( password.isEmpty() )
3938 mPasswordHelperErrorCode = QKeychain::EntryNotFound;
3950 passwordHelperProcessError();
3958bool QgsAuthManager::passwordHelperWrite(
const QString &password )
3963 Q_ASSERT( !password.isEmpty() );
3966 QKeychain::WritePasswordJob job( AUTH_PASSWORD_HELPER_FOLDER_NAME );
3968 job.setAutoDelete(
false );
3969 job.setKey( authPasswordHelperKeyName() );
3970 job.setTextData( password );
3972 connect( &job, &QKeychain::Job::finished, &loop, &QEventLoop::quit );
3977 mPasswordHelperErrorCode = job.error();
3978 mPasswordHelperErrorMessage = tr(
"Storing password in the %1 failed: %2." ).arg(
passwordHelperDisplayName(), job.errorString() );
3985 passwordHelperClearErrors();
3990 passwordHelperProcessError();
3993 Q_UNUSED( password )
4013 enabled ? tr(
"Your %1 will be <b>used from now</b> on to store and retrieve the master password." ).arg(
passwordHelperDisplayName() )
4014 : tr(
"Your %1 will <b>not be used anymore</b> to store and retrieve the master password." ).arg(
passwordHelperDisplayName() )
4040void QgsAuthManager::passwordHelperClearErrors()
4043 mPasswordHelperErrorCode = QKeychain::NoError;
4044 mPasswordHelperErrorMessage.clear();
4048void QgsAuthManager::passwordHelperProcessError()
4053 if ( mPasswordHelperErrorCode == QKeychain::AccessDenied
4054 || mPasswordHelperErrorCode == QKeychain::AccessDeniedByUser
4055 || mPasswordHelperErrorCode == QKeychain::NoBackendAvailable
4056 || mPasswordHelperErrorCode == QKeychain::NotImplemented )
4062 mPasswordHelperErrorMessage = tr(
4063 "There was an error and integration with your %1 has been disabled. "
4064 "You can re-enable it at any time through the \"Utilities\" menu "
4065 "in the Authentication pane of the options dialog. %2"
4069 if ( mPasswordHelperErrorCode != QKeychain::NoError )
4075 passwordHelperClearErrors();
4080bool QgsAuthManager::masterPasswordInput()
4089 bool storedPasswordIsValid =
false;
4095 bool readOk =
false;
4096 pass = passwordHelperRead( readOk );
4097 if ( readOk && !pass.isEmpty() && ( mPasswordHelperErrorCode == QKeychain::NoError ) )
4103 storedPasswordIsValid =
true;
4118 if ( ok && !pass.isEmpty() && mMasterPass != pass )
4123 if ( !passwordHelperWrite( pass ) )
4136bool QgsAuthManager::masterPasswordRowsInDb(
int &rows )
const
4147 QMutexLocker locker( mMutex.get() );
4152 if ( storages.empty() )
4158 for ( QgsAuthConfigurationStorage *storage : std::as_const( storages ) )
4166 catch (
const QgsNotSupportedException &e )
4190 if ( !masterPasswordRowsInDb( rows ) )
4192 const char *err = QT_TR_NOOP(
"Master password: FAILED to access database" );
4198 return ( rows == 1 );
4204bool QgsAuthManager::masterPasswordCheckAgainstDb(
const QString &compare )
const
4217 const QList<QgsAuthConfigurationStorage::MasterPasswordConfig> passwords { defaultStorage->masterPasswords() };
4218 if ( passwords.size() == 0 )
4223 const QgsAuthConfigurationStorage::MasterPasswordConfig storedPassword { passwords.first() };
4226 catch (
const QgsNotSupportedException &e )
4244bool QgsAuthManager::masterPasswordStoreInDb()
const
4252 QString salt, hash, civ;
4260 return defaultStorage->storeMasterPassword( { salt, civ, hash } );
4262 catch (
const QgsNotSupportedException &e )
4279bool QgsAuthManager::masterPasswordClearDb()
4291 return defaultStorage->clearMasterPasswords();
4293 catch (
const QgsNotSupportedException &e )
4310const QString QgsAuthManager::masterPasswordCiv()
const
4322 const QList<QgsAuthConfigurationStorage::MasterPasswordConfig> passwords { defaultStorage->masterPasswords() };
4323 if ( passwords.size() == 0 )
4328 return passwords.first().civ;
4330 catch (
const QgsNotSupportedException &e )
4352 QStringList configKeys = QStringList();
4366 for (
auto it = configs.cbegin(); it != configs.cend(); ++it )
4368 if ( !configKeys.contains( it.key() ) )
4370 configKeys.append( it.key() );
4387 return QStringList();
4391bool QgsAuthManager::verifyPasswordCanDecryptConfigs()
const
4404 for (
const QgsAuthConfigurationStorage *storage : std::as_const( storages ) )
4414 for (
auto it = configs.cbegin(); it != configs.cend(); ++it )
4416 QString configstring(
QgsAuthCrypto::decrypt( mMasterPass, masterPasswordCiv(), it.value().config( u
"encrypted_payload"_s ) ) );
4417 if ( configstring.isEmpty() )
4419 QgsDebugError( u
"Verify password can decrypt configs FAILED, could not decrypt a config (id: %1) from storage %2"_s.arg( it.key(), storage->
name() ) );
4424 catch (
const QgsNotSupportedException &e )
4432 if ( storages.empty() )
4444bool QgsAuthManager::reencryptAllAuthenticationConfigs(
const QString &prevpass,
const QString &prevciv )
4454 for (
const auto &configid : ids )
4456 res = res && reencryptAuthenticationConfig( configid, prevpass, prevciv );
4460 Q_UNUSED( prevpass )
4466bool QgsAuthManager::reencryptAuthenticationConfig(
const QString &authcfg,
const QString &prevpass,
const QString &prevciv )
4479 for ( QgsAuthConfigurationStorage *storage : std::as_const( storages ) )
4491 const QgsAuthMethodConfig config = storage->
loadMethodConfig( authcfg, payload,
true );
4492 if ( payload.isEmpty() || !config.
isValid(
true ) )
4494 QgsDebugError( u
"Reencrypt FAILED, could not find config (id: %1)"_s.arg( authcfg ) );
4499 if ( configstring.isEmpty() )
4501 QgsDebugError( u
"Reencrypt FAILED, could not decrypt config (id: %1)"_s.arg( authcfg ) );
4515 catch (
const QgsNotSupportedException &e )
4523 if ( storages.empty() )
4535 Q_UNUSED( prevpass )
4541bool QgsAuthManager::reencryptAllAuthenticationSettings(
const QString &prevpass,
const QString &prevciv )
4546 Q_UNUSED( prevpass )
4559 QStringList encryptedsettings;
4560 encryptedsettings <<
"";
4562 for (
const auto & sett, std::as_const( encryptedsettings ) )
4569 QSqlQuery query( authDbConnection() );
4571 query.prepare( QStringLiteral(
"SELECT value FROM %1 "
4572 "WHERE setting = :setting" ).arg( authDbSettingsTable() ) );
4574 query.bindValue(
":setting", sett );
4576 if ( !authDbQuery( &query ) )
4579 if ( !query.isActive() || !query.isSelect() )
4581 QgsDebugError( u
"Reencrypt FAILED, query not active or a select operation for setting: %2"_s.arg( sett ) );
4585 if ( query.first() )
4591 query.prepare( QStringLiteral(
"UPDATE %1 "
4592 "SET value = :value "
4593 "WHERE setting = :setting" ).arg( authDbSettingsTable() ) );
4595 query.bindValue(
":setting", sett );
4598 if ( !authDbStartTransaction() )
4601 if ( !authDbQuery( &query ) )
4604 if ( !authDbCommit() )
4612 QgsDebugError( u
"Reencrypt FAILED, could not find in db setting: %2"_s.arg( sett ) );
4618 QgsDebugError( u
"Select contains more than one for setting: %1"_s.arg( sett ) );
4629bool QgsAuthManager::reencryptAllAuthenticationIdentities(
const QString &prevpass,
const QString &prevciv )
4639 for (
const auto &identid : ids )
4641 res = res && reencryptAuthenticationIdentity( identid, prevpass, prevciv );
4645 Q_UNUSED( prevpass )
4651bool QgsAuthManager::reencryptAuthenticationIdentity(
const QString &identid,
const QString &prevpass,
const QString &prevciv )
4665 for ( QgsAuthConfigurationStorage *storage : std::as_const( storages ) )
4678 if ( keystring.isEmpty() )
4680 QgsDebugError( u
"Reencrypt FAILED, could not decrypt identity id: %1"_s.arg( identid ) );
4688 catch (
const QgsNotSupportedException &e )
4696 if ( storages.empty() )
4708 Q_UNUSED( prevpass )
4720 for (
const auto &cert : certs )
4722 mCaCertsCache.insert( QgsAuthCertUtils::shaHexForCert( cert ), QPair<QgsAuthCertUtils::CaCertSource, QSslCertificate>( source, cert ) );
4731QString QgsAuthManager::authPasswordHelperKeyName()
const
4736 QString dbProfilePath;
4742 const QFileInfo info( mAuthDatabaseConnectionUri );
4743 dbProfilePath = info.dir().dirName();
4747 dbProfilePath = QCryptographicHash::hash( ( mAuthDatabaseConnectionUri.toUtf8() ), QCryptographicHash::Md5 ).toHex();
4751 return AUTH_PASSWORD_HELPER_KEY_NAME_BASE + ( dbProfilePath.compare(
"default"_L1, Qt::CaseInsensitive ) == 0 ? QString() : dbProfilePath );
4764 if ( qobject_cast<QgsAuthConfigurationStorageDb *>( storage ) )
4779 Q_UNUSED( capability )
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 delete 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.
CertTrustPolicy
Type of certificate trust policy.
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...
void messageLog(const QString &message, const QString &tag=u"Authentication"_s, Qgis::MessageLevel level=Qgis::MessageLevel::Info)
Custom logging signal to relay to console output and QgsMessageLog.
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.
virtual QString lastError() const
Returns the last error message.
QMap< QString, QVariant > settings() const
Returns the settings of the storage.
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 which offers an interface to manage the authentication configuration database and to utiliz...
bool storeAuthSetting(const QString &key, const QVariant &value, bool encrypt=false)
Stores an authentication setting.
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.
QString sqliteDatabasePath() const
Returns the path to the authentication database file or an empty string if the database is not SQLite...
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)
Returns a previously set authentication setting.
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.
static const QgsSettingsEntryBool * settingsPasswordHelperInsecureFallback
bool configIdUnique(const QString &id) const
Verify if provided authentication id is unique.
static const QgsSettingsEntryBool * settingsGenerateRandomPasswordForPasswordHelper
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.
bool createAndStoreRandomMasterPasswordInKeyChain()
Creates a new securely seeded random password and stores it in the system keychain as the new master ...
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.
const QString passwordHelperErrorMessage()
Error message getter.
static const QgsSettingsEntryBool * settingsPasswordHelperLogging
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.
static const QgsSettingsEntryBool * settingsUsingGeneratedRandomPassword
bool resetMasterPassword(const QString &newpass, const QString &oldpass, bool keepbackup, QString *backuppath=nullptr)
Reset the master password to a new one, then re-encrypts all previous configs with the new password.
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,...
static QgsAuthManager * instance()
Enforce singleton pattern.
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.
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.
static const QgsSettingsEntryBool * settingsUsePasswordHelper
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.
static const QString AUTH_PASSWORD_HELPER_DISPLAY_NAME
The display name of the password helper (platform dependent).
bool storeAuthenticationConfig(QgsAuthMethodConfig &mconfig, bool overwrite=false)
Store an authentication config in the database.
bool verifyStoredPasswordHelperPassword()
Verify the password stored in the password helper.
bool removeCertIdentity(const QString &id)
Remove a certificate identity.
static QString passwordHelperDisplayName(bool titleCase=false)
Returns a translated display name of the password helper (platform dependent).
bool resetMasterPasswordUsingStoredPasswordHelper(const QString &newPassword, bool keepBackup, QString *backupPath=nullptr)
Reset the master password to a new one, hen re-encrypts all previous configs with the new password.
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.
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.
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, const char *file=__builtin_FILE(), const char *function=__builtin_FUNCTION(), int line=__builtin_LINE(), Qgis::StringFormat format=Qgis::StringFormat::PlainText)
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.
T value(const QString &dynamicKeyPart=QString()) const
Returns settings value.
A boolean settings entry.
static QgsSettingsTreeNode * sTreeAuthentication
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)