25#include <QDialogButtonBox>
31#include "moc_qgsauthsslconfigwidget.cpp"
33using namespace Qt::StringLiterals;
35static const QString configFoundText_() {
return QObject::tr(
"Configuration loaded from database" ); }
36static const QString configNotFoundText_() {
return QObject::tr(
"Configuration not found in database" ); }
41 , mConnectionCAs( connectionCAs )
46 mAuthNotifyLayout =
new QVBoxLayout;
47 this->setLayout( mAuthNotifyLayout );
49 mAuthNotifyLayout->addWidget( mAuthNotify );
54 connect( btnCertInfo, &QToolButton::clicked,
this, &QgsAuthSslConfigWidget::btnCertInfo_clicked );
62 lblLoadedConfig->setVisible(
false );
63 lblLoadedConfig->clear();
89 return grpbxSslConfig;
93QTreeWidgetItem *QgsAuthSslConfigWidget::addRootItem(
const QString &label )
95 QTreeWidgetItem *item =
new QTreeWidgetItem(
96 QStringList() << label,
97 static_cast<int>( ConfigParent )
100 item->setTextAlignment( 0, Qt::AlignVCenter );
101 item->setFlags( item->flags() & ~Qt::ItemIsSelectable );
102 treeSslConfig->insertTopLevelItem( treeSslConfig->topLevelItemCount(), item );
107void QgsAuthSslConfigWidget::setUpSslConfigTree()
109 treeSslConfig->setColumnCount( 1 );
112 mProtocolItem = addRootItem( tr(
"Protocol" ) );
113 mProtocolCmbBx =
new QComboBox( treeSslConfig );
114 mProtocolCmbBx->addItem( QgsAuthCertUtils::getSslProtocolName( QSsl::SecureProtocols ),
static_cast<int>( QSsl::SecureProtocols ) );
115 mProtocolCmbBx->addItem( QgsAuthCertUtils::getSslProtocolName( QSsl::TlsV1_0 ),
static_cast<int>( QSsl::TlsV1_0 ) );
116 mProtocolCmbBx->setMaximumWidth( 300 );
117 mProtocolCmbBx->setCurrentIndex( 0 );
118 QTreeWidgetItem *protocolitem =
new QTreeWidgetItem(
120 QStringList() << QString(),
121 static_cast<int>( ConfigItem )
123 protocolitem->setFlags( protocolitem->flags() & ~Qt::ItemIsSelectable );
124 treeSslConfig->setItemWidget( protocolitem, 0, mProtocolCmbBx );
125 mProtocolItem->setExpanded(
true );
127 mVerifyModeItem = addRootItem( tr(
"Peer verification" ) );
128 mVerifyPeerCmbBx =
new QComboBox( treeSslConfig );
129 mVerifyPeerCmbBx->addItem( tr(
"Verify Peer Certs" ),
static_cast<int>( QSslSocket::VerifyPeer ) );
130 mVerifyPeerCmbBx->addItem( tr(
"Do Not Verify Peer Certs" ),
static_cast<int>( QSslSocket::VerifyNone ) );
131 mVerifyPeerCmbBx->setMaximumWidth( 300 );
132 mVerifyPeerCmbBx->setCurrentIndex( 0 );
133 QTreeWidgetItem *peerverifycmbxitem =
new QTreeWidgetItem(
135 QStringList() << QString(),
136 static_cast<int>( ConfigItem )
138 peerverifycmbxitem->setFlags( peerverifycmbxitem->flags() & ~Qt::ItemIsSelectable );
139 treeSslConfig->setItemWidget( peerverifycmbxitem, 0, mVerifyPeerCmbBx );
140 mVerifyModeItem->setExpanded(
true );
142 mVerifyDepthItem = addRootItem( tr(
"Peer verification depth (0 = complete cert chain)" ) );
143 mVerifyDepthSpnBx =
new QSpinBox( treeSslConfig );
144 mVerifyDepthSpnBx->setMinimum( 0 );
145 mVerifyDepthSpnBx->setMaximum( 10 );
146 mVerifyDepthSpnBx->setMaximumWidth( 200 );
147 mVerifyDepthSpnBx->setAlignment( Qt::AlignHCenter );
148 QTreeWidgetItem *peerverifyspnbxitem =
new QTreeWidgetItem(
150 QStringList() << QString(),
151 static_cast<int>( ConfigItem )
153 peerverifyspnbxitem->setFlags( peerverifyspnbxitem->flags() & ~Qt::ItemIsSelectable );
154 treeSslConfig->setItemWidget( peerverifyspnbxitem, 0, mVerifyDepthSpnBx );
155 mVerifyDepthItem->setExpanded(
true );
157 mIgnoreErrorsItem = addRootItem( tr(
"Ignore errors" ) );
159 const QList<QPair<QSslError::SslError, QString>> errenums = QgsAuthCertUtils::sslErrorEnumStrings();
160 for (
int i = 0; i < errenums.size(); i++ )
162 QTreeWidgetItem *item =
new QTreeWidgetItem(
164 QStringList() << errenums.at( i ).second,
165 static_cast<int>( ConfigItem )
167 item->setCheckState( 0, Qt::Unchecked );
168 item->setTextAlignment( 0, Qt::AlignVCenter );
169 item->setFlags( item->flags() & ~Qt::ItemIsSelectable );
170 item->setData( 0, Qt::UserRole, errenums.at( i ).first );
172 mIgnoreErrorsItem->setExpanded(
true );
195 return QSslCertificate();
206 return leHost->text();
215 if ( grpbxSslConfig->isCheckable() )
217 grpbxSslConfig->setChecked( enable );
233 if ( !hostport.isEmpty() )
238 const QString sha( QgsAuthCertUtils::shaHexForCert( cert ) );
245 lblLoadedConfig->setVisible(
true );
253 lblLoadedConfig->setText( configNotFoundText_() );
254 leCommonName->setText( QgsAuthCertUtils::resolvedCertName( mCert ) );
282 leCommonName->setText( QgsAuthCertUtils::resolvedCertName( cert ) );
288 lblLoadedConfig->setVisible(
true );
289 lblLoadedConfig->setText( configFoundText_() );
300 QgsDebugError( u
"SSL custom config FAILED to store in authentication storage"_s );
311 mConnectionCAs.clear();
312 leCommonName->clear();
313 leCommonName->setStyleSheet( QString() );
316 lblLoadedConfig->setVisible(
false );
317 lblLoadedConfig->clear();
328 return QSsl::UnknownProtocol;
330 return ( QSsl::SslProtocol ) mProtocolCmbBx->currentData().toInt();
339 const int indx( mProtocolCmbBx->findData(
static_cast<int>( protocol ) ) );
340 mProtocolCmbBx->setCurrentIndex( indx );
349 mProtocolCmbBx->setCurrentIndex( 0 );
360 QList<QSslError::SslError> errenums;
361 const auto constErrors = errors;
362 for (
const QSslError &err : constErrors )
364 errenums << err.error();
367 for (
int i = 0; i < mIgnoreErrorsItem->childCount(); i++ )
369 QTreeWidgetItem *item( mIgnoreErrorsItem->child( i ) );
370 if ( errenums.contains( ( QSslError::SslError ) item->data( 0, Qt::UserRole ).toInt() ) )
372 item->setCheckState( 0, Qt::Checked );
383 QList<QSslError> errors;
384 const auto constErrorenums = errorenums;
385 for (
const QSslError::SslError errorenum : constErrorenums )
387 errors << QSslError( errorenum );
398 if ( errors.isEmpty() )
405 QList<QSslError::SslError> errenums;
406 const auto constErrors = errors;
407 for (
const QSslError &err : constErrors )
409 errenums << err.error();
412 for (
int i = 0; i < mIgnoreErrorsItem->childCount(); i++ )
414 QTreeWidgetItem *item( mIgnoreErrorsItem->child( i ) );
415 const bool enable( errenums.contains( ( QSslError::SslError ) item->data( 0, Qt::UserRole ).toInt() ) );
416 item->setCheckState( 0, enable ? Qt::Checked : Qt::Unchecked );
426 for (
int i = 0; i < mIgnoreErrorsItem->childCount(); i++ )
428 mIgnoreErrorsItem->child( i )->setCheckState( 0, Qt::Unchecked );
434 QList<QSslError::SslError> errs;
439 for (
int i = 0; i < mIgnoreErrorsItem->childCount(); i++ )
441 QTreeWidgetItem *item( mIgnoreErrorsItem->child( i ) );
442 if ( item->checkState( 0 ) == Qt::Checked )
444 errs.append( ( QSslError::SslError ) item->data( 0, Qt::UserRole ).toInt() );
454 return QSslSocket::AutoVerifyPeer;
456 return ( QSslSocket::PeerVerifyMode ) mVerifyPeerCmbBx->currentData().toInt();
465 return mVerifyDepthSpnBx->value();
476 const int indx( mVerifyPeerCmbBx->findData(
static_cast<int>( mode ) ) );
477 mVerifyPeerCmbBx->setCurrentIndex( indx );
479 mVerifyDepthSpnBx->setValue( modedepth );
488 mVerifyPeerCmbBx->setCurrentIndex( 0 );
489 mVerifyDepthSpnBx->setValue( 0 );
498 const bool cansave = ( isEnabled() && ( grpbxSslConfig->isCheckable() ? grpbxSslConfig->isChecked() :
true ) && validateHostPort( leHost->text() ) );
499 if ( mCanSave != cansave )
513 leHost->setText( host );
516bool QgsAuthSslConfigWidget::validateHostPort(
const QString &txt )
518 const QString hostport( txt );
519 if ( hostport.isEmpty() )
526 const QString urlbase( u
"https://%1"_s.arg( hostport ) );
527 const QUrl url( urlbase );
528 return ( !url.host().isEmpty() && QString::number( url.port() ).size() > 0 && u
"https://%1:%2"_s.arg( url.host() ).arg( url.port() ) == urlbase );
537 const bool valid = validateHostPort( txt );
548 grpbxSslConfig->setCheckable( checkable );
551 grpbxSslConfig->setEnabled(
true );
555void QgsAuthSslConfigWidget::btnCertInfo_clicked()
557 if ( mCert.isNull() )
562 QgsAuthCertInfoDialog *dlg =
new QgsAuthCertInfoDialog( mCert,
false,
this, mConnectionCAs );
563 dlg->setWindowModality( Qt::WindowModal );
564 dlg->resize( 675, 500 );
576 setWindowTitle( tr(
"Custom Certificate Configuration" ) );
577 QVBoxLayout *layout =
new QVBoxLayout(
this );
578 layout->setContentsMargins( 6, 6, 6, 6 );
582 layout->addWidget( mSslConfigWdgt );
584 QDialogButtonBox *buttonBox =
new QDialogButtonBox(
585 QDialogButtonBox::Close | QDialogButtonBox::Save, Qt::Horizontal,
this
588 buttonBox->button( QDialogButtonBox::Close )->setDefault(
true );
589 mSaveButton = buttonBox->button( QDialogButtonBox::Save );
590 connect( buttonBox, &QDialogButtonBox::rejected,
this, &QWidget::close );
592 layout->addWidget( buttonBox );
595 mSaveButton->setEnabled( mSslConfigWdgt->readyToSave() );
600 mSslConfigWdgt->saveSslCertConfig();
604void QgsAuthSslConfigDialog::checkCanSave(
bool cansave )
606 mSaveButton->setEnabled( cansave );
static QgsAuthManager * authManager()
Returns the application's authentication manager instance.
Configuration container for SSL server connection exceptions or overrides.
void setSslProtocol(QSsl::SslProtocol protocol)
Sets SSL server protocol to use in connections.
void setSslCertificate(const QSslCertificate &cert)
Sets server certificate object.
void setSslHostPort(const QString &hostport)
Sets server host:port string.
QSsl::SslProtocol sslProtocol() const
SSL server protocol to use in connections.
void setSslPeerVerifyMode(QSslSocket::PeerVerifyMode mode)
Sets SSL client's peer verify mode to use in connections.
void setSslPeerVerifyDepth(int depth)
Set number or SSL client's peer to verify in connections.
int sslPeerVerifyDepth() const
Number or SSL client's peer to verify in connections.
bool isNull() const
Whether configuration is null (missing components).
void setSslIgnoredErrorEnums(const QList< QSslError::SslError > &errors)
Sets SSL server errors (as enum list) to ignore in connections.
const QList< QSslError::SslError > sslIgnoredErrorEnums() const
SSL server errors (as enum list) to ignore in connections.
QSslSocket::PeerVerifyMode sslPeerVerifyMode() const
SSL client's peer verify mode to use in connections.
const QSslCertificate sslCertificate() const
Server certificate object.
const QString sslHostPort() const
Server host:port string.
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.
static QString orangeTextStyleSheet(const QString &selector="*")
Orange text stylesheet representing loaded component, but not stored in database.
static void setItemBold(QTreeWidgetItem *item)
Call setFirstColumnSpanned(true) on the item and make its font bold.
QgsAuthSslConfigDialog(QWidget *parent=nullptr, const QSslCertificate &cert=QSslCertificate(), const QString &hostport=QString())
Construct wrapper dialog for the SSL config widget.
#define QgsDebugError(str)