cantango 0.8.0 → 0.8.5.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 (270) hide show
  1. data/Gemfile +32 -19
  2. data/README.textile +79 -131
  3. data/VERSION +1 -1
  4. data/cantango.gemspec +94 -61
  5. data/lib/cantango.rb +4 -6
  6. data/lib/cantango/ability.rb +28 -17
  7. data/lib/cantango/ability/cache.rb +30 -60
  8. data/lib/cantango/ability/cache/base_cache.rb +1 -1
  9. data/lib/cantango/ability/cache/key.rb +39 -0
  10. data/lib/cantango/ability/cache/kompiler.rb +22 -6
  11. data/lib/cantango/ability/cache/moneta_cache.rb +1 -1
  12. data/lib/cantango/ability/cache/reader.rb +32 -0
  13. data/lib/cantango/ability/cache/rules_cache.rb +31 -0
  14. data/lib/cantango/ability/cache/session_cache.rb +3 -2
  15. data/lib/cantango/ability/cache/writer.rb +42 -0
  16. data/lib/cantango/ability/cache_helpers.rb +28 -0
  17. data/lib/cantango/ability/masquerade_helpers.rb +7 -2
  18. data/lib/cantango/ability/permission_helpers.rb +0 -8
  19. data/lib/cantango/ability/permit_helpers.rb +0 -17
  20. data/lib/cantango/ability/role_helpers.rb +0 -2
  21. data/lib/cantango/ability/user_helpers.rb +1 -0
  22. data/lib/cantango/adapter/compiler.rb +9 -0
  23. data/lib/cantango/adapter/moneta.rb +23 -0
  24. data/lib/cantango/api.rb +1 -1
  25. data/lib/cantango/api/aliases.rb +4 -8
  26. data/lib/cantango/api/attributes.rb +17 -0
  27. data/lib/cantango/api/common.rb +6 -0
  28. data/lib/cantango/api/options.rb +9 -5
  29. data/lib/cantango/cache.rb +1 -1
  30. data/lib/cantango/cache/hash_cache.rb +34 -0
  31. data/lib/cantango/configuration.rb +13 -8
  32. data/lib/cantango/configuration/adapters.rb +25 -0
  33. data/lib/cantango/configuration/categories.rb +3 -1
  34. data/lib/cantango/configuration/engines.rb +83 -11
  35. data/lib/cantango/configuration/engines/cache.rb +12 -1
  36. data/lib/cantango/configuration/engines/engine.rb +5 -5
  37. data/lib/cantango/configuration/engines/permission.rb +1 -1
  38. data/lib/cantango/configuration/permit_registry.rb +17 -0
  39. data/lib/cantango/configuration/permits.rb +29 -0
  40. data/lib/cantango/configuration/registry.rb +5 -2
  41. data/lib/cantango/configuration/role_groups.rb +3 -0
  42. data/lib/cantango/configuration/role_registry.rb +4 -0
  43. data/lib/cantango/configuration/roles.rb +2 -0
  44. data/lib/cantango/configuration/user_accounts.rb +1 -0
  45. data/lib/cantango/configuration/users.rb +1 -0
  46. data/lib/cantango/engine.rb +13 -0
  47. data/lib/cantango/filters.rb +5 -0
  48. data/lib/cantango/filters/filter.rb +34 -0
  49. data/lib/cantango/filters/role_filter.rb +29 -0
  50. data/lib/cantango/filters/role_group_filter.rb +28 -0
  51. data/lib/cantango/permission_engine.rb +26 -1
  52. data/lib/cantango/permission_engine/collector.rb +7 -2
  53. data/lib/cantango/permission_engine/compiler.rb +8 -1
  54. data/lib/cantango/permission_engine/evaluator.rb +2 -2
  55. data/lib/cantango/permission_engine/factory.rb +8 -12
  56. data/lib/cantango/permission_engine/loader.rb +1 -1
  57. data/lib/cantango/permission_engine/loader/base.rb +1 -1
  58. data/lib/cantango/permission_engine/loader/categories.rb +3 -3
  59. data/lib/cantango/permission_engine/loader/permissions.rb +8 -5
  60. data/lib/cantango/permission_engine/moneta_store.rb +2 -2
  61. data/lib/cantango/permission_engine/parser.rb +1 -1
  62. data/lib/cantango/permission_engine/parser/categories.rb +1 -1
  63. data/lib/cantango/permission_engine/parser/category.rb +1 -1
  64. data/lib/cantango/permission_engine/parser/default.rb +1 -2
  65. data/lib/cantango/permission_engine/parser/ownership.rb +1 -1
  66. data/lib/cantango/permission_engine/parser/permissions.rb +1 -1
  67. data/lib/cantango/permission_engine/parser/regex.rb +2 -2
  68. data/lib/cantango/permission_engine/parser/relationship.rb +1 -1
  69. data/lib/cantango/permission_engine/parser/rule.rb +1 -1
  70. data/lib/cantango/permission_engine/permission.rb +2 -2
  71. data/lib/cantango/permission_engine/selector.rb +3 -3
  72. data/lib/cantango/permission_engine/selector/account_types.rb +24 -0
  73. data/lib/cantango/permission_engine/selector/base.rb +3 -3
  74. data/lib/cantango/permission_engine/selector/licenses.rb +2 -2
  75. data/lib/cantango/permission_engine/selector/role_groups.rb +7 -6
  76. data/lib/cantango/permission_engine/selector/roles.rb +10 -6
  77. data/lib/cantango/permission_engine/selector/user_types.rb +23 -0
  78. data/lib/cantango/permission_engine/selector/users.rb +2 -2
  79. data/lib/cantango/permission_engine/statement.rb +10 -9
  80. data/lib/cantango/permission_engine/statements.rb +27 -25
  81. data/lib/cantango/permission_engine/store.rb +1 -1
  82. data/lib/cantango/permission_engine/yaml_store.rb +2 -2
  83. data/lib/cantango/permit_engine.rb +29 -4
  84. data/lib/cantango/permit_engine/builder.rb +2 -3
  85. data/lib/cantango/permit_engine/builder/base.rb +9 -1
  86. data/lib/cantango/permit_engine/builder/special_permits.rb +7 -8
  87. data/lib/cantango/permit_engine/compatibility.rb +1 -1
  88. data/lib/cantango/permit_engine/executor.rb +1 -1
  89. data/lib/cantango/permit_engine/executor/abstract.rb +1 -1
  90. data/lib/cantango/permit_engine/executor/base.rb +1 -1
  91. data/lib/cantango/permit_engine/executor/system.rb +1 -1
  92. data/lib/cantango/permit_engine/factory.rb +2 -7
  93. data/lib/cantango/permit_engine/finder.rb +43 -9
  94. data/lib/cantango/permit_engine/role_matcher.rb +1 -1
  95. data/lib/cantango/permit_engine/util.rb +2 -1
  96. data/lib/cantango/permits.rb +9 -0
  97. data/lib/cantango/{permit_engine → permits}/account_permit.rb +15 -4
  98. data/lib/cantango/{permit_engine → permits}/account_permit/builder.rb +2 -6
  99. data/lib/cantango/{permit_engine → permits}/account_permit/finder.rb +2 -2
  100. data/lib/cantango/{permit_engine → permits}/license.rb +1 -1
  101. data/lib/cantango/{permit_engine → permits}/license/loader.rb +1 -1
  102. data/lib/cantango/{permit_engine → permits}/license/rules.rb +1 -1
  103. data/lib/cantango/permits/macros.rb +19 -0
  104. data/lib/cantango/{permit_engine → permits}/permit.rb +13 -1
  105. data/lib/cantango/{permit_engine → permits}/role_group_permit.rb +15 -3
  106. data/lib/cantango/{permit_engine → permits}/role_group_permit/builder.rb +10 -22
  107. data/lib/cantango/{permit_engine → permits}/role_group_permit/finder.rb +2 -2
  108. data/lib/cantango/{permit_engine → permits}/role_permit.rb +15 -3
  109. data/lib/cantango/permits/role_permit/builder.rb +27 -0
  110. data/lib/cantango/{permit_engine → permits}/role_permit/finder.rb +2 -2
  111. data/lib/cantango/{permit_engine → permits}/user_permit.rb +15 -3
  112. data/lib/cantango/{permit_engine → permits}/user_permit/builder.rb +2 -6
  113. data/lib/cantango/{permit_engine → permits}/user_permit/finder.rb +2 -2
  114. data/lib/cantango/rails.rb +3 -1
  115. data/lib/cantango/rails/engine.rb +11 -6
  116. data/lib/cantango/rails/helpers/base_helper.rb +28 -0
  117. data/lib/cantango/rails/helpers/controller_helper.rb +17 -0
  118. data/lib/cantango/rails/helpers/rest_helper.rb +44 -0
  119. data/lib/cantango/rails/helpers/view_helper.rb +17 -0
  120. data/lib/cantango/rails/railtie.rb +1 -1
  121. data/lib/cantango/rspec/config.rb +1 -1
  122. data/lib/cantango/rspec/matchers/be_allowed_to.rb +5 -3
  123. data/lib/cantango/rules/user_relation.rb +1 -1
  124. data/lib/cantango/users/macros.rb +8 -2
  125. data/lib/cantango/users/user.rb +1 -1
  126. data/lib/generators/cantango/account_permit/account_permit_generator.rb +37 -0
  127. data/lib/generators/cantango/account_permit/templates/account_permit.erb +13 -0
  128. data/lib/generators/cantango/base.rb +15 -18
  129. data/lib/generators/cantango/basic.rb +41 -0
  130. data/lib/generators/cantango/install/install_generator.rb +37 -0
  131. data/lib/generators/cantango/install/templates/cantango.rb +4 -0
  132. data/{spec/active_record/scenarios/user_accounts/config/account_permits.yml → lib/generators/cantango/install/templates/categories.yml} +0 -0
  133. data/lib/generators/cantango/install/templates/permissions.yml +4 -0
  134. data/lib/generators/cantango/license/license_generator.rb +6 -11
  135. data/lib/generators/cantango/license/templates/license.erb +1 -1
  136. data/lib/generators/cantango/license_base.rb +2 -2
  137. data/lib/generators/cantango/licenses/licenses_generator.rb +2 -7
  138. data/lib/generators/cantango/permit_generator.rb +31 -10
  139. data/lib/generators/cantango/role_permit/role_permit_generator.rb +11 -14
  140. data/lib/generators/cantango/role_permit/templates/account_permit.erb +2 -2
  141. data/lib/generators/cantango/role_permit/templates/role_group_permit.erb +2 -2
  142. data/lib/generators/cantango/role_permit/templates/role_permit.erb +2 -2
  143. data/lib/generators/cantango/role_permits/role_permits_generator.rb +16 -98
  144. data/lib/generators/cantango/user_permit/templates/account_permit.erb +5 -0
  145. data/lib/generators/cantango/user_permit/templates/user_permit.erb +13 -0
  146. data/lib/generators/cantango/user_permit/user_permit_generator.rb +36 -0
  147. data/spec/TODO +1 -6
  148. data/spec/active_record/helper/permits_config.rb +1 -1
  149. data/spec/active_record/scenarios/engines/permission_engine/{cantango_permissions.yml → permissions.yml} +2 -1
  150. data/spec/active_record/scenarios/engines/permission_engine/tango_permission_yml_spec.rb +8 -9
  151. data/spec/active_record/scenarios/engines/permit_engine/licenses_spec.rb +2 -2
  152. data/spec/active_record/scenarios/engines/permit_engine/role_groups_permits_spec.rb +2 -2
  153. data/spec/active_record/scenarios/shared/{can_tango.rb → cantango.rb} +1 -1
  154. data/spec/active_record/scenarios/shared/models/items.rb +0 -1
  155. data/spec/active_record/scenarios/shared/models/users.rb +6 -1
  156. data/spec/active_record/spec_helper.rb +6 -4
  157. data/spec/cantango/ability/cache/key_spec.rb +64 -0
  158. data/spec/cantango/ability/cache/{compiler_spec.rb → kompiler_spec.rb} +9 -21
  159. data/spec/cantango/ability/cache/reader_compile_spec.rb +42 -0
  160. data/spec/cantango/ability/cache/reader_spec.rb +33 -0
  161. data/spec/cantango/ability/cache/rules_cache_spec.rb +15 -0
  162. data/spec/cantango/ability/cache/session_cache_spec.rb +1 -1
  163. data/spec/cantango/ability/cache/writer_spec.rb +21 -0
  164. data/spec/cantango/ability/cache_spec.rb +6 -2
  165. data/spec/cantango/ability_filters_spec.rb +5 -10
  166. data/spec/cantango/ability_spec.rb +2 -3
  167. data/spec/cantango/api/attributes_spec.rb +27 -0
  168. data/spec/cantango/api/user/can_api_spec.rb +2 -2
  169. data/spec/cantango/api/user_account/can_api_spec.rb +2 -2
  170. data/spec/cantango/configuration/adapter_spec.rb +28 -0
  171. data/spec/cantango/configuration/engines/cache_spec.rb +2 -2
  172. data/spec/cantango/configuration/engines/permission_spec.rb +3 -3
  173. data/spec/cantango/configuration/engines/permit_spec.rb +1 -1
  174. data/spec/cantango/configuration/engines/store_shared.rb +3 -1
  175. data/spec/cantango/configuration/engines_spec.rb +106 -3
  176. data/spec/cantango/configuration/hash_registry_spec.rb +1 -1
  177. data/spec/cantango/configuration/permit_registry_spec.rb +14 -0
  178. data/spec/cantango/configuration/permits_spec.rb +25 -0
  179. data/spec/cantango/configuration/registry_spec.rb +1 -1
  180. data/spec/cantango/configuration/shared/registry_ex.rb +2 -1
  181. data/spec/cantango/configuration_spec.rb +5 -5
  182. data/spec/cantango/permission_engine/compiler_spec.rb +8 -0
  183. data/spec/cantango/permission_engine/permission_spec.rb +1 -1
  184. data/spec/cantango/permission_engine/yaml_store_spec.rb +14 -4
  185. data/spec/cantango/permission_engine_spec.rb +0 -0
  186. data/spec/cantango/permit_engine/account_permit_spec.rb +2 -4
  187. data/spec/cantango/permit_engine/builder/role_group_permits_spec.rb +4 -7
  188. data/spec/cantango/permit_engine/builder/role_permits_spec.rb +5 -6
  189. data/spec/cantango/permit_engine/builder/special_permits_spec.rb +3 -4
  190. data/spec/cantango/permit_engine/executor/system_spec.rb +2 -2
  191. data/spec/cantango/permit_engine/factory_spec.rb +2 -3
  192. data/spec/cantango/permit_engine/finder_spec.rb +144 -23
  193. data/spec/cantango/permit_engine/permit/permit_static_and_dynamic_rules_spec.rb +4 -5
  194. data/spec/cantango/permit_engine/role_group_permit_spec.rb +1 -1
  195. data/spec/cantango/permit_engine/role_permit_spec.rb +6 -7
  196. data/spec/cantango/permit_engine/user_permit_spec.rb +2 -3
  197. data/spec/cantango/permit_engine_spec.rb +2 -0
  198. data/spec/cantango/permits/macros_spec.rb +41 -0
  199. data/spec/cantango/permits/permit_spec.rb +46 -0
  200. data/spec/cantango_spec.rb +13 -0
  201. data/spec/devise-dummy/app/helpers/application_helper.rb +7 -0
  202. data/spec/devise-dummy/app/views/articles/admin.html.haml +1 -1
  203. data/spec/devise-dummy/app/views/articles/admin_account.html.haml +1 -1
  204. data/spec/devise-dummy/app/views/articles/guest.html.haml +1 -1
  205. data/spec/devise-dummy/app/views/articles/index.html.haml +1 -1
  206. data/spec/devise-dummy/app/views/comments/guest.html.haml +1 -1
  207. data/spec/devise-dummy/app/views/comments/index.html.haml +1 -1
  208. data/spec/devise-dummy/app/views/concertos/admin.html.haml +1 -1
  209. data/spec/devise-dummy/app/views/concertos/admin_account.html.haml +1 -1
  210. data/spec/devise-dummy/app/views/concertos/guest.html.haml +1 -1
  211. data/spec/devise-dummy/app/views/concertos/index.html.haml +1 -1
  212. data/spec/devise-dummy/app/views/users/index.html.haml +1 -1
  213. data/spec/devise-dummy/config/initializers/cantango.rb +3 -3
  214. data/spec/devise-dummy/config/{cantango_permissions.yml → permissions.yml} +2 -1
  215. data/spec/devise-integration/concerto_spec.rb +1 -1
  216. data/spec/dummy/app/models/user.rb +1 -0
  217. data/spec/dummy/app/views/articles/admin.html.haml +1 -1
  218. data/spec/dummy/app/views/articles/admin_account.html.haml +1 -1
  219. data/spec/dummy/app/views/articles/guest.html.haml +1 -1
  220. data/spec/dummy/app/views/articles/index.html.haml +1 -1
  221. data/spec/dummy/app/views/comments/guest.html.haml +1 -1
  222. data/spec/dummy/app/views/comments/index.html.haml +1 -1
  223. data/spec/dummy/app/views/concertos/admin.html.haml +1 -1
  224. data/spec/dummy/app/views/concertos/admin_account.html.haml +1 -1
  225. data/spec/dummy/app/views/concertos/guest.html.haml +1 -1
  226. data/spec/dummy/app/views/concertos/index.html.haml +1 -1
  227. data/spec/dummy/app/views/posts/admin.html.haml +1 -1
  228. data/spec/dummy/app/views/posts/admin_account.html.haml +1 -1
  229. data/spec/dummy/app/views/posts/guest.html.haml +1 -1
  230. data/spec/dummy/app/views/posts/index.html.haml +1 -1
  231. data/spec/dummy/app/views/users/admin.html.haml +1 -1
  232. data/spec/dummy/app/views/users/admin_account.html.haml +1 -1
  233. data/spec/dummy/app/views/users/guest.html.haml +1 -1
  234. data/spec/dummy/app/views/users/index.html.haml +1 -1
  235. data/spec/dummy/config/application.rb +1 -0
  236. data/spec/dummy/config/initializers/cantango.rb +1 -3
  237. data/spec/dummy/config/{cantango_permissions.yml → permissions.yml} +2 -2
  238. data/spec/dummy_spec_helper.rb +2 -0
  239. data/spec/entire_suite_spec.rb +2 -0
  240. data/spec/factories/user.rb +8 -0
  241. data/spec/factories/user_account.rb +6 -0
  242. data/spec/fixtures/config/permissions.yml +60 -19
  243. data/spec/fixtures/models/admin.rb +2 -0
  244. data/spec/fixtures/models/admin_account.rb +22 -0
  245. data/spec/fixtures/models/simple_roles.rb +5 -0
  246. data/spec/fixtures/models/user.rb +4 -0
  247. data/spec/helpers/dummy_app_ability.rb +2 -5
  248. data/spec/integration/cache_using_moneta_spec.rb +3 -1
  249. data/spec/integration/cache_using_session_spec.rb +2 -2
  250. data/spec/integration/user/articles_spec.rb +1 -1
  251. data/spec/integration/user/concerto_spec.rb +1 -1
  252. data/spec/spec_helper.rb +5 -5
  253. metadata +120 -95
  254. data/lib/cantango/ability/class_methods.rb +0 -27
  255. data/lib/cantango/api/aliases/account_permit.rb +0 -8
  256. data/lib/cantango/api/aliases/license.rb +0 -7
  257. data/lib/cantango/api/aliases/permit.rb +0 -9
  258. data/lib/cantango/api/aliases/role_group_permit.rb +0 -7
  259. data/lib/cantango/api/aliases/role_permit.rb +0 -7
  260. data/lib/cantango/api/aliases/user_permit.rb +0 -8
  261. data/lib/cantango/permission_engine/builder.rb +0 -6
  262. data/lib/cantango/permit_engine/role_permit/builder.rb +0 -46
  263. data/lib/cantango/rails/base_helpers.rb +0 -26
  264. data/lib/cantango/rails/controller_helpers.rb +0 -15
  265. data/lib/cantango/rails/view_helpers.rb +0 -15
  266. data/spec/active_record/scenarios/shared/permits/PERMITS README.textile +0 -3
  267. data/spec/active_record/scenarios/user_accounts/docs/USER_ACCOUNTS_SCENARIO.textile +0 -20
  268. data/spec/active_record/scenarios/user_accounts/docs/basic_rules_spec_possible_samples.txt +0 -84
  269. data/spec/factories.rb +0 -8
  270. data/spec/fixtures/config/cantango_permissions.yml +0 -48
