cantango-roles 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. data/.document +5 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +36 -0
  4. data/Gemfile.lock +147 -0
  5. data/LICENSE.txt +20 -0
  6. data/README.mdown +83 -0
  7. data/Rakefile +53 -0
  8. data/VERSION +1 -0
  9. data/lib/cantango/roles.rb +11 -0
  10. data/lib/cantango/roles_ext.rb +9 -0
  11. data/lib/cantango/roles_ext/ability.rb +7 -0
  12. data/lib/cantango/roles_ext/ability/helper.rb +7 -0
  13. data/lib/cantango/roles_ext/ability/helper/role.rb +17 -0
  14. data/lib/cantango/roles_ext/ability/helper/role_group.rb +17 -0
  15. data/lib/cantango/roles_ext/builder.rb +7 -0
  16. data/lib/cantango/roles_ext/builder/permit.rb +7 -0
  17. data/lib/cantango/roles_ext/builder/permit/role.rb +35 -0
  18. data/lib/cantango/roles_ext/builder/permit/role_group.rb +61 -0
  19. data/lib/cantango/roles_ext/configuration.rb +13 -0
  20. data/lib/cantango/roles_ext/configuration/registry/role.rb +34 -0
  21. data/lib/cantango/roles_ext/configuration/role_groups.rb +17 -0
  22. data/lib/cantango/roles_ext/configuration/roles.rb +16 -0
  23. data/lib/cantango/roles_ext/configuration/system.rb +43 -0
  24. data/lib/cantango/roles_ext/engine.rb +7 -0
  25. data/lib/cantango/roles_ext/engine/permits.rb +5 -0
  26. data/lib/cantango/roles_ext/filter.rb +7 -0
  27. data/lib/cantango/roles_ext/filter/role.rb +29 -0
  28. data/lib/cantango/roles_ext/filter/role_group.rb +28 -0
  29. data/lib/cantango/roles_ext/helpers.rb +7 -0
  30. data/lib/cantango/roles_ext/helpers/role.rb +14 -0
  31. data/lib/cantango/roles_ext/helpers/role_group.rb +14 -0
  32. data/lib/cantango/roles_ext/permit.rb +0 -0
  33. data/lib/cantango/roles_ext/permit/helper/role_matcher.rb +13 -0
  34. data/lib/cantango/roles_ext/permit/role.rb +35 -0
  35. data/lib/cantango/roles_ext/permit/role_group.rb +47 -0
  36. data/lib/generators/cantango/base.rb +71 -0
  37. data/lib/generators/cantango/basic.rb +41 -0
  38. data/lib/generators/cantango/license_base.rb +15 -0
  39. data/lib/generators/cantango/permit_generator.rb +58 -0
  40. data/lib/generators/cantango/role_permit/role_permit_generator.rb +39 -0
  41. data/lib/generators/cantango/role_permit/templates/account_permit.erb +4 -0
  42. data/lib/generators/cantango/role_permit/templates/role_group_permit.erb +24 -0
  43. data/lib/generators/cantango/role_permit/templates/role_permit.erb +23 -0
  44. data/lib/generators/cantango/role_permits/role_permits_generator.rb +45 -0
  45. data/spec/cantango/ability/helper/role_group_spec.rb +33 -0
  46. data/spec/cantango/ability/helper/role_spec.rb +33 -0
  47. data/spec/cantango/ability/helper/shared/role_ex.rb +0 -0
  48. data/spec/cantango/ability/helper/shared/role_group_ex.rb +0 -0
  49. data/spec/cantango/builder/role_group_spec.rb +5 -0
  50. data/spec/cantango/builder/role_spec.rb +5 -0
  51. data/spec/cantango/configuration/role_groups_spec.rb +13 -0
  52. data/spec/cantango/configuration/role_registry_spec.rb +9 -0
  53. data/spec/cantango/configuration/roles_spec.rb +11 -0
  54. data/spec/cantango/configuration/shared/registry_ex.rb +40 -0
  55. data/spec/cantango/configuration/shared/role_registry_ex.rb +15 -0
  56. data/spec/cantango/configuration/shared/system_ex.rb +39 -0
  57. data/spec/cantango/configuration/system_spec.rb +9 -0
  58. data/spec/cantango/engine/permits_spec.rb +7 -0
  59. data/spec/cantango/filter/role_group_spec.rb +96 -0
  60. data/spec/cantango/filter/role_spec.rb +96 -0
  61. data/spec/cantango/helpers/role_group_spec.rb +26 -0
  62. data/spec/cantango/helpers/role_spec.rb +26 -0
  63. data/spec/fixtures/models.rb +2 -0
  64. data/spec/fixtures/models/admin.rb +2 -0
  65. data/spec/fixtures/models/admin_account.rb +22 -0
  66. data/spec/fixtures/models/items.rb +8 -0
  67. data/spec/fixtures/models/permission.rb +12 -0
  68. data/spec/fixtures/models/project.rb +2 -0
  69. data/spec/fixtures/models/simple_roles.rb +48 -0
  70. data/spec/fixtures/models/user.rb +52 -0
  71. data/spec/fixtures/models/user_account.rb +7 -0
  72. data/spec/helpers/current_user_accounts.rb +20 -0
  73. data/spec/helpers/current_users.rb +10 -0
  74. data/spec/spec_helper.rb +2 -0
  75. metadata +223 -0
@@ -0,0 +1,35 @@
1
+ module CanTango::Builder
2
+ module Permit
3
+ class Role < Base
4
+ include CanTango::Helpers::Debug
5
+
6
+ # builds a list of Permits for each role of the current ability user (or account)
7
+ # @return [Array<RoleGroupPermit::Base>] the role permits built for this ability
8
+ def build
9
+ if roles.empty?
10
+ debug "Not building any RolePermit"
11
+ return []
12
+ end
13
+ roles.inject([]) do |permits, role|
14
+ debug "Building RolePermit for #{role}"
15
+ (permits << create_permit(role)) if valid?(role.to_sym)
16
+ permits
17
+ end.compact
18
+ end
19
+
20
+ protected
21
+
22
+ def roles
23
+ ability.respond_to?(:roles) ? ability.roles : []
24
+ end
25
+
26
+ def valid? role
27
+ filter(role).valid?
28
+ end
29
+
30
+ def filter role
31
+ CanTango::Filters::RoleFilter.new role
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,61 @@
1
+ module CanTango::Builder
2
+ module Permit
3
+ class RoleGroup < Base
4
+ include CanTango::Helpers::Debug
5
+ # builds a list of Permits for each role group of the current ability user (or account)
6
+ # @return [Array<RoleGroupPermit::Base>] the role group permits built for this ability
7
+ def build
8
+ matching_permits = matching_role_groups(roles).inject([]) do |permits, role_group|
9
+ debug "Building RoleGroupPermit for #{role_group}"
10
+ (permits << create_permit(role_group)) if valid?(role_group)
11
+ permits
12
+ end.compact
13
+
14
+ if matching_permits.empty?
15
+ debug "Not building any RoleGroupPermits since no role groups could be found that are relevant for the permission candidate"
16
+ return []
17
+ end
18
+ matching_permits
19
+ end
20
+
21
+ def name
22
+ :role_group
23
+ end
24
+
25
+ def valid? role_group
26
+ return true if !role_groups_filter?
27
+ filter(role_group).valid?
28
+ end
29
+
30
+ def filter role_group
31
+ CanTango::Filters::RoleGroupFilter.new role_group
32
+ end
33
+
34
+ private
35
+
36
+ def role_groups
37
+ ability.respond_to?(:role_groups) ? ability.role_groups : []
38
+ end
39
+
40
+ def matching_role_groups roles
41
+ role_groups | matching_role_groups_for(roles)
42
+ end
43
+
44
+ # will also run role_groups for which any role of the candidate is a member
45
+ # so if the candidate is a user and the user has a :trustee role and this role is part of the :trust role group,
46
+ # then the :trust role group permit will be run!
47
+ # Thus if the candidate has a particular role group or just has a role belonging to that role group, the permit
48
+ # for that role group will be run
49
+ def matching_role_groups_for roles
50
+ roles.inject([]) do |groups, role|
51
+ groups << subject.role_groups_for(role) if subject.respond_to?(:role_groups_for)
52
+ groups
53
+ end.flatten.compact.uniq
54
+ end
55
+
56
+ def role_groups_filter?
57
+ CanTango.config.role_groups.filter?
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,13 @@
1
+ module CanTango
2
+ class Configuration
3
+ module Registry
4
+ sweet_scope :ns => {:CanTango => 'cantango/roles_ext'} do
5
+ sweetload :Role
6
+ end
7
+ end
8
+
9
+ sweet_scope :ns => {:CanTango => 'cantango/roles_ext'} do
10
+ sweetload :System, :RoleGroups, :Roles
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,34 @@
1
+ module CanTango
2
+ class Configuration
3
+ module Registry
4
+ class Role < Base
5
+ def only *names
6
+ @onlies = names.select_labels
7
+ end
8
+
9
+ def onlies
10
+ @onlies ||= []
11
+ end
12
+
13
+ def excluded
14
+ @excluded ||= []
15
+ end
16
+
17
+ def exclude *names
18
+ @excluded = names.select_labels
19
+ end
20
+
21
+ def filter?
22
+ !(excluded + onlies).empty?
23
+ end
24
+
25
+ def clear!
26
+ super
27
+ @excluded = []
28
+ @onlies = []
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+
@@ -0,0 +1,17 @@
1
+ module CanTango
2
+ class Configuration
3
+ class RoleGroups < System
4
+ def system
5
+ @system ||= :troles
6
+ end
7
+
8
+ def default_system_apis
9
+ {
10
+ :troles => {:list => :role_group_list, :has => :in_role_group?}
11
+ }
12
+ end
13
+ end
14
+ end
15
+ end
16
+
17
+
@@ -0,0 +1,16 @@
1
+ module CanTango
2
+ class Configuration
3
+ class Roles < System
4
+ def system
5
+ @system ||= :simple_roles
6
+ end
7
+
8
+ def default_system_apis
9
+ {
10
+ :troles => {:list => :role_list, :has => :has_role?},
11
+ :simple_roles => {:list => :roles_list}
12
+ }
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,43 @@
1
+ module CanTango
2
+ class Configuration
3
+ class System < Registry::Role
4
+ include Singleton
5
+
6
+ def system= name
7
+ raise ArgumentError, "Must be a label" if !name.kind_of_label?
8
+ @system = name.to_sym
9
+ end
10
+
11
+ def system_apis= system_apis
12
+ raise ArgumentError, "Must be a hash fx :troles => :role_list, was: #{system_apis}" if !system_apis.kind_of?(Hash)
13
+ @system_apis = system_apis
14
+ end
15
+
16
+ def system
17
+ @system ||= default_system
18
+ end
19
+
20
+ def default_system
21
+ nil
22
+ end
23
+
24
+ def add_systems system_apis
25
+ raise ArgumentError, "Must be a hash fx :troles => :role_list, was: #{system_apis}" if !system_apis.kind_of?(Hash)
26
+ self.system_apis.merge! system_apis
27
+ end
28
+ alias_method :add_system, :add_systems
29
+
30
+ def system_api
31
+ system_apis[system] || {}
32
+ end
33
+
34
+ def system_apis
35
+ @system_apis ||= default_system_apis
36
+ end
37
+
38
+ def default_system_apis
39
+ {}
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,7 @@
1
+ module CanTango
2
+ class Engine
3
+ if defined? CanTango::Permit
4
+ sweetload :Permit
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,5 @@
1
+ module CanTango::Engine
2
+ class Permits < Base
3
+ include CanTango::Ability::Helpers::Role
4
+ end
5
+ end
@@ -0,0 +1,7 @@
1
+ module CanTango
2
+ module Filter
3
+ sweet_scope :ns => {:CanTango => 'cantango/roles_ext'} do
4
+ sweetload :Role, :RoleGroup
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,29 @@
1
+ module CanTango
2
+ module Filter
3
+ class Role < Base
4
+ alias_method :role, :item
5
+
6
+ def initialize role, roles = nil
7
+ super
8
+ end
9
+
10
+ def not_only?
11
+ !only_roles.empty? && !only_roles.include?(role)
12
+ end
13
+
14
+ def excluded?
15
+ !excluded_roles.empty? && excluded_roles.include?(role)
16
+ end
17
+
18
+ def only_roles
19
+ CanTango.config.roles.onlies
20
+ end
21
+
22
+ def excluded_roles
23
+ CanTango.config.roles.excluded
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+
@@ -0,0 +1,28 @@
1
+ module CanTango
2
+ module Filter
3
+ class RoleGroup < Base
4
+ alias_method :role_group, :item
5
+
6
+ def initialize role_group, role_groups = nil
7
+ super
8
+ end
9
+
10
+ def not_only?
11
+ !only_role_groups.empty? && !only_role_groups.include?(role_group)
12
+ end
13
+
14
+ def excluded?
15
+ !excluded_role_groups.empty? && excluded_role_groups.include?(role_group)
16
+ end
17
+
18
+ def only_role_groups
19
+ CanTango.config.role_groups.onlies
20
+ end
21
+
22
+ def excluded_role_groups
23
+ CanTango.config.role_groups.excluded
24
+ end
25
+ end
26
+ end
27
+ end
28
+
@@ -0,0 +1,7 @@
1
+ module CanTango
2
+ module Helpers
3
+ sweet_scope :ns => {:CanTango => 'cantango/roles_ext'} do
4
+ sweetload :Role, :RoleGroup
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,14 @@
1
+ module CanTango
2
+ module Helpers
3
+ module Role
4
+ def role_method name
5
+ config.roles.method_names[name]
6
+ end
7
+
8
+ def config
9
+ CanTango.config
10
+ end
11
+ end
12
+ end
13
+ end
14
+
@@ -0,0 +1,14 @@
1
+ module CanTango
2
+ module Helpers
3
+ module RoleGroup
4
+ def role_group_method name
5
+ config.roles_groups.method_names[name]
6
+ end
7
+
8
+ def config
9
+ CanTango.config
10
+ end
11
+ end
12
+ end
13
+ end
14
+
File without changes
@@ -0,0 +1,13 @@
1
+ module CanTango::Permit
2
+ module Helper
3
+ module RoleMatcher
4
+ def role_match? candidate
5
+ candidate.has_role? permit_name(self.class)
6
+ end
7
+
8
+ def role_group_match? candidate, group_name = nil
9
+ candidate.is_in_group? permit_name(self.class)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,35 @@
1
+ module CanTango
2
+ module Permit
3
+ class Role < Base
4
+ extend ClassMethods
5
+
6
+ # creates the permit
7
+ # @param [Permits::Ability] the ability
8
+ # @param [Hash] the options
9
+ def initialize ability
10
+ super
11
+ end
12
+
13
+ def valid_for? subject
14
+ in_role? subject
15
+ end
16
+
17
+ def self.hash_key
18
+ roles_list_meth
19
+ end
20
+
21
+ protected
22
+
23
+ include CanTango::Permit::Helper::RoleMatcher
24
+
25
+ include CanTango::Helpers::RoleMethods
26
+ extend CanTango::Helpers::RoleMethods
27
+
28
+ def in_role? subject
29
+ return subject.send(has_role_meth, role) if subject.respond_to? has_role_meth
30
+ return subject.send(roles_list_meth).include? role if subject.respond_to? roles_list_meth
31
+ false
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,47 @@
1
+ module CanTango
2
+ module Permit
3
+ class RoleGroup < Base
4
+ extend ClassMethods
5
+
6
+ def name
7
+ self.class.permit_name self.class
8
+ end
9
+
10
+ # creates the permit
11
+ def initialize executor
12
+ super
13
+ end
14
+
15
+ def execute!
16
+ super
17
+ end
18
+
19
+ def valid_for? subject
20
+ in_role_group? subject
21
+ end
22
+
23
+ def self.hash_key
24
+ role_groups_list_meth
25
+ end
26
+
27
+ protected
28
+
29
+ include CanTango::Permit::Helper::RoleMatcher
30
+
31
+ include CanTango::Helpers::RoleMethods
32
+ extend CanTango::Helpers::RoleMethods
33
+
34
+ def in_role_group? subject
35
+ has_role_group?(subject) || role_groups_of(subject).include?(role)
36
+ end
37
+
38
+ def has_role_group? subject
39
+ subject.send(has_role_group_meth, role) if subject.respond_to?(has_role_group_meth)
40
+ end
41
+
42
+ def role_groups_of subject
43
+ subject.respond_to?(role_groups_list_meth) ? subject.send(role_groups_list_meth) : []
44
+ end
45
+ end
46
+ end
47
+ end