Skip to content

Instantly share code, notes, and snippets.

@sayhicoelho
Created July 2, 2020 23:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save sayhicoelho/92a6ceddd0e5c9164c6aa45c61d4898c to your computer and use it in GitHub Desktop.
Save sayhicoelho/92a6ceddd0e5c9164c6aa45c61d4898c to your computer and use it in GitHub Desktop.
ACL with Nodejs and MongoDB.
const { Router } = require('express')
const ensureAuth = require('../middleware/ensureAuth')
const ensureHasPermissions = require('../middleware/ensureHasPermissions')
const bankController = require('../controllers/bankController')
const router = Router()
router.use('/', ensureAuth)
router.get('/', ensureHasPermissions('banks.read'), bankController.getAll)
router.get('/:id', ensureHasPermissions('banks.read'), bankController.getOne)
router.post('/', ensureHasPermissions('banks.create'), bankController.create)
router.patch('/:id', ensureHasPermissions('banks.update'), bankController.update)
router.delete('/:id', ensureHasPermissions('banks.delete'), bankController.delete)
module.exports = router
function handle(permissions) {
return function(req, res, next) {
if (req.user.superAdmin) {
return next()
} else if (req.user.role === null) {
return res.status(401).json({
message: 'Unauthorized.'
})
}
const splitted = permissions.split(',')
for (const permission of splitted) {
const [name, action] = permission.split('.')
if (req.user.role.permissions[name][action]) {
return next()
}
}
res.status(401).json({
message: 'Unauthorized.'
})
}
}
module.exports = handle
const { Schema, model } = require('mongoose')
const CRUDActions = {
create: {
type: Boolean,
default: false,
},
read: {
type: Boolean,
default: false,
},
update: {
type: Boolean,
default: false,
},
delete: {
type: Boolean,
default: false,
},
}
const ExampleActions = {
notify: {
type: Boolean,
default: false,
}
}
const RoleSchema = new Schema(
{
name: {
type: String,
required: true,
unique: true,
trim: true,
},
permissions: {
users: CRUDActions,
banks: CRUDActions,
example: ExampleActions,
}
},
{
timestamps: true,
toJSON: {
virtuals: true
}
}
)
RoleSchema.virtual('users', {
ref: 'User',
localField: '_id',
foreignField: 'roleId',
justOne: false,
})
module.exports = model('Role', RoleSchema)
const { Schema, model } = require('mongoose')
const UserSchema = new Schema(
{
roleId: {
type: Schema.Types.ObjectId,
required: false,
},
superAdmin: {
type: Boolean,
required: false,
},
name: {
type: String,
required: true,
trim: true,
},
email: {
type: String,
required: true,
trim: true,
unique: true,
lowercase: true,
},
password: {
type: String,
required: true,
select: false,
}
},
{
timestamps: true,
toJSON: {
virtuals: true
}
}
)
UserSchema.virtual('role', {
ref: 'Role',
localField: 'roleId',
foreignField: '_id',
justOne: true,
})
module.exports = model('User', UserSchema)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment