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