'use strict'; const {Client, Attribute} = require('ldapts'); const LRUCache = require('lru-native2'); const conf = require('>/conf').ldap; var userLUR = new LRUCache({ // The maximum age (in milliseconds) of an item. // The item will be removed if get() is called and the item is too old. // Default: 0, meaning items will never expire. maxAge: 60000, }); const user_parse = function(data){ if(data[conf.userNameAttribute]){ data.username = data[conf.userNameAttribute]; data.userPassword = undefined; data.userBacking = "LDAP"; } return data; } var User = {} User.backing = "LDAP"; User.list = async function(){ try{ const client = new Client({ url: conf.url, }); await client.bind(conf.bindDN, conf.bindPassword); const res = await client.search(conf.userBase, { scope: 'sub', filter: conf.userFilter, attributes: ['*', 'createTimestamp', 'modifyTimestamp'], }); await client.unbind(); return res.searchEntries.map(function(user){return user.uid}); }catch(error){ throw error; } }; User.listDetail = async function(){ try{ const client = new Client({ url: conf.url, }); await client.bind(conf.bindDN, conf.bindPassword); const res = await client.search(conf.userBase, { scope: 'sub', filter: conf.userFilter, attributes: ['*', 'createTimestamp', 'modifyTimestamp'], }); await client.unbind(); let users = []; for(let user of res.searchEntries){ let obj = Object.create(this); Object.assign(obj, user_parse(user)); users.push(obj); } return users; }catch(error){ throw error; } }; User.get = async function(data, key){ try{ if(typeof data !== 'object'){ let uid = data; data = {}; data.uid = uid; } data.searchKey = data.searchKey || key || conf.userNameAttribute; data.searchValue = data.searchValue || data.uid; let filter = `(&${conf.userFilter}(${data.searchKey}=${data.searchValue}))`; if(userLUR.get(filter)) return userLUR.get(filter); const client = new Client({ url: conf.url, }); await client.bind(conf.bindDN, conf.bindPassword); const res = await client.search(conf.userBase, { scope: 'sub', filter: filter, attributes: ['*', 'createTimestamp', 'modifyTimestamp'], }); await client.unbind(); if(res.searchEntries[0]){ let obj = Object.create(this); Object.assign(obj, user_parse(res.searchEntries[0])); userLUR.set(filter, obj); return obj; }else{ let error = new Error('UserNotFound'); error.name = 'UserNotFound'; error.message = `LDAP:${data.searchValue} does not exists`; error.status = 404; throw error; } }catch(error){ throw error; } }; User.exists = async function(data, key){ // Return true or false if the requested entry exists ignoring error's. try{ await this.get(data, key); return true }catch(error){ return false; } }; User.login = async function(data){ try{ let user = await this.get(data.uid || data[conf.userNameAttribute] || data.username); const client = new Client({ url: conf.url, }); await client.bind(user.dn, data.password); await client.unbind(); return user; }catch(error){ throw error; } }; module.exports = {User}; // (async function(){ // try{ // console.log(await User.list()); // console.log(await User.listDetail()); // console.log(await User.get('wmantly')) // }catch(error){ // console.error(error) // } // })()