29#include <QDialogButtonBox>
36#include "moc_qgsauthsslerrorsdialog.cpp"
38using namespace Qt::StringLiterals;
42 , mSslConfiguration( reply->sslConfiguration() )
43 , mSslErrors( sslErrors )
45 , mHostPort( hostport )
47 if ( mDigest.isEmpty() )
49 mDigest = QgsAuthCertUtils::shaHexForCert( mSslConfiguration.peerCertificate() );
51 if ( mHostPort.isEmpty() )
53 mHostPort = u
"%1:%2"_s
54 .arg( reply->url().host() )
55 .arg( reply->url().port() != -1 ? reply->url().port() : 443 )
60 connect( buttonBox, &QDialogButtonBox::clicked,
this, &QgsAuthSslErrorsDialog::buttonBox_clicked );
61 connect( btnChainInfo, &QToolButton::clicked,
this, &QgsAuthSslErrorsDialog::btnChainInfo_clicked );
62 connect( btnChainCAs, &QToolButton::clicked,
this, &QgsAuthSslErrorsDialog::btnChainCAs_clicked );
64 QStyle *style = QApplication::style();
65 lblWarningIcon->setPixmap( style->standardIcon( QStyle::SP_MessageBoxWarning ).pixmap( 48, 48 ) );
66 lblWarningIcon->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
68 lblErrorsText->setStyleSheet( u
"QLabel{ font-weight: bold; }"_s );
69 leUrl->setText( reply->request().url().toString() );
71 ignoreButton()->setDefault(
false );
72 abortButton()->setDefault(
true );
76 saveButton()->setEnabled(
false );
78 saveButton()->setText( u
"%1 && %2"_s.arg( saveButton()->text(), ignoreButton()->text() ) );
80 grpbxSslConfig->setChecked(
false );
81 grpbxSslConfig->setCollapsed(
true );
82 connect( grpbxSslConfig, &QGroupBox::toggled,
this, &QgsAuthSslErrorsDialog::loadUnloadCertificate );
85 wdgtSslConfig->setConfigCheckable(
false );
86 wdgtSslConfig->certificateGroupBox()->setFlat(
true );
90 btnChainInfo->setVisible(
false );
91 btnChainCAs->setVisible(
false );
92 grpbxSslConfig->setVisible(
false );
93 saveButton()->setVisible(
false );
99void QgsAuthSslErrorsDialog::loadUnloadCertificate(
bool load )
101 grpbxSslErrors->setCollapsed( load );
105 clearCertificateConfig();
108 wdgtSslConfig->setEnabled(
true );
109 QgsDebugMsgLevel( u
"Loading certificate for host:port = %1"_s.arg( mHostPort ), 2 );
110 wdgtSslConfig->setSslCertificate( mSslConfiguration.peerCertificate(), mHostPort );
111 if ( !mSslErrors.isEmpty() )
113 wdgtSslConfig->appendSslIgnoreErrors( mSslErrors );
117void QgsAuthSslErrorsDialog::showCertificateChainInfo()
119 QList<QSslCertificate> peerchain( mSslConfiguration.peerCertificateChain() );
121 if ( !peerchain.isEmpty() )
123 const QSslCertificate cert = peerchain.takeFirst();
124 if ( !cert.isNull() )
126 QgsAuthCertInfoDialog *dlg =
new QgsAuthCertInfoDialog( cert,
false,
this, peerchain );
127 dlg->setWindowModality( Qt::WindowModal );
128 dlg->resize( 675, 500 );
135void QgsAuthSslErrorsDialog::showCertificateChainCAsInfo()
137 const QList<QSslCertificate> certificates = mSslConfiguration.caCertificates();
138 for (
const auto &cert : certificates )
140 qDebug() << cert.subjectInfo( QSslCertificate::SubjectInfo::CommonName );
143 QgsAuthTrustedCAsDialog *dlg =
new QgsAuthTrustedCAsDialog(
this, mSslConfiguration.caCertificates() );
144 dlg->setWindowModality( Qt::WindowModal );
145 dlg->resize( 675, 500 );
150void QgsAuthSslErrorsDialog::widgetReadyToSaveChanged(
bool cansave )
152 ignoreButton()->setDefault(
false );
153 abortButton()->setDefault( !cansave );
154 saveButton()->setEnabled( cansave );
155 saveButton()->setDefault( cansave );
158void QgsAuthSslErrorsDialog::checkCanSave()
160 widgetReadyToSaveChanged( wdgtSslConfig->readyToSave() );
163void QgsAuthSslErrorsDialog::clearCertificateConfig()
165 wdgtSslConfig->resetSslCertConfig();
166 wdgtSslConfig->setEnabled(
false );
170void QgsAuthSslErrorsDialog::buttonBox_clicked( QAbstractButton *button )
172 const QDialogButtonBox::StandardButton btnenum( buttonBox->standardButton( button ) );
175 case QDialogButtonBox::Ignore:
177 u
"%1:%2"_s.arg( mDigest, mHostPort ),
182 case QDialogButtonBox::Save:
184 wdgtSslConfig->saveSslCertConfig();
187 case QDialogButtonBox::Abort:
194 if ( btnenum == QDialogButtonBox::Abort && QgsSettings().value( u
"clear_auth_cache_on_errors"_s,
true,
QgsSettings::Section::Auth ).toBool() )
200void QgsAuthSslErrorsDialog::populateErrorsList()
203 errs.reserve( mSslErrors.size() );
204 const auto constMSslErrors = mSslErrors;
205 for (
const QSslError &err : constMSslErrors )
207 errs << u
"* %1: %2"_s
208 .arg( QgsAuthCertUtils::sslErrorEnumString( err.error() ), err.errorString() );
210 teSslErrors->setPlainText( errs.join( QLatin1Char(
'\n' ) ) );
213QPushButton *QgsAuthSslErrorsDialog::ignoreButton()
215 return buttonBox->button( QDialogButtonBox::Ignore );
218QPushButton *QgsAuthSslErrorsDialog::saveButton()
220 return buttonBox->button( QDialogButtonBox::Save );
223QPushButton *QgsAuthSslErrorsDialog::abortButton()
225 return buttonBox->button( QDialogButtonBox::Abort );
228void QgsAuthSslErrorsDialog::btnChainInfo_clicked()
230 showCertificateChainInfo();
233void QgsAuthSslErrorsDialog::btnChainCAs_clicked()
235 showCertificateChainCAsInfo();
238void QgsAuthSslErrorsDialog::grpbxSslErrors_collapsedStateChanged(
bool collapsed )
242 btnChainInfo->setVisible(
false );
243 btnChainCAs->setVisible(
false );
static QgsAuthManager * authManager()
Returns the application's authentication manager instance.
bool updateIgnoredSslErrorsCache(const QString &shahostport, const QList< QSslError > &errors)
Update ignored SSL error cache with possible ignored SSL errors, using sha:host:port key.
QgsAuthSslErrorsDialog(QNetworkReply *reply, const QList< QSslError > &sslErrors, QWidget *parent=nullptr, const QString &digest=QString(), const QString &hostport=QString())
Construct a dialog to handle SSL errors and saving SSL server certificate exceptions.
void collapsedStateChanged(bool collapsed)
Signal emitted when groupbox collapsed/expanded state is changed, and when first shown.
static QgsNetworkAccessManager * instance(Qt::ConnectionType connectionType=Qt::BlockingQueuedConnection)
Returns a pointer to the active QgsNetworkAccessManager for the current thread.
#define QgsDebugMsgLevel(str, level)