31#include <QGlobalStatic> 
   33QMutex QgsCredentialDialog::sIgnoredConnectionsCacheMutex;
 
   40static QString invalidStyle_( 
const QString &selector = QStringLiteral( 
"QLineEdit" ) )
 
   42  return QStringLiteral( 
"%1{color: rgb(200, 0, 0);}" ).arg( selector );
 
   46  : QDialog( parent, fl )
 
   52  connect( leMasterPass, &QgsPasswordLineEdit::textChanged, 
this, &QgsCredentialDialog::leMasterPass_textChanged );
 
   53  connect( leMasterPassVerify, &QgsPasswordLineEdit::textChanged, 
this, &QgsCredentialDialog::leMasterPassVerify_textChanged );
 
   54  connect( chkbxEraseAuthDb, &QCheckBox::toggled, 
this, &QgsCredentialDialog::chkbxEraseAuthDb_toggled );
 
   57           this, &QgsCredentialDialog::requestCredentials,
 
   58           Qt::BlockingQueuedConnection );
 
   60           this, &QgsCredentialDialog::requestCredentialsMasterPassword,
 
   61           Qt::BlockingQueuedConnection );
 
   64  mIgnoreButton->setToolTip( tr( 
"All requests for this connection will be automatically rejected" ) );
 
   65  QMenu *menu = 
new QMenu( mIgnoreButton );
 
   66  QAction *ignoreTemporarily = 
new QAction( tr( 
"Ignore for 10 Seconds" ), menu );
 
   67  ignoreTemporarily->setToolTip( tr( 
"All requests for this connection will be automatically rejected for 10 seconds" ) );
 
   68  QAction *ignoreForSession = 
new QAction( tr( 
"Ignore for Session" ), menu );
 
   69  ignoreForSession->setToolTip( tr( 
"All requests for this connection will be automatically rejected for the duration of the current session" ) );
 
   70  menu->addAction( ignoreTemporarily );
 
   71  menu->addAction( ignoreForSession );
 
   72  connect( ignoreTemporarily, &QAction::triggered, 
this, [ = ]
 
   74    mIgnoreMode = IgnoreTemporarily;
 
   75    mIgnoreButton->setText( ignoreTemporarily->text() );
 
   76    mIgnoreButton->setToolTip( ignoreTemporarily->toolTip() );
 
   78  connect( ignoreForSession, &QAction::triggered, 
this, [ = ]
 
   80    mIgnoreMode = IgnoreForSession;
 
   81    mIgnoreButton->setText( ignoreForSession->text() );
 
   82    mIgnoreButton->setToolTip( ignoreForSession->toolTip() );
 
   84  mIgnoreButton->setText( mIgnoreMode == IgnoreTemporarily ? ignoreTemporarily->text() : ignoreForSession->text() );
 
   85  mIgnoreButton->setToolTip( mIgnoreMode == IgnoreTemporarily ? ignoreTemporarily->toolTip() : ignoreForSession->toolTip() );
 
   86  mIgnoreButton->setMenu( menu );
 
   87  mIgnoreButton->setMaximumHeight( mOkButton->sizeHint().height() );
 
   90  connect( mOkButton, &QPushButton::clicked, 
this, &QgsCredentialDialog::accept );
 
   91  connect( mCancelButton, &QPushButton::clicked, 
this, &QgsCredentialDialog::reject );
 
   94  connect( mIgnoreButton, &QPushButton::clicked, 
this, [ = ]( 
bool )
 
   96    const QString realm { mRealm };
 
   98      const QMutexLocker locker( &sIgnoredConnectionsCacheMutex );
 
  100      sIgnoredConnectionsCache->insert( realm );
 
  102    if ( mIgnoreMode == IgnoreTemporarily )
 
  104      QTimer::singleShot( 10000, 
nullptr, [ = ]()
 
  106        QgsDebugMsgLevel( QStringLiteral( 
"Removing ignored connection from cache: %1" ).arg( realm ), 4 );
 
  107        const QMutexLocker locker( &sIgnoredConnectionsCacheMutex );
 
  108        sIgnoredConnectionsCache->remove( realm );
 
  114  leMasterPass->setPlaceholderText( tr( 
"Required" ) );
 
  115  chkbxPasswordHelperEnable->setText( tr( 
"Store/update the master password in your %1" )
 
  117  leUsername->setFocus();
 
 
  123  if ( qApp->thread() != QThread::currentThread() )
 
  127    QgsDebugMsgLevel( QStringLiteral( 
"signal returned %1 (username=%2)" ).arg( ok ? 
"true" : 
"false", username ), 2 );
 
  131    requestCredentials( realm, &username, &password, message, &ok );
 
 
  136void QgsCredentialDialog::requestCredentials( 
const QString &realm, QString *username, QString *password, 
const QString &message, 
bool *ok )
 
  138  Q_ASSERT( qApp->thread() == thread() && thread() == QThread::currentThread() );
 
  141    const QMutexLocker locker( &sIgnoredConnectionsCacheMutex );
 
  142    if ( sIgnoredConnectionsCache->contains( realm ) )
 
  144      QgsDebugMsgLevel( QStringLiteral( 
"Skipping ignored connection: " ) + realm, 2 );
 
  149  stackedWidget->setCurrentIndex( 0 );
 
  150  mIgnoreButton->show();
 
  154  leUsername->setText( *username );
 
  155  lePassword->setText( *password );
 
  156  labelMessage->setText( message );
 
  157  labelMessage->setHidden( message.isEmpty() );
 
  159  if ( leUsername->text().isEmpty() )
 
  160    leUsername->setFocus();
 
  162    lePassword->setFocus();
 
  164  QWidget *activeWindow = qApp->activeWindow();
 
  166  QApplication::setOverrideCursor( Qt::ArrowCursor );
 
  169  *ok = exec() == QDialog::Accepted;
 
  170  QgsDebugMsgLevel( QStringLiteral( 
"exec(): %1" ).arg( *ok ? 
"true" : 
"false" ), 4 );
 
  172  QApplication::restoreOverrideCursor();
 
  175    activeWindow->raise();
 
  179    *username = leUsername->text();
 
  180    *password = lePassword->text();
 
  187  if ( qApp->thread() != QThread::currentThread() )
 
  194    requestCredentialsMasterPassword( &password, stored, &ok );
 
 
  199void QgsCredentialDialog::requestCredentialsMasterPassword( QString *password, 
bool stored, 
bool *ok )
 
  202  stackedWidget->setCurrentIndex( 1 );
 
  204  mIgnoreButton->hide();
 
  205  leMasterPass->setFocus();
 
  207  const QString titletxt( stored ? tr( 
"Enter CURRENT master authentication password" ) : tr( 
"Set NEW master authentication password" ) );
 
  208  lblPasswordTitle->setText( titletxt );
 
  212  leMasterPassVerify->setVisible( !stored );
 
  213  lblDontForget->setVisible( !stored );
 
  215  QApplication::setOverrideCursor( Qt::ArrowCursor );
 
  217  grpbxPassAttempts->setVisible( 
false );
 
  221    mOkButton->setEnabled( 
false );
 
  223    if ( passfailed >= 3 )
 
  225      lblSavedForSession->setVisible( 
false );
 
  226      grpbxPassAttempts->setTitle( tr( 
"Password attempts: %1" ).arg( passfailed ) );
 
  227      grpbxPassAttempts->setVisible( 
true );
 
  231    QSize s = sizeHint();
 
  232    s.setWidth( width() );
 
  236    *ok = exec() == QDialog::Accepted;
 
  237    QgsDebugMsgLevel( QStringLiteral( 
"exec(): %1" ).arg( *ok ? 
"true" : 
"false" ), 4 );
 
  241      bool passok = !leMasterPass->text().isEmpty();
 
  242      if ( passok && stored && !chkbxEraseAuthDb->isChecked() )
 
  247      if ( passok && !stored )
 
  249        passok = ( leMasterPass->text() == leMasterPassVerify->text() );
 
  252      if ( passok || chkbxEraseAuthDb->isChecked() )
 
  254        if ( stored && chkbxEraseAuthDb->isChecked() )
 
  260          *password = leMasterPass->text();
 
  274        leMasterPass->setStyleSheet( invalidStyle_() );
 
  275        if ( leMasterPassVerify->isVisible() )
 
  277          leMasterPassVerify->setStyleSheet( invalidStyle_() );
 
  286    if ( passfailed >= 5 )
 
  293  leMasterPass->clear();
 
  294  leMasterPassVerify->clear();
 
  296  chkbxEraseAuthDb->setChecked( 
false );
 
  297  lblSavedForSession->setVisible( 
true );
 
  301  mOkButton->setEnabled( 
true );
 
  303  QApplication::restoreOverrideCursor();
 
  305  if ( passfailed >= 5 )
 
  311void QgsCredentialDialog::leMasterPass_textChanged( 
const QString &pass )
 
  313  leMasterPass->setStyleSheet( QString() );
 
  314  bool passok = !pass.isEmpty(); 
 
  315  if ( leMasterPassVerify->isVisible() )
 
  317    leMasterPassVerify->setStyleSheet( QString() );
 
  318    passok = passok && ( leMasterPass->text() == leMasterPassVerify->text() );
 
  320  mOkButton->setEnabled( passok );
 
  322  if ( leMasterPassVerify->isVisible() && !passok )
 
  324    leMasterPass->setStyleSheet( invalidStyle_() );
 
  325    leMasterPassVerify->setStyleSheet( invalidStyle_() );
 
  329void QgsCredentialDialog::leMasterPassVerify_textChanged( 
const QString &pass )
 
  331  if ( leMasterPassVerify->isVisible() )
 
  333    leMasterPass->setStyleSheet( QString() );
 
  334    leMasterPassVerify->setStyleSheet( QString() );
 
  337    const bool passok = !pass.isEmpty() && ( leMasterPass->text() == leMasterPassVerify->text() );
 
  338    mOkButton->setEnabled( passok );
 
  341      leMasterPass->setStyleSheet( invalidStyle_() );
 
  342      leMasterPassVerify->setStyleSheet( invalidStyle_() );
 
  347void QgsCredentialDialog::chkbxEraseAuthDb_toggled( 
bool checked )
 
  350    mOkButton->setEnabled( 
true );
 
static QgsAuthManager * authManager()
Returns the application's authentication manager instance.
 
bool verifyMasterPassword(const QString &compare=QString())
Verify the supplied master password against any existing hash in authentication database.
 
static bool passwordHelperEnabled()
Password helper enabled getter.
 
void setPasswordHelperEnabled(bool enabled)
Password helper enabled setter.
 
void setScheduledAuthDatabaseErase(bool scheduleErase)
Schedule an optional erase of authentication database, starting when mutex is lockable.
 
static const QString AUTH_PASSWORD_HELPER_DISPLAY_NAME
The display name of the password helper (platform dependent)
 
QgsCredentialDialog(QWidget *parent=nullptr, Qt::WindowFlags fl=QgsGuiUtils::ModalDialogFlags)
QgsCredentialDialog constructor.
 
bool requestMasterPassword(QString &password, bool stored=false) override
request a master password
 
bool request(const QString &realm, QString &username, QString &password, const QString &message=QString()) override
request a password
 
void credentialsRequested(const QString &, QString *, QString *, const QString &, bool *)
 
void credentialsRequestedMasterPassword(QString *, bool, bool *)
 
void setInstance(QgsCredentials *instance)
register instance
 
static QString removePassword(const QString &aUri, bool hide=false)
Removes the password element from a URI.
 
static void enableAutoGeometryRestore(QWidget *widget, const QString &key=QString())
Register the widget to allow its position to be automatically saved and restored when open and closed...
 
Q_GLOBAL_STATIC(IgnoredConnectionsSet, sIgnoredConnectionsCache)
Temporary cache for ignored connections, to avoid GUI freezing by multiple credentials requests to th...
 
QSet< QString > IgnoredConnectionsSet
 
#define QgsDebugMsgLevel(str, level)