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