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