cantango-permits 0.1.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 (166) hide show
  1. data/.rspec +1 -0
  2. data/Gemfile +39 -0
  3. data/Gemfile.lock +155 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README.mdown +362 -0
  6. data/Rakefile +45 -0
  7. data/VERSION +1 -0
  8. data/lib/cantango/executor.rb +5 -0
  9. data/lib/cantango/executor/base.rb +9 -0
  10. data/lib/cantango/executor/permit.rb +7 -0
  11. data/lib/cantango/executor/permit/abstract.rb +27 -0
  12. data/lib/cantango/executor/permit/base.rb +19 -0
  13. data/lib/cantango/executor/permit/special.rb +9 -0
  14. data/lib/cantango/executor/permit_type.rb +50 -0
  15. data/lib/cantango/license.rb +19 -0
  16. data/lib/cantango/license/rules.rb +17 -0
  17. data/lib/cantango/permit.mdown +4 -0
  18. data/lib/cantango/permit.rb +5 -0
  19. data/lib/cantango/permit/account_type.rb +44 -0
  20. data/lib/cantango/permit/attribute.rb +71 -0
  21. data/lib/cantango/permit/base.rb +94 -0
  22. data/lib/cantango/permit/class_methods.rb +49 -0
  23. data/lib/cantango/permit/helper.rb +11 -0
  24. data/lib/cantango/permit/helper/execution.rb +38 -0
  25. data/lib/cantango/permit/helper/host.rb +13 -0
  26. data/lib/cantango/permit/helper/license.rb +34 -0
  27. data/lib/cantango/permit/helper/naming.rb +38 -0
  28. data/lib/cantango/permit/helper/state.rb +21 -0
  29. data/lib/cantango/permit/special.rb +17 -0
  30. data/lib/cantango/permit/user.rb +36 -0
  31. data/lib/cantango/permit/user_type.rb +34 -0
  32. data/lib/cantango/permits.rb +20 -0
  33. data/lib/cantango/permits_ext.rb +7 -0
  34. data/lib/cantango/permits_ext/ability.rb +7 -0
  35. data/lib/cantango/permits_ext/ability/helper.rb +9 -0
  36. data/lib/cantango/permits_ext/ability/helper/permits.rb +8 -0
  37. data/lib/cantango/permits_ext/builder.rb +7 -0
  38. data/lib/cantango/permits_ext/builder/permit.rb +9 -0
  39. data/lib/cantango/permits_ext/builder/permit/account_type.rb +13 -0
  40. data/lib/cantango/permits_ext/builder/permit/base.rb +94 -0
  41. data/lib/cantango/permits_ext/builder/permit/special.rb +13 -0
  42. data/lib/cantango/permits_ext/builder/permit/user_type.rb +7 -0
  43. data/lib/cantango/permits_ext/class_methods.rb +28 -0
  44. data/lib/cantango/permits_ext/config.rb +11 -0
  45. data/lib/cantango/permits_ext/config/engines.rb +9 -0
  46. data/lib/cantango/permits_ext/config/engines/permit.rb +20 -0
  47. data/lib/cantango/permits_ext/config/permits.rb +43 -0
  48. data/lib/cantango/permits_ext/config/permits/accounts.rb +15 -0
  49. data/lib/cantango/permits_ext/config/permits/disabling.rb +22 -0
  50. data/lib/cantango/permits_ext/config/permits/enabling.rb +14 -0
  51. data/lib/cantango/permits_ext/config/permits/execution.rb +21 -0
  52. data/lib/cantango/permits_ext/config/permits/key.rb +19 -0
  53. data/lib/cantango/permits_ext/config/permits/registration.rb +33 -0
  54. data/lib/cantango/permits_ext/config/permits/tracking.rb +19 -0
  55. data/lib/cantango/permits_ext/config/permits/types.rb +25 -0
  56. data/lib/cantango/permits_ext/engine.rb +7 -0
  57. data/lib/cantango/permits_ext/engine/permits.rb +75 -0
  58. data/lib/cantango/permits_ext/factory.rb +7 -0
  59. data/lib/cantango/permits_ext/factory/permits.rb +40 -0
  60. data/lib/cantango/permits_ext/finder.rb +7 -0
  61. data/lib/cantango/permits_ext/finder/base.rb +35 -0
  62. data/lib/cantango/permits_ext/finder/permit.rb +7 -0
  63. data/lib/cantango/permits_ext/finder/permit/account.rb +47 -0
  64. data/lib/cantango/permits_ext/finder/permit/base.rb +53 -0
  65. data/lib/cantango/permits_ext/loader.rb +7 -0
  66. data/lib/cantango/permits_ext/loader/categories.rb +50 -0
  67. data/lib/cantango/permits_ext/loader/license.rb +19 -0
  68. data/lib/cantango/permits_ext/macros.rb +7 -0
  69. data/lib/cantango/permits_ext/macros/permit.rb +32 -0
  70. data/lib/cantango/permits_ext/parser.rb +7 -0
  71. data/lib/cantango/permits_ext/parser/categories.rb +15 -0
  72. data/lib/cantango/permits_ext/registry.rb +7 -0
  73. data/lib/cantango/permits_ext/registry/permit.rb +45 -0
  74. data/lib/generators/cantango/account_permit/account_permit_generator.rb +37 -0
  75. data/lib/generators/cantango/account_permit/templates/account_permit.erb +23 -0
  76. data/lib/generators/cantango/base.rb +71 -0
  77. data/lib/generators/cantango/basic.rb +41 -0
  78. data/lib/generators/cantango/license/license_generator.rb +29 -0
  79. data/lib/generators/cantango/license/templates/license.erb +10 -0
  80. data/lib/generators/cantango/license_base.rb +15 -0
  81. data/lib/generators/cantango/licenses/licenses_generator.rb +26 -0
  82. data/lib/generators/cantango/permit_generator.rb +58 -0
  83. data/lib/generators/cantango/role_permit/role_permit_generator.rb +39 -0
  84. data/lib/generators/cantango/role_permit/templates/account_permit.erb +4 -0
  85. data/lib/generators/cantango/role_permit/templates/role_group_permit.erb +24 -0
  86. data/lib/generators/cantango/role_permit/templates/role_permit.erb +23 -0
  87. data/lib/generators/cantango/role_permits/role_permits_generator.rb +45 -0
  88. data/lib/generators/cantango/user_permit/templates/account_permit.erb +5 -0
  89. data/lib/generators/cantango/user_permit/templates/user_permit.erb +23 -0
  90. data/lib/generators/cantango/user_permit/user_permit_generator.rb +36 -0
  91. data/lib/tasks/permits_tasks.rake +4 -0
  92. data/spec/cantango/ability/helper/permits_spec.rb +14 -0
  93. data/spec/cantango/builder/permit/account_type_spec.rb +25 -0
  94. data/spec/cantango/builder/permit/base_spec.rb +30 -0
  95. data/spec/cantango/builder/permit/special_spec.rb +25 -0
  96. data/spec/cantango/builder/permit/user_type_spec.rb +27 -0
  97. data/spec/cantango/config/engines/permit_spec.rb +14 -0
  98. data/spec/cantango/config/engines_spec.rb +142 -0
  99. data/spec/cantango/config/permit_registry_ex.rb +9 -0
  100. data/spec/cantango/config/permit_registry_spec.rb +8 -0
  101. data/spec/cantango/config/permits/accounts_spec.rb +23 -0
  102. data/spec/cantango/config/permits/disabling_spec.rb +38 -0
  103. data/spec/cantango/config/permits/enabling_spec.rb +19 -0
  104. data/spec/cantango/config/permits/execution_spec.rb +27 -0
  105. data/spec/cantango/config/permits/registration_spec.rb +15 -0
  106. data/spec/cantango/config/permits/tracking_spec.rb +19 -0
  107. data/spec/cantango/config/permits/types_spec.rb +27 -0
  108. data/spec/cantango/config/permits_spec.rb +76 -0
  109. data/spec/cantango/engine/permit_cached_spec.rb +52 -0
  110. data/spec/cantango/engine/permit_spec.rb +58 -0
  111. data/spec/cantango/engine/permit_static_dynamic_spec.rb +65 -0
  112. data/spec/cantango/executor/custom_permit_spec.rb +65 -0
  113. data/spec/cantango/executor/more_permit_spec.rb +45 -0
  114. data/spec/cantango/executor/permit_base_spec.rb +46 -0
  115. data/spec/cantango/executor/permit_spec.rb +53 -0
  116. data/spec/cantango/executor/special_permit_spec.rb +36 -0
  117. data/spec/cantango/factory/permits_spec.rb +70 -0
  118. data/spec/cantango/finder/account_permit_spec.rb +30 -0
  119. data/spec/cantango/finder/permit_spec.rb +23 -0
  120. data/spec/cantango/license/save_license_spec.rb +24 -0
  121. data/spec/cantango/license_spec.rb +0 -0
  122. data/spec/cantango/loader/categories_spec.rb +47 -0
  123. data/spec/cantango/loader/license_spec.rb +7 -0
  124. data/spec/cantango/macros/permit_spec.rb +38 -0
  125. data/spec/cantango/parser/categories_spec.rb +19 -0
  126. data/spec/cantango/permit/account_type_spec.rb +34 -0
  127. data/spec/cantango/permit/attribute_permit_spec.rb +65 -0
  128. data/spec/cantango/permit/base_spec.rb +106 -0
  129. data/spec/cantango/permit/class_methods_spec.rb +34 -0
  130. data/spec/cantango/permit/helper/execution_spec.rb +54 -0
  131. data/spec/cantango/permit/helper/host_spec.rb +29 -0
  132. data/spec/cantango/permit/helper/license_spec.rb +37 -0
  133. data/spec/cantango/permit/helper/naming_spec.rb +56 -0
  134. data/spec/cantango/permit/helper/state_spec.rb +24 -0
  135. data/spec/cantango/permit/special_default_spec.rb +2 -0
  136. data/spec/cantango/permit/special_first_spec.rb +2 -0
  137. data/spec/cantango/permit/user_type_spec.rb +78 -0
  138. data/spec/cantango/registry/permit_spec.rb +67 -0
  139. data/spec/fixtures/config/cantango_permissions.yml +49 -0
  140. data/spec/fixtures/config/categories.yml +6 -0
  141. data/spec/fixtures/config/evaluator_fixtures.yml +18 -0
  142. data/spec/fixtures/config/licenses.yml +4 -0
  143. data/spec/fixtures/config/permissions.yml +60 -0
  144. data/spec/fixtures/config/role_group.yml +4 -0
  145. data/spec/fixtures/config/roles.yml +4 -0
  146. data/spec/fixtures/config/test_permissions.yml +55 -0
  147. data/spec/fixtures/config/user_permissions.yml +8 -0
  148. data/spec/fixtures/models.rb +15 -0
  149. data/spec/fixtures/models/admin.rb +2 -0
  150. data/spec/fixtures/models/admin_account.rb +22 -0
  151. data/spec/fixtures/models/items.rb +11 -0
  152. data/spec/fixtures/models/permission.rb +12 -0
  153. data/spec/fixtures/models/simple_roles.rb +49 -0
  154. data/spec/fixtures/models/user.rb +52 -0
  155. data/spec/fixtures/models/user_account.rb +21 -0
  156. data/spec/fixtures/tango_fixtures.rb +29 -0
  157. data/spec/generators/cantango/account_role_permit_generator_spec.rb +35 -0
  158. data/spec/generators/cantango/account_role_permits_generator_spec.rb +59 -0
  159. data/spec/generators/cantango/license_generator_spec.rb +33 -0
  160. data/spec/generators/cantango/licenses_generator_spec.rb +58 -0
  161. data/spec/generators/cantango/role_permit_generator_spec.rb +35 -0
  162. data/spec/generators/cantango/role_permits_generator_spec.rb +58 -0
  163. data/spec/helpers/current_user_accounts.rb +20 -0
  164. data/spec/helpers/current_users.rb +10 -0
  165. data/spec/spec_helper.rb +24 -0
  166. metadata +325 -0
@@ -0,0 +1,13 @@
1
+ module CanTango
2
+ module Builder::Permit
3
+ class Special < Base
4
+ def build
5
+ special_permits.map{|name| create_permit(name) }.compact
6
+ end
7
+
8
+ def special_permits
9
+ [:system, :any]
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,7 @@
1
+ module CanTango
2
+ module Builder::Permit
3
+ class UserType < Base
4
+ end
5
+ end
6
+ end
7
+
@@ -0,0 +1,28 @@
1
+ module CanTango
2
+ module ClassMethods
3
+ def permits_allowed candidate, actions, subjects, *extra_args
4
+ raise "Debugging has not been turned on. Turn it on using: CanTango.debug!" if CanTango.config.debug.off?
5
+ config.permits.allowed candidate, actions, subjects, *extra_args
6
+ end
7
+
8
+ def permits_denied candidate, actions, subjects, *extra_args
9
+ raise "Debugging has not been turned on. Turn it on using: CanTango.debug!" if CanTango.config.debug.off?
10
+ config.permits.denied candidate, actions, subjects, *extra_args
11
+ end
12
+
13
+ def debug_permits_registry
14
+ puts "permits registry:" << CanTango.config.permits.show_all.inspect
15
+ end
16
+
17
+ def debug_ability candidate, actions, subjects, *extra_args
18
+ puts "Ability: #{actions} on #{subjects}"
19
+ puts "permits allowed:" << permits_allowed(candidate, actions, subjects, *extra_args).inspect
20
+ puts "permits denied:" << permits_denied(candidate, actions, subjects, *extra_args).inspect
21
+ end
22
+
23
+ def clear_permits_executed!
24
+ config.permits.clear_executed!
25
+ end
26
+ end
27
+ extend ClassMethods
28
+ end
@@ -0,0 +1,11 @@
1
+ module CanTango
2
+ class Config
3
+ sweet_scope :ns => {:CanTango => 'cantango/permits_ext'} do
4
+ sweetload :Permits
5
+ end
6
+
7
+ def permits
8
+ CanTango::Config::Permits.instance
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ module CanTango
2
+ class Config
3
+ class Engines < Registry::Hash
4
+ sweet_scope :ns => {:CanTango => 'cantango/permits_ext'} do
5
+ sweetload :PermitEngineConfig
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,20 @@
1
+ module CanTango
2
+ class Config
3
+ class Engines
4
+ class PermitEngineConfig < EngineConfig
5
+ def on?
6
+ @state ||= :on
7
+ @state == :on
8
+ end
9
+
10
+ protected
11
+
12
+ def valid_mode_names
13
+ [:cache, :no_cache, :both]
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+
@@ -0,0 +1,43 @@
1
+ module CanTango
2
+ class Config
3
+ class Permits
4
+ include Singleton
5
+ include CanTango::Helpers::Debug
6
+ include CanTango::Registry::Permit
7
+
8
+ sweet_scope :ns => {:CanTango => 'cantango/permits_ext'} do
9
+ sweetload :Execution, :Tracking, :Enabling, :Disabling
10
+ sweetload :Accounts, :Types, :Registration, :Key
11
+ end
12
+
13
+ include Execution
14
+ include Tracking
15
+ include Enabling
16
+ include Disabling
17
+ include Registration
18
+
19
+ attr_writer :available, :default_permits
20
+
21
+ def available
22
+ @available ||= default_permits
23
+ end
24
+
25
+ def default_permits
26
+ @default_permits ||= {}
27
+ end
28
+
29
+ def accounts
30
+ Accounts.instance
31
+ end
32
+
33
+ # permit types
34
+ def types
35
+ Types.instance
36
+ end
37
+
38
+ def key
39
+ Key.instance
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,15 @@
1
+ class CanTango::Config
2
+ class Permits
3
+ class Accounts
4
+ include Singleton
5
+
6
+ def registry_for name
7
+ registries[name] ||= CanTango::Registry::Permit::Base.new
8
+ end
9
+
10
+ def registries
11
+ @registries ||= {}
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,22 @@
1
+ class CanTango::Config
2
+ class Permits
3
+ module Disabling
4
+ def disable_for type, *names
5
+ @disabled ||= {}
6
+ @disabled[type.to_sym] = names.to_symbols
7
+ end
8
+
9
+ def disabled
10
+ @disabled ||= {}
11
+ end
12
+
13
+ def disabled? type, *names
14
+ (names.flatten - disabled_for(type)).empty?
15
+ end
16
+
17
+ def disabled_for type
18
+ disabled[type.to_sym] || []
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,14 @@
1
+ class CanTango::Config
2
+ class Permits
3
+ module Enabling
4
+ def enable_all_for type
5
+ @disabled ||= {}
6
+ @disabled[type.to_sym] = nil
7
+ end
8
+
9
+ def enable_all!
10
+ @disabled = {}
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,21 @@
1
+ class CanTango::Config
2
+ class Permits
3
+ module Execution
4
+ def was_executed permit, ability
5
+ executed_for(ability) << permit
6
+ end
7
+
8
+ def executed_for ability
9
+ executed[hash_key_for(ability)] ||= []
10
+ end
11
+
12
+ def executed
13
+ @executed ||= {}
14
+ end
15
+
16
+ def clear_executed!
17
+ @executed = nil
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,19 @@
1
+ class CanTango::Config
2
+ class Permits
3
+ class Key
4
+ include Singleton
5
+
6
+ def hash_for ability
7
+ create_for(ability).value
8
+ end
9
+
10
+ def create_for ability
11
+ ability.respond_to?(:subject) ? maker.create_for(ability) : maker.new(ability)
12
+ end
13
+
14
+ def maker
15
+ CanTango::Ability::Cache::SimpleKey
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,33 @@
1
+ class CanTango::Config
2
+ class Permits
3
+ module Registration
4
+ include CanTango::Permit::Helper::Naming
5
+
6
+ def register_permit clazz, options = {}
7
+ register clazz, options
8
+ end
9
+
10
+ def register_permit_type clazz, options = {}
11
+ types.register permit_name(clazz), clazz
12
+ end
13
+
14
+ def register permit_clazz, options = {}
15
+ permit_name = options[:name] || permit_name(permit_clazz)
16
+ permit_type = options[:type] || permit_type(permit_clazz)
17
+ acc_name = options[:account] || (permit_clazz.account_name if permit_clazz.respond_to?(:account_name))
18
+
19
+ registry = acc_name ? accounts.registry_for(acc_name) : self
20
+
21
+ unless registry
22
+ raise acc_name ? "Missing Permit account Registry for #{acc_name}" : "Missing Permit Registry for #{self}"
23
+ end
24
+
25
+ acc_debug = acc_name ? "(#{acc_name})" : ''
26
+ debug "Registering #{permit_type} permit: #{permit_name} of class #{permit_clazz} #{acc_debug}"
27
+
28
+ permit_registry = registry.registry_for(permit_type)
29
+ permit_registry.register permit_name => permit_clazz
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,19 @@
1
+ class CanTango::Config
2
+ class Permits
3
+ module Tracking
4
+ def allowed candidate, actions, subjects, *extra_args
5
+ executed_for(candidate).inject([]) do |result, permit|
6
+ result << permit.class if permit.can? actions, subjects, *extra_args
7
+ result
8
+ end
9
+ end
10
+
11
+ def denied candidate, actions, subjects, *extra_args
12
+ executed_for(candidate).inject([]) do |result, permit|
13
+ result << permit.class if permit.cannot? actions, subjects, *extra_args
14
+ result
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,25 @@
1
+ class CanTango::Config
2
+ class Permits
3
+ class Types < CanTango::Registry::Base
4
+ include Singleton
5
+
6
+ attr_writer :enabled
7
+
8
+ def available
9
+ registered
10
+ end
11
+
12
+ def enabled
13
+ @enabled || available
14
+ end
15
+
16
+ def disable *types
17
+ @enabled = available - registered.flatten
18
+ end
19
+
20
+ def enable_all!
21
+ @enabled = available
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,7 @@
1
+ module CanTango
2
+ class Engine
3
+ sweet_scope :ns => {:CanTango => 'cantango/permits_ext'} do
4
+ sweetload :Permits
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,75 @@
1
+ module CanTango
2
+ class Engine
3
+ class Permits < CanTango::Ability::Executor::Base
4
+ include CanTango::Ability::Helper::User
5
+
6
+ def initialize ability
7
+ super
8
+ end
9
+
10
+ def calc_rules
11
+ # push result of each permit type execution into main ability rules array
12
+ permits.each_pair do |type, permits|
13
+ perm_rules = executor(type, permits).execute!
14
+ rules << perm_rules if !perm_rules.blank?
15
+ end
16
+ end
17
+
18
+ def executor type, permits
19
+ CanTango::Ability::Executor::PermitType.new self, type, permits_of(type)
20
+ end
21
+
22
+ def engine_name
23
+ :permit
24
+ end
25
+
26
+ def valid?
27
+ return false if !valid_mode?
28
+ permits.empty? ? invalid : true
29
+ end
30
+
31
+ # by default, only execute permits for which the user
32
+ # has a role or a role group
33
+ # also execute any permit marked as special
34
+ def permits_of type
35
+ @permits ||= permit_factory(type).create
36
+ end
37
+
38
+ def permit_class_names
39
+ @permit_class_names ||= permits.map{|p| p.class.to_s}
40
+ end
41
+
42
+ protected
43
+
44
+ alias_method :cache_key, :engine_name
45
+
46
+ def start_execute
47
+ debug "Permit Engine executing..."
48
+ end
49
+
50
+ def end_execute
51
+ debug "Done executing Permit Engine"
52
+ end
53
+
54
+ def invalid
55
+ debug "No permits found!"
56
+ false
57
+ end
58
+
59
+ def permit_factory type
60
+ @permit_factory ||= CanTango::Factory::Permit.new self, type
61
+ end
62
+
63
+ def key_method_names
64
+ permits.keys.map do |permit|
65
+ permit_class = available_permits_for permit
66
+ permit_class.hash_key if permit_class && permit_class.respond_to?(:hash_key)
67
+ end.compact
68
+ end
69
+
70
+ def available_permits_for type
71
+ CanTango.config.permits.types.available
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,7 @@
1
+ module CanTango
2
+ module Factory
3
+ sweet_scope :ns => {:CanTango => 'cantango/permits_ext'} do
4
+ sweetload :Permits
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,40 @@
1
+ module CanTango
2
+ module Factory
3
+ class Permits
4
+ include CanTango::Helpers::Debug
5
+
6
+ attr_accessor :ability
7
+ attr_reader :type
8
+
9
+ # creates the factory for the ability
10
+ # note that the ability contains the roles and role groups of the user (or account)
11
+ # @param [Permits::Ability] the ability
12
+ def initialize ability, type
13
+ @ability, @type = [ability, type]
14
+ end
15
+
16
+ def create
17
+ permits.build
18
+ end
19
+
20
+ def permits
21
+ permits_builder.new ability
22
+ end
23
+
24
+ def permits_builder
25
+ permits_builder_class.constantize
26
+ end
27
+
28
+ def permits_builder_class
29
+ return "CanTango::Builder::Permit::Special" if type == :special
30
+ "CanTango::Builder::Permit::#{type.to_s.camelize}"
31
+ end
32
+
33
+ protected
34
+
35
+ def enabled_permit_types
36
+ CanTango.config.permits.types.enabled
37
+ end
38
+ end
39
+ end
40
+ end