#!/usr/local/bin/coffee
#!/usr/local/bin/coffee
This is an implmentation of Role-Based Access Control in CoffeeScript. The intended uses are in NodeJS (for access control) and in the browser (for ui creation). It is based on http://csrc.nist.gov/rbac/sandhu-ferraiolo-kuhn-00.pdf [The NIST Model for Role-Based Access Control: Towards A Unified Standard] Functional Capabilities define the space of RBAC implementations
Other Reading: Role-Based Access Control (RBAC) Lab – Minix Version http://www.cis.syr.edu/~wedu/seed/Labs/RBAC_Cap/RBAC_Cap.pdf An assignment to add RBAC security to Minix
An enhancement of the Role-Based Access Control model to facilitate information access management in context of team collaboration and workflow http://www.sciencedirect.com/science/article/pii/S1532046412000913
Constraints in Role-Based Access Control http://www.isg.rhul.ac.uk/~jason/Slides/sacmat03.pdf
class Organization
constructor: (id) ->
@getId = -> id
@roles = new Array
addRole: (a_role) ->
@roles.push(a_role)
getRoles: ->
(role for role in @roles)
class Role
has ManyToMany with Organization: OrgHasRole
constructor: (id,_includes_roles) ->
@__ = {incl: _includes_roles or [], perms: []}
@getId = -> id
getIncludedRoles: () ->
return (role for role in @__.incl)
removeRole: (a_role) ->
idx = @__.incl.indexOf a_role
if idx > -1
@__.incl.splice(idx,1)
includesRole: (a_role) ->
console.log @_.incl,a_role.getId()
a_role in @__.incl
includeRole: (a_role) ->
if @__.incl.indexOf(a_role) is -1
@__.incl.push(a_role)
addPermission: (a_perm) ->
@__.perms.push(a_perm)
hasPermission: (a_perm) ->
@__.perms.indexOf(a_perm) > -1
removePermission: (a_perm) ->
idx = @__.perms.indexOf(a_perm)
if idx > -1
@__.perms.splice(idx,1)
permitsOperation: (an_op) ->
if @directlyPermitsOperation an_op
return true
for role in @__.incl
if role.permitsOperation an_op
return true
return false
directlyPermitsOperation: (an_op) ->
for perm in @__.perms
if perm.hasOperation an_op
return true
return false
class Operation
constructor: (id) ->
@getId = -> id
class Permission
has ManyToMany with Operation: PermissionHasOperation (PermissionForOperation?)
constructor: (id) ->
@_ = {ops: []}
@getId = -> id
addOperation: (an_op) ->
if an_op.constructor isnt exports.Operation
throw new TypeError "'#{an_op}' is not an rbac.Operation "
if not @hasOperation(an_op)
@_.ops.push(an_op)
hasOperation: (an_op) ->
@_.ops.indexOf(an_op) isnt -1
removeOperation: (an_op) ->
idx = @_.ops.indexOf(an_op)
if idx > -1
@_.ops.splice(idx,1)
class Actor
Person, Program or Machine (RBAC Subject) has ManyToMany with Role: ActorHasRole has OneToMany with Session (each Actor can have many Sessions)
constructor: (id) ->
@_ = {roles: []}
@getId = -> id
addRole: (a_role) ->
if not @hasRole(a_role)
@_.roles.push(a_role)
hasRole: (a_role) ->
@_.roles.indexOf(a_role) isnt -1
removeRole: (a_role) ->
idx = @_.roles.indexOf(a_role)
if idx > -1
@_.roles.splice(idx,1)
class Session
has ManyToOne with Actor (each Session is associated with one Actor) has ManyToMany with Role: SessionUsingRole
constructor: (id,actor,role) ->
@getActor = -> actor
@getId = -> id
@__ = {role: role}
setRole: (a_role) ->
@__.role = a_role
getRole: ->
@__.role
permitsOperation: (an_op) ->
@__.role.permitsOperation an_op
class ActorRoleConstraint
constructor: (@id,@actor_has_role) ->
class RoleActivationConstraint
constructor: (@id,@session_using_role) ->
(exports ? this).Actor = Actor
(exports ? this).Organization = Organization
(exports ? this).Operation = Operation
(exports ? this).Permission = Permission
(exports ? this).Role = Role
(exports ? this).Session = Session
(exports ? this).ActorRoleConstraint = ActorRoleConstraint
(exports ? this).RoleActivationConstraint = RoleActivationConstraint