QGIS API Documentation 4.1.0-Master (5bf3c20f3c9)
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 "qgsapplication.h"
20#include "qgsauthmanager.h"
22#include "qgslogger.h"
23#include "qgsmessagebar.h"
24#include "qgssettings.h"
25
26#include <QFileDialog>
27#include <QInputDialog>
28#include <QLineEdit>
29#include <QMessageBox>
30#include <QString>
31#include <QTreeWidgetItem>
32
33using namespace Qt::StringLiterals;
34
36{
37 return QColor( 0, 170, 0 );
38}
39
41{
42 return QColor( 255, 128, 0 );
43}
44
46{
47 return QColor( 200, 0, 0 );
48}
49
51{
52 return QColor( 255, 255, 125 );
53}
54
55QString QgsAuthGuiUtils::greenTextStyleSheet( const QString &selector )
56{
57 return u"%1{color: %2;}"_s.arg( selector, QgsAuthGuiUtils::greenColor().name() );
58}
59
60QString QgsAuthGuiUtils::orangeTextStyleSheet( const QString &selector )
61{
62 return u"%1{color: %2;}"_s.arg( selector, QgsAuthGuiUtils::orangeColor().name() );
63}
64
65QString QgsAuthGuiUtils::redTextStyleSheet( const QString &selector )
66{
67 return u"%1{color: %2;}"_s.arg( selector, QgsAuthGuiUtils::redColor().name() );
68}
69
71{
73 {
74 msgbar->clearWidgets();
75 msgbar->pushMessage( QObject::tr( "Authentication System" ), QObject::tr( "DISABLED. Resources authenticating via the system can not be accessed" ), Qgis::MessageLevel::Critical );
76 return true;
77 }
78 return false;
79}
80
81void QgsAuthGuiUtils::exportSelectedAuthenticationConfigs( QStringList authenticationConfigIds, QgsMessageBar *msgbar )
82{
83 const QString password = QInputDialog::getText( msgbar, QObject::tr( "Export Authentication Configurations" ), QObject::tr( "Enter a password to encrypt the configuration file:" ), QLineEdit::Password );
84 if ( password.isEmpty() )
85 {
86 if ( QMessageBox::warning(
87 msgbar,
88 QObject::tr( "Export Authentication Configurations" ),
89 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?" ),
90 QMessageBox::Ok | QMessageBox::Cancel,
91 QMessageBox::Cancel
92 )
93 == QMessageBox::Cancel )
94 {
95 return;
96 }
97 }
98
99 const QString filename = QFileDialog::getSaveFileName( msgbar, QObject::tr( "Export Authentication Configurations" ), QDir::homePath(), QObject::tr( "XML files (*.xml *.XML)" ) );
100 if ( filename.isEmpty() )
101 return;
102
103 const bool ok = QgsApplication::authManager()->exportAuthenticationConfigsToXml( filename, authenticationConfigIds, password );
104 if ( !ok )
105 {
106 msgbar->clearWidgets();
107 msgbar->pushMessage( QgsApplication::authManager()->authManTag(), QObject::tr( "Export of authentication configurations failed." ), Qgis::MessageLevel::Critical );
108 }
109}
110
112{
113 const QString filename = QFileDialog::getOpenFileName( msgbar, QObject::tr( "Import Authentication Configurations" ), QDir::homePath(), QObject::tr( "XML files (*.xml *.XML)" ) );
114 if ( filename.isEmpty() )
115 return;
116
117
118 QFile file( filename );
119 if ( !file.open( QFile::ReadOnly ) )
120 {
121 return;
122 }
123
124 QDomDocument document( u"qgis_authentication"_s );
125 if ( !document.setContent( &file ) )
126 {
127 file.close();
128 return;
129 }
130 file.close();
131
132 const QDomElement root = document.documentElement();
133 if ( root.tagName() != "qgis_authentication"_L1 )
134 {
135 return;
136 }
137
138 QString password;
139 if ( root.hasAttribute( u"salt"_s ) )
140 {
141 password = QInputDialog::getText( msgbar, QObject::tr( "Import Authentication Configurations" ), QObject::tr( "Enter the password to decrypt the configurations file:" ), QLineEdit::Password );
142 }
143
144 const bool ok = QgsApplication::authManager()->importAuthenticationConfigsFromXml( filename, password );
145 if ( !ok )
146 {
147 msgbar->clearWidgets();
148 msgbar->pushMessage( QgsApplication::authManager()->authManTag(), QObject::tr( "Import of authentication configurations failed." ), Qgis::MessageLevel::Critical );
149 }
150}
151
153{
154 if ( QgsAuthGuiUtils::isDisabled( msgbar ) )
155 return;
156
157 if ( QgsApplication::authManager()->masterPasswordIsSet() )
158 {
159 msgbar->clearWidgets();
160 msgbar->pushMessage( QgsApplication::authManager()->authManTag(), QObject::tr( "Master password already set." ), Qgis::MessageLevel::Info );
161 return;
162 }
163 ( void ) QgsApplication::authManager()->setMasterPassword( true );
164}
165
167{
168 if ( QgsAuthGuiUtils::isDisabled( msgbar ) )
169 return;
170
171 QString msg( QObject::tr( "Master password not cleared because it is not set." ) );
173
174 if ( QgsApplication::authManager()->masterPasswordIsSet() )
175 {
177 msg = QObject::tr( "Master password cleared (NOTE: network connections may be cached)." );
178 if ( QgsApplication::authManager()->masterPasswordIsSet() )
179 {
180 msg = QObject::tr( "Master password FAILED to be cleared." );
182 }
183 }
184
185 msgbar->clearWidgets();
186 msgbar->pushMessage( QgsApplication::authManager()->authManTag(), msg, level );
187}
188
190{
191 if ( QgsAuthGuiUtils::isDisabled( msgbar ) )
192 return;
193
194 QString msg( QObject::tr( "Master password reset" ) );
196
197 // check that a master password is even set in auth db
198 if ( !QgsApplication::authManager()->masterPasswordHashInDatabase() )
199 {
200 msg = QObject::tr( "Master password reset: NO current password hash in database" );
201 msgbar->clearWidgets();
203 return;
204 }
205
206 // get new password via dialog; do current password verification in-dialog
207 QString newpass;
208 QString oldpass;
209
210 bool keepbackup = false;
211 QgsMasterPasswordResetDialog dlg( parent );
212
213 QString backuppath;
214 // if password helper enabled and user is using the default random generated password, then
215 // just fill this in automatically (the user will have NO idea what this is!)
216 if ( QgsApplication::authManager()->verifyStoredPasswordHelperPassword()
217 && ( QgsApplication::authManager()->masterPasswordIsSet() || QgsApplication::authManager()->setMasterPassword( true ) )
219 {
220 dlg.oldPasswordLineEdit()->setText( u"***************"_s );
221 dlg.oldPasswordLineEdit()->setEnabled( false );
222 dlg.oldPasswordLineEdit()->setToolTip( QObject::tr( "Existing password has been automatically read from the %1" ).arg( QgsAuthManager::passwordHelperDisplayName() ) );
223 if ( !dlg.requestMasterPasswordReset( &newpass, &oldpass, &keepbackup ) )
224 {
225 QgsDebugMsgLevel( u"Master password reset: input canceled by user"_s, 2 );
226 return;
227 }
228 if ( !QgsApplication::authManager()->resetMasterPasswordUsingStoredPasswordHelper( newpass, keepbackup, &backuppath ) )
229 {
230 msg = QObject::tr( "Master password FAILED to be reset" );
232 }
233 }
234 else
235 {
236 if ( !dlg.requestMasterPasswordReset( &newpass, &oldpass, &keepbackup ) )
237 {
238 QgsDebugMsgLevel( u"Master password reset: input canceled by user"_s, 2 );
239 return;
240 }
241 if ( !QgsApplication::authManager()->resetMasterPassword( newpass, oldpass, keepbackup, &backuppath ) )
242 {
243 msg = QObject::tr( "Master password FAILED to be reset" );
245 }
246 }
247
248 if ( !backuppath.isEmpty() )
249 {
250 msg += QObject::tr( " (database backup: %1)" ).arg( backuppath );
251 }
252
253 msgbar->clearWidgets();
254 msgbar->pushMessage( QgsApplication::authManager()->authManTag(), msg, level );
255}
256
258{
259 if ( QgsAuthGuiUtils::isDisabled( msgbar ) )
260 return;
261
263 const QString msg = QObject::tr( "Cached authentication configurations for session cleared" );
264 msgbar->clearWidgets();
266}
267
269{
270 if ( QgsAuthGuiUtils::isDisabled( msgbar ) )
271 return;
272
273 if ( QMessageBox::warning(
274 parent,
275 QObject::tr( "Remove Configurations" ),
276 QObject::tr(
277 "Are you sure you want to remove ALL authentication configurations?\n\n"
278 "Operation can NOT be undone!"
279 ),
280 QMessageBox::Ok | QMessageBox::Cancel,
281 QMessageBox::Cancel
282 )
283 == QMessageBox::Cancel )
284 {
285 return;
286 }
287
288 QString msg( QObject::tr( "Authentication configurations removed." ) );
290
291 if ( !QgsApplication::authManager()->removeAllAuthenticationConfigs() )
292 {
293 msg = QObject::tr( "Authentication configurations FAILED to be removed." );
295 }
296
297 msgbar->clearWidgets();
298 msgbar->pushMessage( QgsApplication::authManager()->authManTag(), msg, level );
299}
300
302{
303 if ( QgsAuthGuiUtils::isDisabled( msgbar ) )
304 return;
305
306 const QMessageBox::StandardButton btn = QMessageBox::warning(
307 parent,
308 QObject::tr( "Erase Database" ),
309 QObject::tr(
310 "Are you sure you want to ERASE the entire authentication database?\n\n"
311 "Operation can NOT be undone!\n\n"
312 "(Current database will be backed up and new one created.)"
313 ),
314 QMessageBox::Ok | QMessageBox::Cancel,
315 QMessageBox::Cancel
316 );
317
319
320 if ( btn == QMessageBox::Cancel )
321 {
322 return;
323 }
324
325 QString msg( QObject::tr( "Active authentication database erased." ) );
327
328 QString backuppath;
329 if ( !QgsApplication::authManager()->eraseAuthenticationDatabase( true, &backuppath ) )
330 {
331 msg = QObject::tr( "Authentication database FAILED to be erased." );
333 }
334 else
335 {
336 if ( !backuppath.isEmpty() )
337 {
338 msg += QObject::tr( " (backup: %1)" ).arg( backuppath );
339 }
341 }
342
343 msgbar->clearWidgets();
344 msgbar->pushMessage( QObject::tr( "RESTART QGIS" ), msg, level );
345}
346
347void QgsAuthGuiUtils::fileFound( bool found, QWidget *widget )
348{
349 if ( !found )
350 {
351 widget->setStyleSheet( QgsAuthGuiUtils::redTextStyleSheet( u"QLineEdit"_s ) );
352 widget->setToolTip( QObject::tr( "File not found" ) );
353 }
354 else
355 {
356 widget->setStyleSheet( QString() );
357 widget->setToolTip( QString() );
358 }
359}
360
361QString QgsAuthGuiUtils::getOpenFileName( QWidget *parent, const QString &title, const QString &extfilter )
362{
363 QgsSettings settings;
364 const QString recentdir = settings.value( u"UI/lastAuthOpenFileDir"_s, QDir::homePath() ).toString();
365 QString f = QFileDialog::getOpenFileName( parent, title, recentdir, extfilter );
366 if ( !f.isEmpty() )
367 {
368 settings.setValue( u"UI/lastAuthOpenFileDir"_s, QFileInfo( f ).absoluteDir().path() );
369 }
370 return f;
371}
372
374{
375 if ( QMessageBox::
376 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 )
377 == QMessageBox::Cancel )
378 {
379 return;
380 }
381 QString msg;
382 Qgis::MessageLevel level;
384 {
387 }
388 else
389 {
390 msg = QObject::tr( "Master password was successfully deleted from the %1" ).arg( QgsAuthManager::passwordHelperDisplayName() );
391
393 }
394 msgbar->clearWidgets();
395 msgbar->pushMessage( QObject::tr( "Password helper delete" ), msg, level );
396}
397
399{
401 const QString msg = enabled ? QObject::tr( "Your %1 will be <b>used from now</b> on to store and retrieve the master password." ).arg( QgsAuthManager::passwordHelperDisplayName() )
402 : QObject::tr( "Your %1 will <b>not be used anymore</b> to store and retrieve the master password." ).arg( QgsAuthManager::passwordHelperDisplayName() );
403 msgbar->clearWidgets();
404 msgbar->pushMessage( QObject::tr( "Password helper write" ), msg, Qgis::MessageLevel::Info );
405}
406
407void QgsAuthGuiUtils::passwordHelperLoggingEnable( bool enabled, QgsMessageBar *msgbar, int timeout )
408{
409 Q_UNUSED( msgbar )
410 Q_UNUSED( timeout )
412}
413
414void QgsAuthGuiUtils::setItemBold( QTreeWidgetItem *item )
415{
416 item->setFirstColumnSpanned( true );
417 QFont secf( item->font( 0 ) );
418 secf.setBold( true );
419 item->setFont( 0, secf );
420}
421
422void QgsAuthGuiUtils::removeChildren( QTreeWidgetItem *item )
423{
424 const auto constTakeChildren = item->takeChildren();
425 for ( QTreeWidgetItem *child : constTakeChildren )
426 {
427 delete child;
428 }
429}
MessageLevel
Level for messages This will be used both for message log and message bar in application.
Definition qgis.h:160
@ Warning
Warning message.
Definition qgis.h:162
@ Critical
Critical/error message.
Definition qgis.h:163
@ Info
Information message.
Definition qgis.h:161
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
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.
Stores settings for use within QGIS.
Definition qgssettings.h:68
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:63