cbac 0.6.1 → 0.6.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. data/Manifest +70 -74
  2. data/README.rdoc +51 -51
  3. data/Rakefile +39 -39
  4. data/cbac.gemspec +30 -31
  5. data/config/cbac/context_roles.rb +21 -21
  6. data/config/cbac/privileges.rb +50 -50
  7. data/context_roles.rb +21 -21
  8. data/init.rb +3 -3
  9. data/lib/cbac.rb +132 -132
  10. data/lib/cbac/cbac_pristine/pristine.rb +138 -135
  11. data/lib/cbac/cbac_pristine/pristine_file.rb +173 -170
  12. data/lib/cbac/cbac_pristine/pristine_permission.rb +205 -194
  13. data/lib/cbac/cbac_pristine/pristine_role.rb +41 -41
  14. data/lib/cbac/config.rb +9 -9
  15. data/lib/cbac/context_role.rb +27 -27
  16. data/lib/cbac/generic_role.rb +5 -5
  17. data/lib/cbac/known_permission.rb +14 -14
  18. data/lib/cbac/membership.rb +3 -3
  19. data/lib/cbac/permission.rb +5 -5
  20. data/lib/cbac/privilege.rb +117 -117
  21. data/lib/cbac/privilege_new_api.rb +56 -56
  22. data/lib/cbac/privilege_set.rb +29 -29
  23. data/lib/cbac/privilege_set_record.rb +6 -6
  24. data/lib/cbac/setup.rb +37 -37
  25. data/lib/generators/cbac/USAGE +33 -33
  26. data/lib/generators/cbac/cbac_generator.rb +75 -75
  27. data/lib/generators/cbac/copy_files/config/cbac.pristine +2 -2
  28. data/lib/generators/cbac/copy_files/config/context_roles.rb +17 -17
  29. data/lib/generators/cbac/copy_files/config/privileges.rb +25 -25
  30. data/lib/generators/cbac/copy_files/controllers/generic_roles_controller.rb +30 -30
  31. data/lib/generators/cbac/copy_files/controllers/memberships_controller.rb +22 -22
  32. data/lib/generators/cbac/copy_files/controllers/permissions_controller.rb +61 -61
  33. data/lib/generators/cbac/copy_files/controllers/upgrade_controller.rb +23 -23
  34. data/lib/generators/cbac/copy_files/fixtures/cbac_generic_roles.yml +9 -9
  35. data/lib/generators/cbac/copy_files/fixtures/cbac_memberships.yml +8 -8
  36. data/lib/generators/cbac/copy_files/fixtures/cbac_permissions.yml +8 -8
  37. data/lib/generators/cbac/copy_files/initializers/cbac_config.rb +4 -4
  38. data/lib/generators/cbac/copy_files/migrate/create_cbac_from_scratch.rb +59 -59
  39. data/lib/generators/cbac/copy_files/migrate/create_cbac_upgrade_path.rb +40 -31
  40. data/lib/generators/cbac/copy_files/stylesheets/cbac.css +65 -65
  41. data/lib/generators/cbac/copy_files/tasks/cbac.rake +345 -345
  42. data/lib/generators/cbac/copy_files/views/generic_roles/index.html.erb +58 -58
  43. data/lib/generators/cbac/copy_files/views/layouts/cbac.html.erb +18 -18
  44. data/lib/generators/cbac/copy_files/views/memberships/_update.html.erb +11 -11
  45. data/lib/generators/cbac/copy_files/views/memberships/index.html.erb +23 -23
  46. data/lib/generators/cbac/copy_files/views/permissions/_update_context_role.html.erb +11 -11
  47. data/lib/generators/cbac/copy_files/views/permissions/_update_generic_role.html.erb +11 -11
  48. data/lib/generators/cbac/copy_files/views/permissions/index.html.erb +39 -39
  49. data/lib/generators/cbac/copy_files/views/upgrade/index.html.erb +31 -31
  50. data/migrations/20110211105533_add_pristine_files_to_cbac_upgrade_path.rb +16 -0
  51. data/privileges.rb +50 -50
  52. data/spec/cbac_pristine_file_spec.rb +329 -329
  53. data/spec/cbac_pristine_permission_spec.rb +358 -358
  54. data/spec/cbac_pristine_role_spec.rb +85 -85
  55. data/spec/rcov.opts +1 -1
  56. data/spec/spec.opts +4 -4
  57. data/spec/spec_helper.rb +11 -11
  58. data/tasks/cbac.rake +345 -345
  59. data/test/fixtures/cbac_generic_roles.yml +9 -9
  60. data/test/fixtures/cbac_memberships.yml +8 -8
  61. data/test/fixtures/cbac_permissions.yml +14 -14
  62. data/test/fixtures/cbac_privilege_set.yml +18 -18
  63. data/test/test_cbac_actions.rb +71 -71
  64. data/test/test_cbac_authorize_context_roles.rb +39 -39
  65. data/test/test_cbac_authorize_generic_roles.rb +36 -36
  66. data/test/test_cbac_context_role.rb +50 -50
  67. data/test/test_cbac_privilege.rb +151 -151
  68. data/test/test_cbac_privilege_set.rb +50 -50
  69. data/test/test_helper.rb +28 -28
  70. metadata +14 -15
  71. data/nbproject/private/private.properties +0 -3
  72. data/nbproject/private/private.xml +0 -4
  73. data/nbproject/private/rake-d.txt +0 -0
  74. data/nbproject/project.properties +0 -9
  75. data/nbproject/project.xml +0 -16
@@ -1,9 +1,9 @@
1
- ###
2
- # Context
3
- ## YAML template for the generic roles
4
-
5
- one:
6
- id: 1
7
- name: administrator
8
- remarks: Administrators role. Grants full access to the entire system.
9
-
1
+ ###
2
+ # Context
3
+ ## YAML template for the generic roles
4
+
5
+ one:
6
+ id: 1
7
+ name: administrator
8
+ remarks: Administrators role. Grants full access to the entire system.
9
+
@@ -1,8 +1,8 @@
1
- ###
2
- # Context
3
- ## YAML template for the memberships
4
-
5
- # Making the first user member of the administrator group
6
- one:
7
- user_id: 1
8
- generic_role_id: 1
1
+ ###
2
+ # Context
3
+ ## YAML template for the memberships
4
+
5
+ # Making the first user member of the administrator group
6
+ one:
7
+ user_id: 1
8
+ generic_role_id: 1
@@ -1,15 +1,15 @@
1
- ###
2
- # Context
3
- ## YAML template for the permissions
4
- #role_id: GenericRole.get_id :authorize_context_role
5
-
6
- # used by test_cbac_authorize_context_roles
7
- one:
8
- context_role: authorize_context_role
9
- privilege_set_id: 2
10
-
11
- # used by test_cbac_authorize_generic_roles
12
- two:
13
- generic_role_id: 1
14
- privilege_set_id: 3
1
+ ###
2
+ # Context
3
+ ## YAML template for the permissions
4
+ #role_id: GenericRole.get_id :authorize_context_role
5
+
6
+ # used by test_cbac_authorize_context_roles
7
+ one:
8
+ context_role: authorize_context_role
9
+ privilege_set_id: 2
10
+
11
+ # used by test_cbac_authorize_generic_roles
12
+ two:
13
+ generic_role_id: 1
14
+ privilege_set_id: 3
15
15
 
@@ -1,18 +1,18 @@
1
- ###
2
- # YAML template for the PrivilegeSets
3
- #
4
-
5
- # Privilegeset
6
- one:
7
- id: 1
8
- name: existing_privilege_set
9
-
10
- # Used by the test_cbac_authorize_context_roles
11
- two:
12
- id: 2
13
- name: cbac_context_role
14
-
15
- # Used by the test_cbac_authorize_generic_roles
16
- three:
17
- id: 3
18
- name: cbac_generic_role
1
+ ###
2
+ # YAML template for the PrivilegeSets
3
+ #
4
+
5
+ # Privilegeset
6
+ one:
7
+ id: 1
8
+ name: existing_privilege_set
9
+
10
+ # Used by the test_cbac_authorize_context_roles
11
+ two:
12
+ id: 2
13
+ name: cbac_context_role
14
+
15
+ # Used by the test_cbac_authorize_generic_roles
16
+ three:
17
+ id: 3
18
+ name: cbac_generic_role
@@ -1,72 +1,72 @@
1
- # Copyright 2010 Bert Meerman
2
- require File.expand_path(File.join(File.dirname(__FILE__), 'test_helper'))
3
-
4
- ########
5
- # Test the actions
6
- # This test set will test whether actions and sets are created. Proper usage
7
- # of these data structures is left to other test files
8
- class CbacActionsTest < ActiveSupport::TestCase
9
- # Adding actions using a simple get or post command
10
- def test_add_simple_action
11
- cbac do
12
- set :test_add_simple_action, "test_add_simple_action" do
13
- post :foo, :bar
14
- get :foo, :bar
15
- end
16
- end
17
- end
18
-
19
- # Adding multiple methods with a single call
20
- def test_add_multiple_methods
21
- cbac do
22
- set :test_add_multiple_methods, "test_add_multiple_methods" do
23
- post :foo, [:bar, :bar2]
24
- get :foo, [:bar, :bar2]
25
- end
26
- end
27
- end
28
-
29
- # Add methods with single parameter
30
- def test_add_method_with_single_parameter
31
- cbac do
32
- set :test_add_method_with_single_parameter, "test_add_method_with_single_parameter" do
33
- post :foo, :bar, :foobar
34
- get :foo, :bar, :foobar
35
- end
36
- end
37
- end
38
-
39
- # Add methods with multiple parameters
40
- def test_add_method_with_multiple_parameter
41
- cbac do
42
- set :test_add_method_with_multiple_parameter, "test_add_method_with_multiple_parameter" do
43
- post :foo, :bar, [:foobar, :foobar2]
44
- get :foo, :bar, [:foobar, :foobar2]
45
- end
46
- end
47
- end
48
-
49
- def test_add_method_with_parameter_mapping
50
- cbac do
51
- set :test_add_method_with_parameter_mapping, "test_add_method_with_parameter_mapping" do
52
- post :foo, :bar, :foobar, {:map => :me}
53
- get :foo, :bar, :foobar, {:map => :me}
54
- end
55
- end
56
- end
57
-
58
- # Test must return multiple warnings, due to usage of _id in the identifier
59
- # specifications (parameters are /always/ identifiers
60
- def test_warning_on_adding_method_with_identifier
61
- cbac do
62
- set :test_warning_on_adding_method_with_identifier, "test_warning_on_adding_method_with_identifier" do
63
- post :foo, :bar, :foobar_id
64
- get :foo, :bar, :foobar_id
65
- post :foo, :bar, [:foobar, :foobar2_id]
66
- get :foo, :bar, [:foobar, :foobar2_id]
67
- end
68
- end
69
- end
70
-
71
- # By default, all parameters will be blocked
1
+ # Copyright 2010 Bert Meerman
2
+ require File.expand_path(File.join(File.dirname(__FILE__), 'test_helper'))
3
+
4
+ ########
5
+ # Test the actions
6
+ # This test set will test whether actions and sets are created. Proper usage
7
+ # of these data structures is left to other test files
8
+ class CbacActionsTest < ActiveSupport::TestCase
9
+ # Adding actions using a simple get or post command
10
+ def test_add_simple_action
11
+ cbac do
12
+ set :test_add_simple_action, "test_add_simple_action" do
13
+ post :foo, :bar
14
+ get :foo, :bar
15
+ end
16
+ end
17
+ end
18
+
19
+ # Adding multiple methods with a single call
20
+ def test_add_multiple_methods
21
+ cbac do
22
+ set :test_add_multiple_methods, "test_add_multiple_methods" do
23
+ post :foo, [:bar, :bar2]
24
+ get :foo, [:bar, :bar2]
25
+ end
26
+ end
27
+ end
28
+
29
+ # Add methods with single parameter
30
+ def test_add_method_with_single_parameter
31
+ cbac do
32
+ set :test_add_method_with_single_parameter, "test_add_method_with_single_parameter" do
33
+ post :foo, :bar, :foobar
34
+ get :foo, :bar, :foobar
35
+ end
36
+ end
37
+ end
38
+
39
+ # Add methods with multiple parameters
40
+ def test_add_method_with_multiple_parameter
41
+ cbac do
42
+ set :test_add_method_with_multiple_parameter, "test_add_method_with_multiple_parameter" do
43
+ post :foo, :bar, [:foobar, :foobar2]
44
+ get :foo, :bar, [:foobar, :foobar2]
45
+ end
46
+ end
47
+ end
48
+
49
+ def test_add_method_with_parameter_mapping
50
+ cbac do
51
+ set :test_add_method_with_parameter_mapping, "test_add_method_with_parameter_mapping" do
52
+ post :foo, :bar, :foobar, {:map => :me}
53
+ get :foo, :bar, :foobar, {:map => :me}
54
+ end
55
+ end
56
+ end
57
+
58
+ # Test must return multiple warnings, due to usage of _id in the identifier
59
+ # specifications (parameters are /always/ identifiers
60
+ def test_warning_on_adding_method_with_identifier
61
+ cbac do
62
+ set :test_warning_on_adding_method_with_identifier, "test_warning_on_adding_method_with_identifier" do
63
+ post :foo, :bar, :foobar_id
64
+ get :foo, :bar, :foobar_id
65
+ post :foo, :bar, [:foobar, :foobar2_id]
66
+ get :foo, :bar, [:foobar, :foobar2_id]
67
+ end
68
+ end
69
+ end
70
+
71
+ # By default, all parameters will be blocked
72
72
  end
@@ -1,39 +1,39 @@
1
- # Copyright 2010 Bert Meerman
2
- require File.expand_path(File.join(File.dirname(__FILE__), 'test_helper'))
3
-
4
- # Dummy code for overriding the default current_user behavior
5
- module Cbac
6
- def current_user
7
- 1
8
- end
9
- end
10
-
11
- ###
12
- # Tests the Cbac system for authorization with context roles
13
- #
14
- class CbacAuthorizeContextRolesTest < ActiveSupport::TestCase
15
- include Cbac
16
-
17
- #self.fixture_path = File.join(File.dirname(__FILE__), "fixtures")
18
- #fixtures :all
19
- attr_accessor :authorize_context_eval_string
20
- attr_accessor :session
21
-
22
- # Setup defines the PrivilegeSet that is being used by all PrivilegeTest methods
23
- def setup
24
- return if PrivilegeSet.sets.include?(:cbac_context_role)
25
- PrivilegeSet.add :cbac_context_role, ""
26
- Privilege.resource :cbac_context_role, "authorize/context/roles", :get
27
- ContextRole.add :authorize_context_role, "context[:authorize_context_eval_string]"
28
- end
29
-
30
- # Check to see if action is correctly authorized
31
- def test_authorize_ok
32
- assert_equal true, authorization_check("authorize/context", "roles", :get, {:authorize_context_eval_string => true})
33
- end
34
-
35
- # Run authorization with incorrect authorization
36
- def test_authorize_incorrect_privilege
37
- assert_equal false, authorization_check("authorize/context", "roles", :get, {:authorize_context_eval_string => false})
38
- end
39
- end
1
+ # Copyright 2010 Bert Meerman
2
+ require File.expand_path(File.join(File.dirname(__FILE__), 'test_helper'))
3
+
4
+ # Dummy code for overriding the default current_user behavior
5
+ module Cbac
6
+ def current_user
7
+ 1
8
+ end
9
+ end
10
+
11
+ ###
12
+ # Tests the Cbac system for authorization with context roles
13
+ #
14
+ class CbacAuthorizeContextRolesTest < ActiveSupport::TestCase
15
+ include Cbac
16
+
17
+ #self.fixture_path = File.join(File.dirname(__FILE__), "fixtures")
18
+ #fixtures :all
19
+ attr_accessor :authorize_context_eval_string
20
+ attr_accessor :session
21
+
22
+ # Setup defines the PrivilegeSet that is being used by all PrivilegeTest methods
23
+ def setup
24
+ return if PrivilegeSet.sets.include?(:cbac_context_role)
25
+ PrivilegeSet.add :cbac_context_role, ""
26
+ Privilege.resource :cbac_context_role, "authorize/context/roles", :get
27
+ ContextRole.add :authorize_context_role, "context[:authorize_context_eval_string]"
28
+ end
29
+
30
+ # Check to see if action is correctly authorized
31
+ def test_authorize_ok
32
+ assert_equal true, authorization_check("authorize/context", "roles", :get, {:authorize_context_eval_string => true})
33
+ end
34
+
35
+ # Run authorization with incorrect authorization
36
+ def test_authorize_incorrect_privilege
37
+ assert_equal false, authorization_check("authorize/context", "roles", :get, {:authorize_context_eval_string => false})
38
+ end
39
+ end
@@ -1,36 +1,36 @@
1
- # Copyright 2010 Bert Meerman
2
- require File.expand_path(File.join(File.dirname(__FILE__), 'test_helper'))
3
-
4
- # Dummy code for overriding the default current_user behavior
5
- module Cbac
6
- def current_user
7
- 1
8
- end
9
- end
10
-
11
- ###
12
- # Tests the Cbac system for authorization with generic roles
13
- #
14
- class CbacAuthorizeGenericRolesTest < ActiveSupport::TestCase
15
- #self.fixture_path = File.join(File.dirname(__FILE__), "fixtures")
16
- #fixtures :all
17
-
18
- # Setup defines the PrivilegeSet that is being used by all PrivilegeTest methods
19
- def setup
20
- return if PrivilegeSet.sets.include?(:cbac_generic_role)
21
- PrivilegeSet.add :cbac_generic_role, ""
22
- PrivilegeSet.add :cbac_generic_role_incorrect, ""
23
- Privilege.resource :cbac_generic_role, "authorize/generic/roles", :get
24
- Privilege.resource :cbac_generic_role_incorrect, "authorize/generic/roles_incorrect", :get
25
- end
26
-
27
- # Check to see if action is correctly authorized
28
- def test_authorize_ok
29
- assert_equal true, authorization_check("authorize/generic", "roles", :get)
30
- end
31
-
32
- # Run authorization with incorrect authorization
33
- def test_authorize_incorrect_privilege
34
- assert_equal false, authorization_check("authorize/generic", "roles_incorrect", :get)
35
- end
36
- end
1
+ # Copyright 2010 Bert Meerman
2
+ require File.expand_path(File.join(File.dirname(__FILE__), 'test_helper'))
3
+
4
+ # Dummy code for overriding the default current_user behavior
5
+ module Cbac
6
+ def current_user
7
+ 1
8
+ end
9
+ end
10
+
11
+ ###
12
+ # Tests the Cbac system for authorization with generic roles
13
+ #
14
+ class CbacAuthorizeGenericRolesTest < ActiveSupport::TestCase
15
+ #self.fixture_path = File.join(File.dirname(__FILE__), "fixtures")
16
+ #fixtures :all
17
+
18
+ # Setup defines the PrivilegeSet that is being used by all PrivilegeTest methods
19
+ def setup
20
+ return if PrivilegeSet.sets.include?(:cbac_generic_role)
21
+ PrivilegeSet.add :cbac_generic_role, ""
22
+ PrivilegeSet.add :cbac_generic_role_incorrect, ""
23
+ Privilege.resource :cbac_generic_role, "authorize/generic/roles", :get
24
+ Privilege.resource :cbac_generic_role_incorrect, "authorize/generic/roles_incorrect", :get
25
+ end
26
+
27
+ # Check to see if action is correctly authorized
28
+ def test_authorize_ok
29
+ assert_equal true, authorization_check("authorize/generic", "roles", :get)
30
+ end
31
+
32
+ # Run authorization with incorrect authorization
33
+ def test_authorize_incorrect_privilege
34
+ assert_equal false, authorization_check("authorize/generic", "roles_incorrect", :get)
35
+ end
36
+ end
@@ -1,50 +1,50 @@
1
- # Copyright 2010 Bert Meerman
2
- require File.expand_path(File.join(File.dirname(__FILE__), 'test_helper'))
3
-
4
- # ### Tests the Cbac::ContextRole class
5
- #
6
- class CbacContextRoleTest < ActiveSupport::TestCase
7
- # Adds a new context role This test should add a new ContextRole and
8
- # everything should be working.
9
- def test_adding_new_context_role_by_string
10
- eval_string = "true"
11
- assert_difference("ContextRole.roles.length", 1, "Failed to add new ContextRole") do
12
- ContextRole.add :test_adding_new_context_role_by_string, eval_string
13
- end
14
- assert_equal(true, ContextRole.roles.keys.include?(:test_adding_new_context_role_by_string), "ContextRole symbol not found.")
15
- result = ContextRole.roles[:test_adding_new_context_role_by_string].call(nil)
16
- assert_equal(true, result, "Incorrect eval string.")
17
- eval_string = "false"
18
- assert_difference("ContextRole.roles.length", 1, "Failed to add new ContextRole") do
19
- ContextRole.add :test_adding_new_context_role_by_string2, eval_string
20
- end
21
- assert_equal(true, ContextRole.roles.keys.include?(:test_adding_new_context_role_by_string2), "ContextRole symbol not found.")
22
- result = ContextRole.roles[:test_adding_new_context_role_by_string2].call(nil)
23
- assert_equal(false, result, "Incorrect eval string.")
24
- end
25
-
26
- # Adds a new context role This test should add a new ContextRole and
27
- # everything should be working.
28
- def test_adding_new_context_role_by_block_statement
29
- assert_difference("ContextRole.roles.length", 1, "Failed to add new ContextRole") do
30
- ContextRole.add :test_adding_new_context_role_by_block_stmt do
31
- @test = 2
32
- true
33
- end
34
- end
35
- assert_equal(true, ContextRole.roles.keys.include?(:test_adding_new_context_role_by_block_stmt), "ContextRole symbol not found.")
36
- @test = 0
37
- ContextRole.roles[:test_adding_new_context_role_by_block_stmt].call
38
- assert_equal(2, @test, "Incorrect eval string.")
39
- end
40
-
41
- # When adding an already existing ContextRole, an ArgumentError should be
42
- # raised. ContextRoles can only be declared once.
43
- def test_adding_double_context_roles
44
- ContextRole.add :test_adding_double_context_roles, ""
45
- assert_raise(ArgumentError) do
46
- ContextRole.add :test_adding_double_context_roles, ""
47
- end
48
- end
49
-
50
- end
1
+ # Copyright 2010 Bert Meerman
2
+ require File.expand_path(File.join(File.dirname(__FILE__), 'test_helper'))
3
+
4
+ # ### Tests the Cbac::ContextRole class
5
+ #
6
+ class CbacContextRoleTest < ActiveSupport::TestCase
7
+ # Adds a new context role This test should add a new ContextRole and
8
+ # everything should be working.
9
+ def test_adding_new_context_role_by_string
10
+ eval_string = "true"
11
+ assert_difference("ContextRole.roles.length", 1, "Failed to add new ContextRole") do
12
+ ContextRole.add :test_adding_new_context_role_by_string, eval_string
13
+ end
14
+ assert_equal(true, ContextRole.roles.keys.include?(:test_adding_new_context_role_by_string), "ContextRole symbol not found.")
15
+ result = ContextRole.roles[:test_adding_new_context_role_by_string].call(nil)
16
+ assert_equal(true, result, "Incorrect eval string.")
17
+ eval_string = "false"
18
+ assert_difference("ContextRole.roles.length", 1, "Failed to add new ContextRole") do
19
+ ContextRole.add :test_adding_new_context_role_by_string2, eval_string
20
+ end
21
+ assert_equal(true, ContextRole.roles.keys.include?(:test_adding_new_context_role_by_string2), "ContextRole symbol not found.")
22
+ result = ContextRole.roles[:test_adding_new_context_role_by_string2].call(nil)
23
+ assert_equal(false, result, "Incorrect eval string.")
24
+ end
25
+
26
+ # Adds a new context role This test should add a new ContextRole and
27
+ # everything should be working.
28
+ def test_adding_new_context_role_by_block_statement
29
+ assert_difference("ContextRole.roles.length", 1, "Failed to add new ContextRole") do
30
+ ContextRole.add :test_adding_new_context_role_by_block_stmt do
31
+ @test = 2
32
+ true
33
+ end
34
+ end
35
+ assert_equal(true, ContextRole.roles.keys.include?(:test_adding_new_context_role_by_block_stmt), "ContextRole symbol not found.")
36
+ @test = 0
37
+ ContextRole.roles[:test_adding_new_context_role_by_block_stmt].call
38
+ assert_equal(2, @test, "Incorrect eval string.")
39
+ end
40
+
41
+ # When adding an already existing ContextRole, an ArgumentError should be
42
+ # raised. ContextRoles can only be declared once.
43
+ def test_adding_double_context_roles
44
+ ContextRole.add :test_adding_double_context_roles, ""
45
+ assert_raise(ArgumentError) do
46
+ ContextRole.add :test_adding_double_context_roles, ""
47
+ end
48
+ end
49
+
50
+ end