data/lib/cantango.rb CHANGED
@@ -2,20 +2,17 @@ require 'cantango/rails/railtie' if defined?(Rails)
2
2
  require 'cantango/rails/engine' if defined?(Rails)
3
3
  require 'cancan'
4
4
  require 'cantango/cancan/rule'
5
- require 'sugar-high/class_ext'
6
5
  require 'sugar-high/array'
7
6
  require 'sugar-high/blank'
8
7
  require 'hashie'
9
- require 'cutter'
10
- require 'moneta'
8
+ require 'sweetloader'
11
9
 
12
- # AutoLoader.root = ''
13
10
  AutoLoader.namespaces = {:CanTango => 'cantango'}
14
11
 
15
12
  module CanTango
16
- autoload_modules :Ability, :Api, :Configuration, :Cache
13
+ autoload_modules :Ability, :Api, :Configuration, :Cache, :Permits
17
14
  autoload_modules :PermitEngine, :Rails, :Users
18
- autoload_modules :PermissionEngine, :Rules, :Api, :Helpers
15
+ autoload_modules :PermissionEngine, :Rules, :Api, :Helpers, :Filters, :Engine
19
16
 
20
17
  class << self
21
18
  def configure &block
@@ -29,4 +26,5 @@ module CanTango
29
26
  end
