cantango 0.8.9.5 → 0.9.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. data/README.textile +35 -7
  2. data/VERSION +1 -1
  3. data/cantango.gemspec +39 -12
  4. data/lib/cantango.rb +4 -3
  5. data/lib/cantango/ability.rb +17 -21
  6. data/lib/cantango/ability/cache/key.rb +32 -4
  7. data/lib/cantango/ability/cache/rules_cache.rb +9 -2
  8. data/lib/cantango/ability/cache_helpers.rb +1 -7
  9. data/lib/cantango/ability/engine_helpers.rb +27 -0
  10. data/lib/cantango/ability_executor.rb +41 -0
  11. data/lib/cantango/api/user/ability.rb +8 -12
  12. data/lib/cantango/api/user/session.rb +2 -1
  13. data/lib/cantango/api/user_account.rb +2 -2
  14. data/lib/cantango/api/user_account/ability.rb +19 -14
  15. data/lib/cantango/api/user_account/can.rb +8 -0
  16. data/lib/cantango/api/user_account/session.rb +33 -0
  17. data/lib/cantango/cached_ability.rb +26 -0
  18. data/lib/cantango/configuration.rb +3 -3
  19. data/lib/cantango/configuration/ability.rb +1 -0
  20. data/lib/cantango/configuration/candidate_registry.rb +51 -0
  21. data/lib/cantango/configuration/categories.rb +2 -2
  22. data/lib/cantango/configuration/engines.rb +7 -3
  23. data/lib/cantango/configuration/engines/permission.rb +5 -0
  24. data/lib/cantango/configuration/engines/permit.rb +1 -0
  25. data/lib/cantango/configuration/engines/user_ac.rb +19 -0
  26. data/lib/cantango/configuration/guest.rb +1 -1
  27. data/lib/cantango/configuration/modes.rb +21 -0
  28. data/lib/cantango/configuration/permits.rb +1 -1
  29. data/lib/cantango/configuration/role_groups.rb +1 -2
  30. data/lib/cantango/configuration/user_accounts.rb +1 -1
  31. data/lib/cantango/configuration/users.rb +1 -1
  32. data/lib/cantango/engine.rb +40 -0
  33. data/lib/cantango/helpers.rb +1 -1
  34. data/lib/cantango/helpers/debug.rb +9 -0
  35. data/lib/cantango/model.rb +6 -0
  36. data/lib/cantango/model/filter.rb +102 -0
  37. data/lib/cantango/model/scope.rb +57 -0
  38. data/lib/cantango/permission_engine.rb +14 -3
  39. data/lib/cantango/permission_engine/loader/base.rb +1 -6
  40. data/lib/cantango/permission_engine/loader/permissions.rb +10 -16
  41. data/lib/cantango/permission_engine/store.rb +1 -7
  42. data/lib/cantango/permission_engine/yaml_store.rb +3 -10
  43. data/lib/cantango/permit_engine.rb +17 -4
  44. data/lib/cantango/permit_engine/builder/base.rb +3 -1
  45. data/lib/cantango/permit_engine/executor/abstract.rb +2 -0
  46. data/lib/cantango/permit_engine/executor/base.rb +1 -1
  47. data/lib/cantango/permit_engine/factory.rb +5 -3
  48. data/lib/cantango/permit_engine/finder.rb +4 -6
  49. data/lib/cantango/permit_engine/util.rb +1 -1
  50. data/lib/cantango/permits/permit.rb +25 -0
  51. data/lib/cantango/permits/role_group_permit/builder.rb +23 -7
  52. data/lib/cantango/permits/role_permit.rb +1 -2
  53. data/lib/cantango/rails/helpers/rest_helper.rb +3 -2
  54. data/lib/cantango/user_ac_engine.rb +40 -0
  55. data/lib/cantango/user_ac_engine/executor.rb +59 -0
  56. data/lib/cantango/users/macros.rb +3 -0
  57. data/lib/cantango/users/user.rb +1 -1
  58. data/lib/cantango/users/user_account.rb +1 -1
  59. data/lib/generators/cantango/permission/permission_generator.rb +43 -0
  60. data/spec/active_record/migrations/008_create_permissions.rb +10 -0
  61. data/spec/cantango/ability_executor/cached_only_spec.rb +76 -0
  62. data/spec/cantango/ability_executor_spec.rb +75 -0
  63. data/spec/cantango/api/attributes_spec.rb +2 -1
  64. data/spec/cantango/api/current_user_accounts.rb +5 -1
  65. data/spec/cantango/api/user/ability_api_spec.rb +17 -4
  66. data/spec/cantango/api/user/can_api_spec.rb +9 -5
  67. data/spec/cantango/api/user/scope_api_spec.rb +15 -7
  68. data/spec/cantango/api/user_account/ability_api_spec.rb +12 -5
  69. data/spec/cantango/api/user_account/can_api_spec.rb +8 -4
  70. data/spec/cantango/cached_ability_spec.rb +0 -0
  71. data/spec/cantango/model/filter_spec.rb +168 -0
  72. data/spec/cantango/model/scope_spec.rb +107 -0
  73. data/spec/cantango/permission_engine/loader/permissions/{cantango_permissions_loader.rb → cantango_permissions_loader_spec.rb} +0 -0
  74. data/spec/cantango/permission_engine/loader/permissions/shared.rb +2 -2
  75. data/spec/cantango/permission_engine/yaml_store_spec.rb +0 -1
  76. data/spec/cantango/permit_engine/role_group_permit_spec.rb +2 -2
  77. data/spec/cantango/permits/permit_spec.rb +2 -2
  78. data/spec/cantango/rules_spec.rb +6 -6
  79. data/spec/cantango/user_ac_engine_spec.rb +53 -0
  80. data/spec/fixtures/config/cantango_permissions.yml +49 -0
  81. data/spec/fixtures/models/permission.rb +12 -0
  82. data/spec/fixtures/models/user.rb +8 -0
  83. data/spec/generators/cantango/permission_generator_spec.rb +44 -0
  84. metadata +59 -35
