00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include <config-kleopatra.h>
00034
00035 #include "certifycertificatedialog.h"
00036 #include "certifycertificatedialog_p.h"
00037
00038 #include <utils/formatting.h>
00039
00040 #include <KDebug>
00041 #include <KLocalizedString>
00042
00043 #include <QGridLayout>
00044 #include <QStandardItem>
00045 #include <QStandardItemModel>
00046 #include <QListView>
00047 #include <QListWidgetItem>
00048 #include <QVBoxLayout>
00049 #include <QWizardPage>
00050
00051 #include <QTextDocument>
00052
00053 #include <cassert>
00054
00055 using namespace boost;
00056 using namespace GpgME;
00057 using namespace Kleo;
00058 using namespace Kleo::Dialogs;
00059 using namespace Kleo::Dialogs::CertifyCertificateDialogPrivate;
00060
00061
00062 void UserIDModel::setCertificateToCertify( const Key & key ) {
00063 m_key = key;
00064 clear();
00065 const std::vector<UserID> ids = key.userIDs();
00066 for ( unsigned int i = 0; i < ids.size(); ++i ) {
00067 QStandardItem * const item = new QStandardItem;
00068 item->setText( Formatting::prettyUserID( key.userID( i ) ) );
00069 item->setData( i, UserIDIndex );
00070 item->setCheckable( true );
00071 item->setEditable( false );
00072 appendRow( item );
00073 }
00074 }
00075
00076 std::vector<unsigned int> UserIDModel::checkedUserIDs() const {
00077 std::vector<unsigned int> ids;
00078 for ( int i = 0; i < rowCount(); ++i )
00079 if ( item( i )->checkState() == Qt::Checked )
00080 ids.push_back( item( i )->data( UserIDIndex ).toUInt() );
00081 return ids;
00082 }
00083
00084 void SecretKeysModel::setSecretKeys( const std::vector<Key> & keys ) {
00085 clear();
00086 m_secretKeys = keys;
00087 for ( unsigned int i = 0; i < m_secretKeys.size(); ++i ) {
00088 const Key key = m_secretKeys[i];
00089 QStandardItem * const item = new QStandardItem;
00090 item->setText( Formatting::prettyNameAndEMail( key ) );
00091 item->setData( i, IndexRole );
00092 item->setEditable( false );
00093 appendRow( item );
00094 }
00095 }
00096
00097 std::vector<GpgME::Key> SecretKeysModel::secretKeys() const {
00098 return m_secretKeys;
00099 }
00100
00101 Key SecretKeysModel::keyFromItem( const QStandardItem * item ) const {
00102 assert( item );
00103 const unsigned int idx = item->data( IndexRole ).toUInt();
00104 assert( idx < m_secretKeys.size() );
00105 return m_secretKeys[idx];
00106 }
00107
00108 Key SecretKeysModel::keyFromIndex( const QModelIndex & idx ) const {
00109 return keyFromItem( itemFromIndex( idx ) );
00110 }
00111
00112 SelectUserIDsPage::SelectUserIDsPage( QWidget * parent ) : QWizardPage( parent ), m_userIDModel() {
00113 QVBoxLayout * const layout = new QVBoxLayout ( this );
00114 QLabel * const label = new QLabel;
00115 label->setText( i18n( "<b>Step 1:</b> Please select the user IDs you wish to certify." ) );
00116 layout->addWidget( label );
00117 m_listView = new QListView;
00118 m_listView->setModel( &m_userIDModel );
00119 connect( &m_userIDModel, SIGNAL(itemChanged(QStandardItem*)), this, SIGNAL(completeChanged()) );
00120 layout->addWidget( m_listView );
00121 }
00122
00123 bool SelectUserIDsPage::isComplete() const {
00124 return !selectedUserIDs().empty();
00125 }
00126
00127 std::vector<unsigned int> SelectUserIDsPage::selectedUserIDs() const {
00128 return m_userIDModel.checkedUserIDs();
00129 }
00130
00131 void SelectUserIDsPage::setCertificateToCertify( const Key & key ) {
00132 m_userIDModel.setCertificateToCertify( key );
00133
00134 }
00135
00136 SelectCheckLevelPage::SelectCheckLevelPage( QWidget * parent ) : QWizardPage( parent ), m_ui() {
00137 m_ui.setupUi( this );
00138 }
00139
00140 unsigned int SelectCheckLevelPage::checkLevel() const {
00141 if ( m_ui.checkLevelNotCheckedRB->isChecked() )
00142 return 1;
00143 if ( m_ui.checkLevelCasualRB->isChecked() )
00144 return 2;
00145 if ( m_ui.checkLevelThoroughlyRB->isChecked() )
00146 return 3;
00147 assert( !"No check level radiobutton checked" );
00148 return 0;
00149 }
00150
00151 OptionsPage::OptionsPage( QWidget * parent ) : QWizardPage( parent ), m_ui() {
00152 m_ui.setupUi( this );
00153 m_ui.keyListView->setModel( &m_model );
00154 connect( m_ui.keyListView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SIGNAL(completeChanged()) );
00155 setCommitPage( true );
00156 setButtonText( QWizard::CommitButton, i18n( "Certify" ) );
00157 }
00158
00159
00160 bool OptionsPage::exportableCertificationSelected() const {
00161 return m_ui.exportableSignatureRB->isChecked();
00162 }
00163
00164 void OptionsPage::setCertificatesWithSecretKeys( const std::vector<Key> & keys ) {
00165 assert( !keys.empty() );
00166 m_model.setSecretKeys( keys );
00167 if ( keys.size() == 1 ) {
00168 m_ui.stackedWidget->setCurrentWidget( m_ui.singleKeyPage );
00169 m_ui.singleKeyLabel->setText( i18n( "Certification will be performed using certificate %1.", Formatting::prettyNameAndEMail( keys[0] ) ) );
00170 } else {
00171 m_ui.stackedWidget->setCurrentWidget( m_ui.multipleKeysPage );
00172 }
00173 emit completeChanged();
00174 }
00175
00176 Key OptionsPage::selectedSecretKey() const {
00177 if ( m_model.secretKeys().size() == 1 )
00178 return m_model.secretKeys().at( 0 );
00179 const QModelIndexList idxs = m_ui.keyListView->selectionModel()->selectedIndexes();
00180 assert( idxs.size() <= 1 );
00181 return idxs.isEmpty() ? Key() : m_model.keyFromIndex( idxs[0] );
00182 }
00183
00184 bool OptionsPage::sendToServer() const {
00185 return m_ui.sendToServerCB->isChecked();
00186 }
00187
00188 bool OptionsPage::validatePage() {
00189 emit nextClicked();
00190 return true;
00191 }
00192
00193 bool OptionsPage::isComplete() const {
00194 return !selectedSecretKey().isNull();
00195 }
00196
00197 SummaryPage::SummaryPage( QWidget * parent ) : QWizardPage( parent ), m_complete( false ) {
00198 QGridLayout * const layout = new QGridLayout( this );
00199 QLabel * const uidLabelLabel = new QLabel( i18n( "Signed user IDs:" ) );
00200 uidLabelLabel->setAlignment( Qt::AlignTop );
00201 int row = 0;
00202 layout->addWidget( new QLabel( i18n( "<b>Summary:</b>" ) ), row, 0, 1, 2 );
00203 layout->addWidget( uidLabelLabel, ++row, 0 );
00204 layout->addWidget( m_userIDsLabel = new QLabel, row, 1 );
00205 #ifdef KLEO_SIGN_KEY_CERTLEVEL_SUPPORT
00206 layout->addWidget( new QLabel( i18n( "Check level:" ) ), ++row, 0 );
00207 layout->addWidget( m_checkLevelLabel = new QLabel, row, 1 );
00208 #endif
00209 layout->addWidget( new QLabel( i18n( "Selected secret certificate:" ) ), ++row, 0 );
00210 layout->addWidget( m_secretKeyLabel = new QLabel, row, 1 );
00211 m_secretKeyLabel->setTextFormat( Qt::PlainText );
00212 layout->addWidget( m_resultLabel = new QLabel, ++row, 0, 1, 2, Qt::AlignCenter );
00213 layout->setRowStretch( row, 1 );
00214 m_resultLabel->setAlignment( Qt::AlignCenter );
00215 }
00216
00217 bool SummaryPage::isComplete() const {
00218 return m_complete;
00219 }
00220
00221 void SummaryPage::setSummary( const SummaryPage::Summary & sum ) {
00222 const Key key = sum.certificateToCertify;
00223 QStringList ids;
00224 Q_FOREACH ( const unsigned int i, sum.selectedUserIDs )
00225 ids += Qt::escape( Formatting::prettyUserID( key.userID( i ) ) );
00226 m_userIDsLabel->setText( "<qt>" + ids.join( "<br/>" ) + "</qt>" );
00227 m_secretKeyLabel->setText( sum.secretKey.isNull() ? i18n( "Default certificate" ) : Formatting::prettyNameAndEMail( sum.secretKey ) );
00228 #ifdef KLEO_SIGN_KEY_CERTLEVEL_SUPPORT
00229 switch( sum.checkLevel ) {
00230 case 0:
00231 m_checkLevelLabel->setText( i18n( "No statement made" ) );
00232 break;
00233 case 1:
00234 m_checkLevelLabel->setText( i18n( "Not checked" ) );
00235 break;
00236 case 2:
00237 m_checkLevelLabel->setText( i18n( "Casually checked" ) );
00238 break;
00239 case 3:
00240 m_checkLevelLabel->setText( i18n( "Thoroughly checked" ) );
00241 break;
00242 }
00243 #endif
00244 }
00245
00246 void SummaryPage::setComplete( bool complete ) {
00247 if ( complete == m_complete )
00248 return;
00249 m_complete = complete;
00250 emit completeChanged();
00251 }
00252 void SummaryPage::setResult( const Error & err ) {
00253 if ( err && !err.isCanceled() )
00254 m_resultLabel->setText( i18n( "The certificate could not be certified. <b>Error</b>: %1", Qt::escape( QString::fromLocal8Bit( err.asString() ) ) ) );
00255 else if ( err.isCanceled() )
00256 m_resultLabel->setText( i18n("Certification canceled.") );
00257 else
00258 m_resultLabel->setText(i18n("Certification successful.") );
00259 }
00260
00261 class CertifyCertificateDialog::Private {
00262 friend class ::Kleo::Dialogs::CertifyCertificateDialog;
00263 CertifyCertificateDialog * const q;
00264
00265 public:
00266 explicit Private( CertifyCertificateDialog * qq )
00267 : q( qq ),
00268 summaryPageId( 0 ),
00269 selectUserIDsPage( 0 ),
00270 selectCheckLevelPage( 0 ),
00271 optionsPage( 0 ),
00272 summaryPage( 0 )
00273 {
00274 selectUserIDsPage = new SelectUserIDsPage( q );
00275 q->addPage( selectUserIDsPage );
00276
00277
00278
00279
00280 optionsPage = new OptionsPage( q );
00281 q->addPage( optionsPage );
00282 summaryPage = new SummaryPage( q );
00283 summaryPageId = q->addPage( summaryPage );
00284 connect( optionsPage, SIGNAL(nextClicked()), q, SIGNAL(certificationPrepared()) );
00285 }
00286
00287 void ensureSummaryPageVisible();
00288
00289 void certificationResult( const Error & error );
00290
00291 void setOperationCompleted() {
00292 summaryPage->setComplete( true );
00293 }
00294
00295 SummaryPage::Summary createSummary() const {
00296 SummaryPage::Summary sum;
00297 sum.selectedUserIDs = selectUserIDsPage->selectedUserIDs();
00298 sum.secretKey = optionsPage->selectedSecretKey();
00299 sum.certificateToCertify = selectUserIDsPage->certificateToCertify();
00300
00301 #ifdef KLEO_SIGN_KEY_CERTLEVEL_SUPPORT
00302 sum.checkLevel = selectCheckLevelPage->checkLevel();
00303 #endif
00304
00305 sum.exportable = optionsPage->exportableCertificationSelected();
00306 sum.sendToServer = optionsPage->sendToServer();
00307 return sum;
00308 }
00309
00310 int summaryPageId;
00311 SelectUserIDsPage * selectUserIDsPage;
00312 SelectCheckLevelPage * selectCheckLevelPage;
00313 OptionsPage * optionsPage;
00314 SummaryPage * summaryPage;
00315 };
00316
00317
00318
00319 CertifyCertificateDialog::CertifyCertificateDialog( QWidget * p, Qt::WindowFlags f )
00320 : QWizard( p, f ), d( new Private( this ) )
00321 {
00322 }
00323
00324 CertifyCertificateDialog::~CertifyCertificateDialog() {}
00325
00326 void CertifyCertificateDialog::setCertificateToCertify( const Key & key ) {
00327 setWindowTitle( i18nc( "arg is name, email of certificate holder", "Certify Certificate: %1", Formatting::prettyName( key ) ) );
00328 d->selectUserIDsPage->setCertificateToCertify( key );
00329 }
00330
00331 void CertifyCertificateDialog::setCertificatesWithSecretKeys( const std::vector<Key> & keys ) {
00332 d->optionsPage->setCertificatesWithSecretKeys( keys );
00333 }
00334
00335 bool CertifyCertificateDialog::exportableCertificationSelected() const {
00336 return d->optionsPage->exportableCertificationSelected();
00337 }
00338
00339 bool CertifyCertificateDialog::trustCertificationSelected() const {
00340 return false;
00341 }
00342
00343 bool CertifyCertificateDialog::nonRevocableCertificationSelected() const {
00344 return false;
00345 }
00346
00347 Key CertifyCertificateDialog::selectedSecretKey() const {
00348 return d->optionsPage->selectedSecretKey();
00349 }
00350
00351 bool CertifyCertificateDialog::sendToServer() const {
00352 return d->optionsPage->sendToServer();
00353 }
00354
00355 unsigned int CertifyCertificateDialog::selectedCheckLevel() const {
00356
00357 #ifdef KLEO_SIGN_KEY_CERTLEVEL_SUPPORT
00358 return d->selectCheckLevelPage->checkLevel();
00359 #endif
00360 return 0;
00361 }
00362
00363 void CertifyCertificateDialog::connectJob( SignKeyJob * job ) {
00364 connect( job, SIGNAL(result(GpgME::Error)), this, SLOT(certificationResult(GpgME::Error)) );
00365 d->summaryPage->setSummary( d->createSummary() );
00366 }
00367
00368 void CertifyCertificateDialog::setError( const Error & error ) {
00369 d->setOperationCompleted();
00370 d->summaryPage->setResult( error );
00371 d->ensureSummaryPageVisible();
00372 if ( error.isCanceled() )
00373 close();
00374 }
00375
00376 void CertifyCertificateDialog::Private::certificationResult( const Error & err ) {
00377 setOperationCompleted();
00378 summaryPage->setResult( err );
00379 ensureSummaryPageVisible();
00380 }
00381
00382 std::vector<unsigned int> CertifyCertificateDialog::selectedUserIDs() const {
00383 return d->selectUserIDsPage->selectedUserIDs();
00384 }
00385
00386 void CertifyCertificateDialog::Private::ensureSummaryPageVisible() {
00387 while ( q->currentId() != summaryPageId )
00388 q->next();
00389 }
00390
00391 #include "moc_certifycertificatedialog.cpp"
00392 #include "moc_certifycertificatedialog_p.cpp"