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