@@ -0,0 +1,10 @@
1
+ class CreatePermissions < ActiveRecord::Migration
2
+ def change
3
+ create_table :permissions do |t|
4
+ t.integer :user_id, :thing_id
5
+ t.string :thing_type, :action
6
+ t.timestamps
7
+ end
8
+ end
9
+ end
10
+
@@ -0,0 +1,76 @@
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
+ end
14
+ # CanTango.debug!
15
+
16
+ class User
17
+ tango_user
18
+ include_and_extend SimpleRoles
19
+ end
20
+
21
+ class AdminRolePermit < CanTango::RolePermit
22
+ def initialize ability
23
+ super
24
+ end
25
+
26
+ protected
27
+
28
+ def static_rules
29
+ can :read, Article
30
+ end
31
+
32
+ module Cached
33
+ def permit_rules
34
+ can :edit, Article
35
+ can :delete, Article
36
+ end
37
+ end
38
+ end
39
+
40
+ module CanTango
41
+ class CachedAbility
42
+ def permit_rules
43
+ can :read, Post
44
+ end
45
+ end
46
+ end
47
+
48
+ describe CanTango::AbilityExecutor do
49
+ context 'cached only' do
50
+ before do
51
+ CanTango.configure.ability.mode = :cache
52
+
53
+ @user = User.new 'admin', 'admin@mail.ru', :role => 'admin'
54
+ @abil = CanTango::AbilityExecutor.new @user
55
+ end
56
+
57
+ subject { CanTango::AbilityExecutor.new @user }
58
+
59
+ describe 'config cache' do
60
+ specify { CanTango.configure.ability.modes.should == [:cache] }
61
+ end
62
+
63
+ describe 'engines_on?' do
64
+ specify { subject.engines_on?.should be_true }
65
+ end
66
+
67
+ its(:cached_rules) { should_not be_empty }
68
+ its(:non_cached_rules) { should be_empty }
69
+
70
+ describe 'rules contain only non-cached rules' do
71
+ specify { subject.rules.size.should == @abil.cached_rules.size }
72
+ specify { subject.rules.size.should == 4 }
73
+ end
74
+ end
75
+ end
76
+
@@ -0,0 +1,75 @@
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
+ end
14
+ # CanTango.debug!
15
+
16
+ class User
17
+ tango_user
18
+ include_and_extend SimpleRoles
19
+ end
20
+
21
+ class AdminRolePermit < CanTango::RolePermit
22
+ def initialize ability
23
+ super
24
+ end
25
+
26
+ protected
27
+
28
+ def static_rules
29
+ can :read, Article
30
+ end
31
+
32
+ module Cached
33
+ def permit_rules
34
+ can :edit, Article
35
+ can :delete, Article
36
+ end
37
+ end
38
+ end
39
+
40
+ module CanTango
41
+ class Ability
42
+ def permit_rules
43
+ can :read, Post
44
+ end
45
+ end
46
+ end
47
+
48
+ describe CanTango::AbilityExecutor do
49
+ context 'non-cached only' do
50
+ before do
51
+ CanTango.configure.ability.mode = :no_cache
52
+
53
+ @user = User.new 'admin', 'admin@mail.ru', :role => 'admin'
54
+ @abil = CanTango::AbilityExecutor.new @user
55
+ end
56
+
57
+ subject { CanTango::AbilityExecutor.new @user }
58
+
59
+ describe 'config no_cache' do
60
+ specify { CanTango.configure.ability.modes.should == [:no_cache] }
61
+ end
62
+
63
+ describe 'engines_on?' do
64
+ specify { subject.engines_on?.should be_true }
65
+ end
66
+
67
+ its(:cached_rules) { should be_empty }
68
+ its(:non_cached_rules) { should_not be_empty }
69
+
70
+ describe 'rules contain only non-cached rules' do
71
+ specify { subject.rules.size.should == @abil.non_cached_rules.size }
72
+ specify { subject.rules.size.should == 2 }
73
+ end
74
+ end
75
+ end
@@ -4,7 +4,8 @@ require 'fixtures/models'
4
4
  require 'cantango/api/current_users'
5
5
  require 'cantango/configuration/engines/store_engine_shared'
6
6
 
7
- CanTango.config.users.register :user, :admin
7
+ CanTango.config.users.register :user, User
8
+ CanTango.config.users.register :admin, Admin
8
9
 
9
10
  class Context
10
11
  include CanTango::Api::User::Ability
@@ -1,7 +1,11 @@
1
1
  require 'cantango/api/current_users'
2
2
 
3
3
  module CurrentUserAccounts
4
- include CurrentUsers
4
+ include ::CurrentUsers
5
+
6
+ def self.included(base)
7
+ base.extend ::CurrentUsers
8
+ end
5
9
 
6
10
  def current_user_account
7
11
  ::UserAccount.new(current_user, :roles => [:user])
@@ -1,16 +1,29 @@
1
1
  require 'rspec'
2
2
  require 'cantango'
3
+ require 'simple_roles'
3
4
  require 'fixtures/models'
4
5
  require 'cantango/api/current_users'
5
- require 'cantango/configuration/engines/store_engine_shared'
6
+ # require 'cantango/configuration/engines/store_engine_shared'
6
7
 
7
- CanTango.config.users.register :user, :admin
8
+ class User
9
+ include_and_extend SimpleRoles
10
+ end
11
+
12
+ class Admin < User
13
+ end
14
+
15
+ CanTango.configure do |config|
16
+ config.users.register :user, User
17
+ config.users.register :admin, Admin
18
+
19
+ config.cache_engine.set :off
20
+ config.permit_engine.set :on
21
+ end
8
22
 
9
23
  class Context
10
24
  include CanTango::Api::User::Ability
11
25
 
12
- include CurrentUsers
13
- extend ::CurrentUsers
26
+ include_and_extend ::CurrentUsers
14
27
  end
15
28
 
16
29
  describe CanTango::Api::User::Ability do
@@ -7,16 +7,21 @@ require 'cantango/api/current_users'
7
7
 
8
8
  class User
9
9
  include CanTango::Users::Masquerade
10
-
11
10
  include_and_extend SimpleRoles
12
11
  end
13
12
 
13
+ class Admin < User
14
+ end
15
+
14
16
  CanTango.configure do |config|
15
- config.users.register :user, :admin
17
+ config.users.register :user, User
18
+ config.users.register :admin, Admin
19
+
16
20
  config.cache_engine.set :off
17
21
  config.permit_engine.set :on
18
22
  end
19
23
 
24
+ # puts "#{CanTango.config.users.registered_classes} : #{CanTango.config.users.registered}"
20
25
 
21
26
  class UserRolePermit < CanTango::RolePermit
22
27
  def initialize ability
@@ -43,8 +48,7 @@ end
43
48
  class Context
44
49
  include CanTango::Api::User::Can
45
50
 
46
- include ::CurrentUsers
47
- extend ::CurrentUsers
51
+ include_and_extend ::CurrentUsers
48
52
  end
49
53
 
50
54
  describe CanTango::Api::User::Can do
@@ -94,7 +98,7 @@ describe CanTango::Api::User::Can do
94
98
 
95
99
  describe 'admin masquerades as user' do
96
100
  before do
97
- Context.current_admin.masquerade_as Context.current_user
101
+ Context.new.current_admin.masquerade_as Context.new.current_user
98
102
  end
99
103
 
100
104
  # admin masquerading as user can do same as user
@@ -1,22 +1,30 @@
1
1
  require 'rspec'
2
2
  require 'cantango'
3
+ require 'simple_roles'
3
4
  require 'fixtures/models'
4
5
  require 'cantango/api/current_users'
6
+ # require 'cantango/configuration/engines/store_engine_shared'
5
7
 
6
- require 'cantango/configuration/engines/store_engine_shared'
8
+ CanTango.configure do |config|
9
+ config.users.register :user, User
10
+ config.users.register :admin, Admin
7
11
 
8
- CanTango.config.users.register :user, :admin
12
+ config.cache_engine.set :off
13
+ config.permit_engine.set :on
14
+ end
15
+
16
+ # puts "#{CanTango.config.users.registered_classes} : #{CanTango.config.users.registered}"
9
17
 
10
18
  class User
11
19
  include CanTango::Users::Masquerade
20
+ include_and_extend ::SimpleRoles
12
21
  end
13
22
 
14
23
  class Context
15
24
  include CanTango::Api::User::Ability
16
25
  include CanTango::Api::User::Scope
17
26
 
18
- include ::CurrentUsers
19
- extend ::CurrentUsers
27
+ include_and_extend ::CurrentUsers
20
28
  end
21
29
 
22
30
  describe CanTango::Api::User::Scope do
@@ -24,7 +32,7 @@ describe CanTango::Api::User::Scope do
24
32
 
25
33
  describe 'scope_user' do
26
34
  before do
27
- Context.current_admin.masquerade_as Context.current_user
35
+ subject.current_admin.masquerade_as subject.current_user
28
36
  end
29
37
 
30
38
  specify do
@@ -43,8 +51,8 @@ describe CanTango::Api::User::Scope do
43
51
 
44
52
  describe 'real_user' do
45
53
  before do
46
- Context.current_user.masquerade_as Context.current_admin
47
- end
54
+ subject.current_user.masquerade_as subject.current_admin
55
+ end
48
56
 
49
57
  specify do
50
58
  subject.real_user(:user) do |user|
@@ -2,16 +2,23 @@ require 'rspec'
2
2
  require 'cantango'
3
3
  require 'fixtures/models'
4
4
  require 'cantango/api/current_user_accounts'
5
- require 'cantango/configuration/engines/store_engine_shared'
5
+ # require 'cantango/configuration/engines/store_engine_shared'
6
6
 
7
- CanTango.config.users.register :user, :admin
8
- CanTango.config.user_accounts.register :user, :admin
7
+ CanTango.configure do |config|
8
+ config.users.register :user, User
9
+ config.users.register :admin, Admin
10
+
11
+ config.user_accounts.register :user, UserAccount
12
+ config.user_accounts.register :admin, AdminAccount
13
+
14
+ config.cache_engine.set :off
15
+ config.permit_engine.set :on
16
+ end
9
17
 
10
18
  class Context
11
19
  include CanTango::Api::UserAccount::Ability
12
20
 
13
- include CurrentUserAccounts
14
- extend CurrentUserAccounts
21
+ include_and_extend ::CurrentUserAccounts
15
22
  end
16
23
 
17
24
  describe CanTango::Api::UserAccount::Ability do
@@ -7,9 +7,14 @@ require 'cantango/api/current_user_accounts'
7
7
  class User
8
8
  include_and_extend SimpleRoles
9
9
  end
10
+
10
11
  CanTango.configure do |config|
11
- config.users.register :user, :admin
12
- config.user_accounts.register :user, :admin
12
+ config.users.register :user, User
13
+ config.users.register :admin, Admin
14
+
15
+ config.user_accounts.register :user, UserAccount
16
+ config.user_accounts.register :admin, AdminAccount
17
+
13
18
  config.cache_engine.set :off
14
19
  config.permit_engine.set :on
15
20
  end
@@ -35,8 +40,7 @@ end
35
40
  class Context
36
41
  include CanTango::Api::UserAccount::Can
37
42
 
38
- include ::CurrentUserAccounts
39
- extend ::CurrentUserAccounts
43
+ include_and_extend ::CurrentUserAccounts
40
44
  end
41
45
 
42
46
  describe CanTango::Api::UserAccount::Can do
File without changes
@@ -0,0 +1,168 @@
1
+ require 'rspec'
2
+ require 'cantango'
3
+ require 'simple_roles'
4
+ require 'fixtures/models'
5
+ require 'cantango/api/current_users'
6
+ require 'cantango/api/current_user_accounts'
7
+
8
+ class User
9
+ include_and_extend SimpleRoles
10
+ end
11
+
12
+ class Admin < User
13
+ end
14
+
15
+ class UserAccount
16
+ tango_account # register
17
+ include_and_extend SimpleRoles
18
+ end
19
+
20
+
21
+ class AdminAccount
22
+ tango_account
23
+ include_and_extend SimpleRoles
24
+ end
25
+
26
+
27
+ CanTango.configure do |config|
28
+ config.users.register :user, User
29
+ config.users.register :admin, Admin
30
+
31
+ config.cache_engine.set :off
32
+ config.permit_engine.set :on
33
+ end
34
+
35
+ class Context
36
+ include CanTango::Api::User::Ability
37
+
38
+ include_and_extend ::CurrentUsers
39
+ include_and_extend ::CurrentUserAccounts
40
+ end
41
+
42
+ class UserRolePermit < CanTango::RolePermit
43
+ def initialize ability
44
+ super
45
+ end
46
+
47
+ def permit_rules
48
+ can :edit, Project
49
+ cannot :publish, Project
50
+ end
51
+ end
52
+
53
+ class AdminRolePermit < CanTango::RolePermit
54
+ def initialize ability
55
+ super
56
+ end
57
+
58
+ def permit_rules
59
+ can :create, Project
60
+ can :show, Project
61
+
62
+ can :has_role?, Project
63
+ can :is_done?, Project
64
+ can :destroy!, Project
65
+
66
+ can :done!, Project
67
+ can :edit, Project
68
+ can :publish, Project
69
+ can :assign_to, Project
70
+ end
71
+ end
72
+
73
+ class Project
74
+ include CanTango::Model::Filter
75
+
76
+ tango_filter :publish, :edit, :DELETE, :is_done?, :done!
77
+ tango_filter :assign_to => [:user], :create => :OPTS, :show => [:ARGS], :has_role? => :role
78
+
79
+ def create options = {}
80
+ options
81
+ end
82
+
83
+ def show *args
84
+ args.flatten.compact
85
+ end
86
+
87
+ def is_done?
88
+ false
89
+ end
90
+
91
+ def has_role? role
92
+ true
93
+ end
94
+
95
+ def done!
96
+ "done"
97
+ end
98
+
99
+ def publish
100
+ "publish"
101
+ end
102
+
103
+ def destroy!
104
+ "destroy!"
105
+ end
106
+
107
+ def edit
108
+ "edit"
109
+ end
110
+
111
+ def assign_to user
112
+ user
113
+ end
114
+ end
115
+
116
+ describe CanTango::Model::Filter do
117
+ let(:context) { Context.new }
118
+
119
+ subject { Project.new }
120
+
121
+ describe '#tango_filter' do
122
+
123
+ describe 'block access to model method due to permission rule' do
124
+ specify { subject.publish_by(context.current_user).should be_nil }
125
+ end
126
+
127
+ describe 'allow access to model method due to permission rule' do
128
+ specify { subject.publish_by(context.current_admin).should == "publish" }
129
+ end
130
+
131
+ describe 'handle method with args' do
132
+ specify { subject.assign_to_by(context.current_admin, context.current_user).should == context.current_user }
133
+ specify { subject.assign_to_by(context.current_user, context.current_admin).should be_nil }
134
+ end
135
+
136
+ describe 'handle method with *args' do
137
+ specify { subject.show_by(context.current_admin, 'love', nil, 'hate').should == ['love', 'hate'] }
138
+ end
139
+
140
+ describe 'handle method with options' do
141
+ specify { subject.create_by(context.current_admin, :love => 5, :hate => 2).should == {:love => 5, :hate => 2} }
142
+ end
143
+
144
+ describe 'handle method with ? postfix' do
145
+ specify { subject.has_role_by?(context.current_admin, 'editor').should be_true }
146
+ specify { subject.is_done_by?(context.current_admin).should be_false }
147
+ end
148
+
149
+ describe 'handle method with ! postfix' do
150
+ specify { subject.done_by!(context.current_admin).should == 'done' }
151
+ end
152
+
153
+ describe 'handle special REST method - DELETE' do
154
+ specify { subject.destroy_by!(context.current_admin).should == 'destroy!' }
155
+ end
156
+ end
157
+
158
+ describe '#tango_account_filter' do
159
+ describe 'block access to model method due to permission rule' do
160
+ specify { subject.publish_by(context.current_user_account).should be_nil }
161
+ end
162
+
163
+ describe 'allow access to model method due to permission rule' do
164
+ specify { subject.publish_by(context.current_admin_account).should == "publish" }
165
+ end
166
+ end
167
+ end
168
+