QGIS API Documentation 3.30.0-'s-Hertogenbosch (f186b8efe0)
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
24#include "qgssettings.h"
25#include "qgsauthmanager.h"
27#include "qgslogger.h"
28#include "qgsmessagebar.h"
29#include "qgsapplication.h"
30
31
33{
34 return QColor( 0, 170, 0 );
35}
36
38{
39 return QColor( 255, 128, 0 );
40}
41
43{
44 return QColor( 200, 0, 0 );
45}
46
48{
49 return QColor( 255, 255, 125 );
50}
51
52QString QgsAuthGuiUtils::greenTextStyleSheet( const QString &selector )
53{
54 return QStringLiteral( "%1{color: %2;}" ).arg( selector, QgsAuthGuiUtils::greenColor().name() );
55}
56
57QString QgsAuthGuiUtils::orangeTextStyleSheet( const QString &selector )
58{
59 return QStringLiteral( "%1{color: %2;}" ).arg( selector, QgsAuthGuiUtils::orangeColor().name() );
60}
61
62QString QgsAuthGuiUtils::redTextStyleSheet( const QString &selector )
63{
64 return QStringLiteral( "%1{color: %2;}" ).arg( selector, QgsAuthGuiUtils::redColor().name() );
65}
66
68{
70 {
71 msgbar->pushMessage( QObject::tr( "Authentication System" ),
72 QObject::tr( "DISABLED. Resources authenticating via the system can not be accessed" ),
73 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" ),
82 QObject::tr( "Enter a password encrypt the configuration file:" ), QLineEdit::Password );
83 if ( password.isEmpty() )
84 {
85 if ( QMessageBox::warning( msgbar,
86 QObject::tr( "Export Authentication Configurations" ),
87 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?" ),
88 QMessageBox::Ok | QMessageBox::Cancel,
89 QMessageBox::Cancel ) == QMessageBox::Cancel )
90 {
91 return;
92 }
93 }
94
95 const QString filename = QFileDialog::getSaveFileName( msgbar, QObject::tr( "Export Authentication Configurations" ), QDir::homePath(),
96 QObject::tr( "XML files (*.xml *.XML)" ) );
97 if ( filename.isEmpty() )
98 return;
99
100 const bool ok = QgsApplication::authManager()->exportAuthenticationConfigsToXml( filename, authenticationConfigIds, password );
101 if ( !ok )
102 {
103 msgbar->pushMessage( QgsApplication::authManager()->authManTag(),
104 QObject::tr( "Export of authentication configurations failed." ),
105 Qgis::MessageLevel::Critical );
106 }
107}
108
110{
111
112 const QString filename = QFileDialog::getOpenFileName( msgbar, QObject::tr( "Export Authentication Configurations" ), QDir::homePath(),
113 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( QStringLiteral( "qgis_authentication" ) );
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() != QLatin1String( "qgis_authentication" ) )
134 {
135 return;
136 }
137
138 QString password;
139 if ( root.hasAttribute( QStringLiteral( "salt" ) ) )
140 {
141 password = QInputDialog::getText( msgbar, QObject::tr( "Import Authentication Configurations" ),
142 QObject::tr( "Enter the password to decrypt the configurations file:" ), QLineEdit::Password );
143 }
144
145 const bool ok = QgsApplication::authManager()->importAuthenticationConfigsFromXml( filename, password );
146 if ( !ok )
147 {
148 msgbar->pushMessage( QgsApplication::authManager()->authManTag(),
149 QObject::tr( "Import of authentication configurations failed." ),
150 Qgis::MessageLevel::Critical );
151 }
152}
153
155{
156 if ( QgsAuthGuiUtils::isDisabled( msgbar ) )
157 return;
158
159 if ( QgsApplication::authManager()->masterPasswordIsSet() )
160 {
161 msgbar->pushMessage( QgsApplication::authManager()->authManTag(),
162 QObject::tr( "Master password already set." ),
163 Qgis::MessageLevel::Info );
164 return;
165 }
167}
168
170{
171 if ( QgsAuthGuiUtils::isDisabled( msgbar ) )
172 return;
173
174 QString msg( QObject::tr( "Master password not cleared because it is not set." ) );
175 Qgis::MessageLevel level( Qgis::MessageLevel::Info );
176
177 if ( QgsApplication::authManager()->masterPasswordIsSet() )
178 {
180 msg = QObject::tr( "Master password cleared (NOTE: network connections may be cached)." );
181 if ( QgsApplication::authManager()->masterPasswordIsSet() )
182 {
183 msg = QObject::tr( "Master password FAILED to be cleared." );
184 level = Qgis::MessageLevel::Warning;
185 }
186 }
187
188 msgbar->pushMessage( QgsApplication::authManager()->authManTag(), msg, level );
189}
190
192{
193 if ( QgsAuthGuiUtils::isDisabled( msgbar ) )
194 return;
195
196 QString msg( QObject::tr( "Master password reset" ) );
197 Qgis::MessageLevel level( Qgis::MessageLevel::Info );
198
199 // check that a master password is even set in auth db
200 if ( !QgsApplication::authManager()->masterPasswordHashInDatabase() )
201 {
202 msg = QObject::tr( "Master password reset: NO current password hash in database" );
203 msgbar->pushMessage( QgsApplication::authManager()->authManTag(), msg, Qgis::MessageLevel::Warning );
204 return;
205 }
206
207 // get new password via dialog; do current password verification in-dialog
208 QString newpass;
209 QString oldpass;
210 bool keepbackup = false;
211 QgsMasterPasswordResetDialog dlg( parent );
212
213 if ( !dlg.requestMasterPasswordReset( &newpass, &oldpass, &keepbackup ) )
214 {
215 QgsDebugMsg( QStringLiteral( "Master password reset: input canceled by user" ) );
216 return;
217 }
218
219 QString backuppath;
220 if ( !QgsApplication::authManager()->resetMasterPassword( newpass, oldpass, keepbackup, &backuppath ) )
221 {
222 msg = QObject::tr( "Master password FAILED to be reset" );
223 level = Qgis::MessageLevel::Warning;
224 }
225
226 if ( !backuppath.isEmpty() )
227 {
228 msg += QObject::tr( " (database backup: %1)" ).arg( backuppath );
229 }
230
231 msgbar->pushMessage( QgsApplication::authManager()->authManTag(), msg, level );
232}
233
235{
236 if ( QgsAuthGuiUtils::isDisabled( msgbar ) )
237 return;
238
240 const QString msg = QObject::tr( "Cached authentication configurations for session cleared" );
241 msgbar->pushMessage( QgsApplication::authManager()->authManTag(), msg, Qgis::MessageLevel::Info );
242}
243
245{
246 if ( QgsAuthGuiUtils::isDisabled( msgbar ) )
247 return;
248
249 if ( QMessageBox::warning( parent,
250 QObject::tr( "Remove Configurations" ),
251 QObject::tr( "Are you sure you want to remove ALL authentication configurations?\n\n"
252 "Operation can NOT be undone!" ),
253 QMessageBox::Ok | QMessageBox::Cancel,
254 QMessageBox::Cancel ) == QMessageBox::Cancel )
255 {
256 return;
257 }
258
259 QString msg( QObject::tr( "Authentication configurations removed." ) );
260 Qgis::MessageLevel level( Qgis::MessageLevel::Info );
261
262 if ( !QgsApplication::authManager()->removeAllAuthenticationConfigs() )
263 {
264 msg = QObject::tr( "Authentication configurations FAILED to be removed." );
265 level = Qgis::MessageLevel::Warning;
266 }
267
268 msgbar->pushMessage( QgsApplication::authManager()->authManTag(), msg, level );
269}
270
272{
273 if ( QgsAuthGuiUtils::isDisabled( msgbar ) )
274 return;
275
276 const QMessageBox::StandardButton btn = QMessageBox::warning(
277 parent,
278 QObject::tr( "Erase Database" ),
279 QObject::tr( "Are you sure you want to ERASE the entire authentication database?\n\n"
280 "Operation can NOT be undone!\n\n"
281 "(Current database will be backed up and new one created.)" ),
282 QMessageBox::Ok | QMessageBox::Cancel,
283 QMessageBox::Cancel );
284
286
287 if ( btn == QMessageBox::Cancel )
288 {
289 return;
290 }
291
292 QString msg( QObject::tr( "Active authentication database erased." ) );
293 Qgis::MessageLevel level( Qgis::MessageLevel::Warning );
294
295 QString backuppath;
296 if ( !QgsApplication::authManager()->eraseAuthenticationDatabase( true, &backuppath ) )
297 {
298 msg = QObject::tr( "Authentication database FAILED to be erased." );
299 level = Qgis::MessageLevel::Warning;
300 }
301 else
302 {
303 if ( !backuppath.isEmpty() )
304 {
305 msg += QObject::tr( " (backup: %1)" ).arg( backuppath );
306 }
307 level = Qgis::MessageLevel::Critical;
308 }
309
310 msgbar->pushMessage( QObject::tr( "RESTART QGIS" ), msg, level );
311}
312
313void QgsAuthGuiUtils::fileFound( bool found, QWidget *widget )
314{
315 if ( !found )
316 {
317 widget->setStyleSheet( QgsAuthGuiUtils::redTextStyleSheet( QStringLiteral( "QLineEdit" ) ) );
318 widget->setToolTip( QObject::tr( "File not found" ) );
319 }
320 else
321 {
322 widget->setStyleSheet( QString() );
323 widget->setToolTip( QString() );
324 }
325}
326
327QString QgsAuthGuiUtils::getOpenFileName( QWidget *parent, const QString &title, const QString &extfilter )
328{
329 QgsSettings settings;
330 const QString recentdir = settings.value( QStringLiteral( "UI/lastAuthOpenFileDir" ), QDir::homePath() ).toString();
331 QString f = QFileDialog::getOpenFileName( parent, title, recentdir, extfilter );
332 if ( !f.isEmpty() )
333 {
334 settings.setValue( QStringLiteral( "UI/lastAuthOpenFileDir" ), QFileInfo( f ).absoluteDir().path() );
335 }
336 return f;
337}
338
340{
341 if ( QMessageBox::warning( parent,
342 QObject::tr( "Delete Password" ),
343 QObject::tr( "Do you really want to delete the master password from your %1?" )
345 QMessageBox::Ok | QMessageBox::Cancel,
346 QMessageBox::Cancel ) == QMessageBox::Cancel )
347 {
348 return;
349 }
350 QString msg;
351 Qgis::MessageLevel level;
353 {
355 level = Qgis::MessageLevel::Warning;
356 }
357 else
358 {
359 msg = QObject::tr( "Master password was successfully deleted from your %1" )
361
362 level = Qgis::MessageLevel::Info;
363 }
364 msgbar->pushMessage( QObject::tr( "Password helper delete" ), msg, level );
365}
366
368{
369 QString msg;
370 Qgis::MessageLevel level;
371 if ( ! QgsApplication::authManager()->masterPasswordIsSet() )
372 {
373 msg = QObject::tr( "Master password is not set and cannot be stored in your %1." )
375 level = Qgis::MessageLevel::Warning;
376 }
378 {
380 level = Qgis::MessageLevel::Warning;
381 }
382 else
383 {
384 msg = QObject::tr( "Master password has been successfully stored in your %1." )
386
387 level = Qgis::MessageLevel::Info;
388 }
389 msgbar->pushMessage( QObject::tr( "Password helper write" ), msg, level );
390}
391
393{
395 const QString msg = enabled ? QObject::tr( "Your %1 will be <b>used from now</b> on to store and retrieve the master password." )
397 QObject::tr( "Your %1 will <b>not be used anymore</b> to store and retrieve the master password." )
399 msgbar->pushMessage( QObject::tr( "Password helper write" ), msg, Qgis::MessageLevel::Info );
400}
401
402void QgsAuthGuiUtils::passwordHelperLoggingEnable( bool enabled, QgsMessageBar *msgbar, int timeout )
403{
404 Q_UNUSED( msgbar )
405 Q_UNUSED( timeout )
407}
MessageLevel
Level for messages This will be used both for message log and message bar in application.
Definition: qgis.h:100
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 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 void passwordHelperSync(QgsMessageBar *msgbar)
Store master password into the 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.
void setPasswordHelperLoggingEnabled(bool enabled)
Password helper logging enabled setter.
bool setMasterPassword(bool verify=false)
Main call to initially set or continually check master password is set.
static const QString AUTH_PASSWORD_HELPER_DISPLAY_NAME
The 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)
A bar for displaying non-blocking messages to the user.
Definition: qgsmessagebar.h:61
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.
This class is a composition of two QSettings instances:
Definition: qgssettings.h:63
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 QgsDebugMsg(str)
Definition: qgslogger.h:38