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