'use strict'; var simpleDI = require('config/simpleDI'); module.exports = simpleDI.inject(['mongoose'], function(mongoose) { var Schema = mongoose.Schema; var RoleSchema = new Schema({ roleName: { type: String, unique: true, required: true } }); return mongoose.model('role', RoleSchema); });
module.exports = simpleDI.inject(['mongoose', 'base/userModel', 'jsonwebtoken', 'app/config'], function (mongoose, User, jwt, appConfig) { var ObjectId = mongoose.Types.ObjectId, secretKey = appConfig.secretKey; return { /** * Create user * requires: {username, password, email} * returns: {email, password} */ create: function (req, res, next) { var newUser = new User(req.body); newUser.provider = 'local'; newUser.save(function (err) { if (err) { return res.json(400, err); } var response = { user: newUser, exp: Math.round(new Date().setDate(new Date().getDate() + 1) / 1000) }; var token = jwt.sign(response, secretKey, { expiresInMinutes: 1440 }); res.json(200, { token: token, message: 'User created.' }); }); }, /** * Show profile * returns {username, profile} */ show: function (req, res, next) { var userId = req.params.userId; User.findById(new ObjectId(userId), function (err, user) { if (err) { return next(new Error('Failed to load User')); } if (user) { res.send({ username: user.username, profile: user.profile }); } else { res.send(404, { message: 'User not found' }); } }); }, /** * Username exists * returns {exists} */ exists: function (req, res, next) { var username = req.params.username; User.findOne({ username: username }, function (err, user) { if (err) { return next(new Error('Failed to load User ' + username)); } if (user) { res.json({ exists: true }); } else { res.json({ exists: false }); } }); } }; });
module.exports = simpleDI.inject(['jsonwebtoken', 'app/config'], function(jwt, appConfig) { var secretKey = appConfig.secretKey; return { /** * Middleware to verify a token * require: { token } * returns: { success, message } */ verifySignature: function (req, res, next) { // Check header, url or post parameters to get the token var token = req.body.token || req.query.token || req.headers['x-access-token']; // If there is no token then return an error if (!token) { return res.json(403, { message: 'No token provided.' }); } else { // Decode and verify the token jwt.verify(token, secretKey, function (err, decodedToken) { if (err) { return res.json(401, { message: 'Failed to authenticate token.' }); } else { // If everything goes right, save the request for use in other routes req.decoded = decodedToken; next(); } }); } } }; });
'use strict'; var simpleDI = require('config/simpleDI'); module.exports = simpleDI.inject(['mongoose'], function(mongoose) { var Schema = mongoose.Schema; var ResourceSchema = new Schema({ name: { type: String, unique: true, required: true }, description: String }); return mongoose.model('resource', ResourceSchema); });
module.exports = simpleDI.inject(['base/userModel', 'jsonwebtoken', 'app/config'], function (User, jwt, appConfig) { var secretKey = appConfig.secretKey; return { /** * Authenticate a user * requires: { email, password } * returns: { success, message, token } */ authenticate: function (req, res) { var email = req.body.email; User.findOne({ email: email }, function (err, user) { if (err) { return res.json(400, err); } // If the user does not exist if (!user) { return res.json(404, { message: 'Authentication failed. User not found.' }); } var password = req.body.password; // Check if the password matches if (!user.validatePassword(password)) { return res.json(401, { message: 'Authentication failed. Wrong password.' }); } // Add one day var date = new Date(); date.setDate(date.getDate() + 1); var response = { user: user, exp: Math.round(date.getTime() / 1000) }; // If the user is found and the password correct then create a token var token = jwt.sign(response, secretKey, { expiresInMinutes: 1440 // the new token expires in 24hs }); return res.json(200, { message: 'Enjoy your token!', token: token }); }); } }; });
module.exports = simpleDI.inject(['mongoose', 'base/resourceModel', 'jsonwebtoken', 'app/config'], function (mongoose, Resource, jwt, appConfig) { var ObjectId = mongoose.Types.ObjectId; return { /** * Create resource * requires: {name, description} * returns: {message} */ create: function (req, res, next) { var newResource = new Resource(); newResource.name = req.body.name; newResource.description = req.body.description; newResource.save(function(err) { if (err) { return res.json(400, { message: err }); } res.json(200, { message: 'Resource created.' }); }); }, /** * get all resources * returns {_id, name, description} */ getAll: function (req, res, next) { Resource.find({}, function (err, resources) { if (err) { return next(err); } if (resources) { res.json(resources); } else { res.json(404, { message: 'Resources not found' }); } }); }, getById: function (req, res, next) { var resourceId = req.params.resourceId; Resource.findById(ObjectId(resourceId)).exec(function (err, resource) { if (err) { return next(err); } if (resource) { res.json(resource); } else { res.json(404, { message: 'Resource not found' }); } }); }, update: function (req, res, next) { var idToUpdate = ObjectId(req.params.resourceId); Resource.update({ _id : idToUpdate }, { name : req.body.name, description: req.body.description }, {}, function (err, affectedRows) { if (err) { res.json(400, err); } if (affectedRows && affectedRows == 1) { res.send(200, "OK"); } else { res.json(404, { message: 'Resource not found' }); } }); }, delete: function (req, res, next) { //TODO: check the role doesn't have users associated? var idToDelete = ObjectId(req.params.resourceId); Resource.remove({ _id : idToDelete }, function (err) { if (err) { res.json(400, err); } res.send(200, "OK"); }); }, }; });
module.exports = simpleDI.inject(['base/authorizationService'], function (authorizationService) { return { getAuthorizationFn: function (resource, action) { return function checkAuthorization(req, res, next) { var roles = []; // Check if there is an authenticated user if (req.decoded) { // User is logged in, get its roles // TODO: Get actual roles for user roles.push('user'); } else { roles.push('anonymous'); } authorizationService.isAuthorized(roles, resource, action, function (error, isAuthorized) { if (error) { return next(error); } if (!isAuthorized) { return res.json(403, { message: 'Not authorized.' }); } next(); }); }; } }; });
module.exports = simpleDI.inject([ 'base/authController', 'base/authenticationMiddleware', 'base/authorizationMiddleware', 'base/commonController', 'base/usersController', 'base/rolesController', 'base/resourcesController' ], function(authController, authenticationMiddleware, authorizationMiddleware, commonController, usersController, rolesController, resourcesController) { return function baseRoutes(app) { // User Routes app.post('/auth/users', authorizationMiddleware.getAuthorizationFn('signup', 'create'), usersController.create ); app.get('/auth/users/:userId', authenticationMiddleware.verifySignature, authorizationMiddleware.getAuthorizationFn('users', 'view'), usersController.show ); app.post('/auth/', authorizationMiddleware.getAuthorizationFn('login', 'create'), authController.authenticate ); app.get('/api/common/menu/', authenticationMiddleware.verifySignature, authorizationMiddleware.getAuthorizationFn('menu', 'view'), commonController.menu ); app.get('/auth/roles/getall', rolesController.getAll); app.get('/auth/roles/:roleId', rolesController.getById); app.post('/auth/roles', rolesController.create); app.put('/auth/roles/:roleId', rolesController.update); app.delete('/auth/roles/:roleId', rolesController.delete); app.get('/auth/resources/getall', resourcesController.getAll); app.get('/auth/resources/:resourceId', resourcesController.getById); app.post('/auth/resources', resourcesController.create); app.put('/auth/resources/:resourceId', resourcesController.update); app.delete('/auth/resources/:resourceId', resourcesController.delete); }; });