20 #include <QDialogButtonBox>
21 #include <QPushButton>
31 static void setItemBold_( QTreeWidgetItem *item )
33 item->setFirstColumnSpanned(
true );
34 QFont secf( item->font( 0 ) );
36 item->setFont( 0, secf );
39 static const QString configFoundText_() {
return QObject::tr(
"Configuration loaded from database" ); }
40 static const QString configNotFoundText_() {
return QObject::tr(
"Configuration not found in database" ); }
43 const QSslCertificate &cert,
44 const QString &hostport,
45 const QList<QSslCertificate> &connectionCAs )
48 , mConnectionCAs( connectionCAs )
53 mAuthNotifyLayout =
new QVBoxLayout;
54 this->setLayout( mAuthNotifyLayout );
56 mAuthNotifyLayout->addWidget( mAuthNotify );
61 connect( btnCertInfo, &QToolButton::clicked,
this, &QgsAuthSslConfigWidget::btnCertInfo_clicked );
69 lblLoadedConfig->setVisible(
false );
70 lblLoadedConfig->clear();
72 connect( leHost, &QLineEdit::textChanged,
97 return grpbxSslConfig;
101 QTreeWidgetItem *QgsAuthSslConfigWidget::addRootItem(
const QString &label )
103 QTreeWidgetItem *item =
new QTreeWidgetItem(
104 QStringList() << label,
105 static_cast<int>( ConfigParent ) );
106 setItemBold_( item );
107 item->setTextAlignment( 0, Qt::AlignVCenter );
108 item->setFlags( item->flags() & ~Qt::ItemIsSelectable );
109 treeSslConfig->insertTopLevelItem( treeSslConfig->topLevelItemCount(), item );
114 void QgsAuthSslConfigWidget::setUpSslConfigTree()
116 treeSslConfig->setColumnCount( 1 );
119 mProtocolItem = addRootItem( tr(
"Protocol" ) );
120 mProtocolCmbBx =
new QComboBox( treeSslConfig );
122 static_cast<int>( QSsl::SecureProtocols ) );
123 #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
125 static_cast<int>( QSsl::TlsV1SslV3 ) );
128 static_cast<int>( QSsl::TlsV1_0 ) );
129 #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
131 static_cast<int>( QSsl::SslV3 ) );
133 static_cast<int>( QSsl::SslV2 ) );
135 mProtocolCmbBx->setMaximumWidth( 300 );
136 mProtocolCmbBx->setCurrentIndex( 0 );
137 QTreeWidgetItem *protocolitem =
new QTreeWidgetItem(
139 QStringList() << QString(),
140 static_cast<int>( ConfigItem ) );
141 protocolitem->setFlags( protocolitem->flags() & ~Qt::ItemIsSelectable );
142 treeSslConfig->setItemWidget( protocolitem, 0, mProtocolCmbBx );
143 mProtocolItem->setExpanded(
true );
145 mVerifyModeItem = addRootItem( tr(
"Peer verification" ) );
146 mVerifyPeerCmbBx =
new QComboBox( treeSslConfig );
147 mVerifyPeerCmbBx->addItem( tr(
"Verify Peer Certs" ),
148 static_cast<int>( QSslSocket::VerifyPeer ) );
149 mVerifyPeerCmbBx->addItem( tr(
"Do Not Verify Peer Certs" ),
150 static_cast<int>( QSslSocket::VerifyNone ) );
151 mVerifyPeerCmbBx->setMaximumWidth( 300 );
152 mVerifyPeerCmbBx->setCurrentIndex( 0 );
153 QTreeWidgetItem *peerverifycmbxitem =
new QTreeWidgetItem(
155 QStringList() << QString(),
156 static_cast<int>( ConfigItem ) );
157 peerverifycmbxitem->setFlags( peerverifycmbxitem->flags() & ~Qt::ItemIsSelectable );
158 treeSslConfig->setItemWidget( peerverifycmbxitem, 0, mVerifyPeerCmbBx );
159 mVerifyModeItem->setExpanded(
true );
161 mVerifyDepthItem = addRootItem( tr(
"Peer verification depth (0 = complete cert chain)" ) );
162 mVerifyDepthSpnBx =
new QSpinBox( treeSslConfig );
163 mVerifyDepthSpnBx->setMinimum( 0 );
164 mVerifyDepthSpnBx->setMaximum( 10 );
165 mVerifyDepthSpnBx->setMaximumWidth( 200 );
166 mVerifyDepthSpnBx->setAlignment( Qt::AlignHCenter );
167 QTreeWidgetItem *peerverifyspnbxitem =
new QTreeWidgetItem(
169 QStringList() << QString(),
170 static_cast<int>( ConfigItem ) );
171 peerverifyspnbxitem->setFlags( peerverifyspnbxitem->flags() & ~Qt::ItemIsSelectable );
172 treeSslConfig->setItemWidget( peerverifyspnbxitem, 0, mVerifyDepthSpnBx );
173 mVerifyDepthItem->setExpanded(
true );
175 mIgnoreErrorsItem = addRootItem( tr(
"Ignore errors" ) );
178 for (
int i = 0; i < errenums.size(); i++ )
180 QTreeWidgetItem *item =
new QTreeWidgetItem(
182 QStringList() << errenums.at( i ).second,
183 static_cast<int>( ConfigItem ) );
184 item->setCheckState( 0, Qt::Unchecked );
185 item->setTextAlignment( 0, Qt::AlignVCenter );
186 item->setFlags( item->flags() & ~Qt::ItemIsSelectable );
187 item->setData( 0, Qt::UserRole, errenums.at( i ).first );
189 mIgnoreErrorsItem->setExpanded(
true );
212 return QSslCertificate();
223 return leHost->text();
232 if ( grpbxSslConfig->isCheckable() )
234 grpbxSslConfig->setChecked( enable );
250 if ( !hostport.isEmpty() )
261 lblLoadedConfig->setVisible(
true );
269 lblLoadedConfig->setText( configNotFoundText_() );
285 QgsDebugMsg( QStringLiteral(
"Passed-in SSL custom config is null" ) );
292 QgsDebugMsg( QStringLiteral(
"SSL custom config's cert is null" ) );
304 lblLoadedConfig->setVisible(
true );
305 lblLoadedConfig->setText( configFoundText_() );
316 QgsDebugMsg( QStringLiteral(
"SSL custom config FAILED to store in authentication database" ) );
327 mConnectionCAs.clear();
328 leCommonName->clear();
329 leCommonName->setStyleSheet( QString() );
332 lblLoadedConfig->setVisible(
false );
333 lblLoadedConfig->clear();
344 return QSsl::UnknownProtocol;
346 return ( QSsl::SslProtocol )mProtocolCmbBx->currentData().toInt();
355 const int indx( mProtocolCmbBx->findData(
static_cast<int>( protocol ) ) );
356 mProtocolCmbBx->setCurrentIndex( indx );
365 mProtocolCmbBx->setCurrentIndex( 0 );
376 QList<QSslError::SslError> errenums;
377 const auto constErrors = errors;
378 for (
const QSslError &err : constErrors )
380 errenums << err.error();
383 for (
int i = 0; i < mIgnoreErrorsItem->childCount(); i++ )
385 QTreeWidgetItem *item( mIgnoreErrorsItem->child( i ) );
386 if ( errenums.contains( ( QSslError::SslError )item->data( 0, Qt::UserRole ).toInt() ) )
388 item->setCheckState( 0, Qt::Checked );
399 QList<QSslError> errors;
400 const auto constErrorenums = errorenums;
401 for (
const QSslError::SslError errorenum : constErrorenums )
403 errors << QSslError( errorenum );
414 if ( errors.isEmpty() )
421 QList<QSslError::SslError> errenums;
422 const auto constErrors = errors;
423 for (
const QSslError &err : constErrors )
425 errenums << err.error();
428 for (
int i = 0; i < mIgnoreErrorsItem->childCount(); i++ )
430 QTreeWidgetItem *item( mIgnoreErrorsItem->child( i ) );
431 const bool enable( errenums.contains( ( QSslError::SslError )item->data( 0, Qt::UserRole ).toInt() ) );
432 item->setCheckState( 0, enable ? Qt::Checked : Qt::Unchecked );
442 for (
int i = 0; i < mIgnoreErrorsItem->childCount(); i++ )
444 mIgnoreErrorsItem->child( i )->setCheckState( 0, Qt::Unchecked );
450 QList<QSslError::SslError> errs;
455 for (
int i = 0; i < mIgnoreErrorsItem->childCount(); i++ )
457 QTreeWidgetItem *item( mIgnoreErrorsItem->child( i ) );
458 if ( item->checkState( 0 ) == Qt::Checked )
460 errs.append( ( QSslError::SslError )item->data( 0, Qt::UserRole ).toInt() );
470 return QSslSocket::AutoVerifyPeer;
472 return ( QSslSocket::PeerVerifyMode )mVerifyPeerCmbBx->currentData().toInt();
481 return mVerifyDepthSpnBx->value();
492 const int indx( mVerifyPeerCmbBx->findData(
static_cast<int>( mode ) ) );
493 mVerifyPeerCmbBx->setCurrentIndex( indx );
495 mVerifyDepthSpnBx->setValue( modedepth );
504 mVerifyPeerCmbBx->setCurrentIndex( 0 );
505 mVerifyDepthSpnBx->setValue( 0 );
514 const bool cansave = ( isEnabled()
515 && ( grpbxSslConfig->isCheckable() ? grpbxSslConfig->isChecked() : true )
516 && validateHostPort( leHost->text() ) );
517 if ( mCanSave != cansave )
531 leHost->setText( host );
534 bool QgsAuthSslConfigWidget::validateHostPort(
const QString &txt )
536 const QString hostport( txt );
537 if ( hostport.isEmpty() )
544 const QString urlbase( QStringLiteral(
"https://%1" ).arg( hostport ) );
545 const QUrl url( urlbase );
546 return ( !url.host().isEmpty() && QString::number( url.port() ).size() > 0
547 && QStringLiteral(
"https://%1:%2" ).arg( url.host() ).arg( url.port() ) == urlbase );
556 const bool valid = validateHostPort( txt );
568 grpbxSslConfig->setCheckable( checkable );
571 grpbxSslConfig->setEnabled(
true );
575 void QgsAuthSslConfigWidget::btnCertInfo_clicked()
577 if ( mCert.isNull() )
583 dlg->setWindowModality( Qt::WindowModal );
584 dlg->resize( 675, 500 );
596 setWindowTitle( tr(
"Custom Certificate Configuration" ) );
597 QVBoxLayout *layout =
new QVBoxLayout(
this );
598 layout->setContentsMargins( 6, 6, 6, 6 );
602 this, &QgsAuthSslConfigDialog::checkCanSave );
603 layout->addWidget( mSslConfigWdgt );
605 QDialogButtonBox *buttonBox =
new QDialogButtonBox(
606 QDialogButtonBox::Close | QDialogButtonBox::Save, Qt::Horizontal,
this );
608 buttonBox->button( QDialogButtonBox::Close )->setDefault(
true );
609 mSaveButton = buttonBox->button( QDialogButtonBox::Save );
610 connect( buttonBox, &QDialogButtonBox::rejected,
this, &QWidget::close );
612 layout->addWidget( buttonBox );
615 mSaveButton->setEnabled( mSslConfigWdgt->
readyToSave() );
624 void QgsAuthSslConfigDialog::checkCanSave(
bool cansave )
626 mSaveButton->setEnabled( cansave );