[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-pim
Subject:    [Kde-pim] Ldap access
From:       Marc TAIEB <TAIEBMA () e-i ! com>
Date:       2003-03-10 9:19:04
[Download RAW message or body]

Hello,

I have made some adaptation in LDAP access, because I couldn't use it in my company.
In kabc, the LDAP servers access are made with URL. But we have to  make an \
authentication before. So I use openldap instead with identification capabilities.
In kaddressbook, the filter of the query was *%2*. I suppressed the first * because \
when you put un * before, the ldap server don't use the index. And when you have 60 \
000 persons in your ldap addressbook you never receive your response. In kmail, the \
Ctrl + left arrow keys are used for auto-completion. I've added a supplementary \
access to ldap addressbook. Only in this case because  the ldap addressbook may be to \
big.

What do you think about my modifs ? They interesting you ?

Regards


Marc TAIEB
Euro Information 
Email : taiebma@e-i.com
Tel : 03 88 14 86 93


["mydiff.kmail" (text/x-diff)]

? thediff
Index: kmcomposewin.cpp
===================================================================
RCS file: /home/kde/kdenetwork/kmail/Attic/kmcomposewin.cpp,v
retrieving revision 1.627.2.4
diff -u -3 -p -u -r1.627.2.4 kmcomposewin.cpp
--- kmcomposewin.cpp	14 Dec 2002 19:49:22 -0000	1.627.2.4
+++ kmcomposewin.cpp	10 Mar 2003 08:46:00 -0000
@@ -84,7 +84,7 @@
 
 #include "kmcomposewin.moc"
 
-
+#include <kabc/ldapclient.h>
 
 //-----------------------------------------------------------------------------
 KMComposeWin::KMComposeWin( KMMessage *aMsg, uint id )
@@ -5219,7 +5219,8 @@ KMLineEdit::KMLineEdit(KMComposeWin* com
   mComposer = composer;
   m_useCompletion = useCompletion;
   m_smartPaste = false;
-
+  m_ldap = NULL;
+  
   if ( !s_completion ) {
       s_completion = new KCompletion();
       s_completion->setOrder( KCompletion::Sorted );
@@ -5292,6 +5293,7 @@ bool KMLineEdit::eventFilter(QObject *o,
       if ((int)text().length() == cursorPosition()) // at End?
       {
         doCompletion(true);
+	doLdapCompletion(true);
         return TRUE;
       }
       return FALSE;
@@ -5400,7 +5402,7 @@ void KMLineEdit::doCompletion(bool ctrlT
           match = s_completion->makeCompletion( "\"" + s );
     }
 
-    // kdDebug(5006) << "** completion for: " << s << " : " << match << endl;
+    kdDebug(5006) << "** completion for: " << s << " : " << match << endl;
 
     if ( ctrlT )
     {
@@ -5474,6 +5476,102 @@ void KMLineEdit::doCompletion(bool ctrlT
         case KGlobalSettings::CompletionNone:
             break;
     }
+}
+
+//-----------------------------------------------------------------------------
+void KMLineEdit::doLdapCompletion(bool ctrlT)
+{
+    if ( !m_useCompletion )
+        return;
+
+    QString s(text());
+    QString prevAddr;
+    int n = s.findRev(',');
+    if (n>= 0)
+    {
+        prevAddr = s.left(n+1) + ' ';
+        s = s.mid(n+1,255).stripWhiteSpace();
+    }
+
+    KCompletionBox *box = completionBox();
+
+    if ( s.isEmpty() )
+    {
+        box->hide();
+        return;
+    }
+
+    KGlobalSettings::Completion  mode = completionMode();
+   
+    QString match;
+    if ( mode != KGlobalSettings::CompletionNone )
+    {
+    	if (m_ldap)
+		delete m_ldap;
+	m_ldap = new KABC::LdapSearch();
+   	connect( m_ldap, SIGNAL( searchData( const QStringList & ) ),
+               this, SLOT( slotLdapCompletion( const QStringList & ) ) ); 
+    	m_ldap->startSearch(s);
+    }
+
+}
+
+//-----------------------------------------------------------------------------
+void KMLineEdit::slotLdapCompletion(const QStringList &lst)
+{
+/*
+    if ( !m_useCompletion )
+        return;
+*/
+    kdDebug(5006) << "Traitement résultat" << endl;
+ 
+    s_completion->clear();
+    
+    QString s(text());
+    QString prevAddr;
+    int n = s.findRev(',');
+    if (n>= 0)
+    {
+        prevAddr = s.left(n+1) + ' ';
+        s = s.mid(n+1,255).stripWhiteSpace();
+    }
+
+    KCompletionBox *box = completionBox();
+
+    if (lst.count() > 1) 
+    {
+	m_previousAddresses = prevAddr;
+	box->setItems( lst );
+	box->setCancelledText( text() );
+	box->popup();
+    }
+    else 
+    	if (lst.count() == 1) 
+    	{
+		setText(prevAddr + lst.first());
+		setEdited( true );
+    	}
+    else
+	box->hide();
+/*
+    if (s_completion->count() > 1) 
+    {
+	m_previousAddresses = prevAddr;
+	box->setItems( s_completion );
+	box->setCancelledText( text() );
+	box->popup();
+    }
+    else 
+    	if (s_completion->count() == 1) 
+    	{
+		setText(prevAddr + s_completion->first());
+		setEdited( true );
+    	}
+    else
+	box->hide();
+*/
+    cursorAtEnd();
+	
 }
 
 //-----------------------------------------------------------------------------
Index: kmcomposewin.h
===================================================================
RCS file: /home/kde/kdenetwork/kmail/Attic/kmcomposewin.h,v
retrieving revision 1.178.2.1
diff -u -3 -p -u -r1.178.2.1 kmcomposewin.h
--- kmcomposewin.h	6 Dec 2002 21:30:13 -0000	1.178.2.1
+++ kmcomposewin.h	10 Mar 2003 08:46:00 -0000
@@ -29,6 +29,8 @@
 
 #include "cryptplugwrapper.h"
 
+#include <kabc/ldapclient.h>
+
 class _StringPair {
  public:
    QString name;
@@ -145,12 +147,14 @@ protected:
   virtual void insert(const QString &t);
   virtual void mouseReleaseEvent( QMouseEvent * e );
   void doCompletion(bool ctrlT);
+  void doLdapCompletion(bool ctrlT);
   KMComposeWin* mComposer;
 
 private slots:
   void slotCompletion() { doCompletion(false); }
   void slotPopupCompletion( const QString& );
-
+  void slotLdapCompletion(const QStringList &lst);
+  
 private:
   void loadAddresses();
   /**
@@ -168,7 +172,8 @@ private:
   QString m_previousAddresses;
   bool m_useCompletion;
   bool m_smartPaste;
-
+  KABC::LdapSearch *m_ldap;
+  
   static bool s_addressesDirty;
   static KCompletion *s_completion;
 

["mydiff.kaddressbook" (text/x-diff)]

? thediff
Index: ldapsearchdialogimpl.cpp
===================================================================
RCS file: /home/kde/kdepim/kaddressbook/Attic/ldapsearchdialogimpl.cpp,v
retrieving revision 1.19
diff -u -3 -p -u -r1.19 ldapsearchdialogimpl.cpp
--- ldapsearchdialogimpl.cpp	25 Sep 2002 11:44:54 -0000	1.19
+++ ldapsearchdialogimpl.cpp	10 Mar 2003 08:54:14 -0000
@@ -229,9 +229,9 @@ QString LDAPSearchDialogImpl::makeFilter
   QString result;
 
   if ( query.isEmpty() )
-    result = "%1=*%2";
+    result = "%1=%2";
   else
-    result = "%1=*%2*";
+    result = "%1=%2*";
 
   if ( attr == i18n( "Name" ) ) {
     result = result.arg( "cn" ).arg( query );

["mydiff.kabc" (text/x-diff)]

? ldapclient.cpp.cvs
? ldapclient.h.cvs
? thediff
Index: ldapclient.cpp
===================================================================
RCS file: /home/kde/kdelibs/kabc/ldapclient.cpp,v
retrieving revision 1.4.2.1
diff -u -3 -p -u -r1.4.2.1 ldapclient.cpp
--- ldapclient.cpp	28 Nov 2002 11:02:37 -0000	1.4.2.1
+++ ldapclient.cpp	10 Mar 2003 08:38:42 -0000
@@ -36,6 +36,8 @@
 
 using namespace KABC;
 
+#define NB_MAX_ATTRIBS		20
+
 QString LdapObject::toString() const
 {
   QString result = QString::fromLatin1( "\ndn: %1\n" ).arg( dn );
@@ -83,6 +85,10 @@ void LdapObject::assign( const LdapObjec
 LdapClient::LdapClient( QObject* parent, const char* name )
   : QObject( parent, name ), mJob( 0 ), mActive( false )
 {
+	mBindDN = "anonymous";
+	mPwdBindDN = "";
+	mIdLdap = 0;
+	mIdSearch = 0;
 }
 
 LdapClient::~LdapClient()
@@ -105,6 +111,16 @@ void LdapClient::setBase( const QString&
   mBase = base;
 }
 
+void LdapClient::setBindDN( const QString& binddn )
+{
+  mBindDN = binddn;
+}
+
+void LdapClient::setPwdBindDN( const QString& pwdbinddn )
+{
+  mPwdBindDN = pwdbinddn;
+}
+
 void LdapClient::setAttrs( const QStringList& attrs )
 {
   mAttrs = attrs;
@@ -112,11 +128,15 @@ void LdapClient::setAttrs( const QString
 
 void LdapClient::startQuery( const QString& filter )
 {
+  int scope = LDAP_SCOPE_SUBTREE ;
+  char *attribs[NB_MAX_ATTRIBS];
+  
   cancelQuery();
   QString query;
   if ( mScope.isEmpty() )
     mScope = "sub";
 
+/*
   QString host = mHost;
   if ( !mPort.isEmpty() ) {
     host += ':';
@@ -140,6 +160,133 @@ void LdapClient::startQuery( const QStri
            this, SLOT( slotInfoMessage( KIO::Job*, const QString& ) ) );
   connect( mJob, SIGNAL( result( KIO::Job* ) ),
            this, SLOT( slotDone() ) );
+*/
+  if ( mPort.isEmpty() ) {
+	  mPort = "389";
+  }
+
+  mIdLdap = ldap_open(mHost.latin1(), mPort.toInt());
+  if (!mIdLdap) 
+  {
+	  kdDebug(5700) << "Can't contact server : (" << mHost.latin1() << ":" << \
mPort.toInt() << ")" <<endl; +  	  emit error( QString("Can't contact server \
%1:%2").arg( mHost ).arg( mPort ) ); +	  return;
+  }
+
+  if (ldap_simple_bind(mIdLdap, mBindDN.latin1(), mPwdBindDN.latin1()) < 0)
+  {
+	  kdDebug(5700) << "Authentification failed : (" << mBindDN.latin1() << "/" << \
mPwdBindDN.latin1() << ")" <<endl; +  	  emit error( QString("Authentification failed \
: (%1/%2)").arg( mBindDN ).arg( mPwdBindDN ) ); +	  return;
+  }
+
+  if (mAttrs.count() >= NB_MAX_ATTRIBS)
+  {
+	  kdDebug(5700) << "Too many arguments" << endl;
+  	  slotDone();
+	  return;
+  }
+
+  if (mScope == "sub")
+	  scope = LDAP_SCOPE_SUBTREE;
+  if (mScope == "one")
+	  scope = LDAP_SCOPE_ONELEVEL;
+  if (mScope == "base")
+	  scope = LDAP_SCOPE_BASE;
+
+  //  Begin search
+  mActive = true;
+  if ( mAttrs.empty() )
+  {
+	char  *defaultattr[] = {"*", NULL};
+	
+  	mIdSearch = ldap_search(
+		mIdLdap, 
+		mBase.latin1(), 
+		scope,
+		filter.ascii(), 
+		defaultattr,
+		0);
+  }
+  else
+  {
+	unsigned int	i;
+
+	memset(attribs, 0, sizeof(attribs));
+	for (i = 0; i < mAttrs.count(); i++)
+  	{
+	  	attribs[i] = (char*)malloc(mAttrs[i].length() + 1);
+	  	strcpy(attribs[i], mAttrs[i].latin1());
+  	}
+  
+  	mIdSearch = ldap_search(
+		mIdLdap, 
+		mBase.latin1(), 
+		scope,
+		filter.ascii(), 
+		attribs,
+		0);
+
+	for (i = 0; i < mAttrs.count(); i++)
+		free(attribs[i]);
+  }
+  
+  LDAPMessage	*ldapresult = NULL;
+  struct timeval	tv;
+  int res;
+  
+  //  Waiting for results
+  tv.tv_sec = 2;
+  tv.tv_usec = 0;
+  res = ldap_result(mIdLdap, mIdSearch, 0, &tv, &ldapresult);
+  while (res > 0 && mActive)
+  {
+	LDAPMessage *entry = NULL;
+	BerElement *ber = NULL;
+	char *attr;
+	char **values;
+	
+	//  for each attributes
+	for (entry = ldap_first_entry(mIdLdap, ldapresult); entry != NULL; entry = \
ldap_next_entry(mIdLdap, entry)) +	{
+		for (attr = ldap_first_attribute(mIdLdap, entry, &ber); attr != NULL;
+				attr = ldap_next_attribute(mIdLdap, entry, ber))
+		{
+			values = ldap_get_values(mIdLdap, entry, attr);
+
+			kdDebug(5700) << "Ajout de " << attr << " = " << values[0] << endl;
+			mCurrentObject.attrs[ attr ].append( QCString(values[0]) );
+
+			ldap_value_free(values);
+			free(attr);
+			mCurrentObject.dn = ldap_get_dn(mIdLdap, entry);
+		}
+		
+		kdDebug(5700) << "Next entry " << endl;
+	}
+
+        if ( !mCurrentObject.dn.isNull() ) 
+	{
+		  kdDebug(5700) << "Utilisateur " <<  mCurrentObject.dn.latin1() << endl;
+	          emit result( mCurrentObject );
+	          mCurrentObject.clear();
+	}
+
+	tv.tv_sec = 0;
+	tv.tv_usec = 0;
+	ldap_msgfree(ldapresult);
+	ldapresult = NULL;
+  	res = ldap_result(mIdLdap, mIdSearch, 0, &tv, &ldapresult);
+  }
+
+  kdDebug(5700) << "Recherche terminée "  << endl;
+
+  if (mIdLdap)
+	ldap_unbind(mIdLdap);
+
+  mActive = false;
+
+  emit done();
 }
 
 void LdapClient::cancelQuery()
@@ -186,6 +333,7 @@ void LdapClient::startParseLDIF()
   mLastAttrName  = 0;
   mLastAttrValue = 0;
   mIsBase64 = false;
+  
 }
 
 void LdapClient::endParseLDIF()
@@ -201,6 +349,8 @@ void LdapClient::endParseLDIF()
         mCurrentObject.attrs[ mLastAttrName ].append( mLastAttrValue );
       }
     }
+    if (mIdLdap)
+	    ldap_unbind(mIdLdap);
     emit result( mCurrentObject );
   }
 }
