QGIS API Documentation  2.18.21-Las Palmas (9fba24a)
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 "ui_qgsauthtrustedcasdialog.h"
19 
20 #include <QPushButton>
21 #include <QSettings>
22 
23 #include "qgsapplication.h"
24 #include "qgsauthcertificateinfo.h"
25 #include "qgsauthguiutils.h"
26 #include "qgsauthmanager.h"
27 #include "qgslogger.h"
28 
29 
31  const QList<QSslCertificate>& trustedCAs )
32  : QDialog( parent )
33  , mTrustedCAs( trustedCAs )
34  , mDisabled( false )
35  , mAuthNotifyLayout( nullptr )
36  , mAuthNotify( nullptr )
37  , mRootCaSecItem( nullptr )
38 {
39  if ( QgsAuthManager::instance()->isDisabled() )
40  {
41  mDisabled = true;
42  mAuthNotifyLayout = new QVBoxLayout;
43  this->setLayout( mAuthNotifyLayout );
44  mAuthNotify = new QLabel( QgsAuthManager::instance()->disabledMessage(), this );
45  mAuthNotifyLayout->addWidget( mAuthNotify );
46  }
47  else
48  {
49  setupUi( this );
50 
51  connect( QgsAuthManager::instance(), SIGNAL( messageOut( const QString&, const QString&, QgsAuthManager::MessageLevel ) ),
52  this, SLOT( authMessageOut( const QString&, const QString&, QgsAuthManager::MessageLevel ) ) );
53 
54  setupCaCertsTree();
55 
56  connect( treeTrustedCAs->selectionModel(), SIGNAL( selectionChanged( const QItemSelection&, const QItemSelection& ) ),
57  this, SLOT( selectionChanged( const QItemSelection&, const QItemSelection& ) ) );
58 
59  connect( treeTrustedCAs, SIGNAL( itemDoubleClicked( QTreeWidgetItem *, int ) ),
60  this, SLOT( handleDoubleClick( QTreeWidgetItem *, int ) ) );
61 
62 
63  btnGroupByOrg->setChecked( false );
64  QVariant sortbyval = QgsAuthManager::instance()->getAuthSetting( QString( "trustedcasortby" ), QVariant( false ) );
65  if ( !sortbyval.isNull() )
66  btnGroupByOrg->setChecked( sortbyval.toBool() );
67 
68  populateCaCertsView();
69  checkSelection();
70  }
71 }
72 
74 {
75 }
76 
77 static void setItemBold_( QTreeWidgetItem* item )
78 {
79  item->setFirstColumnSpanned( true );
80  QFont secf( item->font( 0 ) );
81  secf.setBold( true );
82  item->setFont( 0, secf );
83 }
84 
85 void QgsAuthTrustedCAsDialog::setupCaCertsTree()
86 {
87  treeTrustedCAs->setColumnCount( 3 );
88  treeTrustedCAs->setHeaderLabels(
89  QStringList() << tr( "Common Name" )
90  << tr( "Serial #" )
91  << tr( "Expiry Date" ) );
92  treeTrustedCAs->setColumnWidth( 0, 300 );
93  treeTrustedCAs->setColumnWidth( 1, 75 );
94 
95  // add root section
96  mRootCaSecItem = new QTreeWidgetItem(
97  treeTrustedCAs,
98  QStringList( tr( "Authorities/Issuers" ) ),
99  ( int )QgsAuthTrustedCAsDialog::Section );
100  setItemBold_( mRootCaSecItem );
101  mRootCaSecItem->setFlags( Qt::ItemIsEnabled );
102  mRootCaSecItem->setExpanded( true );
103  treeTrustedCAs->insertTopLevelItem( 0, mRootCaSecItem );
104 }
105 
106 static void removeChildren_( QTreeWidgetItem* item )
107 {
108  Q_FOREACH ( QTreeWidgetItem* child, item->takeChildren() )
109  {
110  delete child;
111  }
112 }
113 
114 void QgsAuthTrustedCAsDialog::populateCaCertsView()
115 {
116  removeChildren_( mRootCaSecItem );
117 
118  if ( mTrustedCAs.isEmpty() )
119  {
120  mTrustedCAs = QgsAuthManager::instance()->getTrustedCaCerts();
121  }
122 
123  populateCaCertsSection( mRootCaSecItem, mTrustedCAs, QgsAuthTrustedCAsDialog::CaCert );
124 }
125 
126 void QgsAuthTrustedCAsDialog::populateCaCertsSection( QTreeWidgetItem* item, const QList<QSslCertificate>& certs,
127  QgsAuthTrustedCAsDialog::CaType catype )
128 {
129  if ( btnGroupByOrg->isChecked() )
130  {
131  appendCertsToGroup( certs, catype, item );
132  }
133  else
134  {
135  appendCertsToItem( certs, catype, item );
136  }
137 }
138 
139 void QgsAuthTrustedCAsDialog::appendCertsToGroup( const QList<QSslCertificate>& certs,
140  QgsAuthTrustedCAsDialog::CaType catype,
142 {
143  if ( certs.size() < 1 )
144  return;
145 
146  if ( !parent )
147  {
148  parent = treeTrustedCAs->currentItem();
149  }
150 
151  // TODO: find all organizational name, sort and make subsections
154 
155  QMap< QString, QList<QSslCertificate> >::const_iterator it = orgcerts.constBegin();
156  for ( ; it != orgcerts.constEnd(); ++it )
157  {
158  QTreeWidgetItem * grpitem( new QTreeWidgetItem( parent,
159  QStringList() << it.key(),
160  ( int )QgsAuthTrustedCAsDialog::OrgName ) );
161  grpitem->setFirstColumnSpanned( true );
162  grpitem->setFlags( Qt::ItemIsEnabled );
163  grpitem->setExpanded( true );
164 
165  QBrush orgb( grpitem->foreground( 0 ) );
166  orgb.setColor( QColor::fromRgb( 90, 90, 90 ) );
167  grpitem->setForeground( 0, orgb );
168  QFont grpf( grpitem->font( 0 ) );
169  grpf.setItalic( true );
170  grpitem->setFont( 0, grpf );
171 
172  appendCertsToItem( it.value(), catype, grpitem );
173  }
174 
175  parent->sortChildren( 0, Qt::AscendingOrder );
176 }
177 
178 void QgsAuthTrustedCAsDialog::appendCertsToItem( const QList<QSslCertificate>& certs,
179  QgsAuthTrustedCAsDialog::CaType catype,
180  QTreeWidgetItem *parent )
181 {
182  if ( certs.size() < 1 )
183  return;
184 
185  if ( !parent )
186  {
187  parent = treeTrustedCAs->currentItem();
188  }
189 
191 
192  // Columns: Common Name, Serial #, Expiry Date
193  Q_FOREACH ( const QSslCertificate& cert, certs )
194  {
196 
197  QStringList coltxts;
198  coltxts << QgsAuthCertUtils::resolvedCertName( cert );
199  coltxts << QString( cert.serialNumber() );
200  coltxts << cert.expiryDate().toString();
201 
202  QTreeWidgetItem * item( new QTreeWidgetItem( parent, coltxts, ( int )catype ) );
203 
204  item->setIcon( 0, QgsApplication::getThemeIcon( "/mIconCertificate.svg" ) );
205  if ( !cert.isValid() )
206  {
207  item->setForeground( 2, redb );
208  item->setIcon( 0, QgsApplication::getThemeIcon( "/mIconCertificateUntrusted.svg" ) );
209  }
210 
211  item->setData( 0, Qt::UserRole, id );
212  }
213 
214  parent->sortChildren( 0, Qt::AscendingOrder );
215 }
216 
217 void QgsAuthTrustedCAsDialog::showCertInfo( QTreeWidgetItem *item )
218 {
219  if ( !item )
220  return;
221 
222  QString digest( item->data( 0, Qt::UserRole ).toString() );
223 
225  QgsAuthManager::instance()->getCaCertsCache() );
226 
227  if ( !cacertscache.contains( digest ) )
228  {
229  QgsDebugMsg( "Certificate Authority not in CA certs cache" );
230  return;
231  }
232 
233  QSslCertificate cert( cacertscache.value( digest ).second );
234 
235  QgsAuthCertInfoDialog * dlg = new QgsAuthCertInfoDialog( cert, false, this );
236  dlg->setWindowModality( Qt::WindowModal );
237  dlg->resize( 675, 500 );
238  dlg->exec();
239  dlg->deleteLater();
240 }
241 
242 void QgsAuthTrustedCAsDialog::selectionChanged( const QItemSelection& selected , const QItemSelection& deselected )
243 {
244  Q_UNUSED( selected );
245  Q_UNUSED( deselected );
246  checkSelection();
247 }
248 
249 void QgsAuthTrustedCAsDialog::checkSelection()
250 {
251  bool iscert = false;
252  if ( treeTrustedCAs->selectionModel()->selection().length() > 0 )
253  {
254  QTreeWidgetItem* item( treeTrustedCAs->currentItem() );
255 
256  switch (( QgsAuthTrustedCAsDialog::CaType )item->type() )
257  {
258  case QgsAuthTrustedCAsDialog::CaCert:
259  iscert = true;
260  break;
261  default:
262  break;
263  }
264  }
265 
266  btnInfoCa->setEnabled( iscert );
267 }
268 
269 void QgsAuthTrustedCAsDialog::handleDoubleClick( QTreeWidgetItem *item, int col )
270 {
271  Q_UNUSED( col );
272  bool iscert = true;
273 
274  switch (( QgsAuthTrustedCAsDialog::CaType )item->type() )
275  {
276  case QgsAuthTrustedCAsDialog::Section:
277  iscert = false;
278  break;
279  case QgsAuthTrustedCAsDialog::OrgName:
280  iscert = false;
281  break;
282  default:
283  break;
284  }
285 
286  if ( iscert )
287  {
288  showCertInfo( item );
289  }
290 }
291 
292 void QgsAuthTrustedCAsDialog::on_btnInfoCa_clicked()
293 {
294  if ( treeTrustedCAs->selectionModel()->selection().length() > 0 )
295  {
296  QTreeWidgetItem* item( treeTrustedCAs->currentItem() );
297  handleDoubleClick( item, 0 );
298  }
299 }
300 
301 void QgsAuthTrustedCAsDialog::on_btnGroupByOrg_toggled( bool checked )
302 {
303  if ( !QgsAuthManager::instance()->storeAuthSetting( QString( "trustedcasortby" ), QVariant( checked ) ) )
304  {
305  authMessageOut( QObject::tr( "Could not store sort by preference" ),
306  QObject::tr( "Trusted Authorities/Issuers" ),
308  }
309  populateCaCertsView();
310 }
311 
312 void QgsAuthTrustedCAsDialog::authMessageOut( const QString& message, const QString& authtag, QgsAuthManager::MessageLevel level )
313 {
314  int levelint = ( int )level;
315  messageBar()->pushMessage( authtag, message, ( QgsMessageBar::MessageLevel )levelint, 7 );
316 }
317 
319 {
320  if ( !mDisabled )
321  {
322  treeTrustedCAs->setFocus();
323  }
324  QWidget::showEvent( e );
325 }
326 
327 QgsMessageBar * QgsAuthTrustedCAsDialog::messageBar()
328 {
329  return msgBar;
330 }
331 
332 int QgsAuthTrustedCAsDialog::messageTimeout()
333 {
334  QSettings settings;
335  return settings.value( "/qgis/messageTimeout", 5 ).toInt();
336 }
QObject * child(const char *objName, const char *inheritsClass, bool recursiveSearch) const
QString toString(Qt::DateFormat format) const
void setupUi(QWidget *widget)
static QgsAuthManager * instance()
Enforce singleton pattern.
static void setItemBold_(QTreeWidgetItem *item)
bool isValid() const
#define QgsDebugMsg(str)
Definition: qgslogger.h:33
void setFont(int column, const QFont &font)
static QIcon getThemeIcon(const QString &theName)
Helper to get a theme icon.
const_iterator constBegin() const
void setIcon(int column, const QIcon &icon)
A bar for displaying non-blocking messages to the user.
Definition: qgsmessagebar.h:42
void showEvent(QShowEvent *e) override
Overridden widget show event.
void setFirstColumnSpanned(bool span)
virtual void setData(int column, int role, const QVariant &value)
virtual QVariant data(int column, int role) const
QString tr(const char *sourceText, const char *disambiguation, int n)
MessageLevel
Message log level (mirrors that of QgsMessageLog, so it can also output there)
int size() const
QVariant getAuthSetting(const QString &key, const QVariant &defaultValue=QVariant(), bool decrypt=false)
Get an authentication setting (retrieved as string and returned as QVariant( QString )) ...
void sortChildren(int column, Qt::SortOrder order)
void setBold(bool enable)
void setFlags(QFlags< Qt::ItemFlag > flags)
QColor fromRgb(QRgb rgb)
void pushMessage(const QString &text, MessageLevel level=INFO, int duration=5)
convenience method for pushing a message to the bar
Definition: qgsmessagebar.h:90
void addWidget(QWidget *widget, int stretch, QFlags< Qt::AlignmentFlag > alignment)
virtual void showEvent(QShowEvent *event)
static QColor redColor()
Red color representing invalid, untrusted, etc.
Dialog wrapper for widget displaying detailed info on a certificate and its hierarchical trust chain...
void setLayout(QLayout *layout)
int toInt(bool *ok) const
bool isNull() const
QgsAuthTrustedCAsDialog(QWidget *parent=nullptr, const QList< QSslCertificate > &trustedCAs=QList< QSslCertificate >())
Construct a dialog that will list the trusted Certificate Authorities.
QList< QTreeWidgetItem * > takeChildren()
bool isEmpty() const
const_iterator constEnd() const
QFont font(int column) const
const QList< QSslCertificate > getTrustedCaCerts(bool includeinvalid=false)
Get list of all trusted CA certificates.
void setItalic(bool enable)
const Key key(const T &value) const
static QString shaHexForCert(const QSslCertificate &cert, bool formatted=false)
Get the sha1 hash for certificate.
QVariant value(const QString &key, const QVariant &defaultValue) const
QByteArray serialNumber() const
void setExpanded(bool expand)
QDateTime expiryDate() const
bool toBool() const
static QMap< QString, QList< QSslCertificate > > certsGroupedByOrg(const QList< QSslCertificate > &certs)
Map certificates to their oraganization.
int type() const
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
static void removeChildren_(QTreeWidgetItem *item)
QObject * parent() const
void setColor(const QColor &color)
QString toString() const
static QString resolvedCertName(const QSslCertificate &cert, bool issuer=false)
Get the general name via RFC 5280 resolution.
void setForeground(int column, const QBrush &brush)
const T value(const Key &key) const