Open bostondv opened 8 years ago
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();
});
}
});
};
Thanks, I'm using this aswell. Feels like there should be a better way to get around this.
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) {
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.
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!