@@ -341,7 +491,7 @@ void LdapSearch::startSearch( const QStr
   } else
     mSearchText = txt;
 
-  QString filter = QString( "|(cn=%1*)(mail=%2*)(givenName=%3*)(sn=%4*)" )
+  QString filter = QString( "(|(cn=%1*)(mail=%2*)(givenName=%3*)(sn=%4*))" )
       .arg( mSearchText ).arg( mSearchText ).arg( mSearchText ).arg( mSearchText );
 
   QValueList< LdapClient* >::Iterator it;
@@ -423,10 +573,12 @@ QStringList LdapSearch::makeSearchData()
         kdDebug() << "<" << name << "><" << mail << ">" << endl;
       ret.append( QString( "%1 <%2>" ).arg( name ).arg( mail ) );
       // this sucks
+/*
       if ( givenname.upper().startsWith( search_text_upper ) )
         ret.append( QString( "$$%1$%2 <%3>" ).arg( givenname ).arg( name ).arg( mail \
) );  if ( sn.upper().startsWith( search_text_upper ) )
         ret.append( QString( "$$%1$%2 <%3>" ).arg( sn ).arg( name ).arg( mail ) );
+*/
     }
   }
 
Index: ldapclient.h
===================================================================
RCS file: /home/kde/kdelibs/kabc/ldapclient.h,v
retrieving revision 1.5
diff -u -3 -p -u -r1.5 ldapclient.h
--- ldapclient.h	24 Sep 2002 18:54:03 -0000	1.5
+++ ldapclient.h	10 Mar 2003 08:38:42 -0000
@@ -33,6 +33,9 @@
 
 #include <kio/job.h>
 
