Skip to content

Commit bbdd78f

Browse files
committed
Initial commit
1 parent eedc06e commit bbdd78f

16 files changed

+529
-0
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,11 @@ build/Release
2525

2626
# Dependency directory
2727
node_modules
28+
bower_components
2829

2930
# Optional npm cache directory
3031
.npm
3132

3233
# Optional REPL history
3334
.node_repl_history
35+
.idea

app.js

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
var express = require('express');
2+
var path = require('path');
3+
var favicon = require('serve-favicon');
4+
var logger = require('morgan');
5+
var cookieParser = require('cookie-parser');
6+
var bodyParser = require('body-parser');
7+
8+
var routes = require('./routes/index');
9+
var ldap = require('./routes/ldap');
10+
//if loaded here, how to propagate / share the values
11+
var ldapCfg = require('./config');
12+
13+
var app = express();
14+
15+
// view engine setup
16+
app.set('views', path.join(__dirname, 'views'));
17+
app.set('view engine', 'jade');
18+
19+
// uncomment after placing your favicon in /public
20+
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
21+
app.use(logger('dev'));
22+
app.use(bodyParser.json());
23+
app.use(bodyParser.urlencoded({extended: false}));
24+
app.use(cookieParser());
25+
app.use(express.static(path.join(__dirname, 'public')));
26+
app.use('/bower_components', express.static(path.join(__dirname, 'bower_components')));
27+
28+
app.use('/', routes);
29+
app.use('/ldap', ldap);
30+
31+
// catch 404 and forward to error handler
32+
app.use(function (req, res, next) {
33+
var err = new Error('Not Found');
34+
err.status = 404;
35+
next(err);
36+
});
37+
38+
// error handlers
39+
40+
// development error handler
41+
// will print stacktrace
42+
if (app.get('env') === 'development') {
43+
app.use(function (err, req, res, next) {
44+
res.status(err.status || 500);
45+
res.render('error', {
46+
message: err.message,
47+
error: err
48+
});
49+
});
50+
}
51+
52+
// production error handler
53+
// no stacktraces leaked to user
54+
app.use(function (err, req, res, next) {
55+
res.status(err.status || 500);
56+
res.render('error', {
57+
message: err.message,
58+
error: {}
59+
});
60+
});
61+
62+
63+
//cant get return value
64+
//var result = ldapClient.userExists('testme');
65+
//console.log('The result is: ' + result);
66+
module.exports = app;

bin/www

+90
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
#!/usr/bin/env node
2+
3+
/**
4+
* Module dependencies.
5+
*/
6+
7+
var app = require('../app');
8+
var debug = require('debug')('ldapRoute-change:server');
9+
var http = require('http');
10+
11+
/**
12+
* Get port from environment and store in Express.
13+
*/
14+
15+
var port = normalizePort(process.env.PORT || '3000');
16+
app.set('port', port);
17+
18+
/**
19+
* Create HTTP server.
20+
*/
21+
22+
var server = http.createServer(app);
23+
24+
/**
25+
* Listen on provided port, on all network interfaces.
26+
*/
27+
28+
server.listen(port);
29+
server.on('error', onError);
30+
server.on('listening', onListening);
31+
32+
/**
33+
* Normalize a port into a number, string, or false.
34+
*/
35+
36+
function normalizePort(val) {
37+
var port = parseInt(val, 10);
38+
39+
if (isNaN(port)) {
40+
// named pipe
41+
return val;
42+
}
43+
44+
if (port >= 0) {
45+
// port number
46+
return port;
47+
}
48+
49+
return false;
50+
}
51+
52+
/**
53+
* Event listener for HTTP server "error" event.
54+
*/
55+
56+
function onError(error) {
57+
if (error.syscall !== 'listen') {
58+
throw error;
59+
}
60+
61+
var bind = typeof port === 'string'
62+
? 'Pipe ' + port
63+
: 'Port ' + port;
64+
65+
// handle specific listen errors with friendly messages
66+
switch (error.code) {
67+
case 'EACCES':
68+
console.error(bind + ' requires elevated privileges');
69+
process.exit(1);
70+
break;
71+
case 'EADDRINUSE':
72+
console.error(bind + ' is already in use');
73+
process.exit(1);
74+
break;
75+
default:
76+
throw error;
77+
}
78+
}
79+
80+
/**
81+
* Event listener for HTTP server "listening" event.
82+
*/
83+
84+
function onListening() {
85+
var addr = server.address();
86+
var bind = typeof addr === 'string'
87+
? 'pipe ' + addr
88+
: 'port ' + addr.port;
89+
debug('Listening on ' + bind);
90+
}

