00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "identity.h"
00022 #include "signature.h"
00023
00024 #include <kdeversion.h>
00025 #include <sonnet/globals.h>
00026 #include <kdebug.h>
00027 #include <klocale.h>
00028 #include <kmessagebox.h>
00029 #include <kconfiggroup.h>
00030 #include <kurl.h>
00031 #include <kprocess.h>
00032 #include <kpimutils/kfileio.h>
00033 #include <kpimutils/email.h>
00034
00035 #include <QFileInfo>
00036 #include <QMimeData>
00037 #include <QByteArray>
00038
00039 #include <sys/types.h>
00040 #include <stdlib.h>
00041 #include <stdio.h>
00042 #include <errno.h>
00043 #include <assert.h>
00044
00045 using namespace KPIMIdentities;
00046
00047
00048 static Identity *identityNull = 0;
00049
00050 Identity::Identity( const QString &id, const QString &fullName,
00051 const QString &emailAddr, const QString &organization,
00052 const QString &replyToAddr )
00053 : mIsDefault( false )
00054 {
00055 setProperty( s_uoid, 0 );
00056 setProperty( s_identity, id );
00057 setProperty( s_name, fullName );
00058 setProperty( s_email, emailAddr );
00059 setProperty( s_organization, organization );
00060 setProperty( s_replyto, replyToAddr );
00061 setDictionary( Sonnet::defaultLanguageName() );
00062 }
00063
00064 Identity::~Identity()
00065 {}
00066
00067 const Identity &Identity::null()
00068 {
00069 if ( !identityNull ) {
00070 identityNull = new Identity;
00071 }
00072 return *identityNull;
00073 }
00074
00075 bool Identity::isNull() const
00076 {
00077 bool empty = true;
00078 QHash<QString, QVariant>::const_iterator i = mPropertiesMap.constBegin();
00079 while ( i != mPropertiesMap.constEnd() ) {
00080
00081
00082 if ( i.key() == s_dict && dictionary() == Sonnet::defaultLanguageName() ) {
00083 ++i;
00084 continue;
00085 }
00086
00087
00088 if ( !( i.key() == s_uoid && i.value().toUInt() == 0 ) ) {
00089 if ( !i.value().isNull() ||
00090 ( i.value().type() == QVariant::String && !i.value().toString().isEmpty() ) ) {
00091 empty = false;
00092 }
00093 }
00094 ++i;
00095 }
00096 return empty;
00097 }
00098
00099 void Identity::readConfig( const KConfigGroup &config )
00100 {
00101
00102 QMap<QString,QString> entries = config.entryMap();
00103 QMap<QString,QString>::const_iterator i = entries.constBegin();
00104 while ( i != entries.constEnd() ) {
00105 if ( i.key() == s_emailAliases ) {
00106
00107 mPropertiesMap.insert( i.key(), config.readEntry( i.key(), QStringList() ) );
00108 } else {
00109 mPropertiesMap.insert( i.key(), config.readEntry( i.key() ) );
00110 }
00111 ++i;
00112 }
00113 mSignature.readConfig( config );
00114 }
00115
00116 void Identity::writeConfig( KConfigGroup &config ) const
00117 {
00118 QHash<QString, QVariant>::const_iterator i = mPropertiesMap.constBegin();
00119 while ( i != mPropertiesMap.constEnd() ) {
00120 config.writeEntry( i.key(), i.value() );
00121 kDebug( 5325 ) << "Store:" << i.key() << ":" << i.value();
00122 ++i;
00123 }
00124 mSignature.writeConfig( config );
00125 }
00126
00127 bool Identity::mailingAllowed() const
00128 {
00129 return !property( s_email ).toString().isEmpty();
00130 }
00131
00132 QString Identity::mimeDataType()
00133 {
00134 return "application/x-kmail-identity-drag";
00135 }
00136
00137 bool Identity::canDecode( const QMimeData*md )
00138 {
00139 return md->hasFormat( mimeDataType() );
00140 }
00141
00142 void Identity::populateMimeData( QMimeData*md )
00143 {
00144 QByteArray a;
00145 {
00146 QDataStream s( &a, QIODevice::WriteOnly );
00147 s << this;
00148 }
00149 md->setData( mimeDataType(), a );
00150 }
00151
00152 Identity Identity::fromMimeData( const QMimeData*md )
00153 {
00154 Identity i;
00155 if ( canDecode( md ) ) {
00156 QByteArray ba = md->data( mimeDataType() );
00157 QDataStream s( &ba, QIODevice::ReadOnly );
00158 s >> i;
00159 }
00160 return i;
00161 }
00162
00163
00164
00165 QDataStream &KPIMIdentities::operator<<
00166 ( QDataStream &stream, const KPIMIdentities::Identity &i )
00167 {
00168 return stream << static_cast<quint32>( i.uoid() )
00169 << i.identityName()
00170 << i.fullName()
00171 << i.organization()
00172 << i.pgpSigningKey()
00173 << i.pgpEncryptionKey()
00174 << i.smimeSigningKey()
00175 << i.smimeEncryptionKey()
00176 << i.primaryEmailAddress()
00177 << i.emailAliases()
00178 << i.replyToAddr()
00179 << i.bcc()
00180 << i.vCardFile()
00181 << i.transport()
00182 << i.fcc()
00183 << i.drafts()
00184 << i.templates()
00185 << i.mPropertiesMap[s_signature]
00186 << i.dictionary()
00187 << i.xface()
00188 << i.preferredCryptoMessageFormat();
00189 }
00190
00191 QDataStream &KPIMIdentities::operator>>
00192 ( QDataStream &stream, KPIMIdentities::Identity &i )
00193 {
00194 quint32 uoid;
00195 QString format;
00196 stream
00197 >> uoid
00198 >> i.mPropertiesMap[s_identity]
00199 >> i.mPropertiesMap[s_name]
00200 >> i.mPropertiesMap[s_organization]
00201 >> i.mPropertiesMap[s_pgps]
00202 >> i.mPropertiesMap[s_pgpe]
00203 >> i.mPropertiesMap[s_smimes]
00204 >> i.mPropertiesMap[s_smimee]
00205 >> i.mPropertiesMap[s_email]
00206 >> i.mPropertiesMap[s_emailAliases]
00207 >> i.mPropertiesMap[s_replyto]
00208 >> i.mPropertiesMap[s_bcc]
00209 >> i.mPropertiesMap[s_vcard]
00210 >> i.mPropertiesMap[s_transport]
00211 >> i.mPropertiesMap[s_fcc]
00212 >> i.mPropertiesMap[s_drafts]
00213 >> i.mPropertiesMap[s_templates]
00214 >> i.mPropertiesMap[s_signature]
00215 >> i.mPropertiesMap[s_dict]
00216 >> i.mPropertiesMap[s_xface]
00217 >> i.mPropertiesMap[s_prefcrypt];
00218 i.setProperty( s_uoid, uoid );
00219 return stream;
00220 }
00221
00222 bool Identity::operator< ( const Identity &other ) const
00223 {
00224 if ( isDefault() ) {
00225 return true;
00226 }
00227 if ( other.isDefault() ) {
00228 return false;
00229 }
00230 return identityName() < other.identityName();
00231 }
00232
00233 bool Identity::operator> ( const Identity &other ) const
00234 {
00235 if ( isDefault() ) {
00236 return false;
00237 }
00238 if ( other.isDefault() ) {
00239 return true;
00240 }
00241 return identityName() > other.identityName();
00242 }
00243
00244 bool Identity::operator<= ( const Identity &other ) const
00245 {
00246 return !operator> ( other );
00247 }
00248
00249 bool Identity::operator>= ( const Identity &other ) const
00250 {
00251 return !operator< ( other );
00252 }
00253
00254 bool Identity::operator== ( const Identity &other ) const
00255 {
00256 return mPropertiesMap == other.mPropertiesMap &&
00257 mSignature == other.mSignature;
00258 }
00259
00260 bool Identity::operator!= ( const Identity &other ) const
00261 {
00262 return !operator== ( other );
00263 }
00264
00265
00266
00267 QVariant Identity::property( const QString &key ) const
00268 {
00269 return mPropertiesMap.value( key );
00270 }
00271
00272 QString Identity::fullEmailAddr( void ) const
00273 {
00274 const QString name = mPropertiesMap.value( s_name ).toString();
00275 const QString mail = mPropertiesMap.value( s_email ).toString();
00276
00277 if ( name.isEmpty() ) {
00278 return mail;
00279 }
00280
00281 const QString specials( "()<>@,.;:[]" );
00282
00283 QString result;
00284
00285
00286 bool needsQuotes=false;
00287 for ( int i=0; i < name.length(); i++ ) {
00288 if ( specials.contains( name[i] ) ) {
00289 needsQuotes = true;
00290 } else if ( name[i] == '\\' || name[i] == '"' ) {
00291 needsQuotes = true;
00292 result += '\\';
00293 }
00294 result += name[i];
00295 }
00296
00297 if ( needsQuotes ) {
00298 result.insert( 0,'"' );
00299 result += '"';
00300 }
00301
00302 result += " <" + mail + '>';
00303
00304 return result;
00305 }
00306
00307 QString Identity::identityName() const
00308 {
00309 return property( QLatin1String( s_identity ) ).toString();
00310 }
00311
00312 QString Identity::signatureText( bool *ok ) const
00313 {
00314 return mSignature.withSeparator( ok );
00315 }
00316
00317 bool Identity::signatureIsInlinedHtml() const
00318 {
00319 return mSignature.isInlinedHtml();
00320 }
00321
00322 bool Identity::isDefault() const
00323 {
00324 return mIsDefault;
00325 }
00326
00327 uint Identity::uoid() const
00328 {
00329 return property( QLatin1String( s_uoid ) ).toInt();
00330 }
00331
00332 QString Identity::fullName() const
00333 {
00334 return property( QLatin1String( s_name ) ).toString();
00335 }
00336
00337 QString Identity::organization() const
00338 {
00339 return property( QLatin1String( s_organization ) ).toString();
00340 }
00341
00342 QByteArray Identity::pgpEncryptionKey() const
00343 {
00344 return property( QLatin1String( s_pgpe ) ).toByteArray();
00345 }
00346
00347 QByteArray Identity::pgpSigningKey() const
00348 {
00349 return property( QLatin1String( s_pgps ) ).toByteArray();
00350 }
00351
00352 QByteArray Identity::smimeEncryptionKey() const
00353 {
00354 return property( QLatin1String( s_smimee ) ).toByteArray();
00355 }
00356
00357 QByteArray Identity::smimeSigningKey() const
00358 {
00359 return property( QLatin1String( s_smimes ) ).toByteArray();
00360 }
00361
00362 QString Identity::preferredCryptoMessageFormat() const
00363 {
00364 return property( QLatin1String( s_prefcrypt ) ).toString();
00365 }
00366
00367 QString Identity::emailAddr() const
00368 {
00369 return primaryEmailAddress();
00370 }
00371
00372 QString Identity::primaryEmailAddress() const
00373 {
00374 return property( QLatin1String( s_email ) ).toString();
00375 }
00376
00377 const QStringList Identity::emailAliases() const
00378 {
00379 return property( QLatin1String( s_emailAliases ) ).toStringList();
00380 }
00381
00382 QString Identity::vCardFile() const
00383 {
00384 return property( QLatin1String( s_vcard ) ).toString();
00385 }
00386
00387 QString Identity::replyToAddr() const
00388 {
00389 return property( QLatin1String( s_replyto ) ).toString();
00390 }
00391
00392 QString Identity::bcc() const
00393 {
00394 return property( QLatin1String( s_bcc ) ).toString();
00395 }
00396
00397 Signature &Identity::signature()
00398 {
00399 return mSignature;
00400 }
00401
00402 bool Identity::isXFaceEnabled() const
00403 {
00404 return property( QLatin1String( s_xfaceenabled ) ).toBool();
00405 }
00406
00407 QString Identity::xface() const
00408 {
00409 return property( QLatin1String( s_xface ) ).toString();
00410 }
00411
00412 QString Identity::dictionary() const
00413 {
00414 return property( QLatin1String( s_dict ) ).toString();
00415 }
00416
00417 QString Identity::templates() const
00418 {
00419 return property( QLatin1String( s_templates ) ).toString();
00420 }
00421
00422 QString Identity::drafts() const
00423 {
00424 return property( QLatin1String( s_drafts ) ).toString();
00425 }
00426
00427 QString Identity::fcc() const
00428 {
00429 return property( QLatin1String( s_fcc ) ).toString();
00430 }
00431
00432 QString Identity::transport() const
00433 {
00434 return property( QLatin1String( s_transport ) ).toString();
00435 }
00436
00437 bool Identity::signatureIsCommand() const
00438 {
00439 return mSignature.type() == Signature::FromCommand;
00440 }
00441
00442 bool Identity::signatureIsPlainFile() const
00443 {
00444 return mSignature.type() == Signature::FromFile;
00445 }
00446
00447 bool Identity::signatureIsInline() const
00448 {
00449 return mSignature.type() == Signature::Inlined;
00450 }
00451
00452 bool Identity::useSignatureFile() const
00453 {
00454 return signatureIsPlainFile() || signatureIsCommand();
00455 }
00456
00457 QString Identity::signatureInlineText() const
00458 {
00459 return mSignature.text();
00460 }
00461
00462 QString Identity::signatureFile() const
00463 {
00464 return mSignature.url();
00465 }
00466
00467
00468
00469 void Identity::setProperty( const QString &key, const QVariant &value )
00470 {
00471 if ( value.isNull() ||
00472 ( value.type() == QVariant::String && value.toString().isEmpty() ) ) {
00473 mPropertiesMap.remove( key );
00474 } else {
00475 mPropertiesMap.insert( key, value );
00476 }
00477 }
00478
00479 void Identity::setUoid( uint aUoid )
00480 {
00481 setProperty( s_uoid, aUoid );
00482 }
00483
00484 void Identity::setIdentityName( const QString &name )
00485 {
00486 setProperty( s_identity, name );
00487 }
00488
00489 void Identity::setFullName( const QString &str )
00490 {
00491 setProperty( s_name, str );
00492 }
00493
00494 void Identity::setOrganization( const QString &str )
00495 {
00496 setProperty( s_organization, str );
00497 }
00498
00499 void Identity::setPGPSigningKey( const QByteArray &str )
00500 {
00501 setProperty( s_pgps, QString( str ) );
00502 }
00503
00504 void Identity::setPGPEncryptionKey( const QByteArray &str )
00505 {
00506 setProperty( s_pgpe, QString( str ) );
00507 }
00508
00509 void Identity::setSMIMESigningKey( const QByteArray &str )
00510 {
00511 setProperty( s_smimes, QString( str ) );
00512 }
00513
00514 void Identity::setSMIMEEncryptionKey( const QByteArray &str )
00515 {
00516 setProperty( s_smimee, QString( str ) );
00517 }
00518
00519 void Identity::setEmailAddr( const QString &str )
00520 {
00521 setPrimaryEmailAddress( str );
00522 }
00523
00524 void Identity::setPrimaryEmailAddress( const QString & email )
00525 {
00526 setProperty( s_email, email );
00527 }
00528
00529 void Identity::setEmailAliases( const QStringList & aliases )
00530 {
00531 setProperty( s_emailAliases, aliases );
00532 }
00533
00534 void Identity::setVCardFile( const QString &str )
00535 {
00536 setProperty( s_vcard, str );
00537 }
00538
00539 void Identity::setReplyToAddr( const QString&str )
00540 {
00541 setProperty( s_replyto, str );
00542 }
00543
00544 void Identity::setSignatureFile( const QString &str )
00545 {
00546 mSignature.setUrl( str, signatureIsCommand() );
00547 }
00548
00549 void Identity::setSignatureInlineText( const QString &str )
00550 {
00551 mSignature.setText( str );
00552 }
00553
00554 void Identity::setTransport( const QString &str )
00555 {
00556 setProperty( s_transport, str );
00557 }
00558
00559 void Identity::setFcc( const QString &str )
00560 {
00561 setProperty( s_fcc, str );
00562 }
00563
00564 void Identity::setDrafts( const QString &str )
00565 {
00566 setProperty( s_drafts, str );
00567 }
00568
00569 void Identity::setTemplates( const QString &str )
00570 {
00571 setProperty( s_templates, str );
00572 }
00573
00574 void Identity::setDictionary( const QString &str )
00575 {
00576 setProperty( s_dict, str );
00577 }
00578
00579 void Identity::setBcc( const QString &str )
00580 {
00581 setProperty( s_bcc, str );
00582 }
00583
00584 void Identity::setIsDefault( bool flag )
00585 {
00586 mIsDefault = flag;
00587 }
00588
00589 void Identity::setPreferredCryptoMessageFormat( const QString &str )
00590 {
00591 setProperty( s_prefcrypt, str );
00592 }
00593
00594 void Identity::setXFace( const QString &str )
00595 {
00596 QString strNew = str;
00597 strNew.remove( ' ' );
00598 strNew.remove( '\n' );
00599 strNew.remove( '\r' );
00600 setProperty( s_xface, strNew );
00601 }
00602
00603 void Identity::setXFaceEnabled( const bool on )
00604 {
00605 setProperty( s_xfaceenabled, on );
00606 }
00607
00608 void Identity::setSignature( const Signature &sig )
00609 {
00610 mSignature = sig;
00611 }
00612
00613 bool Identity::matchesEmailAddress( const QString & addr ) const
00614 {
00615 const QString addrSpec = KPIMUtils::extractEmailAddress( addr ).toLower();
00616 if ( addrSpec == primaryEmailAddress().toLower() )
00617 return true;
00618
00619 foreach ( const QString &alias, emailAliases() ) {
00620 if ( alias.toLower() == addrSpec )
00621 return true;
00622 }
00623
00624 return false;
00625 }