cantango-core 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. data/Gemfile +7 -1
  2. data/Gemfile.lock +70 -12
  3. data/README.mdown +16 -14
  4. data/VERSION +1 -1
  5. data/cantango-core.gemspec +41 -51
  6. data/lib/cantango/ability/base/callbacks.rb +37 -0
  7. data/lib/cantango/ability/base.rb +21 -8
  8. data/lib/cantango/ability/cache.rb +1 -1
  9. data/lib/cantango/ability/executor/modes.rb +6 -6
  10. data/lib/cantango/ability/executor/no_cache_mode.rb +2 -6
  11. data/lib/cantango/ability/executor.rb +1 -1
  12. data/lib/cantango/ability/helper/account.rb +6 -10
  13. data/lib/cantango/ability/helper/engine.rb +22 -26
  14. data/lib/cantango/ability/helper/user.rb +10 -14
  15. data/lib/cantango/ability/helper.rb +1 -1
  16. data/lib/cantango/ability.rb +7 -2
  17. data/lib/cantango/adaptor/active_record.rb +6 -0
  18. data/lib/cantango/adaptor/data_mapper.rb +5 -0
  19. data/lib/cantango/adaptor/generic.rb +12 -0
  20. data/lib/cantango/adaptor/mongo.rb +13 -0
  21. data/lib/cantango/adaptor/mongo_mapper.rb +5 -0
  22. data/lib/cantango/adaptor/mongoid.rb +5 -0
  23. data/lib/cantango/adaptor/relational.rb +8 -0
  24. data/lib/cantango/{rules/adaptor.rb → adaptor.rb} +4 -4
  25. data/lib/cantango/{rules → cancan}/rule_class.rb +1 -1
  26. data/lib/cantango/cancan.rb +5 -0
  27. data/lib/cantango/core.rb +5 -13
  28. data/lib/cantango/engine.rb +6 -16
  29. data/lib/cantango/filter/base.rb +1 -1
  30. data/lib/cantango/helpers/debug.rb +31 -1
  31. data/lib/cantango/loader/yaml.rb +2 -11
  32. data/lib/cantango/model/guest.rb +3 -1
  33. data/spec/cantango/ability/base_spec.rb +13 -63
  34. data/spec/cantango/ability/cache/simple_key_spec.rb +29 -0
  35. data/spec/cantango/ability/executor/base_spec.rb +12 -52
  36. data/spec/cantango/ability/executor/custom_spec.rb +51 -0
  37. data/spec/cantango/ability/executor/modes_spec.rb +27 -49
  38. data/spec/cantango/ability/executor/no_cache_mode_spec.rb +29 -0
  39. data/spec/cantango/ability/helper/account_spec.rb +37 -0
  40. data/spec/cantango/ability/helper/engine_spec.rb +36 -0
  41. data/spec/cantango/ability/helper/user_spec.rb +38 -0
  42. data/spec/cantango/adaptor/active_record_spec.rb +38 -0
  43. data/spec/cantango/adaptor/data_mapper_spec.rb +39 -0
  44. data/spec/cantango/{rules/adaptor → adaptor}/mongo_mapper_spec.rb +0 -0
  45. data/spec/cantango/{rules/adaptor → adaptor}/mongoid_spec.rb +0 -0
  46. data/spec/cantango/cancan/rule_spec.rb +5 -0
  47. data/spec/cantango/core_spec.rb +0 -2
  48. data/spec/cantango/engine_spec.rb +51 -0
  49. data/spec/cantango/filter/base_spec.rb +25 -0
  50. data/spec/cantango/helpers/debug_spec.rb +29 -0
  51. data/spec/cantango/loader/yaml_spec.rb +5 -0
  52. data/spec/cantango/model/guest_spec.rb +14 -0
  53. data/spec/cantango/rspec/be_allowed_to_spec.rb +5 -0
  54. data/spec/cantango/scope/ability_spec.rb +33 -0
  55. data/spec/fixtures/models/account.rb +7 -0
  56. data/spec/fixtures/models/admin.rb +2 -0
  57. data/spec/fixtures/models/admin_account.rb +8 -0
  58. data/spec/fixtures/models/items.rb +11 -0
  59. data/spec/fixtures/models/user.rb +20 -0
  60. data/spec/fixtures/models.rb +2 -0
  61. data/spec/spec_helper.rb +4 -0
  62. metadata +60 -67
  63. data/lib/cantango/ability/executor/cache_mode.rb +0 -33
  64. data/lib/cantango/ability/helper/role.rb +0 -21
  65. data/lib/cantango/ability/helper/role_group.rb +0 -21
  66. data/lib/cantango/macros/account.rb +0 -14
  67. data/lib/cantango/macros/user.rb +0 -16
  68. data/lib/cantango/macros.rb +0 -11
  69. data/lib/cantango/rules/adaptor/active_record.rb +0 -10
  70. data/lib/cantango/rules/adaptor/data_mapper.rb +0 -11
  71. data/lib/cantango/rules/adaptor/generic.rb +0 -16
  72. data/lib/cantango/rules/adaptor/mongo.rb +0 -19
  73. data/lib/cantango/rules/adaptor/mongo_mapper.rb +0 -10
  74. data/lib/cantango/rules/adaptor/mongoid.rb +0 -9
  75. data/lib/cantango/rules/adaptor/relational.rb +0 -13
  76. data/lib/cantango/rules/dsl.rb +0 -24
  77. data/lib/cantango/rules/relation.rb +0 -67
  78. data/lib/cantango/rules/scope.rb +0 -24
  79. data/lib/cantango/rules.rb +0 -8
  80. data/spec/cantango/ability/cached_spec.rb +0 -0
  81. data/spec/cantango/ability/executor/base2.rb +0 -75
  82. data/spec/cantango/ability/executor/cache_mode_spec.rb +0 -77
  83. data/spec/cantango/macros/account_spec.rb +0 -0
  84. data/spec/cantango/macros/user_spec.rb +0 -0
  85. data/spec/cantango/rules/adaptor/active_record_spec.rb +0 -0
  86. data/spec/cantango/rules/adaptor/data_mapper_spec.rb +0 -0
  87. data/spec/cantango/rules/adaptor_spec.rb +0 -0
  88. data/spec/cantango/rules/dsl_spec.rb +0 -0
  89. data/spec/cantango/rules/relation_spec.rb +0 -0
  90. data/spec/cantango/rules/rule_class_spec.rb +0 -0
  91. data/spec/cantango/rules/scope_spec.rb +0 -0
  92. data/spec/cantango/rules_spec.rb +0 -55
