Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bypass all access control for certain users #15

Open
bostondv opened this issue Sep 28, 2016 · 4 comments
Open

Bypass all access control for certain users #15

bostondv opened this issue Sep 28, 2016 · 4 comments

Comments

@bostondv
Copy link

Hi there, is there a way to bypass group access control for specific user(s) so they could access all content?

I've considered several ideas such as filtering all requests for particular users but haven't been able to get a working solution.

Any help would be appreciated!

@bostondv
Copy link
Author

FWIW I found a way but suspect it could be done better, especially the 2nd part below which feels like it would be best to prevent the query from being changed in the first place for admin users.

  1. Registered a role resolver with model ACL's to allow users with a truthy "admin" property on their user model.

  2. Observe access to all models and if admin user, remove any "where" queries that are added to the context by this component.

module.exports = function observeAdminQueries(server) {
  const settings = server.settings['loopback-component-access-groups'] || {};
  const foreignKey = settings.foreignKey || 'groupId';
  const groupModelName = settings.groupModel || 'Group';

  function isGroupModel(modelClass) {
    if (modelClass) {
      const groupModel = server.models[groupModelName];

      return modelClass === groupModel ||
        modelClass.prototype instanceof groupModel ||
        modelClass === groupModel;
    }
    return false;
  }

  Object.keys(server.models).forEach(modelName => {
    const Model = server.models[modelName];

    if (typeof Model.observe === 'function') {
      debug('Attaching access observer to %s', modelName);
      Model.observe('access', (ctx, next) => {
        const currentCtx = server.loopback.getCurrentContext();
        const currentUser = currentCtx && currentCtx.get('currentUser') || null;
        const Model = ctx.Model;
        const key = isGroupModel(Model) ? Model.getIdName() : foreignKey;

        if (currentUser && currentUser.admin) {
          debug('Current user is admin, clear group access query params');
          if (ctx.query.where && ctx.query.where[key]) {
            debug('original query: %o', JSON.stringify(ctx.query, null, 4));
            delete ctx.query.where[key];
            debug('modified query: %s', JSON.stringify(ctx.query, null, 4));
          }
        }

        return next();
      });
    }
  });
};

@Undrium
Copy link

Undrium commented Nov 24, 2016

Thanks, I'm using this aswell. Feels like there should be a better way to get around this.

@Undrium
Copy link

Undrium commented Nov 24, 2016

To elaborate some more on this hack, the query should only be modified if the "inq" is present and it contains an empty array. I'm sure there is more cases I've missed.

Quickfix:

if (ctx.query.where && ctx.query.where[key] && ctx.query.where[key].inq && ctx.query.where[key].inq.length == 0) {

@Undrium
Copy link

Undrium commented Nov 25, 2016

I do think the best solution for this would be to respect the ACL, if it does look like this:

{
      "accessType": "*",
      "principalType": "ROLE",
      "principalId": "$everyone",
      "permission": "DENY"
    },
    {
      "accessType": "*",
      "principalType": "ROLE",
      "principalId": "admin",
      "permission": "ALLOW"
    },
    {
      "accessType": "*",
      "principalType": "ROLE",
      "principalId": "$group:member",
      "permission": "ALLOW"
    }

Then definately users with the admin role should still have all access. The hack provided in this thread doesn't work on all cases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants