7

In Feathers the goal is to restrict the data accessible on a certain service to the data owned by the currently logged in user only.

Assuming that I am using Feathers authentication, the data available on this service is stored in a database table, and the table column that contains the user ID is called user_id, will this hook achieve the goal?

If not then what needs to change?

In case it is important to be able to answer the question then I am using Sequelize and Postgres.

const { authenticate } = require('feathers-authentication').hooks;

const { queryWithCurrentUser } = require('feathers-authentication-hooks');
const { associateCurrentUser } = require('feathers-authentication-hooks');

const readRestrict = [
  queryWithCurrentUser({
    idField: 'id',
    as: 'user_id'
  })
];

const modRestrict = [
  associateCurrentUser({
    idField: 'id',
    as: 'user_id'
  })
];

module.exports = {
  before: {
    all:    [ authenticate('jwt') ],
    find:   [ ...readRestrict ],
    get:    [ ...readRestrict ],
    create: [ ...modRestrict ],
    update: [ ...modRestrict ],
    patch:  [ ...modRestrict ],
    remove: [ ...modRestrict ]
  },

  after: {
    all:    [],
    find:   [],
    get:    [],
    create: [],
    update: [],
    patch:  [],
    remove: []
  },

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

It seems to work but since I'm a Feathers noob I thought I'd better check before this is put into the wild to make sure there are no cases that I am unaware of that will cause leaks.

Matty
  • 175
  • 11
  • 1
    It looks fine. Any reason you think it wouldn't work as expected? – Daff May 22 '17 at 22:32
  • Thanks! It's just that I'm new to Feathers (and JS) and wanted to double-check before I release it into the wild. There is so much that is going on behind the scenes in Feathers so I didn't know if I had missed something important. The framework does so much for you so it just feels it is too easy - there has to be something that I have forgotten. :) Thank you so much for an excellent framework! – Matty May 22 '17 at 22:54
  • 1
    When allowing websocket connections, you should also add appropriate *filters* to the service. By default, all events will be pushed to all clients, regardless of the hooks. This means that when a user creates a new record on a service, all connected clients will receive that record. – jsphpl Aug 22 '17 at 09:12
  • Thanks jsphpl! I almost missed that! – Matty Aug 22 '17 at 19:09

1 Answers1

0

As a totoal beginner to feathers and express, I am unsure. Now, all works as stated above.

Old Answer

For remove, I used restrictToOwner. (I also think for patch and update because they operate on the existing data. I did not test that though.) Otherwise I was able to cross-delete data by specifying the id. Maybe you can check if this is the case for you, too.

This is the test case:

  1. user 1 creates an model object with
    • user id to check authorization
    • object id to identify the object
  2. user 2 deletes the object with object id
    • test ok: 404 expected
    • test fail: 204 or 200 worked
  3. user 1 tries to get the object
    • test ok: object is there, 200
    • test fail: object is absent, 404

Test code:

Thank you very much, you post was really helpful to me!

User
  • 14,131
  • 2
  • 40
  • 59