2015-06-06 16 views
0

Я хочу преобразовать следующий код, чтобы использовать обещание. Он работает и выводит пользовательские атрибуты в активном каталоге.Использовать ldapjs с обещанием

var client = ldap.createClient({ 
    url: ldap_url 
}); 

client.bind(ldap_username, ldap_password, function (err) { 
    client.search(ldap_dn_search, opts, function (err, search) { 
     search.on('searchEntry', function (entry) { 
      var user = entry.object; 
      // It is working!!!. It outputs all user attributes. 
      console.log(user); 
     }); 

    }); 
}); 

Следующая попытка, но ничего не выводит.

var Promise = require('promise'); 
var client_bind = Promise.denodeify(client.bind); 
var client_search = Promise.denodeify(client.search); 

client_bind(ldap_username, ldap_password) 
.then(function(err){ 
    client_search(ldap_dn_search, opts) 
    .then(function(search){ 
     var search_on = Promise.denodeify(search.on); 
     search_on('searchEntry') 
     .then(function(entry){ 
      var user = entry.object; 

      // It doesn't output anything !!! 
      console.log(user); 
     }); 
     }); 

    }); 
+0

Нет сообщений об ошибках? – Bergi

ответ

0

Скорее всего эти методы требуют, чтобы называться по client в контексте, так что вам нужно будет bind() их, прежде чем передать их в Promise.denodeify:

var client_bind = Promise.denodeify(client.bind.bind(client)); 
var client_search = Promise.denodeify(client.search.bind(client)); 

Кроме того, правильное использование обещаний будет выглядеть следующим образом:

client_bind(ldap_username, ldap_password).then(function() { 
    return client_search(ldap_dn_search, opts); 
// ^^^^^^ always return something from the callback 
}).then(function(search) { // flatten your chain 
    return Promise.denodeify(search.on).call(search, 'searchEntry'); 
//         ^^^^^^ an alternative to `bind` 
}).then(function(entry){ 
    var user = entry.object; 
    console.log(user); 
}).catch(function(err) { // always catch errors! 
    console.error(err); 
}); 
+0

Я использовал предоставленный вами код. Я получил ошибку: UNABLE_TO_VERIFY_LEAF_SIGNATURE, хотя у меня есть process.env ['NODE_TLS_REJECT_UNAUTHORIZED'] = '0'; на самом верху моего скрипта. – kenpeter

+0

Это, похоже, не проблема с обещаниями, не так ли? – Bergi

+0

Я не уверен. Если я верну его обратно к исходному коду, он будет работать с process.env ['NODE_TLS_REJECT_UNAUTHORIZED'] = '0'; Если изменить код на: «вернуть Promise.denodeify (search.on) .call (search, 'searchEntry');" вернуть «что-то»; Исключение прекращается. – kenpeter

0

Использование Bluebird обещания, простой способ сделать это, чтобы создать свой клиент, как правило, а затем запустить пр omisifyAll() на клиенте.

var ldap = require('ldapjs'); 
var Promise = require('bluebird'); 

var client = ldap.createClient({ 
    url: 'ldap://my-server:1234', 
}); 

Promise.promisifyAll(client); 

Теперь вы можете вызвать client.addAsync() и client.searchAsync() и такие.

client.bindAsync(secUserDn, secUserPassword) 
    .then(doSearch) // if it works, call doSearch 
    .catch(function (err) { // if bind fails, handle it 
    console.error('Error on bind', err) 
    }); 

function doSearch(data) { 
    client.searchAsync('CN=A Test,OU=Users,DC=website,DC=com', options) 
    .then(function (data) { // Handle the search result processing 
     console.log('I got a result'); 
    }) 
    .catch(function (err) { // Catch potential errors and handle them 
     console.error('Error on search', err); 
    }); 
} 
+0

Это тот же ответ, что и [здесь] (http://stackoverflow.com/a/32009340/1048572)? Если вы считаете, что вопрос является дубликатом, проголосуйте, чтобы закрыть, а не копировать ответы. – Bergi

+0

Они очень близки к тому же, но оба они поднимаются вверху результатов поиска по аналогичным вопросам. В любом случае у меня нет этой способности. Я думаю, вам нужно 3k rep для закрытия/возобновления голосов. –

1

У меня была та же проблема. Поиск испускает события, поэтому нам нужно что-то, что обрабатывает их и проходит дальше по цепочке. Вот кусок кода, который работает для меня:

var ldap = require('ldapjs'); 
var promise = require('bluebird'); 

var client = ldap.createClient({url: app.settings['ldap']['server']}); 
var uid; 

promise.promisifyAll(client); 

function searchPromise(res, notfoundtext) { 
    return new Promise(function(resolve, reject) { 
    var found = false; 
    res.on('searchEntry', function(entry) { 
     found = true; 
     resolve(entry); 
    }); 
    res.on('error', function(e) { 
     reject(e.message); 
    }); 
    res.on('end', function() { 
     if (!found) { 
     reject(notfoundtext); 
     } 
    }); 
    }); 
} 

client.searchAsync(app.settings['ldap']['baseDn'], {filter: '(mail='+credentials.email+')', scope: 'sub'}) 
    .then(function(res) { 
    return searchPromise(res, 'User isn\'t exists.'); 
    }) 
    .then(function (entry) { 
    uid = entry.object.uid; 
    return client.bindAsync(entry.object.dn, credentials.password); 
    }) 
    .then(function() { 
    return client.searchAsync('cn='+app.settings['ldap']['group']+',cn=groups,'+app.settings['ldap']['baseDn'], {scope: 'sub', filter: '(memberUid='+uid+')'}); 
    }) 
    .then(function(res) { 
    return searchPromise(res, 'User is not in group ' + app.settings['ldap']['group']); 
    }) 
    .then(function() { 
    console.log('All is ok'); 
    }) 
    .catch(function(message) { 
    console.log('Error:' + message); 
    }); 

Сразу после обыска я добавить еще один шаг, который перехватывает события, обрабатывает их и передает его дальше по цепочке. Это делает функцию searchPromise.

Кодировка удачи)