+#include <ldap.h>
+#include <pthread.h>
+
 namespace KABC {
 
 typedef QValueList<QByteArray> LdapAttrValue;
@@ -123,6 +126,18 @@ class LdapClient : public QObject
     void setBase( const QString& base );
     QString base() const { return mBase; }
 
+    /*!
+     * Set the bind DN 
+     */
+    void setBindDN( const QString& binddn );
+    QString binddn() const { return mBindDN; }
+
+    /*!
+     * Set the pwd bind DN 
+     */
+    void setPwdBindDN( const QString& pwdbinddn );
+    QString pwdbinddn() const { return mPwdBindDN; }
+
     /*! Set the attributes that should be
      * returned, or an empty list if
      * all attributes are wanted
@@ -151,15 +166,21 @@ class LdapClient : public QObject
     void startParseLDIF();
     void parseLDIF( const QByteArray& data );
     void endParseLDIF();
+    void parseLdapResult(void *arg);
 
     QString mHost;
     QString mPort;
     QString mBase;
     QString mScope;
+    QString mBindDN;
+    QString mPwdBindDN;
     QStringList mAttrs;
   
     QGuardedPtr<KIO::SimpleJob> mJob;
     bool mActive;
+    LDAP *mIdLdap;
+    int mIdSearch;
+    pthread_t mHthread;
   
     LdapObject mCurrentObject;
     QCString mBuf;


_______________________________________________
kde-pim mailing list
kde-pim@mail.kde.org
http://mail.kde.org/mailman/listinfo/kde-pim
kde-pim home page at http://pim.kde.org/

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic