cantango 0.9.3.2 → 0.9.4

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 (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