adva_rbac 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE +22 -0
  5. data/NOTES +98 -0
  6. data/README.md +29 -0
  7. data/Rakefile +2 -0
  8. data/adva_rbac.gemspec +17 -0
  9. data/app/controllers/roles_controller.rb +28 -0
  10. data/app/helpers/roles_helper.rb +64 -0
  11. data/app/views/admin/sections/settings/_permissions.html.erb +16 -0
  12. data/app/views/roles/index.js.erb +3 -0
  13. data/config/initializers/base_controller.rb +4 -0
  14. data/config/initializers/rbac.rb +60 -0
  15. data/config/initializers/user.rb +80 -0
  16. data/db/migrate/20080402000006_create_role_tables.rb +13 -0
  17. data/db/migrate/20090720132900_migrate_roles_table_to_new_rbac.rb +15 -0
  18. data/lib/action_controller/guards_permissions.rb +77 -0
  19. data/lib/adva_rbac.rb +18 -0
  20. data/lib/adva_rbac/version.rb +3 -0
  21. data/lib/permission_map.rb +70 -0
  22. data/lib/rbac.rb +26 -0
  23. data/lib/rbac/acts_as_role_context.rb +44 -0
  24. data/lib/rbac/acts_as_role_subject.rb +65 -0
  25. data/lib/rbac/context.rb +85 -0
  26. data/lib/rbac/role.rb +10 -0
  27. data/lib/rbac/role_type.rb +73 -0
  28. data/lib/rbac/role_type/active_record.rb +47 -0
  29. data/lib/rbac/role_type/static.rb +144 -0
  30. data/lib/rbac/subject.rb +52 -0
  31. data/test/functional/roles_controller_test.rb +21 -0
  32. data/test/integration/user_rbac_test.rb +34 -0
  33. data/test/rbac/all.rb +3 -0
  34. data/test/rbac/database.rb +155 -0
  35. data/test/rbac/database.yml +3 -0
  36. data/test/rbac/implementation/active_record_test.rb +17 -0
  37. data/test/rbac/implementation/static_test.rb +14 -0
  38. data/test/rbac/static.rb +25 -0
  39. data/test/rbac/test_helper.rb +62 -0
  40. data/test/rbac/tests/acts_as_role_context.rb +37 -0
  41. data/test/rbac/tests/context.rb +35 -0
  42. data/test/rbac/tests/group.rb +40 -0
  43. data/test/rbac/tests/has_role.rb +126 -0
  44. data/test/rbac/tests/role_type.rb +110 -0
  45. data/test/test_helper.rb +1 -0
  46. data/test/unit/helpers/roles_helper_test.rb +69 -0
  47. data/test/unit/models/rbac_context_test.rb +37 -0
  48. data/test/unit/models/rbac_user_test.rb +100 -0
  49. data/test/unit/models/role_test.rb +185 -0
  50. metadata +110 -0
@@ -0,0 +1,3 @@
1
+ test:
2
+ adapter: sqlite3
3
+ database: ":memory:"
@@ -0,0 +1,17 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ class RoleTypeActiveRecordTest < Test::Unit::TestCase
4
+ def setup
5
+ Rbac::RoleType.implementation = Rbac::RoleType::ActiveRecord::RoleType
6
+ end
7
+
8
+ # include Tests::ActsAsRoleContext
9
+ include Tests::Context
10
+ include Tests::HasRole
11
+ include Tests::RoleType
12
+ include Tests::Group
13
+
14
+ # def test_foo
15
+ # p superuser_type.minions
16
+ # end
17
+ end
@@ -0,0 +1,14 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ class RoleTypeStaticTest < Test::Unit::TestCase
4
+ def setup
5
+ Rbac::RoleType.implementation = Rbac::RoleType::Static
6
+ end
7
+
8
+ include Rbac::RoleType::Static
9
+ include Tests::ActsAsRoleContext
10
+ include Tests::Context
11
+ include Tests::HasRole
12
+ include Tests::RoleType
13
+ include Tests::Group
14
+ end
@@ -0,0 +1,25 @@
1
+ module Rbac
2
+ module RoleType
3
+ module Static
4
+ self.role_types = [:editor, :superuser, :moderator, :author, :user, :anonymous, :pizzaboy]
5
+
6
+ module Pizzaboy
7
+ extend Rbac::RoleType
8
+
9
+ class << self
10
+ def requires_context?
11
+ true
12
+ end
13
+
14
+ def masters
15
+ []
16
+ end
17
+
18
+ def minions
19
+ []
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,62 @@
1
+ $: << File.dirname(__FILE__) + '/../lib'
2
+
3
+ require 'rubygems'
4
+ require 'active_record'
5
+ require 'activesupport'
6
+ require 'test/unit'
7
+ require 'rbac'
8
+
9
+ require 'rbac/role_type/static'
10
+ require 'rbac/role_type/active_record'
11
+
12
+ require File.dirname(__FILE__) + '/database'
13
+ require File.dirname(__FILE__) + '/static'
14
+
15
+ Dir[File.dirname(__FILE__) + '/tests/*.rb'].each do |filename|
16
+ require filename
17
+ end
18
+
19
+
20
+ class Test::Unit::TestCase
21
+ def self.test(name, &block)
22
+ define_method("test: " + name, &block)
23
+ end
24
+
25
+ def with_default_permissions(permissions_map={}, &block)
26
+ original_permissions = Rbac::Context.default_permissions
27
+ Rbac::Context.default_permissions = permissions_map
28
+ yield
29
+ Rbac::Context.default_permissions = original_permissions
30
+ end
31
+
32
+ protected
33
+
34
+ def method_missing(method, *args)
35
+ return Rbac::RoleType.build(method.to_s.gsub(/_type/, '')) if method.to_s =~ /_type$/
36
+ return ::User.find_by_name(method.to_s) if user_names.include?(method.to_s)
37
+ return ::Group.find_by_name(method.to_s) if group_names.include?(method.to_s)
38
+ super
39
+ end
40
+
41
+ def user_names
42
+ @user_names ||= User.scoped.map(&:name)
43
+ end
44
+
45
+ def group_names
46
+ @group_names ||= Group.scoped.map(&:name)
47
+ end
48
+
49
+ def blog
50
+ ::Section.find_by_title('blog')
51
+ end
52
+
53
+ def content
54
+ ::Content.find_by_title('content')
55
+ end
56
+ end
57
+
58
+ module TestHelper
59
+ def self.test(name, &block)
60
+ define_method("test: " + name, &block)
61
+ end
62
+ end
@@ -0,0 +1,37 @@
1
+ module Tests
2
+ module ActsAsRoleContext
3
+ define_method "test: Content acts as a role context" do
4
+ assert_equal true, Content.acts_as_role_context?
5
+ end
6
+
7
+ define_method "test: there is an Rbac root context" do
8
+ assert_equal true, Rbac::Context.root.is_a?(Rbac::Context::Base)
9
+ end
10
+
11
+ define_method "test: content can instantiate its role context decorator" do
12
+ assert_equal Content::RoleContext, content.role_context.class
13
+ end
14
+
15
+ define_method "test: the content's role_context's parent is the blog's role_context" do
16
+ assert_equal blog, content.role_context.parent.object
17
+ end
18
+
19
+ define_method "test: the section's role_context's parent is the root context" do
20
+ assert_equal Rbac::Context.root, blog.role_context.parent
21
+ end
22
+
23
+ define_method "test: the blog's role_context includes the content's role_context" do
24
+ assert_equal true, blog.role_context.include?(content.role_context)
25
+ end
26
+
27
+ protected
28
+
29
+ def blog
30
+ @blog ||= ::Section.find_by_title('blog')
31
+ end
32
+
33
+ def content
34
+ @content ||= Content.find_by_title('content')
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,35 @@
1
+ module Tests
2
+ module Context
3
+ define_method "test: authorizing_role_types_for raises when given action is nil" do
4
+ assert_raises(ArgumentError) { content.role_context.authorizing_role_types_for(nil) }
5
+ end
6
+
7
+ define_method "test: authorizing_role_types_for falls back to permissions from root context" do
8
+ with_default_permissions(:'edit content' => [:author]) do
9
+ assert_equal [:author], content.role_context.authorizing_role_types_for('edit content')
10
+ end
11
+ end
12
+
13
+ define_method "test: authorizing_role_types_for uses object's permissions if given" do
14
+ content = self.content
15
+ content.permissions = { :'edit content' => [:superuser] }
16
+ assert_equal [:superuser], content.role_context.authorizing_role_types_for('edit content')
17
+ end
18
+
19
+ define_method "test: expand_roles_for permutate all roles from authorizing_role_types_for w/ all context types" do
20
+ content = self.content
21
+ with_default_permissions(:'edit content' => [:user]) do
22
+ content.permissions = { :'edit content' => [:moderator] }
23
+ expected = %w(author-content-1 author-section-1 editor-content-1 editor-section-1 moderator-content-1 moderator-section-1 superuser user)
24
+ actual = content.role_context.expand_roles_for('edit content')
25
+ assert_equal expected, actual.sort
26
+ end
27
+ end
28
+
29
+ protected
30
+
31
+ def content
32
+ Content.find_by_title('content')
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,40 @@
1
+ module Tests
2
+ module Group
3
+ define_method "test: make sure people are members of their groups" do
4
+ assert_equal true, beatles.members.include?(john)
5
+ assert_equal true, beatles.members.include?(paul)
6
+
7
+ assert_equal true, stones.members.include?(mick)
8
+ assert_equal true, stones.members.include?(keith)
9
+ end
10
+
11
+ define_method "test: make sure people aren't members of groups they don't belong to" do
12
+ assert_equal false, stones.members.include?(john)
13
+ assert_equal false, stones.members.include?(paul)
14
+
15
+ assert_equal false, beatles.members.include?(mick)
16
+ assert_equal false, beatles.members.include?(keith)
17
+ end
18
+
19
+ define_method "test: people should inherit roles from their groups" do
20
+ assert_equal true, beatles.has_role?(:superuser)
21
+ assert_equal true, john.has_role?(:superuser)
22
+ assert_equal true, paul.has_role?(:superuser)
23
+
24
+ assert_equal true, stones.has_role?(:pizzaboy)
25
+ assert_equal true, mick.has_role?(:pizzaboy)
26
+ assert_equal true, keith.has_role?(:pizzaboy)
27
+ end
28
+
29
+ define_method "test: people should inherit permissions from their groups" do
30
+ with_default_permissions(:'edit content' => [:editor]) do
31
+ content = self.content
32
+ content.section.permissions = { :'edit content' => [:pizzaboy] }
33
+
34
+ assert_equal true, stones.has_permission?('edit content', content)
35
+ assert_equal true, mick.has_permission?('edit content', content)
36
+ assert_equal true, keith.has_permission?('edit content', content)
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,126 @@
1
+ module Tests
2
+ module HasRole
3
+
4
+ define_method "test: a superuser has the global role :superuser" do
5
+ assert_equal true, superuser.has_global_role?(:superuser)
6
+ assert_equal true, superuser.has_global_role?(:superuser, site)
7
+ assert_equal true, superuser.has_global_role?(:superuser, another_site)
8
+ end
9
+
10
+ define_method "test: a admin has the global role :admin on 'site'" do
11
+ assert_equal true, site_admin.has_global_role?(:admin, site)
12
+ end
13
+
14
+ define_method "test: a moderator for 'site' has the global role :moderator on 'site'" do
15
+ assert_equal true, site_moderator.has_global_role?(:moderator, site)
16
+ end
17
+
18
+ define_method "test: a author for 'site' has the global role :author on 'site'" do
19
+ assert_equal true, site_author.has_global_role?(:author, site)
20
+ end
21
+
22
+ define_method "test: a designer for 'site' has the global role :designer on 'site'" do
23
+ assert_equal true, site_designer.has_global_role?(:designer, site)
24
+ end
25
+
26
+ define_method "test: a admin does not have the global role :admin on 'another site'" do
27
+ assert_equal false, site_admin.has_global_role?(:admin, another_site)
28
+ end
29
+
30
+ define_method "test: a moderator for a section (blog) of 'site' does not have the global role :moderator on 'site'" do
31
+ assert_equal false, blog_moderator.has_global_role?(:moderator, site)
32
+ end
33
+
34
+ define_method "test: a superuser has permissions for the admin areas of all sites" do
35
+ assert_equal true, superuser.has_permission_for_admin_area?(site)
36
+ assert_equal true, superuser.has_permission_for_admin_area?(another_site)
37
+ end
38
+
39
+ define_method "test: a admin, moderator, author and designer for 'site' have permission for the admin area of 'site'" do
40
+ assert_equal true, site_admin.has_permission_for_admin_area?(site)
41
+ assert_equal true, site_moderator.has_permission_for_admin_area?(site)
42
+ assert_equal true, site_author.has_permission_for_admin_area?(site)
43
+ assert_equal true, site_designer.has_permission_for_admin_area?(site)
44
+ end
45
+
46
+ define_method "test: a admin, moderator, author and designer for 'site' do not have permissions for the admin area of 'another_site'" do
47
+ assert_equal false, site_admin.has_permission_for_admin_area?(another_site)
48
+ assert_equal false, site_moderator.has_permission_for_admin_area?(another_site)
49
+ assert_equal false, site_author.has_permission_for_admin_area?(another_site)
50
+ assert_equal false, site_designer.has_permission_for_admin_area?(another_site)
51
+ end
52
+
53
+ define_method "test: a moderator for a section (blog) of a 'site' does not have permission for the admin area of 'site'" do
54
+ assert_equal false, blog_moderator.has_permission_for_admin_area?(site)
55
+ end
56
+
57
+ define_method "test: has_role? (single argument)" do
58
+ assert_equal true, superuser.has_role?(:superuser)
59
+ assert_equal true, superuser.has_role?(:user)
60
+ assert_equal true, superuser.has_role?(:anonymous)
61
+ end
62
+
63
+ define_method "test: has_role? (array argument)" do
64
+ assert_equal false, moderator.has_role?([:superuser])
65
+ assert_equal false, moderator.has_role?([:moderator, :superuser])
66
+ assert_equal true, moderator.has_role?([:moderator, :superuser], blog)
67
+ assert_equal true, moderator.has_role?([:author, :superuser], content)
68
+ end
69
+
70
+ define_method "test: has_explicit_role?" do
71
+ assert_equal true, superuser.has_explicit_role?(:superuser)
72
+ assert_equal false, superuser.has_explicit_role?(:user)
73
+ assert_equal false, superuser.has_explicit_role?(:anonymous)
74
+ end
75
+
76
+ define_method "test: has_permission? raises Rbac::AuthorizingRoleNotFound exception when authorizing role can not be found" do
77
+ assert_raises(Rbac::AuthorizingRoleNotFound) { superuser.has_permission?('drink redbull', Rbac::Context.root) }
78
+ end
79
+
80
+ define_method "test: has_permission? returns true when the user has a role that authorizes the action" do
81
+ with_default_permissions(:'edit content' => [:author]) do
82
+ assert_equal true, superuser.has_permission?('edit content', Rbac::Context.root)
83
+ end
84
+ end
85
+
86
+ define_method "test: has_permission? returns true for authorized roles that aren't part of the same role hierarchy" do
87
+ with_default_permissions(:'edit content' => [:editor]) do
88
+ content = self.content
89
+ content.section.permissions = { :'edit content' => [:moderator] }
90
+ assert_equal true, moderator.has_permission?('edit content', content)
91
+ assert_equal true, editor.has_permission?('edit content', content)
92
+ end
93
+ end
94
+
95
+ protected
96
+
97
+ def site
98
+ @site ||= ::Site.find_by_name('a site')
99
+ end
100
+
101
+ def another_site
102
+ @another_site ||= ::Site.find_by_name('another site')
103
+ end
104
+
105
+ def site_admin
106
+ @site_admin ||= ::User.find_by_name('site admin')
107
+ end
108
+
109
+ def blog_moderator
110
+ @blog_moderator ||= ::User.find_by_name('moderator')
111
+ end
112
+
113
+ def site_moderator
114
+ @site_moderator ||= ::User.find_by_name('site moderator')
115
+ end
116
+
117
+ def site_author
118
+ @site_author ||= ::User.find_by_name('author')
119
+ end
120
+
121
+ def site_designer
122
+ @site_designer ||= ::User.find_by_name('designer')
123
+ end
124
+
125
+ end
126
+ end
@@ -0,0 +1,110 @@
1
+ module Tests
2
+ module RoleType
3
+ define_method "test: RoleType knows all available types" do
4
+ expected = %w(anonymous author editor moderator superuser user)
5
+ actual = Rbac::RoleType.types.map(&:name).sort
6
+ assert_equal expected, actual & expected
7
+ end
8
+
9
+ define_method "test: masters" do
10
+ assert_equal [], superuser_type.masters.map(&:name)
11
+ assert_equal ['superuser'], moderator_type.masters.map(&:name)
12
+ assert_equal ['superuser'], editor_type.masters.map(&:name)
13
+ assert_equal ['moderator'], author_type.masters.map(&:name)
14
+ assert_equal ['author', 'editor'], user_type.masters.map(&:name).sort
15
+ assert_equal ['user'], anonymous_type.masters.map(&:name)
16
+ end
17
+
18
+ define_method "test: all_masters" do
19
+ assert_equal [], superuser_type.all_masters.map(&:name).sort
20
+ assert_equal ['superuser'], moderator_type.all_masters.map(&:name).sort
21
+ assert_equal ['superuser'], editor_type.all_masters.map(&:name)
22
+ assert_equal ['moderator', 'superuser'], author_type.all_masters.map(&:name).sort
23
+ assert_equal ['author', 'editor', 'moderator', 'superuser'], user_type.all_masters.map(&:name).sort
24
+ assert_equal ['author', 'editor', 'moderator', 'superuser', 'user'], anonymous_type.all_masters.map(&:name).sort
25
+ end
26
+
27
+ define_method "test: self_and_masters" do
28
+ assert_equal ['superuser'], superuser_type.self_and_masters.map(&:name).sort
29
+ assert_equal ['moderator', 'superuser'], moderator_type.self_and_masters.map(&:name).sort
30
+ assert_equal ['editor', 'superuser'], editor_type.self_and_masters.map(&:name)
31
+ assert_equal ['author', 'moderator', 'superuser'], author_type.self_and_masters.map(&:name).sort
32
+ assert_equal ['author', 'editor', 'moderator', 'superuser', 'user'], user_type.self_and_masters.map(&:name).sort
33
+ assert_equal ['anonymous', 'author', 'editor', 'moderator', 'superuser', 'user'], anonymous_type.self_and_masters.map(&:name).sort
34
+ end
35
+
36
+ define_method "test: minions" do
37
+ assert_equal ['editor', 'moderator'], superuser_type.minions.map(&:name).sort
38
+ assert_equal ['author'], moderator_type.minions.map(&:name).sort
39
+ assert_equal ['user'], author_type.minions.map(&:name).sort
40
+ assert_equal ['user'], editor_type.minions.map(&:name).sort
41
+ assert_equal ['anonymous'], user_type.minions.map(&:name).sort
42
+ assert_equal [], anonymous_type.minions.map(&:name).sort
43
+ end
44
+
45
+ define_method "test: all_minions" do
46
+ assert_equal ['anonymous', 'author', 'editor', 'moderator', 'user'], superuser_type.all_minions.map(&:name).sort
47
+ assert_equal ['anonymous', 'author', 'user'], moderator_type.all_minions.map(&:name).sort
48
+ assert_equal ['anonymous', 'user'], author_type.all_minions.map(&:name).sort
49
+ assert_equal ['anonymous', 'user'], editor_type.all_minions.map(&:name).sort
50
+ assert_equal ['anonymous'], user_type.all_minions.map(&:name).sort
51
+ assert_equal [], anonymous_type.all_minions.map(&:name).sort
52
+ end
53
+
54
+ define_method "test: self_and_minions" do
55
+ assert_equal ['anonymous', 'author', 'editor', 'moderator', 'superuser', 'user'], superuser_type.self_and_minions.map(&:name).sort
56
+ assert_equal ['anonymous', 'author', 'moderator', 'user'], moderator_type.self_and_minions.map(&:name).sort
57
+ assert_equal ['anonymous', 'author', 'user'], author_type.self_and_minions.map(&:name).sort
58
+ assert_equal ['anonymous', 'editor', 'user'], editor_type.self_and_minions.map(&:name).sort
59
+ assert_equal ['anonymous', 'user'], user_type.self_and_minions.map(&:name).sort
60
+ assert_equal ['anonymous'], anonymous_type.self_and_minions.map(&:name).sort
61
+ end
62
+
63
+ define_method "test: RoleType#build returns an Rbac::RoleType" do
64
+ %w(anonymous author editor moderator superuser user).each do |role_type|
65
+ assert Rbac::RoleType.build(role_type.to_sym).respond_to?(:granted_to?)
66
+ end
67
+ end
68
+
69
+ define_method "test: RoleType#granted_to? returns true for assigned role and all minion roles" do
70
+ assert_equal true, superuser_type.granted_to?(superuser)
71
+ assert_equal true, moderator_type.granted_to?(superuser)
72
+ assert_equal true, editor_type.granted_to?(superuser)
73
+ assert_equal true, author_type.granted_to?(superuser, content)
74
+ assert_equal true, user_type.granted_to?(superuser)
75
+ assert_equal true, anonymous_type.granted_to?(superuser)
76
+
77
+ assert_equal false, superuser_type.granted_to?(moderator)
78
+ assert_equal false, editor_type.granted_to?(moderator)
79
+ assert_equal false, moderator_type.granted_to?(moderator)
80
+ assert_equal true, moderator_type.granted_to?(moderator, blog)
81
+ assert_equal true, author_type.granted_to?(moderator, content)
82
+ assert_equal true, user_type.granted_to?(moderator)
83
+ assert_equal true, anonymous_type.granted_to?(moderator )
84
+
85
+ assert_equal false, superuser_type.granted_to?(author)
86
+ assert_equal false, editor_type.granted_to?(author)
87
+ assert_equal false, moderator_type.granted_to?(author)
88
+ assert_equal false, moderator_type.granted_to?(author, content)
89
+ assert_equal true, author_type.granted_to?(author, content)
90
+ assert_equal true, user_type.granted_to?(author)
91
+ assert_equal true, anonymous_type.granted_to?(author)
92
+
93
+ assert_equal false, superuser_type.granted_to?(user)
94
+ assert_equal false, editor_type.granted_to?(user)
95
+ assert_equal false, moderator_type.granted_to?(user)
96
+ assert_equal false, moderator_type.granted_to?(user, content)
97
+ assert_equal false, author_type.granted_to?(user, content)
98
+ assert_equal true, user_type.granted_to?(user)
99
+ assert_equal true, anonymous_type.granted_to?(user)
100
+
101
+ assert_equal false, superuser_type.granted_to?(anonymous)
102
+ assert_equal false, editor_type.granted_to?(anonymous)
103
+ assert_equal false, moderator_type.granted_to?(anonymous)
104
+ assert_equal false, moderator_type.granted_to?(anonymous, content)
105
+ assert_equal false, author_type.granted_to?(anonymous, content)
106
+ assert_equal false, user_type.granted_to?(anonymous)
107
+ assert_equal true, anonymous_type.granted_to?(anonymous)
108
+ end
109
+ end
110
+ end