has_roles 0.0.2 → 0.3.0

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 (49) hide show
  1. data/CHANGELOG.rdoc +46 -0
  2. data/{MIT-LICENSE → LICENSE} +2 -2
  3. data/README.rdoc +92 -0
  4. data/Rakefile +49 -39
  5. data/app/models/permission.rb +48 -31
  6. data/app/models/role.rb +32 -24
  7. data/app/models/role_assignment.rb +5 -6
  8. data/app/models/role_permission.rb +25 -0
  9. data/db/migrate/{002_create_permissions.rb → 001_create_permissions.rb} +4 -5
  10. data/db/migrate/{003_create_roles.rb → 002_create_roles.rb} +1 -3
  11. data/db/migrate/003_create_role_permissions.rb +11 -0
  12. data/db/migrate/{005_create_role_assignments.rb → 004_create_role_assignments.rb} +2 -3
  13. data/lib/has_roles/authorization_helper.rb +66 -47
  14. data/lib/has_roles/url_helper.rb +38 -0
  15. data/lib/has_roles.rb +29 -56
  16. data/test/app_root/app/controllers/admin/base_controller.rb +2 -0
  17. data/test/app_root/app/controllers/admin/users_controller.rb +10 -1
  18. data/test/app_root/app/controllers/application_controller.rb +7 -0
  19. data/test/app_root/config/environment.rb +6 -19
  20. data/test/app_root/config/routes.rb +1 -0
  21. data/test/app_root/db/migrate/001_create_users.rb +1 -1
  22. data/test/app_root/db/migrate/002_migrate_has_roles_to_version_4.rb +13 -0
  23. data/test/factory.rb +63 -0
  24. data/test/functional/application_controller_test.rb +45 -0
  25. data/test/functional/has_roles_test.rb +68 -0
  26. data/test/helpers/authorization_helper_test.rb +92 -0
  27. data/test/helpers/url_helper_test.rb +35 -0
  28. data/test/test_helper.rb +13 -4
  29. data/test/unit/permission_test.rb +92 -27
  30. data/test/unit/role_assignment_test.rb +46 -15
  31. data/test/unit/role_permission_test.rb +34 -0
  32. data/test/unit/role_test.rb +122 -20
  33. metadata +93 -78
  34. data/CHANGELOG +0 -19
  35. data/README +0 -83
  36. data/app/models/controller.rb +0 -82
  37. data/db/migrate/001_create_controllers.rb +0 -13
  38. data/db/migrate/004_create_permissions_roles.rb +0 -13
  39. data/test/app_root/app/controllers/payment/pay_pal/transactions_controller.rb +0 -2
  40. data/test/app_root/app/controllers/payment/transactions_controller.rb +0 -2
  41. data/test/fixtures/controllers.yml +0 -19
  42. data/test/fixtures/permissions.yml +0 -27
  43. data/test/fixtures/permissions_roles.yml +0 -15
  44. data/test/fixtures/role_assignments.yml +0 -17
  45. data/test/fixtures/roles.yml +0 -11
  46. data/test/fixtures/users.yml +0 -11
  47. data/test/unit/authorization_helper_test.rb +0 -40
  48. data/test/unit/controller_test.rb +0 -95
  49. data/test/unit/has_roles_test.rb +0 -49
data/README DELETED
@@ -1,83 +0,0 @@
1
- = has_roles
2
-
3
- +has_roles+ provides simple role management based on controllers/actions.
4
-
5
- == Resources
6
-
7
- API
8
-
9
- * http://api.pluginaweek.org/has_roles
10
-
11
- Wiki
12
-
13
- * http://wiki.pluginaweek.org/Has_roles
14
-
15
- Announcement
16
-
17
- * http://www.pluginaweek.org
18
-
19
- Source
20
-
21
- * http://svn.pluginaweek.org/trunk/plugins/active_record/has/has_roles
22
-
23
- Development
24
-
25
- * http://dev.pluginaweek.org/browser/trunk/plugins/active_record/has/has_roles
26
-
27
- == Description
28
-
29
- One of the easiest and most straightforward techniques for adding role management
30
- and authorization to specific parts of your application is restricting usage on
31
- controller/action-basis. Each role defined in your system is mapped to one or
32
- more permissions. Each permission is a combination of a controller and action.
33
-
34
- == Usage
35
-
36
- === Checking a user's authorization
37
-
38
- Below is an example of checking a user's authorization for a url before display
39
- information:
40
-
41
- app/views/layouts/application.rhtml:
42
-
43
- <% if authorized_for?(:controller => 'admin/users') -%>
44
- <p>Read to start administering your website?</p>
45
- <% end -%>
46
-
47
- === Global authorization
48
-
49
- You can define a global permission that will add access for all controllers by
50
- defining a controller with the path 'application'. See the test fixtures for
51
- more information.
52
-
53
- === Running migrations
54
-
55
- To migrate the tables required for this plugin, you can either run the
56
- migration from the command line like so:
57
-
58
- rake db:migrate:plugins PLUGIN=has_roles
59
-
60
- or (more ideally) generate a migration file that will integrate into your main
61
- application's migration path:
62
-
63
- ruby script/generate plugin_migration has_roles
64
-
65
- == Testing
66
-
67
- Before you can run any tests, the following gems must be installed:
68
- * plugin_test_helper[http://wiki.pluginaweek.org/Plugin_test_helper]
69
- * dry_validity_assertions[http://wiki.pluginaweek.org/Dry_validity_assertions]
70
-
71
- == Dependencies
72
-
73
- This plugin is a plugin+. That means that it contains a slice of an
74
- application, such as models and migrations. To test or use a plugin+, you
75
- must have the following plugins/gems installed:
76
- * plugin_dependencies[http://wiki.pluginaweek.org/Plugin_dependencies]
77
- * loaded_plugins[http://wiki.pluginaweek.org/Loaded_plugins]
78
- * appable_plugins[http://wiki.pluginaweek.org/Appable_plugins]
79
- * plugin_migrations[http://wiki.pluginaweek.org/Plugin_migrations]
80
-
81
- Instead of installing each individual plugin+ feature, you can install them all
82
- at once using the plugins+[http://wiki.pluginaweek.org/Plugins_plus] meta package,
83
- which contains all additional features.
@@ -1,82 +0,0 @@
1
- # Represents the name of a controller in the application. The path of the controller
2
- # includes its namespace, if any. For example:
3
- #
4
- # users # => UsersController
5
- # admin/users # => Admin::UsersController
6
- class Controller < ActiveRecord::Base
7
- has_many :permissions,
8
- :dependent => :destroy
9
-
10
- validates_presence_of :path
11
- validates_format_of :path,
12
- :with => /^[a-z]+(\/[a-z]+)*$/i,
13
- :allow_nil => true
14
- validates_uniqueness_of :path,
15
- :allow_nil => true
16
-
17
- class << self
18
- # Finds all of the permissioned controllers and maps/orders them by parent
19
- def find_all_mapped_by_parent
20
- controllers_by_parent = Controller.find(:all).inject(ActiveSupport::OrderedHash.new) do |controllers, controller|
21
- controller.klass.parents.each {|parent| controllers[parent] ||= []}
22
- controllers[controller.klass.parent] << controller
23
- controllers
24
- end
25
-
26
- # Sort all the controllers within each parent alphabetically
27
- controllers_by_parent.each do |parent, controllers|
28
- controllers.sort! do |c1, c2|
29
- c1.name <=> c2.name
30
- end
31
- end
32
-
33
- # Sort the parents (first by closest to Object, then alphabetically)
34
- controllers_by_parent.sort! do |c1, c2|
35
- if c1.first == Object
36
- -1
37
- elsif c2.first == Object
38
- 1
39
- else
40
- c1.first.name <=> c2.first.name
41
- end
42
- end
43
- end
44
-
45
- # Parses the controller path and action from the given options
46
- def recognize_path(options = '')
47
- options = ActionController::Routing::Routes.recognize_path(URI.parse(options).path) if options.is_a?(String)
48
- controller_path, action = options[:controller], options[:action]
49
- controller_path = controller_path.controller_path if controller_path.is_a?(Class)
50
-
51
- return controller_path, action ? action.to_s : 'index'
52
- end
53
- end
54
-
55
- # Returns the class that this controller represents
56
- def klass
57
- @klass ||= "#{path.camelize}Controller".constantize
58
- end
59
-
60
- # The humanized name of this controller. This will not include the parent's name.
61
- def name
62
- @name ||= klass.controller_name.titleize
63
- end
64
-
65
- # Possible paths that can match this controller. This includes paths from all
66
- # superclasses up to ApplicationController.
67
- def possible_path_matches
68
- klass.ancestors.select {|c| Class === c && c < ActionController::Base}.map(&:controller_path)
69
- end
70
-
71
- # Is this a global controller? If a user has a permission on the global
72
- # controller, then he has permissions on all controllers. At least one user
73
- # in the system should have global access.
74
- def global?
75
- path == 'application'
76
- end
77
-
78
- # Returns the name of the controller
79
- def to_s #:nodoc
80
- name
81
- end
82
- end
@@ -1,13 +0,0 @@
1
- class CreateControllers < ActiveRecord::Migration
2
- def self.up
3
- create_table :controllers do |t|
4
- t.column :path, :string, :null => false
5
- t.column :description, :text
6
- end
7
- add_index :controllers, :path, :unique => true
8
- end
9
-
10
- def self.down
11
- drop_table :controllers
12
- end
13
- end
@@ -1,13 +0,0 @@
1
- class CreatePermissionsRoles < ActiveRecord::Migration
2
- def self.up
3
- create_table :permissions_roles, :id => false do |t|
4
- t.column :permission_id, :integer, :null => false
5
- t.column :role_id, :integer, :null => false
6
- end
7
- add_index :permissions_roles, [:permission_id, :role_id], :unique => true
8
- end
9
-
10
- def self.down
11
- drop_table :permissions_roles
12
- end
13
- end
@@ -1,2 +0,0 @@
1
- class Payment::PayPal::TransactionsController < Payment::TransactionsController
2
- end
@@ -1,2 +0,0 @@
1
- class Payment::TransactionsController < ApplicationController
2
- end
@@ -1,19 +0,0 @@
1
- application:
2
- id: 1
3
- path: application
4
-
5
- users:
6
- id: 2
7
- path: users
8
-
9
- admin_users:
10
- id: 3
11
- path: admin/users
12
-
13
- payment_transactions:
14
- id: 4
15
- path: payment/transactions
16
-
17
- payment_pay_pal_transactions:
18
- id: 5
19
- path: payment/pay_pal/transactions
@@ -1,27 +0,0 @@
1
- crud_application:
2
- id: 1
3
- controller_id: 1
4
-
5
- read_application:
6
- id: 2
7
- controller_id: 1
8
- action: index
9
-
10
- read_users:
11
- id: 3
12
- controller_id: 2
13
- action: index
14
-
15
- update_users:
16
- id: 4
17
- controller_id: 2
18
- action: update
19
-
20
- crud_admin_users:
21
- id: 5
22
- controller_id: 3
23
-
24
- create_pay_pal_payment_transactions:
25
- id: 6
26
- controller_id: 5
27
- action: create
@@ -1,15 +0,0 @@
1
- administrator_crud_application:
2
- role_id: 1
3
- permission_id: 1
4
-
5
- moderator_crud_admin_users:
6
- role_id: 2
7
- permission_id: 5
8
-
9
- guest_read_application:
10
- role_id: 3
11
- permission_id: 2
12
-
13
- guest_create_pay_pal_payment_transactions:
14
- role_id: 3
15
- permission_id: 6
@@ -1,17 +0,0 @@
1
- administrator:
2
- id: 1
3
- role_id: 1
4
- assignee_id: 1
5
- assignee_type: User
6
-
7
- moderator:
8
- id: 2
9
- role_id: 2
10
- assignee_id: 2
11
- assignee_type: User
12
-
13
- guest:
14
- id: 3
15
- role_id: 3
16
- assignee_id: 3
17
- assignee_type: User
@@ -1,11 +0,0 @@
1
- administrator:
2
- id: 1
3
- name: Administrator
4
-
5
- moderator:
6
- id: 2
7
- name: Moderator
8
-
9
- guest:
10
- id: 3
11
- name: Guest
@@ -1,11 +0,0 @@
1
- administrator:
2
- id: 1
3
- login: admin
4
-
5
- moderator:
6
- id: 2
7
- login: moderator
8
-
9
- guest:
10
- id: 3
11
- login: guest
@@ -1,40 +0,0 @@
1
- require "#{File.dirname(__FILE__)}/../test_helper"
2
-
3
- class AuthorizationHelperTest < Test::Unit::TestCase
4
- include ActionView::Helpers::TagHelper
5
- include ActionView::Helpers::UrlHelper
6
- include PluginAWeek::Has::Roles::AuthorizationHelper
7
-
8
- fixtures :controllers, :permissions, :roles, :permissions_roles, :users, :role_assignments
9
-
10
- def setup
11
- @controller = HomeController.new
12
- @controller.request = ActionController::TestRequest.new
13
- @controller.instance_eval {@_params = request.path_parameters}
14
- @controller.send(:initialize_current_url)
15
- end
16
-
17
- def current_user
18
- users(:guest)
19
- end
20
-
21
- def test_should_be_authorized_if_user_has_proper_permissions
22
- assert authorized_for?('/users/index')
23
- end
24
-
25
- def test_should_not_be_authorized_if_user_doesnt_have_proper_permissions
26
- assert !authorized_for?('/admin/users/destroy')
27
- end
28
-
29
- def test_should_link_to_nothing_if_not_authorized_and_not_showing_text
30
- assert_equal '', link_to_if_authorized('Destroy User', '/admin/users/destroy', :show_text => false)
31
- end
32
-
33
- def test_should_display_text_if_not_authorized_and_showing_text
34
- assert_equal 'Destroy User', link_to_if_authorized('Destroy User', '/admin/users/destroy', :show_text => true)
35
- end
36
-
37
- def test_should_link_to_url_if_authorized
38
- assert_equal '<a href="/users">Destroy User</a>', link_to_if_authorized('Destroy User', {:controller => 'users', :action => 'index'}, :show_text => false)
39
- end
40
- end
@@ -1,95 +0,0 @@
1
- require "#{File.dirname(__FILE__)}/../test_helper"
2
-
3
- class ControllerTest < Test::Unit::TestCase
4
- fixtures :controllers, :permissions
5
-
6
- def test_should_be_valid
7
- assert_valid controllers(:users)
8
- end
9
-
10
- def test_should_require_path
11
- assert_invalid controllers(:users), :path, nil, ''
12
- end
13
-
14
- def test_should_require_specific_format_for_paths
15
- assert_invalid controllers(:users), :path, '/users', '//users', 'users/', 'admin//users', '1'
16
- end
17
-
18
- def test_should_require_unique_path
19
- assert_invalid controllers(:users).clone, :path
20
- end
21
-
22
- def test_should_have_associated_permissions
23
- assert_equal [permissions(:read_users), permissions(:update_users)], controllers(:users).permissions
24
- end
25
-
26
- def test_should_destroy_associated_permissions_when_destroyed
27
- controllers(:users).destroy
28
- assert_nil Permission.find_by_controller_id(2)
29
- end
30
-
31
- def test_should_use_path_for_klass
32
- assert_equal UsersController, controllers(:users).klass
33
- end
34
-
35
- def test_should_use_namespaced_path_for_klass
36
- assert_equal Admin::UsersController, controllers(:admin_users).klass
37
- end
38
-
39
- def test_should_use_controller_name_for_name_if_controller_is_not_namespaced
40
- assert_equal 'Users', controllers(:users).name
41
- end
42
-
43
- def test_should_use_demodulized_controller_name_for_name_if_controller_is_namespaced
44
- assert_equal 'Users', controllers(:admin_users).name
45
- end
46
-
47
- def test_possible_path_matches_should_include_all_superclasses_except_base_controller
48
- assert_equal %w(users application), controllers(:users).possible_path_matches
49
- assert_equal %w(admin/users application), controllers(:admin_users).possible_path_matches
50
- assert_equal %w(payment/pay_pal/transactions payment/transactions application), controllers(:payment_pay_pal_transactions).possible_path_matches
51
- end
52
-
53
- def test_should_be_global_if_path_is_application
54
- assert controllers(:application).global?
55
- end
56
-
57
- def test_should_not_be_global_if_path_is_not_application
58
- assert !controllers(:users).global?
59
- assert !controllers(:admin_users).global?
60
- end
61
-
62
- def test_stringification_should_use_name
63
- assert_equal 'Users', controllers(:users).to_s
64
- end
65
-
66
- def test_should_map_parents_for_all_controllers
67
- expected = [
68
- [Object, [controllers(:application), controllers(:users)]],
69
- [Admin, [controllers(:admin_users)]],
70
- [Payment, [controllers(:payment_transactions)]],
71
- [Payment::PayPal, [controllers(:payment_pay_pal_transactions)]]
72
- ]
73
- assert_equal expected, Controller.find_all_mapped_by_parent
74
- end
75
-
76
- def test_should_recognize_path_by_string
77
- assert_equal ['users', 'index'], Controller.recognize_path('/users')
78
- end
79
-
80
- def test_should_recognize_namespaced_path_by_string
81
- assert_equal ['admin/users', 'update'], Controller.recognize_path('/admin/users/update')
82
- end
83
-
84
- def test_should_recognize_path_by_hash
85
- assert_equal ['users', 'index'], Controller.recognize_path(:controller => 'users', :action => 'index')
86
- end
87
-
88
- def test_should_recognize_namespaced_path_by_hash
89
- assert_equal ['admin/users', 'update'], Controller.recognize_path(:controller => 'admin/users', :action => 'update', :id => 1)
90
- end
91
-
92
- def test_should_recognize_path_if_action_not_specified
93
- assert_equal ['users', 'index'], Controller.recognize_path(:controller => 'users')
94
- end
95
- end
@@ -1,49 +0,0 @@
1
- require "#{File.dirname(__FILE__)}/../test_helper"
2
-
3
- class HasRolesTest < Test::Unit::TestCase
4
- fixtures :controllers, :permissions, :roles, :permissions_roles, :users, :role_assignments
5
-
6
- def test_should_have_role_assignments_association
7
- assert_equal [role_assignments(:administrator)], users(:administrator).role_assignments
8
- end
9
-
10
- def test_should_destroy_role_assignments_when_destroyed
11
- users(:administrator).destroy
12
- assert_nil RoleAssignment.find_by_assignee_id(1)
13
- end
14
-
15
- def test_should_have_roles_association
16
- assert_equal [roles(:administrator)], users(:administrator).roles
17
- end
18
-
19
- def test_should_be_authorized_if_user_has_proper_permissions
20
- assert users(:guest).authorized_for?('/users/index')
21
- end
22
-
23
- def test_should_not_be_authorized_if_user_doesnt_have_proper_permissions
24
- assert !users(:guest).authorized_for?('/admin/users/destroy')
25
- end
26
-
27
- def test_roles_ids_should_map_all_ids
28
- assert_equal [1], users(:administrator).role_ids
29
- end
30
-
31
-
32
- def test_should_destroy_old_roles_when_replaced
33
- user = users(:administrator)
34
- user.role_ids = []
35
- assert_equal [], user.roles
36
- end
37
-
38
- def test_should_add_new_roles_when_replaced
39
- user = users(:administrator)
40
- user.role_ids = [1, 2]
41
- assert_equal [roles(:administrator), roles(:moderator)], user.roles
42
- end
43
-
44
- def test_should_destroy_old_roles_and_add_new_roles_when_replaced
45
- user = users(:administrator)
46
- user.role_ids = [2]
47
- assert_equal [roles(:moderator)], user.roles
48
- end
49
- end