Skip to content
This repository has been archived by the owner on Mar 22, 2022. It is now read-only.

RestrictToOwner now takes an array #231

Merged
merged 1 commit into from
Jul 7, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions src/hooks/restrict-to-owner.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export default function(options = {}){
}

options = Object.assign({}, defaults, hook.app.get('auth'), options);

const id = hook.params.user[options.idField];

if (id === undefined) {
Expand All @@ -51,17 +51,22 @@ export default function(options = {}){

let field = data[options.ownerField];

// Handle nested Sequelize or Mongoose models
// Handle nested Sequelize or Mongoose models
if (isPlainObject(field)) {
field = field[options.idField];
}

if ( field === undefined || field.toString() !== id.toString() ) {
if (Array.isArray(field)) {
const fieldArray = field.map(idValue => idValue.toString());
if (fieldArray.length === 0 || fieldArray.indexOf(id.toString()) < 0) {
reject(new errors.Forbidden('You do not have the permissions to access this.'));
}
} else if ( field === undefined || field.toString() !== id.toString() ) {
reject(new errors.Forbidden('You do not have the permissions to access this.'));
}

resolve(hook);
}).catch(reject);
});
};
}
}
50 changes: 49 additions & 1 deletion test/src/hooks/restrict-to-owner.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,26 @@ import sinon from 'sinon';
import { restrictToOwner } from '../../../src/hooks';

let MockData;
let MockData2;
let MockService;
let MockService2;

describe('restrictToOwner', () => {
beforeEach(() => {
MockData = {
userId: '1',
text: 'hey'
};
MockData2 = {
userId: ['1'],
text: 'hey'
};
MockService = {
get: sinon.stub().returns(Promise.resolve(MockData))
};
MockService2 = {
get: sinon.stub().returns(Promise.resolve(MockData2))
};
});

describe('when not called as a before hook', () => {
Expand Down Expand Up @@ -137,6 +146,45 @@ describe('restrictToOwner', () => {
});
});

describe('when an empty array is passed', () => {
it('throws an error', () => {
hook.userId = [];

try {
restrictToOwner()(hook);
}
catch(error) {
expect(error).to.not.equal(undefined);
}
});
});

describe('when user does not own the resource and idField is an array', () => {
it('returns a Forbidden error', done => {
hook.userId = ['1'];
hook.params.user._id = '2';
let fn = restrictToOwner();

fn.call(MockService2, hook).then(done).catch(error => {
expect(error.code).to.equal(403);
done();
});
});
});

describe('when user owns the resource and idField is an array', () => {
it('does nothing', done => {
hook.userId = ['1'];

let fn = restrictToOwner();

fn.call(MockService2, hook).then(returnedHook => {
expect(returnedHook).to.deep.equal(hook);
done();
}).catch(done);
});
});

describe('when user owns the resource', () => {
it('does nothing', done => {
let fn = restrictToOwner();
Expand All @@ -148,4 +196,4 @@ describe('restrictToOwner', () => {
});
});
});
});
});