QGIS API Documentation  2.14.0-Essen
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 #include <QSettings>
24 
25 #include <QtCrypto>
26 
27 #include "qgsauthcertutils.h"
28 #include "qgsauthguiutils.h"
29 #include "qgsauthmanager.h"
30 
31 
35  : QDialog( parent )
36  , mFilter( filter )
37  , mInput( input )
38  , mDisabled( false )
39  , mAuthNotifyLayout( nullptr )
40  , mAuthNotify( nullptr )
41 {
42  if ( QgsAuthManager::instance()->isDisabled() )
43  {
44  mDisabled = true;
45  mAuthNotifyLayout = new QVBoxLayout;
46  this->setLayout( mAuthNotifyLayout );
47  mAuthNotify = new QLabel( QgsAuthManager::instance()->disabledMessage(), this );
48  mAuthNotifyLayout->addWidget( mAuthNotify );
49  }
50  else
51  {
52  setupUi( this );
53 
54  connect( buttonBox, SIGNAL( accepted() ), this, SLOT( accept() ) );
55  connect( buttonBox, SIGNAL( rejected() ), this, SLOT( reject() ) );
56 
57  connect( teCertText, SIGNAL( textChanged() ), this, SLOT( validateCertificates() ) );
58 
59  connect( radioImportFile, SIGNAL( toggled( bool ) ), this, SLOT( updateGui() ) );
60  connect( radioImportText, SIGNAL( toggled( bool ) ), this, SLOT( 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 
89 {
90 }
91 
93 {
94  if ( mDisabled )
95  {
96  return QList<QSslCertificate>();
97  }
98  return mCerts;
99 }
100 
102 {
103  if ( mDisabled )
104  {
105  return QString();
106  }
107  if ( !radioImportFile->isChecked() )
108  return QString();
109 
110  return leImportFile->text();
111 }
112 
114 {
115  if ( mDisabled )
116  {
117  return QString();
118  }
119  if ( !radioImportText->isChecked() )
120  return QString();
121 
122  return teCertText->toPlainText().trimmed();
123 }
124 
126 {
127  if ( mDisabled )
128  {
129  return false;
130  }
131  return chkAllowInvalid->isChecked();
132 }
133 
135 {
136  if ( mDisabled )
137  {
139  }
140  return cmbbxTrust->trustPolicy();
141 }
142 
143 void QgsAuthImportCertDialog::updateGui()
144 {
145  frameImportFile->setEnabled( radioImportFile->isChecked() );
146  teCertText->setEnabled( radioImportText->isChecked() );
147  validateCertificates();
148 }
149 
150 void QgsAuthImportCertDialog::validateCertificates()
151 {
152  mCerts.clear();
153  teValidation->clear();
154  teValidation->setStyleSheet( "" );
155 
156  bool valid = false;
158  QList<QSslCertificate> nixcerts;
159  int validcerts = 0;
160  bool allowinvalid = chkAllowInvalid->isChecked();
161  bool filterCAs = ( mFilter == CaFilter );
162  int cas = 0;
163 
164  if ( radioImportFile->isChecked() && !leImportFile->text().isEmpty() )
165  {
166  certs = QgsAuthCertUtils::certsFromFile( leImportFile->text() );
167  }
168  else if ( radioImportText->isChecked() && !teCertText->toPlainText().trimmed().isEmpty() )
169  {
170  certs = QgsAuthCertUtils::certsFromString( teCertText->toPlainText().trimmed() );
171  }
172 
173  int certssize = certs.size();
174 
175  Q_FOREACH ( const QSslCertificate &cert, certs )
176  {
177  if ( cert.isValid() )
178  ++validcerts;
179 
180  if ( filterCAs )
181  {
183  {
184  ++cas;
185  }
186  else
187  {
188  nixcerts << cert;
189  }
190  }
191  }
192 
193  valid = ( certssize > 0
194  && ( allowinvalid || certssize == validcerts )
195  && ( !filterCAs || nixcerts.size() < certssize ) );
196 
197  if ( !nixcerts.isEmpty() )
198  {
199  Q_FOREACH ( const QSslCertificate &nixcert, nixcerts )
200  {
201  certs.removeOne( nixcert );
202  }
203  }
204 
205  if ( valid )
206  mCerts = certs;
207 
208  if ( certssize > 0 )
209  {
210  teValidation->setStyleSheet(
211  valid ? QgsAuthGuiUtils::greenTextStyleSheet( "QTextEdit" )
212  : QgsAuthGuiUtils::redTextStyleSheet( "QTextEdit" ) );
213  }
214 
215  QString msg = tr( "Certificates found: %1\n"
216  "Certificates valid: %2" ).arg( certssize ).arg( validcerts );
217 
218  if ( filterCAs )
219  {
220  msg += tr( "\nAuthorities/Issuers: %1%2" ).arg( cas )
221  .arg( !nixcerts.isEmpty() && nixcerts.size() < certssize ? " (others not imported)" : "" );
222  }
223 
224  teValidation->setText( msg );
225 
226  okButton()->setEnabled( valid );
227 }
228 
229 void QgsAuthImportCertDialog::on_btnImportFile_clicked()
230 {
231  const QString& fn = getOpenFileName( tr( "Open Certificate File" ), tr( "PEM (*.pem);;DER (*.der)" ) );
232  if ( !fn.isEmpty() )
233  {
234  leImportFile->setText( fn );
235  }
236  validateCertificates();
237 }
238 
239 void QgsAuthImportCertDialog::on_chkAllowInvalid_toggled( bool checked )
240 {
241  Q_UNUSED( checked );
242  validateCertificates();
243 }
244 
245 QString QgsAuthImportCertDialog::getOpenFileName( const QString &title, const QString &extfilter )
246 {
247  QSettings settings;
248  QString recentdir = settings.value( "UI/lastAuthImportCertOpenFileDir", QDir::homePath() ).toString();
249  QString f = QFileDialog::getOpenFileName( this, title, recentdir, extfilter );
250 
251  // return dialog focus on Mac
252  this->raise();
253  this->activateWindow();
254 
255  if ( !f.isEmpty() )
256  {
257  settings.setValue( "UI/lastAuthImportCertOpenFileDir", QFileInfo( f ).absoluteDir().path() );
258  }
259  return f;
260 }
261 
262 QPushButton* QgsAuthImportCertDialog::okButton()
263 {
264  return buttonBox->button( QDialogButtonBox::Ok );
265 }
void clear()
void setupUi(QWidget *widget)
virtual void reject()
static QgsAuthManager * instance()
Enforce singleton pattern.
bool isValid() const
const QString certTextToImport()
Get certificate text to import.
void rejected()
static QList< QSslCertificate > certsFromFile(const QString &certspath)
Return list of concatenated certs from a PEM or DER formatted file.
void accepted()
static bool certificateIsAuthorityOrIssuer(const QSslCertificate &cert)
Get 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()
Get the file path to a certificate to import.
QString homePath()
QString tr(const char *sourceText, const char *disambiguation, int n)
int size() const
CertInput
Type of inputs for certificates.
void setValue(const QString &key, const QVariant &value)
QgsAuthCertUtils::CertTrustPolicy certTrustPolicy()
Defined trust policy for imported certificates.
void setEnabled(bool)
void addWidget(QWidget *widget, int stretch, QFlags< Qt::AlignmentFlag > alignment)
void setLayout(QLayout *layout)
static QString greenTextStyleSheet(const QString &selector="*")
Green text stylesheet representing valid, trusted, etc.
bool isEmpty() const
bool isEmpty() const
QString trimmed() const
virtual void accept()
static QList< QSslCertificate > certsFromString(const QString &pemtext)
Return list of concatenated certs from a PEM Base64 text block.
const QList< QSslCertificate > certificatesToImport()
Get list of certificate objects to import.
static QString redTextStyleSheet(const QString &selector="*")
Red text stylesheet representing invalid, untrusted, etc.
QVariant value(const QString &key, const QVariant &defaultValue) const
void activateWindow()
void setText(const QString &text)
CertTrustPolicy
Type of certificate trust policy.
QString getOpenFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFlags< QFileDialog::Option > options)
CertFilter
Type of filter to apply to dialog.
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QgsAuthImportCertDialog(QWidget *parent=nullptr, QgsAuthImportCertDialog::CertFilter filter=NoFilter, QgsAuthImportCertDialog::CertInput input=AllInputs)
Construct a dialog for importing certificates.
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
QString toString() const
bool removeOne(const T &value)