25#include <QDialogButtonBox>
31#include "moc_qgsauthsslconfigwidget.cpp"
33using namespace Qt::StringLiterals;
35static const QString configFoundText_()
37 return QObject::tr(
"Configuration loaded from database" );
39static const QString configNotFoundText_()
41 return QObject::tr(
"Configuration not found in database" );
47 , mConnectionCAs( connectionCAs )
52 mAuthNotifyLayout =
new QVBoxLayout;
53 this->setLayout( mAuthNotifyLayout );
55 mAuthNotifyLayout->addWidget( mAuthNotify );
60 connect( btnCertInfo, &QToolButton::clicked,
this, &QgsAuthSslConfigWidget::btnCertInfo_clicked );
68 lblLoadedConfig->setVisible(
false );
69 lblLoadedConfig->clear();
95 return grpbxSslConfig;
99QTreeWidgetItem *QgsAuthSslConfigWidget::addRootItem(
const QString &label )
101 QTreeWidgetItem *item =
new QTreeWidgetItem( QStringList() << label,
static_cast<int>( ConfigParent ) );
103 item->setTextAlignment( 0, Qt::AlignVCenter );
104 item->setFlags( item->flags() & ~Qt::ItemIsSelectable );
105 treeSslConfig->insertTopLevelItem( treeSslConfig->topLevelItemCount(), item );
110void QgsAuthSslConfigWidget::setUpSslConfigTree()
112 treeSslConfig->setColumnCount( 1 );
115 mProtocolItem = addRootItem( tr(
"Protocol" ) );
116 mProtocolCmbBx =
new QComboBox( treeSslConfig );
117 mProtocolCmbBx->addItem( QgsAuthCertUtils::getSslProtocolName( QSsl::SecureProtocols ),
static_cast<int>( QSsl::SecureProtocols ) );
118 mProtocolCmbBx->addItem( QgsAuthCertUtils::getSslProtocolName( QSsl::TlsV1_0 ),
static_cast<int>( QSsl::TlsV1_0 ) );
119 mProtocolCmbBx->setMaximumWidth( 300 );
120 mProtocolCmbBx->setCurrentIndex( 0 );
121 QTreeWidgetItem *protocolitem =
new QTreeWidgetItem( mProtocolItem, QStringList() << QString(),
static_cast<int>( ConfigItem ) );
122 protocolitem->setFlags( protocolitem->flags() & ~Qt::ItemIsSelectable );
123 treeSslConfig->setItemWidget( protocolitem, 0, mProtocolCmbBx );
124 mProtocolItem->setExpanded(
true );
126 mVerifyModeItem = addRootItem( tr(
"Peer verification" ) );
127 mVerifyPeerCmbBx =
new QComboBox( treeSslConfig );
128 mVerifyPeerCmbBx->addItem( tr(
"Verify Peer Certs" ),
static_cast<int>( QSslSocket::VerifyPeer ) );
129 mVerifyPeerCmbBx->addItem( tr(
"Do Not Verify Peer Certs" ),
static_cast<int>( QSslSocket::VerifyNone ) );
130 mVerifyPeerCmbBx->setMaximumWidth( 300 );
131 mVerifyPeerCmbBx->setCurrentIndex( 0 );
132 QTreeWidgetItem *peerverifycmbxitem =
new QTreeWidgetItem( mVerifyModeItem, QStringList() << QString(),
static_cast<int>( ConfigItem ) );
133 peerverifycmbxitem->setFlags( peerverifycmbxitem->flags() & ~Qt::ItemIsSelectable );
134 treeSslConfig->setItemWidget( peerverifycmbxitem, 0, mVerifyPeerCmbBx );
135 mVerifyModeItem->setExpanded(
true );
137 mVerifyDepthItem = addRootItem( tr(
"Peer verification depth (0 = complete cert chain)" ) );
138 mVerifyDepthSpnBx =
new QSpinBox( treeSslConfig );
139 mVerifyDepthSpnBx->setMinimum( 0 );
140 mVerifyDepthSpnBx->setMaximum( 10 );
141 mVerifyDepthSpnBx->setMaximumWidth( 200 );
142 mVerifyDepthSpnBx->setAlignment( Qt::AlignHCenter );
143 QTreeWidgetItem *peerverifyspnbxitem =
new QTreeWidgetItem( mVerifyDepthItem, QStringList() << QString(),
static_cast<int>( ConfigItem ) );
144 peerverifyspnbxitem->setFlags( peerverifyspnbxitem->flags() & ~Qt::ItemIsSelectable );
145 treeSslConfig->setItemWidget( peerverifyspnbxitem, 0, mVerifyDepthSpnBx );
146 mVerifyDepthItem->setExpanded(
true );
148 mIgnoreErrorsItem = addRootItem( tr(
"Ignore errors" ) );
150 const QList<QPair<QSslError::SslError, QString>> errenums = QgsAuthCertUtils::sslErrorEnumStrings();
151 for (
int i = 0; i < errenums.size(); i++ )
153 QTreeWidgetItem *item =
new QTreeWidgetItem( mIgnoreErrorsItem, QStringList() << errenums.at( i ).second,
static_cast<int>( ConfigItem ) );
154 item->setCheckState( 0, Qt::Unchecked );
155 item->setTextAlignment( 0, Qt::AlignVCenter );
156 item->setFlags( item->flags() & ~Qt::ItemIsSelectable );
157 item->setData( 0, Qt::UserRole, errenums.at( i ).first );
159 mIgnoreErrorsItem->setExpanded(
true );
182 return QSslCertificate();
193 return leHost->text();
202 if ( grpbxSslConfig->isCheckable() )
204 grpbxSslConfig->setChecked( enable );
220 if ( !hostport.isEmpty() )
225 const QString sha( QgsAuthCertUtils::shaHexForCert( cert ) );
230 lblLoadedConfig->setVisible(
true );
238 lblLoadedConfig->setText( configNotFoundText_() );
239 leCommonName->setText( QgsAuthCertUtils::resolvedCertName( mCert ) );
267 leCommonName->setText( QgsAuthCertUtils::resolvedCertName( cert ) );
273 lblLoadedConfig->setVisible(
true );
274 lblLoadedConfig->setText( configFoundText_() );
285 QgsDebugError( u
"SSL custom config FAILED to store in authentication storage"_s );
296 mConnectionCAs.clear();
297 leCommonName->clear();
298 leCommonName->setStyleSheet( QString() );
301 lblLoadedConfig->setVisible(
false );
302 lblLoadedConfig->clear();
313 return QSsl::UnknownProtocol;
315 return ( QSsl::SslProtocol ) mProtocolCmbBx->currentData().toInt();
324 const int indx( mProtocolCmbBx->findData(
static_cast<int>( protocol ) ) );
325 mProtocolCmbBx->setCurrentIndex( indx );
334 mProtocolCmbBx->setCurrentIndex( 0 );
345 QList<QSslError::SslError> errenums;
346 const auto constErrors = errors;
347 for (
const QSslError &err : constErrors )
349 errenums << err.error();
352 for (
int i = 0; i < mIgnoreErrorsItem->childCount(); i++ )
354 QTreeWidgetItem *item( mIgnoreErrorsItem->child( i ) );
355 if ( errenums.contains( ( QSslError::SslError ) item->data( 0, Qt::UserRole ).toInt() ) )
357 item->setCheckState( 0, Qt::Checked );
368 QList<QSslError> errors;
369 const auto constErrorenums = errorenums;
370 for (
const QSslError::SslError errorenum : constErrorenums )
372 errors << QSslError( errorenum );
383 if ( errors.isEmpty() )
390 QList<QSslError::SslError> errenums;
391 const auto constErrors = errors;
392 for (
const QSslError &err : constErrors )
394 errenums << err.error();
397 for (
int i = 0; i < mIgnoreErrorsItem->childCount(); i++ )
399 QTreeWidgetItem *item( mIgnoreErrorsItem->child( i ) );
400 const bool enable( errenums.contains( ( QSslError::SslError ) item->data( 0, Qt::UserRole ).toInt() ) );
401 item->setCheckState( 0, enable ? Qt::Checked : Qt::Unchecked );
411 for (
int i = 0; i < mIgnoreErrorsItem->childCount(); i++ )
413 mIgnoreErrorsItem->child( i )->setCheckState( 0, Qt::Unchecked );
419 QList<QSslError::SslError> errs;
424 for (
int i = 0; i < mIgnoreErrorsItem->childCount(); i++ )
426 QTreeWidgetItem *item( mIgnoreErrorsItem->child( i ) );
427 if ( item->checkState( 0 ) == Qt::Checked )
429 errs.append( ( QSslError::SslError ) item->data( 0, Qt::UserRole ).toInt() );
439 return QSslSocket::AutoVerifyPeer;
441 return ( QSslSocket::PeerVerifyMode ) mVerifyPeerCmbBx->currentData().toInt();
450 return mVerifyDepthSpnBx->value();
461 const int indx( mVerifyPeerCmbBx->findData(
static_cast<int>( mode ) ) );
462 mVerifyPeerCmbBx->setCurrentIndex( indx );
464 mVerifyDepthSpnBx->setValue( modedepth );
473 mVerifyPeerCmbBx->setCurrentIndex( 0 );
474 mVerifyDepthSpnBx->setValue( 0 );
483 const bool cansave = ( isEnabled() && ( grpbxSslConfig->isCheckable() ? grpbxSslConfig->isChecked() :
true ) && validateHostPort( leHost->text() ) );
484 if ( mCanSave != cansave )
498 leHost->setText( host );
501bool QgsAuthSslConfigWidget::validateHostPort(
const QString &txt )
503 const QString hostport( txt );
504 if ( hostport.isEmpty() )
511 const QString urlbase( u
"https://%1"_s.arg( hostport ) );
512 const QUrl url( urlbase );
513 return ( !url.host().isEmpty() && QString::number( url.port() ).size() > 0 && u
"https://%1:%2"_s.arg( url.host() ).arg( url.port() ) == urlbase );
522 const bool valid = validateHostPort( txt );
533 grpbxSslConfig->setCheckable( checkable );
536 grpbxSslConfig->setEnabled(
true );
540void QgsAuthSslConfigWidget::btnCertInfo_clicked()
542 if ( mCert.isNull() )
547 QgsAuthCertInfoDialog *dlg =
new QgsAuthCertInfoDialog( mCert,
false,
this, mConnectionCAs );
548 dlg->setWindowModality( Qt::WindowModal );
549 dlg->resize( 675, 500 );
561 setWindowTitle( tr(
"Custom Certificate Configuration" ) );
562 QVBoxLayout *layout =
new QVBoxLayout(
this );
563 layout->setContentsMargins( 6, 6, 6, 6 );
567 layout->addWidget( mSslConfigWdgt );
569 QDialogButtonBox *buttonBox =
new QDialogButtonBox( QDialogButtonBox::Close | QDialogButtonBox::Save, Qt::Horizontal,
this );
571 buttonBox->button( QDialogButtonBox::Close )->setDefault(
true );
572 mSaveButton = buttonBox->button( QDialogButtonBox::Save );
573 connect( buttonBox, &QDialogButtonBox::rejected,
this, &QWidget::close );
575 layout->addWidget( buttonBox );
578 mSaveButton->setEnabled( mSslConfigWdgt->readyToSave() );
583 mSslConfigWdgt->saveSslCertConfig();
587void QgsAuthSslConfigDialog::checkCanSave(
bool cansave )
589 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)