bower.json

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"name": "ldap-change",
3+
"description": "ldap-change",
4+
"main": "",
5+
"authors": [
6+
"4F2E4A2E <[email protected]>"
7+
],
8+
"license": "MIT",
9+
"moduleType": [
10+
"node"
11+
],
12+
"homepage": "",
13+
"private": true,
14+
"ignore": [
15+
"**/.*",
16+
"node_modules",
17+
"bower_components",
18+
"test",
19+
"tests"
20+
],
21+
"dependencies": {
22+
"bootstrap": "^3.3.6",
23+
"jquery": "^2.2.3",
24+
"form.validation": "*"
25+
}
26+
}

config.json

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"ldap_host_url": "ldap://127.0.0.1:10389",
3+
"ldap_base_dn": "dc=company,dc=com",
4+
"ldap_bind_user": "<user-dn>",
5+
"ldap_bind_password": "",
6+
"ldap_user_prefix": "uid="
7+
}

package.json

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"name": "ldap-change",
3+
"version": "0.0.0",
4+
"private": true,
5+
"scripts": {
6+
"start": "node ./bin/www"
7+
},
8+
"dependencies": {
9+
"body-parser": "~1.13.2",
10+
"cookie-parser": "~1.3.5",
11+
"debug": "~2.2.0",
12+
"express": "~4.13.1",
13+
"jade": "~1.11.0",
14+
"ldapjs": "^1.0.0",
15+
"morgan": "~1.6.1",
16+
"serve-favicon": "~2.3.0"
17+
}
18+
}
+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
var ldap = require('ldapjs');
2+
var ldapCfg = require('../../config');
3+
4+
5+
var client = ldap.createClient({
6+
url: ldapCfg.ldap_host_url,
7+
idleTimeout: 200
8+
});
9+
10+
function bind() {
11+
client = ldap.createClient({
12+
url: ldapCfg.ldap_host_url,
13+
idleTimeout: 200
14+
});
15+
client.bind(ldapCfg.ldap_bind_user, ldapCfg.ldap_bind_password, function (err) {
16+
if (err != null) {
17+
console.log(err);
18+
} else {
19+
console.log('LDAP-Client successful binded.');
20+
}
21+
});
22+
}
23+
24+
25+
exports.changePassword = function (userId, oldPassword, newPassword) {
26+
bind();
27+
client.search(ldapCfg.ldap_base_dn, opts = {
28+
filter: ldapCfg.ldap_user_prefix + userId,
29+
scope: 'sub',
30+
attributes: ['dn']
31+
}, function (err, res) {
32+
res.on('searchEntry', function (entry) {
33+
var userDN = entry.object.dn;
34+
client.bind(userDN, oldPassword, function (err) {
35+
client.modify(userDN, [
36+
new ldap.Change({
37+
operation: 'replace',
38+
modification: {
39+
userPassword: newPassword
40+
}
41+
})
42+
], function (err) {
43+
if (err) {
44+
console.log(err.code);
45+
console.log(err.name);
46+
console.log(err.message);
47+
}
48+
else {
49+
console.log('Password changed!');
50+
}
51+
});
52+
});
53+
});
54+
res.on('end', function (result) {
55+
console.log('Status: ' + result.status);
56+
});
57+
});
58+
59+
};
60+
61+
exports.userExists = function (userId) {
62+
bind();
63+
client.search(ldapCfg.ldap_base_dn, opts = {
64+
filter: ldapCfg.ldap_user_prefix + userId,
65+
scope: 'sub',
66+
attributes: ['dn']
67+
}, function (err, res) {
68+
if (err != null)
69+
console.log(err);
70+
71+
res.on('searchEntry', function (_entry) {
72+
client.userAvailable = true;
73+
console.log('entry: ' + JSON.stringify(_entry.object));
74+
});
75+
76+
res.on('error', function (err) {
77+
console.error('error: ' + err.message);
78+
});
79+
80+
res.on('end', function (result) {
81+
console.log('LDAP-Client successful search. Status: ' + result.status);
82+
client.unbind();
83+
});
84+
85+
});
86+
87+
};

