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 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.begin();
00308
00309 if ( !mAttributes[ "mail" ].isEmpty() ) {
00310 if ( mod ) {
00311 tmp += KLDAP::Ldif::assembleLine( "replace", mAttributes[ "mail" ] ) + '\n';
00312 }
00313 if ( mailIt != emails.end() ) {
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.end(); ++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.setUser( d->mUser );
00441 d->mLDAPUrl.setPass( d->mPassword );
00442 }
00443 d->mLDAPUrl.setProtocol( d->mSSL ? "ldaps" : "ldap" );
00444 d->mLDAPUrl.setHost( d->mHost );
00445 d->mLDAPUrl.setPort( d->mPort );
00446 d->mLDAPUrl.setDn( KLDAP::LdapDN( d->mDn ) );
00447
00448 if ( !d->mAttributes.empty() ) {
00449 QMap<QString,QString>::Iterator it;
00450 QStringList attr;
00451 for ( it = d->mAttributes.begin(); it != d->mAttributes.end(); ++it ) {
00452 if ( !it.value().isEmpty() && it.key() != "objectClass" ) {
00453 attr.append( it.value() );
00454 }
00455 }
00456 d->mLDAPUrl.setAttributes( attr );
00457 }
00458
00459 d->mLDAPUrl.setScope( d->mSubTree ? KLDAP::LdapUrl::Sub : KLDAP::LdapUrl::One );
00460 if ( !d->mFilter.isEmpty() && d->mFilter != "(objectClass=*)" ) {
00461 d->mLDAPUrl.setFilter( d->mFilter );
00462 }
00463 d->mLDAPUrl.setExtension( "x-dir", "base" );
00464 if ( d->mTLS ) {
00465 d->mLDAPUrl.setExtension( "x-tls", "" );
00466 }
00467 d->mLDAPUrl.setExtension( "x-ver", QString::number( d->mVer ) );
00468 if ( d->mSizeLimit ) {
00469 d->mLDAPUrl.setExtension( "x-sizelimit", QString::number( d->mSizeLimit ) );
00470 }
00471 if ( d->mTimeLimit ) {
00472 d->mLDAPUrl.setExtension( "x-timelimit", QString::number( d->mTimeLimit ) );
00473 }
00474 if ( d->mSASL ) {
00475 d->mLDAPUrl.setExtension( "x-sasl", "" );
00476 if ( !d->mBindDN.isEmpty() ) {
00477 d->mLDAPUrl.setExtension( "bindname", d->mBindDN );
00478 }
00479 if ( !d->mMech.isEmpty() ) {
00480 d->mLDAPUrl.setExtension( "x-mech", d->mMech );
00481 }
00482 if ( !d->mRealm.isEmpty() ) {
00483 d->mLDAPUrl.setExtension( "x-realm", d->mRealm );
00484 }
00485 }
00486
00487 d->mReadOnly = readOnly();
00488
00489 kDebug() << "resource_ldapkio url:" << d->mLDAPUrl.prettyUrl();
00490 }
00491
00492 void ResourceLDAPKIO::writeConfig( KConfigGroup &group )
00493 {
00494 Resource::writeConfig( group );
00495
00496 group.writeEntry( "LdapUser", d->mUser );
00497 group.writeEntry( "LdapPassword", KStringHandler::obscure( d->mPassword ) );
00498 group.writeEntry( "LdapDn", d->mDn );
00499 group.writeEntry( "LdapHost", d->mHost );
00500 group.writeEntry( "LdapPort", d->mPort );
00501 group.writeEntry( "LdapFilter", d->mFilter );
00502 group.writeEntry( "LdapAnonymous", d->mAnonymous );
00503 group.writeEntry( "LdapTLS", d->mTLS );
00504 group.writeEntry( "LdapSSL", d->mSSL );
00505 group.writeEntry( "LdapSubTree", d->mSubTree );
00506 group.writeEntry( "LdapSASL", d->mSASL );
00507 group.writeEntry( "LdapMech", d->mMech );
00508 group.writeEntry( "LdapVer", d->mVer );
00509 group.writeEntry( "LdapTimeLimit", d->mTimeLimit );
00510 group.writeEntry( "LdapSizeLimit", d->mSizeLimit );
00511 group.writeEntry( "LdapRDNPrefix", d->mRDNPrefix );
00512 group.writeEntry( "LdapRealm", d->mRealm );
00513 group.writeEntry( "LdapBindDN", d->mBindDN );
00514 group.writeEntry( "LdapCachePolicy", d->mCachePolicy );
00515 group.writeEntry( "LdapAutoCache", d->mAutoCache );
00516
00517 QStringList attributes;
00518 QMap<QString, QString>::const_iterator it;
00519 for ( it = d->mAttributes.constBegin(); it != d->mAttributes.constEnd(); ++it ) {
00520 attributes << it.key() << it.value();
00521 }
00522
00523 group.writeEntry( "LdapAttributes", attributes );
00524 }
00525
00526 Ticket *ResourceLDAPKIO::requestSaveTicket()
00527 {
00528 if ( !addressBook() ) {
00529 kDebug() << "no addressbook";
00530 return 0;
00531 }
00532
00533 return createTicket( this );
00534 }
00535
00536 void ResourceLDAPKIO::releaseSaveTicket( Ticket *ticket )
00537 {
00538 delete ticket;
00539 }
00540
00541 bool ResourceLDAPKIO::doOpen()
00542 {
00543 return true;
00544 }
00545
00546 void ResourceLDAPKIO::doClose()
00547 {
00548 }
00549
00550 void ResourceLDAPKIO::Private::createCache()
00551 {
00552 mTmp = 0;
00553 if ( mCachePolicy == Cache_NoConnection && mAutoCache ) {
00554 mTmp = new KTemporaryFile;
00555 mTmp->setPrefix( mCacheDst );
00556 mTmp->setSuffix( "tmp" );
00557 mTmp->open();
00558 }
00559 }
00560
00561 void ResourceLDAPKIO::Private::activateCache()
00562 {
00563 if ( mTmp && mError == 0 ) {
00564 QString filename = mTmp->fileName();
00565 delete mTmp;
00566 mTmp = 0;
00567 KDE_rename( QFile::encodeName( filename ), QFile::encodeName( mCacheDst ) );
00568 }
00569 }
00570
00571 KIO::Job *ResourceLDAPKIO::Private::loadFromCache()
00572 {
00573 KIO::Job *job = 0;
00574 if ( mCachePolicy == Cache_Always ||
00575 ( mCachePolicy == Cache_NoConnection &&
00576 mError == KIO::ERR_COULD_NOT_CONNECT ) ) {
00577
00578 mAddr = Addressee();
00579 mAd = Address( Address::Home );
00580
00581 mLdif.startParsing();
00582
00583 mParent->Resource::setReadOnly( true );
00584
00585 KUrl url( mCacheDst );
00586 job = KIO::get( url, KIO::Reload, KIO::HideProgressInfo );
00587 mParent->connect( job, SIGNAL( data( KIO::Job*, const QByteArray& ) ),
00588 mParent, SLOT( data( KIO::Job*, const QByteArray& ) ) );
00589 }
00590
00591 return job;
00592 }
00593
00594 bool ResourceLDAPKIO::load()
00595 {
00596 kDebug();
00597 KIO::Job *job;
00598
00599 clear();
00600
00601 d->mAddr = Addressee();
00602 d->mAd = Address( Address::Home );
00603
00604 d->mLdif.startParsing();
00605
00606
00607 Resource::setReadOnly( d->mReadOnly );
00608
00609 d->createCache();
00610 if ( d->mCachePolicy != Cache_Always ) {
00611 job = KIO::get( d->mLDAPUrl, KIO::Reload, KIO::HideProgressInfo );
00612 connect( job, SIGNAL( data( KIO::Job*, const QByteArray& ) ),
00613 this, SLOT( data( KIO::Job*, const QByteArray& ) ) );
00614 connect( job, SIGNAL( result( KJob* ) ),
00615 this, SLOT( syncLoadSaveResult( KJob* ) ) );
00616 d->enter_loop();
00617 }
00618
00619 job = d->loadFromCache();
00620 if ( job ) {
00621 connect( job, SIGNAL( result( KJob* ) ),
00622 this, SLOT( syncLoadSaveResult( KJob* ) ) );
00623 d->enter_loop();
00624 }
00625 if ( d->mErrorMsg.isEmpty() ) {
00626 kDebug() << "ResourceLDAPKIO load ok!";
00627 return true;
00628 } else {
00629 kDebug() << "ResourceLDAPKIO load finished with error:" << d->mErrorMsg;
00630 addressBook()->error( d->mErrorMsg );
00631 return false;
00632 }
00633 }
00634
00635 bool ResourceLDAPKIO::asyncLoad()
00636 {
00637 clear();
00638
00639 d->mAddr = Addressee();
00640 d->mAd = Address( Address::Home );
00641
00642 d->mLdif.startParsing();
00643
00644 Resource::setReadOnly( d->mReadOnly );
00645
00646 d->createCache();
00647 if ( d->mCachePolicy != Cache_Always ) {
00648 KIO::Job *job = KIO::get( d->mLDAPUrl, KIO::Reload, KIO::HideProgressInfo );
00649 connect( job, SIGNAL( data( KIO::Job*, const QByteArray& ) ),
00650 this, SLOT( data( KIO::Job*, const QByteArray& ) ) );
00651 connect( job, SIGNAL( result( KJob* ) ),
00652 this, SLOT( result( KJob* ) ) );
00653 } else {
00654 result( 0 );
00655 }
00656 return true;
00657 }
00658
00659 void ResourceLDAPKIO::data( KIO::Job *job, const QByteArray &data )
00660 {
00661 Q_UNUSED( job );
00662 if ( data.size() ) {
00663 d->mLdif.setLdif( data );
00664 if ( d->mTmp ) {
00665 d->mTmp->write( data );
00666 }
00667 } else {
00668 d->mLdif.endLdif();
00669 }
00670
00671 KLDAP::Ldif::ParseValue ret;
00672 QString name;
00673 QByteArray value;
00674 do {
00675 ret = d->mLdif.nextItem();
00676 switch ( ret ) {
00677 case KLDAP::Ldif::NewEntry:
00678 kDebug() << "new entry:" << d->mLdif.dn().toString();
00679 break;
00680 case KLDAP::Ldif::Item:
00681 name = d->mLdif.attr().toLower();
00682 value = d->mLdif.value();
00683 if ( name == d->mAttributes[ "commonName" ].toLower() ) {
00684 if ( !d->mAddr.formattedName().isEmpty() ) {
00685 QString fn = d->mAddr.formattedName();
00686 d->mAddr.setNameFromString( QString::fromUtf8( value, value.size() ) );
00687 d->mAddr.setFormattedName( fn );
00688 } else {
00689 d->mAddr.setNameFromString( QString::fromUtf8( value, value.size() ) );
00690 }
00691 } else if ( name == d->mAttributes[ "formattedName" ].toLower() ) {
00692 d->mAddr.setFormattedName( QString::fromUtf8( value, value.size() ) );
00693 } else if ( name == d->mAttributes[ "givenName" ].toLower() ) {
00694 d->mAddr.setGivenName( QString::fromUtf8( value, value.size() ) );
00695 } else if ( name == d->mAttributes[ "mail" ].toLower() ) {
00696 d->mAddr.insertEmail( QString::fromUtf8( value, value.size() ), true );
00697 } else if ( name == d->mAttributes[ "mailAlias" ].toLower() ) {
00698 d->mAddr.insertEmail( QString::fromUtf8( value, value.size() ), false );
00699 } else if ( name == d->mAttributes[ "phoneNumber" ].toLower() ) {
00700 PhoneNumber phone;
00701 phone.setNumber( QString::fromUtf8( value, value.size() ) );
00702 d->mAddr.insertPhoneNumber( phone );
00703 } else if ( name == d->mAttributes[ "telephoneNumber" ].toLower() ) {
00704 PhoneNumber phone( QString::fromUtf8( value, value.size() ),
00705 PhoneNumber::Work );
00706 d->mAddr.insertPhoneNumber( phone );
00707 } else if ( name == d->mAttributes[ "facsimileTelephoneNumber" ].toLower() ) {
00708 PhoneNumber phone( QString::fromUtf8( value, value.size() ),
00709 PhoneNumber::Fax );
00710 d->mAddr.insertPhoneNumber( phone );
00711 } else if ( name == d->mAttributes[ "mobile" ].toLower() ) {
00712 PhoneNumber phone( QString::fromUtf8( value, value.size() ),
00713 PhoneNumber::Cell );
00714 d->mAddr.insertPhoneNumber( phone );
00715 } else if ( name == d->mAttributes[ "pager" ].toLower() ) {
00716 PhoneNumber phone( QString::fromUtf8( value, value.size() ),
00717 PhoneNumber::Pager );
00718 d->mAddr.insertPhoneNumber( phone );
00719 } else if ( name == d->mAttributes[ "description" ].toLower() ) {
00720 d->mAddr.setNote( QString::fromUtf8( value, value.size() ) );
00721 } else if ( name == d->mAttributes[ "title" ].toLower() ) {
00722 d->mAddr.setTitle( QString::fromUtf8( value, value.size() ) );
00723 } else if ( name == d->mAttributes[ "street" ].toLower() ) {
00724 d->mAd.setStreet( QString::fromUtf8( value, value.size() ) );
00725 } else if ( name == d->mAttributes[ "state" ].toLower() ) {
00726 d->mAd.setRegion( QString::fromUtf8( value, value.size() ) );
00727 } else if ( name == d->mAttributes[ "city" ].toLower() ) {
00728 d->mAd.setLocality( QString::fromUtf8( value, value.size() ) );
00729 } else if ( name == d->mAttributes[ "postalcode" ].toLower() ) {
00730 d->mAd.setPostalCode( QString::fromUtf8( value, value.size() ) );
00731 } else if ( name == d->mAttributes[ "organization" ].toLower() ) {
00732 d->mAddr.setOrganization( QString::fromUtf8( value, value.size() ) );
00733 } else if ( name == d->mAttributes[ "familyName" ].toLower() ) {
00734 d->mAddr.setFamilyName( QString::fromUtf8( value, value.size() ) );
00735 } else if ( name == d->mAttributes[ "uid" ].toLower() ) {
00736 d->mAddr.setUid( QString::fromUtf8( value, value.size() ) );
00737 } else if ( name == d->mAttributes[ "jpegPhoto" ].toLower() ) {
00738 KABC::Picture photo;
00739 QImage img = QImage::fromData( value );
00740 if ( !img.isNull() ) {
00741 photo.setData( img );
00742 photo.setType( "image/jpeg" );
00743 d->mAddr.setPhoto( photo );
00744 }
00745 }
00746
00747 break;
00748 case KLDAP::Ldif::EndEntry:
00749 {
00750 d->mAddr.setResource( this );
00751 d->mAddr.insertAddress( d->mAd );
00752 d->mAddr.setChanged( false );
00753 insertAddressee( d->mAddr );
00754
00755 d->mAddr = Addressee();
00756 d->mAd = Address( Address::Home );
00757 }
00758 break;
00759 default:
00760 break;
00761 }
00762 } while ( ret != KLDAP::Ldif::MoreData );
00763 }
00764
00765 void ResourceLDAPKIO::loadCacheResult( KJob *job )
00766 {
00767 d->mErrorMsg.clear();
00768 d->mError = job->error();
00769 if ( d->mError && d->mError != KIO::ERR_USER_CANCELED ) {
00770 d->mErrorMsg = job->errorString();
00771 }
00772 if ( !d->mErrorMsg.isEmpty() ) {
00773 emit loadingError( this, d->mErrorMsg );
00774 } else {
00775 emit loadingFinished( this );
00776 }
00777 }
00778
00779 void ResourceLDAPKIO::result( KJob *job )
00780 {
00781 d->mErrorMsg.clear();
00782 if ( job ) {
00783 d->mError = job->error();
00784 if ( d->mError && d->mError != KIO::ERR_USER_CANCELED ) {
00785 d->mErrorMsg = job->errorString();
00786 }
00787 } else {
00788 d->mError = 0;
00789 }
00790 d->activateCache();
00791
00792 KIO::Job *cjob;
00793 cjob = d->loadFromCache();
00794 if ( cjob ) {
00795 connect( cjob, SIGNAL( result( KJob* ) ),
00796 this, SLOT( loadCacheResult( KJob* ) ) );
00797 } else {
00798 if ( !d->mErrorMsg.isEmpty() ) {
00799 emit loadingError( this, d->mErrorMsg );
00800 } else {
00801 emit loadingFinished( this );
00802 }
00803 }
00804 }
00805
00806 bool ResourceLDAPKIO::save( Ticket *ticket )
00807 {
00808 Q_UNUSED( ticket );
00809 kDebug();
00810
00811 d->mSaveIt = begin();
00812 KIO::Job *job = KIO::put( d->mLDAPUrl, -1, KIO::Overwrite | KIO::HideProgressInfo );
00813 connect( job, SIGNAL( dataReq( KIO::Job*, QByteArray& ) ),
00814 this, SLOT( saveData( KIO::Job*, QByteArray& ) ) );
00815 connect( job, SIGNAL( result( KJob* ) ),
00816 this, SLOT( syncLoadSaveResult( KJob* ) ) );
00817 d->enter_loop();
00818 if ( d->mErrorMsg.isEmpty() ) {
00819 kDebug() << "ResourceLDAPKIO save ok!";
00820 return true;
00821 } else {
00822 kDebug() << "ResourceLDAPKIO finished with error:" << d->mErrorMsg;
00823 addressBook()->error( d->mErrorMsg );
00824 return false;
00825 }
00826 }
00827
00828 bool ResourceLDAPKIO::asyncSave( Ticket *ticket )
00829 {
00830 Q_UNUSED( ticket );
00831 kDebug();
00832 d->mSaveIt = begin();
00833 KIO::Job *job = KIO::put( d->mLDAPUrl, -1, KIO::Overwrite | KIO::HideProgressInfo );
00834 connect( job, SIGNAL( dataReq( KIO::Job*, QByteArray& ) ),
00835 this, SLOT( saveData( KIO::Job*, QByteArray& ) ) );
00836 connect( job, SIGNAL( result( KJob* ) ),
00837 this, SLOT( saveResult( KJob* ) ) );
00838 return true;
00839 }
00840
00841 void ResourceLDAPKIO::syncLoadSaveResult( KJob *job )
00842 {
00843 d->mError = job->error();
00844 if ( d->mError && d->mError != KIO::ERR_USER_CANCELED ) {
00845 d->mErrorMsg = job->errorString();
00846 } else {
00847 d->mErrorMsg.clear();
00848 }
00849 d->activateCache();
00850
00851 emit leaveModality();
00852 }
00853
00854 void ResourceLDAPKIO::saveResult( KJob *job )
00855 {
00856 d->mError = job->error();
00857 if ( d->mError && d->mError != KIO::ERR_USER_CANCELED ) {
00858 emit savingError( this, job->errorString() );
00859 } else {
00860 emit savingFinished( this );
00861 }
00862 }
00863
00864 void ResourceLDAPKIO::saveData( KIO::Job *job, QByteArray &data )
00865 {
00866 Q_UNUSED( job );
00867 while ( d->mSaveIt != end() && !(*d->mSaveIt).changed() ) {
00868 d->mSaveIt++;
00869 }
00870
00871 if ( d->mSaveIt == end() ) {
00872 kDebug() << "ResourceLDAPKIO endData";
00873 data.resize( 0 );
00874 return;
00875 }
00876
00877 kDebug() << "ResourceLDAPKIO saveData:" << (*d->mSaveIt).assembledName();
00878
00879 d->AddresseeToLDIF( data, *d->mSaveIt, d->findUid( (*d->mSaveIt).uid() ) );
00880
00881
00882 (*d->mSaveIt).setChanged( false );
00883
00884 d->mSaveIt++;
00885 }
00886
00887 void ResourceLDAPKIO::removeAddressee( const Addressee &addr )
00888 {
00889 QString dn = d->findUid( addr.uid() );
00890
00891 kDebug() << dn;
00892
00893 if ( !d->mErrorMsg.isEmpty() ) {
00894 addressBook()->error( d->mErrorMsg );
00895 return;
00896 }
00897 if ( !dn.isEmpty() ) {
00898 kDebug() << "ResourceLDAPKIO: found uid:" << dn;
00899 KLDAP::LdapUrl url( d->mLDAPUrl );
00900 url.setPath( '/' + dn );
00901 url.setExtension( "x-dir", "base" );
00902 url.setScope( KLDAP::LdapUrl::Base );
00903 if ( KIO::NetAccess::del( url, 0 ) ) {
00904 mAddrMap.remove( addr.uid() );
00905 }
00906 } else {
00907
00908 mAddrMap.remove( addr.uid() );
00909 }
00910 }
00911
00912 void ResourceLDAPKIO::setUser( const QString &user )
00913 {
00914 d->mUser = user;
00915 }
00916
00917 QString ResourceLDAPKIO::user() const
00918 {
00919 return d->mUser;
00920 }
00921
00922 void ResourceLDAPKIO::setPassword( const QString &password )
00923 {
00924 d->mPassword = password;
00925 }
00926
00927 QString ResourceLDAPKIO::password() const
00928 {
00929 return d->mPassword;
00930 }
00931
00932 void ResourceLDAPKIO::setDn( const QString &dn )
00933 {
00934 d->mDn = dn;
00935 }
00936
00937 QString ResourceLDAPKIO::dn() const
00938 {
00939 return d->mDn;
00940 }
00941
00942 void ResourceLDAPKIO::setHost( const QString &host )
00943 {
00944 d->mHost = host;
00945 }
00946
00947 QString ResourceLDAPKIO::host() const
00948 {
00949 return d->mHost;
00950 }
00951
00952 void ResourceLDAPKIO::setPort( int port )
00953 {
00954 d->mPort = port;
00955 }
00956
00957 int ResourceLDAPKIO::port() const
00958 {
00959 return d->mPort;
00960 }
00961
00962 void ResourceLDAPKIO::setVer( int ver )
00963 {
00964 d->mVer = ver;
00965 }
00966
00967 int ResourceLDAPKIO::ver() const
00968 {
00969 return d->mVer;
00970 }
00971
00972 void ResourceLDAPKIO::setSizeLimit( int sizelimit )
00973 {
00974 d->mSizeLimit = sizelimit;
00975 }
00976
00977 int ResourceLDAPKIO::sizeLimit()
00978 {
00979 return d->mSizeLimit;
00980 }
00981
00982 void ResourceLDAPKIO::setTimeLimit( int timelimit )
00983 {
00984 d->mTimeLimit = timelimit;
00985 }
00986
00987 int ResourceLDAPKIO::timeLimit()
00988 {
00989 return d->mTimeLimit;
00990 }
00991
00992 void ResourceLDAPKIO::setFilter( const QString &filter )
00993 {
00994 d->mFilter = filter;
00995 }
00996
00997 QString ResourceLDAPKIO::filter() const
00998 {
00999 return d->mFilter;
01000 }
01001
01002 void ResourceLDAPKIO::setIsAnonymous( bool value )
01003 {
01004 d->mAnonymous = value;
01005 }
01006
01007 bool ResourceLDAPKIO::isAnonymous() const
01008 {
01009 return d->mAnonymous;
01010 }
01011
01012 void ResourceLDAPKIO::setIsTLS( bool value )
01013 {
01014 d->mTLS = value;
01015 }
01016
01017 bool ResourceLDAPKIO::isTLS() const
01018 {
01019 return d->mTLS;
01020 }
01021 void ResourceLDAPKIO::setIsSSL( bool value )
01022 {
01023 d->mSSL = value;
01024 }
01025
01026 bool ResourceLDAPKIO::isSSL() const
01027 {
01028 return d->mSSL;
01029 }
01030
01031 void ResourceLDAPKIO::setIsSubTree( bool value )
01032 {
01033 d->mSubTree = value;
01034 }
01035
01036 bool ResourceLDAPKIO::isSubTree() const
01037 {
01038 return d->mSubTree;
01039 }
01040
01041 void ResourceLDAPKIO::setAttributes( const QMap<QString, QString> &attributes )
01042 {
01043 d->mAttributes = attributes;
01044 }
01045
01046 QMap<QString, QString> ResourceLDAPKIO::attributes() const
01047 {
01048 return d->mAttributes;
01049 }
01050
01051 void ResourceLDAPKIO::setRDNPrefix( int value )
01052 {
01053 d->mRDNPrefix = value;
01054 }
01055
01056 int ResourceLDAPKIO::RDNPrefix() const
01057 {
01058 return d->mRDNPrefix;
01059 }
01060
01061 void ResourceLDAPKIO::setIsSASL( bool value )
01062 {
01063 d->mSASL = value;
01064 }
01065
01066 bool ResourceLDAPKIO::isSASL() const
01067 {
01068 return d->mSASL;
01069 }
01070
01071 void ResourceLDAPKIO::setMech( const QString &mech )
01072 {
01073 d->mMech = mech;
01074 }
01075
01076 QString ResourceLDAPKIO::mech() const
01077 {
01078 return d->mMech;
01079 }
01080
01081 void ResourceLDAPKIO::setRealm( const QString &realm )
01082 {
01083 d->mRealm = realm;
01084 }
01085
01086 QString ResourceLDAPKIO::realm() const
01087 {
01088 return d->mRealm;
01089 }
01090
01091 void ResourceLDAPKIO::setBindDN( const QString &binddn )
01092 {
01093 d->mBindDN = binddn;
01094 }
01095
01096 QString ResourceLDAPKIO::bindDN() const
01097 {
01098 return d->mBindDN;
01099 }
01100
01101 void ResourceLDAPKIO::setCachePolicy( int pol )
01102 {
01103 d->mCachePolicy = pol;
01104 }
01105
01106 int ResourceLDAPKIO::cachePolicy() const
01107 {
01108 return d->mCachePolicy;
01109 }
01110
01111 void ResourceLDAPKIO::setAutoCache( bool value )
01112 {
01113 d->mAutoCache = value;
01114 }
01115
01116 bool ResourceLDAPKIO::autoCache()
01117 {
01118 return d->mAutoCache;
01119 }
01120
01121 QString ResourceLDAPKIO::cacheDst() const
01122 {
01123 return d->mCacheDst;
01124 }
01125
01126 #include "resourceldapkio.moc"