QGIS API Documentation 3.41.0-Master (1deb1daf037)
Loading...
Searching...
No Matches
qgsauthguiutils.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsauthutils.cpp
3 ---------------------
4 begin : October 24, 2014
5 copyright : (C) 2014 by Boundless Spatial, Inc. USA
6 author : Larry Shaffer
7 email : lshaffer at boundlessgeo dot com
8 ***************************************************************************
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 ***************************************************************************/
16
17#include "qgsauthguiutils.h"
18
19#include <QFileDialog>
20#include <QInputDialog>
21#include <QLineEdit>
22#include <QMessageBox>
23#include <QTreeWidgetItem>
24
25#include "qgssettings.h"
26#include "qgsauthmanager.h"
28#include "qgslogger.h"
29#include "qgsmessagebar.h"
30#include "qgsapplication.h"
31
32
34{
35 return QColor( 0, 170, 0 );
36}
37
39{
40 return QColor( 255, 128, 0 );
41}
42
44{
45 return QColor( 200, 0, 0 );
46}
47
49{
50 return QColor( 255, 255, 125 );
51}
52
53QString QgsAuthGuiUtils::greenTextStyleSheet( const QString &selector )
54{
55 return QStringLiteral( "%1{color: %2;}" ).arg( selector, QgsAuthGuiUtils::greenColor().name() );
56}
57
58QString QgsAuthGuiUtils::orangeTextStyleSheet( const QString &selector )
59{
60 return QStringLiteral( "%1{color: %2;}" ).arg( selector, QgsAuthGuiUtils::orangeColor().name() );
61}
62
63QString QgsAuthGuiUtils::redTextStyleSheet( const QString &selector )
64{
65 return QStringLiteral( "%1{color: %2;}" ).arg( selector, QgsAuthGuiUtils::redColor().name() );
66}
67
69{
71 {
72 msgbar->clearWidgets();
73 msgbar->pushMessage( QObject::tr( "Authentication System" ), QObject::tr( "DISABLED. Resources authenticating via the system can not be accessed" ), Qgis::MessageLevel::Critical );
74 return true;
75 }
76 return false;
77}
78
79void QgsAuthGuiUtils::exportSelectedAuthenticationConfigs( QStringList authenticationConfigIds, QgsMessageBar *msgbar )
80{
81 const QString password = QInputDialog::getText( msgbar, QObject::tr( "Export Authentication Configurations" ), QObject::tr( "Enter a password encrypt the configuration file:" ), QLineEdit::Password );
82 if ( password.isEmpty() )
83 {
84 if ( QMessageBox::warning( msgbar, QObject::tr( "Export Authentication Configurations" ), QObject::tr( "Exporting authentication configurations with a blank password will result in a plain text file which may contain sensitive information. Are you sure you want to do this?" ), QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel ) == QMessageBox::Cancel )
85 {
86 return;
87 }
88 }
89
90 const QString filename = QFileDialog::getSaveFileName( msgbar, QObject::tr( "Export Authentication Configurations" ), QDir::homePath(), QObject::tr( "XML files (*.xml *.XML)" ) );
91 if ( filename.isEmpty() )
92 return;
93
94 const bool ok = QgsApplication::authManager()->exportAuthenticationConfigsToXml( filename, authenticationConfigIds, password );
95 if ( !ok )
96 {
97 msgbar->clearWidgets();
98 msgbar->pushMessage( QgsApplication::authManager()->authManTag(), QObject::tr( "Export of authentication configurations failed." ), Qgis::MessageLevel::Critical );
99 }
100}
101
103{
104 const QString filename = QFileDialog::getOpenFileName( msgbar, QObject::tr( "Export Authentication Configurations" ), QDir::homePath(), QObject::tr( "XML files (*.xml *.XML)" ) );
105 if ( filename.isEmpty() )
106 return;
107
108
109 QFile file( filename );
110 if ( !file.open( QFile::ReadOnly ) )
111 {
112 return;
113 }
114
115 QDomDocument document( QStringLiteral( "qgis_authentication" ) );
116 if ( !document.setContent( &file ) )
117 {
118 file.close();
119 return;
120 }
121 file.close();
122
123 const QDomElement root = document.documentElement();
124 if ( root.tagName() != QLatin1String( "qgis_authentication" ) )
125 {
126 return;
127 }
128
129 QString password;
130 if ( root.hasAttribute( QStringLiteral( "salt" ) ) )
131 {
132 password = QInputDialog::getText( msgbar, QObject::tr( "Import Authentication Configurations" ), QObject::tr( "Enter the password to decrypt the configurations file:" ), QLineEdit::Password );
133 }
134
135 const bool ok = QgsApplication::authManager()->importAuthenticationConfigsFromXml( filename, password );
136 if ( !ok )
137 {
138 msgbar->clearWidgets();
139 msgbar->pushMessage( QgsApplication::authManager()->authManTag(), QObject::tr( "Import of authentication configurations failed." ), Qgis::MessageLevel::Critical );
140 }
141}
142
144{
145 if ( QgsAuthGuiUtils::isDisabled( msgbar ) )
146 return;
147
148 if ( QgsApplication::authManager()->masterPasswordIsSet() )
149 {
150 msgbar->clearWidgets();
151 msgbar->pushMessage( QgsApplication::authManager()->authManTag(), QObject::tr( "Master password already set." ), Qgis::MessageLevel::Info );
152 return;
153 }
155}
156
158{
159 if ( QgsAuthGuiUtils::isDisabled( msgbar ) )
160 return;
161
162 QString msg( QObject::tr( "Master password not cleared because it is not set." ) );
164
165 if ( QgsApplication::authManager()->masterPasswordIsSet() )
166 {
168 msg = QObject::tr( "Master password cleared (NOTE: network connections may be cached)." );
169 if ( QgsApplication::authManager()->masterPasswordIsSet() )
170 {
171 msg = QObject::tr( "Master password FAILED to be cleared." );
173 }
174 }
175
176 msgbar->clearWidgets();
177 msgbar->pushMessage( QgsApplication::authManager()->authManTag(), msg, level );
178}
179
181{
182 if ( QgsAuthGuiUtils::isDisabled( msgbar ) )
183 return;
184
185 QString msg( QObject::tr( "Master password reset" ) );
187
188 // check that a master password is even set in auth db
189 if ( !QgsApplication::authManager()->masterPasswordHashInDatabase() )
190 {
191 msg = QObject::tr( "Master password reset: NO current password hash in database" );
192 msgbar->clearWidgets();
194 return;
195 }
196
197 // get new password via dialog; do current password verification in-dialog
198 QString newpass;
199 QString oldpass;
200
201 bool keepbackup = false;
202 QgsMasterPasswordResetDialog dlg( parent );
203
204 QString backuppath;
205 // if password helper enabled and user is using the default random generated password, then
206 // just fill this in automatically (the user will have NO idea what this is!)
207 if ( QgsApplication::authManager()->verifyStoredPasswordHelperPassword()
208 && ( QgsApplication::authManager()->masterPasswordIsSet() || QgsApplication::authManager()->setMasterPassword( true ) )
210 {
211 dlg.oldPasswordLineEdit()->setText( QStringLiteral( "***************" ) );
212 dlg.oldPasswordLineEdit()->setEnabled( false );
213 dlg.oldPasswordLineEdit()->setToolTip( QObject::tr( "Existing password has been automatically read from the %1" ).arg( QgsAuthManager::passwordHelperDisplayName() ) );
214 if ( !dlg.requestMasterPasswordReset( &newpass, &oldpass, &keepbackup ) )
215 {
216 QgsDebugMsgLevel( QStringLiteral( "Master password reset: input canceled by user" ), 2 );
217 return;
218 }
219 if ( !QgsApplication::authManager()->resetMasterPasswordUsingStoredPasswordHelper( newpass, keepbackup, &backuppath ) )
220 {
221 msg = QObject::tr( "Master password FAILED to be reset" );
223 }
224 }
225 else
226 {
227 if ( !dlg.requestMasterPasswordReset( &newpass, &oldpass, &keepbackup ) )
228 {
229 QgsDebugMsgLevel( QStringLiteral( "Master password reset: input canceled by user" ), 2 );
230 return;
231 }
232 if ( !QgsApplication::authManager()->resetMasterPassword( newpass, oldpass, keepbackup, &backuppath ) )
233 {
234 msg = QObject::tr( "Master password FAILED to be reset" );
236 }
237 }
238
239 if ( !backuppath.isEmpty() )
240 {
241 msg += QObject::tr( " (database backup: %1)" ).arg( backuppath );
242 }
243
244 msgbar->clearWidgets();
245 msgbar->pushMessage( QgsApplication::authManager()->authManTag(), msg, level );
246}
247
249{
250 if ( QgsAuthGuiUtils::isDisabled( msgbar ) )
251 return;
252
254 const QString msg = QObject::tr( "Cached authentication configurations for session cleared" );
255 msgbar->clearWidgets();
257}
258
260{
261 if ( QgsAuthGuiUtils::isDisabled( msgbar ) )
262 return;
263
264 if ( QMessageBox::warning( parent, QObject::tr( "Remove Configurations" ), QObject::tr( "Are you sure you want to remove ALL authentication configurations?\n\n"
265 "Operation can NOT be undone!" ),
266 QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel )
267 == QMessageBox::Cancel )
268 {
269 return;
270 }
271
272 QString msg( QObject::tr( "Authentication configurations removed." ) );
274
275 if ( !QgsApplication::authManager()->removeAllAuthenticationConfigs() )
276 {
277 msg = QObject::tr( "Authentication configurations FAILED to be removed." );
279 }
280
281 msgbar->clearWidgets();
282 msgbar->pushMessage( QgsApplication::authManager()->authManTag(), msg, level );
283}
284
286{
287 if ( QgsAuthGuiUtils::isDisabled( msgbar ) )
288 return;
289
290 const QMessageBox::StandardButton btn = QMessageBox::warning(
291 parent,
292 QObject::tr( "Erase Database" ),
293 QObject::tr( "Are you sure you want to ERASE the entire authentication database?\n\n"
294 "Operation can NOT be undone!\n\n"
295 "(Current database will be backed up and new one created.)" ),
296 QMessageBox::Ok | QMessageBox::Cancel,
297 QMessageBox::Cancel
298 );
299
301
302 if ( btn == QMessageBox::Cancel )
303 {
304 return;
305 }
306
307 QString msg( QObject::tr( "Active authentication database erased." ) );
309
310 QString backuppath;
311 if ( !QgsApplication::authManager()->eraseAuthenticationDatabase( true, &backuppath ) )
312 {
313 msg = QObject::tr( "Authentication database FAILED to be erased." );
315 }
316 else
317 {
318 if ( !backuppath.isEmpty() )
319 {
320 msg += QObject::tr( " (backup: %1)" ).arg( backuppath );
321 }
323 }
324
325 msgbar->clearWidgets();
326 msgbar->pushMessage( QObject::tr( "RESTART QGIS" ), msg, level );
327}
328
329void QgsAuthGuiUtils::fileFound( bool found, QWidget *widget )
330{
331 if ( !found )
332 {
333 widget->setStyleSheet( QgsAuthGuiUtils::redTextStyleSheet( QStringLiteral( "QLineEdit" ) ) );
334 widget->setToolTip( QObject::tr( "File not found" ) );
335 }
336 else
337 {
338 widget->setStyleSheet( QString() );
339 widget->setToolTip( QString() );
340 }
341}
342
343QString QgsAuthGuiUtils::getOpenFileName( QWidget *parent, const QString &title, const QString &extfilter )
344{
345 QgsSettings settings;
346 const QString recentdir = settings.value( QStringLiteral( "UI/lastAuthOpenFileDir" ), QDir::homePath() ).toString();
347 QString f = QFileDialog::getOpenFileName( parent, title, recentdir, extfilter );
348 if ( !f.isEmpty() )
349 {
350 settings.setValue( QStringLiteral( "UI/lastAuthOpenFileDir" ), QFileInfo( f ).absoluteDir().path() );
351 }
352 return f;
353}
354
356{
357 if ( QMessageBox::warning( parent, QObject::tr( "Delete Password" ), QObject::tr( "Do you really want to delete the master password from the %1?" ).arg( QgsAuthManager::passwordHelperDisplayName() ), QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel ) == QMessageBox::Cancel )
358 {
359 return;
360 }
361 QString msg;
362 Qgis::MessageLevel level;
364 {
367 }
368 else
369 {
370 msg = QObject::tr( "Master password was successfully deleted from the %1" )
372
374 }
375 msgbar->clearWidgets();
376 msgbar->pushMessage( QObject::tr( "Password helper delete" ), msg, level );
377}
378
380{
382 const QString msg = enabled ? QObject::tr( "Your %1 will be <b>used from now</b> on to store and retrieve the master password." )
384 : QObject::tr( "Your %1 will <b>not be used anymore</b> to store and retrieve the master password." )
386 msgbar->clearWidgets();
387 msgbar->pushMessage( QObject::tr( "Password helper write" ), msg, Qgis::MessageLevel::Info );
388}
389
390void QgsAuthGuiUtils::passwordHelperLoggingEnable( bool enabled, QgsMessageBar *msgbar, int timeout )
391{
392 Q_UNUSED( msgbar )
393 Q_UNUSED( timeout )
395}
396
397void QgsAuthGuiUtils::setItemBold( QTreeWidgetItem *item )
398{
399 item->setFirstColumnSpanned( true );
400 QFont secf( item->font( 0 ) );
401 secf.setBold( true );
402 item->setFont( 0, secf );
403}
404
405void QgsAuthGuiUtils::removeChildren( QTreeWidgetItem *item )
406{
407 const auto constTakeChildren = item->takeChildren();
408 for ( QTreeWidgetItem *child : constTakeChildren )
409 {
410 delete child;
411 }
412}
MessageLevel
Level for messages This will be used both for message log and message bar in application.
Definition qgis.h:154
@ Warning
Warning message.
Definition qgis.h:156
@ Critical
Critical/error message.
Definition qgis.h:157
@ Info
Information message.
Definition qgis.h:155
static QgsAuthManager * authManager()
Returns the application's authentication manager instance.
static void importAuthenticationConfigs(QgsMessageBar *msgbar)
Import authentication configurations from a XML file.
static void exportSelectedAuthenticationConfigs(QStringList authenticationConfigIds, QgsMessageBar *msgbar)
Exports selected authentication configurations to a XML file.
static QString greenTextStyleSheet(const QString &selector="*")
Green text stylesheet representing valid, trusted, etc. certificate.
static void resetMasterPassword(QgsMessageBar *msgbar, QWidget *parent=nullptr)
Reset the cached master password, updating its hash in authentication database and resetting all exis...
static QColor greenColor()
Green color representing valid, trusted, etc. certificate.
static QColor orangeColor()
Orange color representing loaded component, but not stored in database.
static QString redTextStyleSheet(const QString &selector="*")
Red text stylesheet representing invalid, untrusted, etc. certificate.
static void clearCachedMasterPassword(QgsMessageBar *msgbar)
Clear the currently cached master password (not its hash in database)
static void passwordHelperEnable(bool enabled, QgsMessageBar *msgbar)
Sets password helper enabled (enable/disable)
static QString orangeTextStyleSheet(const QString &selector="*")
Orange text stylesheet representing loaded component, but not stored in database.
static void setItemBold(QTreeWidgetItem *item)
Call setFirstColumnSpanned(true) on the item and make its font bold.
static void removeChildren(QTreeWidgetItem *item)
Remove the children of the passed item.
static void clearCachedAuthenticationConfigs(QgsMessageBar *msgbar)
Clear all cached authentication configs for session.
static bool isDisabled(QgsMessageBar *msgbar)
Verify the authentication system is active, else notify user.
static void passwordHelperLoggingEnable(bool enabled, QgsMessageBar *msgbar, int timeout=0)
Sets password helper logging enabled (enable/disable)
static void eraseAuthenticationDatabase(QgsMessageBar *msgbar, QWidget *parent=nullptr)
Completely clear out the authentication database (configs and master password)
static void removeAuthenticationConfigs(QgsMessageBar *msgbar, QWidget *parent=nullptr)
Remove all authentication configs.
static QColor yellowColor()
Yellow color representing caution regarding action.
static void fileFound(bool found, QWidget *widget)
Color a widget via a stylesheet if a file path is found or not.
static void setMasterPassword(QgsMessageBar *msgbar)
Sets the cached master password (and verifies it if its hash is in authentication database)
static QString getOpenFileName(QWidget *parent, const QString &title, const QString &extfilter)
Open file dialog for auth associated widgets.
static void passwordHelperDelete(QgsMessageBar *msgbar, QWidget *parent=nullptr)
Remove master password from wallet.
static QColor redColor()
Red color representing invalid, untrusted, etc. certificate.
void clearAllCachedConfigs()
Clear all authentication configs from authentication method caches.
bool exportAuthenticationConfigsToXml(const QString &filename, const QStringList &authcfgs, const QString &password=QString())
Export authentication configurations to an XML file.
void setPasswordHelperEnabled(bool enabled)
Password helper enabled setter.
void setScheduledAuthDatabaseErase(bool scheduleErase)
Schedule an optional erase of authentication database, starting when mutex is lockable.
bool importAuthenticationConfigsFromXml(const QString &filename, const QString &password=QString(), bool overwrite=false)
Import authentication configurations from an XML file.
void clearMasterPassword()
Clear supplied master password.
const QString passwordHelperErrorMessage()
Error message getter.
static void setPasswordHelperLoggingEnabled(bool enabled)
Password helper logging enabled setter.
static const QgsSettingsEntryBool * settingsUsingGeneratedRandomPassword
bool setMasterPassword(bool verify=false)
Main call to initially set or continually check master password is set.
static QString passwordHelperDisplayName(bool titleCase=false)
Returns a translated display name of the password helper (platform dependent).
Dialog to verify current master password and initiate reset of authentication database with a new pas...
bool requestMasterPasswordReset(QString *newpass, QString *oldpass, bool *keepbackup)
QgsPasswordLineEdit * oldPasswordLineEdit()
Returns the old password line edit widget.
A bar for displaying non-blocking messages to the user.
void pushMessage(const QString &text, Qgis::MessageLevel level=Qgis::MessageLevel::Info, int duration=-1)
A convenience method for pushing a message with the specified text to the bar.
bool clearWidgets()
Removes all items from the bar.
This class is a composition of two QSettings instances:
Definition qgssettings.h:64
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
#define QgsDebugMsgLevel(str, level)
Definition qgslogger.h:41