kleopatra
encryptcommand.cpp
Go to the documentation of this file.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 "encryptcommand.h"
00036
00037 #include <crypto/encryptemailcontroller.h>
00038
00039 #include <utils/kleo_assert.h>
00040 #include <utils/exception.h>
00041 #include <utils/input.h>
00042 #include <utils/output.h>
00043
00044 #include <KLocale>
00045
00046 #include <QTimer>
00047
00048 using namespace Kleo;
00049 using namespace Kleo::Crypto;
00050 using namespace boost;
00051
00052 class EncryptCommand::Private : public QObject {
00053 Q_OBJECT
00054 private:
00055 friend class ::Kleo::EncryptCommand;
00056 EncryptCommand * const q;
00057 public:
00058 explicit Private( EncryptCommand * qq )
00059 : q( qq ),
00060 controller()
00061 {
00062
00063 }
00064
00065 private:
00066 void checkForErrors() const;
00067
00068 private Q_SLOTS:
00069 void slotDone();
00070 void slotError( int, const QString & );
00071 void slotRecipientsResolved();
00072
00073 private:
00074 shared_ptr<EncryptEMailController> controller;
00075 };
00076
00077 EncryptCommand::EncryptCommand()
00078 : AssuanCommandMixin<EncryptCommand>(), d( new Private( this ) )
00079 {
00080
00081 }
00082
00083 EncryptCommand::~EncryptCommand() {}
00084
00085 void EncryptCommand::Private::checkForErrors() const {
00086
00087 if ( q->numFiles() )
00088 throw Exception( makeError( GPG_ERR_CONFLICT ),
00089 i18n( "ENCRYPT is an email mode command, connection seems to be in filmanager mode" ) );
00090
00091 if ( !q->senders().empty() && !q->informativeSenders() )
00092 throw Exception( makeError( GPG_ERR_CONFLICT ),
00093 i18n( "SENDER may not be given prior to ENCRYPT, except with --info" ) );
00094
00095 if ( q->inputs().empty() )
00096 throw Exception( makeError( GPG_ERR_ASS_NO_INPUT ),
00097 i18n( "At least one INPUT must be present" ) );
00098
00099 if ( q->outputs().empty() )
00100 throw Exception( makeError( GPG_ERR_ASS_NO_OUTPUT ),
00101 i18n( "At least one OUTPUT must be present" ) );
00102
00103 if ( q->outputs().size() != q->inputs().size() )
00104 throw Exception( makeError( GPG_ERR_CONFLICT ),
00105 i18n( "INPUT/OUTPUT count mismatch" ) );
00106
00107 if ( !q->messages().empty() )
00108 throw Exception( makeError( GPG_ERR_INV_VALUE ),
00109 i18n( "MESSAGE command is not allowed before ENCRYPT" ) );
00110
00111 if ( q->hasMemento( EncryptEMailController::mementoName() ) ) {
00112
00113 const shared_ptr<EncryptEMailController> m = q->mementoContent< shared_ptr<EncryptEMailController> >( EncryptEMailController::mementoName() );
00114 kleo_assert( m );
00115
00116 if ( m->protocol() != q->checkProtocol( EMail ) )
00117 throw Exception( makeError( GPG_ERR_CONFLICT ),
00118 i18n( "Protocol given conflicts with protocol determined by PREP_ENCRYPT" ) );
00119
00120 if ( !q->recipients().empty() )
00121 throw Exception( makeError( GPG_ERR_CONFLICT ),
00122 i18n( "New recipients added after PREP_ENCRYPT command" ) );
00123 if ( !q->senders().empty() )
00124 throw Exception( makeError( GPG_ERR_CONFLICT ),
00125 i18n( "New senders added after PREP_ENCRYPT command" ) );
00126
00127 } else {
00128
00129 if ( q->recipients().empty() || q->informativeRecipients() )
00130 throw Exception( makeError( GPG_ERR_MISSING_VALUE ),
00131 i18n( "No recipients given, or only with --info" ) );
00132
00133 }
00134
00135 }
00136
00137 int EncryptCommand::doStart() {
00138
00139 d->checkForErrors();
00140
00141 const bool hasPreviousMemento = hasMemento( EncryptEMailController::mementoName() );
00142
00143 if ( hasPreviousMemento ) {
00144 d->controller = mementoContent< shared_ptr<EncryptEMailController> >( EncryptEMailController::mementoName() );
00145 removeMemento( EncryptEMailController::mementoName() );
00146 d->controller->setExecutionContext( shared_from_this() );
00147 } else {
00148 d->controller.reset( new EncryptEMailController( shared_from_this(), EncryptEMailController::GpgOLMode ) );
00149 d->controller->setProtocol( checkProtocol( EMail ) );
00150 }
00151
00152 kleo_assert( d->controller );
00153
00154 QObject::connect( d->controller.get(), SIGNAL(recipientsResolved()), d.get(), SLOT(slotRecipientsResolved()), Qt::QueuedConnection );
00155 QObject::connect( d->controller.get(), SIGNAL(done()), d.get(), SLOT(slotDone()), Qt::QueuedConnection );
00156 QObject::connect( d->controller.get(), SIGNAL(error(int,QString)), d.get(), SLOT(slotError(int,QString)), Qt::QueuedConnection );
00157
00158 if ( hasPreviousMemento )
00159 QTimer::singleShot( 0, d.get(), SLOT(slotRecipientsResolved()) );
00160 else
00161 d->controller->startResolveRecipients( recipients() );
00162
00163 return 0;
00164 }
00165
00166 void EncryptCommand::Private::slotRecipientsResolved() {
00167
00168 const shared_ptr<EncryptEMailController> cont( controller );
00169
00170 try {
00171 const QString sessionTitle = q->sessionTitle();
00172 if ( !sessionTitle.isNull() ) {
00173 Q_FOREACH ( const shared_ptr<Input> & i, q->inputs() )
00174 i->setLabel( sessionTitle );
00175 Q_FOREACH ( const shared_ptr<Output> & i, q->outputs() )
00176 i->setLabel( sessionTitle );
00177 }
00178
00179 cont->setInputsAndOutputs( q->inputs(), q->outputs() );
00180 cont->start();
00181
00182 return;
00183
00184 } catch ( const Exception & e ) {
00185 q->done( e.error(), e.message() );
00186 } catch ( const std::exception & e ) {
00187 q->done( makeError( GPG_ERR_UNEXPECTED ),
00188 i18n("Caught unexpected exception in EncryptCommand::Private::slotRecipientsResolved: %1",
00189 QString::fromLocal8Bit( e.what() ) ) );
00190 } catch ( ... ) {
00191 q->done( makeError( GPG_ERR_UNEXPECTED ),
00192 i18n("Caught unknown exception in EncryptCommand::Private::slotRecipientsResolved") );
00193 }
00194 cont->cancel();
00195 }
00196
00197 void EncryptCommand::Private::slotDone() {
00198 q->done();
00199 }
00200
00201 void EncryptCommand::Private::slotError( int err, const QString & details ) {
00202 q->done( err, details );
00203 }
00204
00205 void EncryptCommand::doCanceled() {
00206 if ( d->controller )
00207 d->controller->cancel();
00208 }
00209
00210 #include "encryptcommand.moc"
00211