Skip to content

Commit

Permalink
Option to ignore the connection temporarily of for the session
Browse files Browse the repository at this point in the history
  • Loading branch information
elpaso authored and nyalldawson committed Nov 11, 2019
1 parent df7d05e commit ca0b7f6
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 67 deletions.
66 changes: 51 additions & 15 deletions src/gui/qgscredentialdialog.cpp
Expand Up @@ -23,11 +23,17 @@
#include "qgsapplication.h"

#include <QPushButton>
#include <QMenu>
#include <QToolButton>
#include <QThread>
#include <QTimer>
#include <QGlobalStatic>

QSet<QString> QgsCredentialDialog::sIgnoredConnectionsCache;
QMutex QgsCredentialDialog::sIgnoredConnectionsCacheMutex;
typedef QSet<QString> IgnoredConnectionsSet;

//! Temporary cache for ignored connections, to avoid GUI freezing by multiple credentials requests to the same connection
Q_GLOBAL_STATIC( IgnoredConnectionsSet, sIgnoredConnectionsCache );


static QString invalidStyle_( const QString &selector = QStringLiteral( "QLineEdit" ) )
Expand All @@ -50,25 +56,55 @@ QgsCredentialDialog::QgsCredentialDialog( QWidget *parent, Qt::WindowFlags fl )
connect( this, &QgsCredentialDialog::credentialsRequestedMasterPassword,
this, &QgsCredentialDialog::requestCredentialsMasterPassword,
Qt::BlockingQueuedConnection );
mOkButton = buttonBox->button( QDialogButtonBox::Ok );
QPushButton *ignoreButton { buttonBox->button( QDialogButtonBox::StandardButton::Ignore ) };
ignoreButton->setToolTip( tr( "All requests for this connection will be automatically rejected for the next 60 seconds." ) );

// Keep a cache of ignored connections, and ignore them for 60 seconds.
connect( ignoreButton, &QPushButton::clicked, [ = ]( bool )
// Setup ignore button
mIgnoreButton->setToolTip( tr( "All requests for this connection will be automatically rejected" ) );
QMenu *menu = new QMenu( mIgnoreButton );
QAction *ignoreTemporarily = new QAction( tr( "Ignore for 10 seconds" ), menu );
ignoreTemporarily->setToolTip( tr( "All requests for this connection will be automatically rejected for 10 seconds" ) );
QAction *ignoreForSession = new QAction( tr( "Ignore for session" ), menu );
ignoreForSession->setToolTip( tr( "All requests for this connection will be automatically rejected for the duration of the current session" ) );
menu->addAction( ignoreTemporarily );
menu->addAction( ignoreForSession );
connect( ignoreTemporarily, &QAction::triggered, [ = ]
{
mIgnoreMode = IgnoreTemporarily;
//mIgnoreButton->setText( ignoreTemporarily->text() );
mIgnoreButton->setToolTip( ignoreTemporarily->toolTip() );
} );
connect( ignoreForSession, &QAction::triggered, [ = ]
{
mIgnoreMode = IgnoreForSession;
//mIgnoreButton->setText( ignoreForSession->text() );
mIgnoreButton->setToolTip( ignoreForSession->toolTip() );
} );
mIgnoreButton->setText( mIgnoreMode == IgnoreTemporarily ? ignoreTemporarily->text() : ignoreForSession->text() );
mIgnoreButton->setToolTip( mIgnoreMode == IgnoreTemporarily ? ignoreTemporarily->toolTip() : ignoreForSession->toolTip() );
mIgnoreButton->setMenu( menu );
mIgnoreButton->setMaximumHeight( mOkButton->sizeHint().height() );

// Connect ok and cancel buttons
connect( mOkButton, &QPushButton::clicked, this, &QgsCredentialDialog::accept );
connect( mCancelButton, &QPushButton::clicked, this, &QgsCredentialDialog::reject );

// Keep a cache of ignored connections, and ignore them for 10 seconds.
connect( mIgnoreButton, &QPushButton::clicked, [ = ]( bool )
{
const QString realm { labelRealm->text() };
{
QMutexLocker locker( &sIgnoredConnectionsCacheMutex );
// Insert the realm in the cache of ignored connections
sIgnoredConnectionsCache.insert( realm );
sIgnoredConnectionsCache->insert( realm );
}
QTimer::singleShot( 60000, [ = ]()
if ( mIgnoreMode == IgnoreTemporarily )
{
QgsDebugMsgLevel( QStringLiteral( "Removing ignored connection from cache: %1" ).arg( realm ), 4 );
QMutexLocker locker( &sIgnoredConnectionsCacheMutex );
sIgnoredConnectionsCache.remove( realm );
} );
QTimer::singleShot( 10000, [ = ]()
{
QgsDebugMsgLevel( QStringLiteral( "Removing ignored connection from cache: %1" ).arg( realm ), 4 );
QMutexLocker locker( &sIgnoredConnectionsCacheMutex );
sIgnoredConnectionsCache->remove( realm );
} );
}
accept( );
} );

