cantango-roles 0.1.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 (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