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 connect( job, SIGNAL( result( KIO::Job* ) ),
00517 this, SLOT( syncLoadSaveResult( KIO::Job* ) ) );
00518 }
00519 return job;
00520 }
00521
00522 bool ResourceLDAPKIO::load()
00523 {
00524 kdDebug(7125) << "ResourceLDAPKIO::load()" << endl;
00525 KIO::Job *job;
00526
00527 clear();
00528
00529 d->mAddr = Addressee();
00530 d->mAd = Address( Address::Home );
00531
00532 d->mLdif.startParsing();
00533
00534
00535 Resource::setReadOnly( d->mReadOnly );
00536
00537 createCache();
00538 if ( d->mCachePolicy != Cache_Always ) {
00539 job = KIO::get( d->mLDAPUrl, true, false );
00540 connect( job, SIGNAL( data( KIO::Job*, const QByteArray& ) ),
00541 this, SLOT( data( KIO::Job*, const QByteArray& ) ) );
00542 connect( job, SIGNAL( result( KIO::Job* ) ),
00543 this, SLOT( syncLoadSaveResult( KIO::Job* ) ) );
00544 enter_loop();
00545 }
00546
00547 job = loadFromCache();
00548 if ( 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::result( KIO::Job *job )
00689 {
00690 mErrorMsg = "";
00691 if ( job ) {
00692 d->mError = job->error();
00693 if ( d->mError && d->mError != KIO::ERR_USER_CANCELED ) {
00694 mErrorMsg = job->errorString();
00695 }
00696 } else {
00697 d->mError = 0;
00698 }
00699 activateCache();
00700
00701 KIO::Job *cjob;
00702 cjob = loadFromCache();
00703 if ( cjob ) {
00704 enter_loop();
00705 job = cjob;
00706 }
00707
00708 if ( !mErrorMsg.isEmpty() )
00709 emit loadingError( this, mErrorMsg );
00710 else
00711 emit loadingFinished( this );
00712 }
00713
00714 bool ResourceLDAPKIO::save( Ticket* )
00715 {
00716 kdDebug(7125) << "ResourceLDAPKIO save" << endl;
00717
00718 d->mSaveIt = begin();
00719 KIO::Job *job = KIO::put( d->mLDAPUrl, -1, true, false, false );
00720 connect( job, SIGNAL( dataReq( KIO::Job*, QByteArray& ) ),
00721 this, SLOT( saveData( KIO::Job*, QByteArray& ) ) );
00722 connect( job, SIGNAL( result( KIO::Job* ) ),
00723 this, SLOT( syncLoadSaveResult( KIO::Job* ) ) );
00724 enter_loop();
00725 if ( mErrorMsg.isEmpty() ) {
00726 kdDebug(7125) << "ResourceLDAPKIO save ok!" << endl;
00727 return true;
00728 } else {
00729 kdDebug(7125) << "ResourceLDAPKIO finished with error: " << mErrorMsg << endl;
00730 addressBook()->error( mErrorMsg );
00731 return false;
00732 }
00733 }
00734
00735 bool ResourceLDAPKIO::asyncSave( Ticket* )
00736 {
00737 kdDebug(7125) << "ResourceLDAPKIO asyncSave" << endl;
00738 d->mSaveIt = begin();
00739 KIO::Job *job = KIO::put( d->mLDAPUrl, -1, true, false, false );
00740 connect( job, SIGNAL( dataReq( KIO::Job*, QByteArray& ) ),
00741 this, SLOT( saveData( KIO::Job*, QByteArray& ) ) );
00742 connect( job, SIGNAL( result( KIO::Job* ) ),
00743 this, SLOT( saveResult( KIO::Job* ) ) );
00744 return true;
00745 }
00746
00747 void ResourceLDAPKIO::syncLoadSaveResult( KIO::Job *job )
00748 {
00749 d->mError = job->error();
00750 if ( d->mError && d->mError != KIO::ERR_USER_CANCELED )
00751 mErrorMsg = job->errorString();
00752 else
00753 mErrorMsg = "";
00754 activateCache();
00755
00756 qApp->exit_loop();
00757 }
00758
00759 void ResourceLDAPKIO::saveResult( KIO::Job *job )
00760 {
00761 d->mError = job->error();
00762 if ( d->mError && d->mError != KIO::ERR_USER_CANCELED )
00763 emit savingError( this, job->errorString() );
00764 else
00765 emit savingFinished( this );
00766 }
00767
00768 void ResourceLDAPKIO::saveData( KIO::Job*, QByteArray& data )
00769 {
00770 while ( d->mSaveIt != end() &&
00771 !(*d->mSaveIt).changed() ) d->mSaveIt++;
00772
00773 if ( d->mSaveIt == end() ) {
00774 kdDebug(7125) << "ResourceLDAPKIO endData" << endl;
00775 data.resize(0);
00776 return;
00777 }
00778
00779 kdDebug(7125) << "ResourceLDAPKIO saveData: " << (*d->mSaveIt).assembledName() << endl;
00780
00781 AddresseeToLDIF( data, *d->mSaveIt, findUid( (*d->mSaveIt).uid() ) );
00782
00783
00784 (*d->mSaveIt).setChanged( false );
00785
00786 d->mSaveIt++;
00787 }
00788
00789 void ResourceLDAPKIO::removeAddressee( const Addressee& addr )
00790 {
00791 QString dn = findUid( addr.uid() );
00792
00793 kdDebug(7125) << "ResourceLDAPKIO: removeAddressee: " << dn << endl;
00794
00795 if ( !mErrorMsg.isEmpty() ) {
00796 addressBook()->error( mErrorMsg );
00797 return;
00798 }
00799 if ( !dn.isEmpty() ) {
00800 kdDebug(7125) << "ResourceLDAPKIO: found uid: " << dn << endl;
00801 LDAPUrl url( d->mLDAPUrl );
00802 url.setPath( "/" + dn );
00803 url.setExtension( "x-dir", "base" );
00804 url.setScope( LDAPUrl::Base );
00805 if ( KIO::NetAccess::del( url, NULL ) ) mAddrMap.erase( addr.uid() );
00806 } else {
00807
00808 mAddrMap.erase( addr.uid() );
00809 }
00810 }
00811
00812
00813 void ResourceLDAPKIO::setUser( const QString &user )
00814 {
00815 mUser = user;
00816 }
00817
00818 QString ResourceLDAPKIO::user() const
00819 {
00820 return mUser;
00821 }
00822
00823 void ResourceLDAPKIO::setPassword( const QString &password )
00824 {
00825 mPassword = password;
00826 }
00827
00828 QString ResourceLDAPKIO::password() const
00829 {
00830 return mPassword;
00831 }
00832
00833 void ResourceLDAPKIO::setDn( const QString &dn )
00834 {
00835 mDn = dn;
00836 }
00837
00838 QString ResourceLDAPKIO::dn() const
00839 {
00840 return mDn;
00841 }
00842
00843 void ResourceLDAPKIO::setHost( const QString &host )
00844 {
00845 mHost = host;
00846 }
00847
00848 QString ResourceLDAPKIO::host() const
00849 {
00850 return mHost;
00851 }
00852
00853 void ResourceLDAPKIO::setPort( int port )
00854 {
00855 mPort = port;
00856 }
00857
00858 int ResourceLDAPKIO::port() const
00859 {
00860 return mPort;
00861 }
00862
00863 void ResourceLDAPKIO::setVer( int ver )
00864 {
00865 d->mVer = ver;
00866 }
00867
00868 int ResourceLDAPKIO::ver() const
00869 {
00870 return d->mVer;
00871 }
00872
00873 void ResourceLDAPKIO::setSizeLimit( int sizelimit )
00874 {
00875 d->mSizeLimit = sizelimit;
00876 }
00877
00878 int ResourceLDAPKIO::sizeLimit()
00879 {
00880 return d->mSizeLimit;
00881 }
00882
00883 void ResourceLDAPKIO::setTimeLimit( int timelimit )
00884 {
00885 d->mTimeLimit = timelimit;
00886 }
00887
00888 int ResourceLDAPKIO::timeLimit()
00889 {
00890 return d->mTimeLimit;
00891 }
00892
00893 void ResourceLDAPKIO::setFilter( const QString &filter )
00894 {
00895 mFilter = filter;
00896 }
00897
00898 QString ResourceLDAPKIO::filter() const
00899 {
00900 return mFilter;
00901 }
00902
00903 void ResourceLDAPKIO::setIsAnonymous( bool value )
00904 {
00905 mAnonymous = value;
00906 }
00907
00908 bool ResourceLDAPKIO::isAnonymous() const
00909 {
00910 return mAnonymous;
00911 }
00912
00913 void ResourceLDAPKIO::setIsTLS( bool value )
00914 {
00915 d->mTLS = value;
00916 }
00917
00918 bool ResourceLDAPKIO::isTLS() const
00919 {
00920 return d->mTLS;
00921 }
00922 void ResourceLDAPKIO::setIsSSL( bool value )
00923 {
00924 d->mSSL = value;
00925 }
00926
00927 bool ResourceLDAPKIO::isSSL() const
00928 {
00929 return d->mSSL;
00930 }
00931
00932 void ResourceLDAPKIO::setIsSubTree( bool value )
00933 {
00934 d->mSubTree = value;
00935 }
00936
00937 bool ResourceLDAPKIO::isSubTree() const
00938 {
00939 return d->mSubTree;
00940 }
00941
00942 void ResourceLDAPKIO::setAttributes( const QMap<QString, QString> &attributes )
00943 {
00944 mAttributes = attributes;
00945 }
00946
00947 QMap<QString, QString> ResourceLDAPKIO::attributes() const
00948 {
00949 return mAttributes;
00950 }
00951
00952 void ResourceLDAPKIO::setRDNPrefix( int value )
00953 {
00954 d->mRDNPrefix = value;
00955 }
00956
00957 int ResourceLDAPKIO::RDNPrefix() const
00958 {
00959 return d->mRDNPrefix;
00960 }
00961
00962 void ResourceLDAPKIO::setIsSASL( bool value )
00963 {
00964 d->mSASL = value;
00965 }
00966
00967 bool ResourceLDAPKIO::isSASL() const
00968 {
00969 return d->mSASL;
00970 }
00971
00972 void ResourceLDAPKIO::setMech( const QString &mech )
00973 {
00974 d->mMech = mech;
00975 }
00976
00977 QString ResourceLDAPKIO::mech() const
00978 {
00979 return d->mMech;
00980 }
00981
00982 void ResourceLDAPKIO::setRealm( const QString &realm )
00983 {
00984 d->mRealm = realm;
00985 }
00986
00987 QString ResourceLDAPKIO::realm() const
00988 {
00989 return d->mRealm;
00990 }
00991
00992 void ResourceLDAPKIO::setBindDN( const QString &binddn )
00993 {
00994 d->mBindDN = binddn;
00995 }
00996
00997 QString ResourceLDAPKIO::bindDN() const
00998 {
00999 return d->mBindDN;
01000 }
01001
01002 void ResourceLDAPKIO::setCachePolicy( int pol )
01003 {
01004 d->mCachePolicy = pol;
01005 }
01006
01007 int ResourceLDAPKIO::cachePolicy() const
01008 {
01009 return d->mCachePolicy;
01010 }
01011
01012 void ResourceLDAPKIO::setAutoCache( bool value )
01013 {
01014 d->mAutoCache = value;
01015 }
01016
01017 bool ResourceLDAPKIO::autoCache()
01018 {
01019 return d->mAutoCache;
01020 }
01021
01022 QString ResourceLDAPKIO::cacheDst() const
01023 {
01024 return d->mCacheDst;
01025 }
01026
01027
01028 #include "resourceldapkio.moc"