• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdepimlibs-4.9.4 API Reference
  • KDE Home
  • Contact Us
 

kabc

  • kabc
  • plugins
  • ldapkio
resourceldapkio.cpp
1 // -*- c-basic-offset: 2 -*-
2 /*
3  This file is part of libkabc.
4  Copyright (c) 2003 Tobias Koenig <tokoe@kde.org>
5  Copyright (c) 2004 Szombathelyi György <gyurco@freemail.hu>
6 
7  This library is free software; you can redistribute it and/or
8  modify it under the terms of the GNU Library General Public
9  License as published by the Free Software Foundation; either
10  version 2 of the License, or (at your option) any later version.
11 
12  This library is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  Library General Public License for more details.
16 
17  You should have received a copy of the GNU Library General Public License
18  along with this library; see the file COPYING.LIB. If not, write to
19  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  Boston, MA 02110-1301, USA.
21 */
22 #include "resourceldapkio.h"
23 #include "resourceldapkioconfig.h"
24 
25 #include "kldap/ldif.h"
26 #include "kldap/ldapdn.h"
27 #include "kldap/ldapurl.h"
28 
29 #include <kio/netaccess.h>
30 #include <kio/udsentry.h>
31 #include <kdebug.h>
32 #include <kde_file.h>
33 #include <kglobal.h>
34 #include <kstandarddirs.h>
35 #include <klineedit.h>
36 #include <klocale.h>
37 #include <kconfig.h>
38 #include <kstringhandler.h>
39 #include <ktemporaryfile.h>
40 
41 #include <QtCore/QBuffer>
42 #include <QtCore/QEventLoop>
43 #include <QtCore/QFile>
44 
45 #include <stdlib.h>
46 
47 using namespace KABC;
48 
49 class ResourceLDAPKIO::Private
50 {
51  public:
52  Private( ResourceLDAPKIO *parent )
53  : mParent( parent ), mPort( 389 ), mAnonymous( true ), mTLS( false ),
54  mSSL( false ), mSubTree( false ), mSASL( false ), mVer( 3 ),
55  mRDNPrefix( 0 ), mTimeLimit( 0 ), mSizeLimit( 0 ),
56  mCachePolicy( Cache_No ), mAutoCache( true )
57  {
58  KGlobal::locale()->insertCatalog( QLatin1String( "libkldap" ) );
59  }
60 
61  KIO::TransferJob *loadFromCache();
62  void createCache();
63  void activateCache();
64  void enter_loop();
65  QByteArray addEntry( const QString &attr, const QString &value, bool mod );
66  QString findUid( const QString &uid );
67  bool AddresseeToLDIF( QByteArray &ldif, const Addressee &addr, const QString &olddn );
68 
69  ResourceLDAPKIO *mParent;
70  QString mUser;
71  QString mPassword;
72  QString mDn;
73  QString mHost;
74  QString mFilter;
75  int mPort;
76  bool mAnonymous;
77  QMap<QString, QString> mAttributes;
78 
79  QString mErrorMsg;
80 
81  KLDAP::Ldif mLdif;
82  bool mTLS, mSSL, mSubTree;
83  QString mResultDn;
84  Addressee mAddr;
85  Address mAd;
86  Resource::Iterator mSaveIt;
87  bool mSASL;
88  QString mMech;
89  QString mRealm, mBindDN;
90  KLDAP::LdapUrl mLDAPUrl;
91  int mVer;
92  int mRDNPrefix;
93  int mTimeLimit;
94  int mSizeLimit;
95  int mError;
96  int mCachePolicy;
97  bool mReadOnly;
98  bool mAutoCache;
99  QString mCacheDst;
100  KTemporaryFile *mTmp;
101 };
102 
103 ResourceLDAPKIO::ResourceLDAPKIO()
104  : Resource(), d( new Private( this ) )
105 {
106  d->mCacheDst = KGlobal::dirs()->saveLocation( "cache", QLatin1String( "ldapkio" ) ) +
107  QLatin1Char( '/' ) + type() + QLatin1Char( '_' ) + identifier();
108  init();
109 }
110 
111 ResourceLDAPKIO::ResourceLDAPKIO( const KConfigGroup &group )
112  : Resource( group ), d( new Private( this ) )
113 {
114  QMap<QString, QString> attrList;
115  QStringList attributes = group.readEntry( "LdapAttributes", QStringList() );
116  for ( int pos = 0; pos < attributes.count(); pos += 2 ) {
117  d->mAttributes.insert( attributes[ pos ], attributes[ pos + 1 ] );
118  }
119 
120  d->mUser = group.readEntry( "LdapUser" );
121  d->mPassword = KStringHandler::obscure( group.readEntry( "LdapPassword" ) );
122  d->mDn = group.readEntry( "LdapDn" );
123  d->mHost = group.readEntry( "LdapHost" );
124  d->mPort = group.readEntry( "LdapPort", 389 );
125  d->mFilter = group.readEntry( "LdapFilter" );
126  d->mAnonymous = group.readEntry( "LdapAnonymous", false );
127  d->mTLS = group.readEntry( "LdapTLS", false );
128  d->mSSL = group.readEntry( "LdapSSL", false );
129  d->mSubTree = group.readEntry( "LdapSubTree", false );
130  d->mSASL = group.readEntry( "LdapSASL", false );
131  d->mMech = group.readEntry( "LdapMech" );
132  d->mRealm = group.readEntry( "LdapRealm" );
133  d->mBindDN = group.readEntry( "LdapBindDN" );
134  d->mVer = group.readEntry( "LdapVer", 3 );
135  d->mTimeLimit = group.readEntry( "LdapTimeLimit", 0 );
136  d->mSizeLimit = group.readEntry( "LdapSizeLimit", 0 );
137  d->mRDNPrefix = group.readEntry( "LdapRDNPrefix", 0 );
138  d->mCachePolicy = group.readEntry( "LdapCachePolicy", 0 );
139  d->mAutoCache = group.readEntry( "LdapAutoCache", true );
140  d->mCacheDst = KGlobal::dirs()->saveLocation(
141  "cache", QLatin1String( "ldapkio" ) ) + QLatin1Char( '/' ) +
142  type() + QLatin1Char( '_' ) + identifier();
143  init();
144 }
145 
146 ResourceLDAPKIO::~ResourceLDAPKIO()
147 {
148  delete d;
149 }
150 
151 void ResourceLDAPKIO::Private::enter_loop()
152 {
153  QEventLoop eventLoop;
154  mParent->connect( mParent, SIGNAL(leaveModality()), &eventLoop, SLOT(quit()) );
155  eventLoop.exec( QEventLoop::ExcludeUserInputEvents );
156 }
157 
158 void ResourceLDAPKIO::entries( KIO::Job *, const KIO::UDSEntryList &list )
159 {
160  KIO::UDSEntryList::ConstIterator it = list.begin();
161  KIO::UDSEntryList::ConstIterator end = list.end();
162  for ( ; it != end; ++it ) {
163  const QString urlStr = (*it).stringValue( KIO::UDSEntry::UDS_URL );
164  if ( !urlStr.isEmpty() ) {
165  KUrl tmpurl( urlStr );
166  d->mResultDn = tmpurl.path();
167  kDebug() << "findUid():" << d->mResultDn;
168  if ( d->mResultDn.startsWith( QLatin1Char( '/' ) ) ) {
169  d->mResultDn.remove( 0, 1 );
170  }
171  return;
172  }
173  }
174 }
175 
176 void ResourceLDAPKIO::listResult( KJob *job )
177 {
178  d->mError = job->error();
179  if ( d->mError && d->mError != KIO::ERR_USER_CANCELED ) {
180  d->mErrorMsg = job->errorString();
181  } else {
182  d->mErrorMsg.clear();
183  }
184  emit leaveModality();
185 }
186 
187 QString ResourceLDAPKIO::Private::findUid( const QString &uid )
188 {
189  KLDAP::LdapUrl url( mLDAPUrl );
190  KIO::UDSEntry entry;
191 
192  mErrorMsg.clear();
193  mResultDn.clear();
194 
195  url.setAttributes( QStringList( QLatin1String( "dn" ) ) );
196  url.setFilter( QLatin1Char( '(' ) + mAttributes[ QLatin1String( "uid" ) ] +
197  QLatin1Char( '=' ) + uid + QLatin1Char( ')' ) + mFilter );
198  url.setExtension( QLatin1String( "x-dir" ), QLatin1String( "one" ) );
199 
200  kDebug() << uid << "url" << url.prettyUrl();
201 
202  KIO::ListJob *listJob = KIO::listDir( url, KIO::HideProgressInfo );
203  mParent->connect( listJob, SIGNAL(entries(KIO::Job*,KIO::UDSEntryList)),
204  SLOT(entries(KIO::Job*,KIO::UDSEntryList)) );
205  mParent->connect( listJob, SIGNAL(result(KJob*)),
206  mParent, SLOT(listResult(KJob*)) );
207 
208  enter_loop();
209  return mResultDn;
210 }
211 
212 QByteArray ResourceLDAPKIO::Private::addEntry( const QString &attr, const QString &value, bool mod )
213 {
214  QByteArray tmp;
215  if ( !attr.isEmpty() ) {
216  if ( mod ) {
217  tmp += KLDAP::Ldif::assembleLine( QLatin1String( "replace" ), attr ) + '\n';
218  }
219  if ( !value.isEmpty() ) {
220  tmp += KLDAP::Ldif::assembleLine( attr, value ) + '\n';
221  }
222  if ( mod ) {
223  tmp += "-\n";
224  }
225  }
226  return tmp;
227 }
228 
229 bool ResourceLDAPKIO::Private::AddresseeToLDIF( QByteArray &ldif, const Addressee &addr,
230  const QString &olddn )
231 {
232  QByteArray tmp;
233  QString dn;
234  QByteArray data;
235  bool mod = false;
236 
237  if ( olddn.isEmpty() ) {
238  //insert new entry
239  switch ( mRDNPrefix ) {
240  case 1:
241  dn = mAttributes[ QLatin1String( "uid" ) ] +
242  QLatin1Char( '=' ) + addr.uid() + QLatin1Char( ',' ) + mDn;
243  break;
244  case 0:
245  default:
246  dn = mAttributes[ QLatin1String( "commonName" ) ] +
247  QLatin1Char( '=' ) + addr.assembledName() + QLatin1Char( ',' ) + mDn;
248  break;
249  }
250  } else {
251  //modify existing entry
252  mod = true;
253  if ( olddn.startsWith( mAttributes[ QLatin1String( "uid" ) ] ) ) {
254  dn = mAttributes[ QLatin1String( "uid" ) ] + QLatin1Char( '=' ) + addr.uid() +
255  QLatin1Char( ',' ) + olddn.section( QLatin1Char( ',' ), 1 );
256  } else if ( olddn.startsWith( mAttributes[ QLatin1String( "commonName" ) ] ) ) {
257  dn = mAttributes[ QLatin1String( "commonName" ) ] +
258  QLatin1Char( '=' ) + addr.assembledName()
259  + QLatin1Char( ',' ) + olddn.section( QLatin1Char( ',' ), 1 );
260  } else {
261  dn = olddn;
262  }
263 
264  if ( olddn.toLower() != dn.toLower() ) {
265  tmp = KLDAP::Ldif::assembleLine( QLatin1String( "dn" ), olddn ) + '\n';
266  tmp += "changetype: modrdn\n";
267  tmp += KLDAP::Ldif::assembleLine( QLatin1String( "newrdn" ),
268  dn.section( QLatin1Char( ',' ), 0, 0 ) ) + '\n';
269  tmp += "deleteoldrdn: 1\n\n";
270  }
271  }
272 
273  tmp += KLDAP::Ldif::assembleLine( QLatin1String( "dn" ), dn ) + '\n';
274  if ( mod ) {
275  tmp += "changetype: modify\n";
276  }
277  if ( !mod ) {
278  tmp += "objectClass: top\n";
279  const QStringList obclass =
280  mAttributes[ QLatin1String( "objectClass" ) ].split( QLatin1Char( ',' ),
281  QString::SkipEmptyParts );
282  for ( QStringList::const_iterator it = obclass.constBegin(); it != obclass.constEnd(); ++it ) {
283  tmp += KLDAP::Ldif::assembleLine( QLatin1String( "objectClass" ), *it ) + '\n';
284  }
285  }
286 
287  tmp += addEntry( mAttributes[ QLatin1String( "commonName" ) ], addr.assembledName(), mod );
288  tmp += addEntry( mAttributes[ QLatin1String( "formattedName" ) ], addr.formattedName(), mod );
289  tmp += addEntry( mAttributes[ QLatin1String( "givenName" ) ], addr.givenName(), mod );
290  tmp += addEntry( mAttributes[ QLatin1String( "familyName" ) ], addr.familyName(), mod );
291  tmp += addEntry( mAttributes[ QLatin1String( "uid" ) ], addr.uid(), mod );
292 
293  PhoneNumber number;
294  number = addr.phoneNumber( PhoneNumber::Home );
295  tmp += addEntry( mAttributes[ QLatin1String( "phoneNumber" ) ], number.number(), mod );
296  number = addr.phoneNumber( PhoneNumber::Work );
297  tmp += addEntry( mAttributes[ QLatin1String( "telephoneNumber" ) ], number.number(), mod );
298  number = addr.phoneNumber( PhoneNumber::Fax );
299  tmp += addEntry( mAttributes[ QLatin1String( "facsimileTelephoneNumber" ) ],
300  number.number(), mod );
301  number = addr.phoneNumber( PhoneNumber::Cell );
302  tmp += addEntry( mAttributes[ QLatin1String( "mobile" ) ], number.number(), mod );
303  number = addr.phoneNumber( PhoneNumber::Pager );
304  tmp += addEntry( mAttributes[ QLatin1String( "pager" ) ], number.number(), mod );
305 
306  tmp += addEntry( mAttributes[ QLatin1String( "description" ) ], addr.note(), mod );
307  tmp += addEntry( mAttributes[ QLatin1String( "title" ) ], addr.title(), mod );
308  tmp += addEntry( mAttributes[ QLatin1String( "organization" ) ], addr.organization(), mod );
309 
310  Address ad = addr.address( Address::Home );
311  if ( !ad.isEmpty() ) {
312  tmp += addEntry( mAttributes[ QLatin1String( "street" ) ], ad.street(), mod );
313  tmp += addEntry( mAttributes[ QLatin1String( "state" ) ], ad.region(), mod );
314  tmp += addEntry( mAttributes[ QLatin1String( "city" ) ], ad.locality(), mod );
315  tmp += addEntry( mAttributes[ QLatin1String( "postalcode" ) ], ad.postalCode(), mod );
316  }
317 
318  QStringList emails = addr.emails();
319  QStringList::ConstIterator mailIt = emails.constBegin();
320 
321  if ( !mAttributes[ QLatin1String( "mail" ) ].isEmpty() ) {
322  if ( mod ) {
323  tmp += KLDAP::Ldif::assembleLine( QLatin1String( "replace" ),
324  mAttributes[ QLatin1String( "mail" ) ] ) + '\n';
325  }
326  if ( mailIt != emails.constEnd() ) {
327  tmp += KLDAP::Ldif::assembleLine( mAttributes[ QLatin1String( "mail" ) ], *mailIt ) + '\n';
328  mailIt ++;
329  }
330  if ( mod &&
331  mAttributes[ QLatin1String( "mail" ) ] != mAttributes[ QLatin1String( "mailAlias" ) ] ) {
332  tmp += "-\n";
333  }
334  }
335 
336  if ( !mAttributes[ QLatin1String( "mailAlias" ) ].isEmpty() ) {
337  if ( mod &&
338  mAttributes[ QLatin1String( "mail" ) ] != mAttributes[ QLatin1String( "mailAlias" ) ] ) {
339  tmp += KLDAP::Ldif::assembleLine( QLatin1String( "replace" ),
340  mAttributes[ QLatin1String( "mailAlias" ) ] ) + '\n';
341  }
342  for ( ; mailIt != emails.constEnd(); ++mailIt ) {
343  tmp += KLDAP::Ldif::assembleLine(
344  mAttributes[ QLatin1String( "mailAlias" ) ], *mailIt ) + '\n';
345  }
346  if ( mod ) {
347  tmp += "-\n";
348  }
349  }
350 
351  if ( !mAttributes[ QLatin1String( "jpegPhoto" ) ].isEmpty() ) {
352  QByteArray pic;
353  QBuffer buffer( &pic );
354  buffer.open( QIODevice::WriteOnly );
355  addr.photo().data().save( &buffer, "JPEG" );
356 
357  if ( mod ) {
358  tmp += KLDAP::Ldif::assembleLine( QLatin1String( "replace" ),
359  mAttributes[ QLatin1String( "jpegPhoto" ) ] ) + '\n';
360  }
361  tmp += KLDAP::Ldif::assembleLine( mAttributes[ QLatin1String( "jpegPhoto" ) ], pic, 76 ) + '\n';
362  if ( mod ) {
363  tmp += "-\n";
364  }
365  }
366 
367  tmp += '\n';
368  kDebug() << "ldif:" << QString::fromUtf8( tmp );
369  ldif = tmp;
370  return true;
371 }
372 
373 void ResourceLDAPKIO::setReadOnly( bool value )
374 {
375  //save the original readonly flag, because offline using disables writing
376  d->mReadOnly = true;
377  Resource::setReadOnly( value );
378 }
379 
380 void ResourceLDAPKIO::init()
381 {
382  if ( d->mPort == 0 ) {
383  d->mPort = 389;
384  }
385 
392  if ( !d->mAttributes.contains( QLatin1String( "objectClass" ) ) ) {
393  d->mAttributes.insert( QLatin1String( "objectClass" ), QLatin1String( "inetOrgPerson" ) );
394  }
395  if ( !d->mAttributes.contains( QLatin1String( "commonName" ) ) ) {
396  d->mAttributes.insert( QLatin1String( "commonName" ), QLatin1String( "cn" ) );
397  }
398  if ( !d->mAttributes.contains( QLatin1String( "formattedName" ) ) ) {
399  d->mAttributes.insert( QLatin1String( "formattedName" ), QLatin1String( "displayName" ) );
400  }
401  if ( !d->mAttributes.contains( QLatin1String( "familyName" ) ) ) {
402  d->mAttributes.insert( QLatin1String( "familyName" ), QLatin1String( "sn" ) );
403  }
404  if ( !d->mAttributes.contains( QLatin1String( "givenName" ) ) ) {
405  d->mAttributes.insert( QLatin1String( "givenName" ), QLatin1String( "givenName" ) );
406  }
407  if ( !d->mAttributes.contains( QLatin1String( "mail" ) ) ) {
408  d->mAttributes.insert( QLatin1String( "mail" ), QLatin1String( "mail" ) );
409  }
410  if ( !d->mAttributes.contains( QLatin1String( "mailAlias" ) ) ) {
411  d->mAttributes.insert( QLatin1String( "mailAlias" ), QString() );
412  }
413  if ( !d->mAttributes.contains( QLatin1String( "phoneNumber" ) ) ) {
414  d->mAttributes.insert( QLatin1String( "phoneNumber" ), QLatin1String( "homePhone" ) );
415  }
416  if ( !d->mAttributes.contains( QLatin1String( "telephoneNumber" ) ) ) {
417  d->mAttributes.insert( QLatin1String( "telephoneNumber" ), QLatin1String( "telephoneNumber" ) );
418  }
419  if ( !d->mAttributes.contains( QLatin1String( "facsimileTelephoneNumber" ) ) ) {
420  d->mAttributes.insert( QLatin1String( "facsimileTelephoneNumber" ),
421  QLatin1String( "facsimileTelephoneNumber" ) );
422  }
423  if ( !d->mAttributes.contains( QLatin1String( "mobile" ) ) ) {
424  d->mAttributes.insert( QLatin1String( "mobile" ), QLatin1String( "mobile" ) );
425  }
426  if ( !d->mAttributes.contains( QLatin1String( "pager" ) ) ) {
427  d->mAttributes.insert( QLatin1String( "pager" ), QLatin1String( "pager" ) );
428  }
429  if ( !d->mAttributes.contains( QLatin1String( "description" ) ) ) {
430  d->mAttributes.insert( QLatin1String( "description" ), QLatin1String( "description" ) );
431  }
432  if ( !d->mAttributes.contains( QLatin1String( "title" ) ) ) {
433  d->mAttributes.insert( QLatin1String( "title" ), QLatin1String( "title" ) );
434  }
435  if ( !d->mAttributes.contains( QLatin1String( "street" ) ) ) {
436  d->mAttributes.insert( QLatin1String( "street" ), QLatin1String( "street" ) );
437  }
438  if ( !d->mAttributes.contains( QLatin1String( "state" ) ) ) {
439  d->mAttributes.insert( QLatin1String( "state" ), QLatin1String( "st" ) );
440  }
441  if ( !d->mAttributes.contains( QLatin1String( "city" ) ) ) {
442  d->mAttributes.insert( QLatin1String( "city" ), QLatin1String( "l" ) );
443  }
444  if ( !d->mAttributes.contains( QLatin1String( "organization" ) ) ) {
445  d->mAttributes.insert( QLatin1String( "organization" ), QLatin1String( "o" ) );
446  }
447  if ( !d->mAttributes.contains( QLatin1String( "postalcode" ) ) ) {
448  d->mAttributes.insert( QLatin1String( "postalcode" ), QLatin1String( "postalCode" ) );
449  }
450  if ( !d->mAttributes.contains( QLatin1String( "uid" ) ) ) {
451  d->mAttributes.insert( QLatin1String( "uid" ), QLatin1String( "uid" ) );
452  }
453  if ( !d->mAttributes.contains( QLatin1String( "jpegPhoto" ) ) ) {
454  d->mAttributes.insert( QLatin1String( "jpegPhoto" ), QLatin1String( "jpegPhoto" ) );
455  }
456 
457  d->mLDAPUrl = KLDAP::LdapUrl( KUrl() );
458  if ( !d->mAnonymous ) {
459  d->mLDAPUrl.setExtension( QLatin1String( "bindname" ), d->mBindDN );
460  d->mLDAPUrl.setUser( d->mUser );
461  d->mLDAPUrl.setPass( d->mPassword );
462  }
463  d->mLDAPUrl.setProtocol( d->mSSL ? QLatin1String( "ldaps" ) : QLatin1String( "ldap" ) );
464  d->mLDAPUrl.setHost( d->mHost );
465  d->mLDAPUrl.setPort( d->mPort );
466  d->mLDAPUrl.setDn( KLDAP::LdapDN( d->mDn ) );
467 
468  if ( !d->mAttributes.empty() ) {
469  QMap<QString,QString>::Iterator it;
470  QStringList attr;
471  for ( it = d->mAttributes.begin(); it != d->mAttributes.end(); ++it ) {
472  if ( !it.value().isEmpty() && it.key() != QLatin1String( "objectClass" ) ) {
473  attr.append( it.value() );
474  }
475  }
476  d->mLDAPUrl.setAttributes( attr );
477  }
478 
479  d->mLDAPUrl.setScope( d->mSubTree ? KLDAP::LdapUrl::Sub : KLDAP::LdapUrl::One );
480  if ( !d->mFilter.isEmpty() && d->mFilter != QLatin1String( "(objectClass=*)" ) ) {
481  d->mLDAPUrl.setFilter( d->mFilter );
482  }
483  d->mLDAPUrl.setExtension( QLatin1String( "x-dir" ), QLatin1String( "base" ) );
484  if ( d->mTLS ) {
485  d->mLDAPUrl.setExtension( QLatin1String( "x-tls" ), QString() );
486  }
487  d->mLDAPUrl.setExtension( QLatin1String( "x-ver" ), QString::number( d->mVer ) );
488  if ( d->mSizeLimit ) {
489  d->mLDAPUrl.setExtension( QLatin1String( "x-sizelimit" ), QString::number( d->mSizeLimit ) );
490  }
491  if ( d->mTimeLimit ) {
492  d->mLDAPUrl.setExtension( QLatin1String( "x-timelimit" ), QString::number( d->mTimeLimit ) );
493  }
494  if ( d->mSASL ) {
495  d->mLDAPUrl.setExtension( QLatin1String( "x-sasl" ), QString() );
496  if ( !d->mMech.isEmpty() ) {
497  d->mLDAPUrl.setExtension( QLatin1String( "x-mech" ), d->mMech );
498  }
499  if ( !d->mRealm.isEmpty() ) {
500  d->mLDAPUrl.setExtension( QLatin1String( "x-realm" ), d->mRealm );
501  }
502  }
503 
504  d->mReadOnly = readOnly();
505 
506  kDebug() << "resource_ldapkio url:" << d->mLDAPUrl.prettyUrl();
507 }
508 
509 void ResourceLDAPKIO::writeConfig( KConfigGroup &group )
510 {
511  Resource::writeConfig( group );
512 
513  group.writeEntry( "LdapUser", d->mUser );
514  group.writeEntry( "LdapPassword", KStringHandler::obscure( d->mPassword ) );
515  group.writeEntry( "LdapDn", d->mDn );
516  group.writeEntry( "LdapHost", d->mHost );
517  group.writeEntry( "LdapPort", d->mPort );
518  group.writeEntry( "LdapFilter", d->mFilter );
519  group.writeEntry( "LdapAnonymous", d->mAnonymous );
520  group.writeEntry( "LdapTLS", d->mTLS );
521  group.writeEntry( "LdapSSL", d->mSSL );
522  group.writeEntry( "LdapSubTree", d->mSubTree );
523  group.writeEntry( "LdapSASL", d->mSASL );
524  group.writeEntry( "LdapMech", d->mMech );
525  group.writeEntry( "LdapVer", d->mVer );
526  group.writeEntry( "LdapTimeLimit", d->mTimeLimit );
527  group.writeEntry( "LdapSizeLimit", d->mSizeLimit );
528  group.writeEntry( "LdapRDNPrefix", d->mRDNPrefix );
529  group.writeEntry( "LdapRealm", d->mRealm );
530  group.writeEntry( "LdapBindDN", d->mBindDN );
531  group.writeEntry( "LdapCachePolicy", d->mCachePolicy );
532  group.writeEntry( "LdapAutoCache", d->mAutoCache );
533 
534  QStringList attributes;
535  QMap<QString, QString>::const_iterator it;
536  for ( it = d->mAttributes.constBegin(); it != d->mAttributes.constEnd(); ++it ) {
537  attributes << it.key() << it.value();
538  }
539 
540  group.writeEntry( "LdapAttributes", attributes );
541 }
542 
543 Ticket *ResourceLDAPKIO::requestSaveTicket()
544 {
545  if ( !addressBook() ) {
546  kDebug() << "no addressbook";
547  return 0;
548  }
549 
550  return createTicket( this );
551 }
552 
553 void ResourceLDAPKIO::releaseSaveTicket( Ticket *ticket )
554 {
555  delete ticket;
556 }
557 
558 bool ResourceLDAPKIO::doOpen()
559 {
560  return true;
561 }
562 
563 void ResourceLDAPKIO::doClose()
564 {
565 }
566 
567 void ResourceLDAPKIO::Private::createCache()
568 {
569  mTmp = 0;
570  if ( mCachePolicy == Cache_NoConnection && mAutoCache ) {
571  mTmp = new KTemporaryFile;
572  mTmp->setPrefix( mCacheDst );
573  mTmp->setSuffix( QLatin1String( "tmp" ) );
574  mTmp->open();
575  }
576 }
577 
578 void ResourceLDAPKIO::Private::activateCache()
579 {
580  if ( mTmp && mError == 0 ) {
581  QString filename = mTmp->fileName();
582  delete mTmp;
583  mTmp = 0;
584  KDE_rename( QFile::encodeName( filename ), QFile::encodeName( mCacheDst ) );
585  }
586 }
587 
588 KIO::TransferJob *ResourceLDAPKIO::Private::loadFromCache()
589 {
590  KIO::TransferJob *job = 0;
591  if ( mCachePolicy == Cache_Always ||
592  ( mCachePolicy == Cache_NoConnection &&
593  mError == KIO::ERR_COULD_NOT_CONNECT ) ) {
594 
595  mAddr = Addressee();
596  mAd = Address( Address::Home );
597  //initialize ldif parser
598  mLdif.startParsing();
599 
600  mParent->Resource::setReadOnly( true );
601 
602  KUrl url( mCacheDst );
603  job = KIO::get( url, KIO::Reload, KIO::HideProgressInfo );
604  mParent->connect( job, SIGNAL(data(KIO::Job*,QByteArray)),
605  mParent, SLOT(data(KIO::Job*,QByteArray)) );
606  }
607 
608  return job;
609 }
610 
611 bool ResourceLDAPKIO::load()
612 {
613  kDebug();
614  KIO::TransferJob *job;
615 
616  clear();
617  //clear the addressee
618  d->mAddr = Addressee();
619  d->mAd = Address( Address::Home );
620  //initialize ldif parser
621  d->mLdif.startParsing();
622 
623  //set to original settings, offline use will disable writing
624  Resource::setReadOnly( d->mReadOnly );
625 
626  d->createCache();
627  if ( d->mCachePolicy != Cache_Always ) {
628  job = KIO::get( d->mLDAPUrl, KIO::Reload, KIO::HideProgressInfo );
629  connect( job, SIGNAL(data(KIO::Job*,QByteArray)),
630  this, SLOT(data(KIO::Job*,QByteArray)) );
631  connect( job, SIGNAL(result(KJob*)),
632  this, SLOT(syncLoadSaveResult(KJob*)) );
633  d->enter_loop();
634  }
635 
636  job = d->loadFromCache();
637  if ( job ) {
638  connect( job, SIGNAL(result(KJob*)),
639  this, SLOT(syncLoadSaveResult(KJob*)) );
640  d->enter_loop();
641  }
642  if ( d->mErrorMsg.isEmpty() ) {
643  kDebug() << "ResourceLDAPKIO load ok!";
644  return true;
645  } else {
646  kDebug() << "ResourceLDAPKIO load finished with error:" << d->mErrorMsg;
647  addressBook()->error( d->mErrorMsg );
648  return false;
649  }
650 }
651 
652 bool ResourceLDAPKIO::asyncLoad()
653 {
654  clear();
655  //clear the addressee
656  d->mAddr = Addressee();
657  d->mAd = Address( Address::Home );
658  //initialize ldif parser
659  d->mLdif.startParsing();
660 
661  Resource::setReadOnly( d->mReadOnly );
662 
663  d->createCache();
664  if ( d->mCachePolicy != Cache_Always ) {
665  KIO::TransferJob *job = KIO::get( d->mLDAPUrl, KIO::Reload, KIO::HideProgressInfo );
666  connect( job, SIGNAL(data(KIO::Job*,QByteArray)),
667  this, SLOT(data(KIO::Job*,QByteArray)) );
668  connect( job, SIGNAL(result(KJob*)),
669  this, SLOT(result(KJob*)) );
670  } else {
671  result( 0 );
672  }
673  return true;
674 }
675 
676 void ResourceLDAPKIO::data( KIO::Job *job, const QByteArray &data )
677 {
678  Q_UNUSED( job );
679  if ( data.size() ) {
680  d->mLdif.setLdif( data );
681  if ( d->mTmp ) {
682  d->mTmp->write( data );
683  }
684  } else {
685  d->mLdif.endLdif();
686  }
687 
688  KLDAP::Ldif::ParseValue ret;
689  QString name;
690  QByteArray value;
691  do {
692  ret = d->mLdif.nextItem();
693  switch ( ret ) {
694  case KLDAP::Ldif::NewEntry:
695  kDebug() << "new entry:" << d->mLdif.dn().toString();
696  break;
697  case KLDAP::Ldif::Item:
698  name = d->mLdif.attr().toLower();
699  value = d->mLdif.value();
700  if ( name == d->mAttributes[ QLatin1String( "commonName" ) ].toLower() ) {
701  if ( !d->mAddr.formattedName().isEmpty() ) {
702  QString fn = d->mAddr.formattedName();
703  d->mAddr.setNameFromString( QString::fromUtf8( value, value.size() ) );
704  d->mAddr.setFormattedName( fn );
705  } else {
706  d->mAddr.setNameFromString( QString::fromUtf8( value, value.size() ) );
707  }
708  } else if ( name == d->mAttributes[ QLatin1String( "formattedName" ) ].toLower() ) {
709  d->mAddr.setFormattedName( QString::fromUtf8( value, value.size() ) );
710  } else if ( name == d->mAttributes[ QLatin1String( "givenName" ) ].toLower() ) {
711  d->mAddr.setGivenName( QString::fromUtf8( value, value.size() ) );
712  } else if ( name == d->mAttributes[ QLatin1String( "mail" ) ].toLower() ) {
713  d->mAddr.insertEmail( QString::fromUtf8( value, value.size() ), true );
714  } else if ( name == d->mAttributes[ QLatin1String( "mailAlias" ) ].toLower() ) {
715  d->mAddr.insertEmail( QString::fromUtf8( value, value.size() ), false );
716  } else if ( name == d->mAttributes[ QLatin1String( "phoneNumber" ) ].toLower() ) {
717  PhoneNumber phone;
718  phone.setNumber( QString::fromUtf8( value, value.size() ) );
719  d->mAddr.insertPhoneNumber( phone );
720  } else if ( name == d->mAttributes[ QLatin1String( "telephoneNumber" ) ].toLower() ) {
721  PhoneNumber phone( QString::fromUtf8( value, value.size() ),
722  PhoneNumber::Work );
723  d->mAddr.insertPhoneNumber( phone );
724  } else if ( name ==
725  d->mAttributes[ QLatin1String( "facsimileTelephoneNumber" ) ].toLower() ) {
726  PhoneNumber phone( QString::fromUtf8( value, value.size() ),
727  PhoneNumber::Fax );
728  d->mAddr.insertPhoneNumber( phone );
729  } else if ( name == d->mAttributes[ QLatin1String( "mobile" ) ].toLower() ) {
730  PhoneNumber phone( QString::fromUtf8( value, value.size() ),
731  PhoneNumber::Cell );
732  d->mAddr.insertPhoneNumber( phone );
733  } else if ( name == d->mAttributes[ QLatin1String( "pager" ) ].toLower() ) {
734  PhoneNumber phone( QString::fromUtf8( value, value.size() ),
735  PhoneNumber::Pager );
736  d->mAddr.insertPhoneNumber( phone );
737  } else if ( name == d->mAttributes[ QLatin1String( "description" ) ].toLower() ) {
738  d->mAddr.setNote( QString::fromUtf8( value, value.size() ) );
739  } else if ( name == d->mAttributes[ QLatin1String( "title" ) ].toLower() ) {
740  d->mAddr.setTitle( QString::fromUtf8( value, value.size() ) );
741  } else if ( name == d->mAttributes[ QLatin1String( "street" ) ].toLower() ) {
742  d->mAd.setStreet( QString::fromUtf8( value, value.size() ) );
743  } else if ( name == d->mAttributes[ QLatin1String( "state" ) ].toLower() ) {
744  d->mAd.setRegion( QString::fromUtf8( value, value.size() ) );
745  } else if ( name == d->mAttributes[ QLatin1String( "city" ) ].toLower() ) {
746  d->mAd.setLocality( QString::fromUtf8( value, value.size() ) );
747  } else if ( name == d->mAttributes[ QLatin1String( "postalcode" ) ].toLower() ) {
748  d->mAd.setPostalCode( QString::fromUtf8( value, value.size() ) );
749  } else if ( name == d->mAttributes[ QLatin1String( "organization" ) ].toLower() ) {
750  d->mAddr.setOrganization( QString::fromUtf8( value, value.size() ) );
751  } else if ( name == d->mAttributes[ QLatin1String( "familyName" ) ].toLower() ) {
752  d->mAddr.setFamilyName( QString::fromUtf8( value, value.size() ) );
753  } else if ( name == d->mAttributes[ QLatin1String( "uid" ) ].toLower() ) {
754  d->mAddr.setUid( QString::fromUtf8( value, value.size() ) );
755  } else if ( name == d->mAttributes[ QLatin1String( "jpegPhoto" ) ].toLower() ) {
756  KABC::Picture photo;
757  QImage img = QImage::fromData( value );
758  if ( !img.isNull() ) {
759  photo.setData( img );
760  photo.setType( QLatin1String( "image/jpeg" ) );
761  d->mAddr.setPhoto( photo );
762  }
763  }
764 
765  break;
766  case KLDAP::Ldif::EndEntry:
767  {
768  d->mAddr.setResource( this );
769  d->mAddr.insertAddress( d->mAd );
770  d->mAddr.setChanged( false );
771  insertAddressee( d->mAddr );
772  //clear the addressee
773  d->mAddr = Addressee();
774  d->mAd = Address( Address::Home );
775  }
776  break;
777  default:
778  break;
779  }
780  } while ( ret != KLDAP::Ldif::MoreData );
781 }
782 
783 void ResourceLDAPKIO::loadCacheResult( KJob *job )
784 {
785  d->mErrorMsg.clear();
786  d->mError = job->error();
787  if ( d->mError && d->mError != KIO::ERR_USER_CANCELED ) {
788  d->mErrorMsg = job->errorString();
789  }
790  if ( !d->mErrorMsg.isEmpty() ) {
791  emit loadingError( this, d->mErrorMsg );
792  } else {
793  emit loadingFinished( this );
794  }
795 }
796 
797 void ResourceLDAPKIO::result( KJob *job )
798 {
799  d->mErrorMsg.clear();
800  if ( job ) {
801  d->mError = job->error();
802  if ( d->mError && d->mError != KIO::ERR_USER_CANCELED ) {
803  d->mErrorMsg = job->errorString();
804  }
805  } else {
806  d->mError = 0;
807  }
808  d->activateCache();
809 
810  KIO::TransferJob *cjob;
811  cjob = d->loadFromCache();
812  if ( cjob ) {
813  connect( cjob, SIGNAL(result(KJob*)),
814  this, SLOT(loadCacheResult(KJob*)) );
815  } else {
816  if ( !d->mErrorMsg.isEmpty() ) {
817  emit loadingError( this, d->mErrorMsg );
818  } else {
819  emit loadingFinished( this );
820  }
821  }
822 }
823 
824 bool ResourceLDAPKIO::save( Ticket *ticket )
825 {
826  Q_UNUSED( ticket );
827  kDebug();
828 
829  d->mSaveIt = begin();
830  KIO::TransferJob *job = KIO::put( d->mLDAPUrl, -1, KIO::Overwrite | KIO::HideProgressInfo );
831  connect( job, SIGNAL(dataReq(KIO::Job*,QByteArray&)),
832  this, SLOT(saveData(KIO::Job*,QByteArray&)) );
833  connect( job, SIGNAL(result(KJob*)),
834  this, SLOT(syncLoadSaveResult(KJob*)) );
835  d->enter_loop();
836  if ( d->mErrorMsg.isEmpty() ) {
837  kDebug() << "ResourceLDAPKIO save ok!";
838  return true;
839  } else {
840  kDebug() << "ResourceLDAPKIO finished with error:" << d->mErrorMsg;
841  addressBook()->error( d->mErrorMsg );
842  return false;
843  }
844 }
845 
846 bool ResourceLDAPKIO::asyncSave( Ticket *ticket )
847 {
848  Q_UNUSED( ticket );
849  kDebug();
850  d->mSaveIt = begin();
851  KIO::TransferJob *job = KIO::put( d->mLDAPUrl, -1, KIO::Overwrite | KIO::HideProgressInfo );
852  connect( job, SIGNAL(dataReq(KIO::Job*,QByteArray&)),
853  this, SLOT(saveData(KIO::Job*,QByteArray&)) );
854  connect( job, SIGNAL(result(KJob*)),
855  this, SLOT(saveResult(KJob*)) );
856  return true;
857 }
858 
859 void ResourceLDAPKIO::syncLoadSaveResult( KJob *job )
860 {
861  d->mError = job->error();
862  if ( d->mError && d->mError != KIO::ERR_USER_CANCELED ) {
863  d->mErrorMsg = job->errorString();
864  } else {
865  d->mErrorMsg.clear();
866  }
867  d->activateCache();
868 
869  emit leaveModality();
870 }
871 
872 void ResourceLDAPKIO::saveResult( KJob *job )
873 {
874  d->mError = job->error();
875  if ( d->mError && d->mError != KIO::ERR_USER_CANCELED ) {
876  emit savingError( this, job->errorString() );
877  } else {
878  emit savingFinished( this );
879  }
880 }
881 
882 void ResourceLDAPKIO::saveData( KIO::Job *job, QByteArray &data )
883 {
884  Q_UNUSED( job );
885  while ( d->mSaveIt != end() && !(*d->mSaveIt).changed() ) {
886  d->mSaveIt++;
887  }
888 
889  if ( d->mSaveIt == end() ) {
890  kDebug() << "ResourceLDAPKIO endData";
891  data.resize( 0 );
892  return;
893  }
894 
895  kDebug() << "ResourceLDAPKIO saveData:" << (*d->mSaveIt).assembledName();
896 
897  d->AddresseeToLDIF( data, *d->mSaveIt, d->findUid( (*d->mSaveIt).uid() ) );
898 // kDebug() << "ResourceLDAPKIO save LDIF:" << QString::fromUtf8(data);
899  // mark as unchanged
900  (*d->mSaveIt).setChanged( false );
901 
902  d->mSaveIt++;
903 }
904 
905 void ResourceLDAPKIO::removeAddressee( const Addressee &addr )
906 {
907  QString dn = d->findUid( addr.uid() );
908 
909  kDebug() << dn;
910 
911  if ( !d->mErrorMsg.isEmpty() ) {
912  addressBook()->error( d->mErrorMsg );
913  return;
914  }
915  if ( !dn.isEmpty() ) {
916  kDebug() << "ResourceLDAPKIO: found uid:" << dn;
917  KLDAP::LdapUrl url( d->mLDAPUrl );
918  url.setPath( QLatin1Char( '/' ) + dn );
919  url.setExtension( QLatin1String( "x-dir" ), QLatin1String( "base" ) );
920  url.setScope( KLDAP::LdapUrl::Base );
921  if ( KIO::NetAccess::del( url, 0 ) ) {
922  mAddrMap.remove( addr.uid() );
923  }
924  } else {
925  //maybe it's not saved yet
926  mAddrMap.remove( addr.uid() );
927  }
928 }
929 
930 void ResourceLDAPKIO::setUser( const QString &user )
931 {
932  d->mUser = user;
933 }
934 
935 QString ResourceLDAPKIO::user() const
936 {
937  return d->mUser;
938 }
939 
940 void ResourceLDAPKIO::setPassword( const QString &password )
941 {
942  d->mPassword = password;
943 }
944 
945 QString ResourceLDAPKIO::password() const
946 {
947  return d->mPassword;
948 }
949 
950 void ResourceLDAPKIO::setDn( const QString &dn )
951 {
952  d->mDn = dn;
953 }
954 
955 QString ResourceLDAPKIO::dn() const
956 {
957  return d->mDn;
958 }
959 
960 void ResourceLDAPKIO::setHost( const QString &host )
961 {
962  d->mHost = host;
963 }
964 
965 QString ResourceLDAPKIO::host() const
966 {
967  return d->mHost;
968 }
969 
970 void ResourceLDAPKIO::setPort( int port )
971 {
972  d->mPort = port;
973 }
974 
975 int ResourceLDAPKIO::port() const
976 {
977  return d->mPort;
978 }
979 
980 void ResourceLDAPKIO::setVer( int ver )
981 {
982  d->mVer = ver;
983 }
984 
985 int ResourceLDAPKIO::ver() const
986 {
987  return d->mVer;
988 }
989 
990 void ResourceLDAPKIO::setSizeLimit( int sizelimit )
991 {
992  d->mSizeLimit = sizelimit;
993 }
994 
995 int ResourceLDAPKIO::sizeLimit()
996 {
997  return d->mSizeLimit;
998 }
999 
1000 void ResourceLDAPKIO::setTimeLimit( int timelimit )
1001 {
1002  d->mTimeLimit = timelimit;
1003 }
1004 
1005 int ResourceLDAPKIO::timeLimit()
1006 {
1007  return d->mTimeLimit;
1008 }
1009 
1010 void ResourceLDAPKIO::setFilter( const QString &filter )
1011 {
1012  d->mFilter = filter;
1013 }
1014 
1015 QString ResourceLDAPKIO::filter() const
1016 {
1017  return d->mFilter;
1018 }
1019 
1020 void ResourceLDAPKIO::setIsAnonymous( bool value )
1021 {
1022  d->mAnonymous = value;
1023 }
1024 
1025 bool ResourceLDAPKIO::isAnonymous() const
1026 {
1027  return d->mAnonymous;
1028 }
1029 
1030 void ResourceLDAPKIO::setIsTLS( bool value )
1031 {
1032  d->mTLS = value;
1033 }
1034 
1035 bool ResourceLDAPKIO::isTLS() const
1036 {
1037  return d->mTLS;
1038 }
1039 void ResourceLDAPKIO::setIsSSL( bool value )
1040 {
1041  d->mSSL = value;
1042 }
1043 
1044 bool ResourceLDAPKIO::isSSL() const
1045 {
1046  return d->mSSL;
1047 }
1048 
1049 void ResourceLDAPKIO::setIsSubTree( bool value )
1050 {
1051  d->mSubTree = value;
1052 }
1053 
1054 bool ResourceLDAPKIO::isSubTree() const
1055 {
1056  return d->mSubTree;
1057 }
1058 
1059 void ResourceLDAPKIO::setAttributes( const QMap<QString, QString> &attributes )
1060 {
1061  d->mAttributes = attributes;
1062 }
1063 
1064 QMap<QString, QString> ResourceLDAPKIO::attributes() const
1065 {
1066  return d->mAttributes;
1067 }
1068 
1069 void ResourceLDAPKIO::setRDNPrefix( int value )
1070 {
1071  d->mRDNPrefix = value;
1072 }
1073 
1074 int ResourceLDAPKIO::RDNPrefix() const
1075 {
1076  return d->mRDNPrefix;
1077 }
1078 
1079 void ResourceLDAPKIO::setIsSASL( bool value )
1080 {
1081  d->mSASL = value;
1082 }
1083 
1084 bool ResourceLDAPKIO::isSASL() const
1085 {
1086  return d->mSASL;
1087 }
1088 
1089 void ResourceLDAPKIO::setMech( const QString &mech )
1090 {
1091  d->mMech = mech;
1092 }
1093 
1094 QString ResourceLDAPKIO::mech() const
1095 {
1096  return d->mMech;
1097 }
1098 
1099 void ResourceLDAPKIO::setRealm( const QString &realm )
1100 {
1101  d->mRealm = realm;
1102 }
1103 
1104 QString ResourceLDAPKIO::realm() const
1105 {
1106  return d->mRealm;
1107 }
1108 
1109 void ResourceLDAPKIO::setBindDN( const QString &binddn )
1110 {
1111  d->mBindDN = binddn;
1112 }
1113 
1114 QString ResourceLDAPKIO::bindDN() const
1115 {
1116  return d->mBindDN;
1117 }
1118 
1119 void ResourceLDAPKIO::setCachePolicy( int pol )
1120 {
1121  d->mCachePolicy = pol;
1122 }
1123 
1124 int ResourceLDAPKIO::cachePolicy() const
1125 {
1126  return d->mCachePolicy;
1127 }
1128 
1129 void ResourceLDAPKIO::setAutoCache( bool value )
1130 {
1131  d->mAutoCache = value;
1132 }
1133 
1134 bool ResourceLDAPKIO::autoCache()
1135 {
1136  return d->mAutoCache;
1137 }
1138 
1139 QString ResourceLDAPKIO::cacheDst() const
1140 {
1141  return d->mCacheDst;
1142 }
1143 
1144 #include "resourceldapkio.moc"
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Tue Dec 11 2012 12:16:19 by doxygen 1.8.1.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kabc

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

kdepimlibs-4.9.4 API Reference

Skip menu "kdepimlibs-4.9.4 API Reference"
  • akonadi
  •   contact
  •   kmime
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal