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