feathersjs-ecosystem / feathers-permissions Goto Github PK
View Code? Open in Web Editor NEWSimple role and service method permissions for Feathers
License: MIT License
Simple role and service method permissions for Feathers
License: MIT License
Having hasPermissions to use with iff
hook would be nice to have.
1- Add the setPermissions hook as a after create hook, and add a password remove hook as an after all hook.
exports.after = {
all: [hooks.remove('password')],
find: [],
get: [],
create: [
permissions.hooks.setPermissions({ permissions: ['users:*:id'] })
],
update: [],
patch: [],
remove: []
};
2- Create an user by calling the user service.
The user should be created successfully, and afterwards updated with the new permissions.
The user is created but the permissions are not saved correctly (the promises fail with an error).
The error message is password cannot be null
.
Patch the resource instead of updating it.
var promises = items.map(function (item) {
return service.update(hook.id || item[service.id], item);
});
to:
var promises = items.map(function (item) {
return service.patch(hook.id || item[service.id], { [options.field]: item[options.field] });
});
The item
has been stripped of it's password (as it should always), and since this is only a partial update, it makes sense changing it into a patch operation.
Module versions:
I'm using the latest version on the filters branch of the feathers-permissions repo.
NodeJS version: 6.9.4
I am suggesting that there should client library for this module, so that we can do conditional rendering/routing/etc without have to make service requests.
After authentication I cache a subset of the current user's data, including their permissions. I would like to do some conditional rendering/routing based on those permissions.
I've been trying to find references that go over channels with respect to permissions and access control but haven't been able to find anything.
What's the recommended way to handle permissions for sending out real time updates without it becoming a mess?
4.3.11
to 4.4.0
.π¨ View failing branch.
This version is covered by your current version range and after updating it in your project the build failed.
@feathersjs/errors is a direct dependency of this project, and it is very likely causing it to break. If other packages depend on yours, this update is probably also breaking those in turn.
Hook
and HookContext
(#1688) (f5d0ddd)The new version differs by 10 commits.
e157e5f
chore(release): publish v4.4.0
1293e08
feat(authentication-oauth): Set oAuth redirect URL dynamically (#1608)
5e65629
feat(authentication): Add parseStrategies to allow separate strategies for creating JWTs and parsing headers (#1708)
18ba231
chore: Update all Node engine versions
a4aecbc
fix(transport-commons): Allow to properly chain SocketIo client.off (#1706)
2331c2a
fix(core): Improve hook missing parameter message by adding the service name (#1703)
5f21272
fix(rest-client): Allow to customize getting the query (#1594)
3951626
fix(authentication-client): Reset authentication promise on socket disconnect (#1696)
f5d0ddd
fix(typescript): Allow specific service typings for Hook
and HookContext
(#1688)
42d81b2
chore: Update version and changelog
See the full diff
There is a collection of frequently asked questions. If those donβt help, you can always ask the humans behind Greenkeeper.
Your Greenkeeper Bot π΄
This hook should be able to be used as a before or after hook. If before it just adds the specified permissions to the permissionsField
. If used as an after hook it will have to patch the resource with the specified permissions on the permissionsField
.
What's the field type of permissions in a mysql db? Is it a comma-separated string or a JSON?
https://github.com/feathersjs/feathers-permissions/tree/master/src/hooks
If you take a quick look at the file naming conventions there, they differ.
I'm wondering if there's a reason for this, or if it's just arbitrary.
Hi, The documentation link I tried was not available. What sites are moved or updated somewhere?
1- Add the setPermissions hook as a before create hook to the users
service, with a template permission using the :id
string.
create: [
permissions.hooks.setPermissions({ permissions: ['users:*:id'] })
]
2- Create an user by calling the users
service.
Given a user id = 1.
The created user should have a permission equal to users:*:1
.
The created user has a permission equal to users:*:id
.
The issue happens because as a before create hook, the setPermissions hook doesn't have access to the user id (the user hasn't been created yet), thus it cannot replace it on the template.
Using the setPermissions hook as an after create hook works correctly.
permissions = permissions.map(function (permission) {
if (id !== undefined && permission.includes(':id')) {
permission = permission.replace(':id', ':' + id);
}
return permission;
});
The solution is to simply check if the hook is being used as a before create hook, and warn the user accordingly (as a before update or before patch hook it works correctly).
Module versions:
I'm using the latest commit from the feathers-permissions filters branch (commit no. b33fcdb).
NodeJS version: 6.9.4
Hi,
is it possible to allow user edit only his own record ? For example:
permissions: [ 'users:update:HIS_ID' ] (service_name:method:ID)
thanks for explanation if is not It would be great implement this feature I guess
How can I use that method?
And one more question. It seems filters
branch more recent than master
.
Why don't you merge them?
Currently the checkPermissions
hook has to have a service
option:
before: {
all: [checkPermissions({service: 'xxx'})]
}
But since now we have hook.path
representing the path of current service, this service
option becomes unnecessary. It's reasonable to allow omitting the service
option, which is needed only when we want to check permission based on other services.
In the source code setPermissions.js
is not exported to hooks
? And the content of setPermissions.js
seems just an old version of checkPermissions
.
From reading through the source code for checkPermissions
, it looks like there are two significant steps:
options.namespace
and hook's method
and (potentially id
.What this doesn't address, is a scenario where the permission is based on the incoming payload, or other request factors e.g. I may have have a user who can update another user to an admin
, but not necessarily to an owner
. In this scenario, the required permissions step won't be able to distinguish between these two, as both would be update methods and map to the same required permissions array.
I think there would be a couple of different ways to address this:
options
to override the classify function, or append to it. Not sure if this is too heavy handed oroption
which selects the required permission from somewhere on the hook.params
e.g. checkPermissions({ permissionsFrom: 'requiredPermissions' });
and a hook with hook.params === { requiredPermissions: [ 'promote_user' ] }
. That way you can just add a hook before the checkPermissions
method which would attach custom permissions to the hook.Would love to get some feedback on this idea / alternative solutions to the overall issue. Cheers!
What I expect when using it is to not throw even when user is not authenticated (provider is undefined)
Instead just set context.params.permitted
to false
throws 403 with You do not have the correct permissions (invalid permission entity).
Hello. I'm starting to use feathers. I don't know how to use checkPermissions with nested permissions without add permissions field to root of my model.
{
"_id": "5cb3bb8115afab14a74e5ad3",
"email": "[email protected]",
"roleId": "5cb3af204ddf5e03c15868a9",
"_include": [
"roles"
],
"roles": {
"_id": "5cb3af204ddf5e03c15868a9"
"permissions": [
"documents-types:*",
],
"name": "documents-types admin",
}
}
User hook
after: {
all: [
populate({ schema: userRoleSchema })
...
]
Documents-types hooks
before: {
all: [checkPermissions({
roles: [ 'documents-types' ],
field: 'roles.permissions',
})],
...
}
It doesn't work. I had to add this hook to user to extract the permissions.
after: {
...
get: [(context) => { context.result.permissions = context.result.roles.permissions; return context;}],
feathers --version 3.9.0
"feathers-hooks-common": "^4.20.7",
"feathers-mongoose": "^7.3.2",
"feathers-permissions": "^0.2.1",
usage with feathers documentation
Should transpile.
Transpilation error: Duplicate declaration "hooks"
Babel REPL
/cc @tgenez
export default {
before: {
all: [authenticate('jwt')],
get: [
// Allow only users with the "products:get" permission
checkPermissions({ roles: ['products:get'] }),
// The user will only get his product unless he is an admin
checkPermissions({ roles: ['admin'], error: false }),
(context: any) => console.log(context.params.permitted, context.params.user),
iff(
(context) => !context.params.permitted,
setField({
from: 'params.user._id',
as: 'params.query.user',
})
),
],
}
}
I was expecting this code first to allow users with the products:get
permission and second to check if the user is an admin or not. In case he is an admin don't limit the results, otherwise, let the user get only the products that belong to him.
The context.params.permitted
is always true no matter whether the user is an admin or not.
I believe this is due to the order here. The second call which is making the permitted: false
is overwritten by the first one since you are destructing ...params
after setting the value of permitted.
This makes the first call to checkPermissions
to have the max priority when it would make sense to have the last call of checkPermissions
being able to determine whether a user has access to perform the requested action.
Also since this is a permissions and roles library it should be strict by default, meaning even if one permission check has failed it should make the permitted value false.
At present, I suspect that NULL is not a valid value for the permissions field. When that field is set to NULL I get the following error:
Cannot read property 'some' of null
In my application, a majority of users will have only a basic set of permissions over their own content. I had planned to leave permissions blank for them, but instead it seems I'll need to give them a basic "user" permission to satisfy this need.
In the future, it'd be neat if the hook could fail out (based on the value of the error parameter) when there are no roles to check.
(First please check that this issue is not already solved as described
here)
Tell us what should happen
Tell us what happens instead
Tell us about the applicable parts of your setup.
Module versions (especially the part that's not working):
NodeJS version:
Operating System:
Browser Version:
React Native Version:
Module Loader:
12.12.1
to 12.12.2
.π¨ View failing branch.
This version is covered by your current version range and after updating it in your project the build failed.
@types/node is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.
There is a collection of frequently asked questions. If those donβt help, you can always ask the humans behind Greenkeeper.
Your Greenkeeper Bot π΄
Add a special permission somewhat like "users:*:own"
where it add permission access level to the user's own information.
In creating a new users, usually, the id
is auto generate by the database upon creation. So there's no easy way of knowing what the id
would be before it will be populated in the database.
So setPermissions
probably won't work as a before
hook with an example:
permissions.hooks.setPermissions({permissions: ['users:*:[id]'], field: 'permissions'})
An alternative would be is to have an after hook (when the id
is already generated) that updates the permission. But that means there will be at least two write
operations just to achieve the desired result.
With an own
permission, this can be simply:
permissions.hooks.setPermissions({permissions: ['users:*:own'], field: 'permissions'})
This library provides the basic needs for permissions usage in an application, but it does not allow for more advanced systems to take place, including the ability to provide context to frontend applications about what the user is able to do. I've started working on a project where I needed this advanced system, and the basics can be found here.
The current version I'm working on will be for SQL based systems. The best course of action for No-SQL would probably be creating a second repo. The main focus is to get the SQL version working / released though.
What is the status of this module? There is a message in the Readme still stating that its not ready yet
"This module is not published yet."
When can we hope to use it in production?
Thanks
Allow subtracting permissions:
[
"users:*:*", // users
"-:users:*:10" // except user with id 10
]
Added -
at the front to indicate negative permission, but there must be a better way to do this.
it's available now, right?
I am trying to check permissions on a user
that has a field role
set to admin.
Here is my setup in user
hooks:
const permissionsOptions = {
permissions: ['admin'],
on: 'user',
service: 'user',
field: 'role'
}
exports.before = {
find: [
auth.hooks.authenticate('jwt'),
permissions.hooks.checkPermissions(permissionsOptions),
permissions.hooks.isPermitted()
}
I would expect that permissionsOptions.permissions
would be compared against the actual field role
on user.
Instead, it is compared against the requiredPermissions array that, given the setup above, always becomes:
[ '*', '*:find', '*:find:*', 'user', 'user:*', 'user:*:*', 'user:find', 'user:find:*' ]
Here is the output from debug console log:
feathers-permissions:hooks:check-permissions Running checkPermissions hook with options:
{ on: 'user',
field: 'role',
permissions: [ 'admin' ],
service: 'user' } +0ms
feathers-permissions:hooks:check-permissions Active permissions [ 'admin' ] +3ms
feathers-permissions:hooks:check-permissions Required Permissions
[ '*',
'*:find',
'*:find:*',
'user',
'user:*',
'user:*:*',
'user:find',
'user:find:*' ] +1ms
error: (403) Route: /users - You do not have the correct permissions.
What am I doing wrong here? The documentation as to how to set up permissions options seems to be invalid or lacking details. The current readme on the plugin page is not very helpful either. I could also help with the docs, if I get it right myself. Thaks!
I assume I'm doing something incorrect here...
const checkPermissions = require('feathers-permissions');
module.exports = {
before: {
all: [
checkPermissions({
roles: async context => {
const { user } = context.params;
console.log('USER ROLES:', user.roles);
const roles = await context.app.service('roles').find({
query: {
name: {
$in: user.roles
}
}
});
console.log('ROLES:', roles);
let permissions = [];
for (let role of roles.data) {
permissions = permissions.concat(role.permissions);
}
console.log('PERMISSIONS:', permissions);
return permissions;
}
})
],
find: [],
get: [],
create: [],
update: [],
patch: [],
remove: []
},
after: {
all: [],
find: [],
get: [],
create: [],
update: [],
patch: [],
remove: []
},
error: {
all: [],
find: [],
get: [],
create: [],
update: [],
patch: [],
remove: []
}
};
This is designed to allow roles that can be changed thus persisting new sets of permissions to users, rather than storing permissions in every user record. I've verified that in my test permissions returns ['*'] so it should not get any denied error. Am I using this method incorrectly?
Thanks!
feathers-permissions
currently uses Feathers 4.5.15. This library is not compatible with the latest Feathers v5 hook types. Specifically, the return type of checkPermissions
(Hook
) is not compatible with the new HookFunction
type - Argument of type 'Hook' is not assignable to parameter of type 'HookFunction<A, S>
.
The common solution seems to be to cast the checkPermissions
hook to any
(or some other matching type), which isn't ideal.
Using the checkPermissions
hook with Feathers v5 does not produce a type error.
Type error when using checkPermissions
hook with Feathers v5.
Tell us about the applicable parts of your setup.
Module versions (especially the part that's not working):
NodeJS version:
v20.3.0
Operating System:
14.3.1 (23D60)
Browser Version:
Chrome Version 123.0.6312.59
context
object not available in checkPermissions() when called from before hook to custom hook.
const checkForAccess = require('../../hooks/check-for-access');
module.exports = {
before: {
...,
get : [authenticate('jwt'), checkForAccess() ],
...
}
const {restrictToOwner} =require('feathers-authentication-hooks');
module.exports = function (options = {}) {
return async context => {
checkPermissions({
roles: ['admin', 'user'],
error: false
});
if(!context.params.permitted)
restrictToOwner({ idField: 'id', ownerField: 'id' });
};
context.params.permitted
should be either true
or false
based on the permission.
context.params.permitted
is undefined thus the function restrictToOwner
always executes.
Break line in checkPermissions
function in node_modules/feathers-permission/lib/
module.exports = function checkPermissions (options = {}) {
options = Object.assign({
entity: 'user',
field: 'permissions'
}, options);
...
return function (context) {
...
}
context is not available (see screenshot at the end)
Debug in VS code.
VSCode version
Version: 1.25.1 Commit: 1dfc5e557209371715f655691b1235b6b26a06be Date: 2018-07-11T15:40:20.190Z Electron: 1.7.12 Chrome: 58.0.3029.110 Node.js: 7.9.0 V8: 5.8.283.38 Architecture: x64
Module versions
"feathers-permissions": "^0.2.1",
"feathers-authentication-hooks": "^0.3.0"
NodeJS version:
v10.6.0
Operating System:
LSB Version: 1.4 Distributor ID: Arch Description: Arch Linux Release: rolling Codename: ISO-Rolling
If doing a permissions check on a route that may be accessed by a logged out user there is no check for the error flag.
https://github.com/feathersjs-ecosystem/feathers-permissions/blob/release/lib/index.js#L33
This causes an issue because currently I'm using permissions check in users before hooks with error false. This makes it easier than implementing it on every method except POST (which you would obviously be logged out for in the event of a new registration).
Is there some reason the error check is not implemented there?
After integrating feathers-permissions (backed by PostgreSQL), I want to make it possible for UI devs to use the same logic.
contrived example: class="'userInstance.can('item:remove') || 'disabled'"
I'd like to move https://github.com/feathersjs-ecosystem/feathers-permissions/blob/master/lib/index.js#L39-L60 into its own function so that it can be used by the existing hook and a more generic implementation.
e.g.
permissionsContain(permissions, roles, method);
checkPermission(permission, permissions);
checkPermission('item:get', [ 'item:*' ]);
FrontendUserModel.prototype.can = function(permission) {
return checkPermission(permission, this.permissions);
}
It seems that currently we don't have any completed docs/examples to show how the permission array and the three hooks works together.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.