• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepim API Reference
  • KDE Home
  • Contact Us
 

kleopatra

  • sources
  • kde-4.12
  • kdepim
  • kleopatra
  • commands
deletecertificatescommand.cpp
Go to the documentation of this file.
1 /* -*- mode: c++; c-basic-offset:4 -*-
2  deleteCertificatescommand.cpp
3 
4  This file is part of Kleopatra, the KDE keymanager
5  Copyright (c) 2007 Klarälvdalens Datakonsult AB
6 
7  Kleopatra is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; either version 2 of the License, or
10  (at your option) any later version.
11 
12  Kleopatra is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 
21  In addition, as a special exception, the copyright holders give
22  permission to link the code of this program with any edition of
23  the Qt library by Trolltech AS, Norway (or with modified versions
24  of Qt that use the same license as Qt), and distribute linked
25  combinations including the two. You must obey the GNU General
26  Public License in all respects for all of the code used other than
27  Qt. If you modify this file, you may extend this exception to
28  your version of the file, but you are not obligated to do so. If
29  you do not wish to do so, delete this exception statement from
30  your version.
31 */
32 
33 #include <config-kleopatra.h>
34 
35 #include "deletecertificatescommand.h"
36 
37 #include "command_p.h"
38 
39 #include <dialogs/deletecertificatesdialog.h>
40 
41 #include <models/keycache.h>
42 #include <models/predicates.h>
43 
44 #include <kleo/stl_util.h>
45 #include <kleo/cryptobackend.h>
46 #include <kleo/cryptobackendfactory.h>
47 #include <kleo/multideletejob.h>
48 #include <kleo/deletejob.h>
49 
50 #include <gpgme++/key.h>
51 
52 #include <KLocale>
53 #include <KMessageBox>
54 
55 #include <QPointer>
56 #include <QAbstractItemView>
57 
58 #include <boost/bind.hpp>
59 
60 #include <algorithm>
61 #include <vector>
62 #include <cassert>
63 
64 using namespace boost;
65 using namespace GpgME;
66 using namespace Kleo;
67 using namespace Kleo::Dialogs;
68 
69 class DeleteCertificatesCommand::Private : public Command::Private {
70  friend class ::Kleo::DeleteCertificatesCommand;
71  DeleteCertificatesCommand * q_func() const { return static_cast<DeleteCertificatesCommand*>(q); }
72 public:
73  explicit Private( DeleteCertificatesCommand * qq, KeyListController * c );
74  ~Private();
75 
76  void startDeleteJob( GpgME::Protocol protocol );
77 
78  void cancelJobs();
79  void pgpDeleteResult( const GpgME::Error & );
80  void cmsDeleteResult( const GpgME::Error & );
81  void showErrorsAndFinish();
82 
83  bool canDelete( GpgME::Protocol proto ) const {
84  if ( const CryptoBackend::Protocol * const cbp = CryptoBackendFactory::instance()->protocol( proto ) )
85  if ( DeleteJob * const job = cbp->deleteJob() ) {
86  job->slotCancel();
87  return true;
88  }
89  return false;
90  }
91 
92  void ensureDialogCreated() {
93  if ( dialog )
94  return;
95  dialog = new DeleteCertificatesDialog;
96  applyWindowID( dialog );
97  dialog->setAttribute( Qt::WA_DeleteOnClose );
98  dialog->setWindowTitle( i18nc("@title:window", "Delete Certificates") );
99  connect( dialog, SIGNAL(accepted()), q_func(), SLOT(slotDialogAccepted()) );
100  connect( dialog, SIGNAL(rejected()), q_func(), SLOT(slotDialogRejected()) );
101  }
102  void ensureDialogShown() {
103  if ( dialog )
104  dialog->show();
105  }
106 
107  void slotDialogAccepted();
108  void slotDialogRejected() {
109  canceled();
110  }
111 
112 private:
113  QPointer<DeleteCertificatesDialog> dialog;
114  QPointer<MultiDeleteJob> cmsJob, pgpJob;
115  GpgME::Error cmsError, pgpError;
116  std::vector<Key> cmsKeys, pgpKeys;
117 };
118 
119 DeleteCertificatesCommand::Private * DeleteCertificatesCommand::d_func() { return static_cast<Private*>(d.get()); }
120 const DeleteCertificatesCommand::Private * DeleteCertificatesCommand::d_func() const { return static_cast<const Private*>(d.get()); }
121 
122 #define d d_func()
123 #define q q_func()
124 
125 DeleteCertificatesCommand::Private::Private( DeleteCertificatesCommand * qq, KeyListController * c )
126  : Command::Private( qq, c )
127 {
128 
129 }
130 
131 DeleteCertificatesCommand::Private::~Private() {}
132 
133 
134 DeleteCertificatesCommand::DeleteCertificatesCommand( KeyListController * p )
135  : Command( new Private( this, p ) )
136 {
137 
138 }
139 
140 DeleteCertificatesCommand::DeleteCertificatesCommand( QAbstractItemView * v, KeyListController * p )
141  : Command( v, new Private( this, p ) )
142 {
143 
144 }
145 
146 DeleteCertificatesCommand::~DeleteCertificatesCommand() {}
147 
148 namespace {
149 
150  enum Action { Nothing = 0, Failure = 1, ClearCMS = 2, ClearPGP = 4 };
151 
152  // const unsigned int errorCase =
153  // openpgp.empty() << 3U | d->canDelete( OpenPGP ) << 2U |
154  // cms.empty() << 1U | d->canDelete( CMS ) << 0U ;
155 
156  static const struct {
157  const char * text;
158  Action actions;
159  } deletionErrorCases[16] = {
160  // if havePGP
161  // if cantPGP
162  // if haveCMS
163  { I18N_NOOP( "Neither the OpenPGP nor the CMS "
164  "backends support certificate deletion.\n"
165  "Check your installation." ),
166  Failure }, // cantCMS
167  { I18N_NOOP( "The OpenPGP backend does not support "
168  "certificate deletion.\n"
169  "Check your installation.\n"
170  "Only the selected CMS certificates "
171  "will be deleted." ),
172  ClearPGP }, // canCMS
173  // if !haveCMS
174  { I18N_NOOP( "The OpenPGP backend does not support "
175  "certificate deletion.\n"
176  "Check your installation." ),
177  Failure },
178  { I18N_NOOP( "The OpenPGP backend does not support "
179  "certificate deletion.\n"
180  "Check your installation." ),
181  Failure },
182  // if canPGP
183  // if haveCMS
184  { I18N_NOOP( "The CMS backend does not support "
185  "certificate deletion.\n"
186  "Check your installation.\n"
187  "Only the selected OpenPGP certificates "
188  "will be deleted." ),
189  ClearCMS }, // cantCMS
190  { 0,
191  Nothing }, // canCMS
192  // if !haveCMS
193  { 0,
194  Nothing }, // cantCMS
195  { 0,
196  Nothing }, // canCMS
197  // if !havePGP
198  // if cantPGP
199  // if haveCMS
200  { I18N_NOOP( "The CMS backend does not support "
201  "certificate deletion.\n"
202  "Check your installation." ),
203  Failure }, // cantCMS
204  { 0,
205  Nothing }, // canCMS
206  // if !haveCMS
207  { 0,
208  Nothing }, // cantCMS
209  { 0,
210  Nothing }, // canCMS
211  // if canPGP
212  // if haveCMS
213  { I18N_NOOP( "The CMS backend does not support "
214  "certificate deletion.\n"
215  "Check your installation." ),
216  Failure }, // cantCMS
217  { 0,
218  Nothing }, // canCMS
219  // if !haveCMS
220  { 0,
221  Nothing }, // cantCMS
222  { 0,
223  Nothing }, // canCMS
224  };
225 } // anon namespace
226 
227 void DeleteCertificatesCommand::doStart() {
228 
229  std::vector<Key> selected = d->keys();
230  if ( selected.empty() ) {
231  d->finished();
232  return;
233  }
234 
235  kdtools::sort( selected, _detail::ByFingerprint<std::less>() );
236 
237  // Calculate the closure of the selected keys (those that need to
238  // be deleted with them, though not selected themselves):
239 
240  std::vector<Key> toBeDeleted = KeyCache::instance()->findSubjects( selected );
241  kdtools::sort( toBeDeleted, _detail::ByFingerprint<std::less>() );
242 
243  std::vector<Key> unselected;
244  unselected.reserve( toBeDeleted.size() );
245  std::set_difference( toBeDeleted.begin(), toBeDeleted.end(),
246  selected.begin(), selected.end(),
247  std::back_inserter( unselected ),
248  _detail::ByFingerprint<std::less>() );
249 
250  d->ensureDialogCreated();
251 
252  d->dialog->setSelectedKeys( selected );
253  d->dialog->setUnselectedKeys( unselected );
254 
255  d->ensureDialogShown();
256 
257 }
258 
259 void DeleteCertificatesCommand::Private::slotDialogAccepted() {
260  std::vector<Key> keys = dialog->keys();
261  assert( !keys.empty() );
262 
263  std::vector<Key>::iterator
264  pgpBegin = keys.begin(),
265  pgpEnd = std::stable_partition( pgpBegin, keys.end(),
266  boost::bind( &GpgME::Key::protocol, _1 ) != CMS ),
267  cmsBegin = pgpEnd,
268  cmsEnd = keys.end() ;
269 
270  std::vector<Key> openpgp( pgpBegin, pgpEnd );
271  std::vector<Key> cms( cmsBegin, cmsEnd );
272 
273  const unsigned int errorCase =
274  openpgp.empty() << 3U | canDelete( OpenPGP ) << 2U |
275  cms.empty() << 1U | canDelete( CMS ) << 0U ;
276 
277  if ( const unsigned int actions = deletionErrorCases[errorCase].actions ) {
278  information( i18n( deletionErrorCases[errorCase].text ),
279  (actions & Failure)
280  ? i18n( "Certificate Deletion Failed" )
281  : i18n( "Certificate Deletion Problem" ) );
282  if ( actions & ClearCMS )
283  cms.clear();
284  if ( actions & ClearPGP )
285  openpgp.clear();
286  if ( actions & Failure ) {
287  canceled();
288  return;
289  }
290  }
291 
292  assert( !openpgp.empty() || !cms.empty() );
293 
294  pgpKeys.swap( openpgp );
295  cmsKeys.swap( cms );
296 
297  if ( !pgpKeys.empty() )
298  startDeleteJob( GpgME::OpenPGP );
299  if ( !cmsKeys.empty() )
300  startDeleteJob( GpgME::CMS );
301 
302  if ( ( pgpKeys.empty() || pgpError.code() ) &&
303  ( cmsKeys.empty() || cmsError.code() ) )
304  showErrorsAndFinish();
305 }
306 
307 void DeleteCertificatesCommand::Private::startDeleteJob( GpgME::Protocol protocol ) {
308  assert( protocol != GpgME::UnknownProtocol );
309 
310  const std::vector<Key> & keys = protocol == CMS ? cmsKeys : pgpKeys ;
311 
312  const CryptoBackend::Protocol * const backend = CryptoBackendFactory::instance()->protocol( protocol );
313  assert( backend );
314 
315  std::auto_ptr<MultiDeleteJob> job( new MultiDeleteJob( backend ) );
316 
317  if ( protocol == CMS )
318  connect( job.get(), SIGNAL(result(GpgME::Error,GpgME::Key)),
319  q_func(), SLOT(cmsDeleteResult(GpgME::Error)) );
320  else
321  connect( job.get(), SIGNAL(result(GpgME::Error,GpgME::Key)),
322  q_func(), SLOT(pgpDeleteResult(GpgME::Error)) );
323 
324  connect( job.get(), SIGNAL(progress(QString,int,int)),
325  q, SIGNAL(progress(QString,int,int)) );
326 
327  if ( const Error err = job->start( keys, true /*allowSecretKeyDeletion*/ ) )
328  ( protocol == CMS ? cmsError : pgpError ) = err;
329  else
330  ( protocol == CMS ? cmsJob : pgpJob ) = job.release();
331 }
332 
333 void DeleteCertificatesCommand::Private::showErrorsAndFinish() {
334 
335  assert( !pgpJob ); assert( !cmsJob );
336 
337  if ( pgpError || cmsError ) {
338  QString pgpErrorString;
339  if ( pgpError )
340  pgpErrorString = i18n( "OpenPGP backend: %1", QString::fromLocal8Bit( pgpError.asString() ) );
341  QString cmsErrorString;
342  if ( cmsError )
343  cmsErrorString = i18n( "CMS backend: %1", QString::fromLocal8Bit( cmsError.asString() ) );
344 
345  const QString msg = i18n("<qt><p>An error occurred while trying to delete "
346  "the certificate:</p>"
347  "<p><b>%1</b></p></qt>",
348  pgpError ? cmsError ? pgpErrorString + QLatin1String("</br>") + cmsErrorString : pgpErrorString : cmsErrorString );
349  error( msg, i18n("Certificate Deletion Failed") );
350  } else {
351  std::vector<Key> keys = pgpKeys;
352  keys.insert( keys.end(), cmsKeys.begin(), cmsKeys.end() );
353  KeyCache::mutableInstance()->remove( keys );
354  }
355 
356  finished();
357 }
358 
359 void DeleteCertificatesCommand::doCancel() {
360  d->cancelJobs();
361 }
362 
363 void DeleteCertificatesCommand::Private::pgpDeleteResult( const Error & err ) {
364  pgpError = err;
365  pgpJob = 0;
366  if ( !cmsJob )
367  showErrorsAndFinish();
368 }
369 
370 void DeleteCertificatesCommand::Private::cmsDeleteResult( const Error & err ) {
371  cmsError = err;
372  cmsJob = 0;
373  if ( !pgpJob )
374  showErrorsAndFinish();
375 }
376 
377 void DeleteCertificatesCommand::Private::cancelJobs()
378 {
379  if ( cmsJob )
380  cmsJob->slotCancel();
381  if ( pgpJob )
382  pgpJob->slotCancel();
383 }
384 
385 #undef d
386 #undef q
387 
388 #include "moc_deletecertificatescommand.cpp"
Kleo::DeleteCertificatesCommand::DeleteCertificatesCommand
DeleteCertificatesCommand(QAbstractItemView *view, KeyListController *parent)
Definition: deletecertificatescommand.cpp:140
Action
Action
Definition: deletecertificatescommand.cpp:150
Kleo::Command::Private
Definition: commands/command_p.h:52
Kleo::KeyListController
Definition: keylistcontroller.h:55
deletecertificatescommand.h
Kleo::Command::d
kdtools::pimpl_ptr< Private > d
Definition: commands/command.h:129
q
#define q
Definition: deletecertificatescommand.cpp:123
Kleo::Class::OpenPGP
Definition: classify.h:49
Kleo::Class::CMS
Definition: classify.h:48
deletecertificatesdialog.h
command_p.h
Kleo::Dialogs::DeleteCertificatesDialog
Definition: deletecertificatesdialog.h:49
predicates.h
Kleo::KeyCache::instance
static boost::shared_ptr< const KeyCache > instance()
Definition: keycache.cpp:189
Kleo::DeleteCertificatesCommand::~DeleteCertificatesCommand
~DeleteCertificatesCommand()
Definition: deletecertificatescommand.cpp:146
keycache.h
d
#define d
Definition: deletecertificatescommand.cpp:122
Kleo::DeleteCertificatesCommand
Definition: deletecertificatescommand.h:39
Kleo::Command
Definition: commands/command.h:58
Kleo::KeyCache::mutableInstance
static boost::shared_ptr< KeyCache > mutableInstance()
Definition: keycache.cpp:193
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:56:41 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kleopatra

Skip menu "kleopatra"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdepim API Reference

Skip menu "kdepim API Reference"
  • akonadi_next
  • akregator
  • blogilo
  • calendarsupport
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt2
  • kjots
  • kleopatra
  • kmail
  • knode
  • knotes
  • kontact
  • korgac
  • korganizer
  • ktimetracker
  • libkdepim
  • libkleo
  • libkpgp
  • mailcommon
  • messagelist
  • messageviewer

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal