QGIS API Documentation 4.1.0-Master (5bf3c20f3c9)
Loading...
Searching...
No Matches
qgsauthauthoritieseditor.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsauthauthoritieseditor.cpp
3 ---------------------
4 begin : April 26, 2015
5 copyright : (C) 2015 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 "ui_qgsauthauthoritieseditor.h"
19
20#include "qgsapplication.h"
22#include "qgsauthcertutils.h"
23#include "qgsauthguiutils.h"
25#include "qgsauthmanager.h"
27#include "qgslogger.h"
28#include "qgssettings.h"
29#include "qgsvariantutils.h"
30
31#include <QAction>
32#include <QComboBox>
33#include <QDateTime>
34#include <QDir>
35#include <QFileDialog>
36#include <QFileInfo>
37#include <QMenu>
38#include <QMessageBox>
39#include <QPair>
40#include <QPushButton>
41#include <QSslConfiguration>
42#include <QString>
43
44#include "moc_qgsauthauthoritieseditor.cpp"
45
46using namespace Qt::StringLiterals;
47
49 : QWidget( parent )
50{
51 if ( QgsApplication::authManager()->isDisabled() )
52 {
53 mDisabled = true;
54 mAuthNotifyLayout = new QVBoxLayout;
55 this->setLayout( mAuthNotifyLayout );
56 mAuthNotify = new QLabel( QgsApplication::authManager()->disabledMessage(), this );
57 mAuthNotifyLayout->addWidget( mAuthNotify );
58 }
59 else
60 {
61 setupUi( this );
62 connect( btnAddCa, &QToolButton::clicked, this, &QgsAuthAuthoritiesEditor::btnAddCa_clicked );
63 connect( btnRemoveCa, &QToolButton::clicked, this, &QgsAuthAuthoritiesEditor::btnRemoveCa_clicked );
64 connect( btnInfoCa, &QToolButton::clicked, this, &QgsAuthAuthoritiesEditor::btnInfoCa_clicked );
65 connect( btnGroupByOrg, &QToolButton::toggled, this, &QgsAuthAuthoritiesEditor::btnGroupByOrg_toggled );
66 connect( btnCaFile, &QToolButton::clicked, this, &QgsAuthAuthoritiesEditor::btnCaFile_clicked );
67 connect( btnCaFileClear, &QToolButton::clicked, this, &QgsAuthAuthoritiesEditor::btnCaFileClear_clicked );
68
69 connect( QgsApplication::authManager(), &QgsAuthManager::messageLog, this, &QgsAuthAuthoritiesEditor::logMessage );
70
71 connect( QgsApplication::authManager(), &QgsAuthManager::authDatabaseChanged, this, &QgsAuthAuthoritiesEditor::refreshCaCertsView );
72
73 setupCaCertsTree();
74
75 connect( treeWidgetCAs->selectionModel(), &QItemSelectionModel::selectionChanged, this, &QgsAuthAuthoritiesEditor::selectionChanged );
76
77 connect( treeWidgetCAs, &QTreeWidget::itemDoubleClicked, this, &QgsAuthAuthoritiesEditor::handleDoubleClick );
78
79 connect( btnViewRefresh, &QAbstractButton::clicked, this, &QgsAuthAuthoritiesEditor::refreshCaCertsView );
80
81 const QVariant cafileval = QgsApplication::authManager()->authSetting( u"cafile"_s );
82 if ( !QgsVariantUtils::isNull( cafileval ) )
83 {
84 leCaFile->setText( cafileval.toString() );
85 }
86
87 btnGroupByOrg->setChecked( false );
88 const QVariant sortbyval = QgsApplication::authManager()->authSetting( u"casortby"_s, QVariant( false ) );
89 if ( !QgsVariantUtils::isNull( sortbyval ) )
90 btnGroupByOrg->setChecked( sortbyval.toBool() );
91
92 mDefaultTrustPolicy = QgsApplication::authManager()->defaultCertTrustPolicy();
93 populateCaCertsView();
94 checkSelection();
95
96 populateUtilitiesMenu();
97 }
98}
99
100void QgsAuthAuthoritiesEditor::setupCaCertsTree()
101{
102 treeWidgetCAs->setColumnCount( 4 );
103 treeWidgetCAs->setHeaderLabels( QStringList() << tr( "Common Name" ) << tr( "Serial #" ) << tr( "Expiry Date" ) << tr( "Trust Policy" ) );
104 treeWidgetCAs->setColumnWidth( 0, 300 );
105 treeWidgetCAs->setColumnWidth( 1, 75 );
106 treeWidgetCAs->setColumnWidth( 2, 200 );
107
108 // add root sections
109 mDbCaSecItem = new QTreeWidgetItem( treeWidgetCAs, QStringList( QgsAuthCertUtils::getCaSourceName( QgsAuthCertUtils::InDatabase ) ), static_cast<int>( QgsAuthAuthoritiesEditor::Section ) );
110 QgsAuthGuiUtils::setItemBold( mDbCaSecItem );
111 mDbCaSecItem->setFlags( Qt::ItemIsEnabled );
112 mDbCaSecItem->setExpanded( true );
113 treeWidgetCAs->insertTopLevelItem( 0, mDbCaSecItem );
114
115 mFileCaSecItem = new QTreeWidgetItem( treeWidgetCAs, QStringList( QgsAuthCertUtils::getCaSourceName( QgsAuthCertUtils::FromFile ) ), static_cast<int>( QgsAuthAuthoritiesEditor::Section ) );
116 QgsAuthGuiUtils::setItemBold( mFileCaSecItem );
117 mFileCaSecItem->setFlags( Qt::ItemIsEnabled );
118 mFileCaSecItem->setExpanded( true );
119 treeWidgetCAs->insertTopLevelItem( 0, mFileCaSecItem );
120
121 mRootCaSecItem = new QTreeWidgetItem( treeWidgetCAs, QStringList( QgsAuthCertUtils::getCaSourceName( QgsAuthCertUtils::SystemRoot ) ), static_cast<int>( QgsAuthAuthoritiesEditor::Section ) );
122 QgsAuthGuiUtils::setItemBold( mRootCaSecItem );
123 mRootCaSecItem->setFlags( Qt::ItemIsEnabled );
124 mRootCaSecItem->setExpanded( false );
125 treeWidgetCAs->insertTopLevelItem( 0, mRootCaSecItem );
126}
127
128void QgsAuthAuthoritiesEditor::populateCaCertsView()
129{
130 updateCertTrustPolicyCache();
131 populateDatabaseCaCerts();
132 populateFileCaCerts();
133 populateRootCaCerts();
134}
135
136void QgsAuthAuthoritiesEditor::refreshCaCertsView()
137{
138 // QgsApplication::authManager()->rebuildCaCertsCache();
139 populateCaCertsView();
140}
141
142void QgsAuthAuthoritiesEditor::populateDatabaseCaCerts()
143{
144 QgsAuthGuiUtils::removeChildren( mDbCaSecItem );
145
146 const bool expanded = mDbCaSecItem->isExpanded();
147 populateCaCertsSection( mDbCaSecItem, QgsApplication::authManager()->databaseCAs(), QgsAuthAuthoritiesEditor::DbCaCert );
148 mDbCaSecItem->setExpanded( expanded );
149}
150
151void QgsAuthAuthoritiesEditor::populateFileCaCerts()
152{
153 QgsAuthGuiUtils::removeChildren( mFileCaSecItem );
154
155 const bool expanded = mFileCaSecItem->isExpanded();
156 populateCaCertsSection( mFileCaSecItem, QgsApplication::authManager()->extraFileCAs(), QgsAuthAuthoritiesEditor::FileCaCert );
157 mFileCaSecItem->setExpanded( expanded );
158}
159
160void QgsAuthAuthoritiesEditor::populateRootCaCerts()
161{
162 QgsAuthGuiUtils::removeChildren( mRootCaSecItem );
163
164 const bool expanded = mRootCaSecItem->isExpanded();
165 populateCaCertsSection( mRootCaSecItem, QgsApplication::authManager()->systemRootCAs(), QgsAuthAuthoritiesEditor::RootCaCert );
166 mRootCaSecItem->setExpanded( expanded );
167}
168
169void QgsAuthAuthoritiesEditor::populateCaCertsSection( QTreeWidgetItem *item, const QList<QSslCertificate> &certs, QgsAuthAuthoritiesEditor::CaType catype )
170{
171 if ( btnGroupByOrg->isChecked() )
172 {
173 appendCertsToGroup( certs, catype, item );
174 }
175 else
176 {
177 appendCertsToItem( certs, catype, item );
178 }
179}
180
181void QgsAuthAuthoritiesEditor::appendCertsToGroup( const QList<QSslCertificate> &certs, QgsAuthAuthoritiesEditor::CaType catype, QTreeWidgetItem *parent )
182{
183 if ( certs.empty() )
184 return;
185
186 if ( !parent )
187 {
188 parent = treeWidgetCAs->currentItem();
189 }
190
191 // TODO: find all organizational name, sort and make subsections
192 const QMap<QString, QList<QSslCertificate>> orgcerts( QgsAuthCertUtils::certsGroupedByOrg( certs ) );
193
194 QMap<QString, QList<QSslCertificate>>::const_iterator it = orgcerts.constBegin();
195 for ( ; it != orgcerts.constEnd(); ++it )
196 {
197 QTreeWidgetItem *grpitem( new QTreeWidgetItem( parent, QStringList() << it.key(), static_cast<int>( QgsAuthAuthoritiesEditor::OrgName ) ) );
198 grpitem->setFirstColumnSpanned( true );
199 grpitem->setFlags( Qt::ItemIsEnabled );
200 grpitem->setExpanded( true );
201
202 QBrush orgb( grpitem->foreground( 0 ) );
203 orgb.setColor( QColor::fromRgb( 90, 90, 90 ) );
204 grpitem->setForeground( 0, orgb );
205 QFont grpf( grpitem->font( 0 ) );
206 grpf.setItalic( true );
207 grpitem->setFont( 0, grpf );
208
209 appendCertsToItem( it.value(), catype, grpitem );
210 }
211
212 parent->sortChildren( 0, Qt::AscendingOrder );
213}
214
215void QgsAuthAuthoritiesEditor::appendCertsToItem( const QList<QSslCertificate> &certs, QgsAuthAuthoritiesEditor::CaType catype, QTreeWidgetItem *parent )
216{
217 if ( certs.empty() )
218 return;
219
220 if ( !parent )
221 {
222 parent = treeWidgetCAs->currentItem();
223 }
224
225 const QBrush greenb( QgsAuthGuiUtils::greenColor() );
226 const QBrush redb( QgsAuthGuiUtils::redColor() );
227
228 const QStringList trustedids = mCertTrustCache.value( QgsAuthCertUtils::Trusted );
229 const QStringList untrustedids = mCertTrustCache.value( QgsAuthCertUtils::Untrusted );
230
231 // Columns: Common Name, Serial #, Expiry Date
232 const auto constCerts = certs;
233 for ( const QSslCertificate &cert : constCerts )
234 {
235 const QString id( QgsAuthCertUtils::shaHexForCert( cert ) );
236
237 QStringList coltxts;
238 coltxts << QgsAuthCertUtils::resolvedCertName( cert );
239 coltxts << QString( cert.serialNumber() );
240 coltxts << cert.expiryDate().toString();
241
242 // trust policy
243 QString policy( QgsAuthCertUtils::getCertTrustName( mDefaultTrustPolicy ) );
244 if ( trustedids.contains( id ) )
245 {
246 policy = QgsAuthCertUtils::getCertTrustName( QgsAuthCertUtils::Trusted );
247 }
248 else if ( untrustedids.contains( id ) || cert.isBlacklisted() || cert.isNull() || cert.expiryDate() <= QDateTime::currentDateTime() || cert.effectiveDate() > QDateTime::currentDateTime() )
249 {
250 policy = QgsAuthCertUtils::getCertTrustName( QgsAuthCertUtils::Untrusted );
251 }
252 coltxts << policy;
253
254 QTreeWidgetItem *item( new QTreeWidgetItem( parent, coltxts, static_cast<int>( catype ) ) );
255
256 item->setIcon( 0, QgsApplication::getThemeIcon( u"/mIconCertificate.svg"_s ) );
257 if ( cert.isBlacklisted() || cert.isNull() || cert.expiryDate() <= QDateTime::currentDateTime() || cert.effectiveDate() > QDateTime::currentDateTime() )
258 {
259 item->setForeground( 2, redb );
260 item->setIcon( 0, QgsApplication::getThemeIcon( u"/mIconCertificateUntrusted.svg"_s ) );
261 }
262
263 if ( trustedids.contains( id ) )
264 {
265 item->setForeground( 3, greenb );
266 if ( !cert.isBlacklisted() && !cert.isNull() && cert.expiryDate() > QDateTime::currentDateTime() && cert.effectiveDate() <= QDateTime::currentDateTime() )
267 {
268 item->setIcon( 0, QgsApplication::getThemeIcon( u"/mIconCertificateTrusted.svg"_s ) );
269 }
270 }
271 else if ( untrustedids.contains( id ) )
272 {
273 item->setForeground( 3, redb );
274 item->setIcon( 0, QgsApplication::getThemeIcon( u"/mIconCertificateUntrusted.svg"_s ) );
275 }
276 else if ( mDefaultTrustPolicy == QgsAuthCertUtils::Untrusted )
277 {
278 item->setIcon( 0, QgsApplication::getThemeIcon( u"/mIconCertificateUntrusted.svg"_s ) );
279 }
280
281 item->setData( 0, Qt::UserRole, id );
282 }
283
284 parent->sortChildren( 0, Qt::AscendingOrder );
285}
286
287void QgsAuthAuthoritiesEditor::updateCertTrustPolicyCache()
288{
289 mCertTrustCache = QgsApplication::authManager()->certTrustCache();
290}
291
292void QgsAuthAuthoritiesEditor::populateUtilitiesMenu()
293{
294 mActionDefaultTrustPolicy = new QAction( u"Change default trust policy"_s, this );
295 connect( mActionDefaultTrustPolicy, &QAction::triggered, this, &QgsAuthAuthoritiesEditor::editDefaultTrustPolicy );
296
297 mActionShowTrustedCAs = new QAction( u"Show trusted authorities/issuers"_s, this );
298 connect( mActionShowTrustedCAs, &QAction::triggered, this, &QgsAuthAuthoritiesEditor::showTrustedCertificateAuthorities );
299
300 mUtilitiesMenu = new QMenu( this );
301 mUtilitiesMenu->addAction( mActionDefaultTrustPolicy );
302 mUtilitiesMenu->addSeparator();
303 mUtilitiesMenu->addAction( mActionShowTrustedCAs );
304
305 btnUtilities->setMenu( mUtilitiesMenu );
306}
307
308void QgsAuthAuthoritiesEditor::showCertInfo( QTreeWidgetItem *item )
309{
310 if ( !item )
311 return;
312
313 const QString digest( item->data( 0, Qt::UserRole ).toString() );
314
315 const QMap<QString, QPair<QgsAuthCertUtils::CaCertSource, QSslCertificate>> cacertscache( QgsApplication::authManager()->caCertsCache() );
316
317 if ( !cacertscache.contains( digest ) )
318 {
319 QgsDebugError( u"Certificate Authority not in CA certs cache"_s );
320 return;
321 }
322
323 const QSslCertificate cert( cacertscache.value( digest ).second );
324
325 QgsAuthCertInfoDialog *dlg = new QgsAuthCertInfoDialog( cert, true, this );
326 dlg->setWindowModality( Qt::WindowModal );
327 dlg->resize( 675, 500 );
328 dlg->exec();
329 if ( dlg->trustCacheRebuilt() )
330 {
331 // QgsApplication::authManager()->rebuildTrustedCaCertsCache() already called in dlg
332 populateCaCertsView();
333 }
334 dlg->deleteLater();
335}
336
337void QgsAuthAuthoritiesEditor::selectionChanged( const QItemSelection &selected, const QItemSelection &deselected )
338{
339 Q_UNUSED( selected )
340 Q_UNUSED( deselected )
341 checkSelection();
342}
343
344void QgsAuthAuthoritiesEditor::checkSelection()
345{
346 bool iscert = false;
347 bool isdbcert = false;
348 if ( treeWidgetCAs->selectionModel()->selection().length() > 0 )
349 {
350 QTreeWidgetItem *item( treeWidgetCAs->currentItem() );
351
352 switch ( ( QgsAuthAuthoritiesEditor::CaType ) item->type() )
353 {
354 case QgsAuthAuthoritiesEditor::RootCaCert:
355 iscert = true;
356 break;
357 case QgsAuthAuthoritiesEditor::FileCaCert:
358 iscert = true;
359 break;
360 case QgsAuthAuthoritiesEditor::DbCaCert:
361 iscert = true;
362 isdbcert = true;
363 break;
364 default:
365 break;
366 }
367 }
368
369 btnRemoveCa->setEnabled( isdbcert );
370 btnInfoCa->setEnabled( iscert );
371}
372
373void QgsAuthAuthoritiesEditor::handleDoubleClick( QTreeWidgetItem *item, int col )
374{
375 Q_UNUSED( col )
376 bool iscert = true;
377
378 switch ( ( QgsAuthAuthoritiesEditor::CaType ) item->type() )
379 {
380 case QgsAuthAuthoritiesEditor::Section:
381 iscert = false;
382 break;
383 case QgsAuthAuthoritiesEditor::OrgName:
384 iscert = false;
385 break;
386 default:
387 break;
388 }
389
390 if ( iscert )
391 {
392 showCertInfo( item );
393 }
394}
395
396void QgsAuthAuthoritiesEditor::btnAddCa_clicked()
397{
398 QgsAuthImportCertDialog *dlg = new QgsAuthImportCertDialog( this, QgsAuthImportCertDialog::CaFilter );
399 dlg->setWindowModality( Qt::WindowModal );
400 dlg->resize( 400, 450 );
401 if ( dlg->exec() )
402 {
403 const QList<QSslCertificate> &certs( dlg->certificatesToImport() );
404 if ( !QgsApplication::authManager()->storeCertAuthorities( certs ) )
405 {
406 messageBar()->pushMessage( tr( "ERROR storing CA(s) in authentication storage" ), Qgis::MessageLevel::Critical );
407 }
408
410
412 {
413 const auto constCerts = certs;
414 for ( const QSslCertificate &cert : constCerts )
415 {
416 if ( !QgsApplication::authManager()->storeCertTrustPolicy( cert, dlg->certTrustPolicy() ) )
417 {
418 logMessage( QObject::tr( "Could not set trust policy for imported certificates" ), QObject::tr( "Authorities Manager" ), Qgis::MessageLevel::Warning );
419 }
420 }
422 updateCertTrustPolicyCache();
423 }
424
426 populateDatabaseCaCerts();
427 mDbCaSecItem->setExpanded( true );
428 }
429 dlg->deleteLater();
430}
431
432void QgsAuthAuthoritiesEditor::btnRemoveCa_clicked()
433{
434 QTreeWidgetItem *item( treeWidgetCAs->currentItem() );
435
436 if ( !item )
437 {
438 QgsDebugMsgLevel( u"Current tree widget item not set"_s, 2 );
439 return;
440 }
441
442 const QString digest( item->data( 0, Qt::UserRole ).toString() );
443
444 if ( digest.isEmpty() )
445 {
446 messageBar()->pushMessage( tr( "Certificate id missing" ), Qgis::MessageLevel::Warning );
447 return;
448 }
449
450 const QMap<QString, QSslCertificate> mappedcerts( QgsApplication::authManager()->mappedDatabaseCAs() );
451
452 if ( !mappedcerts.contains( digest ) )
453 {
454 QgsDebugError( u"Certificate Authority not in mapped database CAs"_s );
455 return;
456 }
457
458 if ( QMessageBox::warning(
459 this,
460 tr( "Remove Certificate Authority" ),
461 tr(
462 "Are you sure you want to remove the selected "
463 "Certificate Authority from the database?\n\n"
464 "Operation can NOT be undone!"
465 ),
466 QMessageBox::Ok | QMessageBox::Cancel,
467 QMessageBox::Cancel
468 )
469 == QMessageBox::Cancel )
470 {
471 return;
472 }
473
474 const QSslCertificate cert( mappedcerts.value( digest ) );
475
476 if ( cert.isNull() )
477 {
478 messageBar()->pushMessage( tr( "Certificate could not be found in the authentication storage for id %1:" ).arg( digest ), Qgis::MessageLevel::Warning );
479 return;
480 }
481
482 if ( !QgsApplication::authManager()->removeCertAuthority( cert ) )
483 {
484 messageBar()->pushMessage( tr( "ERROR removing CA from the authentication storage for id %1:" ).arg( digest ), Qgis::MessageLevel::Critical );
485 return;
486 }
487
488 if ( !QgsApplication::authManager()->removeCertTrustPolicy( cert ) )
489 {
490 messageBar()->pushMessage( tr( "ERROR removing cert trust policy from the authentication storage for id %1:" ).arg( digest ), Qgis::MessageLevel::Critical );
491 return;
492 }
493
496 updateCertTrustPolicyCache();
497
498 item->parent()->removeChild( item );
499 delete item;
500
501 // populateDatabaseCaCerts();
502 mDbCaSecItem->setExpanded( true );
503}
504
505void QgsAuthAuthoritiesEditor::btnInfoCa_clicked()
506{
507 if ( treeWidgetCAs->selectionModel()->selection().length() > 0 )
508 {
509 QTreeWidgetItem *item( treeWidgetCAs->currentItem() );
510 handleDoubleClick( item, 0 );
511 }
512}
513
514void QgsAuthAuthoritiesEditor::btnGroupByOrg_toggled( bool checked )
515{
516 if ( !QgsApplication::authManager()->storeAuthSetting( u"casortby"_s, QVariant( checked ) ) )
517 {
518 logMessage( QObject::tr( "Could not store sort by preference" ), QObject::tr( "Authorities Manager" ), Qgis::MessageLevel::Warning );
519 }
520 populateCaCertsView();
521}
522
523void QgsAuthAuthoritiesEditor::editDefaultTrustPolicy()
524{
525 QDialog *dlg = new QDialog( this );
526 dlg->setWindowTitle( tr( "Default Trust Policy" ) );
527 QVBoxLayout *layout = new QVBoxLayout( dlg );
528
529 QHBoxLayout *hlayout = new QHBoxLayout();
530
531 QLabel *lblwarn = new QLabel( dlg );
532 QStyle *style = QApplication::style();
533 lblwarn->setPixmap( style->standardIcon( QStyle::SP_MessageBoxWarning ).pixmap( 48, 48 ) );
534 lblwarn->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
535 hlayout->addWidget( lblwarn );
536
537 QLabel *lbltxt = new QLabel( dlg );
538 lbltxt->setText( tr(
539 "Changing the default certificate authority trust policy to 'Untrusted' "
540 "can cause unexpected SSL network connection results."
541 ) );
542 lbltxt->setWordWrap( true );
543 hlayout->addWidget( lbltxt );
544
545 layout->addLayout( hlayout );
546
547 QHBoxLayout *hlayout2 = new QHBoxLayout();
548
549 QLabel *lblpolicy = new QLabel( tr( "Default policy" ), dlg );
550 lblpolicy->setSizePolicy( QSizePolicy::Maximum, QSizePolicy::Preferred );
551 hlayout2->addWidget( lblpolicy );
552
553 QComboBox *cmbpolicy = new QComboBox( dlg );
554 QList<QPair<QgsAuthCertUtils::CertTrustPolicy, QString>> policies;
555 policies
556 << qMakePair( QgsAuthCertUtils::Trusted, QgsAuthCertUtils::getCertTrustName( QgsAuthCertUtils::Trusted ) )
557 << qMakePair( QgsAuthCertUtils::Untrusted, QgsAuthCertUtils::getCertTrustName( QgsAuthCertUtils::Untrusted ) );
558
559 for ( int i = 0; i < policies.size(); i++ )
560 {
561 cmbpolicy->addItem( policies.at( i ).second, QVariant( static_cast<int>( policies.at( i ).first ) ) );
562 }
563
564 const int idx = cmbpolicy->findData( QVariant( static_cast<int>( mDefaultTrustPolicy ) ) );
565 cmbpolicy->setCurrentIndex( idx == -1 ? 0 : idx );
566 hlayout2->addWidget( cmbpolicy );
567
568 layout->addLayout( hlayout2 );
569
570 QDialogButtonBox *buttonBox = new QDialogButtonBox( QDialogButtonBox::Close | QDialogButtonBox::Ok, Qt::Horizontal, dlg );
571 buttonBox->button( QDialogButtonBox::Close )->setDefault( true );
572
573 layout->addWidget( buttonBox );
574
575 connect( buttonBox, &QDialogButtonBox::accepted, dlg, &QDialog::accept );
576 connect( buttonBox, &QDialogButtonBox::rejected, dlg, &QWidget::close );
577
578 dlg->setLayout( layout );
579 dlg->setWindowModality( Qt::WindowModal );
580 dlg->resize( 400, 200 );
581 dlg->setMinimumSize( 400, 200 );
582 dlg->setMaximumSize( 500, 300 );
583 if ( dlg->exec() )
584 {
585 const QgsAuthCertUtils::CertTrustPolicy trustpolicy( ( QgsAuthCertUtils::CertTrustPolicy ) cmbpolicy->currentData().toInt() );
586 if ( mDefaultTrustPolicy != trustpolicy )
587 {
588 defaultTrustPolicyChanged( trustpolicy );
589 }
590 }
591 dlg->deleteLater();
592}
593
594void QgsAuthAuthoritiesEditor::defaultTrustPolicyChanged( QgsAuthCertUtils::CertTrustPolicy trustpolicy )
595{
596 if ( !QgsApplication::authManager()->setDefaultCertTrustPolicy( trustpolicy ) )
597 {
598 logMessage( QObject::tr( "Could not store default trust policy." ), QObject::tr( "Authorities Manager" ), Qgis::MessageLevel::Critical );
599 }
600 mDefaultTrustPolicy = trustpolicy;
603 populateCaCertsView();
604}
605
606void QgsAuthAuthoritiesEditor::btnCaFile_clicked()
607{
608 QgsAuthImportCertDialog *dlg = new QgsAuthImportCertDialog( this, QgsAuthImportCertDialog::CaFilter, QgsAuthImportCertDialog::FileInput );
609 dlg->setWindowModality( Qt::WindowModal );
610 dlg->resize( 400, 250 );
611 if ( dlg->exec() )
612 {
613 // clear out any currently defined file certs and their trust settings
614 if ( !leCaFile->text().isEmpty() )
615 {
616 btnCaFileClear_clicked();
617 }
618
619 const QString &fn = dlg->certFileToImport();
620 leCaFile->setText( fn );
621
622 if ( !QgsApplication::authManager()->storeAuthSetting( u"cafile"_s, QVariant( fn ) ) )
623 {
624 logMessage( QObject::tr( "Could not store 'CA file path' in authentication storage." ), QObject::tr( "Authorities Manager" ), Qgis::MessageLevel::Warning );
625 }
626 if ( !QgsApplication::authManager()->storeAuthSetting( u"cafileallowinvalid"_s, QVariant( dlg->allowInvalidCerts() ) ) )
627 {
628 logMessage( QObject::tr( "Could not store 'CA file allow invalids' setting in authentication storage." ), QObject::tr( "Authorities Manager" ), Qgis::MessageLevel::Warning );
629 }
630
632
634 {
635 const QList<QSslCertificate> certs( QgsApplication::authManager()->extraFileCAs() );
636 const auto constCerts = certs;
637 for ( const QSslCertificate &cert : constCerts )
638 {
639 if ( !QgsApplication::authManager()->storeCertTrustPolicy( cert, dlg->certTrustPolicy() ) )
640 {
641 logMessage( QObject::tr( "Could not set trust policy for imported certificates." ), QObject::tr( "Authorities Manager" ), Qgis::MessageLevel::Warning );
642 }
643 }
645 updateCertTrustPolicyCache();
646 }
647
649
650 populateFileCaCerts();
651 mFileCaSecItem->setExpanded( true );
652 }
653 dlg->deleteLater();
654}
655
656void QgsAuthAuthoritiesEditor::btnCaFileClear_clicked()
657{
658 if ( !QgsApplication::authManager()->removeAuthSetting( u"cafile"_s ) )
659 {
660 logMessage( QObject::tr( "Could not remove 'CA file path' from authentication storage." ), QObject::tr( "Authorities Manager" ), Qgis::MessageLevel::Warning );
661 return;
662 }
663 if ( !QgsApplication::authManager()->removeAuthSetting( u"cafileallowinvalid"_s ) )
664 {
665 logMessage( QObject::tr( "Could not remove 'CA file allow invalids' setting from authentication storage." ), QObject::tr( "Authorities Manager" ), Qgis::MessageLevel::Warning );
666 return;
667 }
668
670
671 const QString fn( leCaFile->text() );
672 if ( QFile::exists( fn ) )
673 {
674 const QList<QSslCertificate> certs( QgsAuthCertUtils::certsFromFile( fn ) );
675
676 if ( !certs.isEmpty() )
677 {
678 if ( !QgsApplication::authManager()->removeCertTrustPolicies( certs ) )
679 {
680 messageBar()->pushMessage( tr( "ERROR removing cert(s) trust policy from authentication storage." ), Qgis::MessageLevel::Critical );
681 return;
682 }
684 updateCertTrustPolicyCache();
685 }
686 }
687
689
690 leCaFile->clear();
691 populateFileCaCerts();
692}
693
694void QgsAuthAuthoritiesEditor::showTrustedCertificateAuthorities()
695{
696 QgsAuthTrustedCAsDialog *dlg = new QgsAuthTrustedCAsDialog( this );
697 dlg->setWindowModality( Qt::WindowModal );
698 dlg->resize( 675, 500 );
699 dlg->exec();
700 dlg->deleteLater();
701}
702
703void QgsAuthAuthoritiesEditor::logMessage( const QString &message, const QString &authtag, Qgis::MessageLevel level )
704{
705 messageBar()->pushMessage( authtag, message, level, 7 );
706}
707
709{
710 if ( !mDisabled )
711 {
712 treeWidgetCAs->setFocus();
713 }
714 QWidget::showEvent( e );
715}
716
717QgsMessageBar *QgsAuthAuthoritiesEditor::messageBar()
718{
719 return msgBar;
720}
721
722int QgsAuthAuthoritiesEditor::messageTimeout()
723{
724 const QgsSettings settings;
725 return settings.value( u"qgis/messageTimeout"_s, 5 ).toInt();
726}
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
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
static QgsAuthManager * authManager()
Returns the application's authentication manager instance.
void showEvent(QShowEvent *e) override
Overridden show event of base widget.
QgsAuthAuthoritiesEditor(QWidget *parent=nullptr)
Widget for viewing and editing certificate authorities directly in database.
bool trustCacheRebuilt() const
Whether the trust cache has been rebuilt.
CertTrustPolicy
Type of certificate trust policy.
static QColor greenColor()
Green color representing valid, trusted, etc. certificate.
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 QColor redColor()
Red color representing invalid, untrusted, etc. certificate.
QgsAuthCertUtils::CertTrustPolicy certTrustPolicy()
Defined trust policy for imported certificates.
const QString certFileToImport()
Gets the file path to a certificate to import.
const QList< QSslCertificate > certificatesToImport()
Gets list of certificate objects to import.
bool allowInvalidCerts()
Whether to allow importation of invalid certificates (so trust policy can be overridden).
const QMap< QgsAuthCertUtils::CertTrustPolicy, QStringList > certTrustCache()
certTrustCache get cache of certificate sha1s, per trust policy
bool rebuildCaCertsCache()
Rebuild certificate authority cache.
void authDatabaseChanged()
Emitted when the authentication db is significantly changed, e.g. large record removal,...
QVariant authSetting(const QString &key, const QVariant &defaultValue=QVariant(), bool decrypt=false)
Returns a previously set authentication setting.
QgsAuthCertUtils::CertTrustPolicy defaultCertTrustPolicy()
Gets the default certificate trust policy preferred by user.
bool rebuildCertTrustCache()
Rebuild certificate authority cache.
void messageLog(const QString &message, const QString &tag=QgsAuthManager::AUTH_MAN_TAG, Qgis::MessageLevel level=Qgis::MessageLevel::Info) const
Custom logging signal to relay to console output and QgsMessageLog.
bool rebuildTrustedCaCertsCache()
Rebuild trusted certificate authorities cache.
A bar for displaying non-blocking messages to the user.
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
#define QgsDebugMsgLevel(str, level)
Definition qgslogger.h:63
#define QgsDebugError(str)
Definition qgslogger.h:59