Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When changing master password, don't prompt for the existing password if it is stored in the system password helper and is valid #55228

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion python/core/auto_generated/auth/qgsauthmanager.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ Check whether supplied password is the same as the one already set
bool resetMasterPassword( const QString &newpass, const QString &oldpass, bool keepbackup, QString *backuppath /In,Out/ = 0 );
%Docstring
Reset the master password to a new one, then re-encrypt all previous
configs in a new database file, optionally backup curren database
configs in a new database file, optionally backup current database

:param newpass: New master password to replace existing
:param oldpass: Current master password to replace existing
Expand All @@ -157,6 +157,7 @@ configs in a new database file, optionally backup curren database




void setScheduledAuthDatabaseEraseRequestEmitted( bool emitted );
%Docstring
Re-emit a signal to schedule an optional erase of authentication database.
Expand Down Expand Up @@ -773,6 +774,7 @@ Store the password manager into the wallet
Available in Python bindings since QGIS 3.8.0
%End


static const QString AUTH_PASSWORD_HELPER_DISPLAY_NAME;

static const QString AUTH_MAN_TAG;
Expand Down
24 changes: 24 additions & 0 deletions src/core/auth/qgsauthmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -802,6 +802,17 @@ bool QgsAuthManager::resetMasterPassword( const QString &newpass, const QString
return true;
}

bool QgsAuthManager::resetMasterPasswordUsingStoredPasswordHelper( const QString &newpass, bool keepbackup, QString *backuppath )
{
if ( !verifyStoredPasswordHelperPassword() )
{
emit passwordHelperMessageOut( tr( "Master password stored in your %1 is not valid" ).arg( AUTH_PASSWORD_HELPER_DISPLAY_NAME ), authManTag(), WARNING );
return false;
}

return resetMasterPassword( newpass, passwordHelperRead(), keepbackup, backuppath );
}

void QgsAuthManager::setScheduledAuthDatabaseErase( bool scheduleErase )
{
mScheduledDbErase = scheduleErase;
Expand Down Expand Up @@ -3070,6 +3081,19 @@ bool QgsAuthManager::passwordHelperSync()
return false;
}

bool QgsAuthManager::verifyStoredPasswordHelperPassword()
{
if ( !passwordHelperEnabled() )
return false;

const QString currentPass = passwordHelperRead();
if ( !currentPass.isEmpty() && ( mPasswordHelperErrorCode == QKeychain::NoError ) )
{
return verifyMasterPassword( currentPass );
}
return false;
}


////////////////// Certificate calls - end ///////////////////////

Expand Down
26 changes: 25 additions & 1 deletion src/core/auth/qgsauthmanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,14 +153,29 @@ class CORE_EXPORT QgsAuthManager : public QObject

/**
* Reset the master password to a new one, then re-encrypt all previous
* configs in a new database file, optionally backup curren database
* configs in a new database file, optionally backup current database
* \param newpass New master password to replace existing
* \param oldpass Current master password to replace existing
* \param keepbackup Whether to keep the generated backup of current database
* \param backuppath Where the backup is located, if kept
*/
bool resetMasterPassword( const QString &newpass, const QString &oldpass, bool keepbackup, QString *backuppath SIP_INOUT = nullptr );

/**
* Reset the master password to a new one, then re-encrypt all previous
* configs in a new database file, optionally backup current database.
*
* The old password will automatically be retrieved from the password helper.
*
* \param newpass New master password to replace existing
* \param keepbackup Whether to keep the generated backup of current database
* \param backuppath Where the backup is located, if kept
*
* \note Not available in Python bindings
* \since QGIS 3.36
*/
bool resetMasterPasswordUsingStoredPasswordHelper( const QString &newpass, bool keepbackup, QString *backuppath = nullptr ) SIP_SKIP;

/**
* Whether there is a scheduled opitonal erase of authentication database.
* \note not available in Python bindings
Expand Down Expand Up @@ -704,6 +719,15 @@ class CORE_EXPORT QgsAuthManager : public QObject
*/
bool passwordHelperSync();

/**
* Verify the password stored in the password helper.
*
*
* \note Not available in Python bindings
* \since QGIS 3.36
*/
bool verifyStoredPasswordHelperPassword() SIP_SKIP;

//! The display name of the password helper (platform dependent)
static const QString AUTH_PASSWORD_HELPER_DISPLAY_NAME;

