25 #include <QPushButton>    27 #include <QToolButton>    30 #include <QGlobalStatic>    32 QMutex QgsCredentialDialog::sIgnoredConnectionsCacheMutex;
    39 static QString invalidStyle_( 
const QString &selector = QStringLiteral( 
"QLineEdit" ) )
    41   return QStringLiteral( 
"%1{color: rgb(200, 0, 0);}" ).arg( selector );
    45   : QDialog( parent, fl )
    49   connect( leMasterPass, &QgsPasswordLineEdit::textChanged, 
this, &QgsCredentialDialog::leMasterPass_textChanged );
    50   connect( leMasterPassVerify, &QgsPasswordLineEdit::textChanged, 
this, &QgsCredentialDialog::leMasterPassVerify_textChanged );
    51   connect( chkbxEraseAuthDb, &QCheckBox::toggled, 
this, &QgsCredentialDialog::chkbxEraseAuthDb_toggled );
    54            this, &QgsCredentialDialog::requestCredentials,
    55            Qt::BlockingQueuedConnection );
    57            this, &QgsCredentialDialog::requestCredentialsMasterPassword,
    58            Qt::BlockingQueuedConnection );
    61   mIgnoreButton->setToolTip( tr( 
"All requests for this connection will be automatically rejected" ) );
    62   QMenu *menu = 
new QMenu( mIgnoreButton );
    63   QAction *ignoreTemporarily = 
new QAction( tr( 
"Ignore for 10 Seconds" ), menu );
    64   ignoreTemporarily->setToolTip( tr( 
"All requests for this connection will be automatically rejected for 10 seconds" ) );
    65   QAction *ignoreForSession = 
