it('should properly handle overridden permissions', () => { const role = new Role(); role.controllers = { '*': { actions: { '*': true } }, controller: { actions: { '*': false } } }; role[_kuzzle] = kuzzle; return role.isActionAllowed(request) .then(isAllowed => { should(isAllowed).be.false(); role.controllers.controller.actions.action = true; return role.isActionAllowed(request); }) .then(isAllowed => { should(isAllowed).be.true(); role.controllers.controller.actions.action = false; return role.isActionAllowed(request); }) .then(isAllowed => { should(isAllowed).be.false(); }); });
it('should allow/deny rights using custom function with args using search', () => { const role = new Role(), allowed = new Request({ controller: 'read', action: 'get', requestId: 'foo', collection: 'barbar', index: 'bar', _id: documentAda._id, body: {} }, context), denied = new Request({ controller: 'read', action: 'get', requestId: 'foo', collection: 'barbar', index: 'bar', _id: documentFalseAda._id, body: {} }, context); role.controllers = { '*': { actions: { '*': { args: { documents: { action: { search: { query: { ids: { values: [ '$request.input.resource._id' ] } } } }, index: 'bar', collection: 'barbar' } }, test: 'return args.documents[0] && args.documents[0].id === $request.input.resource._id;' } } } }; kuzzle.services.list.storageEngine.search.returns(Bluebird.resolve({hits: [documentAda]})); role[_kuzzle] = kuzzle; return role.isActionAllowed(allowed) .then(isAllowed => { should(isAllowed).be.true(); return role.isActionAllowed(denied); }) .then(isAllowed => should(isAllowed).be.false()); });
it('should not allow if collection is not specified', () => { const role = new Role(), req = new Request({ controller: 'read', action: 'get', requestId: 'foo', collection: 'barbar', index: 'bar', _id: documentAda._id, body: {} }, context); role.controllers = { '*': { actions: { '*': { args: { document: { action: { get: '$currentId' }, collection: 'barbar' } }, test: 'return args.document && args.document.id === $request.input.resource._id;' } } } }; role[_kuzzle] = kuzzle; return should(role.isActionAllowed(req)) .be.fulfilledWith(false); });
.then(isAllowed => { should(isAllowed).be.false(); role.closures = {}; role.controllers['*'].actions['*'] = { args: {}, test: 'return $request.input.action !== \'action\'; ' }; return role.isActionAllowed(request); })
it('should allow/deny rights using custom function with args using get', () => { let role = new Role(), allowed = new Request({ controller: 'document', action: 'get', requestId: 'foo', collection: 'barbar', index: 'bar', _id: documentAda._id, body: {} }, context), denied = new Request({ controller: 'document', action: 'get', requestId: 'foo', collection: 'barbar', index: 'bar', _id: documentFalseAda._id, body: {} }, context); role.controllers = { '*': { actions: { '*': { args: { document: { action: { get: '$currentId' }, index: 'bar', collection: 'barbar' } }, test: 'return args.document && args.document.id === $request.input.resource._id;' } } } }; kuzzle.services.list.storageEngine.get.returns(Bluebird.resolve(documentAda)); role[_kuzzle] = kuzzle; return role.isActionAllowed(allowed) .then(isAllowed => { should(isAllowed).be.true(); return role.isActionAllowed(denied); }) .then(isAllowed => should(isAllowed).be.false()); });
it('should reject if the rights configuration is not either a boolean or a closure', () => { const role = new Role(); role.controllers = { '*': { actions: { '*': {an: 'object'} } } }; role[_kuzzle] = kuzzle; return should(role.isActionAllowed(request)) .be.rejected(); });
it('should allow a wildcard action', () => { const role = new Role(); role.controllers = { '*': { actions: { '*': true } } }; role[_kuzzle] = kuzzle; return should(role.isActionAllowed(request)) .be.fulfilledWith(true); });
it('should reject if the closure function return a non boolean value', () => { const role = new Role(); role.controllers = { '*': { actions: { '*': {test: 'return "retret";'} } } }; role[_kuzzle] = kuzzle; return should(role.isActionAllowed(request)) .be.rejected(); });
it('should allow an action explicitely set to true', () => { const role = new Role(); role.controllers = { controller: { actions: { action: true } } }; role[_kuzzle] = kuzzle; return should(role.isActionAllowed(request)) .be.fulfilledWith(true); });
it('should reject if an invalid function is given', () => { const role = new Role(); role.controllers = { '*': { actions: { '*': { test: '(some invalid code', args: {} } } } }; role[_kuzzle] = kuzzle; return should(role.isActionAllowed(request)) .be.rejectedWith(ParseError); });
it('should handle a custom right function', () => { const role = new Role(), noMatchRequest = new Request({ collection: 'collection', controller: 'controller', action: 'noaction' }, context); role.controllers = { '*': { actions: { '*': { args: {}, test: 'return $request.input.action === \'action\'; ' } } } }; role[_kuzzle] = kuzzle; return role.isActionAllowed(request) .then(isAllowed => { should(isAllowed).be.true(); return role.isActionAllowed(noMatchRequest); }) .then(isAllowed => { should(isAllowed).be.false(); role.closures = {}; role.controllers['*'].actions['*'] = { args: {}, test: 'return $request.input.action !== \'action\'; ' }; return role.isActionAllowed(request); }) .then(isAllowed => { should(isAllowed).be.false(); }); });
it('should reject if an invalid argument is given', () => { const role = new Role(); role.controllers = { '*': { actions: { '*': { test: 'return args.document && args.document.id === $request.input.resource._id;', args: { document: { get: '$request.input.resource.._id' } } } } } }; role[_kuzzle] = kuzzle; return should(role.isActionAllowed(request)) .be.rejectedWith(ParseError); });
it('should disallow any action when no matching entry can be found', () => { const role = new Role(); role.controllers = { controller: { actions: {} } }; role[_kuzzle] = kuzzle; return role.isActionAllowed(request) .then(isAllowed => { should(isAllowed).be.false(); delete role.controllers.controller.actions; return role.isActionAllowed(request); }) .then(isAllowed => { should(isAllowed).be.false(); delete role.controllers.controller; return role.isActionAllowed(request); }) .then(isAllowed => { should(isAllowed).be.false(); delete role.controllers; return role.isActionAllowed(request); }) .then(isAllowed => { should(isAllowed).be.false(); }); });
it('should not allow bad method call', () => { const role = new Role(), req = new Request({ controller: 'read', action: 'get', requestId: 'foo', collection: 'barbar', index: 'bar', _id: documentAda._id, body: {} }); role.controllers = { '*': { actions: { '*': { args: { document: { action: { foo: '$currentId' }, index: 'bar', collection: 'barbar' } }, test: 'return args.document && args.document.id === $request.input.resource._id;' } } } }; role[_kuzzle] = kuzzle; return role.isActionAllowed(req) .then(isAllowed => should(isAllowed).be.false()); });
.then(isAllowed => { should(isAllowed).be.false(); delete role.controllers; return role.isActionAllowed(request); })
.then(isAllowed => { should(isAllowed).be.true(); return role.isActionAllowed(req, restrictions); })
.then(isAllowed => { should(isAllowed).be.true(); return role.isActionAllowed(denied); })
.then(isAllowed => { should(isAllowed).be.true(); req.input.resource.collection = 'collection2'; return role.isActionAllowed(req, restrictions); })
.then(isAllowed => { should(isAllowed).be.false(); req.input.resource.index = 'index3'; return role.isActionAllowed(req, restrictions); })
.then(isAllowed => { should(isAllowed).be.true(); role.controllers.controller.actions.action = false; return role.isActionAllowed(request); })
.then(isAllowed => { should(isAllowed).be.true(); return role.isActionAllowed(noMatchRequest); })
it('should properly handle restrictions', () => { const role = new Role(), req = new Request({ controller: 'controller', action: 'action' }, context), restrictions = [ {index: 'index1'}, {index: 'index2', collections: ['collection1']}, {index: 'index3', collections: ['collection1', 'collection2']} ]; role.controllers = { controller: { actions: { action: true } } }; role[_kuzzle] = kuzzle; return role.isActionAllowed(req) .then(isAllowed => { should(isAllowed).be.true(); return role.isActionAllowed(req, restrictions); }) .then(isAllowed => { should(isAllowed).be.true(); req.input.resource.index = 'index'; return role.isActionAllowed(req, restrictions); }) .then(isAllowed => { should(isAllowed).be.false(); req.input.resource.index = 'index1'; return role.isActionAllowed(req, restrictions); }) .then(isAllowed => { should(isAllowed).be.true(); req.input.resource.index = 'index2'; return role.isActionAllowed(req, restrictions); }) .then(isAllowed => { should(isAllowed).be.true(); req.input.resource.collection = 'collection'; return role.isActionAllowed(req, restrictions); }) .then(isAllowed => { should(isAllowed).be.false(); req.input.resource.collection = 'collection1'; return role.isActionAllowed(req, restrictions); }) .then(isAllowed => { should(isAllowed).be.true(); req.input.resource.collection = 'collection2'; return role.isActionAllowed(req, restrictions); }) .then(isAllowed => { should(isAllowed).be.false(); req.input.resource.index = 'index3'; return role.isActionAllowed(req, restrictions); }) .then(isAllowed => { should(isAllowed).be.true(); }); });