@@ -1,32 +1,28 @@
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
1
+ module CanTango::Ability::Helper
2
+ module Engine
3
+ def execute_engines!
4
+ each_engine do |engine|
5
+ engine_rules = engine.new(self).execute! if engine
6
+ @rules << engine_rules if !engine_rules.blank?
7
+ end
8
+ end
11
9
 
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
10
+ def each_engine &block
11
+ engines.execution_order.each do |name|
12
+ yield engines.registered[name] if engines.active? name
13
+ end
14
+ end
17
15
 
18
- def opts_engines_off?
19
- options[:engines] == :off
20
- end
16
+ def opts_engines_off?
17
+ options[:engines] == :off
18
+ end
21
19
 
22
- def engines_on?
23
- CanTango.config.engines.any?(:on) && !opts_engines_off?
24
- end
20
+ def engines_on?
21
+ CanTango.config.engines.any?(:on) && !opts_engines_off?
22
+ end
25
23
 
26
- def engines
27
- CanTango.config.engines
28
- end
29
- end
24
+ def engines
25
+ CanTango.config.engines
30
26
  end
31
27
  end
32
- end
28
+ end
@@ -1,18 +1,14 @@
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
1
+ module CanTango::Ability::Helper
2
+ module User
3
+ def user
4
+ return subject.user if subject.respond_to? :user
5
+ subject
6
+ end
9
7
 
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
8
+ def user_key_field
9
+ key_field = CanTango.config.user.unique_key_field
10
+ raise "\nModel <#{user.class}> has no ##{key_field} as defined in CanTango.config.user.unique_key_field" if !user.respond_to?(key_field)
11
+ key_field
16
12
  end
17
13
  end
18
14
  end
@@ -2,7 +2,7 @@ module CanTango
2
2
  module Ability
3
3
  module Helper
4
4
  def self.modules
5
- [:Account, :Cache, :Engine, :Masquerade, :Permit, :PermitStore, :Role, :RoleGroup, :User]
5
+ [:Account, :Engine, :User]
6
6
  end
7
7
 
8
8
  autoload_modules *modules
@@ -1,5 +1,10 @@
1
1
  module CanTango
2
- module Ability
3
- autoload_modules :Base, :Cache, :Cached, :Executor, :Helper
2
+ module Ability
3
+ autoload_modules :Base, :Cache, :Executor, :Helper
4
+
5
+ # by default add callbacks?
6
+ class Base
7
+ include Callbacks
8
+ end
4
9
  end
5
10
  end
@@ -0,0 +1,6 @@
1
+ module CanTango::Adaptor
2
+ module ActiveRecord
3
+ include CanTango::Rules::Adaptor::Relational
4
+ end
5
+ end
6
+
@@ -0,0 +1,5 @@
1
+ module CanTango::Adaptor
2
+ module DataMapper
3
+ include CanTango::Rules::Adaptor::Relational
4
+ end
5
+ end
@@ -0,0 +1,12 @@
1
+ module CanTango::Adaptor
2
+ module Generic
3
+
4
+ def attribute_condition attribute, candidate
5
+ Proc.new { |model| model.send(attribute) == candidate }
6
+ end
7
+
8
+ def include_condition attribute, candidate
9
+ Proc.new { |model| model.send(attribute).include? candidate }
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,13 @@
1
+ module CanTango::Adaptor
2
+ module Mongo
3
+ #include CanTango::Rules::Adaptor::Generic
4
+ # using #in on Hash (Mongoid query)
5
+ def include_condition attribute, candidate
6
+ { attribute.to_sym.in => candidate.send(attribute) }
7
+ end
8
+
9
+ def attribute_condition attribute, user_scope
10
+ { attribute.to_sym => candidate.send(attribute) }
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,5 @@
1
+ module CanTango::Adaptor
2
+ module MongoMapper
3
+ include module CanTango::Rules::Adaptor::Mongo
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module CanTango::Adaptor
2
+ module Mongoid
3
+ include module CanTango::Rules::Adaptor::Mongo
4
+ end
5
+ end
@@ -0,0 +1,8 @@
1
+ module CanTango::Adaptor
2
+ module Relational
3
+ def attribute_condition attribute, candidate
4
+ { attribute.to_sym => candidate.send(attribute) }
5
+ end
6
+ alias_method :include_condition, :attribute_condition
7
+ end
8
+ end
@@ -25,10 +25,10 @@ module CanTango
25
25
 
26
26
  def orm_map
27
27
  {
28
- :active_record => "ActiveRecord::Base",
29
- :data_mapper => "DataMapper::Resource",
30
- :mongoid => "Mongoid::Document",
31
- :mongo_mapper => "MongoMapper::Document"
28
+ :active_record => "ActiveRecord::Base",
29
+ :data_mapper => "DataMapper::Resource",
30
+ :mongoid => "Mongoid::Document",
31
+ :mongo_mapper => "MongoMapper::Document"
32
32
  }
33
33
  end
34
34
  end
@@ -1,5 +1,5 @@
1
1
  module CanTango
2
- module Rules
2
+ module CanCan
3
3
  module RuleClass
4
4
  # CanCan 1.5 compatibility
