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