30
27
 
31
28
  require 'cantango/api/aliases'
29
+ require 'cantango/permits/macros'
32
30
  require 'cantango/users/macros'
@@ -1,17 +1,14 @@
1
- # @stanislaw: needed?
2
1
  require 'cantango/permit_engine/util'
3
2
 
4
3
  module CanTango
5
4
  class Ability
6
- autoload_modules :ClassMethods, :Scope, :Cache
5
+ autoload_modules :Scope, :Cache
7
6
  autoload_modules :MasqueradeHelpers, :PermitHelpers, :PermissionHelpers
8
- autoload_modules :UserHelpers, :RoleHelpers
7
+ autoload_modules :UserHelpers, :RoleHelpers, :CacheHelpers
9
8
 
10
9
  include CanCan::Ability
11
- include Cache
12
- extend ClassMethods
13
10
 
14
- attr_reader :options, :subject, :session
11
+ attr_reader :options, :subject, :session, :candidate
15
12
 
16
13
  # Equivalent to a CanCan Ability#initialize call
17
14
  # which executes all the permission logic
@@ -22,31 +19,45 @@ module CanTango
22
19
 
23
20
  return if cached_rules?
24
21
 
25
- # run permission evaluators
26
- with(:permissions) {|permission| permission.evaluate! user }
27
- with(:permits) {|permit| break if permit.execute == :break }
22
+ clear_rules!
23
+ permit_rules
24
+ execute_engines!
28
25
 
