├── app └── components │ ├── core │ ├── controllers │ │ └── core.controller.js │ └── routes │ │ └── core.routes.js │ ├── users │ ├── routes │ │ ├── authenticate.routes.js │ │ └── users.routes.js │ ├── models │ │ └── user.models.js │ ├── policies │ │ └── users.policy.js │ └── controllers │ │ ├── authenticate.controller.js │ │ └── users.controller.js │ ├── breweries │ ├── models │ │ └── brewery.models.js │ ├── routes │ │ └── breweries.routes.js │ ├── policies │ │ └── breweries.policy.js │ └── controllers │ │ └── breweries.controller.js │ └── beers │ ├── models │ └── beer.models.js │ ├── routes │ └── beers.routes.js │ ├── policies │ └── beers.policy.js │ └── controllers │ └── beers.controller.js ├── config ├── env │ ├── all.js │ ├── production.js │ └── development.js ├── config.js └── express.js ├── server.js ├── .gitignore ├── package.json └── README.md /app/components/core/controllers/core.controller.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.index = function(req, res) { 4 | res.json({ message: 'API Simple' }); 5 | }; 6 | -------------------------------------------------------------------------------- /config/env/all.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | app: { 5 | title: 'API NodeJS Simple Token Auth - Component-based architecture', 6 | }, 7 | port: process.env.PORT || 3000 8 | }; 9 | -------------------------------------------------------------------------------- /app/components/core/routes/core.routes.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function(app) { 4 | var core = require('../controllers/core.controller'); 5 | app.route('/').get(core.index); 6 | }; 7 | -------------------------------------------------------------------------------- /config/env/production.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | db: 'mongodb://localhost/api-nodejs-token-auth', 5 | app: { 6 | title: 'API NodeJS Simple Token Auth - Component-based architecture' 7 | } 8 | }; 9 | -------------------------------------------------------------------------------- /config/env/development.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | db: 'mongodb://localhost/api-nodejs-token-auth-dev', 5 | app: { 6 | title: 'API NodeJS Simple Token Auth - Component-based architecture - development' 7 | } 8 | }; 9 | -------------------------------------------------------------------------------- /app/components/users/routes/authenticate.routes.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function(api) { 4 | var authenticate = require('../controllers/authenticate.controller'); 5 | api.route('/setup').get(authenticate.setup); 6 | api.route('/signin').post(authenticate.signin); 7 | }; 8 | -------------------------------------------------------------------------------- /app/components/breweries/models/brewery.models.js: -------------------------------------------------------------------------------- 1 | var mongoose = require('mongoose'), 2 | Schema = mongoose.Schema; 3 | 4 | var BrewerySchema = new Schema({ 5 | name: { 6 | type: String, 7 | unique: true, 8 | required: true 9 | }, 10 | description: { 11 | type: String, 12 | }, 13 | user: { 14 | type: Schema.ObjectId, 15 | ref: 'User' 16 | } 17 | }); 18 | 19 | module.exports = mongoose.model('Brewery', BrewerySchema); 20 | -------------------------------------------------------------------------------- /app/components/beers/models/beer.models.js: -------------------------------------------------------------------------------- 1 | var mongoose = require('mongoose'), 2 | Schema = mongoose.Schema; 3 | 4 | var BeerSchema = new Schema({ 5 | name: { 6 | type: String, 7 | unique: true, 8 | required: true 9 | }, 10 | description: { 11 | type: String, 12 | }, 13 | brewery: { 14 | type: Schema.ObjectId, 15 | ref: 'Brewery' 16 | }, 17 | user: { 18 | type: Schema.ObjectId, 19 | ref: 'User' 20 | } 21 | }); 22 | 23 | module.exports = mongoose.model('Beer', BeerSchema); 24 | -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var config = require('./config/config'), 4 | mongoose = require('mongoose'), 5 | chalk = require('chalk'); 6 | 7 | var db = mongoose.connect(config.db, function(err) { 8 | if (err) { 9 | console.error(chalk.red('Could not connect to MongoDB!')); 10 | console.log(chalk.red(err)); 11 | } 12 | }); 13 | 14 | var app = require('./config/express')(db); 15 | 16 | app.listen(config.port); 17 | 18 | exports = module.exports = app; 19 | 20 | console.log('Application started on port ' + config.port); 21 | -------------------------------------------------------------------------------- /app/components/beers/routes/beers.routes.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var beersPolicy = require('../policies/beers.policy'); 4 | 5 | module.exports = function(api) { 6 | var beers = require('../controllers/beers.controller'); 7 | 8 | api.route('/beers') 9 | .all(beersPolicy.isAllowed) 10 | .get(beers.findAll) 11 | .post(beers.create); 12 | 13 | api.route('/beers/:beerId') 14 | .all(beersPolicy.isAllowed) 15 | .get(beers.find) 16 | .put(beers.update) 17 | .delete(beers.delete); 18 | 19 | api.param('beerId', beers.beerByID); 20 | }; 21 | -------------------------------------------------------------------------------- /app/components/users/routes/users.routes.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var usersPolicy = require('../policies/users.policy'); 4 | 5 | module.exports = function(api) { 6 | var users = require('../controllers/users.controller'); 7 | 8 | api.route('/users') 9 | .all(usersPolicy.isAllowed) 10 | .get(users.findAll) 11 | .post(users.create); 12 | 13 | api.route('/users/:userId') 14 | .all(usersPolicy.isAllowed) 15 | .get(users.find) 16 | .put(users.update) 17 | .delete(users.delete); 18 | 19 | api.param('userId', users.userByID); 20 | }; 21 | -------------------------------------------------------------------------------- /app/components/breweries/routes/breweries.routes.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var breweriesPolicy = require('../policies/breweries.policy'); 4 | 5 | module.exports = function(api) { 6 | var breweries = require('../controllers/breweries.controller'); 7 | 8 | api.route('/breweries') 9 | .all(breweriesPolicy.isAllowed) 10 | .get(breweries.findAll) 11 | .post(breweries.create); 12 | 13 | api.route('/breweries/:breweryId') 14 | .all(breweriesPolicy.isAllowed) 15 | .get(breweries.find) 16 | .put(breweries.update) 17 | .delete(breweries.delete); 18 | 19 | api.param('breweryId', breweries.breweryByID); 20 | }; 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # node-waf configuration 20 | .lock-wscript 21 | 22 | # Compiled binary addons (http://nodejs.org/api/addons.html) 23 | build/Release 24 | 25 | # Dependency directory 26 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 27 | node_modules 28 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "api-nodejs-token-auth", 3 | "version": "1.0.0", 4 | "description": "API NodeJS Simple Token Auth - Component-based architecture", 5 | "main": "server.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "NODE_ENV=development nodemon server.js" 9 | }, 10 | "author": "Gui Seek", 11 | "license": "THE BEER-WARE LICENSE", 12 | "dependencies": { 13 | "acl": "^0.4.9", 14 | "bcryptjs": "^2.3.0", 15 | "body-parser": "^1.14.2", 16 | "chalk": "^1.1.1", 17 | "cors": "^2.7.1", 18 | "express": "^4.13.3", 19 | "glob": "^6.0.2", 20 | "jsonwebtoken": "^5.4.1", 21 | "lodash": "^3.10.1", 22 | "mongoose": "^4.3.4", 23 | "morgan": "^1.6.1" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # API NodeJS Simple Token Auth and ACL - Component-based architecture 2 | 3 | 4 | ## Run 5 | Install node modules: 6 | ``` 7 | npm install 8 | ``` 9 | 10 | After installing node modules, the start (I hope the mongodb is running): 11 | ``` 12 | npm start 13 | ``` 14 | 15 | Now go to the [/api/setup](http://localhost:3000/api/setup) to create the user *demo*, admin role as default. 16 | 17 | Retrieve a token accessing via POST [/api/signin](http://localhost:3000/api/signin) with a body raw json: 18 | ```json 19 | {"username": "demo", "password": "demo"} 20 | ``` 21 | 22 | Use the recovered token in the header of the next requests with *Authorization*. 23 | 24 | Go to [/api/users](http://localhost:3000/api/users) with GET method to list users (make sure the Authorization header with token). 25 | 26 | This seed has the complete CRUD, using the methods GET, POST, PUT and DELETE, to list, create, change and remove users, respectively. 27 | 28 | Enjoy and collaborate with the project. :) 29 | 30 | [About me](http://guiseek.github.io) 31 | -------------------------------------------------------------------------------- /config/config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var _ = require('lodash'), 4 | glob = require('glob'); 5 | 6 | module.exports = _.extend( 7 | require('./env/all'), 8 | require('./env/' + process.env.NODE_ENV) || {} 9 | ); 10 | 11 | module.exports.getGlobbedFiles = function(globPatterns, removeRoot) { 12 | var _this = this; 13 | 14 | var urlRegex = new RegExp('^(?:[a-z]+:)?\/\/', 'i'); 15 | 16 | var output = []; 17 | 18 | if (_.isArray(globPatterns)) { 19 | globPatterns.forEach(function(globPattern) { 20 | output = _.union(output, _this.getGlobbedFiles(globPattern, removeRoot)); 21 | }); 22 | } else if (_.isString(globPatterns)) { 23 | if (urlRegex.test(globPatterns)) { 24 | output.push(globPatterns); 25 | } else { 26 | var files = glob.sync(globPatterns); 27 | if (removeRoot) { 28 | files = files.map(function(file) { 29 | return file.replace(removeRoot, ''); 30 | }); 31 | } 32 | output = _.union(output, files); 33 | } 34 | } 35 | 36 | return output; 37 | }; 38 | -------------------------------------------------------------------------------- /app/components/users/models/user.models.js: -------------------------------------------------------------------------------- 1 | var mongoose = require('mongoose'), 2 | bcrypt = require('bcryptjs'), 3 | Schema = mongoose.Schema; 4 | 5 | var UserSchema = new Schema({ 6 | name: { 7 | type: String, 8 | unique: true, 9 | required: true 10 | }, 11 | username: { 12 | type: String, 13 | unique: true, 14 | required: true 15 | }, 16 | password: { 17 | type: String, 18 | required: true 19 | }, 20 | email: String, 21 | roles: { 22 | type: Array, 23 | default: ['user'] 24 | } 25 | }); 26 | 27 | UserSchema.pre('save', function(next) { 28 | var user = this; 29 | if (this.isModified('password') || this.isNew) { 30 | bcrypt.genSalt(10, function(err, salt) { 31 | if (err) { 32 | return next(err); 33 | } 34 | bcrypt.hash(user.password, salt, function(err, hash) { 35 | if (err) { 36 | return next(err); 37 | } 38 | user.password = hash; 39 | next(); 40 | }); 41 | }); 42 | } else { 43 | return next(); 44 | } 45 | }); 46 | 47 | UserSchema.methods.comparePassword = function(passw, cb) { 48 | bcrypt.compare(passw, this.password, function(err, isMatch) { 49 | if (err) { 50 | return cb(err); 51 | } 52 | cb(null, isMatch); 53 | }); 54 | }; 55 | 56 | module.exports = mongoose.model('User', UserSchema); 57 | -------------------------------------------------------------------------------- /app/components/users/policies/users.policy.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var acl = require('acl'); 4 | 5 | acl = new acl(new acl.memoryBackend()); 6 | 7 | exports.invokeRolesPolicies = function () { 8 | acl.allow([{ 9 | roles: ['admin'], 10 | allows: [{ 11 | resources: '/users', 12 | permissions: '*' 13 | }, { 14 | resources: '/users/:userId', 15 | permissions: '*' 16 | }, { 17 | resources: '/users/search/:query', 18 | permissions: '*' 19 | }] 20 | }, { 21 | roles: ['user'], 22 | allows: [{ 23 | resources: '/users', 24 | permissions: ['get','post'] 25 | }, { 26 | resources: '/users/:userId', 27 | permissions: ['get','put','delete'] 28 | }, { 29 | resources: '/api/users/search/:query', 30 | permissions: ['get'] 31 | }] 32 | }]); 33 | }; 34 | 35 | exports.isAllowed = function (req, res, next) { 36 | var roles = (req.decoded) ? req.decoded.roles : ['guest']; 37 | // if (req.decoded._id == req.user._id) { 38 | // next(); 39 | // } 40 | 41 | acl.areAnyRolesAllowed(roles, req.route.path, req.method.toLowerCase(), function (err, isAllowed) { 42 | if (err) { 43 | res.status(500).json({message: 'Unexpected authorization error'}); 44 | } else { 45 | if (isAllowed) { 46 | next(); 47 | } else { 48 | res.status(403).json({ 49 | message: 'User is not authorized' 50 | }); 51 | } 52 | } 53 | }); 54 | }; 55 | -------------------------------------------------------------------------------- /app/components/beers/policies/beers.policy.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var acl = require('acl'); 4 | 5 | acl = new acl(new acl.memoryBackend()); 6 | 7 | exports.invokeRolesPolicies = function () { 8 | acl.allow([{ 9 | roles: ['admin'], 10 | allows: [{ 11 | resources: '/beers', 12 | permissions: '*' 13 | }, { 14 | resources: '/beers/:beerId', 15 | permissions: '*' 16 | }, { 17 | resources: '/beers/search/:query', 18 | permissions: '*' 19 | }] 20 | }, { 21 | roles: ['user'], 22 | allows: [{ 23 | resources: '/beers', 24 | permissions: ['get','post'] 25 | }, { 26 | resources: '/beers/:beerId', 27 | permissions: ['get','put','delete'] 28 | }, { 29 | resources: '/api/beers/search/:query', 30 | permissions: ['get'] 31 | }] 32 | }]); 33 | }; 34 | 35 | exports.isAllowed = function (req, res, next) { 36 | var roles = (req.decoded) ? req.decoded.roles : ['guest']; 37 | // if (req.decoded._id == req.beer.user._id) { 38 | // next(); 39 | // } 40 | 41 | console.log(roles); 42 | acl.areAnyRolesAllowed(roles, req.route.path, req.method.toLowerCase(), function (err, isAllowed) { 43 | if (err) { 44 | res.status(500).json({message: 'Unexpected authorization error'}); 45 | } else { 46 | if (isAllowed) { 47 | next(); 48 | } else { 49 | res.status(403).json({ 50 | message: 'Beer is not authorized' 51 | }); 52 | } 53 | } 54 | }); 55 | }; 56 | -------------------------------------------------------------------------------- /app/components/breweries/policies/breweries.policy.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var acl = require('acl'); 4 | 5 | acl = new acl(new acl.memoryBackend()); 6 | 7 | exports.invokeRolesPolicies = function () { 8 | acl.allow([{ 9 | roles: ['admin'], 10 | allows: [{ 11 | resources: '/breweries', 12 | permissions: '*' 13 | }, { 14 | resources: '/breweries/:breweryId', 15 | permissions: '*' 16 | }, { 17 | resources: '/breweries/search/:query', 18 | permissions: '*' 19 | }] 20 | }, { 21 | roles: ['user'], 22 | allows: [{ 23 | resources: '/breweries', 24 | permissions: ['get','post'] 25 | }, { 26 | resources: '/breweries/:breweryId', 27 | permissions: ['get','put','delete'] 28 | }, { 29 | resources: '/api/breweries/search/:query', 30 | permissions: ['get'] 31 | }] 32 | }]); 33 | }; 34 | 35 | exports.isAllowed = function (req, res, next) { 36 | var roles = (req.decoded) ? req.decoded.roles : ['guest']; 37 | // if (req.decoded._id == req.brewery.user._id) { 38 | // next(); 39 | // } 40 | 41 | console.log(roles); 42 | acl.areAnyRolesAllowed(roles, req.route.path, req.method.toLowerCase(), function (err, isAllowed) { 43 | if (err) { 44 | res.status(500).json({message: 'Unexpected authorization error'}); 45 | } else { 46 | if (isAllowed) { 47 | next(); 48 | } else { 49 | res.status(403).json({ 50 | message: 'Brewery is not authorized' 51 | }); 52 | } 53 | } 54 | }); 55 | }; 56 | -------------------------------------------------------------------------------- /config/express.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var express = require('express'), 4 | morgan = require('morgan'), 5 | bodyParser = require('body-parser'), 6 | config = require('./config'), 7 | path = require('path'), 8 | cors = require('cors'); 9 | 10 | module.exports = function(db) { 11 | var app = express(); 12 | 13 | app.set('showStackError', true); 14 | 15 | if (process.env.NODE_ENV === 'development') { 16 | app.use(morgan('dev')); 17 | } 18 | 19 | app.use(bodyParser.urlencoded({ 20 | extended: true 21 | })); 22 | 23 | app.use(bodyParser.json()); 24 | app.use(cors()); 25 | 26 | config.getGlobbedFiles('./app/components/*/models/*.js').forEach(function(modelPath) { 27 | require(path.resolve(modelPath)); 28 | }); 29 | 30 | config.getGlobbedFiles('./app/components/*/policies/*.js').forEach(function(policyPath) { 31 | require(path.resolve(policyPath)).invokeRolesPolicies(); 32 | }); 33 | 34 | var api = express.Router(); 35 | 36 | require(path.resolve('./app/components/users/routes/authenticate.routes'))(api); 37 | 38 | var authenticate = require(path.resolve('./app/components/users/controllers/authenticate.controller')); 39 | api.use(authenticate.verify); 40 | 41 | config.getGlobbedFiles('./app/components/*/routes/*.js').forEach(function(routePath) { 42 | require(path.resolve(routePath))(api); 43 | }); 44 | 45 | app.use('/api', api); 46 | 47 | app.use(function(err, req, res, next) { 48 | if (!err) return next(); 49 | 50 | console.error(err.stack); 51 | 52 | res.status(500).json({ 53 | error: err.stack 54 | }); 55 | }); 56 | 57 | // app.use(function(req, res) { 58 | // res.status(404).json({ 59 | // url: req.originalUrl, 60 | // error: 'Not Found' 61 | // }); 62 | // }); 63 | 64 | return app; 65 | }; 66 | -------------------------------------------------------------------------------- /app/components/users/controllers/authenticate.controller.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var jwt = require('jsonwebtoken'), 4 | User = require('../models/user.models'); 5 | 6 | var secret = 'api-simple'; 7 | 8 | exports.setup = function(req, res) { 9 | var demo = new User({ 10 | name: 'Demo', 11 | username: 'demo', 12 | password: 'demo', 13 | email: 'demo@demo.com', 14 | roles: ['admin'] 15 | }); 16 | demo.save(function(err) { 17 | if (err) throw err; 18 | res.status(200).json({ message: 'User saved successfully', user: demo }); 19 | }); 20 | }; 21 | exports.signin = function(req, res) { 22 | if (!req.body.username) { 23 | res.status(400).json({ message: 'Username required'}); 24 | return; 25 | } 26 | if (!req.body.password) { 27 | res.status(400).json({ message: 'Password required'}); 28 | return; 29 | } 30 | User.findOne({ 31 | username: req.body.username 32 | }, function(err, user) { 33 | if (err) { 34 | res.status(500).json({ message: err}); 35 | return; 36 | } 37 | if (!user) { 38 | res.status(401).json({ message: 'Authentication failed, try again.'}); 39 | return; 40 | } 41 | user.comparePassword(req.body.password, function(err, valid) { 42 | if (err) { 43 | res.status(500).json({ message: err}); 44 | return; 45 | } 46 | if (!valid) { 47 | res.status(401).json({ message: 'Authentication failed, try again.'}); 48 | return; 49 | } 50 | var token = jwt.sign(user, secret); 51 | res.status(200).json({ 52 | user: user, 53 | token: token, 54 | rememberme: req.body.rememberme 55 | }); 56 | }); 57 | }); 58 | }; 59 | exports.verify = function(req, res, next) { 60 | var token = req.body.token || req.params.token || req.headers['authorization']; 61 | if (token) { 62 | jwt.verify(token, secret, function(err, decoded) { 63 | if (err) { 64 | res.status(400).json({ message: 'Failed to authenticate token.' }); 65 | // return; 66 | } else { 67 | req.decoded = decoded._doc; 68 | next(); 69 | } 70 | }); 71 | } else { 72 | res.status(403).json({ 73 | message: 'No token provided.' 74 | }); 75 | } 76 | }; 77 | -------------------------------------------------------------------------------- /app/components/beers/controllers/beers.controller.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var mongoose = require('mongoose'), 4 | Beer = require('../models/beer.models'); 5 | 6 | exports.findAll = function (req, res) { 7 | Beer.find({}).populate('user').populate('brewery').exec(function (err, beers) { 8 | res.json(beers); 9 | }); 10 | }; 11 | exports.find = function (req, res) { 12 | res.json(req.beer); 13 | }; 14 | exports.create = function (req, res) { 15 | var beer = new Beer(req.body); 16 | 17 | beer.save(function (err) { 18 | if (err) { 19 | return res.status(400).json({ 20 | message: err 21 | }); 22 | } else { 23 | res.json({ 24 | message: 'Beer created successfully', 25 | beer: beer 26 | }); 27 | } 28 | }); 29 | }; 30 | exports.update = function (req, res) { 31 | console.log(req.beer); 32 | var beer = req.beer; 33 | beer.name = req.body.name; 34 | beer.description = req.body.description; 35 | beer.brewery = req.body.brewery; 36 | beer.user = req.body.user; 37 | 38 | beer.save(function (err) { 39 | if (err) { 40 | res.status(400).json({ 41 | message: err 42 | }); 43 | } else { 44 | res.json({ 45 | message: 'Beer updated successfully', 46 | beer: beer 47 | }); 48 | } 49 | }); 50 | }; 51 | exports.delete = function (req, res) { 52 | var beer = req.beer; 53 | 54 | beer.remove(function (err) { 55 | if (err) { 56 | res.status(400).json({ 57 | message: err 58 | }); 59 | } else { 60 | res.json({ 61 | message: 'Beer removed successfully', 62 | beer: beer 63 | }); 64 | } 65 | }); 66 | }; 67 | 68 | exports.beerByID = function (req, res, next, beerId) { 69 | if (!mongoose.Types.ObjectId.isValid(beerId)) { 70 | res.status(400).json({ 71 | message: 'Beer is invalid' 72 | }); 73 | } 74 | Beer.findById(beerId).populate('user').populate('brewery').exec(function (err, beer) { 75 | if (err) return next(err); 76 | if (!beer) return next(new Error('Failed to load Beer ' + beerId)); 77 | req.beer = beer; 78 | next(); 79 | }); 80 | }; 81 | -------------------------------------------------------------------------------- /app/components/breweries/controllers/breweries.controller.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var mongoose = require('mongoose'), 4 | Brewery = require('../models/brewery.models'); 5 | 6 | exports.findAll = function (req, res) { 7 | Brewery.find({}).populate('user').exec(function (err, breweries) { 8 | res.json(breweries); 9 | }); 10 | }; 11 | exports.find = function (req, res) { 12 | res.json(req.brewery); 13 | }; 14 | exports.create = function (req, res) { 15 | var brewery = new Brewery(req.body); 16 | 17 | brewery.save(function (err) { 18 | if (err) { 19 | return res.status(400).json({ 20 | message: err 21 | }); 22 | } else { 23 | res.json({ 24 | message: 'Brewery created successfully', 25 | brewery: brewery 26 | }); 27 | } 28 | }); 29 | }; 30 | exports.update = function (req, res) { 31 | console.log(req.brewery); 32 | var brewery = req.brewery; 33 | brewery.name = req.body.name; 34 | brewery.description = req.body.description; 35 | brewery.user = req.body.user; 36 | 37 | brewery.save(function (err) { 38 | if (err) { 39 | res.status(400).json({ 40 | message: err 41 | }); 42 | } else { 43 | res.json({ 44 | message: 'Brewery updated successfully', 45 | brewery: brewery 46 | }); 47 | } 48 | }); 49 | }; 50 | exports.delete = function (req, res) { 51 | var brewery = req.brewery; 52 | 53 | brewery.remove(function (err) { 54 | if (err) { 55 | res.status(400).json({ 56 | message: err 57 | }); 58 | } else { 59 | res.json({ 60 | message: 'Brewery removed successfully', 61 | brewery: brewery 62 | }); 63 | } 64 | }); 65 | }; 66 | 67 | exports.breweryByID = function (req, res, next, breweryId) { 68 | if (!mongoose.Types.ObjectId.isValid(breweryId)) { 69 | res.status(400).json({ 70 | message: 'Brewery is invalid' 71 | }); 72 | } 73 | Brewery.findById(breweryId).populate('user').exec(function (err, brewery) { 74 | if (err) return next(err); 75 | if (!brewery) return next(new Error('Failed to load Brewery ' + breweryId)); 76 | req.brewery = brewery; 77 | next(); 78 | }); 79 | }; 80 | -------------------------------------------------------------------------------- /app/components/users/controllers/users.controller.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var mongoose = require('mongoose'), 4 | User = require('../models/user.models'); 5 | 6 | exports.findAll = function (req, res) { 7 | User.find({}, '-password', function (err, users) { 8 | res.json(users); 9 | }); 10 | }; 11 | exports.find = function (req, res) { 12 | res.json(req.user); 13 | }; 14 | exports.create = function (req, res) { 15 | var user = req.body; 16 | if (user.roles.length == 0) { 17 | user.roles = ['user']; 18 | } 19 | var user = new User(user); 20 | 21 | user.save(function (err) { 22 | if (err) { 23 | return res.status(400).json({ 24 | message: err 25 | }); 26 | } else { 27 | res.json({ 28 | message: 'User created successfully', 29 | user: user 30 | }); 31 | } 32 | }); 33 | }; 34 | exports.update = function (req, res) { 35 | var user = req.user; 36 | user.name = req.body.name; 37 | user.username = req.body.username; 38 | user.email = req.body.email; 39 | user.roles = req.body.roles; 40 | if (req.body.password) { 41 | user.password = req.body.password; 42 | } 43 | 44 | user.save(function (err) { 45 | if (err) { 46 | res.status(400).json({ 47 | message: err 48 | }); 49 | } else { 50 | res.json({ 51 | message: 'User updated successfully', 52 | user: user 53 | }); 54 | } 55 | }); 56 | }; 57 | exports.delete = function (req, res) { 58 | var user = req.user; 59 | 60 | user.remove(function (err) { 61 | if (err) { 62 | res.status(400).json({ 63 | message: err 64 | }); 65 | } else { 66 | res.json({ 67 | message: 'User removed successfully', 68 | user: user 69 | }); 70 | } 71 | }); 72 | }; 73 | 74 | exports.userByID = function (req, res, next, userId) { 75 | if (!mongoose.Types.ObjectId.isValid(userId)) { 76 | res.status(400).json({ 77 | message: 'User is invalid' 78 | }); 79 | } 80 | User.findById(userId, function (err, user) { 81 | if (err) return next(err); 82 | if (!user) return next(new Error('Failed to load Brewery ' + userId)); 83 | req.user = user; 84 | next(); 85 | }); 86 | }; 87 | --------------------------------------------------------------------------------