cantango-core 0.1.0
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.
- data/.document +5 -0
- data/.rspec +3 -0
- data/Gemfile +54 -0
- data/Gemfile.lock +231 -0
- data/LICENSE.txt +20 -0
- data/README.mdown +90 -0
- data/Rakefile +48 -0
- data/VERSION +1 -0
- data/cantango-core.gemspec +177 -0
- data/lib/cantango/ability.rb +5 -0
- data/lib/cantango/ability/base.rb +61 -0
- data/lib/cantango/ability/cache.rb +7 -0
- data/lib/cantango/ability/cache/key.rb +38 -0
- data/lib/cantango/ability/cached.rb +28 -0
- data/lib/cantango/ability/executor.rb +7 -0
- data/lib/cantango/ability/executor/base.rb +53 -0
- data/lib/cantango/ability/executor/cache_mode.rb +33 -0
- data/lib/cantango/ability/executor/modes.rb +52 -0
- data/lib/cantango/ability/executor/no_cache_mode.rb +17 -0
- data/lib/cantango/ability/helper.rb +11 -0
- data/lib/cantango/ability/helper/account.rb +13 -0
- data/lib/cantango/ability/helper/engine.rb +32 -0
- data/lib/cantango/ability/helper/role.rb +21 -0
- data/lib/cantango/ability/helper/role_group.rb +21 -0
- data/lib/cantango/ability/helper/user.rb +18 -0
- data/lib/cantango/cancan/rule.rb +6 -0
- data/lib/cantango/core.rb +84 -0
- data/lib/cantango/engine.rb +39 -0
- data/lib/cantango/filter.rb +5 -0
- data/lib/cantango/filter/base.rb +31 -0
- data/lib/cantango/helpers.rb +5 -0
- data/lib/cantango/helpers/debug.rb +10 -0
- data/lib/cantango/loader.rb +5 -0
- data/lib/cantango/loader/yaml.rb +33 -0
- data/lib/cantango/macros.rb +11 -0
- data/lib/cantango/macros/account.rb +14 -0
- data/lib/cantango/macros/user.rb +16 -0
- data/lib/cantango/model.rb +5 -0
- data/lib/cantango/model/guest.rb +25 -0
- data/lib/cantango/rails.rb +7 -0
- data/lib/cantango/rails/engine.rb +63 -0
- data/lib/cantango/rails/helpers/base_helper.rb +29 -0
- data/lib/cantango/rails/helpers/controller_helper.rb +17 -0
- data/lib/cantango/rails/helpers/rest_helper.rb +76 -0
- data/lib/cantango/rails/helpers/view_helper.rb +17 -0
- data/lib/cantango/rails/railtie.rb +7 -0
- data/lib/cantango/rspec.rb +1 -0
- data/lib/cantango/rspec/config.rb +3 -0
- data/lib/cantango/rspec/matchers.rb +1 -0
- data/lib/cantango/rspec/matchers/be_allowed_to.rb +28 -0
- data/lib/cantango/rules.rb +8 -0
- data/lib/cantango/rules/adaptor.rb +37 -0
- data/lib/cantango/rules/adaptor/active_record.rb +10 -0
- data/lib/cantango/rules/adaptor/data_mapper.rb +11 -0
- data/lib/cantango/rules/adaptor/generic.rb +16 -0
- data/lib/cantango/rules/adaptor/mongo.rb +19 -0
- data/lib/cantango/rules/adaptor/mongo_mapper.rb +10 -0
- data/lib/cantango/rules/adaptor/mongoid.rb +9 -0
- data/lib/cantango/rules/adaptor/relational.rb +13 -0
- data/lib/cantango/rules/dsl.rb +24 -0
- data/lib/cantango/rules/relation.rb +67 -0
- data/lib/cantango/rules/rule_class.rb +11 -0
- data/lib/cantango/rules/scope.rb +24 -0
- data/lib/cantango/scope.rb +5 -0
- data/lib/cantango/scope/ability.rb +20 -0
- data/lib/generators/cantango/install/install_generator.rb +37 -0
- data/lib/generators/cantango/install/templates/cantango.rb +4 -0
- data/lib/generators/cantango/install/templates/categories.yml +0 -0
- data/lib/generators/cantango/install/templates/permissions.yml +6 -0
- data/spec/cantango/ability/base_spec.rb +73 -0
- data/spec/cantango/ability/cached_spec.rb +0 -0
- data/spec/cantango/ability/executor/base2.rb +75 -0
- data/spec/cantango/ability/executor/base_spec.rb +67 -0
- data/spec/cantango/ability/executor/cache_mode_spec.rb +77 -0
- data/spec/cantango/ability/executor/modes_spec.rb +68 -0
- data/spec/cantango/ability/executor/no_cache_mode_spec.rb +0 -0
- data/spec/cantango/cancan/rule_spec.rb +0 -0
- data/spec/cantango/core_spec.rb +9 -0
- data/spec/cantango/engine_spec.rb +0 -0
- data/spec/cantango/filter/base_spec.rb +0 -0
- data/spec/cantango/helpers/debug_spec.rb +0 -0
- data/spec/cantango/loader/yaml_spec.rb +0 -0
- data/spec/cantango/macros/account_spec.rb +0 -0
- data/spec/cantango/macros/user_spec.rb +0 -0
- data/spec/cantango/rspec/be_allowed_to_spec.rb +0 -0
- data/spec/cantango/rules/adaptor/active_record_spec.rb +0 -0
- data/spec/cantango/rules/adaptor/data_mapper_spec.rb +0 -0
- data/spec/cantango/rules/adaptor/mongo_mapper_spec.rb +0 -0
- data/spec/cantango/rules/adaptor/mongoid_spec.rb +0 -0
- data/spec/cantango/rules/adaptor_spec.rb +0 -0
- data/spec/cantango/rules/dsl_spec.rb +0 -0
- data/spec/cantango/rules/relation_spec.rb +0 -0
- data/spec/cantango/rules/rule_class_spec.rb +0 -0
- data/spec/cantango/rules/scope_spec.rb +0 -0
- data/spec/cantango/rules_spec.rb +55 -0
- data/spec/cantango/scope/ability_spec.rb +0 -0
- data/spec/cantango_spec.rb +0 -0
- data/spec/generators/cantango/install_generator_spec.rb +42 -0
- data/spec/spec_helper.rb +9 -0
- metadata +310 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module CanTango
|
|
2
|
+
class Ability
|
|
3
|
+
module Helper
|
|
4
|
+
module Engine
|
|
5
|
+
def execute_engines!
|
|
6
|
+
each_engine do |engine|
|
|
7
|
+
engine_rules = engine.new(self).execute! if engine
|
|
8
|
+
@rules << engine_rules if !engine_rules.blank?
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def each_engine &block
|
|
13
|
+
engines.execution_order.each do |name|
|
|
14
|
+
yield engines.registered[name] if engines.active? name
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def opts_engines_off?
|
|
19
|
+
options[:engines] == :off
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def engines_on?
|
|
23
|
+
CanTango.config.engines.any?(:on) && !opts_engines_off?
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def engines
|
|
27
|
+
CanTango.config.engines
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module CanTango
|
|
2
|
+
class Ability
|
|
3
|
+
module Helper
|
|
4
|
+
module Role
|
|
5
|
+
include CanTango::Helpers::RoleMethods
|
|
6
|
+
|
|
7
|
+
# return list roles the user has
|
|
8
|
+
def roles
|
|
9
|
+
return [] if !subject.respond_to?(roles_list_meth) || roles_of(subject).blank?
|
|
10
|
+
roles_of(subject).flatten
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
protected
|
|
14
|
+
|
|
15
|
+
def roles_of subject
|
|
16
|
+
@subj_roles ||= subject.send(roles_list_meth)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module CanTango
|
|
2
|
+
class Ability
|
|
3
|
+
module Helper
|
|
4
|
+
module RoleGroup
|
|
5
|
+
include CanTango::Helpers::RoleMethods
|
|
6
|
+
|
|
7
|
+
# return list of symbols for role groups the user belongs to
|
|
8
|
+
def role_groups
|
|
9
|
+
return [] if !subject.respond_to?(role_groups_list_meth) || role_groups_of(subject).blank?
|
|
10
|
+
role_groups_of(subject).flatten
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
protected
|
|
14
|
+
|
|
15
|
+
def role_groups_of subject
|
|
16
|
+
@subj_role_groups ||= subject.send(role_groups_list_meth)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module CanTango
|
|
2
|
+
class Ability
|
|
3
|
+
module Helper
|
|
4
|
+
module User
|
|
5
|
+
def user
|
|
6
|
+
return subject.user if subject.respond_to? :user
|
|
7
|
+
subject
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def user_key_field
|
|
11
|
+
key_field = config.user.unique_key_field
|
|
12
|
+
raise "\nModel <#{user.class}> has no ##{key_field} as defined in CanTango.config.user.unique_key_field" if !user.respond_to?(key_field)
|
|
13
|
+
key_field
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
require 'cantango/rails/railtie' if defined?(Rails)
|
|
2
|
+
require 'cantango/rails/engine' if defined?(Rails)
|
|
3
|
+
|
|
4
|
+
# essential cantango extensions
|
|
5
|
+
# require 'cantango/config'
|
|
6
|
+
# require 'cantango/api'
|
|
7
|
+
|
|
8
|
+
require 'cancan'
|
|
9
|
+
require 'active_support' # for Delegate module
|
|
10
|
+
require 'active_support/core_ext/module/delegation'
|
|
11
|
+
|
|
12
|
+
require 'cantango/cancan/rule'
|
|
13
|
+
require 'sugar-high/array'
|
|
14
|
+
require 'sugar-high/blank'
|
|
15
|
+
require 'hashie'
|
|
16
|
+
require 'sweetloader'
|
|
17
|
+
|
|
18
|
+
AutoLoader.namespaces = {:CanTango => 'cantango'}
|
|
19
|
+
|
|
20
|
+
module CanTango
|
|
21
|
+
autoload_modules :Ability, :Engine, :Filter
|
|
22
|
+
autoload_modules :Helpers, :Loader, :Macros, :Model
|
|
23
|
+
autoload_modules :Rails, :Rules, :Scope
|
|
24
|
+
|
|
25
|
+
class << self
|
|
26
|
+
def configure &block
|
|
27
|
+
conf = CanTango::Configuration.instance
|
|
28
|
+
yield conf if block
|
|
29
|
+
conf
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
alias_method :config, :configure
|
|
33
|
+
|
|
34
|
+
# Engine hook
|
|
35
|
+
# Run after the initializers are ran for all Railties (including the application itself), but before eager loading and the middleware stack is built.
|
|
36
|
+
# More importantly, will run upon every request in development, but only once (during boot-up) in production and test.
|
|
37
|
+
def to_prepare
|
|
38
|
+
config.hook(:to_prepare).call if config.hook(:to_prepare)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# engine hook, run after all Rails initializations have been executed
|
|
42
|
+
def after_initialize
|
|
43
|
+
config.hook(:after_initialize).call if config.hook(:after_initialize)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def permits_allowed candidate, actions, subjects, *extra_args
|
|
47
|
+
raise "Debugging has not been turned on. Turn it on using: CanTango.debug!" if CanTango.config.debug.off?
|
|
48
|
+
config.permits.allowed candidate, actions, subjects, *extra_args
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def permits_denied candidate, actions, subjects, *extra_args
|
|
52
|
+
raise "Debugging has not been turned on. Turn it on using: CanTango.debug!" if CanTango.config.debug.off?
|
|
53
|
+
config.permits.denied candidate, actions, subjects, *extra_args
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def debug_permits_registry
|
|
57
|
+
puts "permits registry:" << CanTango.config.permits.show_all.inspect
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def debug_ability candidate, actions, subjects, *extra_args
|
|
61
|
+
puts "Ability: #{actions} on #{subjects}"
|
|
62
|
+
puts "permits allowed:" << permits_allowed(candidate, actions, subjects, *extra_args).inspect
|
|
63
|
+
puts "permits denied:" << permits_denied(candidate, actions, subjects, *extra_args).inspect
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def clear_permits_executed!
|
|
67
|
+
config.permits.clear_executed!
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def debug!
|
|
71
|
+
config.debug.set :on
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def debug_off!
|
|
75
|
+
config.debug.set :off
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def debug?
|
|
79
|
+
config.debug.on?
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
require 'cantango/macros'
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
module CanTango
|
|
2
|
+
class Engine
|
|
3
|
+
include CanTango::Helpers::Debug
|
|
4
|
+
|
|
5
|
+
attr_reader :ability
|
|
6
|
+
|
|
7
|
+
delegate :session, :user, :subject, :candidate, :cached?, :to => :ability
|
|
8
|
+
|
|
9
|
+
def initialize ability
|
|
10
|
+
@ability = ability
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def execute!
|
|
14
|
+
raise NotImplementedError
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def engine_name
|
|
18
|
+
raise NotImplementedError
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
protected
|
|
22
|
+
|
|
23
|
+
def valid_mode?
|
|
24
|
+
valid_cache_mode? || valid_no_cache_mode?
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def valid_cache_mode?
|
|
28
|
+
modes.include?(:cache) && cached?
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def valid_no_cache_mode?
|
|
32
|
+
modes.include?(:no_cache) && !cached?
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def modes
|
|
36
|
+
CanTango.config.engine(engine_name.to_sym).modes
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module CanTango
|
|
2
|
+
module Filter
|
|
3
|
+
class Base
|
|
4
|
+
attr_reader :item, :include_list
|
|
5
|
+
|
|
6
|
+
def initialize item, list = nil
|
|
7
|
+
@item = item.to_sym
|
|
8
|
+
@include_list = list || []
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def valid?
|
|
12
|
+
return false if !in_include_list?
|
|
13
|
+
return false if not_only?
|
|
14
|
+
!excluded?
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def in_include_list?
|
|
18
|
+
return false if include_list.blank?
|
|
19
|
+
include_list.include? item
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def not_only?
|
|
23
|
+
false
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def excluded?
|
|
27
|
+
false
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module CanTango
|
|
2
|
+
module Loader
|
|
3
|
+
class Yaml
|
|
4
|
+
attr_accessor :file_name
|
|
5
|
+
|
|
6
|
+
def self.inherited subclass
|
|
7
|
+
subclass.extend ClassMethods
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def parser
|
|
11
|
+
raise NotImplementedError
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def yml_content
|
|
15
|
+
YAML.load_file(file_name)
|
|
16
|
+
rescue
|
|
17
|
+
raise "Couldn't load permissions file: #{file_name}. Either disable Permission engine or add this file."
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
module ClassMethods
|
|
21
|
+
protected
|
|
22
|
+
|
|
23
|
+
def config_file name
|
|
24
|
+
File.join(config_path, "#{name}.yml") if rails?
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def config_path
|
|
28
|
+
CanTango.config.permissions.config_path
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module CanTango::Macros
|
|
2
|
+
module Account
|
|
3
|
+
def tango_user_account options = {}
|
|
4
|
+
self.send :include, CanTango::AccountApi
|
|
5
|
+
|
|
6
|
+
if defined? CanTango::Macros::Masquerader
|
|
7
|
+
self.send :include, CanTango::Macros::Masquerader
|
|
8
|
+
masquerader if options[:masquerade]
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
alias_method :tango_account, :tango_user_account
|
|
12
|
+
alias_method :cantango_account, :tango_user_account
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module CanTango::Macros
|
|
2
|
+
module User
|
|
3
|
+
def tango_user options = {}
|
|
4
|
+
self.send :include, CanTango::UserApi
|
|
5
|
+
self.send :include, CanTango::Masquerade::UserApi
|
|
6
|
+
masquerader if options[:masquerade]
|
|
7
|
+
end
|
|
8
|
+
alias_method :cantango_user, :tango_user
|
|
9
|
+
|
|
10
|
+
module Masquerader
|
|
11
|
+
def masquerader
|
|
12
|
+
self.send :include, CanTango::Masquerade::UserApi
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require 'active_model'
|
|
2
|
+
|
|
3
|
+
module CanTango
|
|
4
|
+
module Model
|
|
5
|
+
module Guest
|
|
6
|
+
def self.included(base)
|
|
7
|
+
base.extend ::ActiveModel::Naming
|
|
8
|
+
base.send :include, ::ActiveModel::Conversion
|
|
9
|
+
base.send :include, ::ActiveModel::Validations
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def email
|
|
13
|
+
'guest@info.com'
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def has_role? role
|
|
17
|
+
role.to_sym == :guest
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def persisted?
|
|
21
|
+
false
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|