cantango-permits 0.1.1

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 (166) hide show
  1. data/.rspec +1 -0
  2. data/Gemfile +39 -0
  3. data/Gemfile.lock +155 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README.mdown +362 -0
  6. data/Rakefile +45 -0
  7. data/VERSION +1 -0
  8. data/lib/cantango/executor.rb +5 -0
  9. data/lib/cantango/executor/base.rb +9 -0
  10. data/lib/cantango/executor/permit.rb +7 -0
  11. data/lib/cantango/executor/permit/abstract.rb +27 -0
  12. data/lib/cantango/executor/permit/base.rb +19 -0
  13. data/lib/cantango/executor/permit/special.rb +9 -0
  14. data/lib/cantango/executor/permit_type.rb +50 -0
  15. data/lib/cantango/license.rb +19 -0
  16. data/lib/cantango/license/rules.rb +17 -0
  17. data/lib/cantango/permit.mdown +4 -0
  18. data/lib/cantango/permit.rb +5 -0
  19. data/lib/cantango/permit/account_type.rb +44 -0
  20. data/lib/cantango/permit/attribute.rb +71 -0
  21. data/lib/cantango/permit/base.rb +94 -0
  22. data/lib/cantango/permit/class_methods.rb +49 -0
  23. data/lib/cantango/permit/helper.rb +11 -0
  24. data/lib/cantango/permit/helper/execution.rb +38 -0
  25. data/lib/cantango/permit/helper/host.rb +13 -0
  26. data/lib/cantango/permit/helper/license.rb +34 -0
  27. data/lib/cantango/permit/helper/naming.rb +38 -0
  28. data/lib/cantango/permit/helper/state.rb +21 -0
  29. data/lib/cantango/permit/special.rb +17 -0
  30. data/lib/cantango/permit/user.rb +36 -0
  31. data/lib/cantango/permit/user_type.rb +34 -0
  32. data/lib/cantango/permits.rb +20 -0
  33. data/lib/cantango/permits_ext.rb +7 -0
  34. data/lib/cantango/permits_ext/ability.rb +7 -0
  35. data/lib/cantango/permits_ext/ability/helper.rb +9 -0
  36. data/lib/cantango/permits_ext/ability/helper/permits.rb +8 -0
  37. data/lib/cantango/permits_ext/builder.rb +7 -0
  38. data/lib/cantango/permits_ext/builder/permit.rb +9 -0
  39. data/lib/cantango/permits_ext/builder/permit/account_type.rb +13 -0
  40. data/lib/cantango/permits_ext/builder/permit/base.rb +94 -0
  41. data/lib/cantango/permits_ext/builder/permit/special.rb +13 -0
  42. data/lib/cantango/permits_ext/builder/permit/user_type.rb +7 -0
  43. data/lib/cantango/permits_ext/class_methods.rb +28 -0
  44. data/lib/cantango/permits_ext/config.rb +11 -0
  45. data/lib/cantango/permits_ext/config/engines.rb +9 -0
  46. data/lib/cantango/permits_ext/config/engines/permit.rb +20 -0
  47. data/lib/cantango/permits_ext/config/permits.rb +43 -0
  48. data/lib/cantango/permits_ext/config/permits/accounts.rb +15 -0
  49. data/lib/cantango/permits_ext/config/permits/disabling.rb +22 -0
  50. data/lib/cantango/permits_ext/config/permits/enabling.rb +14 -0
  51. data/lib/cantango/permits_ext/config/permits/execution.rb +21 -0
  52. data/lib/cantango/permits_ext/config/permits/key.rb +19 -0
  53. data/lib/cantango/permits_ext/config/permits/registration.rb +33 -0
  54. data/lib/cantango/permits_ext/config/permits/tracking.rb +19 -0
  55. data/lib/cantango/permits_ext/config/permits/types.rb +25 -0
  56. data/lib/cantango/permits_ext/engine.rb +7 -0
  57. data/lib/cantango/permits_ext/engine/permits.rb +75 -0
  58. data/lib/cantango/permits_ext/factory.rb +7 -0
  59. data/lib/cantango/permits_ext/factory/permits.rb +40 -0
  60. data/lib/cantango/permits_ext/finder.rb +7 -0
  61. data/lib/cantango/permits_ext/finder/base.rb +35 -0
  62. data/lib/cantango/permits_ext/finder/permit.rb +7 -0
  63. data/lib/cantango/permits_ext/finder/permit/account.rb +47 -0
  64. data/lib/cantango/permits_ext/finder/permit/base.rb +53 -0
  65. data/lib/cantango/permits_ext/loader.rb +7 -0
  66. data/lib/cantango/permits_ext/loader/categories.rb +50 -0
  67. data/lib/cantango/permits_ext/loader/license.rb +19 -0
  68. data/lib/cantango/permits_ext/macros.rb +7 -0
  69. data/lib/cantango/permits_ext/macros/permit.rb +32 -0
  70. data/lib/cantango/permits_ext/parser.rb +7 -0
  71. data/lib/cantango/permits_ext/parser/categories.rb +15 -0
  72. data/lib/cantango/permits_ext/registry.rb +7 -0
  73. data/lib/cantango/permits_ext/registry/permit.rb +45 -0
  74. data/lib/generators/cantango/account_permit/account_permit_generator.rb +37 -0
  75. data/lib/generators/cantango/account_permit/templates/account_permit.erb +23 -0
  76. data/lib/generators/cantango/base.rb +71 -0
  77. data/lib/generators/cantango/basic.rb +41 -0
  78. data/lib/generators/cantango/license/license_generator.rb +29 -0
  79. data/lib/generators/cantango/license/templates/license.erb +10 -0
  80. data/lib/generators/cantango/license_base.rb +15 -0
  81. data/lib/generators/cantango/licenses/licenses_generator.rb +26 -0
  82. data/lib/generators/cantango/permit_generator.rb +58 -0
  83. data/lib/generators/cantango/role_permit/role_permit_generator.rb +39 -0
  84. data/lib/generators/cantango/role_permit/templates/account_permit.erb +4 -0
  85. data/lib/generators/cantango/role_permit/templates/role_group_permit.erb +24 -0
  86. data/lib/generators/cantango/role_permit/templates/role_permit.erb +23 -0
  87. data/lib/generators/cantango/role_permits/role_permits_generator.rb +45 -0
  88. data/lib/generators/cantango/user_permit/templates/account_permit.erb +5 -0
  89. data/lib/generators/cantango/user_permit/templates/user_permit.erb +23 -0
  90. data/lib/generators/cantango/user_permit/user_permit_generator.rb +36 -0
  91. data/lib/tasks/permits_tasks.rake +4 -0
  92. data/spec/cantango/ability/helper/permits_spec.rb +14 -0
  93. data/spec/cantango/builder/permit/account_type_spec.rb +25 -0
  94. data/spec/cantango/builder/permit/base_spec.rb +30 -0
  95. data/spec/cantango/builder/permit/special_spec.rb +25 -0
  96. data/spec/cantango/builder/permit/user_type_spec.rb +27 -0
  97. data/spec/cantango/config/engines/permit_spec.rb +14 -0
  98. data/spec/cantango/config/engines_spec.rb +142 -0
  99. data/spec/cantango/config/permit_registry_ex.rb +9 -0
  100. data/spec/cantango/config/permit_registry_spec.rb +8 -0
  101. data/spec/cantango/config/permits/accounts_spec.rb +23 -0
  102. data/spec/cantango/config/permits/disabling_spec.rb +38 -0
  103. data/spec/cantango/config/permits/enabling_spec.rb +19 -0
  104. data/spec/cantango/config/permits/execution_spec.rb +27 -0
  105. data/spec/cantango/config/permits/registration_spec.rb +15 -0
  106. data/spec/cantango/config/permits/tracking_spec.rb +19 -0
  107. data/spec/cantango/config/permits/types_spec.rb +27 -0
  108. data/spec/cantango/config/permits_spec.rb +76 -0
  109. data/spec/cantango/engine/permit_cached_spec.rb +52 -0
  110. data/spec/cantango/engine/permit_spec.rb +58 -0
  111. data/spec/cantango/engine/permit_static_dynamic_spec.rb +65 -0
  112. data/spec/cantango/executor/custom_permit_spec.rb +65 -0
  113. data/spec/cantango/executor/more_permit_spec.rb +45 -0
  114. data/spec/cantango/executor/permit_base_spec.rb +46 -0
  115. data/spec/cantango/executor/permit_spec.rb +53 -0
  116. data/spec/cantango/executor/special_permit_spec.rb +36 -0
  117. data/spec/cantango/factory/permits_spec.rb +70 -0
  118. data/spec/cantango/finder/account_permit_spec.rb +30 -0
  119. data/spec/cantango/finder/permit_spec.rb +23 -0
  120. data/spec/cantango/license/save_license_spec.rb +24 -0
  121. data/spec/cantango/license_spec.rb +0 -0
  122. data/spec/cantango/loader/categories_spec.rb +47 -0
  123. data/spec/cantango/loader/license_spec.rb +7 -0
  124. data/spec/cantango/macros/permit_spec.rb +38 -0
  125. data/spec/cantango/parser/categories_spec.rb +19 -0
  126. data/spec/cantango/permit/account_type_spec.rb +34 -0
  127. data/spec/cantango/permit/attribute_permit_spec.rb +65 -0
  128. data/spec/cantango/permit/base_spec.rb +106 -0
  129. data/spec/cantango/permit/class_methods_spec.rb +34 -0
  130. data/spec/cantango/permit/helper/execution_spec.rb +54 -0
  131. data/spec/cantango/permit/helper/host_spec.rb +29 -0
  132. data/spec/cantango/permit/helper/license_spec.rb +37 -0
  133. data/spec/cantango/permit/helper/naming_spec.rb +56 -0
  134. data/spec/cantango/permit/helper/state_spec.rb +24 -0
  135. data/spec/cantango/permit/special_default_spec.rb +2 -0
  136. data/spec/cantango/permit/special_first_spec.rb +2 -0
  137. data/spec/cantango/permit/user_type_spec.rb +78 -0
  138. data/spec/cantango/registry/permit_spec.rb +67 -0
  139. data/spec/fixtures/config/cantango_permissions.yml +49 -0
  140. data/spec/fixtures/config/categories.yml +6 -0
  141. data/spec/fixtures/config/evaluator_fixtures.yml +18 -0
  142. data/spec/fixtures/config/licenses.yml +4 -0
  143. data/spec/fixtures/config/permissions.yml +60 -0
  144. data/spec/fixtures/config/role_group.yml +4 -0
  145. data/spec/fixtures/config/roles.yml +4 -0
  146. data/spec/fixtures/config/test_permissions.yml +55 -0
  147. data/spec/fixtures/config/user_permissions.yml +8 -0
  148. data/spec/fixtures/models.rb +15 -0
  149. data/spec/fixtures/models/admin.rb +2 -0
  150. data/spec/fixtures/models/admin_account.rb +22 -0
  151. data/spec/fixtures/models/items.rb +11 -0
  152. data/spec/fixtures/models/permission.rb +12 -0
  153. data/spec/fixtures/models/simple_roles.rb +49 -0
  154. data/spec/fixtures/models/user.rb +52 -0
  155. data/spec/fixtures/models/user_account.rb +21 -0
  156. data/spec/fixtures/tango_fixtures.rb +29 -0
  157. data/spec/generators/cantango/account_role_permit_generator_spec.rb +35 -0
  158. data/spec/generators/cantango/account_role_permits_generator_spec.rb +59 -0
  159. data/spec/generators/cantango/license_generator_spec.rb +33 -0
  160. data/spec/generators/cantango/licenses_generator_spec.rb +58 -0
  161. data/spec/generators/cantango/role_permit_generator_spec.rb +35 -0
  162. data/spec/generators/cantango/role_permits_generator_spec.rb +58 -0
  163. data/spec/helpers/current_user_accounts.rb +20 -0
  164. data/spec/helpers/current_users.rb +10 -0
  165. data/spec/spec_helper.rb +24 -0
  166. metadata +325 -0
