QGIS API Documentation  3.2.0-Bonn (bc43194)
qgsauthimportcertdialog.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsauthimportcertdialog.cpp
3  ---------------------
4  begin : April 30, 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 
19 #include <QDir>
20 #include <QFileDialog>
21 #include <QFileInfo>
22 #include <QPushButton>
23 
24 #include <QtCrypto>
25 
26 #include "qgssettings.h"
27 #include "qgsauthcertutils.h"
28 #include "qgsauthguiutils.h"
29 #include "qgsauthmanager.h"
30 #include "qgsapplication.h"
31 
32 
36  : QDialog( parent )
37  , mFilter( filter )
38  , mInput( input )
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( btnImportFile, &QToolButton::clicked, this, &QgsAuthImportCertDialog::btnImportFile_clicked );
52  connect( chkAllowInvalid, &QCheckBox::toggled, this, &QgsAuthImportCertDialog::chkAllowInvalid_toggled );
53 
54  connect( buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept );
55  connect( buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject );
56 
57  connect( teCertText, &QPlainTextEdit::textChanged, this, &QgsAuthImportCertDialog::validateCertificates );
58 
59  connect( radioImportFile, &QAbstractButton::toggled, this, &QgsAuthImportCertDialog::updateGui );
60  connect( radioImportText, &QAbstractButton::toggled, this, &QgsAuthImportCertDialog::updateGui );
61 
62  // hide unused widgets
63  if ( mInput == FileInput )
64  {
65  radioImportText->setHidden( true );
66  teCertText->setHidden( true );
67  }
68  else if ( mInput == TextInput )
69  {
70  radioImportFile->setHidden( true );
71  frameImportFile->setHidden( true );
72  }
73 
74  radioImportFile->setChecked( true );
75  updateGui();
76 
77  if ( mFilter == CaFilter )
78  {
79  grpbxImportCert->setTitle( tr( "Import Certificate Authorities" ) );
80  }
81 
82  okButton()->setText( tr( "Import" ) );
83  okButton()->setEnabled( false );
84  teValidation->setFocus();
85  }
86 }
87 
88 const QList<QSslCertificate> QgsAuthImportCertDialog::certificatesToImport()
89 {
90  if ( mDisabled )
91  {
92  return QList<QSslCertificate>();
93  }
94  return mCerts;
95 }
96 
98 {
99  if ( mDisabled )
100  {
101  return QString();
102  }
103  if ( !radioImportFile->isChecked() )
104  return QString();
105 
106  return leImportFile->text();
107 }
108 
110 {
111  if ( mDisabled )
112  {
113  return QString();
114  }
115  if ( !radioImportText->isChecked() )
116  return QString();
117 
118  return teCertText->toPlainText().trimmed();
119 }
120 
122 {
123  if ( mDisabled )
124  {
125  return false;
126  }
127  return chkAllowInvalid->isChecked();
128 }
129 
131 {
132  if ( mDisabled )
133  {
135  }
136  return cmbbxTrust->trustPolicy();
137 }
138 
139 void QgsAuthImportCertDialog::updateGui()
140 {
141  frameImportFile->setEnabled( radioImportFile->isChecked() );
142  teCertText->setEnabled( radioImportText->isChecked() );
143  validateCertificates();
144 }
145 
146 void QgsAuthImportCertDialog::validateCertificates()
147 {
148  mCerts.clear();
149  teValidation->clear();
150  teValidation->setStyleSheet( QLatin1String( "" ) );
151 
152  bool valid = false;
153  QList<QSslCertificate> certs;
154  QList<QSslCertificate> nixcerts;
155  int validcerts = 0;
156  bool allowinvalid = chkAllowInvalid->isChecked();
157  bool filterCAs = ( mFilter == CaFilter );
158  int cas = 0;
159 
160  if ( radioImportFile->isChecked() && !leImportFile->text().isEmpty() )
161  {
162  certs = QgsAuthCertUtils::certsFromFile( leImportFile->text() );
163  }
164  else if ( radioImportText->isChecked() && !teCertText->toPlainText().trimmed().isEmpty() )
165  {
166  certs = QgsAuthCertUtils::certsFromString( teCertText->toPlainText().trimmed() );
167  }
168 
169  int certssize = certs.size();
170 
171  Q_FOREACH ( const QSslCertificate &cert, certs )
172  {
173  if ( QgsAuthCertUtils::certIsViable( cert ) )
174  ++validcerts;
175 
176  if ( filterCAs )
177  {
179  {
180  ++cas;
181  }
182  else
183  {
184  nixcerts << cert;
185  }
186  }
187  }
188 
189  valid = ( certssize > 0
190  && ( allowinvalid || certssize == validcerts )
191  && ( !filterCAs || nixcerts.size() < certssize ) );
192 
193  if ( !nixcerts.isEmpty() )
194  {
195  Q_FOREACH ( const QSslCertificate &nixcert, nixcerts )
196  {
197  certs.removeOne( nixcert );
198  }
199  }
200 
201  if ( valid )
202  mCerts = certs;
203 
204  if ( certssize > 0 )
205  {
206  teValidation->setStyleSheet(
207  valid ? QgsAuthGuiUtils::greenTextStyleSheet( QStringLiteral( "QTextEdit" ) )
208  : QgsAuthGuiUtils::redTextStyleSheet( QStringLiteral( "QTextEdit" ) ) );
209  }
210 
211  QString msg = tr( "Certificates found: %1\n"
212  "Certificates valid: %2" ).arg( certssize ).arg( validcerts );
213 
214  if ( filterCAs )
215  {
216  msg += tr( "\nAuthorities/Issuers: %1%2" ).arg( cas )
217  .arg( !nixcerts.isEmpty() && nixcerts.size() < certssize ? " (others not imported)" : "" );
218  }
219 
220  teValidation->setText( msg );
221 
222  okButton()->setEnabled( valid );
223 }
224 
225 void QgsAuthImportCertDialog::btnImportFile_clicked()
226 {
227  const QString &fn = getOpenFileName( tr( "Open Certificate File" ), tr( "All files (*.*);;PEM (*.pem);;DER (*.der)" ) );
228  if ( !fn.isEmpty() )
229  {
230  leImportFile->setText( fn );
231  }
232  validateCertificates();
233 }
234 
235 void QgsAuthImportCertDialog::chkAllowInvalid_toggled( bool checked )
236 {
237  Q_UNUSED( checked );
238  validateCertificates();
239 }
240 
241 QString QgsAuthImportCertDialog::getOpenFileName( const QString &title, const QString &extfilter )
242 {
243  QgsSettings settings;
244  QString recentdir = settings.value( QStringLiteral( "UI/lastAuthImportCertOpenFileDir" ), QDir::homePath() ).toString();
245  QString f = QFileDialog::getOpenFileName( this, title, recentdir, extfilter );
246 
247  // return dialog focus on Mac
248  this->raise();
249  this->activateWindow();
250 
251  if ( !f.isEmpty() )
252  {
253  settings.setValue( QStringLiteral( "UI/lastAuthImportCertOpenFileDir" ), QFileInfo( f ).absoluteDir().path() );
254  }
255  return f;
256 }
257 
258 QPushButton *QgsAuthImportCertDialog::okButton()
259 {
260  return buttonBox->button( QDialogButtonBox::Ok );
261 }
This class is a composition of two QSettings instances:
Definition: qgssettings.h:58
const QString certTextToImport()
Gets certificate text to import.
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
static QList< QSslCertificate > certsFromFile(const QString &certspath)
Returns a list of concatenated certs from a PEM or DER formatted file.
static bool certificateIsAuthorityOrIssuer(const QSslCertificate &cert)
Gets whether a certificate is an Authority or can at least sign other certificates.
bool allowInvalidCerts()
Whether to allow importation of invalid certificates (so trust policy can be overridden) ...
const QString certFileToImport()
Gets the file path to a certificate to import.
CertInput
Type of inputs for certificates.
static bool certIsViable(const QSslCertificate &cert)
certIsViable checks for viability errors of cert and whether it is NULL
QgsAuthCertUtils::CertTrustPolicy certTrustPolicy()
Defined trust policy for imported certificates.
static QString greenTextStyleSheet(const QString &selector="*")
Green text stylesheet representing valid, trusted, etc. certificate.
static QList< QSslCertificate > certsFromString(const QString &pemtext)
Returns a list of concatenated certs from a PEM Base64 text block.
const QList< QSslCertificate > certificatesToImport()
Gets list of certificate objects to import.
static QgsAuthManager * authManager()
Returns the application&#39;s authentication manager instance.
static QString redTextStyleSheet(const QString &selector="*")
Red text stylesheet representing invalid, untrusted, etc. certificate.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
CertTrustPolicy
Type of certificate trust policy.
CertFilter
Type of filter to apply to dialog.
QgsAuthImportCertDialog(QWidget *parent=nullptr, QgsAuthImportCertDialog::CertFilter filter=NoFilter, QgsAuthImportCertDialog::CertInput input=AllInputs)
Construct a dialog for importing certificates.