Giter VIP home page Giter VIP logo

casl-feathersjs-example's Introduction

Hi there ๐Ÿ‘‹

I'm a Full Stack Open Source developer, building apps, managing different insfrastructure and sometimes other people.

Node JavaScript TypeScript Vue Angular

Ruby PHP Bash Postgres MongoDB

  • ๐Ÿ”ญ Iโ€™m currently working on CASL and other interesting projects
  • ๐Ÿ“ซ If you like my work and want to support, please do this on Open Collective

Serhii Stotskyi's GitHub stats

casl-feathersjs-example's People

Contributors

mattbradbury avatar sarkistlt avatar stalniy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

casl-feathersjs-example's Issues

hasToken(hook) does not return a correct value

in authenticate.js

function hasToken(hook) {
  if (hook.params.headers == undefined) return false
  if (hook.data.accessToken == undefined) return false
  return hook.params.headers.authorization || hook.data.accessToken
}

Looks like execution never reaches the 3rd line if params has headers and data does not have accessToken. In this case if the request has token in request headers (and not in request body) hasToken() returns false even when the authorization is truthy.

RangeError: Maximum call stack size exceeded

Hi. Thanks for sharing this repo and posting that article. Really helpful.

I modified and tried the abilities.js for a simpler use case (no anonymous access, no user-specific acl):

abilities.js

const { AbilityBuilder, Ability } = require('casl');
const { Forbidden } = require('@feathersjs/errors');
const TYPE_KEY = Symbol.for('type');

Ability.addAlias('update', 'patch');
Ability.addAlias('read', ['get', 'find']);
Ability.addAlias('remove', 'delete');
Ability.addAlias('create', 'create');

function subjectName(subject) {
  if (!subject || typeof subject === 'string') {
    return subject;
  }

  return subject[TYPE_KEY];
}

function defineAbilitiesFor(groupName) {
  const { rules, can } = AbilityBuilder.extract();

  /* eslint-disable */
  switch(groupName) {
    case 'Administrators':
      can('manage', 'all');
      break;
    case 'Sales':
      can('manage', ['events']);
      break;
    case 'Logistics':
      can('read', 'deliveries');
      break;
    case 'Warehouse':
      can('manage', 'inventories');
      break;
  }
  /* eslint-enable */
  return new Ability(rules, { subjectName });
}

module.exports = function authorize(name = null) {
  return async function(context) {
    const action = context.method;
    const service = name || context.path;
    const groupName = context.params.user.groupName;
    const ability = defineAbilitiesFor(groupName);

    if (ability.cannot(action, service)) {
      throw new Forbidden(`You are not allowed to ${action} ${service}`);
    }

    return context;
  };
};

This is how it's being called:

app.hooks.js

module.exports = {
  before: {
    all: [
      authenticate('jwt'),
      when(
        context => context.params.provider && `/${context.path}` !== context.app.get('authentication').path,
        authorize(),
      ),
      logger()
    ],
    find: [ includer() ],
    get: [ includer() ],
    create: [],
    update: [],
    patch: [],
    remove: []
  },

  after: {
    all: [ logger() ],
    find: [ dehydrator() ],
    get: [],
    create: [],
    update: [],
    patch: [],
    remove: []
  },

  error: {
    all: [ logger() ],
    find: [],
    get: [],
    create: [],
    update: [],
    patch: [],
    remove: []
  }
};

It works on simple tests (eg, simple find) but when I use it with the mobile app I'm working on, I'm having this error:

error:  RangeError: Maximum call stack size exceeded
    at Array.reduce (native)

It works when I remove the authorize hook. Any hints on how I can further debug this? Thanks.

How to manage channels and real time updates in this setup?

Is there any example on how we can manage channels and real time updates in this setup?

With the generated code in feathersjs setup, everyone logged in gets all the updates. Building on top of that, I tried setting up different channels based on resource names and roles but it quickly got out of hands with too much hard coded stuff.

Is there any base/example that would be helpful in understanding how we can setup channels and limit the events to clients that have access?

For example, any time a new blog post is created, how can I limit the event to users who have access? (Say Blog is in draft mode and should only be accessible by admins, and I have casl rules that define that - how to use those rules in determining which channels to publish the events to?)

Nested document key example

Hi, I'm trying to use your example (with mongoose) for my use case:

Domain definition:
A "User" could has more "Vehicles"
A "Document" must have a "Vehicle"

Schema definition:

vehicle { users: [ {type: objectId, ref: 'user'} ] }
document { vehicle: {type: objectId, ref: 'vehicle' }}

Rule definition
I successfully defined an ability for user to read/update only his vehicles
can(['read', 'update'], 'vehicle', { users: { $in: [user._id] } } )

How can I define a rule to check "user can read/update only documents of his vehicles" ?
I tried with:

can(['read', 'update'], 'document', { "vehicle.users": { $in: [user._id] } } )

Obviously with no success. Can you provide "more nested level" example?
Thanks you

doesnot work on `find` and `create` action

I want to restrict some role to find and create posts, so I wrote the following code:

cannot('find','posts')
cannot('create', 'posts')

however it doesn't work, I can still find and create posts

Update to Feathers 3.x

Hello

I am a beginner in the use of feathers and I see that this project uses version 2. I don't know if the use of CASL is the same in v3 (especially when calling in a hook a service)

Thank !

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.