@@ -0,0 +1,45 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "cantango-permits"
18
+ gem.homepage = "http://github.com/kristianmandrup/cantango-permits"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{Permits with engine for cantango}
21
+ gem.description = %Q{Permit classes and engine for CanTango}
22
+ gem.email = "kmandrup@gmail.com, s.pankevich@gmail.com"
23
+ gem.authors = ["Kristian Mandrup", "Stanislaw Pankevich"]
24
+ # dependencies defined in Gemfile
25
+ end
26
+ Jeweler::RubygemsDotOrgTasks.new
27
+
28
+ require 'rake/testtask'
29
+ Rake::TestTask.new(:test) do |test|
30
+ test.libs << 'lib' << 'test'
31
+ test.pattern = 'test/**/test_*.rb'
32
+ test.verbose = true
33
+ end
34
+
35
+ task :default => :test
36
+
37
+ require 'rdoc/task'
38
+ RDoc::Task.new do |rdoc|
39
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
40
+
41
+ rdoc.rdoc_dir = 'rdoc'
42
+ rdoc.title = "cantango-permits #{version}"
43
+ rdoc.rdoc_files.include('README*')
44
+ rdoc.rdoc_files.include('lib/**/*.rb')
45
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.1
@@ -0,0 +1,5 @@
1
+ module CanTango
2
+ module Executor
3
+ sweetload :Base, :Permit, :PermitType
4
+ end
5
+ end
@@ -0,0 +1,9 @@
1
+ module CanTango
2
+ module Executor
3
+ class Base
4
+ def execute!
5
+ raise NotImplementedError
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,7 @@
1
+ module CanTango
2
+ module Executor
3
+ module Permit
4
+ autoload_modules :Abstract, :Base, :Special
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,27 @@
1
+ module CanTango
2
+ module Executor
3
+ module Permit
4
+ class Abstract
5
+ include CanTango::Helpers::Debug
6
+
7
+ attr_accessor :permit
8
+
9
+ def initialize permit
10
+ @permit = permit
11
+ end
12
+
13
+ def execute!
14
+ permit.execute! if permit
15
+ end
16
+
17
+ protected
18
+
19
+ delegate :subject, :rules, :to => :permit
20
+
21
+ def valid_for? subject
22
+ permit.valid_for?(subject) if permit
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,19 @@
1
+ module CanTango
2
+ module Executor
3
+ module Permit
4
+ class Base < Abstract
5
+ # execute the permit
6
+ def execute!
7
+ not_valid_permit and return unless permit.valid?
8
+ super
9
+ end
10
+
11
+ protected
12
+
13
+ def not_valid_permit
14
+ debug "Permit #{permit} is not valid for #{subject}"
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,9 @@
1
+ module CanTango
2
+ module Executor
3
+ module Permit
4
+ class Special < Base
5
+ end
6
+ end
7
+ end
8
+ end
9
+
@@ -0,0 +1,50 @@
1
+ # This class is responsible for executing a set of similar Permits and collecting their rule results into one rule collection
2
+ # which can be cached under some key and later reused
3
+ #
4
+ module CanTango
5
+ module Executor
6
+ class PermitType < Base
7
+ attr_reader :ability, :permit_type, :permits
8
+
9
+ def initialize ability, permit_type, permits
10
+ @ability = ability
11
+ @permit_type = permit_type
12
+ @permits = permits
13
+ end
14
+
15
+ alias_method :cache_key, :permit_type
16
+
17
+ def cache
18
+ @cache ||= CanTango::Ability::Cache.new self, :cache_key => cache_key, :key_method_names => key_method_names
19
+ end
20
+
21
+ def execute!
22
+ # TODO: somehow type specific caching of result of permits!
23
+ permits.each do |permit|
24
+ CanTango.config.permits.was_executed(permit, ability) if CanTango.debug?
25
+ break if permit.execute == :break
26
+ end
27
+ end
28
+
29
+ protected
30
+
31
+ def valid?
32
+ true
33
+ end
34
+
35
+ def start_execute
36
+ debug "Execute #{permit_type} permits"
37
+ end
38
+
39
+ def end_execute
40
+ debug "Done #{permit_type} permits"
41
+ end
42
+
43
+ def key_method_names
44
+ permit_class = CanTango.config.permits.available_permits[permit_type]
45
+ key = permit_class.hash_key if permit_class && permit_class.respond_to?(:hash_key)
46
+ key ? [key] : []
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,19 @@
1
+ module CanTango
2
+ class License
3
+ sweetload :Rules
4
+
5
+ include Rules
6
+
7
+ attr_reader :ability, :licenses
8
+
9
+ def initialize ability
10
+ @ability = ability
11
+ end
12
+
13
+ def calc_rules
14
+ end
15
+
16
+ def execute
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,17 @@
1
+ module CanTango
2
+ class License
3
+ module Rules
4
+ def can(action, subject, conditions = nil, &block)
5
+ ability.can action, subject, conditions, &block
6
+ end
7
+
8
+ def cannot(action, subject, conditions = nil, &block)
9
+ ability.cannot action, subject, conditions, &block
10
+ end
11
+
12
+ def owns(user_account, clazz, ownership_relation = :user_id, user_id_attribute = :id)
13
+ ability.owns user_account, clazz, ownership_relation, user_id_attribute
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,4 @@
1
+ # Permit
2
+
3
+ The Permit folder contains functionality that work to find and build a Permit to be executed by the
4
+ Permit engine.
@@ -0,0 +1,5 @@
1
+ module CanTango
2
+ module Permit
3
+ sweetload :Helper, :ClassMethods
4
+ end
5
+ end
@@ -0,0 +1,44 @@
1
+ module CanTango
2
+ module Permit
3
+ class AccountType < Base
4
+ module ClassMethods
5
+ def type
6
+ :account
7
+ end
8
+
9
+ def hash_key
10
+ account_type_name(self)
11
+ end
12
+ end
13
+ extend ClassMethods
14
+
15
+ # creates the permit
16
+ # @param [Permits::Ability] the ability
17
+ # @param [Hash] the options
18
+ def initialize ability
19
+ super
20
+ end
21
+
22
+ def valid?
23
+ debug_invalid if !(subject_name == account_name)
24
+ subject_name == account_name
25
+ end
26
+
27
+ protected
28
+
29
+ def debug_invalid
30
+ puts "Not a valid permit for subject: (account class) #{subject_account} != #{permit_account} (permit account)" if CanTango.debug?
31
+ end
32
+
33
+ def subject_name
34
+ subject.class.name.sub(/.*(Account)$/, '').underscore.to_sym
35
+ end
36
+
37
+ def account_name
38
+ permit_name(self.class)
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+
@@ -0,0 +1,71 @@
1
+ module CanTango::Permit
2
+ class Attribute < Base
3
+ module ClassMethods
4
+ def attribute name = nil
5
+ @attribute ||= self.name.demodulize.gsub(/(.*)Permit/, '\1').underscore.to_sym
6
+ return @attribute unless name
7
+ @attribute = name
8
+ end
9
+
10
+ alias_method :type, :attribute
11
+ alias_method :hash_key, :attribute
12
+
13
+ def inherited(base_clazz)
14
+ register_type base_clazz
15
+ # register base_clazz, :name => attribute_name(base_clazz)
16
+ end
17
+
18
+ def attribute_name clazz = nil
19
+ clazz ||= self
20
+ clazz.name.demodulize.gsub(/(.*)(#{attribute.to_s.camelize}Permit)/, '\1').underscore.to_sym
21
+ end
22
+ end
23
+ extend ClassMethods
24
+
25
+ module TestAttribute
26
+ def plural_attribute
27
+ @pl ||= attribute.to_s.pluralize
28
+ end
29
+
30
+ def valid?
31
+ test_single || test_plural
32
+ end
33
+
34
+ def test_single
35
+ return false unless subject.respond_to?(attribute)
36
+ subject.send(attribute) == attribute
37
+ end
38
+
39
+ def test_plural
40
+ return false unless subject.respond_to?(plural_attribute)
41
+ subject.send(plural_attribute).include? attribute
42
+ end
43
+ end
44
+ include TestAttribute
45
+
46
+ def permit_name
47
+ self.class.attribute_name
48
+ end
49
+
50
+ def attribute name = nil
51
+ self.class.attribute
52
+ end
53
+
54
+ class Builder < CanTango::Builder::Permit::Base
55
+ def build
56
+ return [] unless valid?
57
+ super
58
+ end
59
+
60
+ protected
61
+
62
+ include CanTango::Permit::Attribute::TestAttribute
63
+
64
+ def self.attribute name = nil
65
+ raise "No attribute defined" unless name || @attribute
66
+ return @attribute unless name
67
+ @attribute = name
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,94 @@
1
+ # The permit base class for both Role Permits and Role Group Permits
2
+ # Should contain all common logic
3
+ module CanTango
4
+ module Permit
5
+ class Base
6
+ include CanTango::Helpers::Debug
7
+ include CanTango::Api::Attributes
8
+
9
+ Helper.modules.each do |name|
10
+ include "CanTango::Permit::Helper::#{name.to_s.camelize}".constantize
11
+ end
12
+ extend CanTango::Permit::ClassMethods
13
+
14
+ # strategy is used to control the owns strategy (see rules.rb)
15
+ attr_reader :ability, :strategy, :disabled
16
+
17
+ delegate :cached?, :options, :subject, :candidate, :user, :user_account, :rules, :can, :cannot, :to => :ability
18
+
19
+ def name
20
+ self.class.permit_name self.class
21
+ end
22
+
23
+ attr_writer :mode
24
+
25
+ # creates the permit
26
+ def initialize ability
27
+ @ability = ability
28
+ end
29
+
30
+ def mode
31
+ @mode ||= :no_cache
32
+ end
33
+
34
+ def modes
35
+ self.class.modes
36
+ end
37
+
38
+ def permit_type
39
+ self.class.permit_type
40
+ end
41
+
42
+ def disable!
43
+ @disabled = true
44
+ end
45
+
46
+ def disabled?
47
+ @disabled || CanTango.config.permits.disabled?(permit_type, name)
48
+ end
49
+
50
+ def valid?
51
+ raise NotImplementedError
52
+ end
53
+
54
+ def category label
55
+ CanTango.config.models.by_category label
56
+ end
57
+
58
+ def any reg_exp
59
+ CanTango.config.models.by_reg_exp reg_exp
60
+ end
61
+
62
+ CanTango::Api::Options.options_list.each do |obj|
63
+ class_eval %{
64
+ def #{obj}
65
+ options[:#{obj}]
66
+ end
67
+ }
68
+ end
69
+
70
+ def sync_rules!
71
+ ability.rules << (rules - ability_rules)
72
+ ability.rules.flatten!
73
+ end
74
+
75
+ protected
76
+
77
+ def config_disabled?
78
+ (CanTango.config.permits.disabled[permit_type] || []).include?(permit_name.to_s)
79
+ end
80
+
81
+ def strategy
82
+ @strategy ||= options[:strategy] || CanTango::Ability.strategy || :default
83
+ end
84
+
85
+ def any_role_match?
86
+ role_match?(subject) || role_group_match?(subject)
87
+ end
88
+
89
+ def config
90
+ CanTango.config
91
+ end
92
+ end
93
+ end
94
+ end