Search code examples
node.jsloopbackjsstrongloop

How can I Add ACL rules at run time for all model?


I am trying to create acl rules at run-time for all models. I have form that contain ACL information Like:

id, 
model name,
property,
accesstype,
principalId, (here I am assign roldId from role table).
PrincipalType.

After submit the form, information will be stored in ACL table (DB: mysql). My question is how to get the data in mixin or boot scritpt or any and when will get acl data from acl table and how to assign to all model at runtime.

I am tried in mixin and boot script but I cant get clear idea.

In mixin file, how to get acl data and how to assing to all models..

I am realy confused because I dnt no when will push acl data in runtime for all model(like boot, mixin, operation hook).

Please give any ideas.

I want to like, In mixin or boot script or any.

Get all data from acl and assign to all models.

In mixin.// I don't know how to get acl data from database in mixin files. 
ACL.find(function(err, data)
{
    var acl = data;
});

// doing some iteration..

 Model.settings.acls.push(data);

Solution

  • By default ACL(base Class) collect and concatenate both static JSON acl rule and ACL Table data at run-time so It will work automatically.

    get Static ACL from Model.JSON ex: user.json

    ACL.getStaticACLs = function getStaticACLs(model, property) {
    var modelClass = loopback.findModel(model);
    var staticACLs = [];
    if (modelClass && modelClass.settings.acls) {
      modelClass.settings.acls.forEach(function(acl) {
        var prop = acl.property;
        // We support static ACL property with array of string values.
        if (Array.isArray(prop) && prop.indexOf(property) >= 0)
          prop = property;
        if (!prop || prop === ACL.ALL || property === prop) {
          staticACLs.push(new ACL({
            model: model,
            property: prop || ACL.ALL,
            principalType: acl.principalType,
            principalId: acl.principalId, // TODO: Should it be a name?
            accessType: acl.accessType || ACL.ALL,
            permission: acl.permission
          }));
        }
      });
    }
    var prop = modelClass && (
      // regular property
      modelClass.definition.properties[property] ||
      // relation/scope
      (modelClass._scopeMeta && modelClass._scopeMeta[property]) ||
      // static method
      modelClass[property] ||
      // prototype method
      modelClass.prototype[property]);
    if (prop && prop.acls) {
      prop.acls.forEach(function(acl) {
        staticACLs.push(new ACL({
          model: modelClass.modelName,
          property: property,
          principalType: acl.principalType,
          principalId: acl.principalId,
          accessType: acl.accessType,
          permission: acl.permission
        }));
      });
    }
    return staticACLs;
    

    };

    get ACL from ACL table(database)

    var self = this;
    var roleModel = registry.getModelByType(Role);
    this.find({where: {model: model.modelName, property: propertyQuery,
      accessType: accessTypeQuery}}, function(err, acls) {
      if (err) {
        if (callback) callback(err);
        return;
      }
      var inRoleTasks = [];
    
      acls = acls.concat(staticACLs);