Skip to content

Latest commit

History

12 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

loopback-custom-roles

Loopback 3 custom roles or security

To use a custom role you can created a custom tables to manage this:

In my case I use this tables:

  • usuario - (Table of users)
  • usuario-grupos - (Table of users asociate a any groups)
  • grupos - (It contains any models to acces)
  • modelos - (Models who can acces by a group)
  • permisos - (Permisions for models)

For all models I have in the acl this:

"acls": [
{
"principalType": "ROLE",
"principalId": "$everyone",
"permission": "ALLOW",
"property": "find"
},
{
"principalType": "ROLE",
"principalId": "$everyone",
"permission": "ALLOW",
"property": "prototype_get_accessTokens"
},
{
"accessType": "EXECUTE",
"principalType": "ROLE",
"principalId": "$unauthenticated",
"permission": "DENY",
"property": "create"
},
{
"accessType": "EXECUTE",
"principalType": "ROLE",
"principalId": "$authenticated",
"permission": "DENY",
"property": "create"
},
{
"accessType": "EXECUTE",
"principalType": "ROLE",
"principalId": "admin",
"permission": "ALLOW",
"property": "create"
},
{
"accessType": "*",
"principalType": "ROLE",
"principalId": "$authenticated",
"permission": "ALLOW"
}
],

Basically I create the acl by the console like this:

Example of data in json of roles for one user:

[
{
"realm": null,
"username": "david",
"email": "david@doe.com",
"emailVerified": null,
"id": 3,
"usuario_grupos": [
{
"id": 1,
"id_usuario": 3,
"id_grupo": 1,
"grupos": [
{
"id": 1,
"nombre": "GRUPO_MOVIMIENTOS_ADMIN",
"descripcion": null,
"modelos": [
{
"id": 1,
"nombre": "movimientos",
"id_grupo": 1,
"permisos": [
{
"id": 1,
"nombre": "read",
"id_modelo": 1
},
{
"id": 2,
"nombre": "write",
"id_modelo": 1
},
{
"id": 3,
"nombre": "update",
"id_modelo": 1
},
{
"id": 4,
"nombre": "delete",
"id_modelo": 1
}
]
},
{
"id": 2,
"nombre": "cementerio",
"id_grupo": 1,
"permisos": [
{
"id": 10,
"nombre": "read",
"id_modelo": 2
},
{
"id": 11,
"nombre": "write",
"id_modelo": 2
},
{
"id": 12,
"nombre": "update",
"id_modelo": 2
},
{
"id": 13,
"nombre": "delete",
"id_modelo": 2
}
]
},
{
"id": 3,
"nombre": "difunto",
"id_grupo": 1,
"permisos": [
{
"id": 14,
"nombre": "read",
"id_modelo": 3
},
{
"id": 15,
"nombre": "write",
"id_modelo": 3
},
{
"id": 16,
"nombre": "update",
"id_modelo": 3
},
{
"id": 17,
"nombre": "delete",
"id_modelo": 3
}
]
},
{
"id": 4,
"nombre": "personas",
"id_grupo": 1,
"permisos": [
{
"id": 18,
"nombre": "read",
"id_modelo": 4
},
{
"id": 19,
"nombre": "write",
"id_modelo": 4
},
{
"id": 20,
"nombre": "update",
"id_modelo": 4
},
{
"id": 21,
"nombre": "delete",
"id_modelo": 4
}
]
}
]
}
]
}
]
}
]

Data for restrict the acces in one model:

'use strict';module.exports=function(Personas){varapp=require('../../server/server');varloopback=require('loopback');Personas.beforeRemote("*",function(context,unused,next){console.log(context);vartipo=context.req.method;varmetodo=context.methodString;// Obtenemos el usuario actualvaruserId=context.args.options.accessToken.userId;// Modelo de usuariosvarUsuarios=app.models.Usuarios;vardata=JSON.parse('{"where":{"id":'+userId+'},"include":{"usuario_grupos":{"grupos":{"modelos":"permisos"}}}}');Usuarios.find(data,function(err,user){if(err){console.log("err --> ",err);next(newError(err));}else{console.log("user --> ",user);varusuario=user[0].toJSON();vararrayDatosfinales=[];letnoNeg=usuario.usuario_grupos.filter(function(index){index.grupos.filter(function(index){index.modelos.filter(function(index){varjson={"nombre": index.nombre,"permisos": index.permisos,}arrayDatosfinales[index.nombre]=json;console.log(" --- "+JSON.stringify(index));})})});console.log(arrayDatosfinales);try{varcompararPermiso="";if(tipo==="GET"){compararPermiso="read";}elseif(tipo==="POST"){compararPermiso="create";}elseif(tipo==="PUT"){compararPermiso="update";}elseif(tipo==="DELETE"){compararPermiso="delete";}// Comprobamos si tenemos algun permisovarpermiso=arrayDatosfinales['movimientos'].permisos.filter(function(index){returnindex.nombre==compararPermiso;});console.log(permiso);if(permiso.length>0){next();}else{// without permisionsvarerror=newError("No dispones de los permisos suficientes");context.res.statusCode=403;next(error);}}catch(error){// without permisionsvarerror=newError("No dispones de los permisos suficientes");context.res.statusCode=403;next(error);}}});});};

Notes:

For all models I think you can use https://loopback.io/doc/en/lb3/Defining-middleware.html

:)

About

loopback custom roles or security

Resources

Stars

1 star

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors