@leansdk/leanrc
Version:
LeanRC is a MVC framework for creating graceful applications
470 lines (468 loc) • 17.8 kB
text/coffeescript
### Moved to *ing mixins
{ IncomingMessage, ServerResponse } = require 'http'
{ expect, assert } = require 'chai'
sinon = require 'sinon'
_ = require 'lodash'
httpErrors = require 'http-errors'
LeanRC = require.main.require 'lib'
{ co } = LeanRC::Utils
describe 'CheckPermissionsMixin', ->
describe '.new', ->
it 'should create new resource', ->
expect ->
class Test extends LeanRC
@inheritProtected()
@root __dirname
Test.initialize()
class TestResource extends LeanRC::Resource
@inheritProtected()
@include LeanRC::CheckPermissionsMixin
@module Test
@public entityName: String,
default: 'TestEntity'
TestResource.initialize()
resource = Test::TestResource.new()
.to.not.throw Error
describe '#_checkOwner', ->
it 'should check if resource owner is matched', ->
co ->
KEY = 'TEST_CHECK_PERMISSIONS_MIXIN_001'
class Test extends LeanRC
@inheritProtected()
@root "#{__dirname}/config/root"
Test.initialize()
facade = Test::Facade.getInstance KEY
configs = Test::Configuration.new Test::CONFIGURATION, Test::ROOT
facade.registerProxy configs
class TestResource extends Test::Resource
@inheritProtected()
@include Test::CheckPermissionsMixin
@module Test
@public entityName: String,
default: 'TestEntity'
TestResource.initialize()
class TestRouter extends Test::Router
@inheritProtected()
@module Test
TestRouter.initialize()
facade.registerProxy TestRouter.new 'TEST_SWITCH_ROUTER'
class TestSwitch extends Test::Switch
@inheritProtected()
@module Test
@public routerName: String,
configurable: yes
default: 'TEST_SWITCH_ROUTER'
TestSwitch.initialize()
class MemoryCollection extends LeanRC::Collection
@inheritProtected()
@include LeanRC::MemoryCollectionMixin
@include LeanRC::GenerateUuidIdMixin
@module Test
MemoryCollection.initialize()
class Space extends Test::Record
@inheritProtected()
@module Test
@attribute ownerId: String
Space.initialize()
facade.registerProxy MemoryCollection.new Test::SPACES,
delegate: Space
serializer: Test::Serializer
body = '{"test":"test"}'
class MyRequest extends IncomingMessage
constructor: (socket) ->
super socket
@method = 'POST'
@url = 'http://localhost:8888/space/SPACE123/test_entity'
@headers =
'x-forwarded-for': '192.168.0.1'
'content-type': 'application/json'
'content-length': "#{body.length}"
@push body
@push null
class MyResponse extends ServerResponse
req = new MyRequest
res = new MyResponse req
facade.registerMediator TestSwitch.new 'TEST_SWITCH_MEDIATOR'
switchMediator = facade.retrieveMediator 'TEST_SWITCH_MEDIATOR'
spaces = facade.retrieveProxy Test::SPACES
space = yield spaces.create id: 'XXX', ownerId: 'YYY'
resource = Test::TestResource.new()
resource.context = Test::Context.new req, res, switchMediator
resource.initializeNotifier KEY
{ pointer: key } = Test::TestResource.instanceMethods['_checkOwner']
isOwner = yield resource[key] 'XXX', 'YYY'
assert.isTrue isOwner
isOwner = yield resource[key] 'XXX', 'YYY12'
assert.isFalse isOwner
facade.remove()
yield return
describe '#_checkRole', ->
it 'should check if resource owner is matched', ->
co ->
KEY = 'TEST_CHECK_PERMISSIONS_MIXIN_002'
class Test extends LeanRC
@inheritProtected()
@root "#{__dirname}/config/root"
Test.initialize()
facade = Test::Facade.getInstance KEY
configs = Test::Configuration.new Test::CONFIGURATION, Test::ROOT
facade.registerProxy configs
class TestResource extends Test::Resource
@inheritProtected()
@include Test::CheckPermissionsMixin
@module Test
@public entityName: String,
default: 'TestEntity'
TestResource.initialize()
class TestRouter extends Test::Router
@inheritProtected()
@module Test
TestRouter.initialize()
facade.registerProxy TestRouter.new 'TEST_SWITCH_ROUTER'
class TestSwitch extends Test::Switch
@inheritProtected()
@module Test
@public routerName: String,
configurable: yes
default: 'TEST_SWITCH_ROUTER'
TestSwitch.initialize()
class MemoryCollection extends LeanRC::Collection
@inheritProtected()
@include LeanRC::MemoryCollectionMixin
@include LeanRC::GenerateUuidIdMixin
@module Test
@public @async findBy: Function,
default: (query) ->
item = _.chain @[Symbol.for '~collection']
.values()
.find query
.value()
result = if item? then [ item ] else []
yield return LeanRC::Cursor.new @, result
MemoryCollection.initialize()
class Role extends Test::Record
@inheritProtected()
@module Test
@attribute spaceId: String
@attribute userId: String
@attribute rules: Object
Role.initialize()
facade.registerProxy MemoryCollection.new Test::ROLES,
delegate: Role
serializer: Test::Serializer
body = '{"test":"test"}'
class MyRequest extends IncomingMessage
constructor: (socket) ->
super socket
@method = 'POST'
@url = 'http://localhost:8888/space/SPACE123/test_entity'
@headers =
'x-forwarded-for': '192.168.0.1'
'content-type': 'application/json'
'content-length': "#{body.length}"
@push body
@push null
class MyResponse extends ServerResponse
req = new MyRequest
res = new MyResponse req
facade.registerMediator TestSwitch.new 'TEST_SWITCH_MEDIATOR'
switchMediator = facade.retrieveMediator 'TEST_SWITCH_MEDIATOR'
roles = facade.retrieveProxy Test::ROLES
yield roles.create
id: 'AAA1'
spaceId: 'XXX'
userId: 'YYY1'
rules: system: administrator: yes
yield roles.create
id: 'AAA2'
spaceId: 'XXX'
userId: 'YYY2'
rules: moderator: 'Test::TestResource': yes
yield roles.create
id: 'AAA3'
spaceId: 'XXX'
userId: 'YYY3'
rules: 'Test::TestResource': create: yes
resource = Test::TestResource.new()
resource.context = Test::Context.new req, res, switchMediator
resource.initializeNotifier KEY
{ pointer: key } = Test::TestResource.instanceMethods['_checkRole']
isRole = yield resource[key] 'XXX', 'YYY', 'ZZZ'
assert.isFalse isRole
isRole = yield resource[key] 'XXX', 'YYY1', 'ZZZ'
assert.isTrue isRole
isRole = yield resource[key] 'XXX', 'YYY2', 'ZZZ'
assert.isTrue isRole
isRole = yield resource[key] 'XXX', 'YYY3', 'create'
assert.isTrue isRole
facade.remove()
yield return
describe '#_checkPermission', ->
it 'should check if permission is enough', ->
co ->
KEY = 'TEST_CHECK_PERMISSIONS_MIXIN_003'
class Test extends LeanRC
@inheritProtected()
@root "#{__dirname}/config/root"
Test.initialize()
facade = Test::Facade.getInstance KEY
configs = Test::Configuration.new Test::CONFIGURATION, Test::ROOT
facade.registerProxy configs
class TestResource extends Test::Resource
@inheritProtected()
@include Test::CheckPermissionsMixin
@module Test
@public entityName: String,
default: 'TestEntity'
TestResource.initialize()
class TestRouter extends Test::Router
@inheritProtected()
@module Test
TestRouter.initialize()
facade.registerProxy TestRouter.new 'TEST_SWITCH_ROUTER'
class TestSwitch extends Test::Switch
@inheritProtected()
@module Test
@public routerName: String,
configurable: yes
default: 'TEST_SWITCH_ROUTER'
TestSwitch.initialize()
class MemoryCollection extends LeanRC::Collection
@inheritProtected()
@include LeanRC::MemoryCollectionMixin
@include LeanRC::GenerateUuidIdMixin
@module Test
@public @async findBy: Function,
default: (query) ->
item = _.chain @[Symbol.for '~collection']
.values()
.find query
.value()
result = if item? then [ item ] else []
yield return LeanRC::Cursor.new @, result
MemoryCollection.initialize()
class Role extends Test::Record
@inheritProtected()
@module Test
@attribute spaceId: String
@attribute userId: String
@attribute rules: Object
Role.initialize()
class Space extends Test::Record
@inheritProtected()
@module Test
@attribute ownerId: String
Space.initialize()
facade.registerProxy MemoryCollection.new Test::SPACES,
delegate: Space
serializer: Test::Serializer
facade.registerProxy MemoryCollection.new Test::ROLES,
delegate: Role
serializer: Test::Serializer
body = '{"test":"test"}'
class MyRequest extends IncomingMessage
constructor: (socket) ->
super socket
@method = 'POST'
@url = 'http://localhost:8888/space/SPACE123/test_entity'
@headers =
'x-forwarded-for': '192.168.0.1'
'content-type': 'application/json'
'content-length': "#{body.length}"
@push body
@push null
class MyResponse extends ServerResponse
req = new MyRequest
res = new MyResponse req
facade.registerMediator TestSwitch.new 'TEST_SWITCH_MEDIATOR'
switchMediator = facade.retrieveMediator 'TEST_SWITCH_MEDIATOR'
spaces = facade.retrieveProxy Test::SPACES
space = yield spaces.create id: 'XXX', ownerId: 'YYY'
roles = facade.retrieveProxy Test::ROLES
yield roles.create
id: 'AAA1'
spaceId: 'XXX'
userId: 'YYY1'
rules: system: administrator: yes
yield roles.create
id: 'AAA2'
spaceId: 'XXX'
userId: 'YYY2'
rules: moderator: 'Test::TestResource': yes
yield roles.create
id: 'AAA3'
spaceId: 'XXX'
userId: 'YYY3'
rules: 'Test::TestResource': create: yes
resource = Test::TestResource.new()
resource.context = Test::Context.new req, res, switchMediator
resource.currentUser = id: 'YYY2'
resource.initializeNotifier KEY
{ pointer: key } = Test::TestResource.instanceMethods['_checkPermission']
try
hasPermissions = yield resource[key] 'XXX', 'ZZZ'
catch e1
hasPermissions = no
assert.isTrue hasPermissions
assert.isUndefined e1
try
resource.currentUser.id = 'YYY4'
hasPermissions = yield resource[key] 'XXX', 'ZZZ'
catch e2
hasPermissions = no
assert.isFalse hasPermissions
assert.instanceOf e2, httpErrors.Forbidden
assert.propertyVal e2, 'message', 'Current user has no access'
facade.remove()
yield return
describe '#checkPermission', ->
facade = null
KEY = 'TEST_CHECK_PERMISSIONS_MIXIN_004'
after ->
facade?.remove?()
it 'should check if permission is enough', ->
co ->
class Test extends LeanRC
@inheritProtected()
@root "#{__dirname}/config/root"
Test.initialize()
facade = Test::Facade.getInstance KEY
configs = Test::Configuration.new Test::CONFIGURATION, Test::ROOT
facade.registerProxy configs
class TestResource extends Test::Resource
@inheritProtected()
@include Test::CheckPermissionsMixin
@module Test
@public entityName: String,
default: 'TestEntity'
@initialHook 'checkPermission'
TestResource.initialize()
class TestRouter extends Test::Router
@inheritProtected()
@module Test
TestRouter.initialize()
facade.registerProxy TestRouter.new 'TEST_SWITCH_ROUTER'
class TestSwitch extends Test::Switch
@inheritProtected()
@module Test
@public routerName: String,
configurable: yes
default: 'TEST_SWITCH_ROUTER'
TestSwitch.initialize()
class MemoryCollection extends LeanRC::Collection
@inheritProtected()
@include LeanRC::MemoryCollectionMixin
@include LeanRC::GenerateUuidIdMixin
@module Test
@public @async findBy: Function,
default: (query) ->
item = _.chain @[Symbol.for '~collection']
.values()
.find query
.value()
result = if item? then [ item ] else []
yield return LeanRC::Cursor.new @, result
MemoryCollection.initialize()
class Role extends Test::Record
@inheritProtected()
@module Test
@attribute spaceId: String
@attribute userId: String
@attribute rules: Object
Role.initialize()
class Space extends Test::Record
@inheritProtected()
@module Test
@attribute ownerId: String
Space.initialize()
facade.registerProxy MemoryCollection.new Test::SPACES,
delegate: Space
serializer: Test::Serializer
facade.registerProxy MemoryCollection.new Test::ROLES,
delegate: Role
serializer: Test::Serializer
body = '{"test":"test"}'
class MyRequest extends IncomingMessage
constructor: (socket) ->
super socket
@method = 'POST'
@url = 'http://localhost:8888/space/SPACE123/test_entity'
@headers =
'x-forwarded-for': '192.168.0.1'
'content-type': 'application/json'
'content-length': "#{body.length}"
@push body
@push null
class MyResponse extends ServerResponse
facade.registerMediator TestSwitch.new 'TEST_SWITCH_MEDIATOR'
switchMediator = facade.retrieveMediator 'TEST_SWITCH_MEDIATOR'
class TestEntity extends LeanRC::Record
@inheritProtected()
@module Test
@attribute test: String
@attribute ownerId: String
@public @static findRecordByName: Function,
default: (asType) -> Test::TestEntity
@public init: Function,
default: ->
@super arguments...
@type = 'Test::TestEntity'
TestEntity.initialize()
spaces = facade.retrieveProxy Test::SPACES
space = yield spaces.create id: 'XXX', ownerId: 'YYY3'
roles = facade.retrieveProxy Test::ROLES
yield roles.create
id: 'AAA1'
spaceId: 'XXX'
userId: 'YYY1'
rules: system: administrator: yes
yield roles.create
id: 'AAA2'
spaceId: 'XXX'
userId: 'YYY2'
rules: moderator: 'Test::TestResource': yes
yield roles.create
id: 'AAA3'
spaceId: 'XXX'
userId: 'YYY3'
rules: 'Test::TestResource': list: yes
resource = Test::TestResource.new()
{ collectionName } = resource
boundCollection = MemoryCollection.new collectionName,
delegate: TestEntity
facade.registerProxy boundCollection
req = new MyRequest
res = new MyResponse req
voContext = Test::Context.new req, res, switchMediator
voContext.pathParams = space: 'XXX'
resource.context = voContext
resource.currentUser = id: 'YYY', role: 'user'
resource.currentUser.isAdmin = no
resource.initializeNotifier KEY
try
yield resource.checkPermission()
catch error1
assert.instanceOf error1, httpErrors.Forbidden
assert.propertyVal error1, 'message', 'Current user has no access'
resource.currentUser.role = 'admin'
resource.currentUser.isAdmin = yes
yield resource.checkPermission()
resource.currentUser.role = 'user'
resource.currentUser.isAdmin = no
try
yield resource.list voContext
catch error2
assert.instanceOf error2, httpErrors.Forbidden
assert.propertyVal error2, 'message', 'Current user has no access'
req = new MyRequest
res = new MyResponse req
voContext = Test::Context.new req, res, switchMediator
voContext.pathParams = space: 'XXX'
resource.currentUser = id: 'YYY3', role: 'user'
resource.currentUser.isAdmin = no
try
yield resource.list voContext
catch error3
assert.isUndefined error3
yield return
###