This commit is contained in:
2024-01-05 22:06:34 -05:00
parent c8f00cdeaf
commit abc547c642
34 changed files with 6586 additions and 1561 deletions

99
models/ldap/group.js Normal file
View File

@ -0,0 +1,99 @@
'use strict';
const { Client, Attribute, Change } = require('ldapts');
const conf = require('>/conf').ldap;
const client = new Client({
url: conf.url,
});
async function getGroups(client, member){
try{
let memberFilter = member ? `(member=${member})`: ''
let groups = (await client.search(conf.groupBase, {
scope: 'sub',
filter: `(&(objectClass=groupOfNames)${memberFilter})`,
attributes: ['*', 'createTimestamp', 'modifyTimestamp'],
})).searchEntries;
return groups.map(function(group){
if(!Array.isArray(group.member)) group.member = [group.member];
return group
});
}catch(error){
throw error;
}
}
var Group = {};
Group.list = async function(member){
try{
await client.bind(conf.bindDN, conf.bindPassword);
let groups = await getGroups(client, member)
await client.unbind();
return groups.map(group => group.cn);
}catch(error){
throw error;
}
}
Group.listDetail = async function(member){
try{
await client.bind(conf.bindDN, conf.bindPassword);
let groups = await getGroups(client, member)
await client.unbind();
return groups;
}catch(error){
throw error;
}
}
Group.get = async function(data){
try{
if(typeof data !== 'object'){
let name = data;
data = {};
data.name = name;
}
await client.bind(conf.bindDN, conf.bindPassword);
let group = (await client.search(conf.groupBase, {
scope: 'sub',
filter: `(&(objectClass=groupOfNames)(cn=${data.name}))`,
attributes: ['*', 'createTimestamp', 'modifyTimestamp'],
})).searchEntries[0];
await client.unbind();
if(!Array.isArray(group.member)) group.member = [group.member];
if(group){
let obj = Object.create(this);
Object.assign(obj, group);
return obj;
}else{
let error = new Error('GroupNotFound');
error.name = 'GroupNotFound';
error.message = `LDAP:${data.cn} does not exists`;
error.status = 404;
throw error;
}
}catch(error){
throw error;
}
}
module.exports = {Group};

6
models/ldap/index.js Normal file
View File

@ -0,0 +1,6 @@
'use strict';
module.exports = {
User: require('./user').User,
Group: require('./group').Group,
};

159
models/ldap/user.js Normal file
View File

@ -0,0 +1,159 @@
'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 client = new Client({
url: conf.url,
});
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{
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{
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)
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);
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)
// }
// })()