00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "resourceldapkio.h"
00023 #include "resourceldapkioconfig.h"
00024
00025 #include "kldap/ldif.h"
00026 #include "kldap/ldapdn.h"
00027 #include "kldap/ldapurl.h"
00028
00029 #include <kio/netaccess.h>
00030 #include <kio/udsentry.h>
00031 #include <kdebug.h>
00032 #include <kde_file.h>
00033 #include <kglobal.h>
00034 #include <kstandarddirs.h>
00035 #include <klineedit.h>
00036 #include <klocale.h>
00037 #include <kconfig.h>
00038 #include <kstringhandler.h>
00039 #include <ktemporaryfile.h>
00040
00041 #include <QtCore/QBuffer>
00042 #include <QtCore/QEventLoop>
00043 #include <QtCore/QFile>
00044
00045 #include <stdlib.h>
00046
00047 using namespace KABC;
00048
00049 class ResourceLDAPKIO::Private
00050 {
00051 public:
00052 Private( ResourceLDAPKIO *parent )
00053 : mParent( parent ), mPort( 389 ), mAnonymous( true ), mTLS( false ),
00054 mSSL( false ), mSubTree( false ), mSASL( false ), mVer( 3 ),
00055 mRDNPrefix( 0 ), mTimeLimit( 0 ), mSizeLimit( 0 ),
00056 mCachePolicy( Cache_No ), mAutoCache( true )
00057 {
00058 KGlobal::locale()->insertCatalog( "libkldap" );
00059 }
00060
00061 KIO::Job *loadFromCache();
00062 void createCache();
00063 void activateCache();
00064 void enter_loop();
00065 QByteArray addEntry( const QString &attr, const QString &value, bool mod );
00066 QString findUid( const QString &uid );
00067 bool AddresseeToLDIF( QByteArray &ldif, const Addressee &addr, const QString &olddn );
00068
00069 ResourceLDAPKIO *mParent;
00070 QString mUser;
00071 QString mPassword;
00072 QString mDn;
00073 QString mHost;
00074 QString mFilter;
00075 int mPort;
00076 bool mAnonymous;
00077 QMap<QString, QString> mAttributes;
00078
00079 QString mErrorMsg;
00080
00081 KLDAP::Ldif mLdif;
00082 bool mTLS, mSSL, mSubTree;
00083 QString mResultDn;
00084 Addressee mAddr;
00085 Address mAd;
00086 Resource::Iterator mSaveIt;
00087 bool mSASL;
00088 QString mMech;
00089 QString mRealm, mBindDN;
00090 KLDAP::LdapUrl mLDAPUrl;
00091 int mVer;
00092 int mRDNPrefix;
00093 int mTimeLimit;
00094 int mSizeLimit;
00095 int mError;
00096 int mCachePolicy;
00097 bool mReadOnly;
00098 bool mAutoCache;
00099 QString mCacheDst;
00100 KTemporaryFile *mTmp;
00101 };
00102
00103 ResourceLDAPKIO::ResourceLDAPKIO()
00104 : Resource(), d( new Private( this ) )
00105 {
00106 d->mCacheDst = KGlobal::dirs()->saveLocation( "cache", "ldapkio" ) + '/' +
00107 type() + '_' + identifier();
00108 init();
00109 }
00110
00111 ResourceLDAPKIO::ResourceLDAPKIO( const KConfigGroup &group )
00112 : Resource( group ), d( new Private( this ) )
00113 {
00114 QMap<QString, QString> attrList;
00115 QStringList attributes = group.readEntry( "LdapAttributes", QStringList() );
00116 for ( int pos = 0; pos < attributes.count(); pos += 2 ) {
00117 d->mAttributes.insert( attributes[ pos ], attributes[ pos + 1 ] );
00118 }
00119
00120 d->mUser = group.readEntry( "LdapUser" );
00121 d->mPassword = KStringHandler::obscure( group.readEntry( "LdapPassword" ) );
00122 d->mDn = group.readEntry( "LdapDn" );
00123 d->mHost = group.readEntry( "LdapHost" );
00124 d->mPort = group.readEntry( "LdapPort", 389 );
00125 d->mFilter = group.readEntry( "LdapFilter" );
00126 d->mAnonymous = group.readEntry( "LdapAnonymous", false );
00127 d->mTLS = group.readEntry( "LdapTLS", false );
00128 d->mSSL = group.readEntry( "LdapSSL", false );
00129 d->mSubTree = group.readEntry( "LdapSubTree", false );
00130 d->mSASL = group.readEntry( "LdapSASL", false );
00131 d->mMech = group.readEntry( "LdapMech" );
00132 d->mRealm = group.readEntry( "LdapRealm" );
00133 d->mBindDN = group.readEntry( "LdapBindDN" );
00134 d->mVer = group.readEntry( "LdapVer", 3 );
00135 d->mTimeLimit = group.readEntry( "LdapTimeLimit", 0 );
00136 d->mSizeLimit = group.readEntry( "LdapSizeLimit", 0 );
00137 d->mRDNPrefix = group.readEntry( "LdapRDNPrefix", 0 );
00138 d->mCachePolicy = group.readEntry( "LdapCachePolicy", 0 );
00139 d->mAutoCache = group.readEntry( "LdapAutoCache", true );
00140 d->mCacheDst = KGlobal::dirs()->saveLocation( "cache", "ldapkio" ) + '/' +
00141 type() + '_' + identifier();
00142 init();
00143 }
00144
00145 ResourceLDAPKIO::~ResourceLDAPKIO()
00146 {
00147 delete d;
00148 }
00149
00150 void ResourceLDAPKIO::Private::enter_loop()
00151 {
00152 QEventLoop eventLoop;
00153 mParent->connect( mParent, SIGNAL( leaveModality() ), &eventLoop, SLOT( quit() ) );
00154 eventLoop.exec( QEventLoop::ExcludeUserInputEvents );
00155 }
00156
00157 void ResourceLDAPKIO::entries( KIO::Job *, const KIO::UDSEntryList &list )
00158 {
00159 KIO::UDSEntryList::ConstIterator it = list.begin();
00160 KIO::UDSEntryList::ConstIterator end = list.end();
00161 for ( ; it != end; ++it ) {
00162 const QString urlStr = (*it).stringValue( KIO::UDSEntry::UDS_URL );
00163 if ( !urlStr.isEmpty() ) {
00164 KUrl tmpurl( urlStr );
00165 d->mResultDn = tmpurl.path();
00166 kDebug() << "findUid():" << d->mResultDn;
00167 if ( d->mResultDn.startsWith( '/' ) ) {
00168 d->mResultDn.remove( 0, 1 );
00169 }
00170 return;
00171 }
00172 }
00173 }
00174
00175 void ResourceLDAPKIO::listResult( KJob *job )
00176 {
00177 d->mError = job->error();
00178 if ( d->mError && d->mError != KIO::ERR_USER_CANCELED ) {
00179 d->mErrorMsg = job->errorString();
00180 } else {
00181 d->mErrorMsg = "";
00182 }
00183 emit leaveModality();
00184 }
00185
00186 QString ResourceLDAPKIO::Private::findUid( const QString &uid )
00187 {
00188 KLDAP::LdapUrl url( mLDAPUrl );
00189 KIO::UDSEntry entry;
00190
00191 mErrorMsg.clear();
00192 mResultDn.clear();
00193
00194 url.setAttributes( QStringList( "dn" ) );
00195 url.setFilter( '(' + mAttributes[ "uid" ] + '=' + uid + ')' + mFilter );
00196 url.setExtension( "x-dir", "one" );
00197
00198 kDebug() << uid << "url" << url.prettyUrl();
00199
00200 KIO::ListJob *listJob = KIO::listDir( url, KIO::HideProgressInfo );
00201 mParent->connect( listJob, SIGNAL( entries( KIO::Job *, const KIO::UDSEntryList& ) ),
00202 SLOT( entries( KIO::Job*, const KIO::UDSEntryList& ) ) );
00203 mParent->connect( listJob, SIGNAL( result( KJob* ) ),
00204 mParent, SLOT( listResult( KJob* ) ) );
00205
00206 enter_loop();
00207 return mResultDn;
00208 }
00209
00210 QByteArray ResourceLDAPKIO::Private::addEntry( const QString &attr, const QString &value, bool mod )
00211 {
00212 QByteArray tmp;
00213 if ( !attr.isEmpty() ) {
00214 if ( mod ) {
00215 tmp += KLDAP::Ldif::assembleLine( "replace", attr ) + '\n';
00216 }
00217 tmp += KLDAP::Ldif::assembleLine( attr, value ) + '\n';
00218 if ( mod ) {
00219 tmp += "-\n";
00220 }
00221 }
00222 return tmp;
00223 }
00224
00225 bool ResourceLDAPKIO::Private::AddresseeToLDIF( QByteArray &ldif, const Addressee &addr,
00226 const QString &olddn )
00227 {
00228 QByteArray tmp;
00229 QString dn;
00230 QByteArray data;
00231 bool mod = false;
00232
00233 if ( olddn.isEmpty() ) {
00234
00235 switch ( mRDNPrefix ) {
00236 case 1:
00237 dn = mAttributes[ "uid" ] + '=' + addr.uid() + ',' + mDn;
00238 break;
00239 case 0:
00240 default:
00241 dn = mAttributes[ "commonName" ] + '=' + addr.assembledName() + ',' + mDn;
00242 break;
00243 }
00244 } else {
00245
00246 mod = true;
00247 if ( olddn.startsWith( mAttributes[ "uid" ] ) ) {
00248 dn = mAttributes[ "uid" ] + '=' + addr.uid() + ',' + olddn.section( ',', 1 );
00249 } else if ( olddn.startsWith( mAttributes[ "commonName" ] ) ) {
00250 dn = mAttributes[ "commonName" ] + '=' + addr.assembledName() + ',' +
00251 olddn.section( ',', 1 );
00252 } else {
00253 dn = olddn;
00254 }
00255
00256 if ( olddn.toLower() != dn.toLower() ) {
00257 tmp = KLDAP::Ldif::assembleLine( "dn", olddn ) + '\n';
00258 tmp += "changetype: modrdn\n";
00259 tmp += KLDAP::Ldif::assembleLine( "newrdn", dn.section( ',', 0, 0 ) ) + '\n';
00260 tmp += "deleteoldrdn: 1\n\n";
00261 }
00262 }
00263
00264 tmp += KLDAP::Ldif::assembleLine( "dn", dn ) + '\n';
00265 if ( mod ) {
00266 tmp += "changetype: modify\n";
00267 }
00268 if ( !mod ) {
00269 tmp += "objectClass: top\n";
00270 const QStringList obclass = mAttributes[ "objectClass" ].split( ',', QString::SkipEmptyParts );
00271 for ( QStringList::const_iterator it = obclass.constBegin(); it != obclass.constEnd(); ++it ) {
00272 tmp += KLDAP::Ldif::assembleLine( "objectClass", *it ) + '\n';
00273 }
00274 }
00275
00276 tmp += addEntry( mAttributes[ "commonName" ], addr.assembledName(), mod );
00277 tmp += addEntry( mAttributes[ "formattedName" ], addr.formattedName(), mod );
00278 tmp += addEntry( mAttributes[ "givenName" ], addr.givenName(), mod );
00279 tmp += addEntry( mAttributes[ "familyName" ], addr.familyName(), mod );
00280 tmp += addEntry( mAttributes[ "uid" ], addr.uid(), mod );
00281
00282 PhoneNumber number;
00283 number = addr.phoneNumber( PhoneNumber::Home );
00284 tmp += addEntry( mAttributes[ "phoneNumber" ], number.number().toUtf8(), mod );
00285 number = addr.phoneNumber( PhoneNumber::Work );
00286 tmp += addEntry( mAttributes[ "telephoneNumber" ], number.number().toUtf8(), mod );
00287 number = addr.phoneNumber( PhoneNumber::Fax );
00288 tmp += addEntry( mAttributes[ "facsimileTelephoneNumber" ], number.number().toUtf8(), mod );
00289 number = addr.phoneNumber( PhoneNumber::Cell );
00290 tmp += addEntry( mAttributes[ "mobile" ], number.number().toUtf8(), mod );
00291 number = addr.phoneNumber( PhoneNumber::Pager );
00292 tmp += addEntry( mAttributes[ "pager" ], number.number().toUtf8(), mod );
00293
00294 tmp += addEntry( mAttributes[ "description" ], addr.note(), mod );
00295 tmp += addEntry( mAttributes[ "title" ], addr.title(), mod );
00296 tmp += addEntry( mAttributes[ "organization" ], addr.organization(), mod );
00297
00298 Address ad = addr.address( Address::Home );
00299 if ( !ad.isEmpty() ) {
00300 tmp += addEntry( mAttributes[ "street" ], ad.street(), mod );
00301 tmp += addEntry( mAttributes[ "state" ], ad.region(), mod );
00302 tmp += addEntry( mAttributes[ "city" ], ad.locality(), mod );
00303 tmp += addEntry( mAttributes[ "postalcode" ], ad.postalCode(), mod );
00304 }
00305
00306 QStringList emails = addr.emails();
00307 QStringList::ConstIterator mailIt = emails.constBegin();
00308
00309 if ( !mAttributes[ "mail" ].isEmpty() ) {
00310 if ( mod ) {
00311 tmp += KLDAP::Ldif::assembleLine( "replace", mAttributes[ "mail" ] ) + '\n';
00312 }
00313 if ( mailIt != emails.constEnd() ) {
00314 tmp += KLDAP::Ldif::assembleLine( mAttributes[ "mail" ], *mailIt ) + '\n';
00315 mailIt ++;
00316 }
00317 if ( mod && mAttributes[ "mail" ] != mAttributes[ "mailAlias" ] ) {
00318 tmp += "-\n";
00319 }
00320 }
00321
00322 if ( !mAttributes[ "mailAlias" ].isEmpty() ) {
00323 if ( mod && mAttributes[ "mail" ] != mAttributes[ "mailAlias" ] ) {
00324 tmp += KLDAP::Ldif::assembleLine( "replace", mAttributes[ "mailAlias" ] ) + '\n';
00325 }
00326 for ( ; mailIt != emails.constEnd(); ++mailIt ) {
00327 tmp += KLDAP::Ldif::assembleLine( mAttributes[ "mailAlias" ], *mailIt ) + '\n';
00328 }
00329 if ( mod ) {
00330 tmp += "-\n";
00331 }
00332 }
00333
00334 if ( !mAttributes[ "jpegPhoto" ].isEmpty() ) {
00335 QByteArray pic;
00336 QBuffer buffer( &pic );
00337 buffer.open( QIODevice::WriteOnly );
00338 addr.photo().data().save( &buffer, "JPEG" );
00339
00340 if ( mod ) {
00341 tmp += KLDAP::Ldif::assembleLine( "replace", mAttributes[ "jpegPhoto" ] ) + '\n';
00342 }
00343 tmp += KLDAP::Ldif::assembleLine( mAttributes[ "jpegPhoto" ], pic, 76 ) + '\n';
00344 if ( mod ) {
00345 tmp += "-\n";
00346 }
00347 }
00348
00349 tmp += '\n';
00350 kDebug() << "ldif:" << QString::fromUtf8( tmp );
00351 ldif = tmp;
00352 return true;
00353 }
00354
00355 void ResourceLDAPKIO::setReadOnly( bool value )
00356 {
00357
00358 d->mReadOnly = true;
00359 Resource::setReadOnly( value );
00360 }
00361
00362 void ResourceLDAPKIO::init()
00363 {
00364 if ( d->mPort == 0 ) {
00365 d->mPort = 389;
00366 }
00367
00374 if ( !d->mAttributes.contains( "objectClass" ) ) {
00375 d->mAttributes.insert( "objectClass", "inetOrgPerson" );
00376 }
00377 if ( !d->mAttributes.contains( "commonName" ) ) {
00378 d->mAttributes.insert( "commonName", "cn" );
00379 }
00380 if ( !d->mAttributes.contains( "formattedName" ) ) {
00381 d->mAttributes.insert( "formattedName", "displayName" );
00382 }
00383 if ( !d->mAttributes.contains( "familyName" ) ) {
00384 d->mAttributes.insert( "familyName", "sn" );
00385 }
00386 if ( !d->mAttributes.contains( "givenName" ) ) {
00387 d->mAttributes.insert( "givenName", "givenName" );
00388 }
00389 if ( !d->mAttributes.contains( "mail" ) ) {
00390 d->mAttributes.insert( "mail", "mail" );
00391 }
00392 if ( !d->mAttributes.contains( "mailAlias" ) ) {
00393 d->mAttributes.insert( "mailAlias", "" );
00394 }
00395 if ( !d->mAttributes.contains( "phoneNumber" ) ) {
00396 d->mAttributes.insert( "phoneNumber", "homePhone" );
00397 }
00398 if ( !d->mAttributes.contains( "telephoneNumber" ) ) {
00399 d->mAttributes.insert( "telephoneNumber", "telephoneNumber" );
00400 }
00401 if ( !d->mAttributes.contains( "facsimileTelephoneNumber" ) ) {
00402 d->mAttributes.insert( "facsimileTelephoneNumber", "facsimileTelephoneNumber" );
00403 }
00404 if ( !d->mAttributes.contains( "mobile" ) ) {
00405 d->mAttributes.insert( "mobile", "mobile" );
00406 }
00407 if ( !d->mAttributes.contains( "pager" ) ) {
00408 d->mAttributes.insert( "pager", "pager" );
00409 }
00410 if ( !d->mAttributes.contains( "description" ) ) {
00411 d->mAttributes.insert( "description", "description" );
00412 }
00413 if ( !d->mAttributes.contains( "title" ) ) {
00414 d->mAttributes.insert( "title", "title" );
00415 }
00416 if ( !d->mAttributes.contains( "street" ) ) {
00417 d->mAttributes.insert( "street", "street" );
00418 }
00419 if ( !d->mAttributes.contains( "state" ) ) {
00420 d->mAttributes.insert( "state", "st" );
00421 }
00422 if ( !d->mAttributes.contains( "city" ) ) {
00423 d->mAttributes.insert( "city", "l" );
00424 }
00425 if ( !d->mAttributes.contains( "organization" ) ) {
00426 d->mAttributes.insert( "organization", "o" );
00427 }
00428 if ( !d->mAttributes.contains( "postalcode" ) ) {
00429 d->mAttributes.insert( "postalcode", "postalCode" );
00430 }
00431 if ( !d->mAttributes.contains( "uid" ) ) {
00432 d->mAttributes.insert( "uid", "uid" );
00433 }
00434 if ( !d->mAttributes.contains( "jpegPhoto" ) ) {
00435 d->mAttributes.insert( "jpegPhoto", "jpegPhoto" );
00436 }
00437
00438 d->mLDAPUrl = KLDAP::LdapUrl( KUrl() );
00439 if ( !d->mAnonymous ) {
00440 d->mLDAPUrl.setExtension( "bindname", d->mBindDN );
00441 d->mLDAPUrl.setUser( d->mUser );
00442 d->mLDAPUrl.setPass( d->mPassword );
00443 }
00444 d->mLDAPUrl.setProtocol( d->mSSL ? "ldaps" : "ldap" );
00445 d->mLDAPUrl.setHost( d->mHost );
00446 d->mLDAPUrl.setPort( d->mPort );
00447 d->mLDAPUrl.setDn( KLDAP::LdapDN( d->mDn ) );
00448
00449 if ( !d->mAttributes.empty() ) {
00450 QMap<QString,QString>::Iterator it;
00451 QStringList attr;
00452 for ( it = d->mAttributes.begin(); it != d->mAttributes.end(); ++it ) {
00453 if ( !it.value().isEmpty() && it.key() != "objectClass" ) {
00454 attr.append( it.value() );
00455 }
00456 }
00457 d->mLDAPUrl.setAttributes( attr );
00458 }
00459
00460 d->mLDAPUrl.setScope( d->mSubTree ? KLDAP::LdapUrl::Sub : KLDAP::LdapUrl::One );
00461 if ( !d->mFilter.isEmpty() && d->mFilter != "(objectClass=*)" ) {
00462 d->mLDAPUrl.setFilter( d->mFilter );
00463 }
00464 d->mLDAPUrl.setExtension( "x-dir", "base" );
00465 if ( d->mTLS ) {
00466 d->mLDAPUrl.setExtension( "x-tls", "" );
00467 }
00468 d->mLDAPUrl.setExtension( "x-ver", QString::number( d->mVer ) );
00469 if ( d->mSizeLimit ) {
00470 d->mLDAPUrl.setExtension( "x-sizelimit", QString::number( d->mSizeLimit ) );
00471 }
00472 if ( d->mTimeLimit ) {
00473 d->mLDAPUrl.setExtension( "x-timelimit", QString::number( d->mTimeLimit ) );
00474 }
00475 if ( d->mSASL ) {
00476 d->mLDAPUrl.setExtension( "x-sasl", "" );
00477 if ( !d->mMech.isEmpty() ) {
00478 d->mLDAPUrl.setExtension( "x-mech", d->mMech );
00479 }
00480 if ( !d->mRealm.isEmpty() ) {
00481 d->mLDAPUrl.setExtension( "x-realm", d->mRealm );
00482 }
00483 }
00484
00485 d->mReadOnly = readOnly();
00486
00487 kDebug() << "resource_ldapkio url:" << d->mLDAPUrl.prettyUrl();
00488 }
00489
00490 void ResourceLDAPKIO::writeConfig( KConfigGroup &group )
00491 {
00492 Resource::writeConfig( group );
00493
00494 group.writeEntry( "LdapUser", d->mUser );
00495 group.writeEntry( "LdapPassword", KStringHandler::obscure( d->mPassword ) );
00496 group.writeEntry( "LdapDn", d->mDn );
00497 group.writeEntry( "LdapHost", d->mHost );
00498 group.writeEntry( "LdapPort", d->mPort );
00499 group.writeEntry( "LdapFilter", d->mFilter );
00500 group.writeEntry( "LdapAnonymous", d->mAnonymous );
00501 group.writeEntry( "LdapTLS", d->mTLS );
00502 group.writeEntry( "LdapSSL", d->mSSL );
00503 group.writeEntry( "LdapSubTree", d->mSubTree );
00504 group.writeEntry( "LdapSASL", d->mSASL );
00505 group.writeEntry( "LdapMech", d->mMech );
00506 group.writeEntry( "LdapVer", d->mVer );
00507 group.writeEntry( "LdapTimeLimit", d->mTimeLimit );
00508 group.writeEntry( "LdapSizeLimit", d->mSizeLimit );
00509 group.writeEntry( "LdapRDNPrefix", d->mRDNPrefix );
00510 group.writeEntry( "LdapRealm", d->mRealm );
00511 group.writeEntry( "LdapBindDN", d->mBindDN );
00512 group.writeEntry( "LdapCachePolicy", d->mCachePolicy );
00513 group.writeEntry( "LdapAutoCache", d->mAutoCache );
00514
00515 QStringList attributes;
00516 QMap<QString, QString>::const_iterator it;
00517 for ( it = d->mAttributes.constBegin(); it != d->mAttributes.constEnd(); ++it ) {
00518 attributes << it.key() << it.value();
00519 }
00520
00521 group.writeEntry( "LdapAttributes", attributes );
00522 }
00523
00524 Ticket *ResourceLDAPKIO::requestSaveTicket()
00525 {
00526 if ( !addressBook() ) {
00527 kDebug() << "no addressbook";
00528 return 0;
00529 }
00530
00531 return createTicket( this );
00532 }
00533
00534 void ResourceLDAPKIO::releaseSaveTicket( Ticket *ticket )
00535 {
00536 delete ticket;
00537 }
00538
00539 bool ResourceLDAPKIO::doOpen()
00540 {
00541 return true;
00542 }
00543
00544 void ResourceLDAPKIO::doClose()
00545 {
00546 }
00547
00548 void ResourceLDAPKIO::Private::createCache()
00549 {
00550 mTmp = 0;
00551 if ( mCachePolicy == Cache_NoConnection && mAutoCache ) {
00552 mTmp = new KTemporaryFile;
00553 mTmp->setPrefix( mCacheDst );
00554 mTmp->setSuffix( "tmp" );
00555 mTmp->open();
00556 }
00557 }
00558
00559 void ResourceLDAPKIO::Private::activateCache()
00560 {
00561 if ( mTmp && mError == 0 ) {
00562 QString filename = mTmp->fileName();
00563 delete mTmp;
00564 mTmp = 0;
00565 KDE_rename( QFile::encodeName( filename ), QFile::encodeName( mCacheDst ) );
00566 }
00567 }
00568
00569 KIO::Job *ResourceLDAPKIO::Private::loadFromCache()
00570 {
00571 KIO::Job *job = 0;
00572 if ( mCachePolicy == Cache_Always ||
00573 ( mCachePolicy == Cache_NoConnection &&
00574 mError == KIO::ERR_COULD_NOT_CONNECT ) ) {
00575
00576 mAddr = Addressee();
00577 mAd = Address( Address::Home );
00578
00579 mLdif.startParsing();
00580
00581 mParent->Resource::setReadOnly( true );
00582
00583 KUrl url( mCacheDst );
00584 job = KIO::get( url, KIO::Reload, KIO::HideProgressInfo );
00585 mParent->connect( job, SIGNAL( data( KIO::Job*, const QByteArray& ) ),
00586 mParent, SLOT( data( KIO::Job*, const QByteArray& ) ) );
00587 }
00588
00589 return job;
00590 }
00591
00592 bool ResourceLDAPKIO::load()
00593 {
00594 kDebug();
00595 KIO::Job *job;
00596
00597 clear();
00598
00599 d->mAddr = Addressee();
00600 d->mAd = Address( Address::Home );
00601
00602 d->mLdif.startParsing();
00603
00604
00605 Resource::setReadOnly( d->mReadOnly );
00606
00607 d->createCache();
00608 if ( d->mCachePolicy != Cache_Always ) {
00609 job = KIO::get( d->mLDAPUrl, KIO::Reload, KIO::HideProgressInfo );
00610 connect( job, SIGNAL( data( KIO::Job*, const QByteArray& ) ),
00611 this, SLOT( data( KIO::Job*, const QByteArray& ) ) );
00612 connect( job, SIGNAL( result( KJob* ) ),
00613 this, SLOT( syncLoadSaveResult( KJob* ) ) );
00614 d->enter_loop();
00615 }
00616
00617 job = d->loadFromCache();
00618 if ( job ) {
00619 connect( job, SIGNAL( result( KJob* ) ),
00620 this, SLOT( syncLoadSaveResult( KJob* ) ) );
00621 d->enter_loop();
00622 }
00623 if ( d->mErrorMsg.isEmpty() ) {
00624 kDebug() << "ResourceLDAPKIO load ok!";
00625 return true;
00626 } else {
00627 kDebug() << "ResourceLDAPKIO load finished with error:" << d->mErrorMsg;
00628 addressBook()->error( d->mErrorMsg );
00629 return false;
00630 }
00631 }
00632
00633 bool ResourceLDAPKIO::asyncLoad()
00634 {
00635 clear();
00636
00637 d->mAddr = Addressee();
00638 d->mAd = Address( Address::Home );
00639
00640 d->mLdif.startParsing();
00641
00642 Resource::setReadOnly( d->mReadOnly );
00643
00644 d->createCache();
00645 if ( d->mCachePolicy != Cache_Always ) {
00646 KIO::Job *job = KIO::get( d->mLDAPUrl, KIO::Reload, KIO::HideProgressInfo );
00647 connect( job, SIGNAL( data( KIO::Job*, const QByteArray& ) ),
00648 this, SLOT( data( KIO::Job*, const QByteArray& ) ) );
00649 connect( job, SIGNAL( result( KJob* ) ),
00650 this, SLOT( result( KJob* ) ) );
00651 } else {
00652 result( 0 );
00653 }
00654 return true;
00655 }
00656
00657 void ResourceLDAPKIO::data( KIO::Job *job, const QByteArray &data )
00658 {
00659 Q_UNUSED( job );
00660 if ( data.size() ) {
00661 d->mLdif.setLdif( data );
00662 if ( d->mTmp ) {
00663 d->mTmp->write( data );
00664 }
00665 } else {
00666 d->mLdif.endLdif();
00667 }
00668
00669 KLDAP::Ldif::ParseValue ret;
00670 QString name;
00671 QByteArray value;
00672 do {
00673 ret = d->mLdif.nextItem();
00674 switch ( ret ) {
00675 case KLDAP::Ldif::NewEntry:
00676 kDebug() << "new entry:" << d->mLdif.dn().toString();
00677 break;
00678 case KLDAP::Ldif::Item:
00679 name = d->mLdif.attr().toLower();
00680 value = d->mLdif.value();
00681 if ( name == d->mAttributes[ "commonName" ].toLower() ) {
00682 if ( !d->mAddr.formattedName().isEmpty() ) {
00683 QString fn = d->mAddr.formattedName();
00684 d->mAddr.setNameFromString( QString::fromUtf8( value, value.size() ) );
00685 d->mAddr.setFormattedName( fn );
00686 } else {
00687 d->mAddr.setNameFromString( QString::fromUtf8( value, value.size() ) );
00688 }
00689 } else if ( name == d->mAttributes[ "formattedName" ].toLower() ) {
00690 d->mAddr.setFormattedName( QString::fromUtf8( value, value.size() ) );
00691 } else if ( name == d->mAttributes[ "givenName" ].toLower() ) {
00692 d->mAddr.setGivenName( QString::fromUtf8( value, value.size() ) );
00693 } else if ( name == d->mAttributes[ "mail" ].toLower() ) {
00694 d->mAddr.insertEmail( QString::fromUtf8( value, value.size() ), true );
00695 } else if ( name == d->mAttributes[ "mailAlias" ].toLower() ) {
00696 d->mAddr.insertEmail( QString::fromUtf8( value, value.size() ), false );
00697 } else if ( name == d->mAttributes[ "phoneNumber" ].toLower() ) {
00698 PhoneNumber phone;
00699 phone.setNumber( QString::fromUtf8( value, value.size() ) );
00700 d->mAddr.insertPhoneNumber( phone );
00701 } else if ( name == d->mAttributes[ "telephoneNumber" ].toLower() ) {
00702 PhoneNumber phone( QString::fromUtf8( value, value.size() ),
00703 PhoneNumber::Work );
00704 d->mAddr.insertPhoneNumber( phone );
00705 } else if ( name == d->mAttributes[ "facsimileTelephoneNumber" ].toLower() ) {
00706 PhoneNumber phone( QString::fromUtf8( value, value.size() ),
00707 PhoneNumber::Fax );
00708 d->mAddr.insertPhoneNumber( phone );
00709 } else if ( name == d->mAttributes[ "mobile" ].toLower() ) {
00710 PhoneNumber phone( QString::fromUtf8( value, value.size() ),
00711 PhoneNumber::Cell );
00712 d->mAddr.insertPhoneNumber( phone );
00713 } else if ( name == d->mAttributes[ "pager" ].toLower() ) {
00714 PhoneNumber phone( QString::fromUtf8( value, value.size() ),
00715 PhoneNumber::Pager );
00716 d->mAddr.insertPhoneNumber( phone );
00717 } else if ( name == d->mAttributes[ "description" ].toLower() ) {
00718 d->mAddr.setNote( QString::fromUtf8( value, value.size() ) );
00719 } else if ( name == d->mAttributes[ "title" ].toLower() ) {
00720 d->mAddr.setTitle( QString::fromUtf8( value, value.size() ) );
00721 } else if ( name == d->mAttributes[ "street" ].toLower() ) {
00722 d->mAd.setStreet( QString::fromUtf8( value, value.size() ) );
00723 } else if ( name == d->mAttributes[ "state" ].toLower() ) {
00724 d->mAd.setRegion( QString::fromUtf8( value, value.size() ) );
00725 } else if ( name == d->mAttributes[ "city" ].toLower() ) {
00726 d->mAd.setLocality( QString::fromUtf8( value, value.size() ) );
00727 } else if ( name == d->mAttributes[ "postalcode" ].toLower() ) {
00728 d->mAd.setPostalCode( QString::fromUtf8( value, value.size() ) );
00729 } else if ( name == d->mAttributes[ "organization" ].toLower() ) {
00730 d->mAddr.setOrganization( QString::fromUtf8( value, value.size() ) );
00731 } else if ( name == d->mAttributes[ "familyName" ].toLower() ) {
00732 d->mAddr.setFamilyName( QString::fromUtf8( value, value.size() ) );
00733 } else if ( name == d->mAttributes[ "uid" ].toLower() ) {
00734 d->mAddr.setUid( QString::fromUtf8( value, value.size() ) );
00735 } else if ( name == d->mAttributes[ "jpegPhoto" ].toLower() ) {
00736 KABC::Picture photo;
00737 QImage img = QImage::fromData( value );
00738 if ( !img.isNull() ) {
00739 photo.setData( img );
00740 photo.setType( "image/jpeg" );
00741 d->mAddr.setPhoto( photo );
00742 }
00743 }
00744
00745 break;
00746 case KLDAP::Ldif::EndEntry:
00747 {
00748 d->mAddr.setResource( this );
00749 d->mAddr.insertAddress( d->mAd );
00750 d->mAddr.setChanged( false );
00751 insertAddressee( d->mAddr );
00752
00753 d->mAddr = Addressee();
00754 d->mAd = Address( Address::Home );
00755 }
00756 break;
00757 default:
00758 break;
00759 }
00760 } while ( ret != KLDAP::Ldif::MoreData );
00761 }
00762
00763 void ResourceLDAPKIO::loadCacheResult( KJob *job )
00764 {
00765 d->mErrorMsg.clear();
00766 d->mError = job->error();
00767 if ( d->mError && d->mError != KIO::ERR_USER_CANCELED ) {
00768 d->mErrorMsg = job->errorString();
00769 }
00770 if ( !d->mErrorMsg.isEmpty() ) {
00771 emit loadingError( this, d->mErrorMsg );
00772 } else {
00773 emit loadingFinished( this );
00774 }
00775 }
00776
00777 void ResourceLDAPKIO::result( KJob *job )
00778 {
00779 d->mErrorMsg.clear();
00780 if ( job ) {
00781 d->mError = job->error();
00782 if ( d->mError && d->mError != KIO::ERR_USER_CANCELED ) {
00783 d->mErrorMsg = job->errorString();
00784 }
00785 } else {
00786 d->mError = 0;
00787 }
00788 d->activateCache();
00789
00790 KIO::Job *cjob;
00791 cjob = d->loadFromCache();
00792 if ( cjob ) {
00793 connect( cjob, SIGNAL( result( KJob* ) ),
00794 this, SLOT( loadCacheResult( KJob* ) ) );
00795 } else {
00796 if ( !d->mErrorMsg.isEmpty() ) {
00797 emit loadingError( this, d->mErrorMsg );
00798 } else {
00799 emit loadingFinished( this );
00800 }
00801 }
00802 }
00803
00804 bool ResourceLDAPKIO::save( Ticket *ticket )
00805 {
00806 Q_UNUSED( ticket );
00807 kDebug();
00808
00809 d->mSaveIt = begin();
00810 KIO::Job *job = KIO::put( d->mLDAPUrl, -1, KIO::Overwrite | KIO::HideProgressInfo );
00811 connect( job, SIGNAL( dataReq( KIO::Job*, QByteArray& ) ),
00812 this, SLOT( saveData( KIO::Job*, QByteArray& ) ) );
00813 connect( job, SIGNAL( result( KJob* ) ),
00814 this, SLOT( syncLoadSaveResult( KJob* ) ) );
00815 d->enter_loop();
00816 if ( d->mErrorMsg.isEmpty() ) {
00817 kDebug() << "ResourceLDAPKIO save ok!";
00818 return true;
00819 } else {
00820 kDebug() << "ResourceLDAPKIO finished with error:" << d->mErrorMsg;
00821 addressBook()->error( d->mErrorMsg );
00822 return false;
00823 }
00824 }
00825
00826 bool ResourceLDAPKIO::asyncSave( Ticket *ticket )
00827 {
00828 Q_UNUSED( ticket );
00829 kDebug();
00830 d->mSaveIt = begin();
00831 KIO::Job *job = KIO::put( d->mLDAPUrl, -1, KIO::Overwrite | KIO::HideProgressInfo );
00832 connect( job, SIGNAL( dataReq( KIO::Job*, QByteArray& ) ),
00833 this, SLOT( saveData( KIO::Job*, QByteArray& ) ) );
00834 connect( job, SIGNAL( result( KJob* ) ),
00835 this, SLOT( saveResult( KJob* ) ) );
00836 return true;
00837 }
00838
00839 void ResourceLDAPKIO::syncLoadSaveResult( KJob *job )
00840 {
00841 d->mError = job->error();
00842 if ( d->mError && d->mError != KIO::ERR_USER_CANCELED ) {
00843 d->mErrorMsg = job->errorString();
00844 } else {
00845 d->mErrorMsg.clear();
00846 }
00847 d->activateCache();
00848
00849 emit leaveModality();
00850 }
00851
00852 void ResourceLDAPKIO::saveResult( KJob *job )
00853 {
00854 d->mError = job->error();
00855 if ( d->mError && d->mError != KIO::ERR_USER_CANCELED ) {
00856 emit savingError( this, job->errorString() );
00857 } else {
00858 emit savingFinished( this );
00859 }
00860 }
00861
00862 void ResourceLDAPKIO::saveData( KIO::Job *job, QByteArray &data )
00863 {
00864 Q_UNUSED( job );
00865 while ( d->mSaveIt != end() && !(*d->mSaveIt).changed() ) {
00866 d->mSaveIt++;
00867 }
00868
00869 if ( d->mSaveIt == end() ) {
00870 kDebug() << "ResourceLDAPKIO endData";
00871 data.resize( 0 );
00872 return;
00873 }
00874
00875 kDebug() << "ResourceLDAPKIO saveData:" << (*d->mSaveIt).assembledName();
00876
00877 d->AddresseeToLDIF( data, *d->mSaveIt, d->findUid( (*d->mSaveIt).uid() ) );
00878
00879
00880 (*d->mSaveIt).setChanged( false );
00881
00882 d->mSaveIt++;
00883 }
00884
00885 void ResourceLDAPKIO::removeAddressee( const Addressee &addr )
00886 {
00887 QString dn = d->findUid( addr.uid() );
00888
00889 kDebug() << dn;
00890
00891 if ( !d->mErrorMsg.isEmpty() ) {
00892 addressBook()->error( d->mErrorMsg );
00893 return;
00894 }
00895 if ( !dn.isEmpty() ) {
00896 kDebug() << "ResourceLDAPKIO: found uid:" << dn;
00897 KLDAP::LdapUrl url( d->mLDAPUrl );
00898 url.setPath( '/' + dn );
00899 url.setExtension( "x-dir", "base" );
00900 url.setScope( KLDAP::LdapUrl::Base );
00901 if ( KIO::NetAccess::del( url, 0 ) ) {
00902 mAddrMap.remove( addr.uid() );
00903 }
00904 } else {
00905
00906 mAddrMap.remove( addr.uid() );
00907 }
00908 }
00909
00910 void ResourceLDAPKIO::setUser( const QString &user )
00911 {
00912 d->mUser = user;
00913 }
00914
00915 QString ResourceLDAPKIO::user() const
00916 {
00917 return d->mUser;
00918 }
00919
00920 void ResourceLDAPKIO::setPassword( const QString &password )
00921 {
00922 d->mPassword = password;
00923 }
00924
00925 QString ResourceLDAPKIO::password() const
00926 {
00927 return d->mPassword;
00928 }
00929
00930 void ResourceLDAPKIO::setDn( const QString &dn )
00931 {
00932 d->mDn = dn;
00933 }
00934
00935 QString ResourceLDAPKIO::dn() const
00936 {
00937 return d->mDn;
00938 }
00939
00940 void ResourceLDAPKIO::setHost( const QString &host )
00941 {
00942 d->mHost = host;
00943 }
00944
00945 QString ResourceLDAPKIO::host() const
00946 {
00947 return d->mHost;
00948 }
00949
00950 void ResourceLDAPKIO::setPort( int port )
00951 {
00952 d->mPort = port;
00953 }
00954
00955 int ResourceLDAPKIO::port() const
00956 {
00957 return d->mPort;
00958 }
00959
00960 void ResourceLDAPKIO::setVer( int ver )
00961 {
00962 d->mVer = ver;
00963 }
00964
00965 int ResourceLDAPKIO::ver() const
00966 {
00967 return d->mVer;
00968 }
00969
00970 void ResourceLDAPKIO::setSizeLimit( int sizelimit )
00971 {
00972 d->mSizeLimit = sizelimit;
00973 }
00974
00975 int ResourceLDAPKIO::sizeLimit()
00976 {
00977 return d->mSizeLimit;
00978 }
00979
00980 void ResourceLDAPKIO::setTimeLimit( int timelimit )
00981 {
00982 d->mTimeLimit = timelimit;
00983 }
00984
00985 int ResourceLDAPKIO::timeLimit()
00986 {
00987 return d->mTimeLimit;
00988 }
00989
00990 void ResourceLDAPKIO::setFilter( const QString &filter )
00991 {
00992 d->mFilter = filter;
00993 }
00994
00995 QString ResourceLDAPKIO::filter() const
00996 {
00997 return d->mFilter;
00998 }
00999
01000 void ResourceLDAPKIO::setIsAnonymous( bool value )
01001 {
01002 d->mAnonymous = value;
01003 }
01004
01005 bool ResourceLDAPKIO::isAnonymous() const
01006 {
01007 return d->mAnonymous;
01008 }
01009
01010 void ResourceLDAPKIO::setIsTLS( bool value )
01011 {
01012 d->mTLS = value;
01013 }
01014
01015 bool ResourceLDAPKIO::isTLS() const
01016 {
01017 return d->mTLS;
01018 }
01019 void ResourceLDAPKIO::setIsSSL( bool value )
01020 {
01021 d->mSSL = value;
01022 }
01023
01024 bool ResourceLDAPKIO::isSSL() const
01025 {
01026 return d->mSSL;
01027 }
01028
01029 void ResourceLDAPKIO::setIsSubTree( bool value )
01030 {
01031 d->mSubTree = value;
01032 }
01033
01034 bool ResourceLDAPKIO::isSubTree() const
01035 {
01036 return d->mSubTree;
01037 }
01038
01039 void ResourceLDAPKIO::setAttributes( const QMap<QString, QString> &attributes )
01040 {
01041 d->mAttributes = attributes;
01042 }
01043
01044 QMap<QString, QString> ResourceLDAPKIO::attributes() const
01045 {
01046 return d->mAttributes;
01047 }
01048
01049 void ResourceLDAPKIO::setRDNPrefix( int value )
01050 {
01051 d->mRDNPrefix = value;
01052 }
01053
01054 int ResourceLDAPKIO::RDNPrefix() const
01055 {
01056 return d->mRDNPrefix;
01057 }
01058
01059 void ResourceLDAPKIO::setIsSASL( bool value )
01060 {
01061 d->mSASL = value;
01062 }
01063
01064 bool ResourceLDAPKIO::isSASL() const
01065 {
01066 return d->mSASL;
01067 }
01068
01069 void ResourceLDAPKIO::setMech( const QString &mech )
01070 {
01071 d->mMech = mech;
01072 }
01073
01074 QString ResourceLDAPKIO::mech() const
01075 {
01076 return d->mMech;
01077 }
01078
01079 void ResourceLDAPKIO::setRealm( const QString &realm )
01080 {
01081 d->mRealm = realm;
01082 }
01083
01084 QString ResourceLDAPKIO::realm() const
01085 {
01086 return d->mRealm;
01087 }
01088
01089 void ResourceLDAPKIO::setBindDN( const QString &binddn )
01090 {
01091 d->mBindDN = binddn;
01092 }
01093
01094 QString ResourceLDAPKIO::bindDN() const
01095 {
01096 return d->mBindDN;
01097 }
01098
01099 void ResourceLDAPKIO::setCachePolicy( int pol )
01100 {
01101 d->mCachePolicy = pol;
01102 }
01103
01104 int ResourceLDAPKIO::cachePolicy() const
01105 {
01106 return d->mCachePolicy;
01107 }
01108
01109 void ResourceLDAPKIO::setAutoCache( bool value )
01110 {
01111 d->mAutoCache = value;
01112 }
01113
01114 bool ResourceLDAPKIO::autoCache()
01115 {
01116 return d->mAutoCache;
01117 }
01118
01119 QString ResourceLDAPKIO::cacheDst() const
01120 {
01121 return d->mCacheDst;
01122 }
01123
01124 #include "resourceldapkio.moc"