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