29
- cache_rules!
26
+ cache_rules! if caching_on?
30
27
  end
31
28
 
32
29
  include CanTango::PermitEngine::Util
33
30
 
34
- def with engine_type, &block
35
- send(engine_type).each do |obj|
36
- yield obj
37
- end if send(:"#{engine_type}?")
31
+ def permit_rules
32
+ end
33
+
34
+ def clear_rules!
35
+ @rules = []
36
+ end
37
+
38
+ def execute_engines!
39
+ each_engine {|engine| engine.new(self).execute! if engine }
40
+ end
41
+
42
+ def each_engine &block
43
+ engines.execution_order.each {|name| yield engines.registered[name] if engines.active? name }
44
+ end
45
+
46
+ def engines
47
+ CanTango.config.engines
38
48
  end
39
49
 
40
50
  def subject
41
- return @candidate.active_user if masquerade_user?
42
- return @candidate.active_account if masquerade_account?
43
- @candidate
51
+ return candidate.active_user if masquerade_user?
52
+ return candidate.active_account if masquerade_account?
53
+ candidate
44
54
  end
45
55
 
46
56
  def config
47
57
  CanTango.config
48
58
  end
49
59
 
60
+ include CacheHelpers
50
61
  include MasqueradeHelpers
51
62
  include PermissionHelpers
52
63
  include PermitHelpers
@@ -1,92 +1,62 @@
1
1
  module CanTango
2
2
  class Ability
3
- module Cache
4
- autoload_modules :BaseCache, :SessionCache, :MonetaCache, :Kompiler
3
+ class Cache
4
+ autoload_modules :BaseCache, :SessionCache, :Reader, :Writer, :RulesCache, :Key
5
5
 
6
- include CanTango::Ability::Cache::Kompiler
6
+ attr_reader :rules_cached, :ability
7
7
 
8
- attr_reader :rules_cached
9
-
10
- def rules
11
- return cached_rules if cached_rules?
12
- super
13
- end
14
-
15
- def cache_rules!
16
- return if !caching_on?
17
- invalidate_cache!
18
- rules_compiled = compile_rules! rules
19
- rules_cache.save cache_key, rules_compiled
20
- session_check!
21
- session[:cache_key] = cache_key
8
+ def initialize ability
9
+ @ability = ability
22
10
  end
23
11
 
24
- def caching_on?
25
- CanTango.config.cache.on?
12
+ def session
13
+ ability.session
26
14
  end
27
15
 
28
- def cached_rules?
29
- caching_on? && cache_key_same?
16
+ def cache_rules!
17
+ writer.save key, reader.prepared_rules
30
18
  end
