kabc Library API Documentation

resourceldapkio.cpp

00001 /*
00002     This file is part of libkabc.
00003     Copyright (c) 2003 Tobias Koenig <tokoe@kde.org>
00004     Copyright (c) 2004 Szombathelyi György <gyurco@freemail.hu>
00005 
00006     This library is free software; you can redistribute it and/or
00007     modify it under the terms of the GNU Library General Public
00008     License as published by the Free Software Foundation; either
00009     version 2 of the License, or (at your option) any later version.
00010 
00011     This library is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014     Library General Public License for more details.
00015 
00016     You should have received a copy of the GNU Library General Public License
00017     along with this library; see the file COPYING.LIB.  If not, write to
00018     the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00019     Boston, MA 02111-1307, USA.
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 // Hack from Netaccess
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 /* no GUI */ );
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     //insert new entry
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     //modify existing entry
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   //save the original readonly flag, because offline using disables writing
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     //initialize ldif parser
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   //clear the addressee
00529   d->mAddr = Addressee();
00530   d->mAd = Address( Address::Home );
00531   //initialize ldif parser
00532   d->mLdif.startParsing();
00533 
00534   //set to original settings, offline use will disable writing
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   //clear the addressee
00565   d->mAddr = Addressee();
00566   d->mAd = Address( Address::Home );
00567   //initialize ldif parser
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         //clear the addressee
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 //  kdDebug(7125) << "ResourceLDAPKIO save LDIF: " << QString::fromUtf8(data) << endl;
00783   // mark as unchanged
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     //maybe it's not saved yet
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"
KDE Logo
This file is part of the documentation for kabc Library Version 3.3.90.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Mar 30 10:21:07 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003