Expand Down
34 changes: 26 additions & 8 deletions src/gui/auth/qgsauthguiutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,20 +213,38 @@ void QgsAuthGuiUtils::resetMasterPassword( QgsMessageBar *msgbar, QWidget *pare
// get new password via dialog; do current password verification in-dialog
QString newpass;
QString oldpass;

bool keepbackup = false;
QgsMasterPasswordResetDialog dlg( parent );

if ( !dlg.requestMasterPasswordReset( &newpass, &oldpass, &keepbackup ) )
QString backuppath;
if ( QgsApplication::authManager()->verifyStoredPasswordHelperPassword()
&& ( QgsApplication::authManager()->masterPasswordIsSet() || QgsApplication::authManager()->setMasterPassword( true ) ) )
{
QgsDebugMsgLevel( QStringLiteral( "Master password reset: input canceled by user" ), 2 );
return;
dlg.useDummyOldPassword();
if ( !dlg.requestMasterPasswordReset( &newpass, &oldpass, &keepbackup ) )
{
QgsDebugMsgLevel( QStringLiteral( "Master password reset: input canceled by user" ), 2 );
return;
}
if ( !QgsApplication::authManager()->resetMasterPasswordUsingStoredPasswordHelper( newpass, keepbackup, &backuppath ) )
{
msg = QObject::tr( "Master password FAILED to be reset" );
level = Qgis::MessageLevel::Warning;
}
}

QString backuppath;
if ( !QgsApplication::authManager()->resetMasterPassword( newpass, oldpass, keepbackup, &backuppath ) )
else
{
msg = QObject::tr( "Master password FAILED to be reset" );
level = Qgis::MessageLevel::Warning;
if ( !dlg.requestMasterPasswordReset( &newpass, &oldpass, &keepbackup ) )
{
QgsDebugMsgLevel( QStringLiteral( "Master password reset: input canceled by user" ), 2 );
return;
}
if ( !QgsApplication::authManager()->resetMasterPassword( newpass, oldpass, keepbackup, &backuppath ) )
{
msg = QObject::tr( "Master password FAILED to be reset" );
level = Qgis::MessageLevel::Warning;
}
}

if ( !backuppath.isEmpty() )
Expand Down
20 changes: 17 additions & 3 deletions src/gui/auth/qgsauthmasterpassresetdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ QgsMasterPasswordResetDialog::QgsMasterPasswordResetDialog( QWidget *parent )
}
}

void QgsMasterPasswordResetDialog::useDummyOldPassword()
{
leMasterPassCurrent->setText( QStringLiteral( "***************" ) );
leMasterPassCurrent->setEnabled( false );
}

bool QgsMasterPasswordResetDialog::requestMasterPasswordReset( QString *newpass, QString *oldpass, bool *keepbackup )
{
if ( !QgsApplication::authManager()->isDisabled() )
Expand Down Expand Up @@ -81,9 +87,17 @@ void QgsMasterPasswordResetDialog::leMasterPassNew_textChanged( const QString &p

void QgsMasterPasswordResetDialog::validatePasswords()
{
const QString ss1 = mPassCurOk ? QgsAuthGuiUtils::greenTextStyleSheet( QStringLiteral( "QLineEdit" ) )
: QgsAuthGuiUtils::redTextStyleSheet( QStringLiteral( "QLineEdit" ) );
leMasterPassCurrent->setStyleSheet( ss1 );
if ( leMasterPassCurrent->isEnabled() )
{
const QString ss1 = mPassCurOk ? QgsAuthGuiUtils::greenTextStyleSheet( QStringLiteral( "QLineEdit" ) )
: QgsAuthGuiUtils::redTextStyleSheet( QStringLiteral( "QLineEdit" ) );
leMasterPassCurrent->setStyleSheet( ss1 );
}
else
{
leMasterPassCurrent->setStyleSheet( QString() );
}

const QString ss2 = mPassNewOk ? QgsAuthGuiUtils::greenTextStyleSheet( QStringLiteral( "QLineEdit" ) )
: QgsAuthGuiUtils::redTextStyleSheet( QStringLiteral( "QLineEdit" ) );
leMasterPassNew->setStyleSheet( ss2 );
Expand Down
9 changes: 9 additions & 0 deletions src/gui/auth/qgsauthmasterpassresetdialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,15 @@ class GUI_EXPORT QgsMasterPasswordResetDialog : public QDialog, private Ui::QgsM
public:
explicit QgsMasterPasswordResetDialog( QWidget *parent = nullptr );

/**
* Use an dummy password for the "old" password option, and disable user entry
* of old password.
*
* This can be used when the old password is not required by the user (i.e. it
* will be retrieved from the system password helper).
*/
void useDummyOldPassword();

bool requestMasterPasswordReset( QString *newpass, QString *oldpass, bool *keepbackup );

private slots:
Expand Down
Loading