33 #include <kldap/ldapobject.h>
34 #include <kldap/ldapserver.h>
35 #include <kldap/ldapurl.h>
36 #include <kldap/ldif.h>
39 #include <KConfigGroup>
42 #include <KProtocolInfo>
43 #include <KStandardDirs>
46 #include <QtCore/QPointer>
47 #include <QtCore/QTimer>
50 using namespace KLDAP;
52 class LdapClientSearch::Private
58 mNoLDAPLookup( false )
60 mClientSearchConfig =
new LdapClientSearchConfig;
65 delete mClientSearchConfig;
70 KLDAP::LdapObject object;
73 void readWeighForClient(
LdapClient *client,
const KConfigGroup &config,
int clientNumber );
79 void slotLDAPError(
const QString& );
82 void slotFileChanged(
const QString& );
92 LdapClientSearchConfig *mClientSearchConfig;
96 :
QObject( parent ), d( new Private( this ) )
100 if ( !KProtocolInfo::isKnownProtocol( KUrl(
"ldap://localhost" ) ) ) {
101 d->mNoLDAPLookup =
true;
107 connect( KDirWatch::self(), SIGNAL(dirty(QString)),
this,
108 SLOT(slotFileChanged(QString)) );
116 void LdapClientSearch::Private::readWeighForClient(
LdapClient *client,
const KConfigGroup &config,
119 const int completionWeight = config.readEntry( QString::fromLatin1(
"SelectedCompletionWeight%1" ).arg( clientNumber ), -1 );
120 if ( completionWeight != -1 ) {
127 KConfigGroup config( KLDAP::LdapClientSearchConfig::config(),
"LDAP" );
128 for (
int i = 0; i < d->mClients.size(); ++i ) {
129 d->readWeighForClient( d->mClients[ i ], config, i );
138 void LdapClientSearch::Private::readConfig()
141 qDeleteAll( mClients );
145 KConfigGroup config( KLDAP::LdapClientSearchConfig::config(),
"LDAP" );
146 const int numHosts = config.readEntry(
"NumSelectedHosts", 0 );
148 mNoLDAPLookup =
true;
150 for (
int j = 0; j < numHosts; ++j ) {
152 KLDAP::LdapServer server;
153 mClientSearchConfig->readConfig( server, config, j,
true );
154 if ( !server.host().isEmpty() ) {
155 mNoLDAPLookup =
false;
159 readWeighForClient( ldapClient, config, j );
162 attrs << QLatin1String(
"cn") << QLatin1String(
"mail") << QLatin1String(
"givenname") << QLatin1String(
"sn");
167 q->connect( ldapClient, SIGNAL(done()),
168 q, SLOT(slotLDAPDone()) );
169 q->connect( ldapClient, SIGNAL(error(QString)),
170 q, SLOT(slotLDAPError(QString)) );
172 mClients.append( ldapClient );
175 q->connect( &mDataTimer, SIGNAL(timeout()), SLOT(slotDataTimer()) );
177 mConfigFile = KStandardDirs::locateLocal(
"config", QLatin1String(
"kabldaprc") );
178 KDirWatch::self()->addFile( mConfigFile );
181 void LdapClientSearch::Private::slotFileChanged(
const QString &file )
183 if ( file == mConfigFile ) {
190 if ( d->mNoLDAPLookup ) {
196 int pos = txt.indexOf( QLatin1Char(
'\"') );
199 const int pos2 = txt.indexOf( QLatin1Char(
'\"'), pos );
201 d->mSearchText = txt.mid( pos, pos2 - pos );
203 d->mSearchText = txt.mid( pos );
206 d->mSearchText = txt;
217 const QString filter = QString::fromLatin1(
"&(|(objectclass=person)(objectclass=groupOfNames)(mail=*))"
218 "(|(cn=%1*)(mail=%1*)(mail=*@%1*)(givenName=%1*)(sn=%1*))" ).arg( d->mSearchText );
221 const QString filter = QString::fromLatin1(
"&(|(objectclass=person)(objectclass=groupOfNames)(mail=*))"
222 "(|(cn=%1*)(mail=%1*)(givenName=%1*)(sn=%1*))" ).arg( d->mSearchText );
226 for ( it = d->mClients.begin(); it != end; ++it ) {
227 (*it)->startQuery( filter );
228 kDebug(5300) <<
"LdapClientSearch::startSearch()" << filter;
237 for ( it = d->mClients.begin(); it != end; ++it ) {
238 (*it)->cancelQuery();
241 d->mActiveClients = 0;
245 void LdapClientSearch::Private::slotLDAPResult(
const LdapClient &client,
246 const KLDAP::LdapObject &obj )
249 result.client = &client;
252 mResults.append( result );
253 if ( !mDataTimer.isActive() ) {
254 mDataTimer.setSingleShot(
true );
255 mDataTimer.start( 500 );
259 void LdapClientSearch::Private::slotLDAPError(
const QString& )
264 void LdapClientSearch::Private::slotLDAPDone()
266 if ( --mActiveClients > 0 ) {
273 void LdapClientSearch::Private::slotDataTimer()
277 makeSearchData( lst, reslist );
278 if ( !lst.isEmpty() ) {
279 emit q->searchData( lst );
281 if ( !reslist.isEmpty() ) {
282 emit q->searchData( reslist );
286 void LdapClientSearch::Private::finish()
291 emit q->searchDone();
294 void LdapClientSearch::Private::makeSearchData( QStringList &ret,
LdapResult::List &resList )
299 for ( it1 = mResults.constBegin(); it1 != end1; ++it1 ) {
300 QString name, mail, givenname, sn;
302 bool isDistributionList =
false;
308 KLDAP::LdapAttrMap::ConstIterator it2;
309 for ( it2 = (*it1).object.attributes().constBegin();
310 it2 != (*it1).object.attributes().constEnd(); ++it2 ) {
311 QByteArray val = (*it2).first();
312 int len = val.size();
313 if ( len > 0 &&
'\0' == val[len-1] ) {
316 const QString tmp = QString::fromUtf8( val, len );
318 if ( it2.key() == QLatin1String(
"cn") ) {
320 if ( mail.isEmpty() ) {
324 mail.prepend( QLatin1String(
".") );
326 mail.prepend( QLatin1String(
"@") );
331 }
else if ( it2.key() == QLatin1String(
"dc") ) {
332 if ( mail.isEmpty() ) {
336 mail.append( QLatin1String(
".") );
338 mail.append( QLatin1String(
"@") );
343 }
else if ( it2.key() == QLatin1String(
"mail") ) {
345 KLDAP::LdapAttrValue::ConstIterator it3 = it2.value().constBegin();
346 for ( ; it3 != it2.value().constEnd(); ++it3 ) {
347 mails.append( QString::fromUtf8( (*it3).data(), (*it3).size() ) );
349 }
else if ( it2.key() == QLatin1String(
"givenName") ) {
351 }
else if ( it2.key() == QLatin1String(
"sn") ) {
353 }
else if ( it2.key() == QLatin1String(
"objectClass") &&
354 (tmp == QLatin1String(
"groupOfNames") || tmp == QLatin1String(
"kolabGroupOfNames")) ) {
355 isDistributionList =
true;
359 if ( mails.isEmpty() ) {
360 if ( !mail.isEmpty() ) {
361 mails.append( mail );
363 if ( isDistributionList ) {
383 }
else if ( name.isEmpty() ) {
386 ret.append( QString::fromLatin1(
"%1 <%2>" ).arg( name ).arg( mail ) );
394 resList.append( sr );
402 return !d->mNoLDAPLookup;
405 #include "ldapclientsearch.moc"
bool isAvailable() const
Returns whether LDAP search is possible at all.
int clientNumber
The client the contact comes from (used for sorting in a ldap-only lookup).
void cancelSearch()
Cancels the currently running search query.
Describes the result returned by an LdapClientSearch query.
QString name
The full name of the contact.
QList< LdapClient * > clients() const
Returns the list of configured LDAP clients.
void setAttributes(const QStringList &attributes)
Sets the LDAP attributes that should be returned in the query result.
LdapClientSearch(QObject *parent=0)
Creates a new ldap client search object.
void startSearch(const QString &query)
Starts the LDAP search on all configured LDAP clients with the given search query.
void setServer(const KLDAP::LdapServer &server)
Sets the LDAP server information that shall be used by this client.
~LdapClientSearch()
Destroys the ldap client search object.
void setCompletionWeight(int weight)
Sets the completion weight of this client.
QStringList email
The list of emails of the contact.
An object that represents a configured LDAP server.
void updateCompletionWeights()
Updates the completion weights for the configured LDAP clients from the configuration file...
int completionWeight
The weight of the contact (used for sorting in a completion list).