Skip to content

Commit

Permalink
Add support for recursive inclusion of roles
Browse files Browse the repository at this point in the history
  • Loading branch information
Tim Connor committed Dec 19, 2018
1 parent 727e1fe commit 4807ccc
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 14 deletions.
11 changes: 5 additions & 6 deletions lib/declarative_authorization/authorization.rb
Original file line number Diff line number Diff line change
Expand Up @@ -345,17 +345,16 @@ def user_roles_privleges_from_options(privilege, options)
[user, roles, privileges]
end

def flatten_roles(roles)
def flatten_roles(roles, ignore: [])
# TODO: caching?
hierarchy = role_hierarchy
flattened_roles = {}
roles.each do |role|
flattened_roles[role] = true
if (hierarchy_for_role = hierarchy[role])
hierarchy_for_role.each do |r|
flattened_roles[r] = true
end
end

children = (hierarchy[role] || []) - ignore
ignore += flattened_roles.keys
flattened_roles.merge!(flatten_roles(children, ignore: ignore)) if children.any?
end
flattened_roles
end
Expand Down
84 changes: 76 additions & 8 deletions test/authorization_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -387,11 +387,11 @@ def test_role_hierarchy
end
}
engine = Authorization::Engine.new(reader)
assert engine.permit?(:lower, :context => :permissions,
:user => MockUser.new(:test_role))
assert engine.permit?(:test, context: :permissions, user: MockUser.new(:test_role))
assert engine.permit?(:lower, context: :permissions, user: MockUser.new(:test_role))
end

def test_role_hierarchy_infinity
def test_role_hierarchy__recursive
reader = Authorization::Reader::DSLReader.new
reader.parse %{
authorization do
Expand All @@ -400,14 +400,61 @@ def test_role_hierarchy_infinity
has_permission_on :permissions, :to => :test
end
role :lower_role do
includes :higher_role
has_permission_on :permissions, :to => :lower
includes :lowest_role
end
role :lowest_role do
has_permission_on :permissions, :to => :lowest
end
end
}
engine = Authorization::Engine.new(reader)
assert engine.permit?(:lower, :context => :permissions,
:user => MockUser.new(:test_role))
assert engine.permit?(:test, context: :permissions, user: MockUser.new(:test_role))
assert engine.permit?(:lower, context: :permissions, user: MockUser.new(:test_role))
assert engine.permit?(:lowest, context: :permissions, user: MockUser.new(:test_role))
end

def test_role_hierarchy__circular
reader = Authorization::Reader::DSLReader.new
reader.parse %{
authorization do
role :test_role do
includes :lower_role
has_permission_on :permissions, :to => :test
end
role :lower_role do
includes :test_role
has_permission_on :permissions, :to => :lower
end
end
}
engine = Authorization::Engine.new(reader)
assert engine.permit?(:test, context: :permissions, user: MockUser.new(:test_role))
assert engine.permit?(:lower, context: :permissions, user: MockUser.new(:test_role))
end

def test_role_hierarchy__recursive__circular
reader = Authorization::Reader::DSLReader.new
reader.parse %{
authorization do
role :test_role do
includes :lower_role
has_permission_on :permissions, :to => :test
end
role :lower_role do
includes :lowest_role
has_permission_on :permissions, :to => :lower
end
role :lowest_role do
includes :test_role
has_permission_on :permissions, :to => :lowest
end
end
}
engine = Authorization::Engine.new(reader)
assert engine.permit?(:test, context: :permissions, user: MockUser.new(:test_role))
assert engine.permit?(:lower, context: :permissions, user: MockUser.new(:test_role))
assert engine.permit?(:lowest, context: :permissions, user: MockUser.new(:test_role))
end

def test_privilege_hierarchy
Expand All @@ -425,8 +472,29 @@ def test_privilege_hierarchy
end
}
engine = Authorization::Engine.new(reader)
assert engine.permit?(:lower, :context => :permissions,
:user => MockUser.new(:test_role))
assert engine.permit?(:lower, context: :permissions, user: MockUser.new(:test_role))
end

def test_privilege_hierarchy__recursive
reader = Authorization::Reader::DSLReader.new
reader.parse %{
privileges do
privilege :test, :permissions do
includes :lower
end
privilege :lower, :permissions do
includes :lowest
end
end
authorization do
role :test_role do
has_permission_on :permissions, :to => :test
end
end
}
engine = Authorization::Engine.new(reader)
assert engine.permit?(:lower, context: :permissions, user: MockUser.new(:test_role))
assert engine.permit?(:lowest, context: :permissions, user: MockUser.new(:test_role))
end

def test_privilege_hierarchy_without_context
Expand Down

0 comments on commit 4807ccc

Please sign in to comment.