QGIS API Documentation  3.21.0-Master (5b68dc587e)
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( QString() );
151 
152  bool valid = false;
153  QList<QSslCertificate> certs;
154  QList<QSslCertificate> nixcerts;
155  int validcerts = 0;
156  const bool allowinvalid = chkAllowInvalid->isChecked();
157  const 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  const int certssize = certs.size();
170 
171  const auto constCerts = certs;
172  for ( const QSslCertificate &cert : constCerts )
173  {
174  if ( QgsAuthCertUtils::certIsViable( cert ) )
175  ++validcerts;
176 
177  if ( filterCAs )
178  {
180  {
181  ++cas;
182  }
183  else
184  {
185  nixcerts << cert;
186  }
187  }
188  }
189 
190  valid = ( certssize > 0
191  && ( allowinvalid || certssize == validcerts )
192  && ( !filterCAs || nixcerts.size() < certssize ) );
193 
194  if ( !nixcerts.isEmpty() )
195  {
196  const auto constNixcerts = nixcerts;
197  for ( const QSslCertificate &nixcert : constNixcerts )
198  {
199  certs.removeOne( nixcert );
200  }
201  }
202 
203  if ( valid )
204  mCerts = certs;
205 
206  if ( certssize > 0 )
207  {
208  teValidation->setStyleSheet(
209  valid ? QgsAuthGuiUtils::greenTextStyleSheet( QStringLiteral( "QTextEdit" ) )
210  : QgsAuthGuiUtils::redTextStyleSheet( QStringLiteral( "QTextEdit" ) ) );
211  }
212 
213  QString msg = tr( "Certificates found: %1\n"
214  "Certificates valid: %2" ).arg( certssize ).arg( validcerts );
215 
216  if ( filterCAs )
217  {
218  msg += tr( "\nAuthorities/Issuers: %1%2" ).arg( cas )
219  .arg( !nixcerts.isEmpty() && nixcerts.size() < certssize ? " (others not imported)" : "" );
220  }
221 
222  teValidation->setText( msg );
223 
224  okButton()->setEnabled( valid );
225 }
226 
227 void QgsAuthImportCertDialog::btnImportFile_clicked()
228 {
229  const QString &fn = getOpenFileName( tr( "Open Certificate File" ), tr( "All files (*.*);;PEM (*.pem);;DER (*.der)" ) );
230  if ( !fn.isEmpty() )
231  {
232  leImportFile->setText( fn );
233  }
234  validateCertificates();
235 }
236 
237 void QgsAuthImportCertDialog::chkAllowInvalid_toggled( bool checked )
238 {
239  Q_UNUSED( checked )
240  validateCertificates();
241 }
242 
243 QString QgsAuthImportCertDialog::getOpenFileName( const QString &title, const QString &extfilter )
244 {
245  QgsSettings settings;
246  const QString recentdir = settings.value( QStringLiteral( "UI/lastAuthImportCertOpenFileDir" ), QDir::homePath() ).toString();
247  QString f = QFileDialog::getOpenFileName( this, title, recentdir, extfilter );
248 
249  // return dialog focus on Mac
250  this->raise();
251  this->activateWindow();
252 
253  if ( !f.isEmpty() )
254  {
255  settings.setValue( QStringLiteral( "UI/lastAuthImportCertOpenFileDir" ), QFileInfo( f ).absoluteDir().path() );
256  }
257  return f;
258 }
259 
260 QPushButton *QgsAuthImportCertDialog::okButton()
261 {
262  return buttonBox->button( QDialogButtonBox::Ok );
263 }
static QgsAuthManager * authManager()
Returns the application's authentication manager instance.
CertTrustPolicy
Type of certificate trust policy.
static bool certIsViable(const QSslCertificate &cert)
certIsViable checks for viability errors of cert and whether it is NULL
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.
static QList< QSslCertificate > certsFromString(const QString &pemtext)
Returns a list of concatenated certs from a PEM Base64 text block.
static QString greenTextStyleSheet(const QString &selector="*")
Green text stylesheet representing valid, trusted, etc. certificate.
static QString redTextStyleSheet(const QString &selector="*")
Red text stylesheet representing invalid, untrusted, etc. certificate.
QgsAuthCertUtils::CertTrustPolicy certTrustPolicy()
Defined trust policy for imported certificates.
const QString certFileToImport()
Gets the file path to a certificate to import.
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.
const QList< QSslCertificate > certificatesToImport()
Gets list of certificate objects to import.
const QString certTextToImport()
Gets certificate text to import.
CertInput
Type of inputs for certificates.
bool allowInvalidCerts()
Whether to allow importation of invalid certificates (so trust policy can be overridden)