-
Notifications
You must be signed in to change notification settings - Fork 181
getGrants of specific role #62
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
Comments
This is not specific to AccessControl.js. You should never expose grants / policies to client side. You should handle the request and grant/deny access on server side. And if granted; filter data if needed (using |
@onury Reply please |
Currently there is no built-in way to get compiled grants with resource-attributes for a role, all at once. I'm marking this as a feature request. For now you can use this function: const actions = ['create', 'read', 'update', 'delete'];
const possessions = ['Any', 'Own'];
function getCompiledGrantsOf(role) {
const compGrants = {};
const can = ac.can(role);
let permission;
ac.getResources().forEach(resource => {
actions.forEach(act => {
possessions.forEach(pos => {
permission = can[act + pos](resource);
if (permission.granted) {
compGrants[resource] = compGrants[resource] || {};
compGrants[resource][`${act}:${pos.toLowerCase()}`] = permission.attributes.concat();
}
});
});
});
return compGrants;
} You can also:
// Let's say menu is a resource with attributes:
// home, profile, videos, accounts
ac.grant('guest').read('menu', ['home'])
.grant('user').read('menu', ['home', 'profile', 'videos'])
.grant('admin').read('menu', ['*']);
// checking and filtering:
const menuItems = ['home', 'profile', 'videos', 'accounts'];
const permission = ac.can(role).read('menu');
if (permission.granted) {
const attrs = permission.attributes;
// instead of permission#filter we'll use Array#filter
if (attrs.length === 1 && attrs[0] === '*') return menuItems.concat();
return menuItems.filter(m => attrs.indexOf(m) >= 0)
} EDIT: filtering part above feels awkward. I'll update this later.
// Let's say menu items are:
// Home, My Profile, Edit Profile, My Videos, All Videos
// on server-side
function getGrantedMenuItemsOf(role) {
const menuItems = ['Home'];
if (!role) return menuItems;
const can = ac.can(role);
if (can.readOwn('profile').granted) menuItems.push('My Profile');
if (can.updateOwn('profile').granted) menuItems.push('Edit Profile');
if (can.readAny('video').granted) {
menuItems.push('My Videos');
menuItems.push('All Videos');
} else if (can.readOwn('video').granted) {
menuItems.push('My Videos');
}
return menuItems;
}
// Bind this to an API endpoint and fetch from client-side. e.g.:
getGrantedMenuItemsOf(req.user.role); Note: These are all quick thoughts. Since I have almost no knowledge of your application, possibly there might be better ways. This is a security concept so, you should carefully consider/improve/test, if you decide to implement. |
I don’t agree that you should not expose permissions. Your clients or users knows what they can do and what they can’t do anyway (because you documented this somewhere on the website). For example, on medium anonymous users can’t leave applause and it’s clear for everybody (because you just can’t do this on ui). So, what’s the difference whether you share permissions as JSON object or as human readable text or as UX? If you don’t share permissions, your clients will need to duplicate or even hardcode permission logic. Later it will be very hard to change. I consider it to be safe to share permissions with client for currently logged in user. Some time ago I wrote an article about this: https://medium.com/dailyjs/casl-and-cancan-permissions-sharing-between-ui-and-api-5f1fa8b4bec |
A good restful design requires to return 403 Forbidden status response for actions which are not allowed. So, anyway it’s quite easy to understand or get a list of permissions for a particular user credentials. Side note: I think the issue with permission sharing in this library exists because it relies on user roles and not on what user can do (e.g., create post, read post, leave comment). If you could share user actions instead of roles, it would not expose any internals of underlying permission logic |
I have use case similar to #31
I don't want expose all roles and action to client , just roles and actions that granted
In the following
If the client's role is
user
, the admin role is exposed tooThe text was updated successfully, but these errors were encountered: