cantango 0.9.3.2 → 0.9.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. data/README.textile +11 -9
  2. data/VERSION +1 -1
  3. data/cantango.gemspec +24 -3
  4. data/lib/cantango/ability/cache/key.rb +6 -2
  5. data/lib/cantango/ability/cache/reader.rb +3 -0
  6. data/lib/cantango/ability/cache/session_cache.rb +7 -3
  7. data/lib/cantango/ability/cache/writer.rb +8 -2
  8. data/lib/cantango/ability/cache.rb +25 -8
  9. data/lib/cantango/ability/cache_helpers.rb +4 -13
  10. data/lib/cantango/ability/cached_executor.rb +0 -0
  11. data/lib/cantango/ability/engine_helpers.rb +4 -1
  12. data/lib/cantango/ability/executor.rb +67 -0
  13. data/lib/cantango/ability/permission_helpers.rb +0 -1
  14. data/lib/cantango/ability.rb +1 -1
  15. data/lib/cantango/cached_ability.rb +3 -2
  16. data/lib/cantango/configuration/engines/cache.rb +0 -3
  17. data/lib/cantango/configuration/engines/engine.rb +5 -0
  18. data/lib/cantango/configuration/engines/permission.rb +5 -4
  19. data/lib/cantango/configuration/engines/permit.rb +0 -5
  20. data/lib/cantango/configuration/engines/user_ac.rb +6 -3
  21. data/lib/cantango/configuration/models/active_record.rb +11 -0
  22. data/lib/cantango/configuration/models/data_mapper.rb +12 -0
  23. data/lib/cantango/configuration/models/generic.rb +12 -0
  24. data/lib/cantango/configuration/models/mongo.rb +12 -0
  25. data/lib/cantango/configuration/models/mongo_mapper.rb +11 -0
  26. data/lib/cantango/configuration/models/mongoid.rb +13 -0
  27. data/lib/cantango/configuration/models.rb +27 -2
  28. data/lib/cantango/configuration/permits.rb +2 -1
  29. data/lib/cantango/configuration.rb +14 -0
  30. data/lib/cantango/engine.rb +5 -19
  31. data/lib/cantango/model/scope.rb +19 -5
  32. data/lib/cantango/permission_engine/collector.rb +3 -0
  33. data/lib/cantango/permission_engine/evaluator.rb +5 -0
  34. data/lib/cantango/permission_engine/factory.rb +3 -0
  35. data/lib/cantango/permission_engine/loader/permissions.rb +7 -8
  36. data/lib/cantango/permission_engine/store.rb +0 -1
  37. data/lib/cantango/permission_engine/yaml_store.rb +15 -4
  38. data/lib/cantango/permission_engine.rb +21 -4
  39. data/lib/cantango/permit_engine/factory.rb +10 -4
  40. data/lib/cantango/permit_engine.rb +39 -9
  41. data/lib/cantango/permits/account_permit/builder.rb +6 -2
  42. data/lib/cantango/{user_ac_engine → permits}/executor.rb +28 -30
  43. data/lib/cantango/permits/permit/class_methods.rb +21 -0
  44. data/lib/cantango/permits/permit/execute.rb +81 -0
  45. data/lib/cantango/permits/permit/license.rb +26 -0
  46. data/lib/cantango/permits/permit.rb +19 -138
  47. data/lib/cantango/permits/role_group_permit/builder.rb +5 -1
  48. data/lib/cantango/permits/role_group_permit.rb +3 -3
  49. data/lib/cantango/permits/role_permit/builder.rb +4 -0
  50. data/lib/cantango/permits/user_permit/builder.rb +5 -1
  51. data/lib/cantango/permits/user_permit.rb +1 -1
  52. data/lib/cantango/permits.rb +1 -0
  53. data/lib/cantango/rails/engine.rb +0 -3
  54. data/lib/cantango/rails/helpers/base_helper.rb +1 -1
  55. data/lib/cantango/rails/helpers/rest_helper.rb +1 -1
  56. data/lib/cantango/rules/adaptor/active_record.rb +1 -4
  57. data/lib/cantango/rules/adaptor/data_mapper.rb +11 -0
  58. data/lib/cantango/rules/adaptor/mongo.rb +19 -0
  59. data/lib/cantango/rules/adaptor/mongo_mapper.rb +10 -0
  60. data/lib/cantango/rules/adaptor/mongoid.rb +1 -5
  61. data/lib/cantango/rules/adaptor/relational.rb +13 -0
  62. data/lib/cantango/rules/adaptor.rb +12 -7
  63. data/lib/cantango/rules/user_relation.rb +1 -2
  64. data/lib/cantango/user_ac_engine.rb +25 -7
  65. data/lib/cantango.rb +2 -0
  66. data/spec/cantango/ability/executor_spec.rb +67 -0
  67. data/spec/cantango/ability_executor/cached_only_spec.rb +1 -0
  68. data/spec/cantango/model/scope_spec.rb +11 -0
  69. data/spec/cantango/models/items.rb +5 -0
  70. data/spec/cantango/permission_engine_cached_spec.rb +51 -0
  71. data/spec/cantango/permission_engine_spec.rb +55 -0
  72. data/spec/cantango/permit_engine_cached_spec.rb +56 -0
  73. data/spec/cantango/permit_engine_spec.rb +57 -1
  74. data/spec/cantango/permits/executor_cached_spec.rb +0 -0
  75. data/spec/cantango/permits/executor_spec.rb +68 -0
  76. data/spec/cantango/user_ac_engine_cached_spec.rb +64 -0
  77. data/spec/cantango/user_ac_engine_spec.rb +14 -2
  78. data/spec/fixtures/models/items.rb +3 -0
  79. data/spec/fixtures/models/user.rb +18 -0
  80. metadata +55 -34
@@ -0,0 +1,67 @@
1
+ require 'rspec'
2
+ require 'cantango'
3
+ require 'fixtures/models'
4
+ require 'cantango/rspec'
5
+
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
39
+ def permit_rules
40
+ can :edit, Project
41
+ end
42
+ end
43
+ end
44
+
45
+ describe CanTango::Ability::Executor do
46
+ context 'no-cache' do
47
+ let (:ability) do
48
+ CanTango::Ability.new @user
49
+ end
50
+
51
+ before do
52
+ @user = User.new 'kris'
53
+ end
54
+
55
+ subject { MyExecutor.new ability }
56
+
57
+ describe '#execute!' do
58
+ before do
59
+ subject.execute!
60
+ end
61
+
62
+ specify { subject.ability.send(:rules).should_not be_empty }
63
+ end
64
+ end
65
+ end
66
+
67
+
@@ -10,6 +10,7 @@ end
10
10
 
11
11
  CanTango.configure do |config|
12
12
  config.clear!
13
+ config.ability.mode = :cache
13
14
  end
14
15
  # CanTango.debug!
15
16
 
@@ -2,6 +2,7 @@ require 'rspec'
2
2
  require 'cantango'
3
3
  # require 'active_record/spec_helper'
4
4
 
5
+ require 'cutter'
5
6
  require 'simple_roles'
6
7
  require 'fixtures/models'
7
8
  require 'cantango/api/current_users'
@@ -31,6 +32,7 @@ end
31
32
  CanTango.configure do |config|
32
33
  config.cache_engine.set :off
33
34
  config.permit_engine.set :on
35
+ config.ability.mode = :no_cache
34
36
  end
35
37
 
36
38
  class Context
@@ -87,6 +89,11 @@ describe CanTango::Model::Scope do
87
89
  specify { subject.send(:"#{meth_name}_by", context.current_user).should be_empty }
88
90
  end
89
91
 
92
+ (CanTango::Model::Scope.rest_actions - [:edit, :create]).each do |action|
93
+ meth_name = action.to_s.sub(/e$/, '') << "able"
94
+ specify { subject.send(:"not_#{meth_name}_by", context.current_user).should_not be_empty }
95
+ end
96
+
90
97
  [:edit, :create].each do |action|
91
98
  meth_name = action.to_s.sub(/e$/, '') << "able"
92
99
  specify { subject.send(:"#{meth_name}_by", context.current_user).should_not be_empty }
@@ -101,6 +108,10 @@ describe CanTango::Model::Scope do
101
108
 
102
109
  specify { subject.allowed_to(:delete, :manage).by_user(context.current_user).should be_empty }
103
110
  end
111
+
112
+ describe '#not_allowed_to' do
113
+ specify { subject.not_allowed_to(:create).by_user(context.current_user).should be_empty }
114
+ end
104
115
  end
105
116
  end
106
117
 
@@ -1,4 +1,5 @@
1
1
  require 'active_record'
2
+
2
3
  class Comment < ActiveRecord::Base
3
4
  belongs_to :user
4
5
  end
@@ -10,3 +11,7 @@ end
10
11
  class Article < ActiveRecord::Base
11
12
  belongs_to :user
12
13
  end
14
+
15
+ class Project < ActiveRecord::Base
16
+ belongs_to :user
17
+ end
@@ -0,0 +1,51 @@
1
+ require 'rspec'
2
+ require 'cantango'
3
+ require 'fixtures/models'
4
+ require 'cantango/rspec'
5
+
6
+ def config_folder
7
+ File.dirname(__FILE__)+ "/../fixtures/config/"
8
+ end
9
+
10
+ CanTango.configure do |config|
11
+ config.clear!
12
+ config.engines.all :off
13
+ config.engine(:permission).set :on
14
+ config.ability.mode = :cache
15
+ config.engine(:permission) do |engine|
16
+ engine.mode = :cache
17
+ engine.config_path(config_folder)
18
+ end
19
+ config.debug!
20
+ end
21
+
22
+ describe CanTango::PermissionEngine do
23
+ context 'cache' do
24
+ let (:ability) do
25
+ CanTango::CachedAbility.new @user
26
+ end
27
+
28
+ before do
29
+ @user = User.new 'kris'
30
+ end
31
+
32
+ subject { CanTango::PermissionEngine.new ability }
33
+
34
+ describe '#execute!' do
35
+ before do
36
+ subject.execute!
37
+ end
38
+
39
+ it 'engine should have rules' do
40
+ subject.rules.should_not be_empty
41
+ end
42
+
43
+ it 'engine cache should be empty' do
44
+ subject.cache.empty?.should_not be_true
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+
51
+
@@ -0,0 +1,55 @@
1
+ require 'rspec'
2
+ require 'cantango'
3
+ require 'fixtures/models'
4
+ require 'cantango/rspec'
5
+
6
+ def config_folder
7
+ File.dirname(__FILE__)+ "/../fixtures/config/"
8
+ end
9
+
10
+ CanTango.configure do |config|
11
+ config.clear!
12
+
13
+ config.engines.all :off
14
+ config.engine(:permission).set :on
15
+
16
+ config.ability.mode = :no_cache
17
+ config.engine(:permission) do |engine|
18
+ engine.mode = :no_cache
19
+ engine.config_path(config_folder)
20
+ end
21
+ config.debug!
22
+ end
23
+
24
+ describe CanTango::PermissionEngine do
25
+ context 'no-cache' do
26
+ let (:ability) do
27
+ CanTango::Ability.new @user
28
+ end
29
+
30
+ before do
31
+ @user = User.new 'kris'
32
+ end
33
+
34
+ subject { CanTango::PermissionEngine.new ability }
35
+
36
+ specify { CanTango.config.ability.modes.should include(:no_cache) }
37
+ specify { subject.cached?.should be_false }
38
+
39
+ describe '#execute!' do
40
+ before do
41
+ subject.execute!
42
+ end
43
+
44
+ it 'ability should have rules' do
45
+ subject.send(:rules).should_not be_empty
46
+ end
47
+
48
+ it 'cache should be empty' do
49
+ subject.cache.empty?.should be_true
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+
@@ -0,0 +1,56 @@
1
+ require 'rspec'
2
+ require 'cantango'
3
+ require 'fixtures/models'
4
+ require 'cantango/rspec'
5
+
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 = :cache
13
+ config.engine(:permit) do |engine|
14
+ engine.mode = :cache
15
+ end
16
+ config.debug!
17
+ end
18
+
19
+ class UserPermit < CanTango::UserPermit
20
+ def initialize ability
21
+ super
22
+ end
23
+
24
+ protected
25
+
26
+ def static_rules
27
+ can :read, Article
28
+ end
29
+ end
30
+
31
+ describe CanTango::PermitEngine do
32
+ context 'cache' do
33
+ before do
34
+ @user = User.new 'kris'
35
+ end
36
+
37
+ let (:ability) do
38
+ CanTango::CachedAbility.new @user
39
+ end
40
+ subject { CanTango::PermitEngine.new ability }
41
+
42
+ describe '#execute!' do
43
+ before do
44
+ subject.execute!
45
+ end
46
+
47
+ it 'engine should have rules' do
48
+ subject.send(:rules).should_not be_empty
49
+ end
50
+
51
+ it 'engine cache should have rules' do
52
+ subject.cache.empty?.should be_false
53
+ end
54
+ end
55
+ end
56
+ end
@@ -1,2 +1,58 @@
1
- # its(:permit_class_names) { should include("UserRolePermit", "AdminsRoleGroupPermit") }
1
+ require 'rspec'
2
+ require 'cantango'
3
+ require 'fixtures/models'
4
+ require 'cantango/rspec'
2
5
 
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
+ config.engine(:permit) do |engine|
14
+ engine.mode = :no_cache
15
+ end
16
+ config.debug!
17
+ end
18
+
19
+ class UserPermit < CanTango::UserPermit
20
+ def initialize ability
21
+ super
22
+ end
23
+
24
+ protected
25
+
26
+ def static_rules
27
+ can :read, Article
28
+ end
29
+ end
30
+
31
+ describe CanTango::PermitEngine do
32
+ context 'no-cache' do
33
+ before do
34
+ @user = User.new 'kris'
35
+ end
36
+
37
+ describe 'Permit engine' do
38
+ let (:ability) do
39
+ CanTango::Ability.new @user
40
+ end
41
+ subject { CanTango::PermitEngine.new ability }
42
+
43
+ describe '#execute!' do
44
+ before do
45
+ subject.execute!
46
+ end
47
+
48
+ it 'engine should have rules' do
49
+ subject.send(:rules).should_not be_empty
50
+ end
51
+
52
+ it 'engine cache should be empty' do
53
+ subject.cache.empty?.should be_true
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
File without changes
@@ -0,0 +1,68 @@
1
+ require 'rspec'
2
+ require 'cantango'
3
+ # require 'simple_roles'
4
+ require 'fixtures/models'
5
+ require 'cantango/rspec'
6
+
7
+ def config_folder
8
+ File.dirname(__FILE__)+ "/../fixtures/config/"
9
+ end
10
+
11
+ CanTango.configure do |config|
12
+ config.clear!
13
+ config.permits.enabled_types = [:role]
14
+ end
15
+ CanTango.debug!
16
+
17
+ class User
18
+ tango_user
19
+ include_and_extend SimpleRoles
20
+ end
21
+
22
+ class AdminRolePermit < CanTango::RolePermit
23
+ def initialize ability
24
+ super
25
+ end
26
+
27
+ protected
28
+
29
+ def static_rules
30
+ can :read, Article
31
+ end
32
+
33
+ module Cached
34
+ def permit_rules
35
+ can :edit, Article
36
+ can :delete, Article
37
+ end
38
+ end
39
+ end
40
+
41
+ describe CanTango::Permits::Executor do
42
+ context 'non-cached only' do
43
+ before do
44
+ CanTango.configure.ability.mode = :no_cache
45
+
46
+ @user = User.new 'admin', 'admin@mail.ru', :role => 'admin'
47
+ @abil = CanTango::AbilityExecutor.new @user
48
+ end
49
+
50
+ subject { CanTango::AbilityExecutor.new @user }
51
+
52
+ describe 'config no_cache' do
53
+ specify { CanTango.configure.ability.modes.should == [:no_cache] }
54
+ end
55
+
56
+ describe 'engines_on?' do
57
+ specify { subject.engines_on?.should be_true }
58
+ end
59
+
60
+ its(:cached_rules) { should be_empty }
61
+ its(:non_cached_rules) { should_not be_empty }
62
+
63
+ describe 'rules contain only non-cached rules' do
64
+ specify { subject.rules.size.should == @abil.non_cached_rules.size }
65
+ specify { subject.rules.size.should == 2 }
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,64 @@
1
+ require 'rspec'
2
+ require 'cantango'
3
+ require 'fixtures/models'
4
+ require 'cantango/rspec'
5
+
6
+ def config_folder
7
+ File.dirname(__FILE__)+ "/../fixtures/config/"
8
+ end
9
+
10
+ CanTango.configure do |config|
11
+ config.clear!
12
+ config.engines.all :off
13
+ config.engine(:user_ac).set :on
14
+ config.ability.mode = :cache
15
+ config.engine(:user_ac) do |engine|
16
+ engine.mode = :cache
17
+ end
18
+ config.debug!
19
+ end
20
+
21
+ class Thingy
22
+ attr_reader :name, :id
23
+
24
+ def initialize name
25
+ @name = name
26
+ @id = rand(1000)
27
+ end
28
+ end
29
+
30
+ describe CanTango::UserAcEngine do
31
+ context 'mode :cache' do
32
+ before do
33
+ @thingy = Thingy.new 'a'
34
+ @user = User.new 'kris'
35
+ @permission = Permission.new @user, :edit, @thingy
36
+ @user.permissions << @permission
37
+ end
38
+
39
+ describe 'Permission' do
40
+ subject { @permission }
41
+ its(:thing_id) { should be_a(Integer) }
42
+ end
43
+
44
+ let (:ability) do
45
+ CanTango::CachedAbility.new @user
46
+ end
47
+ subject { CanTango::UserAcEngine.new ability }
48
+
49
+ describe '#execute!' do
50
+ before do
51
+ subject.execute!
52
+ end
53
+
54
+ it 'engine should have rules' do
55
+ subject.send(:rules).should_not be_empty
56
+ end
57
+
58
+ it 'engine cache should have rules' do
59
+ subject.cache.empty?.should be_false
60
+ end
61
+ end
62
+ end
63
+ end
64
+
@@ -9,6 +9,13 @@ end
9
9
 
10
10
  CanTango.configure do |config|
11
11
  config.clear!
12
+ config.engines.all :off
13
+ config.engine(:user_ac).set :on
14
+ config.ability.mode = :no_cache
15
+ config.engine(:user_ac) do |engine|
16
+ engine.mode = :no_cache
17
+ end
18
+ config.debug!
12
19
  end
13
20
 
14
21
  class Thingy
@@ -20,7 +27,6 @@ class Thingy
20
27
  end
21
28
  end
22
29
 
23
-
24
30
  describe CanTango::UserAcEngine do
25
31
  context 'User model has_many Permissions' do
26
32
  before do
@@ -46,7 +52,13 @@ describe CanTango::UserAcEngine do
46
52
  subject.execute!
47
53
  end
48
54
 
49
- specify { subject.ability.send(:rules).should_not be_empty }
55
+ it 'engine should have rules' do
56
+ subject.send(:rules).should_not be_empty
57
+ end
58
+
59
+ it 'engine cache should be empty' do
60
+ subject.cache.empty?.should be_true
61
+ end
50
62
  end
51
63
  end
52
64
  end
@@ -6,3 +6,6 @@ end
6
6
 
7
7
  class Comment
8
8
  end
9
+
10
+ class Project
11
+ end
@@ -28,7 +28,25 @@ class User
28
28
  @role || ''
29
29
  end
30
30
 
31
+ # This hash should be recalculated anytime the permissions collection changes
32
+ #
33
+
34
+ # after_update :recalculate_permissions_hash
35
+
36
+ def permissions_hash
37
+ @permissions_hash = permissions.hash
38
+ end
39
+
31
40
  def permissions
32
41
  @permissions ||= []
33
42
  end
43
+
44
+ # allows implementation specific to ORM, fx using #all on some datastores such as Mongoid etc.
45
+ alias_method :all_permissions, :permissions
46
+
47
+ protected
48
+
49
+ def recalculate_permissions_hash
50
+ @permissions_hash = nil if self.permissions_changed?
51
+ end
34
52
  end