cantango-core 0.1.3 → 0.1.4
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/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
|