31
19
 
32
20
  def cached_rules
33
- rules_compiled = rules_cache.load(cache_key)
34
- rules_raw = decompile_rules! rules_compiled
35
- @rules ||= rules_raw
21
+ @rules ||= reader.prepared_rules
36
22
  end
37
23
 
38
- def cache_key
39
- @cache_key ||= begin
40
- user_key_field = CanTango.config.user.unique_key_field || :email
41
- raise "#{user.class} must have a method ##{user_key_field}. You can configure this with CanTango.config#user.unique_key_field" if !user.respond_to?(user_key_field)
42
-
43
- user_key = user.send(user_key_field)
44
- [user_key, subject_roles_hash].hash
45
- end
24
+ def compiler
25
+ @compiler ||= Kompiler.new
46
26
  end
47
27
 
48
- def subject_roles_hash
49
- [subject.roles_list, subject.role_groups_list].hash
28
+ def reader
29
+ @reader ||= Reader.new(self)
50
30
  end
51
31
 
52
- def invalidate_cache!
53
- session_check!
54
- rules_cache.invalidate! session[:cache_key]
32
+ def writer
33
+ @writer ||= Writer.new(self)
55
34
  end
56
35
 
57
- def rules_cache
58
- @rules_cache ||= rules_cache_instance
59
- end
60
-
61
- protected
62
-
63
- def cache_key_same?
64
- session_check!
65
- session[:cache_key] && (cache_key == session[:cache_key])
36
+ def cached_rules?
37
+ key.same? session
66
38
  end