public/stylesheets/style.css

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
body {
2+
padding: 50px;
3+
font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
4+
}
5+
6+
a {
7+
color: #00B7FF;
8+
}

routes/index.js

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
var express = require('express');
2+
var router = express.Router();
3+
4+
/* GET home page. */
5+
router.get('/', function(req, res, next) {
6+
res.render('ldap', { title: 'LDAP Password Change Tool' });
7+
});
8+
9+
module.exports = router;

routes/ldap.js

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
var express = require('express');
2+
var ldapClient = require('../public/javascripts/ldap-client-apacheds.js');
3+
var router = express.Router();
4+
5+
/* GET ldapRoute listing. */
6+
router.get('/', function (req, res, next) {
7+
console.log(req.body);
8+
//res.send('respond with a resource');
9+
res.render('ldap', {title: 'HTML5 LDAP Password Change Tool'});
10+
11+
});
12+
13+
14+
router.use('/change/password', function (req, res, next) {
15+
ldapClient.changePassword(req.body.userName, req.body.oldPassword, req.body.confirmPassword);
16+
res.send('O.K.');
17+
});
18+
19+
module.exports = router;

views/error.jade

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
extends ../node_modules/jade-bootstrap/layouts/starter
2+
block body
3+
h1= message
4+
h2= error.status
5+
pre #{error.stack}

views/index.html

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<head><title></title><link rel="stylesheet" href="/bower_components/bootstrap/dist/css/bootstrap.min.css"/><script type="text/javascript" src="/bower_components/jquery/dist/jquery.min.js"></script><script type="text/javascript" src="/bower_components/bootstrap/dist/js/bootstrap.min.js"></script><script type="text/javascript" src="/bower_components/form.validation/dist/js/formValidation.min.js"></script><script type="text/javascript" src="/bower_components/form.validation/dist/js/framework/bootstrap.min.js"></script><script type="text/javascript" src="/javascripts/ldap-client-apacheds.js"></script><body><h1></h1><p>Welcome to </p></body></head><!DOCTYPE html><html></html>

views/index.jade

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
extends ../node_modules/jade-bootstrap/_bootstrap
2+
extends layout
3+
4+
block content
5+
h1= title
6+
p Welcome to #{title}

views/layout.jade

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
head
2+
title= title
3+
link(rel='stylesheet', href='/bower_components/bootstrap/dist/css/bootstrap.min.css')
4+
5+
script(type='text/javascript', src='/bower_components/jquery/dist/jquery.min.js')
6+
script(type='text/javascript', src='/bower_components/bootstrap/dist/js/bootstrap.min.js')
7+
script(type='text/javascript', src='/bower_components/form.validation/dist/js/formValidation.min.js')
8+
script(type='text/javascript', src='/bower_components/form.validation/dist/js/framework/bootstrap.min.js')
9+
10+
script(type='text/javascript', src='/javascripts/ldap-client-apacheds.js')
11+
12+
body
13+
block content
14+
doctype
15+
html

0 commit comments

Comments
 (0)