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,67 @@
1
+ require 'active_support/inflector'
2
+
3
+ module CanTango
4
+ module Rules
5
+ class Relation
6
+ attr_reader :attribute, :permit, :scope, :models
7
+
8
+ include CanTango::Rules::Adaptor
9
+ include CanTango::Rules::RuleClass
10
+
11
+ def initialize attribute, permit, scope, *models, &block
12
+ @attribute = attribute
13
+ @scope = scope
14
+ @permit = permit
15
+ @models = models
16
+
17
+ check_models
18
+ use_adaptor! self, user_scope
19
+ end
20
+
21
+ def can(action)
22
+ models.each do |model|
23
+ rules << rule_class.new(true, action, model, nil, condition_block(model))
24
+ end
25
+ end
26
+
27
+ def cannot(action)
28
+ models.each do |model|
29
+ rules << rule_class.new(false, action, model, nil, condition_block(model))
30
+ end
31
+ end
32
+
33
+ protected
34
+
35
+ def condition_block model
36
+ return attribute_condition(attribute, user_scope) if model.new.respond_to?(attribute)
37
+ return include_condition(plural_attribute, user_scope) if model.new.respond_to?(plural_attribute)
38
+ end
39
+
40
+ def user_scope
41
+ @user_scope ||= (scope == :account) ? permit.user_account : permit.user
42
+ end
43
+
44
+ def scope_key
45
+ @scope_key ||= (scope == :account) ? :user_account : :user
46
+ end
47
+
48
+ def ability
49
+ permit.ability
50
+ end
51
+
52
+ def rules
53
+ ability.send :rules
54
+ end
55
+
56
+ def plural_attribute
57
+ :"#{attribute.to_s.pluralize}"
58
+ end
59
+
60
+ def check_models
61
+ models.each do |model|
62
+ raise "#{model} has no :#{attribute} or :#{plural_attribute} defined" if !model.new.respond_to?(attribute) && !model.new.respond_to?(plural_attribute)
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,11 @@
1
+ module CanTango
2
+ module Rules
3
+ module RuleClass
4
+ # CanCan 1.5 compatibility
5
+ def rule_class
6
+ return CanCan::Rule if defined? CanCan::Rule
7
+ CanCan::CanDefinition
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,24 @@
1
+ module CanTango
2
+ module Rules
3
+ class Scope
4
+ attr_reader :name, :permit
5
+
6
+ def initialize name, permit, &block
7
+ @name = name.to_sym
8
+ @permit = permit
9
+ end
10
+
11
+ ::CanTango.config.user.relations.each do |relationship|
12
+ base.class_eval %{
13
+ def #{relationship}_of *models, &block
14
+ options = models.extract_options!
15
+ scope = options[:scope] || name
16
+ relation = UserRelation.new :#{relationship}, permit, scope, models, &block
17
+ yield relation if block
18
+ relation
19
+ end
20
+ }
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,5 @@
1
+ module CanTango
2
+ module Scope
3
+ autoload_modules :Ability
4
+ end
5
+ end
@@ -0,0 +1,20 @@
1
+ module CanTango
2
+ module Scope
3
+ class Ability
4
+ attr_accessor :ability
5
+
6
+ def initialize ability
7
+ @ability = ability
8
+ end
9
+
10
+ def can? *args
11
+ ability.can? *args
12
+ end
13
+
14
+ def cannot? *args
15
+ ability.cannot? *args
16
+ end
17
+ end
18
+ end
19
+ end
20
+
@@ -0,0 +1,37 @@
1
+ module Cantango
2
+ module Generators
3
+ class InstallGenerator < Rails::Generators::Base
4
+ desc "Add role strategy to a User model"
5
+
6
+ source_root File.expand_path("../templates", __FILE__)
7
+
8
+ class_option :categories, :type => :boolean, :default => true, :desc => "Create categories"
9
+ class_option :permissions, :type => :boolean, :default => true, :desc => "Create yaml permissions store"
10
+
11
+ def copy_initializer
12
+ template "cantango.rb", "config/initializers/cantango.rb"
13
+ end
14
+
15
+ def copy_categories
16
+ return unless categories?
17
+ template "categories.yml", "config/categories.yml"
18
+ end
19
+
20
+ def copy_permissions
21
+ return unless permissions?
22
+ template "permissions.yml", "config/permissions.yml"
23
+ end
24
+
25
+ protected
26
+
27
+ def permissions?
28
+ options[:permissions]
29
+ end
30
+
31
+ def categories?
32
+ options[:categories]
33
+ end
34
+ end
35
+ end
36
+ end
37
+
@@ -0,0 +1,4 @@
1
+ CanTango.config do |config|
2
+ config.engines.all :on
3
+ # more configuration here...
4
+ end
@@ -0,0 +1,6 @@
1
+ account_types:
2
+ user_types:
3
+ roles:
4
+ role_groups:
5
+ licenses:
6
+ users:
@@ -0,0 +1,73 @@
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.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
29
+ end
30
+ end
31
+
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
+
55
+ before do
56
+ CanTango.config.clear!
57
+ @ability = CanTango::Ability.new user_account
58
+ end
59
+
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) }
70
+
71
+ its(:roles) { should_not be_empty }
72
+ its(:role_groups) { should_not be_empty }
73
+ end
File without changes
@@ -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
@@ -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
+
@@ -0,0 +1,77 @@
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.ability.mode = :cache
14
+ end
15
+ # CanTango.debug!
16
+
17
+ class User
18
+ tango_user
19
+ include_and_extend SimpleRoles
20
+ end
21
+
22
+ class AdminRolePermit < CanTango::Permit::Role
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
+ module CanTango
42
+ class CachedAbility
43
+ def permit_rules
44
+ can :read, Post
45
+ end
46
+ end
47
+ end
48
+
49
+ describe CanTango::Ability::Executor::CacheMode do
50
+ context 'cached only' do
51
+ before do
52
+ CanTango.configure.ability.mode = :cache
53
+
54
+ @user = User.new 'admin', 'admin@mail.ru', :role => 'admin'
55
+ @abil = CanTango::AbilityExecutor.new @user
56
+ end
57
+
58
+ subject { CanTango::AbilityExecutor.new @user }
59
+
60
+ describe 'config cache' do
61
+ specify { CanTango.configure.ability.modes.should == [:cache] }
62
+ end
63
+
64
+ describe 'engines_on?' do
65
+ specify { subject.engines_on?.should be_true }
66
+ end
67
+
68
+ its(:cached_rules) { should_not be_empty }
69
+ its(:non_cached_rules) { should be_empty }
70
+
71
+ describe 'rules contain only non-cached rules' do
72
+ specify { subject.rules.size.should == @abil.cached_rules.size }
73
+ specify { subject.rules.size.should == 4 }
74
+ end
75
+ end
76
+ end
77
+