Expand Down Expand Up @@ -100,15 +136,15 @@ void QgsCredentialDialog::requestCredentials( const QString &realm, QString *use
QgsDebugMsgLevel( QStringLiteral( "Entering." ), 4 );
{
QMutexLocker locker( &sIgnoredConnectionsCacheMutex );
if ( sIgnoredConnectionsCache.contains( realm ) )
if ( sIgnoredConnectionsCache->contains( realm ) )
{
QgsDebugMsg( QStringLiteral( "Skipping ignored connection: " ) + realm );
*ok = false;
return;
}
}
stackedWidget->setCurrentIndex( 0 );
buttonBox->button( QDialogButtonBox::StandardButton::Ignore )->show();
mIgnoreButton->show();
chkbxPasswordHelperEnable->setChecked( QgsApplication::authManager()->passwordHelperEnabled() );
labelRealm->setText( realm );
leUsername->setText( *username );
Expand Down Expand Up @@ -161,7 +197,7 @@ void QgsCredentialDialog::requestCredentialsMasterPassword( QString *password, b
QgsDebugMsgLevel( QStringLiteral( "Entering." ), 4 );
stackedWidget->setCurrentIndex( 1 );

buttonBox->button( QDialogButtonBox::StandardButton::Ignore )->hide();
mIgnoreButton->hide();
leMasterPass->setFocus();

QString titletxt( stored ? tr( "Enter CURRENT master authentication password" ) : tr( "Set NEW master authentication password" ) );
Expand Down
16 changes: 13 additions & 3 deletions src/gui/qgscredentialdialog.h
Expand Up @@ -63,11 +63,21 @@ class GUI_EXPORT QgsCredentialDialog : public QDialog, public QgsCredentials, pr
bool requestMasterPassword( QString &password SIP_INOUT, bool stored = false ) override;

private:
QPushButton *mOkButton = nullptr;
//! Temporary cache for ignored connections, to avoid GUI freezing by multiple credentials requests to the same connection
static QSet<QString> sIgnoredConnectionsCache;

/**
* The ConnectionsIgnoreMode enum represent the modes a connection can be ignored
*/
enum ConnectionsIgnoreMode
{
IgnoreTemporarily, //!< Ignore for a certain amount of time
IgnoreForSession, //!< Ignore for the whole QGIS session
};

//! mutex for the static ignored connections cache
static QMutex sIgnoredConnectionsCacheMutex;

ConnectionsIgnoreMode mIgnoreMode = ConnectionsIgnoreMode::IgnoreTemporarily;

};

#endif
108 changes: 59 additions & 49 deletions src/ui/qgscredentialdialog.ui
Expand Up @@ -6,28 +6,15 @@
<rect>
<x>0</x>
<y>0</y>
<width>396</width>
<width>358</width>
<height>293</height>
</rect>
</property>
<property name="windowTitle">
<string>Enter Credentials</string>
</property>
<layout class="QFormLayout" name="formLayout">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::ExpandingFieldsGrow</enum>
</property>
<item row="3" column="0" colspan="2">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ignore|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<item row="0" column="0">
<widget class="QStackedWidget" name="stackedWidget">
<property name="currentIndex">
<number>1</number>
Expand Down Expand Up @@ -212,6 +199,62 @@ font-style: italic;
</widget>
</widget>
</item>
<item row="1" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="mOkButton">
<property name="text">
<string>Ok</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="mIgnoreButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="toolTip">
<string>All requests for this connection will be automatically rejected for the next 60 seconds</string>
</property>
<property name="text">
<string>Ignore</string>
</property>
<property name="popupMode">
<enum>QToolButton::MenuButtonPopup</enum>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextOnly</enum>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="mCancelButton">
<property name="text">
<string>Cancel</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
Expand All @@ -229,38 +272,5 @@ font-style: italic;
<tabstop>chkbxEraseAuthDb</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>QgsCredentialDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>QgsCredentialDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
<connections/>
</ui>

0 comments on commit ca0b7f6

Please sign in to comment.