• Skip to content
  • Skip to link menu
KDE 4.1 API Reference
  • KDE API Reference
  • KDE-PIM Libraries
  • Sitemap
  • Contact Us
 

kabc

resourceldapkio.cpp

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

kabc

Skip menu "kabc"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

KDE-PIM Libraries

Skip menu "KDE-PIM Libraries"
  • akonadi
  • kabc
  • kblog
  • kcal
  • kimap
  • kioslave
  •   imap4
  •   mbox
  • kldap
  • kmime
  • kpimidentities
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Generated for KDE-PIM Libraries by doxygen 1.5.6
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal