forked from tasansga/haraka-ldap
-
Notifications
You must be signed in to change notification settings - Fork 4
/
pool.js
101 lines (84 loc) · 2.73 KB
/
pool.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
'use strict';
const ldap = require('ldapjs');
class LdapPool {
constructor(config) {
this._set_config(config);
this.pool = { servers: [] };
}
_set_config(config = {}) {
if (config.main === undefined) config.main = {};
this.config = {
servers: config.main.server || ['ldap://localhost:389'],
timeout: config.main.timeout,
tls_enabled: config.main.tls_enabled || false,
tls_rejectUnauthorized: config.main.tls_rejectUnauthorized,
scope: config.main.scope || 'sub',
binddn: config.main.binddn,
bindpw: config.main.bindpw,
basedn: config.main.basedn,
aliases: config.aliases,
authn: config.authn,
authz: config.authz,
rcpt_to: config.rcpt_to,
};
return this.config;
}
_get_ldapjs_config() {
const config = {
url: this.config.servers.shift(),
timeout: this.config.timeout,
};
this.config.servers.push(config.url);
if (this.config.tls_rejectUnauthorized !== undefined) {
config.tlsOptions = {
rejectUnauthorized: this.config.tls_rejectUnauthorized,
};
}
return config;
}
_create_client(next) {
const client = ldap.createClient(this._get_ldapjs_config());
client.on('connectError', (err) => {
console.error(err);
});
if (!this.config.tls_enabled) return next(null, client);
client.starttls({}, null, (err) => {
if (err) return next(err);
next(null, client);
});
}
close(next) {
if (this.pool.servers.length <= 0) return next();
while (this.pool.servers.length > 0) {
this.pool.servers.shift().unbind();
if (this.pool.servers.length === 0) next();
}
}
_bind_default(next) {
const cfg = this.config;
this._create_client((err, client) => {
if (err) return next(err);
if (cfg.binddn && cfg.bindpw) {
client.bind(cfg.binddn, cfg.bindpw, (err2) => {
next(err2, client);
});
} else {
next(null, client);
}
});
}
get(next) {
const pool = this.pool;
if (pool.servers.length >= this.config.servers.length) {
// shift and push for round-robin
const client = pool.servers.shift();
pool.servers.push(client);
return next(null, client);
}
this._bind_default((err, client) => {
pool.servers.push(client);
next(err, client);
});
}
}
exports.LdapPool = LdapPool;