Вторник, 02 февраля 2021 19:00

Расширенный поиск в каталоге LDAP - пользователи. Работа с LDAP в Qt5. Часть 4.

Россия
Оцените материал
(0 голосов)

Сегодня мы доработаем функционал поиска в каталоге LDAP. Будет создан класс QLdapSearch и добавлены методы для упрощения поиска в каталоге.

Мы будем использовать проект из предыдущей статьи.

Создаем класс QLdapSearch

Добавим в проект класс QLdapSearch:

Заголовок:

#ifndef QLDAPSEARCH_H
#define QLDAPSEARCH_H

#include "qldap.h"



class QLdapSearch
{
public:
    QLdapSearch(QLdap *ldap);

private:
    QLdap *ldap;
};

#endif // QLDAPSEARCH_H

Реализация
#include "qldapsearch.h"

QLdapSearch::QLdapSearch(QLdap *ldap)
{
    this->ldap = ldap;
}

Реализация:

#include "qldapsearch.h"

QLdapSearch::QLdapSearch(QLdap *ldap)
{
    this->ldap = ldap;
}

Добавим метод для поиска пользователей в LDAP и вспомогательные методы.

Область поиска

Для поиска в каталоге LDAP мы должны указать область поиска с помощью сроки DN.

Нет смысла каждый раз передавать её при поиске, поэтому мы будем сохранять её в поле класса:

private:
    QString searchDN;

Добавим сеттер:

void QLdapSearch::setDN(const QString &value)
{
    searchDN = value;
}

Результаты поиска

Для сохранения результатов поиска мы используем указатель, так что его тоже нет смысла каждый раз передавать в качестве параметра, добавим для него поле и сеттер/геттер:

private:
    QLdapEntryList *results;

void QLdapSearch::setResult(QLdapEntryList *value)
{
    results = value;
}

QLdapEntryList *QLdapSearch::getResult() const
{
    return results;
}

Поиск пользователей

Для поиска пользователей реализуем простой метод:

int QLdapSearch::user(QString filter)
{
    this->results->clear();
    QString aFilter = "(&(objectCategory=person)" + filter + ")";
    return this->ldap->search(this->searchDN,
                 aFilter,
                 this->results);
}

Здесь всё просто, мы добавляем к фильтру дополнительные условия.

Обратите внимание – мы используем метод clear() чтобы очистить результаты перед поиском, иначе они будут накапливаться в списке.

Использование поиска по пользователям

Удалим из конструктора главной формы лишний код и приведём его к виду: 

    QLdap *ldap = new QLdap();

     const QString url= "ldap://192.168.0.1:389";

     int result = ldap->init(url);
     if ( result != LDAP_SUCCESS )
     {
         QString msg = QString("QLDAP init() error: ") + QString(ldap_err2string(result));
         qFatal("%s",msg.toLatin1().constData());
         return;
     }

     qDebug() << "Init result = " << ldap_err2string(result);

     result = ldap->bind("CN=ldap-bind,CN=Users,DC=altuninvv,DC=local", "Pas#w0rds#1");

     if ( result != LDAP_SUCCESS )
     {
         QString msg = QString("QLDAP bind() error: ") + QString(ldap_err2string(result));
         qFatal("%s",msg.toLatin1().constData());
         ldap->close();
         return;
     }

     qDebug() << "Bind result = " << ldap_err2string(result);



     QLdapEntryList *userSearchResult = new QLdapEntryList();

     QLdapSearch search = QLdapSearch(ldap);
     search.setDN("OU=Company,DC=altuninvv,DC=local");
     search.setResult(userSearchResult);

     result = search.user("");

     if ( result != LDAP_SUCCESS )
     {
         QString msg = QString("QLDAP bind() error: ") + QString(ldap_err2string(result));
         qFatal("%s",msg.toLatin1().constData());
         ldap->close();
         return;
     }
     qDebug() << "User search result = " << ldap_err2string(result);

     QLdapEntry a = userSearchResult->at(0);
     QLdapUser user1 = QLdapUser(&a);
     qDebug() << user1["company"];
     qDebug() << user1["displayName"];


     result = ldap->close();
     if ( result != LDAP_SUCCESS )
     {
         QString msg = QString("QLDAP init() error: ") + QString(ldap_err2string(result));
         qFatal("%s",msg.toLatin1().constData());
         return;
     }
     qDebug() << "Close result = " << ldap_err2string(result);

Обратите внимание – любой код для поиска по LDAP вы должны добавлять до вызова:result = ldap->close();

 Запустим:

Init result =  Success
Bind result =  Success
Search result =  Success
Search results count =  100
Search results ref =  0
User search result =  Success
"Altunin Soft"
"Павлова Ясмина Всеволодовна"

Попробуем найти другого пользователя, чтобы не загромождать статью я буду опускать проверку результатов поиска, но вы обязательно должны это делать! 

     result = search.user("(displayName=орло*)");
     QLdapEntry b = userSearchResult->at(0);
     user1 = QLdapUser(&b);
     qDebug() << user1["company"];
     qDebug() << user1["displayName"];

Запустим:

Search result =  Success
Search results count =  1
Search results ref =  0
User search result =  Success
"Altunin Soft"
"Орлова Милана Артёмовна"
Close result =  Success

Поиск работает, как и ожидалось.

Поиск по имени и логину

Поиск по ФИО и логину чаще всего встречается, давайте добавим методы-обертки для метода user:

int QLdapSearch::userByName(QString name)
{
    return this->user("(displayName=" + name + ")");
}

int QLdapSearch::userByLogin(QString login)
{
    return this->user("(sAMAccountName=" + login + ")");
}

 

Добавим в конструктор главной формы код:

      //Search by name method
       result = search.userByName("федор*");

       for( auto e = userSearchResult->begin(); e != userSearchResult->end(); ++e)
       {
           user1 = QLdapUser(&(*e));
           qDebug() << user1["company"];
           qDebug() << user1["displayName"];
       }

 

Запустим:

"(&(objectCategory=person)(displayName=федор*))"
Search result =  Success
Search results count =  2
Search results ref =  0
User name search result =  Success
"Altunin Soft"
"Федоров Григорий Львович"
"Altunin Soft"
"Федоров Максим Матвеевич"

Я добавил вывод значения фильтра, для большей наглядности.

Попробуем поиск по логину:

      //Search by login method
        result = search.userByLogin("ber*");

        for( auto e = userSearchResult->begin(); e != userSearchResult->end(); ++e)
        {
            user1 = QLdapUser(&(*e));
            qDebug() << user1["company"];
            qDebug() << user1["displayName"];
        }

Запустим:

"(&(objectCategory=person)(sAMAccountName=ber*))"
Search result =  Success
Search results count =  2
Search results ref =  0
User name search result =  Success
"Altunin Soft"
"Березина Ирина Данииловна"
"Altunin Soft"
"Березин Михаил Святославович"

Как видите поиск может возвращать более одного пользователя.

Вы можете добавить столько методов-оберток сколько вам необходимо, тут всё зависит от удобства и как часто используется поиск по тем или иным атрибутам.

Заключение

Сегодня мы создали класс для расширенного поиска QLdapSearch

Добавили метод для поиска по атрибутам пользователя.

Добавили методы-обертки для поиска по имени пользователя и его логину.

В следующей статье мы рассмотрим поиск по группам в каталоге LDAP.

Исходный код проекта вы можете найти на Github.

Прочитано 313 раз Последнее изменение Вторник, 02 февраля 2021 19:21