• Skip to content
  • Skip to link menu
KDE 4.2 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     const 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.constBegin();
00308 
00309   if ( !mAttributes[ "mail" ].isEmpty() ) {
00310     if ( mod ) {
00311       tmp += KLDAP::Ldif::assembleLine( "replace", mAttributes[ "mail" ] ) + '\n';
00312     }
00313     if ( mailIt != emails.constEnd() ) {
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.constEnd(); ++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.setExtension( "bindname", d->mBindDN );
00441     d->mLDAPUrl.setUser( d->mUser );
00442     d->mLDAPUrl.setPass( d->mPassword );
00443   }
00444   d->mLDAPUrl.setProtocol( d->mSSL ? "ldaps" : "ldap" );
00445   d->mLDAPUrl.setHost( d->mHost );
00446   d->mLDAPUrl.setPort( d->mPort );
00447   d->mLDAPUrl.setDn( KLDAP::LdapDN( d->mDn ) );
00448 
00449   if ( !d->mAttributes.empty() ) {
00450     QMap<QString,QString>::Iterator it;
00451     QStringList attr;
00452     for ( it = d->mAttributes.begin(); it != d->mAttributes.end(); ++it ) {
00453       if ( !it.value().isEmpty() && it.key() != "objectClass" ) {
00454         attr.append( it.value() );
00455       }
00456     }
00457     d->mLDAPUrl.setAttributes( attr );
00458   }
00459 
00460   d->mLDAPUrl.setScope( d->mSubTree ? KLDAP::LdapUrl::Sub : KLDAP::LdapUrl::One );
00461   if ( !d->mFilter.isEmpty() && d->mFilter != "(objectClass=*)" ) {
00462     d->mLDAPUrl.setFilter( d->mFilter );
00463   }
00464   d->mLDAPUrl.setExtension( "x-dir", "base" );
00465   if ( d->mTLS ) {
00466     d->mLDAPUrl.setExtension( "x-tls", "" );
00467   }
00468   d->mLDAPUrl.setExtension( "x-ver", QString::number( d->mVer ) );
00469   if ( d->mSizeLimit ) {
00470     d->mLDAPUrl.setExtension( "x-sizelimit", QString::number( d->mSizeLimit ) );
00471   }
00472   if ( d->mTimeLimit ) {
00473     d->mLDAPUrl.setExtension( "x-timelimit", QString::number( d->mTimeLimit ) );
00474   }
00475   if ( d->mSASL ) {
00476     d->mLDAPUrl.setExtension( "x-sasl", "" );
00477     if ( !d->mMech.isEmpty() ) {
00478       d->mLDAPUrl.setExtension( "x-mech", d->mMech );
00479     }
00480     if ( !d->mRealm.isEmpty() ) {
00481       d->mLDAPUrl.setExtension( "x-realm", d->mRealm );
00482     }
00483   }
00484 
00485   d->mReadOnly = readOnly();
00486 
00487   kDebug() << "resource_ldapkio url:" << d->mLDAPUrl.prettyUrl();
00488 }
00489 
00490 void ResourceLDAPKIO::writeConfig( KConfigGroup &group )
00491 {
00492   Resource::writeConfig( group );
00493 
00494   group.writeEntry( "LdapUser", d->mUser );
00495   group.writeEntry( "LdapPassword", KStringHandler::obscure( d->mPassword ) );
00496   group.writeEntry( "LdapDn", d->mDn );
00497   group.writeEntry( "LdapHost", d->mHost );
00498   group.writeEntry( "LdapPort", d->mPort );
00499   group.writeEntry( "LdapFilter", d->mFilter );
00500   group.writeEntry( "LdapAnonymous", d->mAnonymous );
00501   group.writeEntry( "LdapTLS", d->mTLS );
00502   group.writeEntry( "LdapSSL", d->mSSL );
00503   group.writeEntry( "LdapSubTree", d->mSubTree );
00504   group.writeEntry( "LdapSASL", d->mSASL );
00505   group.writeEntry( "LdapMech", d->mMech );
00506   group.writeEntry( "LdapVer", d->mVer );
00507   group.writeEntry( "LdapTimeLimit", d->mTimeLimit );
00508   group.writeEntry( "LdapSizeLimit", d->mSizeLimit );
00509   group.writeEntry( "LdapRDNPrefix", d->mRDNPrefix );
00510   group.writeEntry( "LdapRealm", d->mRealm );
00511   group.writeEntry( "LdapBindDN", d->mBindDN );
00512   group.writeEntry( "LdapCachePolicy", d->mCachePolicy );
00513   group.writeEntry( "LdapAutoCache", d->mAutoCache );
00514 
00515   QStringList attributes;
00516   QMap<QString, QString>::const_iterator it;
00517   for ( it = d->mAttributes.constBegin(); it != d->mAttributes.constEnd(); ++it ) {
00518     attributes << it.key() << it.value();
00519   }
00520 
00521   group.writeEntry( "LdapAttributes", attributes );
00522 }
00523 
00524 Ticket *ResourceLDAPKIO::requestSaveTicket()
00525 {
00526   if ( !addressBook() ) {
00527     kDebug() << "no addressbook";
00528     return 0;
00529   }
00530 
00531   return createTicket( this );
00532 }
00533 
00534 void ResourceLDAPKIO::releaseSaveTicket( Ticket *ticket )
00535 {
00536   delete ticket;
00537 }
00538 
00539 bool ResourceLDAPKIO::doOpen()
00540 {
00541   return true;
00542 }
00543 
00544 void ResourceLDAPKIO::doClose()
00545 {
00546 }
00547 
00548 void ResourceLDAPKIO::Private::createCache()
00549 {
00550   mTmp = 0;
00551   if ( mCachePolicy == Cache_NoConnection && mAutoCache ) {
00552     mTmp = new KTemporaryFile;
00553     mTmp->setPrefix( mCacheDst );
00554     mTmp->setSuffix( "tmp" );
00555     mTmp->open();
00556   }
00557 }
00558 
00559 void ResourceLDAPKIO::Private::activateCache()
00560 {
00561   if ( mTmp && mError == 0 ) {
00562     QString filename = mTmp->fileName();
00563     delete mTmp;
00564     mTmp = 0;
00565     KDE_rename( QFile::encodeName( filename ), QFile::encodeName( mCacheDst ) );
00566   }
00567 }
00568 
00569 KIO::Job *ResourceLDAPKIO::Private::loadFromCache()
00570 {
00571   KIO::Job *job = 0;
00572   if ( mCachePolicy == Cache_Always ||
00573      ( mCachePolicy == Cache_NoConnection &&
00574       mError == KIO::ERR_COULD_NOT_CONNECT ) ) {
00575 
00576     mAddr = Addressee();
00577     mAd = Address( Address::Home );
00578     //initialize ldif parser
00579     mLdif.startParsing();
00580 
00581     mParent->Resource::setReadOnly( true );
00582 
00583     KUrl url( mCacheDst );
00584     job = KIO::get( url, KIO::Reload, KIO::HideProgressInfo );
00585     mParent->connect( job, SIGNAL( data( KIO::Job*, const QByteArray& ) ),
00586                       mParent, SLOT( data( KIO::Job*, const QByteArray& ) ) );
00587   }
00588 
00589   return job;
00590 }
00591 
00592 bool ResourceLDAPKIO::load()
00593 {
00594   kDebug();
00595   KIO::Job *job;
00596 
00597   clear();
00598   //clear the addressee
00599   d->mAddr = Addressee();
00600   d->mAd = Address( Address::Home );
00601   //initialize ldif parser
00602   d->mLdif.startParsing();
00603 
00604   //set to original settings, offline use will disable writing
00605   Resource::setReadOnly( d->mReadOnly );
00606 
00607   d->createCache();
00608   if ( d->mCachePolicy != Cache_Always ) {
00609     job = KIO::get( d->mLDAPUrl, KIO::Reload, KIO::HideProgressInfo );
00610     connect( job, SIGNAL( data( KIO::Job*, const QByteArray& ) ),
00611       this, SLOT( data( KIO::Job*, const QByteArray& ) ) );
00612     connect( job, SIGNAL( result( KJob* ) ),
00613       this, SLOT( syncLoadSaveResult( KJob* ) ) );
00614     d->enter_loop();
00615   }
00616 
00617   job = d->loadFromCache();
00618   if ( job ) {
00619     connect( job, SIGNAL( result( KJob* ) ),
00620       this, SLOT( syncLoadSaveResult( KJob* ) ) );
00621     d->enter_loop();
00622   }
00623   if ( d->mErrorMsg.isEmpty() ) {
00624     kDebug() << "ResourceLDAPKIO load ok!";
00625     return true;
00626   } else {
00627     kDebug() << "ResourceLDAPKIO load finished with error:" << d->mErrorMsg;
00628     addressBook()->error( d->mErrorMsg );
00629     return false;
00630   }
00631 }
00632 
00633 bool ResourceLDAPKIO::asyncLoad()
00634 {
00635   clear();
00636   //clear the addressee
00637   d->mAddr = Addressee();
00638   d->mAd = Address( Address::Home );
00639   //initialize ldif parser
00640   d->mLdif.startParsing();
00641 
00642   Resource::setReadOnly( d->mReadOnly );
00643 
00644   d->createCache();
00645   if ( d->mCachePolicy != Cache_Always ) {
00646     KIO::Job *job = KIO::get( d->mLDAPUrl, KIO::Reload, KIO::HideProgressInfo );
00647     connect( job, SIGNAL( data( KIO::Job*, const QByteArray& ) ),
00648       this, SLOT( data( KIO::Job*, const QByteArray& ) ) );
00649     connect( job, SIGNAL( result( KJob* ) ),
00650       this, SLOT( result( KJob* ) ) );
00651   } else {
00652     result( 0 );
00653   }
00654   return true;
00655 }
00656 
00657 void ResourceLDAPKIO::data( KIO::Job *job, const QByteArray &data )
00658 {
00659   Q_UNUSED( job );
00660   if ( data.size() ) {
00661     d->mLdif.setLdif( data );
00662     if ( d->mTmp ) {
00663       d->mTmp->write( data );
00664     }
00665   } else {
00666     d->mLdif.endLdif();
00667   }
00668 
00669   KLDAP::Ldif::ParseValue ret;
00670   QString name;
00671   QByteArray value;
00672   do {
00673     ret = d->mLdif.nextItem();
00674     switch ( ret ) {
00675       case KLDAP::Ldif::NewEntry:
00676         kDebug() << "new entry:" << d->mLdif.dn().toString();
00677         break;
00678       case KLDAP::Ldif::Item:
00679         name = d->mLdif.attr().toLower();
00680         value = d->mLdif.value();
00681         if ( name == d->mAttributes[ "commonName" ].toLower() ) {
00682           if ( !d->mAddr.formattedName().isEmpty() ) {
00683             QString fn = d->mAddr.formattedName();
00684             d->mAddr.setNameFromString( QString::fromUtf8( value, value.size() ) );
00685             d->mAddr.setFormattedName( fn );
00686           } else {
00687             d->mAddr.setNameFromString( QString::fromUtf8( value, value.size() ) );
00688           }
00689         } else if ( name == d->mAttributes[ "formattedName" ].toLower() ) {
00690           d->mAddr.setFormattedName( QString::fromUtf8( value, value.size() ) );
00691         } else if ( name == d->mAttributes[ "givenName" ].toLower() ) {
00692           d->mAddr.setGivenName( QString::fromUtf8( value, value.size() ) );
00693         } else if ( name == d->mAttributes[ "mail" ].toLower() ) {
00694           d->mAddr.insertEmail( QString::fromUtf8( value, value.size() ), true );
00695         } else if ( name == d->mAttributes[ "mailAlias" ].toLower() ) {
00696           d->mAddr.insertEmail( QString::fromUtf8( value, value.size() ), false );
00697         } else if ( name == d->mAttributes[ "phoneNumber" ].toLower() ) {
00698           PhoneNumber phone;
00699           phone.setNumber( QString::fromUtf8( value, value.size() ) );
00700           d->mAddr.insertPhoneNumber( phone );
00701         } else if ( name == d->mAttributes[ "telephoneNumber" ].toLower() ) {
00702           PhoneNumber phone( QString::fromUtf8( value, value.size() ),
00703             PhoneNumber::Work );
00704           d->mAddr.insertPhoneNumber( phone );
00705         } else if ( name == d->mAttributes[ "facsimileTelephoneNumber" ].toLower() ) {
00706           PhoneNumber phone( QString::fromUtf8( value, value.size() ),
00707             PhoneNumber::Fax );
00708           d->mAddr.insertPhoneNumber( phone );
00709         } else if ( name == d->mAttributes[ "mobile" ].toLower() ) {
00710           PhoneNumber phone( QString::fromUtf8( value, value.size() ),
00711             PhoneNumber::Cell );
00712           d->mAddr.insertPhoneNumber( phone );
00713         } else if ( name == d->mAttributes[ "pager" ].toLower() ) {
00714           PhoneNumber phone( QString::fromUtf8( value, value.size() ),
00715             PhoneNumber::Pager );
00716           d->mAddr.insertPhoneNumber( phone );
00717         } else if ( name == d->mAttributes[ "description" ].toLower() ) {
00718           d->mAddr.setNote( QString::fromUtf8( value, value.size() ) );
00719         } else if ( name == d->mAttributes[ "title" ].toLower() ) {
00720           d->mAddr.setTitle( QString::fromUtf8( value, value.size() ) );
00721         } else if ( name == d->mAttributes[ "street" ].toLower() ) {
00722           d->mAd.setStreet( QString::fromUtf8( value, value.size() ) );
00723         } else if ( name == d->mAttributes[ "state" ].toLower() ) {
00724           d->mAd.setRegion( QString::fromUtf8( value, value.size() ) );
00725         } else if ( name == d->mAttributes[ "city" ].toLower() ) {
00726           d->mAd.setLocality( QString::fromUtf8( value, value.size() ) );
00727         } else if ( name == d->mAttributes[ "postalcode" ].toLower() ) {
00728           d->mAd.setPostalCode( QString::fromUtf8( value, value.size() ) );
00729         } else if ( name == d->mAttributes[ "organization" ].toLower() ) {
00730           d->mAddr.setOrganization( QString::fromUtf8( value, value.size() ) );
00731         } else if ( name == d->mAttributes[ "familyName" ].toLower() ) {
00732           d->mAddr.setFamilyName( QString::fromUtf8( value, value.size() ) );
00733         } else if ( name == d->mAttributes[ "uid" ].toLower() ) {
00734           d->mAddr.setUid( QString::fromUtf8( value, value.size() ) );
00735         } else if ( name == d->mAttributes[ "jpegPhoto" ].toLower() ) {
00736           KABC::Picture photo;
00737           QImage img = QImage::fromData( value );
00738           if ( !img.isNull() ) {
00739             photo.setData( img );
00740             photo.setType( "image/jpeg" );
00741             d->mAddr.setPhoto( photo );
00742           }
00743         }
00744 
00745         break;
00746       case KLDAP::Ldif::EndEntry:
00747       {
00748         d->mAddr.setResource( this );
00749         d->mAddr.insertAddress( d->mAd );
00750         d->mAddr.setChanged( false );
00751         insertAddressee( d->mAddr );
00752         //clear the addressee
00753         d->mAddr = Addressee();
00754         d->mAd = Address( Address::Home );
00755       }
00756       break;
00757       default:
00758         break;
00759     }
00760   } while ( ret != KLDAP::Ldif::MoreData );
00761 }
00762 
00763 void ResourceLDAPKIO::loadCacheResult( KJob *job )
00764 {
00765   d->mErrorMsg.clear();
00766   d->mError = job->error();
00767   if ( d->mError && d->mError != KIO::ERR_USER_CANCELED ) {
00768     d->mErrorMsg = job->errorString();
00769   }
00770   if ( !d->mErrorMsg.isEmpty() ) {
00771     emit loadingError( this, d->mErrorMsg );
00772   } else {
00773     emit loadingFinished( this );
00774   }
00775 }
00776 
00777 void ResourceLDAPKIO::result( KJob *job )
00778 {
00779   d->mErrorMsg.clear();
00780   if ( job ) {
00781     d->mError = job->error();
00782     if ( d->mError && d->mError != KIO::ERR_USER_CANCELED ) {
00783       d->mErrorMsg = job->errorString();
00784     }
00785   } else {
00786     d->mError = 0;
00787   }
00788   d->activateCache();
00789 
00790   KIO::Job *cjob;
00791   cjob = d->loadFromCache();
00792   if ( cjob ) {
00793     connect( cjob, SIGNAL( result( KJob* ) ),
00794       this, SLOT( loadCacheResult( KJob* ) ) );
00795   } else {
00796     if ( !d->mErrorMsg.isEmpty() ) {
00797       emit loadingError( this, d->mErrorMsg );
00798     } else {
00799       emit loadingFinished( this );
00800     }
00801   }
00802 }
00803 
00804 bool ResourceLDAPKIO::save( Ticket *ticket )
00805 {
00806   Q_UNUSED( ticket );
00807   kDebug();
00808 
00809   d->mSaveIt = begin();
00810   KIO::Job *job = KIO::put( d->mLDAPUrl, -1, KIO::Overwrite | KIO::HideProgressInfo );
00811   connect( job, SIGNAL( dataReq( KIO::Job*, QByteArray& ) ),
00812     this, SLOT( saveData( KIO::Job*, QByteArray& ) ) );
00813   connect( job, SIGNAL( result( KJob* ) ),
00814     this, SLOT( syncLoadSaveResult( KJob* ) ) );
00815   d->enter_loop();
00816   if ( d->mErrorMsg.isEmpty() ) {
00817     kDebug() << "ResourceLDAPKIO save ok!";
00818     return true;
00819   } else {
00820     kDebug() << "ResourceLDAPKIO finished with error:" << d->mErrorMsg;
00821     addressBook()->error( d->mErrorMsg );
00822     return false;
00823   }
00824 }
00825 
00826 bool ResourceLDAPKIO::asyncSave( Ticket *ticket )
00827 {
00828   Q_UNUSED( ticket );
00829   kDebug();
00830   d->mSaveIt = begin();
00831   KIO::Job *job = KIO::put( d->mLDAPUrl, -1, KIO::Overwrite | KIO::HideProgressInfo );
00832   connect( job, SIGNAL( dataReq( KIO::Job*, QByteArray& ) ),
00833     this, SLOT( saveData( KIO::Job*, QByteArray& ) ) );
00834   connect( job, SIGNAL( result( KJob* ) ),
00835     this, SLOT( saveResult( KJob* ) ) );
00836   return true;
00837 }
00838 
00839 void ResourceLDAPKIO::syncLoadSaveResult( KJob *job )
00840 {
00841   d->mError = job->error();
00842   if ( d->mError && d->mError != KIO::ERR_USER_CANCELED ) {
00843     d->mErrorMsg = job->errorString();
00844   } else {
00845     d->mErrorMsg.clear();
00846   }
00847   d->activateCache();
00848 
00849   emit leaveModality();
00850 }
00851 
00852 void ResourceLDAPKIO::saveResult( KJob *job )
00853 {
00854   d->mError = job->error();
00855   if ( d->mError && d->mError != KIO::ERR_USER_CANCELED ) {
00856     emit savingError( this, job->errorString() );
00857   } else {
00858     emit savingFinished( this );
00859   }
00860 }
00861 
00862 void ResourceLDAPKIO::saveData( KIO::Job *job, QByteArray &data )
00863 {
00864   Q_UNUSED( job );
00865   while ( d->mSaveIt != end() && !(*d->mSaveIt).changed() ) {
00866     d->mSaveIt++;
00867   }
00868 
00869   if ( d->mSaveIt == end() ) {
00870     kDebug() << "ResourceLDAPKIO endData";
00871     data.resize( 0 );
00872     return;
00873   }
00874 
00875   kDebug() << "ResourceLDAPKIO saveData:" << (*d->mSaveIt).assembledName();
00876 
00877   d->AddresseeToLDIF( data, *d->mSaveIt, d->findUid( (*d->mSaveIt).uid() ) );
00878 //  kDebug() << "ResourceLDAPKIO save LDIF:" << QString::fromUtf8(data);
00879   // mark as unchanged
00880   (*d->mSaveIt).setChanged( false );
00881 
00882   d->mSaveIt++;
00883 }
00884 
00885 void ResourceLDAPKIO::removeAddressee( const Addressee &addr )
00886 {
00887   QString dn = d->findUid( addr.uid() );
00888 
00889   kDebug() << dn;
00890 
00891   if ( !d->mErrorMsg.isEmpty() ) {
00892     addressBook()->error( d->mErrorMsg );
00893     return;
00894   }
00895   if ( !dn.isEmpty() ) {
00896     kDebug() << "ResourceLDAPKIO: found uid:" << dn;
00897     KLDAP::LdapUrl url( d->mLDAPUrl );
00898     url.setPath( '/' + dn );
00899     url.setExtension( "x-dir", "base" );
00900     url.setScope( KLDAP::LdapUrl::Base );
00901     if ( KIO::NetAccess::del( url, 0 ) ) {
00902       mAddrMap.remove( addr.uid() );
00903     }
00904   } else {
00905     //maybe it's not saved yet
00906     mAddrMap.remove( addr.uid() );
00907   }
00908 }
00909 
00910 void ResourceLDAPKIO::setUser( const QString &user )
00911 {
00912   d->mUser = user;
00913 }
00914 
00915 QString ResourceLDAPKIO::user() const
00916 {
00917   return d->mUser;
00918 }
00919 
00920 void ResourceLDAPKIO::setPassword( const QString &password )
00921 {
00922   d->mPassword = password;
00923 }
00924 
00925 QString ResourceLDAPKIO::password() const
00926 {
00927   return d->mPassword;
00928 }
00929 
00930 void ResourceLDAPKIO::setDn( const QString &dn )
00931 {
00932   d->mDn = dn;
00933 }
00934 
00935 QString ResourceLDAPKIO::dn() const
00936 {
00937   return d->mDn;
00938 }
00939 
00940 void ResourceLDAPKIO::setHost( const QString &host )
00941 {
00942   d->mHost = host;
00943 }
00944 
00945 QString ResourceLDAPKIO::host() const
00946 {
00947   return d->mHost;
00948 }
00949 
00950 void ResourceLDAPKIO::setPort( int port )
00951 {
00952   d->mPort = port;
00953 }
00954 
00955 int ResourceLDAPKIO::port() const
00956 {
00957   return d->mPort;
00958 }
00959 
00960 void ResourceLDAPKIO::setVer( int ver )
00961 {
00962   d->mVer = ver;
00963 }
00964 
00965 int ResourceLDAPKIO::ver() const
00966 {
00967   return d->mVer;
00968 }
00969 
00970 void ResourceLDAPKIO::setSizeLimit( int sizelimit )
00971 {
00972   d->mSizeLimit = sizelimit;
00973 }
00974 
00975 int ResourceLDAPKIO::sizeLimit()
00976 {
00977   return d->mSizeLimit;
00978 }
00979 
00980 void ResourceLDAPKIO::setTimeLimit( int timelimit )
00981 {
00982   d->mTimeLimit = timelimit;
00983 }
00984 
00985 int ResourceLDAPKIO::timeLimit()
00986 {
00987   return d->mTimeLimit;
00988 }
00989 
00990 void ResourceLDAPKIO::setFilter( const QString &filter )
00991 {
00992   d->mFilter = filter;
00993 }
00994 
00995 QString ResourceLDAPKIO::filter() const
00996 {
00997   return d->mFilter;
00998 }
00999 
01000 void ResourceLDAPKIO::setIsAnonymous( bool value )
01001 {
01002   d->mAnonymous = value;
01003 }
01004 
01005 bool ResourceLDAPKIO::isAnonymous() const
01006 {
01007   return d->mAnonymous;
01008 }
01009 
01010 void ResourceLDAPKIO::setIsTLS( bool value )
01011 {
01012   d->mTLS = value;
01013 }
01014 
01015 bool ResourceLDAPKIO::isTLS() const
01016 {
01017   return d->mTLS;
01018 }
01019 void ResourceLDAPKIO::setIsSSL( bool value )
01020 {
01021   d->mSSL = value;
01022 }
01023 
01024 bool ResourceLDAPKIO::isSSL() const
01025 {
01026   return d->mSSL;
01027 }
01028 
01029 void ResourceLDAPKIO::setIsSubTree( bool value )
01030 {
01031   d->mSubTree = value;
01032 }
01033 
01034 bool ResourceLDAPKIO::isSubTree() const
01035 {
01036   return d->mSubTree;
01037 }
01038 
01039 void ResourceLDAPKIO::setAttributes( const QMap<QString, QString> &attributes )
01040 {
01041   d->mAttributes = attributes;
01042 }
01043 
01044 QMap<QString, QString> ResourceLDAPKIO::attributes() const
01045 {
01046   return d->mAttributes;
01047 }
01048 
01049 void ResourceLDAPKIO::setRDNPrefix( int value )
01050 {
01051   d->mRDNPrefix = value;
01052 }
01053 
01054 int ResourceLDAPKIO::RDNPrefix() const
01055 {
01056   return d->mRDNPrefix;
01057 }
01058 
01059 void ResourceLDAPKIO::setIsSASL( bool value )
01060 {
01061   d->mSASL = value;
01062 }
01063 
01064 bool ResourceLDAPKIO::isSASL() const
01065 {
01066   return d->mSASL;
01067 }
01068 
01069 void ResourceLDAPKIO::setMech( const QString &mech )
01070 {
01071   d->mMech = mech;
01072 }
01073 
01074 QString ResourceLDAPKIO::mech() const
01075 {
01076   return d->mMech;
01077 }
01078 
01079 void ResourceLDAPKIO::setRealm( const QString &realm )
01080 {
01081   d->mRealm = realm;
01082 }
01083 
01084 QString ResourceLDAPKIO::realm() const
01085 {
01086   return d->mRealm;
01087 }
01088 
01089 void ResourceLDAPKIO::setBindDN( const QString &binddn )
01090 {
01091   d->mBindDN = binddn;
01092 }
01093 
01094 QString ResourceLDAPKIO::bindDN() const
01095 {
01096   return d->mBindDN;
01097 }
01098 
01099 void ResourceLDAPKIO::setCachePolicy( int pol )
01100 {
01101   d->mCachePolicy = pol;
01102 }
01103 
01104 int ResourceLDAPKIO::cachePolicy() const
01105 {
01106   return d->mCachePolicy;
01107 }
01108 
01109 void ResourceLDAPKIO::setAutoCache( bool value )
01110 {
01111   d->mAutoCache = value;
01112 }
01113 
01114 bool ResourceLDAPKIO::autoCache()
01115 {
01116   return d->mAutoCache;
01117 }
01118 
01119 QString ResourceLDAPKIO::cacheDst() const
01120 {
01121   return d->mCacheDst;
01122 }
01123 
01124 #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
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Generated for KDE-PIM Libraries by doxygen 1.5.7.1
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