67
39
 
68
- def rules_cache_instance
69
- @rules_cache_instance ||= begin
70
- options = rules_cache_options
71
- options.merge!(:session => session) if session?
72
- rules_cache_class.new :rules_cache, options
73
- end
40
+ def key
41
+ @key ||= Key.new ability.user, ability.subject
74
42
  end
75
43
 
76
- def rules_cache_options
77
- CanTango.config.cache.store.options || {}
44
+ def rules_cache
45
+ @rules_cache ||= RulesCache.new(session).instance
78
46
  end
79
47
 
80
- def rules_cache_class
81
- CanTango.config.cache.store.default_class
48
+ def invalidate!
49
+ raise "no session" if !session
50
+ rules_cache.invalidate! session[:cache_key]
82
51
  end
83
52
 
84
- def session?
85
- session
53
+ def compile_on?
54
+ return false if !compile_adapter?
55
+ CanTango.config.cache_engine.compile?
86
56
  end
87
57
 
88
- def session_check!
89
- raise "No session available" if !session?
58
+ def compile_adapter?
59
+ CanTango.config.adapters.registered?(:compiler)
90
60
  end
91
61
  end
92
62
  end
@@ -1,6 +1,6 @@
1
1
  module CanTango
2
2
  class Ability
3
- module Cache
3
+ class Cache
4
4
  class BaseCache
5
5
  attr_reader :name, :options
6
6
 
@@ -0,0 +1,39 @@
1
+ module CanTango
2
+ class Ability
3
+ class Cache
4
+ class Key
5
+ attr_reader :user, :subject
6
+
7
+ def initialize user, subject
8
+ @user = user
9
+ @subject = subject
10
+ end
11
+
12
+ def value
13
+ raise "#{user.class} must have a method ##{user_key_field}. You can configure this with CanTango.config#user.unique_key_field" if !user.respond_to?(user_key_field)
14
+ @value ||= [user_key, subject_roles_hash].hash
15
+ end
16
+
17
+ def same? session
18
+ raise "No session available" if !session
19
+ session[:cache_key] && (value == session[:cache_key].value)
20
+ end
21
+
22
+ protected
23
+
24
+ def user_key
25
+ user.send(user_key_field)
26
+ end
27
+
28
+ def user_key_field
29
+ CanTango.config.user.unique_key_field || :email
30
+ end
31
+
32
+ def subject_roles_hash
33
+ [subject.roles_list, subject.role_groups_list].hash
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+
@@ -1,23 +1,39 @@
1
1
  require 'sourcify'
2
+
2
3
  module CanTango
3
4
  class Ability
4
- module Cache
5
- module Kompiler
5
+ class Cache
6
+ class Kompiler
7
+ class CacheMarshallError < StandardError; end
6
8
 
