cantango-core 0.1.3 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- data/README.mdown +12 -34
- data/VERSION +1 -1
- data/cantango-core.gemspec +33 -16
- data/lib/cantango/ability/base.rb +8 -52
- data/lib/cantango/ability/cache/simple_key.rb +1 -0
- data/lib/cantango/ability/callbacks.rb +36 -0
- data/lib/cantango/ability/executor/base.rb +21 -46
- data/lib/cantango/ability/executor/modal.rb +46 -0
- data/lib/cantango/ability/executor.rb +24 -1
- data/lib/cantango/ability/mode/base.rb +32 -0
- data/lib/cantango/ability/mode/finder.rb +19 -0
- data/lib/cantango/ability/mode/no_cache.rb +8 -0
- data/lib/cantango/ability/mode.rb +7 -0
- data/lib/cantango/ability/rules.rb +24 -0
- data/lib/cantango/ability.rb +1 -6
- data/lib/cantango/adaptor/active_record.rb +1 -1
- data/lib/cantango/adaptor/data_mapper.rb +1 -1
- data/lib/cantango/adaptor/mongo.rb +1 -1
- data/lib/cantango/adaptor/mongo_mapper.rb +1 -1
- data/lib/cantango/adaptor/mongoid.rb +1 -1
- data/lib/cantango/adaptor.rb +24 -26
- data/lib/cantango/core.rb +1 -1
- data/lib/cantango/helpers/debug.rb +4 -2
- data/lib/cantango/loader/yaml.rb +5 -1
- data/spec/active_record/001_create_posters.rb +13 -0
- data/spec/active_record/002_create_users.rb +13 -0
- data/spec/cantango/ability/base_spec.rb +3 -6
- data/spec/cantango/ability/callbacks_spec.rb +48 -0
- data/spec/cantango/ability/executor/base_spec.rb +15 -14
- data/spec/cantango/ability/executor/custom_spec.rb +3 -3
- data/spec/cantango/ability/executor/modal_spec.rb +35 -0
- data/spec/cantango/ability/executor_spec.rb +29 -0
- data/spec/cantango/ability/mode/base_example.rb +28 -0
- data/spec/cantango/ability/mode/base_spec.rb +15 -0
- data/spec/cantango/ability/mode/no_cache_spec.rb +15 -0
- data/spec/cantango/ability/rules_spec.rb +48 -0
- data/spec/cantango/adaptor/active_record_spec.rb +11 -2
- data/spec/cantango/loader/yaml_spec.rb +9 -1
- data/spec/cantango/rspec/be_allowed_to_spec.rb +1 -1
- data/spec/db/database.yml +4 -0
- data/spec/fixtures/test.yml +2 -0
- data/spec/migration_helper.rb +17 -0
- data/spec/spec_helper.rb +4 -0
- metadata +51 -37
- data/lib/cantango/ability/base/callbacks.rb +0 -37
- data/lib/cantango/ability/executor/modes.rb +0 -52
- data/lib/cantango/ability/executor/no_cache_mode.rb +0 -13
- data/spec/cantango/ability/executor/modes_spec.rb +0 -46
- data/spec/cantango/ability/executor/no_cache_mode_spec.rb +0 -29
data/README.mdown
CHANGED
@@ -27,9 +27,9 @@ Run bundler in a terminal/console from the folder of your Gemfile (root folder o
|
|
27
27
|
|
28
28
|
`$ bundle`
|
29
29
|
|
30
|
-
## CanTango
|
30
|
+
## CanTango core extensions
|
31
31
|
|
32
|
-
|
32
|
+
The following CanTango components extend core:
|
33
33
|
|
34
34
|
* [Cantango core](https://github.com/kristianmandrup/cantango-core)
|
35
35
|
* [Cantango config](https://github.com/kristianmandrup/cantango-config)
|
@@ -38,42 +38,20 @@ CanTango has now been split up into these logical components:
|
|
38
38
|
* [Cantango masquerade](https://github.com/kristianmandrup/cantango-masquerade)
|
39
39
|
* [Cantango roles](https://github.com/kristianmandrup/cantango-roles)
|
40
40
|
|
41
|
-
Engines (Ability executors):
|
42
41
|
|
43
|
-
|
44
|
-
* [Permit store](https://github.com/kristianmandrup/cantango-permit_store)
|
45
|
-
* [Permissions](https://github.com/kristianmandrup/cantango-permissions)
|
42
|
+
## Extending core
|
46
43
|
|
47
|
-
|
44
|
+
To extend core, you should follow the CanTango extension conventions. We will demonstrate these conventions using the _-api_ extension as an example. The extension file structure should look like this:
|
48
45
|
|
49
|
-
|
46
|
+
```text
|
47
|
+
/cantango
|
48
|
+
/api
|
49
|
+
/api_ext
|
50
|
+
api.rb
|
51
|
+
api_ext.rb_
|
52
|
+
```
|
50
53
|
|
51
|
-
|
52
|
-
|
53
|
-
## Quickstart
|
54
|
-
|
55
|
-
See the [Quickstart guide](https://github.com/kristianmandrup/cantango/wiki/Quickstart) in the wiki.
|
56
|
-
|
57
|
-
For [devise](https://github.com/plataformatec/devise) integration, see [Quickstart CanTango with Devise](https://github.com/kristianmandrup/cantango/wiki/Quickstart-cantango-with-devise)
|
58
|
-
|
59
|
-
The following scenarios demonstrate some of the problems CanTango can help solve in an elegant way
|
60
|
-
|
61
|
-
* [Simple scenario](https://github.com/kristianmandrup/cantango/wiki/Simple-scenario)
|
62
|
-
* [Complex scenario](https://github.com/kristianmandrup/cantango/wiki/Complex-scenario)
|
63
|
-
|
64
|
-
### Generators
|
65
|
-
|
66
|
-
Cantango comes with a set of [Generators](https://github.com/kristianmandrup/cantango/wiki/Generators) to get your app dancing...
|
67
|
-
|
68
|
-
Install CanTango using
|
69
|
-
|
70
|
-
* cantango:install
|
71
|
-
|
72
|
-
`$ rails g cantango:install`
|
73
|
-
|
74
|
-
### Configuration
|
75
|
-
|
76
|
-
The CanTango [Configuration](https://github.com/kristianmandrup/cantango/wiki/Configuration) consists of a nice nested configuration DSL.
|
54
|
+
The main API logic should go in the `cantango/api` folder. Extensions to core go into the `cantango/api_ext` folder. The extensions should use the same folder structure as core if possible.
|
77
55
|
|
78
56
|
## Contributing to cantango-core
|
79
57
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.4
|
data/cantango-core.gemspec
CHANGED
@@ -4,14 +4,17 @@
|
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
|
-
s.name =
|
8
|
-
s.version = "0.1.
|
7
|
+
s.name = %q{cantango-core}
|
8
|
+
s.version = "0.1.4"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
-
s.authors = [
|
12
|
-
s.date =
|
13
|
-
s.description =
|
14
|
-
|
11
|
+
s.authors = [%q{Kristian Mandrup}, %q{Stanislaw Pankevich}]
|
12
|
+
s.date = %q{2011-12-03}
|
13
|
+
s.description = %q{Define your permission rules as role- or role group specific permits.
|
14
|
+
Integrates well with multiple Devise user acounts.
|
15
|
+
Includes rules caching.
|
16
|
+
Store permissions in yaml file or key-value store}
|
17
|
+
s.email = %q{kmandrup@gmail.com, s.pankevich@gmail.com}
|
15
18
|
s.extra_rdoc_files = [
|
16
19
|
"LICENSE.txt",
|
17
20
|
"README.mdown"
|
@@ -28,17 +31,21 @@ Gem::Specification.new do |s|
|
|
28
31
|
"cantango-core.gemspec",
|
29
32
|
"lib/cantango/ability.rb",
|
30
33
|
"lib/cantango/ability/base.rb",
|
31
|
-
"lib/cantango/ability/base/callbacks.rb",
|
32
34
|
"lib/cantango/ability/cache.rb",
|
33
35
|
"lib/cantango/ability/cache/simple_key.rb",
|
36
|
+
"lib/cantango/ability/callbacks.rb",
|
34
37
|
"lib/cantango/ability/executor.rb",
|
35
38
|
"lib/cantango/ability/executor/base.rb",
|
36
|
-
"lib/cantango/ability/executor/
|
37
|
-
"lib/cantango/ability/executor/no_cache_mode.rb",
|
39
|
+
"lib/cantango/ability/executor/modal.rb",
|
38
40
|
"lib/cantango/ability/helper.rb",
|
39
41
|
"lib/cantango/ability/helper/account.rb",
|
40
42
|
"lib/cantango/ability/helper/engine.rb",
|
41
43
|
"lib/cantango/ability/helper/user.rb",
|
44
|
+
"lib/cantango/ability/mode.rb",
|
45
|
+
"lib/cantango/ability/mode/base.rb",
|
46
|
+
"lib/cantango/ability/mode/finder.rb",
|
47
|
+
"lib/cantango/ability/mode/no_cache.rb",
|
48
|
+
"lib/cantango/ability/rules.rb",
|
42
49
|
"lib/cantango/adaptor.rb",
|
43
50
|
"lib/cantango/adaptor/active_record.rb",
|
44
51
|
"lib/cantango/adaptor/data_mapper.rb",
|
@@ -70,15 +77,22 @@ Gem::Specification.new do |s|
|
|
70
77
|
"lib/generators/cantango/install/templates/cantango.rb",
|
71
78
|
"lib/generators/cantango/install/templates/categories.yml",
|
72
79
|
"lib/generators/cantango/install/templates/permissions.yml",
|
80
|
+
"spec/active_record/001_create_posters.rb",
|
81
|
+
"spec/active_record/002_create_users.rb",
|
73
82
|
"spec/cantango/ability/base_spec.rb",
|
74
83
|
"spec/cantango/ability/cache/simple_key_spec.rb",
|
84
|
+
"spec/cantango/ability/callbacks_spec.rb",
|
75
85
|
"spec/cantango/ability/executor/base_spec.rb",
|
76
86
|
"spec/cantango/ability/executor/custom_spec.rb",
|
77
|
-
"spec/cantango/ability/executor/
|
78
|
-
"spec/cantango/ability/
|
87
|
+
"spec/cantango/ability/executor/modal_spec.rb",
|
88
|
+
"spec/cantango/ability/executor_spec.rb",
|
79
89
|
"spec/cantango/ability/helper/account_spec.rb",
|
80
90
|
"spec/cantango/ability/helper/engine_spec.rb",
|
81
91
|
"spec/cantango/ability/helper/user_spec.rb",
|
92
|
+
"spec/cantango/ability/mode/base_example.rb",
|
93
|
+
"spec/cantango/ability/mode/base_spec.rb",
|
94
|
+
"spec/cantango/ability/mode/no_cache_spec.rb",
|
95
|
+
"spec/cantango/ability/rules_spec.rb",
|
82
96
|
"spec/cantango/adaptor/active_record_spec.rb",
|
83
97
|
"spec/cantango/adaptor/data_mapper_spec.rb",
|
84
98
|
"spec/cantango/adaptor/mongo_mapper_spec.rb",
|
@@ -93,20 +107,23 @@ Gem::Specification.new do |s|
|
|
93
107
|
"spec/cantango/rspec/be_allowed_to_spec.rb",
|
94
108
|
"spec/cantango/scope/ability_spec.rb",
|
95
109
|
"spec/cantango_spec.rb",
|
110
|
+
"spec/db/database.yml",
|
96
111
|
"spec/fixtures/models.rb",
|
97
112
|
"spec/fixtures/models/account.rb",
|
98
113
|
"spec/fixtures/models/admin.rb",
|
99
114
|
"spec/fixtures/models/admin_account.rb",
|
100
115
|
"spec/fixtures/models/items.rb",
|
101
116
|
"spec/fixtures/models/user.rb",
|
117
|
+
"spec/fixtures/test.yml",
|
102
118
|
"spec/generators/cantango/install_generator_spec.rb",
|
119
|
+
"spec/migration_helper.rb",
|
103
120
|
"spec/spec_helper.rb"
|
104
121
|
]
|
105
|
-
s.homepage =
|
106
|
-
s.licenses = [
|
107
|
-
s.require_paths = [
|
108
|
-
s.rubygems_version =
|
109
|
-
s.summary =
|
122
|
+
s.homepage = %q{http://github.com/kristianmandrup/cantango}
|
123
|
+
s.licenses = [%q{MIT}]
|
124
|
+
s.require_paths = [%q{lib}]
|
125
|
+
s.rubygems_version = %q{1.8.6}
|
126
|
+
s.summary = %q{CanCan extension with role oriented permission management and more}
|
110
127
|
|
111
128
|
if s.respond_to? :specification_version then
|
112
129
|
s.specification_version = 3
|
@@ -1,74 +1,30 @@
|
|
1
1
|
module CanTango
|
2
2
|
module Ability
|
3
3
|
class Base
|
4
|
-
autoload_modules :Callbacks
|
5
|
-
|
6
4
|
include CanCan::Ability
|
7
|
-
|
8
|
-
|
5
|
+
include CanTango::Ability::Rules
|
6
|
+
|
7
|
+
attr_reader :candidate, :options
|
9
8
|
|
10
9
|
# Equivalent to a CanCan Ability#initialize call
|
11
10
|
# which executes all the permission logic
|
12
11
|
def initialize candidate, options = {}
|
13
12
|
raise "Candidate must be something!" if !candidate
|
14
13
|
@candidate, @options = candidate, options
|
15
|
-
execute!
|
16
14
|
end
|
17
15
|
|
18
|
-
def execute
|
19
|
-
|
20
|
-
|
21
|
-
permit_rules
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
def within_callbacks &block
|
26
|
-
yield
|
27
|
-
end
|
28
|
-
|
29
|
-
# overriden by Engine helper
|
30
|
-
def engines_on?
|
31
|
-
false
|
32
|
-
end
|
33
|
-
|
34
|
-
def cached?
|
35
|
-
false
|
16
|
+
def execute
|
17
|
+
clear_rules!
|
18
|
+
calculate_rules
|
36
19
|
end
|
37
|
-
|
38
|
-
def rules
|
39
|
-
@rules
|
40
|
-
end
|
41
|
-
|
42
|
-
# developer can add rules here to be included in all subclasses!
|
43
|
-
def permit_rules
|
44
|
-
end
|
45
|
-
|
46
|
-
def clear_rules!
|
47
|
-
@rules ||= default_rules
|
48
|
-
end
|
49
|
-
|
20
|
+
|
50
21
|
def session
|
51
|
-
@session
|
52
|
-
end
|
53
|
-
|
54
|
-
# overriden by Masquerade helper
|
55
|
-
def subject
|
56
|
-
candidate
|
57
|
-
end
|
58
|
-
|
59
|
-
def config
|
60
|
-
CanTango.config
|
22
|
+
@session ||= options[:session] || {} # seperate session cache for each type of user?
|
61
23
|
end
|
62
24
|
|
63
25
|
# Helper.modules.each do |name|
|
64
26
|
# include "CanTango::Ability::Helper::#{name.to_s.camelize}".constantize
|
65
27
|
# end
|
66
|
-
|
67
|
-
protected
|
68
|
-
|
69
|
-
def default_rules
|
70
|
-
[]
|
71
|
-
end
|
72
28
|
end
|
73
29
|
end
|
74
30
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module CanTango::Ability
|
2
|
+
module Callbacks
|
3
|
+
include CanTango::Helpers::Debug
|
4
|
+
|
5
|
+
def self.included(base)
|
6
|
+
base.extend ClassMethods
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
[:after, :before].each do |type|
|
11
|
+
class_eval %{
|
12
|
+
def #{type}_execute_callbacks
|
13
|
+
@#{type}_execute_callbacks ||= []
|
14
|
+
end
|
15
|
+
|
16
|
+
def #{type}_execute *callbacks
|
17
|
+
@#{type}_execute_callbacks = callbacks.flatten
|
18
|
+
end
|
19
|
+
}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# should execute :after_execute callbacks
|
24
|
+
def handle_callbacks type
|
25
|
+
callbacks_method = "#{type}_execute_callbacks"
|
26
|
+
raise ArgumentError, "Not a valid callback type: #{type}" if !self.class.respond_to? callbacks_method
|
27
|
+
self.class.send(callbacks_method).each {|callback| send(callback) }
|
28
|
+
end
|
29
|
+
|
30
|
+
def within_callbacks &block
|
31
|
+
handle_callbacks :before
|
32
|
+
yield
|
33
|
+
handle_callbacks :after
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -1,53 +1,28 @@
|
|
1
|
-
module CanTango
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
include CanTango::Helpers::Debug
|
1
|
+
module CanTango::Ability::Executor
|
2
|
+
class Base
|
3
|
+
include CanTango::Ability::Executor
|
4
|
+
include CanTango::Ability::Callbacks
|
6
5
|
|
7
|
-
|
6
|
+
attr_reader :candidate, :modes, :options
|
8
7
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
clear_rules!
|
15
|
-
permit_rules
|
16
|
-
|
17
|
-
end_execute
|
18
|
-
rules # return rule set
|
19
|
-
end
|
20
|
-
|
21
|
-
def rules
|
22
|
-
@rules ||= []
|
23
|
-
end
|
24
|
-
|
25
|
-
def clear_rules!
|
26
|
-
@rules ||= []
|
27
|
-
end
|
28
|
-
|
29
|
-
def permit_rules
|
30
|
-
raise NotImplementedError
|
31
|
-
end
|
32
|
-
|
33
|
-
def cached?
|
34
|
-
false
|
35
|
-
end
|
36
|
-
|
37
|
-
protected
|
38
|
-
|
39
|
-
def start_execute
|
40
|
-
debug "Executing base Ability"
|
41
|
-
end
|
8
|
+
def initialize candidate, options = {}
|
9
|
+
raise ArgumentError, "Candidate must be something!" if !candidate
|
10
|
+
@candidate, @options = [candidate, options]
|
11
|
+
end
|
42
12
|
|
43
|
-
|
44
|
-
|
45
|
-
|
13
|
+
def rules
|
14
|
+
raise NotImplementedError
|
15
|
+
end
|
16
|
+
|
17
|
+
def calculate_rules
|
18
|
+
raise NotImplementedError
|
19
|
+
end
|
46
20
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
21
|
+
def self.inherited(base)
|
22
|
+
base.send :include, CanTango::Helpers::Debug
|
23
|
+
base.send :include, CanTango::Ability::Executor
|
24
|
+
base.send :include, CanTango::Ability::Rules
|
25
|
+
base.send :include, CanTango::Ability::Callbacks
|
51
26
|
end
|
52
27
|
end
|
53
28
|
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module CanTango::Ability::Executor
|
2
|
+
class Modal < Base
|
3
|
+
def initialize candidate, modes, options = {}
|
4
|
+
super candidate, options
|
5
|
+
modes = [modes].flatten if modes
|
6
|
+
raise ArgumentError, "Modes must be a list of modes to execute!" if modes.blank?
|
7
|
+
@modes = modes
|
8
|
+
end
|
9
|
+
|
10
|
+
def calculate_rules
|
11
|
+
@rules = modes.inject([]) do |result, mode|
|
12
|
+
result = result + modal_rules(mode)
|
13
|
+
result
|
14
|
+
end
|
15
|
+
normalize_rules!
|
16
|
+
end
|
17
|
+
|
18
|
+
def execute
|
19
|
+
clear_rules!
|
20
|
+
calculate_rules
|
21
|
+
return rules
|
22
|
+
rescue Exception => e
|
23
|
+
debug e.message
|
24
|
+
rules
|
25
|
+
end
|
26
|
+
|
27
|
+
def finder
|
28
|
+
@finder ||= CanTango::Ability::Mode::Finder.new self
|
29
|
+
end
|
30
|
+
|
31
|
+
protected
|
32
|
+
|
33
|
+
def modal_rules mode
|
34
|
+
puts "modal rules: #{mode}"
|
35
|
+
mode?(mode) ? executor(mode).execute : []
|
36
|
+
end
|
37
|
+
|
38
|
+
def executor mode
|
39
|
+
@executor ||= finder.executor_for(mode)
|
40
|
+
end
|
41
|
+
|
42
|
+
def mode? mode
|
43
|
+
modes.include?(mode)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -1,7 +1,30 @@
|
|
1
1
|
module CanTango
|
2
2
|
module Ability
|
3
3
|
module Executor
|
4
|
-
autoload_modules :Base, :
|
4
|
+
autoload_modules :Base, :Modal
|
5
|
+
|
6
|
+
include CanTango::Helpers::Debug
|
7
|
+
|
8
|
+
include CanTango::Ability::Rules
|
9
|
+
include CanTango::Ability::Callbacks
|
10
|
+
|
11
|
+
def self.included(base)
|
12
|
+
base.send :include, CanTango::Helpers::Debug
|
13
|
+
base.send :include, CanTango::Ability::Rules
|
14
|
+
base.send :include, CanTango::Ability::Callbacks
|
15
|
+
end
|
16
|
+
|
17
|
+
# the way to abort execution is to raise an exception!
|
18
|
+
def execute
|
19
|
+
within_callbacks do
|
20
|
+
clear_rules!
|
21
|
+
calculate_rules
|
22
|
+
end
|
23
|
+
return rules
|
24
|
+
rescue Exception => e
|
25
|
+
debug e.message
|
26
|
+
rules
|
27
|
+
end
|
5
28
|
end
|
6
29
|
end
|
7
30
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module CanTango
|
2
|
+
module Ability
|
3
|
+
module Mode
|
4
|
+
class InvalidError < StandardError; end
|
5
|
+
|
6
|
+
class Base
|
7
|
+
include CanTango::Ability::Executor
|
8
|
+
|
9
|
+
attr_reader :ability
|
10
|
+
|
11
|
+
delegate :session, :user, :subject, :candidate, :to => :ability
|
12
|
+
delegate :can, :cannot, :can?, :cannot?, :rules, :to => :ability
|
13
|
+
|
14
|
+
def initialize ability, options = {}
|
15
|
+
@ability, @options = [ability, options]
|
16
|
+
end
|
17
|
+
|
18
|
+
def within_callbacks
|
19
|
+
handle_callbacks :before
|
20
|
+
raise CanTango::Ability::Mode::InvalidError, "Not valid mode: #{self.class}" if !valid?
|
21
|
+
yield
|
22
|
+
handle_callbacks :after
|
23
|
+
rules
|
24
|
+
end
|
25
|
+
|
26
|
+
def valid?
|
27
|
+
true
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module CanTango::Ability::Mode
|
2
|
+
class Finder
|
3
|
+
attr_reader :executor
|
4
|
+
|
5
|
+
delegate :candidate, :options, :to => :executor
|
6
|
+
|
7
|
+
def initialize executor
|
8
|
+
@executor = executor
|
9
|
+
end
|
10
|
+
|
11
|
+
def executor_for mode
|
12
|
+
class_for(mode).new candidate, options
|
13
|
+
end
|
14
|
+
|
15
|
+
def class_for mode
|
16
|
+
"CanTango::Ability::Mode::#{mode.to_s.camelize}".constantize
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module CanTango::Ability
|
2
|
+
module Rules
|
3
|
+
def calculate_rules
|
4
|
+
rules
|
5
|
+
end
|
6
|
+
|
7
|
+
def normalize_rules!
|
8
|
+
rules.flatten!
|
9
|
+
rules.compact!
|
10
|
+
end
|
11
|
+
|
12
|
+
def rules
|
13
|
+
@rules ||= []
|
14
|
+
end
|
15
|
+
|
16
|
+
def clear_rules!
|
17
|
+
rules = default_rules
|
18
|
+
end
|
19
|
+
|
20
|
+
def default_rules
|
21
|
+
[]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/cantango/ability.rb
CHANGED
data/lib/cantango/adaptor.rb
CHANGED
@@ -1,36 +1,34 @@
|
|
1
1
|
module CanTango
|
2
|
-
module
|
3
|
-
|
4
|
-
|
5
|
-
autoload_modules :ActiveRecord, :DataMapper, :Mongoid, :MongoMapper
|
2
|
+
module Adaptor
|
3
|
+
autoload_modules :Generic, :Relational, :Mongo
|
4
|
+
autoload_modules :ActiveRecord, :DataMapper, :Mongoid, :MongoMapper
|
6
5
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
end
|
6
|
+
# include adaptor depending on which ORM the object inherits from or includes
|
7
|
+
def use_adaptor! base, object
|
8
|
+
orm_map.each_pair do |orm, const|
|
9
|
+
begin
|
10
|
+
base.class.send :include, get_adapter(object, const.constantize, orm)
|
11
|
+
rescue
|
12
|
+
next
|
15
13
|
end
|
16
14
|
end
|
15
|
+
end
|
17
16
|
|
18
|
-
|
19
|
-
|
20
|
-
|
17
|
+
def get_adapter object, adaptor_class, orm
|
18
|
+
object.kind_of?(adaptor_class) ? adaptor_for(orm) : adaptor_for(:generic)
|
19
|
+
end
|
21
20
|
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
def adaptor_for orm
|
22
|
+
"#{self.class}::#{orm.to_s.camelize}".constantize
|
23
|
+
end
|
25
24
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
end
|
25
|
+
def orm_map
|
26
|
+
{
|
27
|
+
:active_record => "ActiveRecord::Base",
|
28
|
+
:data_mapper => "DataMapper::Resource",
|
29
|
+
:mongoid => "Mongoid::Document",
|
30
|
+
:mongo_mapper => "MongoMapper::Document"
|
31
|
+
}
|
34
32
|
end
|
35
33
|
end
|
36
34
|
end
|