Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Simple role and service method permissions for Feathers

License

Notifications You must be signed in to change notification settings

feathersjs-ecosystem/feathers-permissions

Open more actions menu

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

118 Commits
118 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

feathers-permissions

CI Dependency Status Download Status

Simple role and service method permissions for Feathers

Note: This module implements a hook simple role and service method based permissions checked against the permissions in a user (entity) object. More complex requirements can already be implemented as custom Feathers hooks. See here and here for more information.

Installation

npm install feathers-permissions --save

Important: The feathers-permissions hook should be used after the authenticate() hook from @feathersjs/authentication.

Simple example

The following example will limit all messages service calls to users that have admin in their roles:

const feathers = require('@feathersjs/feathers');
const memory = require('feathers-memory');
const checkPermissions = require('feathers-permissions');
const app = feathers();

app.use('/messages', memory());

app.service('messages').hooks({
  before: [
    authenticate('jwt'),
    checkPermissions({
      roles: [ 'admin' ]
    })
  ]
});

// User from the database
const user = {
  email: 'someuser@example.com',
  permissions: [ 'admin' ]
}

Documentation

Feathers permissions allows you to grant and manage permissions in a flexible nature based on role and service method. Each object that requires permissions must have an array or a comma separated string of permissions stored on it (typically in your database).

Options

The following options are available:

  • roles - A list of permission roles to check or a function that takes the hook context and returns a list of roles. Can be a comma separated string of roles or an array of roles.
  • entity (default: user) - The name of the entity (params[entity])
  • field (default: permissions) - The name of the permissions field on the entity. May be dot separated to access nested fields.
  • error - If set to false will not throw a Forbidden error but instead set params.permitted to true or false. Useful for chaining permission hooks.

Permission format

The list of permissions will be obtained from params[entity] and field. It can be a comma separate list or an array of permissions in the following format:

  • * - Allow everything
  • ${role} or ${role}:* - Allow every service method (find, get, create, update, patch, remove) for role
  • *:${method} - Allow method service method for any role
  • ${role}:${method} - Allow method service method for role

This means the following use of feathers-permissions:

app.service('messages').hooks({
  before: checkPermissions({
    roles: [ 'admin', 'user' ]
  })
});

Will allow user permissions containing *, admin:*, user:* and the service method that is being called (e.g. admin:create or user:find and *:create and *:find).

The following will create a dynamic permission based on the hook context.path:

app.service('messages').hooks({
  before: checkPermissions({
    roles: context => {
      return [ 'admin', context.path ];
    }
  })
});

Permissions can also be assembled asynchronously:

app.service('messages').hooks({
  before: checkPermissions({
    roles: async context => {
      const { user } = context.params;
      const roles = await app.service('roles').find({
        query: {
          userId: user._id
        }
      });

      return roles.data;
    }
  })
});

Conditionally restricting permissions

To conditionally either allow access by roles or otherwise restrict to the current user, a combination of feathers-permissions - setting the error option to false - feathers-authentication-hooks and feathers-hooks-common#iff (checking for params.permitted) can be used:

app.service('messages').hooks({
  before: {
    find: [
      checkPermissions({
        roles: ['super_admin', 'admin'],
        field: 'roles',
        error: false
      }),
      iff(context => !context.params.permitted,
        setField({
          from: 'params.user._id',
          as: 'params.query.userId'
        })
      )
    ]
  }
});

More examples

const feathers = require('@feathersjs/feathers');
const memory = require('feathers-memory');
const checkPermissions = require('feathers-permissions');
const app = feathers();

app.use('/messages', memory());

app.service('messages').hooks({
  before: checkPermissions({
    roles: [ 'admin', 'messages' ]
  })
});

// User from the database (e.g. added via @feathersjs/authentication)
const user = {
  email: 'someuser@example.com',
  permissions: [ 'messages:find', 'messages:get' ]
  // Also possible
  permissions: 'messages:find,messages:get'
}

const admin = {
  email: 'someuser@example.com',
  permissions: [ 'admin:*' ]
}

// Will pass
app.service('messages').find({
  user
});

// Will fail
app.service('messages').create({
  user
});

// Will pass
app.service('messages').create({
  provider: 'rest', // this will be set automatically by external calls
  user: admin
});

License

Copyright (c) 2019

Licensed under the MIT license.

About

Simple role and service method permissions for Feathers

Resources

License

Contributing

Stars

Watchers

Forks

Packages

No packages published

Contributors 16

Morty Proxy This is a proxified and sanitized view of the page, visit original site.