QGIS API Documentation 3.41.0-Master (cea29feecf2)
Loading...
Searching...
No Matches
qgsauthtrustedcasdialog.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsauthtrustedcasdialog.cpp
3 ---------------------
4 begin : May 9, 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
18#include "moc_qgsauthtrustedcasdialog.cpp"
19#include "ui_qgsauthtrustedcasdialog.h"
20
21#include <QPushButton>
22
23#include "qgssettings.h"
24#include "qgsapplication.h"
26#include "qgsauthcertutils.h"
27#include "qgsauthguiutils.h"
28#include "qgsauthmanager.h"
29#include "qgslogger.h"
30#include "qgsvariantutils.h"
31
32QgsAuthTrustedCAsDialog::QgsAuthTrustedCAsDialog( QWidget *parent, const QList<QSslCertificate> &trustedCAs )
33 : QDialog( parent )
34 , mTrustedCAs( trustedCAs )
35{
36 if ( QgsApplication::authManager()->isDisabled() )
37 {
38 mDisabled = true;
39 mAuthNotifyLayout = new QVBoxLayout;
40 this->setLayout( mAuthNotifyLayout );
41 mAuthNotify = new QLabel( QgsApplication::authManager()->disabledMessage(), this );
42 mAuthNotifyLayout->addWidget( mAuthNotify );
43 }
44 else
45 {
46 setupUi( this );
47 connect( btnInfoCa, &QToolButton::clicked, this, &QgsAuthTrustedCAsDialog::btnInfoCa_clicked );
48 connect( btnGroupByOrg, &QToolButton::toggled, this, &QgsAuthTrustedCAsDialog::btnGroupByOrg_toggled );
49
50 connect( QgsApplication::authManager(), &QgsAuthManager::messageLog, this, &QgsAuthTrustedCAsDialog::authMessageLog );
51
52 setupCaCertsTree();
53
54 connect( treeTrustedCAs->selectionModel(), &QItemSelectionModel::selectionChanged, this, &QgsAuthTrustedCAsDialog::selectionChanged );
55
56 connect( treeTrustedCAs, &QTreeWidget::itemDoubleClicked, this, &QgsAuthTrustedCAsDialog::handleDoubleClick );
57
58
59 btnGroupByOrg->setChecked( false );
60 const QVariant sortbyval = QgsApplication::authManager()->authSetting( QStringLiteral( "trustedcasortby" ), QVariant( false ) );
61 if ( !QgsVariantUtils::isNull( sortbyval ) )
62 btnGroupByOrg->setChecked( sortbyval.toBool() );
63
64 populateCaCertsView();
65 checkSelection();
66 }
67}
68
69void QgsAuthTrustedCAsDialog::setupCaCertsTree()
70{
71 treeTrustedCAs->setColumnCount( 3 );
72 treeTrustedCAs->setHeaderLabels(
73 QStringList() << tr( "Common Name" )
74 << tr( "Serial #" )
75 << tr( "Expiry Date" )
76 );
77 treeTrustedCAs->setColumnWidth( 0, 300 );
78 treeTrustedCAs->setColumnWidth( 1, 75 );
79
80 // add root section
81 mRootCaSecItem = new QTreeWidgetItem(
82 treeTrustedCAs,
83 QStringList( tr( "Authorities/Issuers" ) ),
84 static_cast<int>( QgsAuthTrustedCAsDialog::Section )
85 );
86 QgsAuthGuiUtils::setItemBold( mRootCaSecItem );
87 mRootCaSecItem->setFlags( Qt::ItemIsEnabled );
88 mRootCaSecItem->setExpanded( true );
89 treeTrustedCAs->insertTopLevelItem( 0, mRootCaSecItem );
90}
91
92void QgsAuthTrustedCAsDialog::populateCaCertsView()
93{
94 QgsAuthGuiUtils::removeChildren( mRootCaSecItem );
95
96 if ( mTrustedCAs.isEmpty() )
97 {
99 }
100
101 populateCaCertsSection( mRootCaSecItem, mTrustedCAs, QgsAuthTrustedCAsDialog::CaCert );
102}
103
104void QgsAuthTrustedCAsDialog::populateCaCertsSection( QTreeWidgetItem *item, const QList<QSslCertificate> &certs, QgsAuthTrustedCAsDialog::CaType catype )
105{
106 if ( btnGroupByOrg->isChecked() )
107 {
108 appendCertsToGroup( certs, catype, item );
109 }
110 else
111 {
112 appendCertsToItem( certs, catype, item );
113 }
114}
115
116void QgsAuthTrustedCAsDialog::appendCertsToGroup( const QList<QSslCertificate> &certs, QgsAuthTrustedCAsDialog::CaType catype, QTreeWidgetItem *parent )
117{
118 if ( certs.empty() )
119 return;
120
121 if ( !parent )
122 {
123 parent = treeTrustedCAs->currentItem();
124 }
125
126 // TODO: find all organizational name, sort and make subsections
127 const QMap<QString, QList<QSslCertificate>> orgcerts(
129 );
130
131 QMap<QString, QList<QSslCertificate>>::const_iterator it = orgcerts.constBegin();
132 for ( ; it != orgcerts.constEnd(); ++it )
133 {
134 QTreeWidgetItem *grpitem( new QTreeWidgetItem( parent, QStringList() << it.key(), static_cast<int>( QgsAuthTrustedCAsDialog::OrgName ) ) );
135 grpitem->setFirstColumnSpanned( true );
136 grpitem->setFlags( Qt::ItemIsEnabled );
137 grpitem->setExpanded( true );
138
139 QBrush orgb( grpitem->foreground( 0 ) );
140 orgb.setColor( QColor::fromRgb( 90, 90, 90 ) );
141 grpitem->setForeground( 0, orgb );
142 QFont grpf( grpitem->font( 0 ) );
143 grpf.setItalic( true );
144 grpitem->setFont( 0, grpf );
145
146 appendCertsToItem( it.value(), catype, grpitem );
147 }
148
149 parent->sortChildren( 0, Qt::AscendingOrder );
150}
151
152void QgsAuthTrustedCAsDialog::appendCertsToItem( const QList<QSslCertificate> &certs, QgsAuthTrustedCAsDialog::CaType catype, QTreeWidgetItem *parent )
153{
154 if ( certs.empty() )
155 return;
156
157 if ( !parent )
158 {
159 parent = treeTrustedCAs->currentItem();
160 }
161
162 const QBrush redb( QgsAuthGuiUtils::redColor() );
163
164 // Columns: Common Name, Serial #, Expiry Date
165 const auto constCerts = certs;
166 for ( const QSslCertificate &cert : constCerts )
167 {
168 const QString id( QgsAuthCertUtils::shaHexForCert( cert ) );
169
170 QStringList coltxts;
171 coltxts << QgsAuthCertUtils::resolvedCertName( cert );
172 coltxts << QString( cert.serialNumber() );
173 coltxts << cert.expiryDate().toString();
174
175 QTreeWidgetItem *item( new QTreeWidgetItem( parent, coltxts, static_cast<int>( catype ) ) );
176
177 item->setIcon( 0, QgsApplication::getThemeIcon( QStringLiteral( "/mIconCertificate.svg" ) ) );
178 if ( !QgsAuthCertUtils::certIsViable( cert ) )
179 {
180 item->setForeground( 2, redb );
181 item->setIcon( 0, QgsApplication::getThemeIcon( QStringLiteral( "/mIconCertificateUntrusted.svg" ) ) );
182 }
183
184 item->setData( 0, Qt::UserRole, id );
185 }
186
187 parent->sortChildren( 0, Qt::AscendingOrder );
188}
189
190void QgsAuthTrustedCAsDialog::showCertInfo( QTreeWidgetItem *item )
191{
192 if ( !item )
193 return;
194
195 const QString digest( item->data( 0, Qt::UserRole ).toString() );
196
197 const QMap<QString, QPair<QgsAuthCertUtils::CaCertSource, QSslCertificate>> cacertscache(
198 QgsApplication::authManager()->caCertsCache()
199 );
200
201 if ( !cacertscache.contains( digest ) )
202 {
203 QgsDebugError( QStringLiteral( "Certificate Authority not in CA certs cache" ) );
204 return;
205 }
206
207 const QSslCertificate cert( cacertscache.value( digest ).second );
208
209 QgsAuthCertInfoDialog *dlg = new QgsAuthCertInfoDialog( cert, false, this );
210 dlg->setWindowModality( Qt::WindowModal );
211 dlg->resize( 675, 500 );
212 dlg->exec();
213 dlg->deleteLater();
214}
215
216void QgsAuthTrustedCAsDialog::selectionChanged( const QItemSelection &selected, const QItemSelection &deselected )
217{
218 Q_UNUSED( selected )
219 Q_UNUSED( deselected )
220 checkSelection();
221}
222
223void QgsAuthTrustedCAsDialog::checkSelection()
224{
225 bool iscert = false;
226 if ( treeTrustedCAs->selectionModel()->selection().length() > 0 )
227 {
228 QTreeWidgetItem *item( treeTrustedCAs->currentItem() );
229
230 switch ( ( QgsAuthTrustedCAsDialog::CaType ) item->type() )
231 {
232 case QgsAuthTrustedCAsDialog::CaCert:
233 iscert = true;
234 break;
235 default:
236 break;
237 }
238 }
239
240 btnInfoCa->setEnabled( iscert );
241}
242
243void QgsAuthTrustedCAsDialog::handleDoubleClick( QTreeWidgetItem *item, int col )
244{
245 Q_UNUSED( col )
246 bool iscert = true;
247
248 switch ( ( QgsAuthTrustedCAsDialog::CaType ) item->type() )
249 {
250 case QgsAuthTrustedCAsDialog::Section:
251 iscert = false;
252 break;
253 case QgsAuthTrustedCAsDialog::OrgName:
254 iscert = false;
255 break;
256 default:
257 break;
258 }
259
260 if ( iscert )
261 {
262 showCertInfo( item );
263 }
264}
265
266void QgsAuthTrustedCAsDialog::btnInfoCa_clicked()
267{
268 if ( treeTrustedCAs->selectionModel()->selection().length() > 0 )
269 {
270 QTreeWidgetItem *item( treeTrustedCAs->currentItem() );
271 handleDoubleClick( item, 0 );
272 }
273}
274
275void QgsAuthTrustedCAsDialog::btnGroupByOrg_toggled( bool checked )
276{
277 if ( !QgsApplication::authManager()->storeAuthSetting( QStringLiteral( "trustedcasortby" ), QVariant( checked ) ) )
278 {
279 authMessageLog( QObject::tr( "Could not store sort by preference" ), QObject::tr( "Trusted Authorities/Issuers" ), Qgis::MessageLevel::Warning );
280 }
281 populateCaCertsView();
282}
283
284void QgsAuthTrustedCAsDialog::authMessageLog( const QString &message, const QString &authtag, Qgis::MessageLevel level )
285{
286 messageBar()->pushMessage( authtag, message, level, 7 );
287}
288
290{
291 if ( !mDisabled )
292 {
293 treeTrustedCAs->setFocus();
294 }
295 QDialog::showEvent( e );
296}
297
298QgsMessageBar *QgsAuthTrustedCAsDialog::messageBar()
299{
300 return msgBar;
301}
302
303int QgsAuthTrustedCAsDialog::messageTimeout()
304{
305 const QgsSettings settings;
306 return settings.value( QStringLiteral( "qgis/messageTimeout" ), 5 ).toInt();
307}
MessageLevel
Level for messages This will be used both for message log and message bar in application.
Definition qgis.h:154
@ Warning
Warning message.
Definition qgis.h:156
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.
Dialog wrapper for widget displaying detailed info on a certificate and its hierarchical trust chain.
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 shaHexForCert(const QSslCertificate &cert, bool formatted=false)
Gets the sha1 hash for certificate.
static bool certIsViable(const QSslCertificate &cert)
certIsViable checks for viability errors of cert and whether it is NULL
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.
QVariant authSetting(const QString &key, const QVariant &defaultValue=QVariant(), bool decrypt=false)
authSetting get an authentication setting (retrieved as string and returned as QVariant( QString ))
const QList< QSslCertificate > trustedCaCerts(bool includeinvalid=false)
trustedCaCerts get list of all trusted CA certificates
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.
void showEvent(QShowEvent *e) override
QgsAuthTrustedCAsDialog(QWidget *parent=nullptr, const QList< QSslCertificate > &trustedCAs=QList< QSslCertificate >())
Construct a dialog that will list the trusted Certificate Authorities.
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.
This class is a composition of two QSettings instances:
Definition qgssettings.h:64
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 QgsDebugError(str)
Definition qgslogger.h:38