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