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