7
- def compile_rules! rules_raw
9
+ def compile! rules_raw
10
+ return if !rules_raw
8
11
  rules_compiled = rules_raw.map do |rule|
9
- rule.block = rule.block.to_source if rule.block.class == Proc
12
+ rule.block = rule.block.to_source if rule.block.class == Proc && sourcify?
10
13
  rule
11
14
  end
12
15
  end
13
16
 
14
- def decompile_rules! rules_compiled
17
+ def decompile! rules_compiled
18
+ return if !rules_compiled
15
19
  rules_raw = rules_compiled.map do |rule|
16
- rule.block = eval("#{rule.block}")
20
+ compiler_check! rule
21
+ rule.block = eval("#{rule.block}") if sourcify?
17
22
  rule
18
23
  end
19
24
  end
20
25
 
26
+ protected
27
+
28
+ def sourcify?
29
+ @sourcify ||= Proc.new {}.respond_to?(:to_source)
30
+ end
31
+
32
+ def compiler_check! rule
33
+ if rule.block && !CanTango.config.adapters.registered?(:compiler)
34
+ raise "You can NOT marshal dynamic rules (with Procs) unless you register the :compiler adapter"
35
+ end
36
+ end
21
37
  end
22
38
  end
23
39
  end
@@ -3,7 +3,7 @@ require 'active_support/inflector'
3
3
 
4
4
  module CanTango
5
5
  class Ability
6
- module Cache
6
+ class Cache
7
7
  class MonetaCache
8
8
  # one cache store is shared for all store instances (w different names)
9
9
  attr_reader :store
@@ -0,0 +1,32 @@
1
+ module CanTango
2
+ class Ability
3
+ class Cache
4
+ class Reader
5
+ attr_reader :cache
6
+
7
+ def initialize cache
8
+ @cache = cache
9
+ end
10
+
11
+ def prepared_rules
12
+ cache.compile_on? ? compiler.decompile!(loaded_rules) : loaded_rules
13
+ end
14
+
15
+ protected
16
+
17
+ def loaded_rules
18
+ rules_cache.load(cache.key)
19
+ end
20
+
21
+ def compiler
22
+ cache.compiler
23
+ end
24
+
25
+ def rules_cache
26
+ cache.rules_cache
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+
@@ -0,0 +1,31 @@
1
+ module CanTango
2
+ class Ability
3
+ class Cache
4
+ class RulesCache
5
+ attr_reader :session
6
+
7
+ def instance
8
+ @instance ||= clazz.new :rules_cache, options
9
+ end
10
+
11
+ def initialize session = nil
12
+ @session = session
13
+ end
14
+
15
+ def options
16
+ @options ||= session ? cache_options.merge(:session => session) : cache_options
17
+ end
18
+
19
+ def cache_options
20
+ CanTango.config.cache_engine.store.options || {}
21
+ end
22
+
23
+ def clazz
24
+ CanTango.config.cache_engine.store.default_class
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+
@@ -1,6 +1,6 @@
1
1
  module CanTango
2
2
  class Ability
3
- module Cache
3
+ class Cache
4
4
  class SessionCache < BaseCache
5
5
  attr_accessor :session
6
6
 
@@ -30,7 +30,8 @@ module CanTango
30
30
  end
31
31
 
32
32
  def cache
33
- CanTango::Cache::MonetaCache.instance
33
+ CanTango::Cache::HashCache.instance
34
+ # CanTango::Cache::MonetaCache.instance
34
35
  end
35
36
  end
36
37
  end
@@ -0,0 +1,42 @@
1
+ module CanTango
2
+ class Ability
3
+ class Cache
4
+ class Writer
5
+ attr_reader :cache
6
+
7
+ def initialize cache
8
+ @cache = cache
9
+ end
10
+
11
+ def save key, rules
12
+ cache.invalidate!
13
+ cache.rules_cache.save cache.key, prepared_rules
14
+ session[:cache_key] = cache.key if session
15
+ end
16
+
17
+ protected
18
+
19
+ def prepared_rules
20
+ cache.compile_on? ? compiler.compile!(rules) : rules
21
+ end
22
+
23
+ def rules
24
+ return cache.cached_rules if cache.cached_rules?
25
+ cache.ability.send :rules # bad!? FIXME
26
+ end
27
+
28
+ def compiler
29
+ cache.compiler
30
+ end
31
+
32
+ def session
33
+ cache.session
34
+ end
35
+
36
+ def rules_cache
37
+ cache.rules_cache
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end