diff options
Diffstat (limited to 'kabc/plugins/ldapkio')
-rw-r--r-- | kabc/plugins/ldapkio/Makefile.am | 28 | ||||
-rw-r--r-- | kabc/plugins/ldapkio/ldapkio.desktop | 10 | ||||
-rw-r--r-- | kabc/plugins/ldapkio/resourceldapkio.cpp | 1041 | ||||
-rw-r--r-- | kabc/plugins/ldapkio/resourceldapkio.h | 171 | ||||
-rw-r--r-- | kabc/plugins/ldapkio/resourceldapkioconfig.cpp | 388 | ||||
-rw-r--r-- | kabc/plugins/ldapkio/resourceldapkioconfig.h | 118 | ||||
-rw-r--r-- | kabc/plugins/ldapkio/resourceldapkioplugin.cpp | 36 |
7 files changed, 1792 insertions, 0 deletions
diff --git a/kabc/plugins/ldapkio/Makefile.am b/kabc/plugins/ldapkio/Makefile.am new file mode 100644 index 000000000..64a72b8f2 --- /dev/null +++ b/kabc/plugins/ldapkio/Makefile.am @@ -0,0 +1,28 @@ +INCLUDES = -I$(top_srcdir)/kabc -I$(top_builddir)/kabc $(all_includes) + +# these are the headers for your project +noinst_HEADERS = resourceldapkioconfig.h + +lib_LTLIBRARIES = libkabc_ldapkio.la +libkabc_ldapkio_la_SOURCES = resourceldapkio.cpp resourceldapkioconfig.cpp +libkabc_ldapkio_la_LDFLAGS = $(KDE_RPATH) $(all_libraries) -version-info 1:0:0 -no-undefined +libkabc_ldapkio_la_LIBADD = $(top_builddir)/kabc/libkabc.la $(LIB_KIO) +libkabc_ldapkio_la_COMPILE_FIRST = $(top_builddir)/kabc/addressee.h + +kde_module_LTLIBRARIES = kabc_ldapkio.la +kabc_ldapkio_la_SOURCES = resourceldapkioplugin.cpp +kabc_ldapkio_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +kabc_ldapkio_la_LIBADD = libkabc_ldapkio.la + +METASOURCES = AUTO + +messages: rc.cpp + $(XGETTEXT) *.cpp -o $(podir)/kabc_ldapkio.pot + +kabcincludedir = $(includedir)/kabc +kabcinclude_HEADERS = resourceldapkio.h + +servicedir = $(kde_servicesdir)/kresources/kabc +service_DATA = ldapkio.desktop + +resourceldapkioplugin.lo: ../../addressee.h diff --git a/kabc/plugins/ldapkio/ldapkio.desktop b/kabc/plugins/ldapkio/ldapkio.desktop new file mode 100644 index 000000000..ebd8b98dd --- /dev/null +++ b/kabc/plugins/ldapkio/ldapkio.desktop @@ -0,0 +1,10 @@ +[Desktop Entry] +Name=LDAP +Name[bn]=এল-ডি-এ-পি (LDAP) +Name[hi]=एलडीएपी (LDAP) +Name[te]=ఎల్డిఏపి +X-KDE-Library=kabc_ldapkio +Type=Service +ServiceTypes=KResources/Plugin +X-KDE-ResourceFamily=contact +X-KDE-ResourceType=ldapkio diff --git a/kabc/plugins/ldapkio/resourceldapkio.cpp b/kabc/plugins/ldapkio/resourceldapkio.cpp new file mode 100644 index 000000000..30b8ba7e0 --- /dev/null +++ b/kabc/plugins/ldapkio/resourceldapkio.cpp @@ -0,0 +1,1041 @@ +/* + This file is part of libkabc. + Copyright (c) 2003 Tobias Koenig <tokoe@kde.org> + Copyright (c) 2004 Szombathelyi György <gyurco@freemail.hu> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + + +#include <qapplication.h> +#include <qbuffer.h> +#include <qfile.h> + +#include <kdebug.h> +#include <kglobal.h> +#include <kstandarddirs.h> +#include <klineedit.h> +#include <klocale.h> +#include <kconfig.h> +#include <kstringhandler.h> +#include <ktempfile.h> + +#include <stdlib.h> +#include <kio/netaccess.h> +#include <kabc/ldif.h> +#include <kabc/ldapurl.h> + +#include "resourceldapkio.h" +#include "resourceldapkioconfig.h" + +using namespace KABC; + +// Hack from Netaccess +void qt_enter_modal( QWidget *widget ); +void qt_leave_modal( QWidget *widget ); + +class ResourceLDAPKIO::ResourceLDAPKIOPrivate +{ + public: + LDIF mLdif; + bool mTLS,mSSL,mSubTree; + QString mResultDn; + Addressee mAddr; + Address mAd; + Resource::Iterator mSaveIt; + bool mSASL; + QString mMech; + QString mRealm, mBindDN; + LDAPUrl mLDAPUrl; + int mVer, mSizeLimit, mTimeLimit, mRDNPrefix; + int mError; + int mCachePolicy; + bool mReadOnly; + bool mAutoCache; + QString mCacheDst; + KTempFile *mTmp; +}; + +ResourceLDAPKIO::ResourceLDAPKIO( const KConfig *config ) + : Resource( config ) +{ + d = new ResourceLDAPKIOPrivate; + if ( config ) { + QMap<QString, QString> attrList; + QStringList attributes = config->readListEntry( "LdapAttributes" ); + for ( uint pos = 0; pos < attributes.count(); pos += 2 ) + mAttributes.insert( attributes[ pos ], attributes[ pos + 1 ] ); + + mUser = config->readEntry( "LdapUser" ); + mPassword = KStringHandler::obscure( config->readEntry( "LdapPassword" ) ); + mDn = config->readEntry( "LdapDn" ); + mHost = config->readEntry( "LdapHost" ); + mPort = config->readNumEntry( "LdapPort", 389 ); + mFilter = config->readEntry( "LdapFilter" ); + mAnonymous = config->readBoolEntry( "LdapAnonymous" ); + d->mTLS = config->readBoolEntry( "LdapTLS" ); + d->mSSL = config->readBoolEntry( "LdapSSL" ); + d->mSubTree = config->readBoolEntry( "LdapSubTree" ); + d->mSASL = config->readBoolEntry( "LdapSASL" ); + d->mMech = config->readEntry( "LdapMech" ); + d->mRealm = config->readEntry( "LdapRealm" ); + d->mBindDN = config->readEntry( "LdapBindDN" ); + d->mVer = config->readNumEntry( "LdapVer", 3 ); + d->mTimeLimit = config->readNumEntry( "LdapTimeLimit", 0 ); + d->mSizeLimit = config->readNumEntry( "LdapSizeLimit", 0 ); + d->mRDNPrefix = config->readNumEntry( "LdapRDNPrefix", 0 ); + d->mCachePolicy = config->readNumEntry( "LdapCachePolicy", 0 ); + d->mAutoCache = config->readBoolEntry( "LdapAutoCache", true ); + } else { + mPort = 389; + mAnonymous = true; + mUser = mPassword = mHost = mFilter = mDn = ""; + d->mMech = d->mRealm = d->mBindDN = ""; + d->mTLS = d->mSSL = d->mSubTree = d->mSASL = false; + d->mVer = 3; d->mRDNPrefix = 0; + d->mTimeLimit = d->mSizeLimit = 0; + d->mCachePolicy = Cache_No; + d->mAutoCache = true; + } + d->mCacheDst = KGlobal::dirs()->saveLocation("cache", "ldapkio") + "/" + + type() + "_" + identifier(); + init(); +} + +ResourceLDAPKIO::~ResourceLDAPKIO() +{ + delete d; +} + +void ResourceLDAPKIO::enter_loop() +{ + QWidget dummy(0,0,WType_Dialog | WShowModal); + dummy.setFocusPolicy( QWidget::NoFocus ); + qt_enter_modal(&dummy); + qApp->enter_loop(); + qt_leave_modal(&dummy); +} + +void ResourceLDAPKIO::entries( KIO::Job*, const KIO::UDSEntryList & list ) +{ + KIO::UDSEntryListConstIterator it = list.begin(); + KIO::UDSEntryListConstIterator end = list.end(); + for (; it != end; ++it) { + KIO::UDSEntry::ConstIterator it2 = (*it).begin(); + for( ; it2 != (*it).end(); it2++ ) { + if ( (*it2).m_uds == KIO::UDS_URL ) { + KURL tmpurl( (*it2).m_str ); + d->mResultDn = tmpurl.path(); + kdDebug(7125) << "findUid(): " << d->mResultDn << endl; + if ( d->mResultDn.startsWith("/") ) d->mResultDn.remove(0,1); + return; + } + } + } +} + +void ResourceLDAPKIO::listResult( KIO::Job *job) +{ + d->mError = job->error(); + if ( d->mError && d->mError != KIO::ERR_USER_CANCELED ) + mErrorMsg = job->errorString(); + else + mErrorMsg = ""; + qApp->exit_loop(); +} + +QString ResourceLDAPKIO::findUid( const QString &uid ) +{ + LDAPUrl url( d->mLDAPUrl ); + KIO::UDSEntry entry; + + mErrorMsg = d->mResultDn = ""; + + url.setAttributes("dn"); + url.setFilter( "(" + mAttributes[ "uid" ] + "=" + uid + ")" + mFilter ); + url.setExtension( "x-dir", "one" ); + + kdDebug(7125) << "ResourceLDAPKIO::findUid() uid: " << uid << " url " << + url.prettyURL() << endl; + + KIO::ListJob * listJob = KIO::listDir( url, false /* no GUI */ ); + connect( listJob, + SIGNAL( entries( KIO::Job *, const KIO::UDSEntryList& ) ), + SLOT( entries( KIO::Job*, const KIO::UDSEntryList& ) ) ); + connect( listJob, SIGNAL( result( KIO::Job* ) ), + this, SLOT( listResult( KIO::Job* ) ) ); + + enter_loop(); + return d->mResultDn; +} + +QCString ResourceLDAPKIO::addEntry( const QString &attr, const QString &value, bool mod ) +{ + QCString tmp; + if ( !attr.isEmpty() ) { + if ( mod ) tmp += LDIF::assembleLine( "replace", attr ) + "\n"; + tmp += LDIF::assembleLine( attr, value ) + "\n"; + if ( mod ) tmp += "-\n"; + } + return ( tmp ); +} + +bool ResourceLDAPKIO::AddresseeToLDIF( QByteArray &ldif, const Addressee &addr, + const QString &olddn ) +{ + QCString tmp; + QString dn; + QByteArray data; + bool mod = false; + + if ( olddn.isEmpty() ) { + //insert new entry + switch ( d->mRDNPrefix ) { + case 1: + dn = mAttributes[ "uid" ] + "=" + addr.uid() + "," +mDn; + break; + case 0: + default: + dn = mAttributes[ "commonName" ] + "=" + addr.assembledName() + "," +mDn; + break; + } + } else { + //modify existing entry + mod = true; + if ( olddn.startsWith( mAttributes[ "uid" ] ) ) { + dn = mAttributes[ "uid" ] + "=" + addr.uid() + "," + olddn.section( ',', 1 ); + } else if ( olddn.startsWith( mAttributes[ "commonName" ] ) ) { + dn = mAttributes[ "commonName" ] + "=" + addr.assembledName() + "," + + olddn.section( ',', 1 ); + } else { + dn = olddn; + } + + if ( olddn.lower() != dn.lower() ) { + tmp = LDIF::assembleLine( "dn", olddn ) + "\n"; + tmp += "changetype: modrdn\n"; + tmp += LDIF::assembleLine( "newrdn", dn.section( ',', 0, 0 ) ) + "\n"; + tmp += "deleteoldrdn: 1\n\n"; + } + } + + + tmp += LDIF::assembleLine( "dn", dn ) + "\n"; + if ( mod ) tmp += "changetype: modify\n"; + if ( !mod ) { + tmp += "objectClass: top\n"; + QStringList obclass = QStringList::split( ',', mAttributes[ "objectClass" ] ); + for ( QStringList::iterator it = obclass.begin(); it != obclass.end(); it++ ) { + tmp += LDIF::assembleLine( "objectClass", *it ) + "\n"; + } + } + + tmp += addEntry( mAttributes[ "commonName" ], addr.assembledName(), mod ); + tmp += addEntry( mAttributes[ "formattedName" ], addr.formattedName(), mod ); + tmp += addEntry( mAttributes[ "givenName" ], addr.givenName(), mod ); + tmp += addEntry( mAttributes[ "familyName" ], addr.familyName(), mod ); + tmp += addEntry( mAttributes[ "uid" ], addr.uid(), mod ); + + PhoneNumber number; + number = addr.phoneNumber( PhoneNumber::Home ); + tmp += addEntry( mAttributes[ "phoneNumber" ], number.number().utf8(), mod ); + number = addr.phoneNumber( PhoneNumber::Work ); + tmp += addEntry( mAttributes[ "telephoneNumber" ], number.number().utf8(), mod ); + number = addr.phoneNumber( PhoneNumber::Fax ); + tmp += addEntry( mAttributes[ "facsimileTelephoneNumber" ], number.number().utf8(), mod ); + number = addr.phoneNumber( PhoneNumber::Cell ); + tmp += addEntry( mAttributes[ "mobile" ], number.number().utf8(), mod ); + number = addr.phoneNumber( PhoneNumber::Pager ); + tmp += addEntry( mAttributes[ "pager" ], number.number().utf8(), mod ); + + tmp += addEntry( mAttributes[ "description" ], addr.note(), mod ); + tmp += addEntry( mAttributes[ "title" ], addr.title(), mod ); + tmp += addEntry( mAttributes[ "organization" ], addr.organization(), mod ); + + Address ad = addr.address( Address::Home ); + if ( !ad.isEmpty() ) { + tmp += addEntry( mAttributes[ "street" ], ad.street(), mod ); + tmp += addEntry( mAttributes[ "state" ], ad.region(), mod ); + tmp += addEntry( mAttributes[ "city" ], ad.locality(), mod ); + tmp += addEntry( mAttributes[ "postalcode" ], ad.postalCode(), mod ); + } + + QStringList emails = addr.emails(); + QStringList::ConstIterator mailIt = emails.begin(); + + if ( !mAttributes[ "mail" ].isEmpty() ) { + if ( mod ) tmp += + LDIF::assembleLine( "replace", mAttributes[ "mail" ] ) + "\n"; + if ( mailIt != emails.end() ) { + tmp += LDIF::assembleLine( mAttributes[ "mail" ], *mailIt ) + "\n"; + mailIt ++; + } + if ( mod && mAttributes[ "mail" ] != mAttributes[ "mailAlias" ] ) tmp += "-\n"; + } + + if ( !mAttributes[ "mailAlias" ].isEmpty() ) { + if ( mod && mAttributes[ "mail" ] != mAttributes[ "mailAlias" ] ) tmp += + LDIF::assembleLine( "replace", mAttributes[ "mailAlias" ] ) + "\n"; + for ( ; mailIt != emails.end(); ++mailIt ) { + tmp += LDIF::assembleLine( mAttributes[ "mailAlias" ], *mailIt ) + "\n" ; + } + if ( mod ) tmp += "-\n"; + } + + if ( !mAttributes[ "jpegPhoto" ].isEmpty() ) { + QByteArray pic; + QBuffer buffer( pic ); + buffer.open( IO_WriteOnly ); + addr.photo().data().save( &buffer, "JPEG" ); + + if ( mod ) tmp += + LDIF::assembleLine( "replace", mAttributes[ "jpegPhoto" ] ) + "\n"; + tmp += LDIF::assembleLine( mAttributes[ "jpegPhoto" ], pic, 76 ) + "\n"; + if ( mod ) tmp += "-\n"; + } + + tmp += "\n"; + kdDebug(7125) << "ldif: " << QString::fromUtf8(tmp) << endl; + ldif = tmp; + return true; +} + +void ResourceLDAPKIO::setReadOnly( bool value ) +{ + //save the original readonly flag, because offline using disables writing + d->mReadOnly = true; + Resource::setReadOnly( value ); +} + +void ResourceLDAPKIO::init() +{ + if ( mPort == 0 ) mPort = 389; + + /** + If you want to add new attributes, append them here, add a + translation string in the ctor of AttributesDialog and + handle them in the load() method below. + These are the default values + */ + if ( !mAttributes.contains("objectClass") ) + mAttributes.insert( "objectClass", "inetOrgPerson" ); + if ( !mAttributes.contains("commonName") ) + mAttributes.insert( "commonName", "cn" ); + if ( !mAttributes.contains("formattedName") ) + mAttributes.insert( "formattedName", "displayName" ); + if ( !mAttributes.contains("familyName") ) + mAttributes.insert( "familyName", "sn" ); + if ( !mAttributes.contains("givenName") ) + mAttributes.insert( "givenName", "givenName" ); + if ( !mAttributes.contains("mail") ) + mAttributes.insert( "mail", "mail" ); + if ( !mAttributes.contains("mailAlias") ) + mAttributes.insert( "mailAlias", "" ); + if ( !mAttributes.contains("phoneNumber") ) + mAttributes.insert( "phoneNumber", "homePhone" ); + if ( !mAttributes.contains("telephoneNumber") ) + mAttributes.insert( "telephoneNumber", "telephoneNumber" ); + if ( !mAttributes.contains("facsimileTelephoneNumber") ) + mAttributes.insert( "facsimileTelephoneNumber", "facsimileTelephoneNumber" ); + if ( !mAttributes.contains("mobile") ) + mAttributes.insert( "mobile", "mobile" ); + if ( !mAttributes.contains("pager") ) + mAttributes.insert( "pager", "pager" ); + if ( !mAttributes.contains("description") ) + mAttributes.insert( "description", "description" ); + + if ( !mAttributes.contains("title") ) + mAttributes.insert( "title", "title" ); + if ( !mAttributes.contains("street") ) + mAttributes.insert( "street", "street" ); + if ( !mAttributes.contains("state") ) + mAttributes.insert( "state", "st" ); + if ( !mAttributes.contains("city") ) + mAttributes.insert( "city", "l" ); + if ( !mAttributes.contains("organization") ) + mAttributes.insert( "organization", "o" ); + if ( !mAttributes.contains("postalcode") ) + mAttributes.insert( "postalcode", "postalCode" ); + + if ( !mAttributes.contains("uid") ) + mAttributes.insert( "uid", "uid" ); + if ( !mAttributes.contains("jpegPhoto") ) + mAttributes.insert( "jpegPhoto", "jpegPhoto" ); + + d->mLDAPUrl = KURL(); + if ( !mAnonymous ) { + d->mLDAPUrl.setUser( mUser ); + d->mLDAPUrl.setPass( mPassword ); + } + d->mLDAPUrl.setProtocol( d->mSSL ? "ldaps" : "ldap"); + d->mLDAPUrl.setHost( mHost ); + d->mLDAPUrl.setPort( mPort ); + d->mLDAPUrl.setDn( mDn ); + + if (!mAttributes.empty()) { + QMap<QString,QString>::Iterator it; + QStringList attr; + for ( it = mAttributes.begin(); it != mAttributes.end(); ++it ) { + if ( !it.data().isEmpty() && it.key() != "objectClass" ) + attr.append( it.data() ); + } + d->mLDAPUrl.setAttributes( attr ); + } + + d->mLDAPUrl.setScope( d->mSubTree ? LDAPUrl::Sub : LDAPUrl::One ); + if ( !mFilter.isEmpty() && mFilter != "(objectClass=*)" ) + d->mLDAPUrl.setFilter( mFilter ); + d->mLDAPUrl.setExtension( "x-dir", "base" ); + if ( d->mTLS ) d->mLDAPUrl.setExtension( "x-tls", "" ); + d->mLDAPUrl.setExtension( "x-ver", QString::number( d->mVer ) ); + if ( d->mSizeLimit ) + d->mLDAPUrl.setExtension( "x-sizelimit", QString::number( d->mSizeLimit ) ); + if ( d->mTimeLimit ) + d->mLDAPUrl.setExtension( "x-timelimit", QString::number( d->mTimeLimit ) ); + if ( d->mSASL ) { + d->mLDAPUrl.setExtension( "x-sasl", "" ); + if ( !d->mBindDN.isEmpty() ) d->mLDAPUrl.setExtension( "bindname", d->mBindDN ); + if ( !d->mMech.isEmpty() ) d->mLDAPUrl.setExtension( "x-mech", d->mMech ); + if ( !d->mRealm.isEmpty() ) d->mLDAPUrl.setExtension( "x-realm", d->mRealm ); + } + + d->mReadOnly = readOnly(); + + kdDebug(7125) << "resource_ldapkio url: " << d->mLDAPUrl.prettyURL() << endl; +} + +void ResourceLDAPKIO::writeConfig( KConfig *config ) +{ + Resource::writeConfig( config ); + + config->writeEntry( "LdapUser", mUser ); + config->writeEntry( "LdapPassword", KStringHandler::obscure( mPassword ) ); + config->writeEntry( "LdapDn", mDn ); + config->writeEntry( "LdapHost", mHost ); + config->writeEntry( "LdapPort", mPort ); + config->writeEntry( "LdapFilter", mFilter ); + config->writeEntry( "LdapAnonymous", mAnonymous ); + config->writeEntry( "LdapTLS", d->mTLS ); + config->writeEntry( "LdapSSL", d->mSSL ); + config->writeEntry( "LdapSubTree", d->mSubTree ); + config->writeEntry( "LdapSASL", d->mSASL ); + config->writeEntry( "LdapMech", d->mMech ); + config->writeEntry( "LdapVer", d->mVer ); + config->writeEntry( "LdapTimeLimit", d->mTimeLimit ); + config->writeEntry( "LdapSizeLimit", d->mSizeLimit ); + config->writeEntry( "LdapRDNPrefix", d->mRDNPrefix ); + config->writeEntry( "LdapRealm", d->mRealm ); + config->writeEntry( "LdapBindDN", d->mBindDN ); + config->writeEntry( "LdapCachePolicy", d->mCachePolicy ); + config->writeEntry( "LdapAutoCache", d->mAutoCache ); + + QStringList attributes; + QMap<QString, QString>::Iterator it; + for ( it = mAttributes.begin(); it != mAttributes.end(); ++it ) + attributes << it.key() << it.data(); + + config->writeEntry( "LdapAttributes", attributes ); +} + +Ticket *ResourceLDAPKIO::requestSaveTicket() +{ + if ( !addressBook() ) { + kdDebug(7125) << "no addressbook" << endl; + return 0; + } + + return createTicket( this ); +} + +void ResourceLDAPKIO::releaseSaveTicket( Ticket *ticket ) +{ + delete ticket; +} + +bool ResourceLDAPKIO::doOpen() +{ + return true; +} + +void ResourceLDAPKIO::doClose() +{ +} + +void ResourceLDAPKIO::createCache() +{ + d->mTmp = NULL; + if ( d->mCachePolicy == Cache_NoConnection && d->mAutoCache ) { + d->mTmp = new KTempFile( d->mCacheDst, "tmp" ); + d->mTmp->setAutoDelete( true ); + } +} + +void ResourceLDAPKIO::activateCache() +{ + if ( d->mTmp && d->mError == 0 ) { + d->mTmp->close(); + rename( QFile::encodeName( d->mTmp->name() ), QFile::encodeName( d->mCacheDst ) ); + } + if ( d->mTmp ) { + delete d->mTmp; + d->mTmp = 0; + } +} + +KIO::Job *ResourceLDAPKIO::loadFromCache() +{ + KIO::Job *job = NULL; + if ( d->mCachePolicy == Cache_Always || + ( d->mCachePolicy == Cache_NoConnection && + d->mError == KIO::ERR_COULD_NOT_CONNECT ) ) { + + d->mAddr = Addressee(); + d->mAd = Address( Address::Home ); + //initialize ldif parser + d->mLdif.startParsing(); + + Resource::setReadOnly( true ); + + KURL url( d->mCacheDst ); + job = KIO::get( url, true, false ); + connect( job, SIGNAL( data( KIO::Job*, const QByteArray& ) ), + this, SLOT( data( KIO::Job*, const QByteArray& ) ) ); + } + return job; +} + +bool ResourceLDAPKIO::load() +{ + kdDebug(7125) << "ResourceLDAPKIO::load()" << endl; + KIO::Job *job; + + clear(); + //clear the addressee + d->mAddr = Addressee(); + d->mAd = Address( Address::Home ); + //initialize ldif parser + d->mLdif.startParsing(); + + //set to original settings, offline use will disable writing + Resource::setReadOnly( d->mReadOnly ); + + createCache(); + if ( d->mCachePolicy != Cache_Always ) { + job = KIO::get( d->mLDAPUrl, true, false ); + connect( job, SIGNAL( data( KIO::Job*, const QByteArray& ) ), + this, SLOT( data( KIO::Job*, const QByteArray& ) ) ); + connect( job, SIGNAL( result( KIO::Job* ) ), + this, SLOT( syncLoadSaveResult( KIO::Job* ) ) ); + enter_loop(); + } + + job = loadFromCache(); + if ( job ) { + connect( job, SIGNAL( result( KIO::Job* ) ), + this, SLOT( syncLoadSaveResult( KIO::Job* ) ) ); + enter_loop(); + } + if ( mErrorMsg.isEmpty() ) { + kdDebug(7125) << "ResourceLDAPKIO load ok!" << endl; + return true; + } else { + kdDebug(7125) << "ResourceLDAPKIO load finished with error: " << mErrorMsg << endl; + addressBook()->error( mErrorMsg ); + return false; + } +} + +bool ResourceLDAPKIO::asyncLoad() +{ + clear(); + //clear the addressee + d->mAddr = Addressee(); + d->mAd = Address( Address::Home ); + //initialize ldif parser + d->mLdif.startParsing(); + + Resource::setReadOnly( d->mReadOnly ); + + createCache(); + if ( d->mCachePolicy != Cache_Always ) { + KIO::Job *job = KIO::get( d->mLDAPUrl, true, false ); + connect( job, SIGNAL( data( KIO::Job*, const QByteArray& ) ), + this, SLOT( data( KIO::Job*, const QByteArray& ) ) ); + connect( job, SIGNAL( result( KIO::Job* ) ), + this, SLOT( result( KIO::Job* ) ) ); + } else { + result( NULL ); + } + return true; +} + +void ResourceLDAPKIO::data( KIO::Job *, const QByteArray &data ) +{ + if ( data.size() ) { + d->mLdif.setLDIF( data ); + if ( d->mTmp ) { + d->mTmp->file()->writeBlock( data ); + } + } else { + d->mLdif.endLDIF(); + } + + LDIF::ParseVal ret; + QString name; + QByteArray value; + do { + ret = d->mLdif.nextItem(); + switch ( ret ) { + case LDIF::NewEntry: + kdDebug(7125) << "new entry: " << d->mLdif.dn() << endl; + break; + case LDIF::Item: + name = d->mLdif.attr().lower(); + value = d->mLdif.val(); + if ( name == mAttributes[ "commonName" ].lower() ) { + if ( !d->mAddr.formattedName().isEmpty() ) { + QString fn = d->mAddr.formattedName(); + d->mAddr.setNameFromString( QString::fromUtf8( value, value.size() ) ); + d->mAddr.setFormattedName( fn ); + } else + d->mAddr.setNameFromString( QString::fromUtf8( value, value.size() ) ); + } else if ( name == mAttributes[ "formattedName" ].lower() ) { + d->mAddr.setFormattedName( QString::fromUtf8( value, value.size() ) ); + } else if ( name == mAttributes[ "givenName" ].lower() ) { + d->mAddr.setGivenName( QString::fromUtf8( value, value.size() ) ); + } else if ( name == mAttributes[ "mail" ].lower() ) { + d->mAddr.insertEmail( QString::fromUtf8( value, value.size() ), true ); + } else if ( name == mAttributes[ "mailAlias" ].lower() ) { + d->mAddr.insertEmail( QString::fromUtf8( value, value.size() ), false ); + } else if ( name == mAttributes[ "phoneNumber" ].lower() ) { + PhoneNumber phone; + phone.setNumber( QString::fromUtf8( value, value.size() ) ); + d->mAddr.insertPhoneNumber( phone ); + } else if ( name == mAttributes[ "telephoneNumber" ].lower() ) { + PhoneNumber phone( QString::fromUtf8( value, value.size() ), + PhoneNumber::Work ); + d->mAddr.insertPhoneNumber( phone ); + } else if ( name == mAttributes[ "facsimileTelephoneNumber" ].lower() ) { + PhoneNumber phone( QString::fromUtf8( value, value.size() ), + PhoneNumber::Fax ); + d->mAddr.insertPhoneNumber( phone ); + } else if ( name == mAttributes[ "mobile" ].lower() ) { + PhoneNumber phone( QString::fromUtf8( value, value.size() ), + PhoneNumber::Cell ); + d->mAddr.insertPhoneNumber( phone ); + } else if ( name == mAttributes[ "pager" ].lower() ) { + PhoneNumber phone( QString::fromUtf8( value, value.size() ), + PhoneNumber::Pager ); + d->mAddr.insertPhoneNumber( phone ); + } else if ( name == mAttributes[ "description" ].lower() ) { + d->mAddr.setNote( QString::fromUtf8( value, value.size() ) ); + } else if ( name == mAttributes[ "title" ].lower() ) { + d->mAddr.setTitle( QString::fromUtf8( value, value.size() ) ); + } else if ( name == mAttributes[ "street" ].lower() ) { + d->mAd.setStreet( QString::fromUtf8( value, value.size() ) ); + } else if ( name == mAttributes[ "state" ].lower() ) { + d->mAd.setRegion( QString::fromUtf8( value, value.size() ) ); + } else if ( name == mAttributes[ "city" ].lower() ) { + d->mAd.setLocality( QString::fromUtf8( value, value.size() ) ); + } else if ( name == mAttributes[ "postalcode" ].lower() ) { + d->mAd.setPostalCode( QString::fromUtf8( value, value.size() ) ); + } else if ( name == mAttributes[ "organization" ].lower() ) { + d->mAddr.setOrganization( QString::fromUtf8( value, value.size() ) ); + } else if ( name == mAttributes[ "familyName" ].lower() ) { + d->mAddr.setFamilyName( QString::fromUtf8( value, value.size() ) ); + } else if ( name == mAttributes[ "uid" ].lower() ) { + d->mAddr.setUid( QString::fromUtf8( value, value.size() ) ); + } else if ( name == mAttributes[ "jpegPhoto" ].lower() ) { + KABC::Picture photo; + QImage img( value ); + if ( !img.isNull() ) { + photo.setData( img ); + photo.setType( "image/jpeg" ); + d->mAddr.setPhoto( photo ); + } + } + + break; + case LDIF::EndEntry: { + d->mAddr.setResource( this ); + d->mAddr.insertAddress( d->mAd ); + d->mAddr.setChanged( false ); + insertAddressee( d->mAddr ); + //clear the addressee + d->mAddr = Addressee(); + d->mAd = Address( Address::Home ); + } + break; + default: + break; + } + } while ( ret != LDIF::MoreData ); +} + +void ResourceLDAPKIO::loadCacheResult( KIO::Job *job ) +{ + mErrorMsg = ""; + d->mError = job->error(); + if ( d->mError && d->mError != KIO::ERR_USER_CANCELED ) { + mErrorMsg = job->errorString(); + } + if ( !mErrorMsg.isEmpty() ) + emit loadingError( this, mErrorMsg ); + else + emit loadingFinished( this ); +} + +void ResourceLDAPKIO::result( KIO::Job *job ) +{ + mErrorMsg = ""; + if ( job ) { + d->mError = job->error(); + if ( d->mError && d->mError != KIO::ERR_USER_CANCELED ) { + mErrorMsg = job->errorString(); + } + } else { + d->mError = 0; + } + activateCache(); + + KIO::Job *cjob; + cjob = loadFromCache(); + if ( cjob ) { + connect( cjob, SIGNAL( result( KIO::Job* ) ), + this, SLOT( loadCacheResult( KIO::Job* ) ) ); + } else { + if ( !mErrorMsg.isEmpty() ) + emit loadingError( this, mErrorMsg ); + else + emit loadingFinished( this ); + } +} + +bool ResourceLDAPKIO::save( Ticket* ) +{ + kdDebug(7125) << "ResourceLDAPKIO save" << endl; + + d->mSaveIt = begin(); + KIO::Job *job = KIO::put( d->mLDAPUrl, -1, true, false, false ); + connect( job, SIGNAL( dataReq( KIO::Job*, QByteArray& ) ), + this, SLOT( saveData( KIO::Job*, QByteArray& ) ) ); + connect( job, SIGNAL( result( KIO::Job* ) ), + this, SLOT( syncLoadSaveResult( KIO::Job* ) ) ); + enter_loop(); + if ( mErrorMsg.isEmpty() ) { + kdDebug(7125) << "ResourceLDAPKIO save ok!" << endl; + return true; + } else { + kdDebug(7125) << "ResourceLDAPKIO finished with error: " << mErrorMsg << endl; + addressBook()->error( mErrorMsg ); + return false; + } +} + +bool ResourceLDAPKIO::asyncSave( Ticket* ) +{ + kdDebug(7125) << "ResourceLDAPKIO asyncSave" << endl; + d->mSaveIt = begin(); + KIO::Job *job = KIO::put( d->mLDAPUrl, -1, true, false, false ); + connect( job, SIGNAL( dataReq( KIO::Job*, QByteArray& ) ), + this, SLOT( saveData( KIO::Job*, QByteArray& ) ) ); + connect( job, SIGNAL( result( KIO::Job* ) ), + this, SLOT( saveResult( KIO::Job* ) ) ); + return true; +} + +void ResourceLDAPKIO::syncLoadSaveResult( KIO::Job *job ) +{ + d->mError = job->error(); + if ( d->mError && d->mError != KIO::ERR_USER_CANCELED ) + mErrorMsg = job->errorString(); + else + mErrorMsg = ""; + activateCache(); + + qApp->exit_loop(); +} + +void ResourceLDAPKIO::saveResult( KIO::Job *job ) +{ + d->mError = job->error(); + if ( d->mError && d->mError != KIO::ERR_USER_CANCELED ) + emit savingError( this, job->errorString() ); + else + emit savingFinished( this ); +} + +void ResourceLDAPKIO::saveData( KIO::Job*, QByteArray& data ) +{ + while ( d->mSaveIt != end() && + !(*d->mSaveIt).changed() ) d->mSaveIt++; + + if ( d->mSaveIt == end() ) { + kdDebug(7125) << "ResourceLDAPKIO endData" << endl; + data.resize(0); + return; + } + + kdDebug(7125) << "ResourceLDAPKIO saveData: " << (*d->mSaveIt).assembledName() << endl; + + AddresseeToLDIF( data, *d->mSaveIt, findUid( (*d->mSaveIt).uid() ) ); +// kdDebug(7125) << "ResourceLDAPKIO save LDIF: " << QString::fromUtf8(data) << endl; + // mark as unchanged + (*d->mSaveIt).setChanged( false ); + + d->mSaveIt++; +} + +void ResourceLDAPKIO::removeAddressee( const Addressee& addr ) +{ + QString dn = findUid( addr.uid() ); + + kdDebug(7125) << "ResourceLDAPKIO: removeAddressee: " << dn << endl; + + if ( !mErrorMsg.isEmpty() ) { + addressBook()->error( mErrorMsg ); + return; + } + if ( !dn.isEmpty() ) { + kdDebug(7125) << "ResourceLDAPKIO: found uid: " << dn << endl; + LDAPUrl url( d->mLDAPUrl ); + url.setPath( "/" + dn ); + url.setExtension( "x-dir", "base" ); + url.setScope( LDAPUrl::Base ); + if ( KIO::NetAccess::del( url, NULL ) ) mAddrMap.erase( addr.uid() ); + } else { + //maybe it's not saved yet + mAddrMap.erase( addr.uid() ); + } +} + + +void ResourceLDAPKIO::setUser( const QString &user ) +{ + mUser = user; +} + +QString ResourceLDAPKIO::user() const +{ + return mUser; +} + +void ResourceLDAPKIO::setPassword( const QString &password ) +{ + mPassword = password; +} + +QString ResourceLDAPKIO::password() const +{ + return mPassword; +} + +void ResourceLDAPKIO::setDn( const QString &dn ) +{ + mDn = dn; +} + +QString ResourceLDAPKIO::dn() const +{ + return mDn; +} + +void ResourceLDAPKIO::setHost( const QString &host ) +{ + mHost = host; +} + +QString ResourceLDAPKIO::host() const +{ + return mHost; +} + +void ResourceLDAPKIO::setPort( int port ) +{ + mPort = port; +} + +int ResourceLDAPKIO::port() const +{ + return mPort; +} + +void ResourceLDAPKIO::setVer( int ver ) +{ + d->mVer = ver; +} + +int ResourceLDAPKIO::ver() const +{ + return d->mVer; +} + +void ResourceLDAPKIO::setSizeLimit( int sizelimit ) +{ + d->mSizeLimit = sizelimit; +} + +int ResourceLDAPKIO::sizeLimit() +{ + return d->mSizeLimit; +} + +void ResourceLDAPKIO::setTimeLimit( int timelimit ) +{ + d->mTimeLimit = timelimit; +} + +int ResourceLDAPKIO::timeLimit() +{ + return d->mTimeLimit; +} + +void ResourceLDAPKIO::setFilter( const QString &filter ) +{ + mFilter = filter; +} + +QString ResourceLDAPKIO::filter() const +{ + return mFilter; +} + +void ResourceLDAPKIO::setIsAnonymous( bool value ) +{ + mAnonymous = value; +} + +bool ResourceLDAPKIO::isAnonymous() const +{ + return mAnonymous; +} + +void ResourceLDAPKIO::setIsTLS( bool value ) +{ + d->mTLS = value; +} + +bool ResourceLDAPKIO::isTLS() const +{ + return d->mTLS; +} +void ResourceLDAPKIO::setIsSSL( bool value ) +{ + d->mSSL = value; +} + +bool ResourceLDAPKIO::isSSL() const +{ + return d->mSSL; +} + +void ResourceLDAPKIO::setIsSubTree( bool value ) +{ + d->mSubTree = value; +} + +bool ResourceLDAPKIO::isSubTree() const +{ + return d->mSubTree; +} + +void ResourceLDAPKIO::setAttributes( const QMap<QString, QString> &attributes ) +{ + mAttributes = attributes; +} + +QMap<QString, QString> ResourceLDAPKIO::attributes() const +{ + return mAttributes; +} + +void ResourceLDAPKIO::setRDNPrefix( int value ) +{ + d->mRDNPrefix = value; +} + +int ResourceLDAPKIO::RDNPrefix() const +{ + return d->mRDNPrefix; +} + +void ResourceLDAPKIO::setIsSASL( bool value ) +{ + d->mSASL = value; +} + +bool ResourceLDAPKIO::isSASL() const +{ + return d->mSASL; +} + +void ResourceLDAPKIO::setMech( const QString &mech ) +{ + d->mMech = mech; +} + +QString ResourceLDAPKIO::mech() const +{ + return d->mMech; +} + +void ResourceLDAPKIO::setRealm( const QString &realm ) +{ + d->mRealm = realm; +} + +QString ResourceLDAPKIO::realm() const +{ + return d->mRealm; +} + +void ResourceLDAPKIO::setBindDN( const QString &binddn ) +{ + d->mBindDN = binddn; +} + +QString ResourceLDAPKIO::bindDN() const +{ + return d->mBindDN; +} + +void ResourceLDAPKIO::setCachePolicy( int pol ) +{ + d->mCachePolicy = pol; +} + +int ResourceLDAPKIO::cachePolicy() const +{ + return d->mCachePolicy; +} + +void ResourceLDAPKIO::setAutoCache( bool value ) +{ + d->mAutoCache = value; +} + +bool ResourceLDAPKIO::autoCache() +{ + return d->mAutoCache; +} + +QString ResourceLDAPKIO::cacheDst() const +{ + return d->mCacheDst; +} + + +#include "resourceldapkio.moc" diff --git a/kabc/plugins/ldapkio/resourceldapkio.h b/kabc/plugins/ldapkio/resourceldapkio.h new file mode 100644 index 000000000..bd72a9b11 --- /dev/null +++ b/kabc/plugins/ldapkio/resourceldapkio.h @@ -0,0 +1,171 @@ +/* + This file is part of libkabc. + Copyright (c) 2003 Tobias Koenig <tokoe@kde.org> + Copyright (c) 2004 Szombathelyi György <gyurco@freemail.hu> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KABC_RESOURCELDAP_H +#define KABC_RESOURCELDAP_H + +#include <kabc/resource.h> +#include <kabc/ldif.h> +#include <kio/job.h> + +class KConfig; + +namespace KABC { + +class KABC_EXPORT ResourceLDAPKIO : public Resource +{ + Q_OBJECT + + public: + enum CachePolicy{ Cache_No, Cache_NoConnection, Cache_Always }; + + ResourceLDAPKIO( const KConfig* ); + virtual ~ResourceLDAPKIO(); + /** + * Call this after you used one of the set... methods + */ + virtual void init(); + + virtual void writeConfig( KConfig* ); + + virtual bool doOpen(); + virtual void doClose(); + + virtual Ticket *requestSaveTicket(); + virtual void releaseSaveTicket( Ticket* ); + + virtual bool readOnly() const { return Resource::readOnly(); } + virtual void setReadOnly( bool value ); + + virtual bool load(); + virtual bool asyncLoad(); + virtual bool save( Ticket * ticket ); + virtual bool asyncSave( Ticket * ticket ); + + virtual void removeAddressee( const Addressee& addr ); + + void setUser( const QString &user ); + QString user() const; + + void setPassword( const QString &password ); + QString password() const; + + void setRealm( const QString &realm ); + QString realm() const; + + void setBindDN( const QString &binddn ); + QString bindDN() const; + + void setDn( const QString &dn ); + QString dn() const; + + void setHost( const QString &host ); + QString host() const; + + void setPort( int port ); + int port() const; + + void setVer( int ver ); + int ver() const; + + void setSizeLimit( int sizelimit ); + int sizeLimit(); + + void setTimeLimit( int timelimit ); + int timeLimit(); + + void setFilter( const QString &filter ); + QString filter() const; + + void setIsAnonymous( bool value ); + bool isAnonymous() const; + + void setAttributes( const QMap<QString, QString> &attributes ); + QMap<QString, QString> attributes() const; + + void setRDNPrefix( int value ); + int RDNPrefix() const; + + void setIsTLS( bool value ); + bool isTLS() const ; + + void setIsSSL( bool value ); + bool isSSL() const; + + void setIsSubTree( bool value ); + bool isSubTree() const ; + + void setIsSASL( bool value ); + bool isSASL() const ; + + void setMech( const QString &mech ); + QString mech() const; + + void setCachePolicy( int pol ); + int cachePolicy() const; + + void setAutoCache( bool value ); + bool autoCache(); + + QString cacheDst() const; + +protected slots: + void entries( KIO::Job*, const KIO::UDSEntryList& ); + void data( KIO::Job*, const QByteArray& ); + void result( KIO::Job* ); + void listResult( KIO::Job* ); + void syncLoadSaveResult( KIO::Job* ); + void saveResult( KIO::Job* ); + void saveData( KIO::Job*, QByteArray& ); + void loadCacheResult( KIO::Job* ); + + private: + QString mUser; + QString mPassword; + QString mDn; + QString mHost; + QString mFilter; + int mPort; + bool mAnonymous; + QMap<QString, QString> mAttributes; + + KURL mLDAPUrl; + int mGetCounter; //KDE 4: remove + bool mErrorOccured; //KDE 4: remove + QString mErrorMsg; + QMap<KIO::Job*, QByteArray> mJobMap; //KDE 4: remove + + KIO::Job *loadFromCache(); + void createCache(); + void activateCache(); + void enter_loop(); + QCString addEntry( const QString &attr, const QString &value, bool mod ); + QString findUid( const QString &uid ); + bool AddresseeToLDIF( QByteArray &ldif, const Addressee &addr, + const QString &olddn ); + + class ResourceLDAPKIOPrivate; + ResourceLDAPKIOPrivate *d; +}; + +} + +#endif diff --git a/kabc/plugins/ldapkio/resourceldapkioconfig.cpp b/kabc/plugins/ldapkio/resourceldapkioconfig.cpp new file mode 100644 index 000000000..ae54ab8c3 --- /dev/null +++ b/kabc/plugins/ldapkio/resourceldapkioconfig.cpp @@ -0,0 +1,388 @@ +/* + This file is part of libkabc. + Copyright (c) 2002 - 2003 Tobias Koenig <tokoe@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +#include <qapplication.h> + +#include <qcheckbox.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qpushbutton.h> +#include <qspinbox.h> +#include <qvbox.h> +#include <qvgroupbox.h> +#include <qhbuttongroup.h> +#include <qradiobutton.h> + +#include <kaccelmanager.h> +#include <kcombobox.h> +#include <kdebug.h> +#include <kdialogbase.h> +#include <klocale.h> +#include <klineedit.h> +#include <kmessagebox.h> +#include <kio/netaccess.h> + +#include "resourceldapkio.h" + +#include "resourceldapkioconfig.h" +#include "resourceldapkioconfig.moc" + +using namespace KABC; + +ResourceLDAPKIOConfig::ResourceLDAPKIOConfig( QWidget* parent, const char* name ) + : KRES::ConfigWidget( parent, name ) +{ + QBoxLayout *mainLayout = new QVBoxLayout( this ); + mainLayout->setAutoAdd( true ); + cfg = new LdapConfigWidget( LdapConfigWidget::W_ALL, this ); + + mSubTree = new QCheckBox( i18n( "Sub-tree query" ), this ); + QHBox *box = new QHBox( this ); + box->setSpacing( KDialog::spacingHint() ); + mEditButton = new QPushButton( i18n( "Edit Attributes..." ), box ); + mCacheButton = new QPushButton( i18n( "Offline Use..." ), box ); + + connect( mEditButton, SIGNAL( clicked() ), SLOT( editAttributes() ) ); + connect( mCacheButton, SIGNAL( clicked() ), SLOT( editCache() ) ); +} + +void ResourceLDAPKIOConfig::loadSettings( KRES::Resource *res ) +{ + ResourceLDAPKIO *resource = dynamic_cast<ResourceLDAPKIO*>( res ); + + if ( !resource ) { + kdDebug(5700) << "ResourceLDAPKIOConfig::loadSettings(): cast failed" << endl; + return; + } + + cfg->setUser( resource->user() ); + cfg->setPassword( resource->password() ); + cfg->setRealm( resource->realm() ); + cfg->setBindDN( resource->bindDN() ); + cfg->setHost( resource->host() ); + cfg->setPort( resource->port() ); + cfg->setVer( resource->ver() ); + cfg->setTimeLimit( resource->timeLimit() ); + cfg->setSizeLimit( resource->sizeLimit() ); + cfg->setDn( resource->dn() ); + cfg->setFilter( resource->filter() ); + cfg->setMech( resource->mech() ); + if ( resource->isTLS() ) cfg->setSecTLS(); + else if ( resource->isSSL() ) cfg->setSecSSL(); + else cfg->setSecNO(); + if ( resource->isAnonymous() ) cfg->setAuthAnon(); + else if ( resource->isSASL() ) cfg->setAuthSASL(); + else cfg->setAuthSimple(); + + mSubTree->setChecked( resource->isSubTree() ); + mAttributes = resource->attributes(); + mRDNPrefix = resource->RDNPrefix(); + mCachePolicy = resource->cachePolicy(); + mCacheDst = resource->cacheDst(); + mAutoCache = resource->autoCache(); +} + +void ResourceLDAPKIOConfig::saveSettings( KRES::Resource *res ) +{ + ResourceLDAPKIO *resource = dynamic_cast<ResourceLDAPKIO*>( res ); + + if ( !resource ) { + kdDebug(5700) << "ResourceLDAPKIOConfig::saveSettings(): cast failed" << endl; + return; + } + + resource->setUser( cfg->user() ); + resource->setPassword( cfg->password() ); + resource->setRealm( cfg->realm() ); + resource->setBindDN( cfg->bindDN() ); + resource->setHost( cfg->host() ); + resource->setPort( cfg->port() ); + resource->setVer( cfg->ver() ); + resource->setTimeLimit( cfg->timeLimit() ); + resource->setSizeLimit( cfg->sizeLimit() ); + resource->setDn( cfg->dn() ); + resource->setFilter( cfg->filter() ); + resource->setIsAnonymous( cfg->isAuthAnon() ); + resource->setIsSASL( cfg->isAuthSASL() ); + resource->setMech( cfg->mech() ); + resource->setIsTLS( cfg->isSecTLS() ); + resource->setIsSSL( cfg->isSecSSL() ); + resource->setIsSubTree( mSubTree->isChecked() ); + resource->setAttributes( mAttributes ); + resource->setRDNPrefix( mRDNPrefix ); + resource->setCachePolicy( mCachePolicy ); + resource->init(); + +} + +void ResourceLDAPKIOConfig::editAttributes() +{ + AttributesDialog dlg( mAttributes, mRDNPrefix, this ); + if ( dlg.exec() ) { + mAttributes = dlg.attributes(); + mRDNPrefix = dlg.rdnprefix(); + } +} + +void ResourceLDAPKIOConfig::editCache() +{ + LDAPUrl src; + QStringList attr; + + src = cfg->url(); + src.setScope( mSubTree->isChecked() ? LDAPUrl::Sub : LDAPUrl::One ); + if (!mAttributes.empty()) { + QMap<QString,QString>::Iterator it; + QStringList attr; + for ( it = mAttributes.begin(); it != mAttributes.end(); ++it ) { + if ( !it.data().isEmpty() && it.key() != "objectClass" ) + attr.append( it.data() ); + } + src.setAttributes( attr ); + } + src.setExtension( "x-dir", "base" ); + OfflineDialog dlg( mAutoCache, mCachePolicy, src, mCacheDst, this ); + if ( dlg.exec() ) { + mCachePolicy = dlg.cachePolicy(); + mAutoCache = dlg.autoCache(); + } + +} + +AttributesDialog::AttributesDialog( const QMap<QString, QString> &attributes, + int rdnprefix, + QWidget *parent, const char *name ) + : KDialogBase( Plain, i18n( "Attributes Configuration" ), Ok | Cancel, + Ok, parent, name, true, true ) +{ + mNameDict.setAutoDelete( true ); + mNameDict.insert( "objectClass", new QString( i18n( "Object classes" ) ) ); + mNameDict.insert( "commonName", new QString( i18n( "Common name" ) ) ); + mNameDict.insert( "formattedName", new QString( i18n( "Formatted name" ) ) ); + mNameDict.insert( "familyName", new QString( i18n( "Family name" ) ) ); + mNameDict.insert( "givenName", new QString( i18n( "Given name" ) ) ); + mNameDict.insert( "organization", new QString( i18n( "Organization" ) ) ); + mNameDict.insert( "title", new QString( i18n( "Title" ) ) ); + mNameDict.insert( "street", new QString( i18n( "Street" ) ) ); + mNameDict.insert( "state", new QString( i18n( "State" ) ) ); + mNameDict.insert( "city", new QString( i18n( "City" ) ) ); + mNameDict.insert( "postalcode", new QString( i18n( "Postal code" ) ) ); + mNameDict.insert( "mail", new QString( i18n( "Email" ) ) ); + mNameDict.insert( "mailAlias", new QString( i18n( "Email alias" ) ) ); + mNameDict.insert( "phoneNumber", new QString( i18n( "Telephone number" ) ) ); + mNameDict.insert( "telephoneNumber", new QString( i18n( "Work telephone number" ) ) ); + mNameDict.insert( "facsimileTelephoneNumber", new QString( i18n( "Fax number" ) ) ); + mNameDict.insert( "mobile", new QString( i18n( "Cell phone number" ) ) ); + mNameDict.insert( "pager", new QString( i18n( "Pager" ) ) ); + mNameDict.insert( "description", new QString( i18n( "Note" ) ) ); + mNameDict.insert( "uid", new QString( i18n( "UID" ) ) ); + mNameDict.insert( "jpegPhoto", new QString( i18n( "Photo" ) ) ); + + // default map + mDefaultMap.insert( "objectClass", "inetOrgPerson" ); + mDefaultMap.insert( "commonName", "cn" ); + mDefaultMap.insert( "formattedName", "displayName" ); + mDefaultMap.insert( "familyName", "sn" ); + mDefaultMap.insert( "givenName", "givenName" ); + mDefaultMap.insert( "title", "title" ); + mDefaultMap.insert( "street", "street" ); + mDefaultMap.insert( "state", "st" ); + mDefaultMap.insert( "city", "l" ); + mDefaultMap.insert( "organization", "o" ); + mDefaultMap.insert( "postalcode", "postalCode" ); + mDefaultMap.insert( "mail", "mail" ); + mDefaultMap.insert( "mailAlias", "" ); + mDefaultMap.insert( "phoneNumber", "homePhone" ); + mDefaultMap.insert( "telephoneNumber", "telephoneNumber" ); + mDefaultMap.insert( "facsimileTelephoneNumber", "facsimileTelephoneNumber" ); + mDefaultMap.insert( "mobile", "mobile" ); + mDefaultMap.insert( "pager", "pager" ); + mDefaultMap.insert( "description", "description" ); + mDefaultMap.insert( "uid", "uid" ); + mDefaultMap.insert( "jpegPhoto", "jpegPhoto" ); + + // overwrite the default values here + QMap<QString, QString> kolabMap, netscapeMap, evolutionMap, outlookMap; + + // kolab + kolabMap.insert( "formattedName", "display-name" ); + kolabMap.insert( "mailAlias", "mailalias" ); + + // evolution + evolutionMap.insert( "formattedName", "fileAs" ); + + mMapList.append( attributes ); + mMapList.append( kolabMap ); + mMapList.append( netscapeMap ); + mMapList.append( evolutionMap ); + mMapList.append( outlookMap ); + + QFrame *page = plainPage(); + QGridLayout *layout = new QGridLayout( page, 4, ( attributes.count() + 4 ) >> 1, + 0, spacingHint() ); + + QLabel *label = new QLabel( i18n( "Template:" ), page ); + layout->addWidget( label, 0, 0 ); + mMapCombo = new KComboBox( page ); + layout->addWidget( mMapCombo, 0, 1 ); + + mMapCombo->insertItem( i18n( "User Defined" ) ); + mMapCombo->insertItem( i18n( "Kolab" ) ); + mMapCombo->insertItem( i18n( "Netscape" ) ); + mMapCombo->insertItem( i18n( "Evolution" ) ); + mMapCombo->insertItem( i18n( "Outlook" ) ); + connect( mMapCombo, SIGNAL( activated( int ) ), SLOT( mapChanged( int ) ) ); + + label = new QLabel( i18n( "RDN prefix attribute:" ), page ); + layout->addWidget( label, 1, 0 ); + mRDNCombo = new KComboBox( page ); + layout->addWidget( mRDNCombo, 1, 1 ); + mRDNCombo->insertItem( i18n( "commonName" ) ); + mRDNCombo->insertItem( i18n( "UID" ) ); + mRDNCombo->setCurrentItem( rdnprefix ); + + QMap<QString, QString>::ConstIterator it; + int i, j = 0; + for ( i = 2, it = attributes.begin(); it != attributes.end(); ++it, ++i ) { + if ( mNameDict[ it.key() ] == 0 ) { + i--; + continue; + } + if ( (uint)(i - 2) == ( mNameDict.count() >> 1 ) ) { + i = 0; + j = 2; + } + kdDebug(7125) << "itkey: " << it.key() << " i: " << i << endl; + label = new QLabel( *mNameDict[ it.key() ] + ":", page ); + KLineEdit *lineedit = new KLineEdit( page ); + mLineEditDict.insert( it.key(), lineedit ); + lineedit->setText( it.data() ); + label->setBuddy( lineedit ); + layout->addWidget( label, i, j ); + layout->addWidget( lineedit, i, j+1 ); + } + + for ( i = 1; i < mMapCombo->count(); i++ ) { + QDictIterator<KLineEdit> it2( mLineEditDict ); + for ( ; it2.current(); ++it2 ) { + if ( mMapList[ i ].contains( it2.currentKey() ) ) { + if ( mMapList[ i ][ it2.currentKey() ] != it2.current()->text() ) break; + } else { + if ( mDefaultMap[ it2.currentKey() ] != it2.current()->text() ) break; + } + } + if ( !it2.current() ) { + mMapCombo->setCurrentItem( i ); + break; + } + } + + KAcceleratorManager::manage( this ); +} + +AttributesDialog::~AttributesDialog() +{ +} + +QMap<QString, QString> AttributesDialog::attributes() const +{ + QMap<QString, QString> map; + + QDictIterator<KLineEdit> it( mLineEditDict ); + for ( ; it.current(); ++it ) + map.insert( it.currentKey(), it.current()->text() ); + + return map; +} + +int AttributesDialog::rdnprefix() const +{ + return mRDNCombo->currentItem(); +} + +void AttributesDialog::mapChanged( int pos ) +{ + + // apply first the default and than the spezific changes + QMap<QString, QString>::Iterator it; + for ( it = mDefaultMap.begin(); it != mDefaultMap.end(); ++it ) + mLineEditDict[ it.key() ]->setText( it.data() ); + + for ( it = mMapList[ pos ].begin(); it != mMapList[ pos ].end(); ++it ) { + if ( !it.data().isEmpty() ) { + KLineEdit *le = mLineEditDict[ it.key() ]; + if ( le ) le->setText( it.data() ); + } + } +} + +OfflineDialog::OfflineDialog( bool autoCache, int cachePolicy, const KURL &src, + const QString &dst, QWidget *parent, const char *name ) + : KDialogBase( Plain, i18n( "Offline Configuration" ), Ok | Cancel, + Ok, parent, name, true, true ) +{ + QFrame *page = plainPage(); + QVBoxLayout *layout = new QVBoxLayout( page ); + layout->setAutoAdd( true ); + + mSrc = src; mDst = dst; + mCacheGroup = new QButtonGroup( 1, Qt::Horizontal, + i18n("Offline Cache Policy"), page ); + + QRadioButton *bt; + new QRadioButton( i18n("Do not use offline cache"), mCacheGroup ); + bt = new QRadioButton( i18n("Use local copy if no connection"), mCacheGroup ); + new QRadioButton( i18n("Always use local copy"), mCacheGroup ); + mCacheGroup->setButton( cachePolicy ); + + mAutoCache = new QCheckBox( i18n("Refresh offline cache automatically"), + page ); + mAutoCache->setChecked( autoCache ); + mAutoCache->setEnabled( bt->isChecked() ); + + connect( bt, SIGNAL(toggled(bool)), mAutoCache, SLOT(setEnabled(bool)) ); + + QPushButton *lcache = new QPushButton( i18n("Load into Cache"), page ); + connect( lcache, SIGNAL( clicked() ), SLOT( loadCache() ) ); +} + +OfflineDialog::~OfflineDialog() +{ +} + +bool OfflineDialog::autoCache() const +{ + return mAutoCache->isChecked(); +} + +int OfflineDialog::cachePolicy() const +{ + return mCacheGroup->selectedId(); +} + +void OfflineDialog::loadCache() +{ + if ( KIO::NetAccess::download( mSrc, mDst, this ) ) { + KMessageBox::information( this, + i18n("Successfully downloaded directory server contents!") ); + } else { + KMessageBox::error( this, + i18n("An error occurred downloading directory server contents into file %1.").arg(mDst) ); + } +} diff --git a/kabc/plugins/ldapkio/resourceldapkioconfig.h b/kabc/plugins/ldapkio/resourceldapkioconfig.h new file mode 100644 index 000000000..c261cbd06 --- /dev/null +++ b/kabc/plugins/ldapkio/resourceldapkioconfig.h @@ -0,0 +1,118 @@ +/* + This file is part of libkabc. + Copyright (c) 2002 - 2003 Tobias Koenig <tokoe@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef RESOURCELDAPCONFIG_H +#define RESOURCELDAPCONFIG_H + +#include <qmap.h> +#include <qradiobutton.h> +#include <qcombobox.h> +#include <qdict.h> + +#include <kdialogbase.h> +#include <kresources/configwidget.h> +#include <kabc/ldif.h> +#include <kabc/ldapconfigwidget.h> + + +class QCheckBox; +class QPushButton; +class QSpinBox; +class QString; + +class KComboBox; +class KLineEdit; + +namespace KABC { + +class KABC_EXPORT ResourceLDAPKIOConfig : public KRES::ConfigWidget +{ + Q_OBJECT + + public: + ResourceLDAPKIOConfig( QWidget* parent = 0, const char* name = 0 ); + + public slots: + void loadSettings( KRES::Resource* ); + void saveSettings( KRES::Resource* ); + + private slots: + void editAttributes(); + void editCache(); + private: + QPushButton *mEditButton, *mCacheButton; + LdapConfigWidget *cfg; + QCheckBox *mSubTree; + QMap<QString, QString> mAttributes; + int mRDNPrefix, mCachePolicy; + bool mAutoCache; + QString mCacheDst; +}; + +class AttributesDialog : public KDialogBase +{ + Q_OBJECT + + public: + AttributesDialog( const QMap<QString, QString> &attributes, int rdnprefix, + QWidget *parent, const char *name = 0 ); + ~AttributesDialog(); + + QMap<QString, QString> attributes() const; + int rdnprefix() const; + + private slots: + void mapChanged( int pos ); + + private: + enum { UserMap, KolabMap, NetscapeMap, EvolutionMap, OutlookMap }; + + KComboBox *mMapCombo, *mRDNCombo; + QValueList< QMap<QString, QString> > mMapList; + QMap<QString, QString> mDefaultMap; + QDict<KLineEdit> mLineEditDict; + QDict<QString> mNameDict; +}; + +class OfflineDialog : public KDialogBase +{ + Q_OBJECT + + public: + OfflineDialog( bool autoCache, int cachePolicy, const KURL &src, + const QString &dst, QWidget *parent, const char *name = 0 ); + ~OfflineDialog(); + + int cachePolicy() const; + bool autoCache() const; + + private slots: + void loadCache(); + + private: + KURL mSrc; + QString mDst; + QButtonGroup *mCacheGroup; + QCheckBox *mAutoCache; +}; + +} + +#endif diff --git a/kabc/plugins/ldapkio/resourceldapkioplugin.cpp b/kabc/plugins/ldapkio/resourceldapkioplugin.cpp new file mode 100644 index 000000000..98b21061e --- /dev/null +++ b/kabc/plugins/ldapkio/resourceldapkioplugin.cpp @@ -0,0 +1,36 @@ +/* + This file is part of libkabc. + Copyright (c) 2003 Tobias Koenig <tokoe@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "resourceldapkio.h" +#include "resourceldapkioconfig.h" + +#include <kglobal.h> +#include <klocale.h> + +using namespace KABC; + +extern "C" +{ + KDE_EXPORT void *init_kabc_ldapkio() + { + KGlobal::locale()->insertCatalogue("kabc_ldapkio"); + return new KRES::PluginFactory<ResourceLDAPKIO, ResourceLDAPKIOConfig>(); + } +} |