5
5
  def rule_class
@@ -0,0 +1,5 @@
1
+ module CanTango
2
+ module CanCan
3
+ autoload_modules :Rule, :RuleClass
4
+ end
5
+ end
data/lib/cantango/core.rb CHANGED
@@ -1,10 +1,3 @@
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
1
  require 'cancan'
9
2
  require 'active_support' # for Delegate module
10
3
  require 'active_support/core_ext/module/delegation'
@@ -15,12 +8,11 @@ require 'sugar-high/blank'
15
8
  require 'hashie'
16
9
  require 'sweetloader'
17
10
 
18
- AutoLoader.namespaces = {:CanTango => 'cantango'}
11
+ SweetLoader.namespaces = {:CanTango => 'cantango'}
12
+ SweetLoader.mode = :require
19
13
 
20
14
  module CanTango
21
- autoload_modules :Ability, :Engine, :Filter
22
- autoload_modules :Helpers, :Loader, :Macros, :Model
23
- autoload_modules :Rules, :Scope
15
+ autoload_modules :Helpers, :Ability, :Engine, :Filter
16
+ autoload_modules :Loader, :Model
17
+ autoload_modules :Scope
24
18
  end
25
-
26
- require 'cantango/macros'
@@ -2,12 +2,12 @@ module CanTango
2
2
  class Engine
3
3
  include CanTango::Helpers::Debug
4
4
 
5
- attr_reader :ability
5
+ attr_reader :ability, :options
6
6
 
7
7
  delegate :session, :user, :subject, :candidate, :cached?, :to => :ability
8
8
 
9
- def initialize ability
10
- @ability = ability
9
+ def initialize ability, options = {}
10
+ @ability, @options = [ability, options]
11
11
  end
12
12
 
13
13
  def execute!
@@ -18,22 +18,12 @@ module CanTango
18
18
  raise NotImplementedError
19
19
  end
20
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?
21
+ def valid_mode? mode
22
+ modes.include? mode.to_sym
33
23
  end
34
24
 
35
25
  def modes
36
- CanTango.config.engine(engine_name.to_sym).modes
26
+ @modes ||= options[:modes] || []
37
27
  end
38
28
  end
39
29
  end
@@ -5,7 +5,7 @@ module CanTango
5
5
 
6
6
  def initialize item, list = nil
7
7
  @item = item.to_sym
8
- @include_list = list || []
8
+ @include_list = list.map(&:to_sym) || []
9
9
  end
10
10
 
11
11
  def valid?
@@ -1,9 +1,39 @@
1
1
  module CanTango
2
2
  module Helpers
3
3
  module Debug
4
+ attr_writer :do_debug, :debug_writer
5
+
6
+ def self.included base
7
+ base.extend ClassMethods
8
+ end
9
+
10
+ module ClassMethods
11
+ attr_writer :do_debug, :debug_writer
12
+
13
+ def debug?
14
+ @do_debug ||= false
15
+ end
16
+
17
+ def debug_writer
18
+ @debug_writer ||= lambda {|m| puts m }
19
+ end
20
+ end
21
+
4
22
  # you can set another writer on CanTango.config.debug, fx to spec it!
5
23
  def debug msg
6
- CanTango.config.debug.write msg if CanTango.debug?
24
+ if debug?
25
+ return debug_writer.write msg if debug_writer.respond_to? :write
26
+ return debug_writer.call(msg) if debug_writer.respond_to? :call
27
+ raise "No debug_writer set!"
28
+ end
29
+ end
30
+
31
+ def debug?
32
+ @do_debug ||= self.class.debug?
33
+ end
34
+
35
+ def debug_writer
36
+ @debug_writer ||= self.class.debug_writer
7
37
  end
8
38
  end
9
39
  end
@@ -14,19 +14,10 @@ module CanTango
14
14
  def yml_content
15
15
  YAML.load_file(file_name)
16
16
  rescue
17
- raise "Couldn't load permissions file: #{file_name}. Either disable Permission engine or add this file."
17
+ raise "Couldn't YAML file: #{file_name}"
18
18
  end
19
-
19
+
20
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
21
  end
31
22
  end
32
23
  end
@@ -5,12 +5,14 @@ module CanTango
5
5
  module Guest
6
6
  def self.included(base)
7
7
  base.extend ::ActiveModel::Naming
8
+ base.extend ::ActiveModel::Callbacks
9
+
8
10
  base.send :include, ::ActiveModel::Conversion
9
11
  base.send :include, ::ActiveModel::Validations
10
12
  end
11
13
 
12
14
  def email
13
- 'guest@info.com'
15
+ 'guest@example.com'
14
16
  end
15
17
 
16
18
  def has_role? role
@@ -1,73 +1,23 @@
1
- require 'rspec'
2
- require 'cantango'
1
+ require 'spec_helper'
3
2
  require 'fixtures/models'
4
- require 'cantango/rspec'
5
3
 
6
- def config_folder
7
- File.dirname(__FILE__)+ "/../fixtures/config/"
8
- end
9
-
10
- CanTango.configure do |config|
11
- config.clear!
12
- # config.permissions.set :on
13
- config.engines.all :on
14
-
15
- config.permission_engine.config_path = config_folder
16
- config.categories.register :blog_items => [Article, Post]
17
- end
18
-
19
- class PublishersRoleGroupPermit < CanTango::RoleGroupPermit
20
- def initialize ability
21
- super
22
- end
23
-
24
- protected
25
-
26
- def static_rules
27
- can :write, category(:blog_items)
28
- cannot :write, Post
4
+ module CanTango::Ability
5
+ class Base
6
+ include CanTango::Ability::Helper::Account
7
+
8
+ def permit_rules
9
+ can :edit, Project
10
+ end
29
11
  end
30
12
  end
31
13
 
32
- class EditorRolePermit < CanTango::RolePermit
33
- def initialize ability
34
- super
35
- end
36
-
37
- protected
38
-
39
- def static_rules
40
- can :read, Comment
41
- end
42
- end
43
-
44
-
45
- describe CanTango::Ability do
46
- let (:user) do
47
- User.new 'krisy', 'krisy@gmail.com'
48
- end
49
-
50
- let (:user_account) do
51
- ua = UserAccount.new user, :roles => [:editor], :role_groups => [:publishers]
52
- user.account = ua
53
- end
54
-
14
+ describe CanTango::Ability::Base do
55
15
  before do
56
- CanTango.config.clear!
57
- @ability = CanTango::Ability.new user_account
16
+ user = User.new 'krisy', 'krisy@gmail.com'
17
+ @account = Account.new user
58
18
  end
59
19
 
60
- specify { CanTango.config.roles.excluded.should be_empty }
61
- specify { CanTango.config.role_groups.excluded.should be_empty }
62
-
63
- subject { @ability }
64
- specify { @ability.should be_allowed_to(:read, Comment) }
65
- specify { @ability.should be_allowed_to(:write, Article) }
66
- specify { @ability.should_not be_allowed_to(:write, Post) }
67
-
68
- its(:user_account) { should be_a(UserAccount) }
69
- its(:user) { should be_a(User) }
20
+ subject { CanTango::Ability::Base.new @account }
70
21
 
71
- its(:roles) { should_not be_empty }
72
- its(:role_groups) { should_not be_empty }
22
+ specify { subject.should be_allowed_to(:edit, Project) }
73
23
  end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+ require 'fixtures/models'
3
+
4
+ describe CanTango::Ability::Cache::SimpleKey do
5
+ before do
6
+ @user = User.new 'krisy', 'krisy@gmail.com'
7
+ @account = Account.new user
8
+ @ability = CanTango::Ability::Base.new @account
9
+ end
10
+
11
+ context 'SimpleKey for user' do
12
+ subject { CanTango::Ability::Cache::SimpleKey.new @user }
13
+
14
+ specify do
15
+ subject.value.should == @user.email.hash
16
+ end
17
+
18
+ specify do
19
+ subject.to_s.should match /#{@user.email.hash}/
20
+ end
21
+
22
+ context '#Simplekey #create_for Ability' do
23
+ subject { CanTango::Ability::Cache::SimpleKey.create_for @ability }
24
+
25
+ specify do
26
+ subject.value.should == @user.email.hash
27
+ end
28
+ end
29
+ end
@@ -1,67 +1,27 @@
1
- require 'rspec'
2
- require 'cantango'
1
+ require 'spec_helper'
3
2
  require 'fixtures/models'
4
- require 'cantango/rspec'
5
3
 
6
- def config_folder
7
- File.dirname(__FILE__)+ "/../fixtures/config/"
8
- end
9
-
10
- CanTango.configure do |config|
11
- config.clear!
12
- config.ability.mode = :no_cache
13
- end
14
-
15
- class MyExecutor
16
- include CanTango::Ability::Executor
17
-
18
- attr_reader :ability
19
-
20
- def initialize ability
21
- @ability = ability
22
- end
23
-
24
- def valid?
25
- true
26
- end
27
-
28
- def cache_key
29
- :my_exec
30
- end
31
-
32
- def permit_rules
33
- ability.permit_rules
34
- end
35
- end
36
-
37
- module CanTango
38
- class Ability
4
+ module CanTango::Ability
5
+ class Base
39
6
  def permit_rules
40
- can :edit, Project
7
+ can :read, Post
41
8
  end
42
9
  end
43
10
  end
44
11
 
45
- describe CanTango::Ability::Executor do
46
- context 'no-cache' do
47
- let (:ability) do
48
- CanTango::Ability.new @user
49
- end
50
-
12
+ describe CanTango::Ability::Executor::Base do
13
+ context 'non-cached only' do
51
14
  before do
52
- @user = User.new 'kris'
15
+ @user = User.new 'admin', 'admin@mail.ru'
53
16
  end
54
17
 
55
- subject { MyExecutor.new ability }
18
+ subject { CanTango::Ability::Executor::Base.new @user }
56
19
 
57
- describe '#execute!' do
58
- before do
59
- subject.execute!
60
- end
20
+ its(:non_cached_rules) { should_not be_empty }
61
21
 
62
- specify { subject.ability.send(:rules).should_not be_empty }
22
+ describe 'rules contain only non-cached rules' do
23
+ specify { subject.rules.size.should == @abil.non_cached_rules.size }
24
+ specify { subject.rules.size.should == 1 }
63
25
  end
64
26
  end
65
27
  end
66
-
67
-
@@ -0,0 +1,51 @@
1
+ require 'spec_helper'
2
+ require 'fixtures/models'
3
+
4
+ class MyExecutor < CanTango::Ability::Executor::Base
5
+ attr_reader :ability
6
+
7
+ def initialize ability
8
+ super
9
+ end
10
+
11
+ def valid?
12
+ true
13
+ end
14
+
15
+ def cache_key
16
+ :my_exec
17
+ end
18
+
19
+ def permit_rules
20
+ ability.permit_rules
21
+ end
22
+ end
23
+
24
+ module CanTango::Ability
25
+ class Base
26
+ def permit_rules
27
+ can :edit, Project
28
+ end
29
+ end
30
+ end
31
+
32
+ describe CanTango::Ability::Executor::Base do
33
+ context 'Custom executor inheriting from Base' do
34
+ before do
35
+ @user = User.new 'kris'
36
+ @ability = CanTango::Ability::Base.new @user
37
+ end
38
+
39
+ subject { MyExecutor.new @ability }
40
+
41
+ describe '#execute!' do
42
+ before do
43
+ subject.execute!
44
+ end
45
+
46
+ specify { subject.ability.send(:rules).should_not be_empty }
47
+ end
48
+ end
49
+ end
50
+
51
+