new QAction( tr( 
"Ignore for Session" ), menu );
    66   ignoreForSession->setToolTip( tr( 
"All requests for this connection will be automatically rejected for the duration of the current session" ) );
    67   menu->addAction( ignoreTemporarily );
    68   menu->addAction( ignoreForSession );
    69   connect( ignoreTemporarily, &QAction::triggered, 
this, [ = ]
    71     mIgnoreMode = IgnoreTemporarily;
    72     mIgnoreButton->setText( ignoreTemporarily->text() );
    73     mIgnoreButton->setToolTip( ignoreTemporarily->toolTip() );
    75   connect( ignoreForSession, &QAction::triggered, 
this, [ = ]
    77     mIgnoreMode = IgnoreForSession;
    78     mIgnoreButton->setText( ignoreForSession->text() );
    79     mIgnoreButton->setToolTip( ignoreForSession->toolTip() );
    81   mIgnoreButton->setText( mIgnoreMode == IgnoreTemporarily ? ignoreTemporarily->text() : ignoreForSession->text() );
    82   mIgnoreButton->setToolTip( mIgnoreMode == IgnoreTemporarily ? ignoreTemporarily->toolTip() : ignoreForSession->toolTip() );
    83   mIgnoreButton->setMenu( menu );
    84   mIgnoreButton->setMaximumHeight( mOkButton->sizeHint().height() );
    87   connect( mOkButton, &QPushButton::clicked, 
this, &QgsCredentialDialog::accept );
    88   connect( mCancelButton, &QPushButton::clicked, 
this, &QgsCredentialDialog::reject );
    91   connect( mIgnoreButton, &QPushButton::clicked, 
this, [ = ]( 
bool )
    93     const QString realm { labelRealm->text() };
    95       QMutexLocker locker( &sIgnoredConnectionsCacheMutex );
    97       sIgnoredConnectionsCache->insert( realm );
    99     if ( mIgnoreMode == IgnoreTemporarily )
   101       QTimer::singleShot( 10000, 
nullptr, [ = ]()
   103         QgsDebugMsgLevel( QStringLiteral( 
"Removing ignored connection from cache: %1" ).arg( realm ), 4 );
   104         QMutexLocker locker( &sIgnoredConnectionsCacheMutex );
   105         sIgnoredConnectionsCache->remove( realm );
   111   leMasterPass->setPlaceholderText( tr( 
"Required" ) );
   112   chkbxPasswordHelperEnable->setText( tr( 
"Store/update the master password in your %1" )
   114   leUsername->setFocus();
   120   if ( qApp->thread() != QThread::currentThread() )
   122     QgsDebugMsg( QStringLiteral( 
"emitting signal" ) );
   124     QgsDebugMsg( QStringLiteral( 
"signal returned %1 (username=%2)" ).arg( ok ? 
"true" : 
"false", username ) );
   128     requestCredentials( realm, &username, &password, message, &ok );
   133 void QgsCredentialDialog::requestCredentials( 
const QString &realm, QString *username, QString *password, 
const QString &message, 
bool *ok )
   135   Q_ASSERT( qApp->thread() == thread() && thread() == QThread::currentThread() );
   138     QMutexLocker locker( &sIgnoredConnectionsCacheMutex );
   139     if ( sIgnoredConnectionsCache->contains( realm ) )
   141       QgsDebugMsg( QStringLiteral( 
"Skipping ignored connection: " ) + realm );
   146   stackedWidget->setCurrentIndex( 0 );
   147   mIgnoreButton->show();
   149   labelRealm->setText( realm );
   150   leUsername->setText( *username );
   151   lePassword->setText( *password );
   152   labelMessage->setText( message );
   153   labelMessage->setHidden( message.isEmpty() );
   155   if ( leUsername->text().isEmpty() )
   156     leUsername->setFocus();
   158     lePassword->setFocus();
   160   QWidget *activeWindow = qApp->activeWindow();
   162   QApplication::setOverrideCursor( Qt::ArrowCursor );
   165   *ok = exec() == QDialog::Accepted;
   166   QgsDebugMsgLevel( QStringLiteral( 
"exec(): %1" ).arg( *ok ? 
"true" : 
"false" ), 4 );
   168   QApplication::restoreOverrideCursor();
   171     activeWindow->raise();
   175     *username = leUsername->text();
   176     *password = lePassword->text();
   183   if ( qApp->thread() != QThread::currentThread() )
   190     requestCredentialsMasterPassword( &password, stored, &ok );
   195 void QgsCredentialDialog::requestCredentialsMasterPassword( QString *password, 
bool stored, 
bool *ok )
   198   stackedWidget->setCurrentIndex( 1 );
   200   mIgnoreButton->hide();
   201   leMasterPass->setFocus();
   203   QString titletxt( stored ? tr( 
"Enter CURRENT master authentication password" ) : tr( 
"Set NEW master authentication password" ) );
   204   lblPasswordTitle->setText( titletxt );
   208   leMasterPassVerify->setVisible( !stored );
   209   lblDontForget->setVisible( !stored );
   211   QApplication::setOverrideCursor( Qt::ArrowCursor );
   213   grpbxPassAttempts->setVisible( 
false );
   217     mOkButton->setEnabled( 
false );
   219     if ( passfailed >= 3 )
   221       lblSavedForSession->setVisible( 
false );
   222       grpbxPassAttempts->setTitle( tr( 
"Password attempts: %1" ).arg( passfailed ) );
   223       grpbxPassAttempts->setVisible( 
true );
   227     QSize s = sizeHint();
   228     s.setWidth( width() );
   232     *ok = exec() == QDialog::Accepted;
   233     QgsDebugMsgLevel( QStringLiteral( 
"exec(): %1" ).arg( *ok ? 
"true" : 
"false" ), 4 );
   237       bool passok = !leMasterPass->text().isEmpty();
   238       if ( passok && stored && !chkbxEraseAuthDb->isChecked() )
   243       if ( passok && !stored )
   245         passok = ( leMasterPass->text() == leMasterPassVerify->text() );
   248       if ( passok || chkbxEraseAuthDb->isChecked() )
   250         if ( stored && chkbxEraseAuthDb->isChecked() )
   256           *password = leMasterPass->text();
   270         leMasterPass->setStyleSheet( invalidStyle_() );
   271         if ( leMasterPassVerify->isVisible() )
   273           leMasterPassVerify->setStyleSheet( invalidStyle_() );
   282     if ( passfailed >= 5 )
   289   leMasterPass->clear();
   290   leMasterPassVerify->clear();
   292   chkbxEraseAuthDb->setChecked( 
false );
   293   lblSavedForSession->setVisible( 
true );
   297   mOkButton->setEnabled( 
true );
   299   QApplication::restoreOverrideCursor();
   301   if ( passfailed >= 5 )
   307 void QgsCredentialDialog::leMasterPass_textChanged( 
const QString &pass )
   309   leMasterPass->setStyleSheet( QString() );
   310   bool passok = !pass.isEmpty(); 
   311   if ( leMasterPassVerify->isVisible() )
   313     leMasterPassVerify->setStyleSheet( QString() );
   314     passok = passok && ( leMasterPass->text() == leMasterPassVerify->text() );
   316   mOkButton->setEnabled( passok );
   318   if ( leMasterPassVerify->isVisible() && !passok )
   320     leMasterPass->setStyleSheet( invalidStyle_() );
   321     leMasterPassVerify->setStyleSheet( invalidStyle_() );
   325 void QgsCredentialDialog::leMasterPassVerify_textChanged( 
const QString &pass )
   327   if ( leMasterPassVerify->isVisible() )
   329     leMasterPass->setStyleSheet( QString() );
   330     leMasterPassVerify->setStyleSheet( QString() );
   333     bool passok = !pass.isEmpty() && ( leMasterPass->text() == leMasterPassVerify->text() );
   334     mOkButton->setEnabled( passok );
   337       leMasterPass->setStyleSheet( invalidStyle_() );
   338       leMasterPassVerify->setStyleSheet( invalidStyle_() );
   343 void QgsCredentialDialog::chkbxEraseAuthDb_toggled( 
bool checked )
   346     mOkButton->setEnabled( 
true );
 bool passwordHelperEnabled() const
Password helper enabled getter. 
 
void setScheduledAuthDatabaseErase(bool scheduleErase)
Schedule an optional erase of authentication database, starting when mutex is lockable. 
 
void setInstance(QgsCredentials *instance)
register instance 
 
QSet< QString > IgnoredConnectionsSet
 
static const QString AUTH_PASSWORD_HELPER_DISPLAY_NAME
The display name of the password helper (platform dependent) 
 
#define QgsDebugMsgLevel(str, level)
 
void credentialsRequested(const QString &, QString *, QString *, const QString &, bool *)
 
Q_GLOBAL_STATIC(IgnoredConnectionsSet, sIgnoredConnectionsCache)
Temporary cache for ignored connections, to avoid GUI freezing by multiple credentials requests to th...
 
static QgsAuthManager * authManager()
Returns the application's authentication manager instance. 
 
bool request(const QString &realm, QString &username, QString &password, const QString &message=QString()) override
request a password 
 
void setPasswordHelperEnabled(bool enabled)
Password helper enabled setter. 
 
QgsCredentialDialog(QWidget *parent=nullptr, Qt::WindowFlags fl=QgsGuiUtils::ModalDialogFlags)
QgsCredentialDialog constructor. 
 
bool requestMasterPassword(QString &password, bool stored=false) override
request a master password 
 
void credentialsRequestedMasterPassword(QString *, bool, bool *)
 
bool verifyMasterPassword(const QString &compare=QString())
Verify the supplied master password against any existing hash in authentication database.