Skip to content

Instantly share code, notes, and snippets.

@leftclickben
Forked from spencermefford/0-model-override.js
Last active July 4, 2018 00:58
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save leftclickben/aa3cf418312c0ffcc547 to your computer and use it in GitHub Desktop.
Save leftclickben/aa3cf418312c0ffcc547 to your computer and use it in GitHub Desktop.
An alternative to extending Loopback's built-in models: use a boot script to enhance the built-in model
(function () {
'use strict';
// Relevant resource: https://gist.github.com/spencermefford/bc73812f216e0e254ad1
module.exports = function (server, callback) {
var ACL = server.models.ACL,
User = server.models.User,
Role = server.models.Role,
RoleMapping = server.models.RoleMapping;
// Ensure that the `administrator` role has access to list users.
ACL.findOrCreate(
{
model: 'User',
principalType: 'ROLE',
principalId: 'administrator',
property: '*',
accessType: '*',
permission: 'ALLOW'
},
callback
);
// Relate Users to Roles so that they can be queried using the `include` filter.
User.hasMany(
Role,
{
through: RoleMapping,
foreignKey: 'principalId'
}
);
// Remove unwanted remote methods that we are overriding
User.disableRemoteMethod('__create__roles', false);
User.disableRemoteMethod('__delete__roles', false);
User.disableRemoteMethod('__link__roles', false);
User.disableRemoteMethod('__unlink__roles', false);
User.disableRemoteMethod('__findById__roles', false);
User.disableRemoteMethod('__updateById__roles', false);
User.disableRemoteMethod('__destroyById__roles', false);
User.disableRemoteMethod('__exists__roles', false);
/**
* Add the user to the given role by name.
*
* @param {string} roleName
* @param {Function} callback
*/
User.prototype.addToRole = function(roleName, callback) {
var error, userId = this.id;
Role.findOne(
{
where: { name: roleName }
},
function(err, role) {
if (err) {
return callback(err);
}
if (!role) {
error = new Error('Role ' + roleName + ' not found.');
error['http_code'] = 404;
return callback(error);
}
RoleMapping.findOne(
{
where: {
principalId: userId,
roleId: role.id
}
},
function(err, roleMapping) {
if (err) {
return callback(err);
}
if (roleMapping) {
return callback();
}
role.principals.create(
{
principalType: RoleMapping.USER,
principalId: userId
},
callback
);
}
);
}
);
};
User.remoteMethod(
'addToRole',
{
description: 'Add User to the named role',
accessType: 'WRITE',
isStatic: false,
accepts: [
{
arg: 'roleName',
type: 'string',
required: true,
description: 'Name of the role to add.',
http: {
source: 'path'
}
}
],
http: {
path: '/roles/:roleName',
verb: 'put'
}
}
);
/**
* Remove the user from the given role by name.
*
* @param {string} roleName
* @param {Function} callback
*/
User.prototype.removeFromRole = function(roleName, callback) {
var error, userId = this.id;
Role.findOne(
{
where: { name: roleName }
},
function(err, role) {
if (err) {
return callback(err);
}
if (!role) {
error = new Error('Role ' + roleName + ' not found.');
error['http_code'] = 404;
return callback(error);
}
RoleMapping.findOne(
{
where: {
principalId: userId,
roleId: role.id
}
},
function(err, roleMapping) {
if (err) {
return callback(err);
}
if (!roleMapping) {
return callback();
}
roleMapping.destroy(callback);
}
);
}
);
};
User.remoteMethod(
'removeFromRole',
{
description: 'Remove User to the named role',
accessType: 'WRITE',
isStatic: false,
accepts: [
{
arg: 'roleName',
type: 'string',
required: true,
description: 'Name of the role to remove.',
http: {
source: 'path'
}
}
],
http: {
path: '/roles/:roleName',
verb: 'delete'
}
}
);
};
}());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment