QGIS API Documentation 3.28.0-Firenze (ed3ad0430f)
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
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
139void QgsAuthImportCertDialog::updateGui()
140{
141 frameImportFile->setEnabled( radioImportFile->isChecked() );
142 teCertText->setEnabled( radioImportText->isChecked() );
143 validateCertificates();
144}
145
146void 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
227void 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
237void QgsAuthImportCertDialog::chkAllowInvalid_toggled( bool checked )
238{
239 Q_UNUSED( checked )
240 validateCertificates();
241}
242
243QString 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
260QPushButton *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)
This class is a composition of two QSettings instances:
Definition: qgssettings.h:62
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.