Open intervalia opened 4 years ago
@intervalia Thanks for posting! We'll take a look as soon as possible.
In the mean time, there are a few ways you can help speed things along:
Please remember: never post in a public forum if you believe you've found a genuine security vulnerability. Instead, disclose it responsibly.
For help with questions about Sails, click here.
@intervalia AFAIK there is no support for expressions when setting policies for controllers/routes. So instead of:
'/api/dogs': 'inRole("dogs")'
you'd need to define a separate policy, e.g. /api/policies/inDogsRole.js
:
module.exports = (req, res, next) => {
if (req.user && req.user.inRole('dogs')) {
next();
}
res.status(403).json({message: `No access to the endpoint ${req.path}` });
};
and reference it like so:
'/api/dogs': 'inDogsRole'
Obviously you could create a shared library for the generic inRole(role)
, but still a little fiddly.
I understand your way of doing things but we have several endpoints that can take one of several roles. So we need to be able to define these roles in a group (Array) And your current system makes that difficult.
We need it to "pass" if the user has ANY of the roles specified. And trying to create a function for every combination is unreasonable.
What I would really like is the ability to do this:
In the file file /api/policies/inRole.js:
module.exports = (roles) => {
if (!Array.isArray(roles)) {
roles = [roles];
}
return (req, res, next) => {
if (req.user && req.user.inRole(roles)) {
next();
}
res.status(403).json({message: `No access to the endpoint ${req.path}` });
};
}
And in the file config/policies.js:
module.exports.policies = {
'/api/dogs': 'inRole(["dogs","cats","birds"])'
};
I agree this would be a useful improvement to how sails handles policies.
Looking at the source code at https://github.com/balderdashy/sails/blob/master/lib/hooks/policies/index.js, you might achieve what you want by assigning functions directly in the policy mapping, e.g.
module.exports.policies = {
'mycontroller/action': (req, res, next) =>
hasAnyRole(req, res, next, 'dog', 'cat', 'bird'),
...
};
function hasAnyRole(.. // implement role lookup and confirmation as appropriate
These functions are almost certainly ExpressJS middleware (https://expressjs.com/en/guide/writing-middleware.html).
You could then clean up the policy definitions by generating the policy functions themselves:
module.exports.policies = {
'mycontroller/action': hasAnyRole('dog', 'cat', 'bird'),
...
};
function hasAnyRole(...roles) {
return (req, res, next) => _hasAnyRole(req, res, next, ...roles),
}
function _hasAnyRole(.. // implement role lookup and confirmation as appropriate
I've made an example project at https://github.com/alxndrsn/sails-function-based-policies, so you can see what this might look like. Policies are defined in https://github.com/alxndrsn/sails-function-based-policies/blob/master/config/policies.js. Note that this example uses client-provided headers in place of roles retrieved on the server-side.
Reading https://sailsjs.com/documentation/concepts/policies, applying functions as policies like this doesn't seem to be a documented feature. OTOH this is a reasonably safe bet, as according to the commit history it was implemented in 2016. Maybe one of the sails team can tell us how dependable this feature is for future sails versions.
Hey, @intervalia!
@alxndrsn is correct in saying that policies don't currently allow the passing in of dynamic data to be evaluated and verified. When we have a situation like yours, we either create multiple policies to cover our various permission cases, or—where permissions vary a great deal—we handle permissions verification in the action itself.
As for assigning functions in the policy mapping, since this isn't a documented feature, we can't make any guarantees regarding its longevity as a solution.
FYI: I am no longer on this project and have no way of validating if this is working or not. I still think it would be a good feature. Others will have to validate if it works.
For anyone coming to this issue, you may want to take a look at https://github.com/luislobo/sails-hook-rbac.
Node version: 10.15.- sails: ^1.2.3, sails-hook-orm: ^2.1.1, sails-hook-sockets: ^2.0.0, sails-mysql: ^1.0.1 Development environment
Any clue about this Error:
I have a file
/api/policies/inRole.js
that looks like this:And in the file
config/policies.js
I have this:I don't understand what I am doing wrong that would produce this error.