Commit a21b1159e7323213cd125287e97f279730021600

Authored by Adhidarma Hadiwinoto
1 parent 971384b244
Exists in master

Manajemen user

Showing 6 changed files with 289 additions and 0 deletions Side-by-side Diff

... ... @@ -3,6 +3,7 @@ var nunjucks = require('nunjucks');
3 3 var session = require('express-session');
4 4 var MongoStore = require('connect-mongo/es5')(session);
5 5 var bodyParser = require('body-parser');
  6 +var mongoObjectID = require('mongodb').ObjectID;
6 7 var mongoClient = require('mongodb').MongoClient;
7 8 var crypto = require('crypto');
8 9 var strftime = require('strftime');
... ... @@ -179,6 +180,7 @@ function pageHome(req, res, next) {
179 180 res.render('index.html', {
180 181 title: 'Transactions',
181 182 config: config,
  183 + session: req.session,
182 184 conditions: conditions,
183 185 trxcount: count,
184 186 pagecount: pagecount,
... ... @@ -234,10 +236,15 @@ function pageSigninPost(req, res, next) {
234 236 }
235 237  
236 238 req.session.username = req.body.username;
  239 +
237 240 if (doc.roles) {
  241 +
238 242 req.session.roles = doc.roles;
  243 + req.session.isAdmin = (doc.roles.indexOf('admin') >= 0);
  244 +
239 245 } else {
240 246 req.session.roles = [];
  247 + req.session.isAdmin = 0;
241 248 }
242 249  
243 250 res.redirect('/');
... ... @@ -245,6 +252,119 @@ function pageSigninPost(req, res, next) {
245 252 });
246 253 }
247 254  
  255 +function pageUsersIndex(req, res, next) {
  256 + mongodb.collection('users').find({}).toArray(function(err, docs) {
  257 + if (err) {
  258 + res.end('Gagal ambil list user');
  259 + return;
  260 + }
  261 +
  262 + /*
  263 + console.log(JSON.stringify(docs));
  264 + res.send(JSON.stringify(docs));
  265 + return;
  266 + */
  267 +
  268 + res.render('users.index.html', {
  269 + title: 'Users',
  270 + config: config,
  271 + session: req.session,
  272 + qs: req.query,
  273 + url: req.url,
  274 + path: req.path,
  275 + users: docs,
  276 + });
  277 + });
  278 +
  279 +}
  280 +
  281 +function pageUsersView(req, res, next) {
  282 +
  283 + mongodb.collection('users').find({_id: new mongoObjectID(req.params.id)}).limit(1).next(function(err, doc) {
  284 + if (err) {
  285 + res.send("Error retrieving data");
  286 + return;
  287 + }
  288 +
  289 + res.render(
  290 + 'users.view.html',
  291 + {
  292 + title: doc.email,
  293 + session: req.session,
  294 + user: doc
  295 + }
  296 + );
  297 +
  298 + });
  299 +
  300 +}
  301 +
  302 +function pageUsersAdd(req, res, next) {
  303 + res.render(
  304 + 'users.add.html',
  305 + {
  306 + title: 'Add a new user',
  307 + session: req.session
  308 + }
  309 + );
  310 +}
  311 +
  312 +function pageUsersAddPost(req, res, next) {
  313 + if (req.body.password1 != req.body.password2) {
  314 + res.redirect("/users/add");
  315 + return;
  316 + }
  317 +
  318 + var passwordHash = crypto.createHash('sha256').update(req.body.password1).digest().toString('hex');
  319 + var roles = req.body.roles.replace(" ", "").split(",");
  320 + var suppliers = req.body.suppliers.replace(" ", "").split(",");
  321 +
  322 + var user = {
  323 + email: req.body.email,
  324 + password: passwordHash,
  325 + roles: roles,
  326 + suppliers: suppliers
  327 + }
  328 +
  329 + mongodb.collection('users').insertOne(user, function(err, r) {
  330 + res.redirect('/users');
  331 + });
  332 +
  333 +}
  334 +
  335 +function pageUsersChangePassword(req, res, next) {
  336 + mongodb.collection('users').find({_id: new mongoObjectID(req.params.id)}).limit(1).next(function(err, doc) {
  337 + if (err) {
  338 + res.send("Error retrieving data");
  339 + return;
  340 + }
  341 +
  342 + res.render(
  343 + 'users.change-password.html',
  344 + {
  345 + title: 'Change Password',
  346 + session: req.session,
  347 + user: doc
  348 + }
  349 + );
  350 + });
  351 +}
  352 +
  353 +function pageUsersChangePasswordPost(req, res, next) {
  354 + if (req.body.passwod1 && (req.body.password1 != req.body.password2)) {
  355 + res.redirect("/users/change-password/" + req.body._id);
  356 + return;
  357 + }
  358 +
  359 + var _id = new mongoObjectID(req.body._id);
  360 + var passwordHash = crypto.createHash('sha256').update(req.body.password1).digest().toString('hex');
  361 +
  362 + mongodb.collection('users').updateOne({_id: _id}, {$set: {password: passwordHash}}, function(err, r) {
  363 + res.redirect("/users/view/" + req.body._id);
  364 + return;
  365 + });
  366 +}
  367 +
248 368 function logout(req, res, next) {
249 369 req.session.username = null;
250 370 res.redirect('/signin');
... ... @@ -257,6 +377,13 @@ app.get('/logout', logout);
257 377  
258 378 app.get('/trx/view/:id', authNeeded, pageTrxView);
259 379  
  380 +app.get('/users', authNeeded, pageUsersIndex);
  381 +app.get('/users/view/:id', authNeeded, pageUsersView);
  382 +app.get('/users/add', authNeeded, pageUsersAdd);
  383 +app.post('/users/add', authNeeded, pageUsersAddPost);
  384 +app.get('/users/change-password/:id', authNeeded, pageUsersChangePassword);
  385 +app.post('/users/change-password/:id', authNeeded, pageUsersChangePasswordPost);
  386 +
260 387 app.listen(config.listen_port, function () {
261 388 console.log('Example app listening on port ' + config.listen_port);
262 389 });
views/starter-template.html
... ... @@ -48,6 +48,16 @@
48 48 <div id="navbar" class="collapse navbar-collapse">
49 49 <ul class="nav navbar-nav">
50 50 <li><a href="/">Home</a></li>
  51 + {% if session.isAdmin %}
  52 + <li class="dropdown">
  53 + <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
  54 + Admin <span class="caret"></span>
  55 + </a>
  56 + <ul class="dropdown-menu">
  57 + <li><a href="/users">Users</a></li>
  58 + </ul>
  59 + </li>
  60 + {% endif %}
51 61 <li><a href="/logout">Logout</a></li>
52 62 </ul>
53 63 </div><!--/.nav-collapse -->
views/users.add.html
... ... @@ -0,0 +1,42 @@
  1 +{% extends "starter-template.html" %}
  2 +{% block content %}
  3 +
  4 +<form class="form-horizontal" method="POST">
  5 +
  6 + <div class="form-group">
  7 + <label for="inputEmail" class="col-sm-2 control-label">Email</label>
  8 + <div class="col-sm-10">
  9 + <input name="email" type="text" class="form-control" id="inputEmail">
  10 + </div>
  11 + </div>
  12 +
  13 + <div class="form-group">
  14 + <label for="inputSuppliers" class="col-sm-2 control-label">Suppliers</label>
  15 + <div class="col-sm-10">
  16 + <input name="suppliers" type="text" class="form-control" id="inputSuppliers">
  17 + </div>
  18 + </div>
  19 +
  20 + <div class="form-group">
  21 + <label for="inputRoles" class="col-sm-2 control-label">Roles</label>
  22 + <div class="col-sm-10">
  23 + <input name="roles" type="text" class="form-control" id="inputRoles">
  24 + </div>
  25 + </div>
  26 +
  27 + <div class="form-group">
  28 + <label for="inputPassword" class="col-sm-2 control-label">Password</label>
  29 + <div class="col-sm-10">
  30 + <input name="password1" type="password" class="form-control" id="inputPassword1" placeholder="Password">
  31 + <input name="password2" type="password" class="form-control" id="inputPassword2" placeholder="Retype password">
  32 + </div>
  33 + </div>
  34 +
  35 + <div class="form-group">
  36 + <div class="col-sm-offset-2 col-sm-10">
  37 + <input type="submit" class="btn btn-primary">
  38 + </div>
  39 + </div>
  40 +
  41 +</form>
  42 +{% endblock %}
views/users.change-password.html
... ... @@ -0,0 +1,32 @@
  1 +{% extends "starter-template.html" %}
  2 +{% block content %}
  3 +
  4 +<form class="form-horizontal" method="POST">
  5 +
  6 + <input name="_id" type="hidden" value="{{ user._id }}">
  7 +
  8 + <div class="form-group">
  9 + <label for="inputEmail" class="col-sm-2 control-label">Email</label>
  10 + <div class="col-sm-10">
  11 + <input name="email" type="text" class="form-control" id="inputEmail" value="{{ user.email }}" readonly>
  12 + </div>
  13 + </div>
  14 +
  15 + <div class="form-group">
  16 + <label for="inputPassword" class="col-sm-2 control-label">Password</label>
  17 + <div class="col-sm-10">
  18 + <input name="password1" type="password" class="form-control" id="inputPassword1" placeholder="Password">
  19 + <input name="password2" type="password" class="form-control" id="inputPassword2" placeholder="Retype password">
  20 + </div>
  21 + </div>
  22 +
  23 + <div class="form-group">
  24 + <div class="col-sm-offset-2 col-sm-10">
  25 + <input type="submit" class="btn btn-primary">
  26 + <a href="/users" class="btn btn-default" role="button">Cancel</a>
  27 + </div>
  28 + </div>
  29 +
  30 +</form>
  31 +
  32 +{% endblock %}
views/users.index.html
... ... @@ -0,0 +1,45 @@
  1 +{% extends "starter-template.html" %}
  2 +{% block content %}
  3 +
  4 +<table class="table table-striped table-hover">
  5 + <tr>
  6 + <th>Email</th>
  7 + <th>Suppliers</th>
  8 + <th>Roles</th>
  9 + <th>&nbsp;</th>
  10 + </tr>
  11 +
  12 + {% for user in users %}
  13 + <tr>
  14 +
  15 + <td class="user-email">
  16 + <a href="/users/view/{{ user._id }}">
  17 + {{ user.email }}
  18 + </a>
  19 + </td>
  20 +
  21 + <td class="user-suppliers">
  22 + {% for supplier in user.suppliers %}
  23 + <span class="label label-default">{{ supplier }}</span>
  24 + {% endfor %}
  25 + </td>
  26 +
  27 + <td class="user-roles">
  28 + {% for role in user.roles %}
  29 + <span class="label label-default">{{ role }}</span>
  30 + {% endfor %}
  31 + </td>
  32 +
  33 + <td class="user-action">
  34 + <a href="/users/change-password/{{ user._id }}" class="btn btn-primary" role="button">
  35 + Change Password
  36 + </a>
  37 + </td>
  38 +
  39 + </tr>
  40 + {% endfor %}
  41 +</table>
  42 +
  43 +<a href="/users/add" class="btn btn-primary" role="button">Add</a>
  44 +
  45 +{% endblock %}
views/users.view.html
... ... @@ -0,0 +1,33 @@
  1 +{% extends "starter-template.html" %}
  2 +{% block content %}
  3 +
  4 +<form class="form-horizontal">
  5 +
  6 + <div class="form-group">
  7 + <label for="inputEmail" class="col-sm-2 control-label">Email</label>
  8 + <div class="col-sm-10">
  9 + <input type="text" class="form-control" id="inputEmail" value="{{ user.email }}" readonly>
  10 + </div>
  11 + </div>
  12 +
  13 + <div class="form-group">
  14 + <label for="inputSuppliers" class="col-sm-2 control-label">Suppliers</label>
  15 + <div class="col-sm-10">
  16 + {% for supplier in user.suppliers %}
  17 + <span class="label label-default">{{ supplier }}</span>
  18 + {% endfor %}
  19 + </div>
  20 + </div>
  21 +
  22 + <div class="form-group">
  23 + <label for="inputRoles" class="col-sm-2 control-label">Roles</label>
  24 + <div class="col-sm-10">
  25 + {% for role in user.roles %}
  26 + <span class="label label-default">{{ role }}</span>
  27 + {% endfor %}
  28 + </div>
  29 + </div>
  30 +
  31 +</form>
  32 +
  33 +{% endblock %}