QGIS API Documentation 3.99.0-Master (e9821da5c6b)
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( 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 )
87 {
88 return;
89 }
90 }
91
92 const QString filename = QFileDialog::getSaveFileName( msgbar, QObject::tr( "Export Authentication Configurations" ), QDir::homePath(), QObject::tr( "XML files (*.xml *.XML)" ) );
93 if ( filename.isEmpty() )
94 return;
95
96 const bool ok = QgsApplication::authManager()->exportAuthenticationConfigsToXml( filename, authenticationConfigIds, password );
97 if ( !ok )
98 {
99 msgbar->clearWidgets();
100 msgbar->pushMessage( QgsApplication::authManager()->authManTag(), QObject::tr( "Export of authentication configurations failed." ), Qgis::MessageLevel::Critical );
101 }
102}
103
105{
106 const QString filename = QFileDialog::getOpenFileName( msgbar, QObject::tr( "Import Authentication Configurations" ), QDir::homePath(), QObject::tr( "XML files (*.xml *.XML)" ) );
107 if ( filename.isEmpty() )
108 return;
109
110
111 QFile file( filename );
112 if ( !file.open( QFile::ReadOnly ) )
113 {
114 return;
115 }
116
117 QDomDocument document( u"qgis_authentication"_s );
118 if ( !document.setContent( &file ) )
119 {
120 file.close();
121 return;
122 }
123 file.close();
124
125 const QDomElement root = document.documentElement();
126 if ( root.tagName() != "qgis_authentication"_L1 )
127 {
128 return;
129 }
130
131 QString password;
132 if ( root.hasAttribute( u"salt"_s ) )
133 {
134 password = QInputDialog::getText( msgbar, QObject::tr( "Import Authentication Configurations" ), QObject::tr( "Enter the password to decrypt the configurations file:" ), QLineEdit::Password );
135 }
136
137 const bool ok = QgsApplication::authManager()->importAuthenticationConfigsFromXml( filename, password );
138 if ( !ok )
139 {
140 msgbar->clearWidgets();
141 msgbar->pushMessage( QgsApplication::authManager()->authManTag(), QObject::tr( "Import of authentication configurations failed." ), Qgis::MessageLevel::Critical );
142 }
143}
144
146{
147 if ( QgsAuthGuiUtils::isDisabled( msgbar ) )
148 return;
149
150 if ( QgsApplication::authManager()->masterPasswordIsSet() )
151 {
152 msgbar->clearWidgets();
153 msgbar->pushMessage( QgsApplication::authManager()->authManTag(), QObject::tr( "Master password already set." ), Qgis::MessageLevel::Info );
154 return;
155 }
156 ( void ) QgsApplication::authManager()->setMasterPassword( true );
157}
158
160{
161 if ( QgsAuthGuiUtils::isDisabled( msgbar ) )
162 return;
163
164 QString msg( QObject::tr( "Master password not cleared because it is not set." ) );
166
167 if ( QgsApplication::authManager()->masterPasswordIsSet() )
168 {
170 msg = QObject::tr( "Master password cleared (NOTE: network connections may be cached)." );
171 if ( QgsApplication::authManager()->masterPasswordIsSet() )
172 {
173 msg = QObject::tr( "Master password FAILED to be cleared." );
175 }
176 }
177
178 msgbar->clearWidgets();
179 msgbar->pushMessage( QgsApplication::authManager()->authManTag(), msg, level );
180}
181
183{
184 if ( QgsAuthGuiUtils::isDisabled( msgbar ) )
185 return;
186
187 QString msg( QObject::tr( "Master password reset" ) );
189
190 // check that a master password is even set in auth db
191 if ( !QgsApplication::authManager()->masterPasswordHashInDatabase() )
192 {
193 msg = QObject::tr( "Master password reset: NO current password hash in database" );
194 msgbar->clearWidgets();
196 return;
197 }
198
199 // get new password via dialog; do current password verification in-dialog
200 QString newpass;
201 QString oldpass;
202
203 bool keepbackup = false;
204 QgsMasterPasswordResetDialog dlg( parent );
205
206 QString backuppath;
207 // if password helper enabled and user is using the default random generated password, then
208 // just fill this in automatically (the user will have NO idea what this is!)
209 if ( QgsApplication::authManager()->verifyStoredPasswordHelperPassword()
210 && ( QgsApplication::authManager()->masterPasswordIsSet() || QgsApplication::authManager()->setMasterPassword( true ) )
212 {
213 dlg.oldPasswordLineEdit()->setText( u"***************"_s );
214 dlg.oldPasswordLineEdit()->setEnabled( false );
215 dlg.oldPasswordLineEdit()->setToolTip( QObject::tr( "Existing password has been automatically read from the %1" ).arg( QgsAuthManager::passwordHelperDisplayName() ) );
216 if ( !dlg.requestMasterPasswordReset( &newpass, &oldpass, &keepbackup ) )
217 {
218 QgsDebugMsgLevel( u"Master password reset: input canceled by user"_s, 2 );
219 return;
220 }
221 if ( !QgsApplication::authManager()->resetMasterPasswordUsingStoredPasswordHelper( newpass, keepbackup, &backuppath ) )
222 {
223 msg = QObject::tr( "Master password FAILED to be reset" );
225 }
226 }
227 else
228 {
229 if ( !dlg.requestMasterPasswordReset( &newpass, &oldpass, &keepbackup ) )
230 {
231 QgsDebugMsgLevel( u"Master password reset: input canceled by user"_s, 2 );
232 return;
233 }
234 if ( !QgsApplication::authManager()->resetMasterPassword( newpass, oldpass, keepbackup, &backuppath ) )
235 {
236 msg = QObject::tr( "Master password FAILED to be reset" );
238 }
239 }
240
241 if ( !backuppath.isEmpty() )
242 {
243 msg += QObject::tr( " (database backup: %1)" ).arg( backuppath );
244 }
245
246 msgbar->clearWidgets();
247 msgbar->pushMessage( QgsApplication::authManager()->authManTag(), msg, level );
248}
249
251{
252 if ( QgsAuthGuiUtils::isDisabled( msgbar ) )
253 return;
254
256 const QString msg = QObject::tr( "Cached authentication configurations for session cleared" );
257 msgbar->clearWidgets();
259}
260
262{
263 if ( QgsAuthGuiUtils::isDisabled( msgbar ) )
264 return;
265
266 if ( QMessageBox::warning( parent, QObject::tr( "Remove Configurations" ), QObject::tr( "Are you sure you want to remove ALL authentication configurations?\n\n"
267 "Operation can NOT be undone!" ),
268 QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel )
269 == QMessageBox::Cancel )
270 {
271 return;
272 }
273
274 QString msg( QObject::tr( "Authentication configurations removed." ) );
276
277 if ( !QgsApplication::authManager()->removeAllAuthenticationConfigs() )
278 {
279 msg = QObject::tr( "Authentication configurations FAILED to be removed." );
281 }
282
283 msgbar->clearWidgets();
284 msgbar->pushMessage( QgsApplication::authManager()->authManTag(), msg, level );
285}
286
288{
289 if ( QgsAuthGuiUtils::isDisabled( msgbar ) )
290 return;
291
292 const QMessageBox::StandardButton btn = QMessageBox::warning(
293 parent,
294 QObject::tr( "Erase Database" ),
295 QObject::tr( "Are you sure you want to ERASE the entire authentication database?\n\n"
296 "Operation can NOT be undone!\n\n"
297 "(Current database will be backed up and new one created.)" ),
298 QMessageBox::Ok | QMessageBox::Cancel,
299 QMessageBox::Cancel
300 );
301
303
304 if ( btn == QMessageBox::Cancel )
305 {
306 return;
307 }
308
309 QString msg( QObject::tr( "Active authentication database erased." ) );
311
312 QString backuppath;
313 if ( !QgsApplication::authManager()->eraseAuthenticationDatabase( true, &backuppath ) )
314 {
315 msg = QObject::tr( "Authentication database FAILED to be erased." );
317 }
318 else
319 {
320 if ( !backuppath.isEmpty() )
321 {
322 msg += QObject::tr( " (backup: %1)" ).arg( backuppath );
323 }
325 }
326
327 msgbar->clearWidgets();
328 msgbar->pushMessage( QObject::tr( "RESTART QGIS" ), msg, level );
329}
330
331void QgsAuthGuiUtils::fileFound( bool found, QWidget *widget )
332{
333 if ( !found )
334 {
335 widget->setStyleSheet( QgsAuthGuiUtils::redTextStyleSheet( u"QLineEdit"_s ) );
336 widget->setToolTip( QObject::tr( "File not found" ) );
337 }
338 else
339 {
340 widget->setStyleSheet( QString() );
341 widget->setToolTip( QString() );
342 }
343}
344
345QString QgsAuthGuiUtils::getOpenFileName( QWidget *parent, const QString &title, const QString &extfilter )
346{
347 QgsSettings settings;
348 const QString recentdir = settings.value( u"UI/lastAuthOpenFileDir"_s, QDir::homePath() ).toString();
349 QString f = QFileDialog::getOpenFileName( parent, title, recentdir, extfilter );
350 if ( !f.isEmpty() )
351 {
352 settings.setValue( u"UI/lastAuthOpenFileDir"_s, QFileInfo( f ).absoluteDir().path() );
353 }
354 return f;
355}
356
358{
359 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 )
360 {
361 return;
362 }
363 QString msg;
364 Qgis::MessageLevel level;
366 {
369 }
370 else
371 {
372 msg = QObject::tr( "Master password was successfully deleted from the %1" )
374
376 }
377 msgbar->clearWidgets();
378 msgbar->pushMessage( QObject::tr( "Password helper delete" ), msg, level );
379}
380
382{
384 const QString msg = enabled ? QObject::tr( "Your %1 will be <b>used from now</b> on to store and retrieve the master password." )
386 : QObject::tr( "Your %1 will <b>not be used anymore</b> to store and retrieve the master password." )
388 msgbar->clearWidgets();
389 msgbar->pushMessage( QObject::tr( "Password helper write" ), msg, Qgis::MessageLevel::Info );
390}
391
392void QgsAuthGuiUtils::passwordHelperLoggingEnable( bool enabled, QgsMessageBar *msgbar, int timeout )
393{
394 Q_UNUSED( msgbar )
395 Q_UNUSED( timeout )
397}
398
399void QgsAuthGuiUtils::setItemBold( QTreeWidgetItem *item )
400{
401 item->setFirstColumnSpanned( true );
402 QFont secf( item->font( 0 ) );
403 secf.setBold( true );
404 item->setFont( 0, secf );
405}
406
407void QgsAuthGuiUtils::removeChildren( QTreeWidgetItem *item )
408{
409 const auto constTakeChildren = item->takeChildren();
410 for ( QTreeWidgetItem *child : constTakeChildren )
411 {
412 delete child;
413 }
414}
MessageLevel
Level for messages This will be used both for message log and message bar in application.
Definition qgis.h:159
@ Warning
Warning message.
Definition qgis.h:161
@ Critical
Critical/error message.
Definition qgis.h:162
@ Info
Information message.
Definition qgis.h:160
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