cantango-core 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. data/.document +5 -0
  2. data/.rspec +3 -0
  3. data/Gemfile +54 -0
  4. data/Gemfile.lock +231 -0
  5. data/LICENSE.txt +20 -0
  6. data/README.mdown +90 -0
  7. data/Rakefile +48 -0
  8. data/VERSION +1 -0
  9. data/cantango-core.gemspec +177 -0
  10. data/lib/cantango/ability.rb +5 -0
  11. data/lib/cantango/ability/base.rb +61 -0
  12. data/lib/cantango/ability/cache.rb +7 -0
  13. data/lib/cantango/ability/cache/key.rb +38 -0
  14. data/lib/cantango/ability/cached.rb +28 -0
  15. data/lib/cantango/ability/executor.rb +7 -0
  16. data/lib/cantango/ability/executor/base.rb +53 -0
  17. data/lib/cantango/ability/executor/cache_mode.rb +33 -0
  18. data/lib/cantango/ability/executor/modes.rb +52 -0
  19. data/lib/cantango/ability/executor/no_cache_mode.rb +17 -0
  20. data/lib/cantango/ability/helper.rb +11 -0
  21. data/lib/cantango/ability/helper/account.rb +13 -0
  22. data/lib/cantango/ability/helper/engine.rb +32 -0
  23. data/lib/cantango/ability/helper/role.rb +21 -0
  24. data/lib/cantango/ability/helper/role_group.rb +21 -0
  25. data/lib/cantango/ability/helper/user.rb +18 -0
  26. data/lib/cantango/cancan/rule.rb +6 -0
  27. data/lib/cantango/core.rb +84 -0
  28. data/lib/cantango/engine.rb +39 -0
  29. data/lib/cantango/filter.rb +5 -0
  30. data/lib/cantango/filter/base.rb +31 -0
  31. data/lib/cantango/helpers.rb +5 -0
  32. data/lib/cantango/helpers/debug.rb +10 -0
  33. data/lib/cantango/loader.rb +5 -0
  34. data/lib/cantango/loader/yaml.rb +33 -0
  35. data/lib/cantango/macros.rb +11 -0
  36. data/lib/cantango/macros/account.rb +14 -0
  37. data/lib/cantango/macros/user.rb +16 -0
  38. data/lib/cantango/model.rb +5 -0
  39. data/lib/cantango/model/guest.rb +25 -0
  40. data/lib/cantango/rails.rb +7 -0
  41. data/lib/cantango/rails/engine.rb +63 -0
  42. data/lib/cantango/rails/helpers/base_helper.rb +29 -0
  43. data/lib/cantango/rails/helpers/controller_helper.rb +17 -0
  44. data/lib/cantango/rails/helpers/rest_helper.rb +76 -0
  45. data/lib/cantango/rails/helpers/view_helper.rb +17 -0
  46. data/lib/cantango/rails/railtie.rb +7 -0
  47. data/lib/cantango/rspec.rb +1 -0
  48. data/lib/cantango/rspec/config.rb +3 -0
  49. data/lib/cantango/rspec/matchers.rb +1 -0
  50. data/lib/cantango/rspec/matchers/be_allowed_to.rb +28 -0
  51. data/lib/cantango/rules.rb +8 -0
  52. data/lib/cantango/rules/adaptor.rb +37 -0
  53. data/lib/cantango/rules/adaptor/active_record.rb +10 -0
  54. data/lib/cantango/rules/adaptor/data_mapper.rb +11 -0
  55. data/lib/cantango/rules/adaptor/generic.rb +16 -0
  56. data/lib/cantango/rules/adaptor/mongo.rb +19 -0
  57. data/lib/cantango/rules/adaptor/mongo_mapper.rb +10 -0
  58. data/lib/cantango/rules/adaptor/mongoid.rb +9 -0
  59. data/lib/cantango/rules/adaptor/relational.rb +13 -0
  60. data/lib/cantango/rules/dsl.rb +24 -0
  61. data/lib/cantango/rules/relation.rb +67 -0
  62. data/lib/cantango/rules/rule_class.rb +11 -0
  63. data/lib/cantango/rules/scope.rb +24 -0
  64. data/lib/cantango/scope.rb +5 -0
  65. data/lib/cantango/scope/ability.rb +20 -0
  66. data/lib/generators/cantango/install/install_generator.rb +37 -0
  67. data/lib/generators/cantango/install/templates/cantango.rb +4 -0
  68. data/lib/generators/cantango/install/templates/categories.yml +0 -0
  69. data/lib/generators/cantango/install/templates/permissions.yml +6 -0
  70. data/spec/cantango/ability/base_spec.rb +73 -0
  71. data/spec/cantango/ability/cached_spec.rb +0 -0
  72. data/spec/cantango/ability/executor/base2.rb +75 -0
  73. data/spec/cantango/ability/executor/base_spec.rb +67 -0
  74. data/spec/cantango/ability/executor/cache_mode_spec.rb +77 -0
  75. data/spec/cantango/ability/executor/modes_spec.rb +68 -0
  76. data/spec/cantango/ability/executor/no_cache_mode_spec.rb +0 -0
  77. data/spec/cantango/cancan/rule_spec.rb +0 -0
  78. data/spec/cantango/core_spec.rb +9 -0
  79. data/spec/cantango/engine_spec.rb +0 -0
  80. data/spec/cantango/filter/base_spec.rb +0 -0
  81. data/spec/cantango/helpers/debug_spec.rb +0 -0
  82. data/spec/cantango/loader/yaml_spec.rb +0 -0
  83. data/spec/cantango/macros/account_spec.rb +0 -0
  84. data/spec/cantango/macros/user_spec.rb +0 -0
  85. data/spec/cantango/rspec/be_allowed_to_spec.rb +0 -0
  86. data/spec/cantango/rules/adaptor/active_record_spec.rb +0 -0
  87. data/spec/cantango/rules/adaptor/data_mapper_spec.rb +0 -0
  88. data/spec/cantango/rules/adaptor/mongo_mapper_spec.rb +0 -0
  89. data/spec/cantango/rules/adaptor/mongoid_spec.rb +0 -0
  90. data/spec/cantango/rules/adaptor_spec.rb +0 -0
  91. data/spec/cantango/rules/dsl_spec.rb +0 -0
  92. data/spec/cantango/rules/relation_spec.rb +0 -0
  93. data/spec/cantango/rules/rule_class_spec.rb +0 -0
  94. data/spec/cantango/rules/scope_spec.rb +0 -0
  95. data/spec/cantango/rules_spec.rb +55 -0
  96. data/spec/cantango/scope/ability_spec.rb +0 -0
  97. data/spec/cantango_spec.rb +0 -0
  98. data/spec/generators/cantango/install_generator_spec.rb +42 -0
  99. data/spec/spec_helper.rb +9 -0
  100. metadata +310 -0
@@ -0,0 +1,17 @@
1
+ module CanTango
2
+ module Ability
3
+ module Executor
4
+ class NonCachedMode < Base
5
+ protected
6
+
7
+ def start_execute
8
+ debug "Executing non-cached Ability"
9
+ end
10
+
11
+ def end_execute
12
+ debug "DONE"
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,11 @@
1
+ module CanTango
2
+ module Ability
3
+ module Helper
4
+ def self.modules
5
+ [:Account, :Cache, :Engine, :Masquerade, :Permit, :PermitStore, :Role, :RoleGroup, :User]
6
+ end
7
+
8
+ autoload_modules *modules
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ module CanTango
2
+ class Ability
3
+ module Helper
4
+ module Account
5
+ def user_account
6
+ return subject.active_account if subject.respond_to? :active_account
7
+ subject
8
+ end
9
+ alias_method :account, :user_account
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,32 @@
1
+ module CanTango
2
+ class Ability
3
+ module Helper
4
+ module Engine
5
+ def execute_engines!
6
+ each_engine do |engine|
7
+ engine_rules = engine.new(self).execute! if engine
8
+ @rules << engine_rules if !engine_rules.blank?
9
+ end
10
+ end
11
+
12
+ def each_engine &block
13
+ engines.execution_order.each do |name|
14
+ yield engines.registered[name] if engines.active? name
15
+ end
16
+ end
17
+
18
+ def opts_engines_off?
19
+ options[:engines] == :off
20
+ end
21
+
22
+ def engines_on?
23
+ CanTango.config.engines.any?(:on) && !opts_engines_off?
24
+ end
25
+
26
+ def engines
27
+ CanTango.config.engines
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,21 @@
1
+ module CanTango
2
+ class Ability
3
+ module Helper
4
+ module Role
5
+ include CanTango::Helpers::RoleMethods
6
+
7
+ # return list roles the user has
8
+ def roles
9
+ return [] if !subject.respond_to?(roles_list_meth) || roles_of(subject).blank?
10
+ roles_of(subject).flatten
11
+ end
12
+
13
+ protected
14
+
15
+ def roles_of subject
16
+ @subj_roles ||= subject.send(roles_list_meth)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ module CanTango
2
+ class Ability
3
+ module Helper
4
+ module RoleGroup
5
+ include CanTango::Helpers::RoleMethods
6
+
7
+ # return list of symbols for role groups the user belongs to
8
+ def role_groups
9
+ return [] if !subject.respond_to?(role_groups_list_meth) || role_groups_of(subject).blank?
10
+ role_groups_of(subject).flatten
11
+ end
12
+
13
+ protected
14
+
15
+ def role_groups_of subject
16
+ @subj_role_groups ||= subject.send(role_groups_list_meth)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,18 @@
1
+ module CanTango
2
+ class Ability
3
+ module Helper
4
+ module User
5
+ def user
6
+ return subject.user if subject.respond_to? :user
7
+ subject
8
+ end
9
+
10
+ def user_key_field
11
+ key_field = config.user.unique_key_field
12
+ raise "\nModel <#{user.class}> has no ##{key_field} as defined in CanTango.config.user.unique_key_field" if !user.respond_to?(key_field)
13
+ key_field
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,6 @@
1
+ module CanCan
2
+ class Rule
3
+ attr_accessor :block
4
+ end
5
+ end
6
+
@@ -0,0 +1,84 @@
1
+ require 'cantango/rails/railtie' if defined?(Rails)
2
+ require 'cantango/rails/engine' if defined?(Rails)
3
+
4
+ # essential cantango extensions
5
+ # require 'cantango/config'
6
+ # require 'cantango/api'
7
+
8
+ require 'cancan'
9
+ require 'active_support' # for Delegate module
10
+ require 'active_support/core_ext/module/delegation'
11
+
12
+ require 'cantango/cancan/rule'
13
+ require 'sugar-high/array'
14
+ require 'sugar-high/blank'
15
+ require 'hashie'
16
+ require 'sweetloader'
17
+
18
+ AutoLoader.namespaces = {:CanTango => 'cantango'}
19
+
20
+ module CanTango
21
+ autoload_modules :Ability, :Engine, :Filter
22
+ autoload_modules :Helpers, :Loader, :Macros, :Model
23
+ autoload_modules :Rails, :Rules, :Scope
24
+
25
+ class << self
26
+ def configure &block
27
+ conf = CanTango::Configuration.instance
28
+ yield conf if block
29
+ conf
30
+ end
31
+
32
+ alias_method :config, :configure
33
+
34
+ # Engine hook
35
+ # Run after the initializers are ran for all Railties (including the application itself), but before eager loading and the middleware stack is built.
36
+ # More importantly, will run upon every request in development, but only once (during boot-up) in production and test.
37
+ def to_prepare
38
+ config.hook(:to_prepare).call if config.hook(:to_prepare)
39
+ end
40
+
41
+ # engine hook, run after all Rails initializations have been executed
42
+ def after_initialize
43
+ config.hook(:after_initialize).call if config.hook(:after_initialize)
44
+ end
45
+
46
+ def permits_allowed candidate, actions, subjects, *extra_args
47
+ raise "Debugging has not been turned on. Turn it on using: CanTango.debug!" if CanTango.config.debug.off?
48
+ config.permits.allowed candidate, actions, subjects, *extra_args
49
+ end
50
+
51
+ def permits_denied candidate, actions, subjects, *extra_args
52
+ raise "Debugging has not been turned on. Turn it on using: CanTango.debug!" if CanTango.config.debug.off?
53
+ config.permits.denied candidate, actions, subjects, *extra_args
54
+ end
55
+
56
+ def debug_permits_registry
57
+ puts "permits registry:" << CanTango.config.permits.show_all.inspect
58
+ end
59
+
60
+ def debug_ability candidate, actions, subjects, *extra_args
61
+ puts "Ability: #{actions} on #{subjects}"
62
+ puts "permits allowed:" << permits_allowed(candidate, actions, subjects, *extra_args).inspect
63
+ puts "permits denied:" << permits_denied(candidate, actions, subjects, *extra_args).inspect
64
+ end
65
+
66
+ def clear_permits_executed!
67
+ config.permits.clear_executed!
68
+ end
69
+
70
+ def debug!
71
+ config.debug.set :on
72
+ end
73
+
74
+ def debug_off!
75
+ config.debug.set :off
76
+ end
77
+
78
+ def debug?
79
+ config.debug.on?
80
+ end
81
+ end
82
+ end
83
+
84
+ require 'cantango/macros'
@@ -0,0 +1,39 @@
1
+ module CanTango
2
+ class Engine
3
+ include CanTango::Helpers::Debug
4
+
5
+ attr_reader :ability
6
+
7
+ delegate :session, :user, :subject, :candidate, :cached?, :to => :ability
8
+
9
+ def initialize ability
10
+ @ability = ability
11
+ end
12
+
13
+ def execute!
14
+ raise NotImplementedError
15
+ end
16
+
17
+ def engine_name
18
+ raise NotImplementedError
19
+ end
20
+
21
+ protected
22
+
23
+ def valid_mode?
24
+ valid_cache_mode? || valid_no_cache_mode?
25
+ end
26
+
27
+ def valid_cache_mode?
28
+ modes.include?(:cache) && cached?
29
+ end
30
+
31
+ def valid_no_cache_mode?
32
+ modes.include?(:no_cache) && !cached?
33
+ end
34
+
35
+ def modes
36
+ CanTango.config.engine(engine_name.to_sym).modes
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,5 @@
1
+ module CanTango
2
+ module Filter
3
+ autoload_modules :Base
4
+ end
5
+ end
@@ -0,0 +1,31 @@
1
+ module CanTango
2
+ module Filter
3
+ class Base
4
+ attr_reader :item, :include_list
5
+
6
+ def initialize item, list = nil
7
+ @item = item.to_sym
8
+ @include_list = list || []
9
+ end
10
+
11
+ def valid?
12
+ return false if !in_include_list?
13
+ return false if not_only?
14
+ !excluded?
15
+ end
16
+
17
+ def in_include_list?
18
+ return false if include_list.blank?
19
+ include_list.include? item
20
+ end
21
+
22
+ def not_only?
23
+ false
24
+ end
25
+
26
+ def excluded?
27
+ false
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,5 @@
1
+ module CanTango
2
+ module Helpers
3
+ autoload_modules :Debug
4
+ end
5
+ end
@@ -0,0 +1,10 @@
1
+ module CanTango
2
+ module Helpers
3
+ module Debug
4
+ # you can set another writer on CanTango.config.debug, fx to spec it!
5
+ def debug msg
6
+ CanTango.config.debug.write msg if CanTango.debug?
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,5 @@
1
+ module CanTango
2
+ module Loader
3
+ autoload_modules :Yaml
4
+ end
5
+ end
@@ -0,0 +1,33 @@
1
+ module CanTango
2
+ module Loader
3
+ class Yaml
4
+ attr_accessor :file_name
5
+
6
+ def self.inherited subclass
7
+ subclass.extend ClassMethods
8
+ end
9
+
10
+ def parser
11
+ raise NotImplementedError
12
+ end
13
+
14
+ def yml_content
15
+ YAML.load_file(file_name)
16
+ rescue
17
+ raise "Couldn't load permissions file: #{file_name}. Either disable Permission engine or add this file."
18
+ end
19
+
20
+ module ClassMethods
21
+ protected
22
+
23
+ def config_file name
24
+ File.join(config_path, "#{name}.yml") if rails?
25
+ end
26
+
27
+ def config_path
28
+ CanTango.config.permissions.config_path
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,11 @@
1
+ module CanTango
2
+ module Macros
3
+ autoload_modules :User, :Account
4
+ end
5
+ end
6
+
7
+ class Module
8
+ [:User, :Account].each do |macro|
9
+ self.send :include, "CanTango::Macros::#{macro.to_s.camelize}".constantize
10
+ end
11
+ end
@@ -0,0 +1,14 @@
1
+ module CanTango::Macros
2
+ module Account
3
+ def tango_user_account options = {}
4
+ self.send :include, CanTango::AccountApi
5
+
6
+ if defined? CanTango::Macros::Masquerader
7
+ self.send :include, CanTango::Macros::Masquerader
8
+ masquerader if options[:masquerade]
9
+ end
10
+ end
11
+ alias_method :tango_account, :tango_user_account
12
+ alias_method :cantango_account, :tango_user_account
13
+ end
14
+ end
@@ -0,0 +1,16 @@
1
+ module CanTango::Macros
2
+ module User
3
+ def tango_user options = {}
4
+ self.send :include, CanTango::UserApi
5
+ self.send :include, CanTango::Masquerade::UserApi
6
+ masquerader if options[:masquerade]
7
+ end
8
+ alias_method :cantango_user, :tango_user
9
+
10
+ module Masquerader
11
+ def masquerader
12
+ self.send :include, CanTango::Masquerade::UserApi
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,5 @@
1
+ module CanTango
2
+ module Model
3
+ autoload_modules :Guest
4
+ end
5
+ end
@@ -0,0 +1,25 @@
1
+ require 'active_model'
2
+
3
+ module CanTango
4
+ module Model
5
+ module Guest
6
+ def self.included(base)
7
+ base.extend ::ActiveModel::Naming
8
+ base.send :include, ::ActiveModel::Conversion
9
+ base.send :include, ::ActiveModel::Validations
10
+ end
11
+
12
+ def email
13
+ 'guest@info.com'
14
+ end
15
+
16
+ def has_role? role
17
+ role.to_sym == :guest
18
+ end
19
+
20
+ def persisted?
21
+ false
22
+ end
23
+ end
24
+ end
25
+ end