be9-acl9 0.9.1 → 0.9.2
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/CHANGELOG.textile +9 -0
- data/Manifest +14 -11
- data/README.textile +59 -22
- data/acl9.gemspec +4 -4
- data/lib/acl9/controller_extensions.rb +37 -13
- data/lib/acl9/controller_extensions/dsl_base.rb +212 -0
- data/lib/acl9/controller_extensions/generators.rb +119 -0
- data/lib/acl9/version.rb +1 -1
- data/spec/access_control_spec.rb +87 -13
- data/spec/dsl_base_spec.rb +703 -0
- data/spec/roles_spec.rb +1 -0
- metadata +22 -18
- data/lib/acl9/controller_extensions/filter_producer.rb +0 -244
- data/spec/filter_producer_spec.rb +0 -707
data/CHANGELOG.textile
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
h2. 0.9.2 (11-Jan-2009)
|
2
|
+
|
3
|
+
* @access_control :method do end@ as shorter form for @access_control :as_method => :method do end@.
|
4
|
+
* Boolean method can now receive an objects hash which will be looked into first before taking
|
5
|
+
an instance variable.
|
6
|
+
|
7
|
+
h2. 0.9.1 (03-Jan-2009)
|
8
|
+
|
9
|
+
Initial release.
|
data/Manifest
CHANGED
@@ -1,19 +1,22 @@
|
|
1
|
-
|
1
|
+
init.rb
|
2
|
+
Manifest
|
3
|
+
lib/acl9/model_extensions.rb
|
4
|
+
lib/acl9/version.rb
|
2
5
|
lib/acl9/model_extensions/subject.rb
|
3
6
|
lib/acl9/model_extensions/object.rb
|
7
|
+
lib/acl9/controller_extensions/generators.rb
|
8
|
+
lib/acl9/controller_extensions/dsl_base.rb
|
9
|
+
lib/acl9/config.rb
|
4
10
|
lib/acl9/controller_extensions.rb
|
5
|
-
lib/acl9/controller_extensions/filter_producer.rb
|
6
|
-
lib/acl9/version.rb
|
7
|
-
lib/acl9/model_extensions.rb
|
8
11
|
lib/acl9.rb
|
12
|
+
README.textile
|
13
|
+
acl9.gemspec
|
14
|
+
CHANGELOG.textile
|
15
|
+
MIT-LICENSE
|
16
|
+
Rakefile
|
9
17
|
spec/db/schema.rb
|
10
|
-
spec/
|
18
|
+
spec/dsl_base_spec.rb
|
11
19
|
spec/spec_helper.rb
|
12
|
-
spec/models.rb
|
13
20
|
spec/access_control_spec.rb
|
14
21
|
spec/roles_spec.rb
|
15
|
-
|
16
|
-
MIT-LICENSE
|
17
|
-
Rakefile
|
18
|
-
README.textile
|
19
|
-
init.rb
|
22
|
+
spec/models.rb
|
data/README.textile
CHANGED
@@ -45,7 +45,7 @@ Acl9 can be installed as a gem from "GitHub":http://github.com.
|
|
45
45
|
Add the following line to your @config/environment.rb@:
|
46
46
|
|
47
47
|
<pre><code>
|
48
|
-
config.gem "be9-acl9", :source => "http://gems.github.com"
|
48
|
+
config.gem "be9-acl9", :source => "http://gems.github.com", :lib => "acl9"
|
49
49
|
</pre></code>
|
50
50
|
|
51
51
|
Then run @rake gems:install@ (with possible @rake gems:unpack@ thereafter) and you're done!
|
@@ -118,7 +118,7 @@ Role control subsystem has been lifted from
|
|
118
118
|
but undergone some modifications.
|
119
119
|
|
120
120
|
It's based on two tables in the database. First, role table, which stores pairs @[role_name, object]@
|
121
|
-
where object is a polymorphic
|
121
|
+
where object is a polymorphic model instance or a class. Second, join table, which joins users and roles.
|
122
122
|
|
123
123
|
To use this subsystem, you should define a @Role@ model.
|
124
124
|
|
@@ -142,7 +142,7 @@ The structure of @roles@ table is as follows:
|
|
142
142
|
end
|
143
143
|
</code></pre>
|
144
144
|
|
145
|
-
Note that you will never use the @Role@ class directly.
|
145
|
+
Note that you will almost never use the @Role@ class directly.
|
146
146
|
|
147
147
|
h2. Subject model
|
148
148
|
|
@@ -333,7 +333,7 @@ In other words, you are _manager_ if you manage at least one @foo@ (or a @bar@..
|
|
333
333
|
user.has_role? :manager # => true
|
334
334
|
</code></pre>
|
335
335
|
|
336
|
-
Our @user@ is no more manager of @foo@, but
|
336
|
+
Our @user@ is no more manager of @foo@, but has become a manager of @bar@.
|
337
337
|
|
338
338
|
<pre><code>
|
339
339
|
user.has_no_roles!
|
@@ -343,7 +343,7 @@ Our @user@ is no more manager of @foo@, but is now a manager of @bar@.
|
|
343
343
|
user.roles # => []
|
344
344
|
</code></pre>
|
345
345
|
|
346
|
-
|
346
|
+
At this time @user@ has no roles in the system.
|
347
347
|
|
348
348
|
h2. Coming up with your own role implementation
|
349
349
|
|
@@ -381,7 +381,7 @@ from unauthorized access. Acl9 provides a nice DSL for writing access rules.
|
|
381
381
|
|
382
382
|
h2. Allow and deny
|
383
383
|
|
384
|
-
Access control is mostly about allowing and denying. So there two
|
384
|
+
Access control is mostly about allowing and denying. So there are two
|
385
385
|
basic methods: @allow@ and @deny@. They have the same syntax:
|
386
386
|
|
387
387
|
<pre><code>
|
@@ -397,8 +397,8 @@ ROLE_LIST is a list of roles (at least 1 role should be there). So,
|
|
397
397
|
allow :manager, :admin
|
398
398
|
deny :banned
|
399
399
|
</code></pre>
|
400
|
-
will match holders of global role _manager_ *and* holders of global role _admin_ as allowed
|
401
|
-
_banned_ as denied.
|
400
|
+
will match holders of global role _manager_ *and* holders of global role _admin_ as allowed.
|
401
|
+
On the contrary, holders of _banned_ role will match as denied.
|
402
402
|
|
403
403
|
Basically this snippet is equivalent to
|
404
404
|
|
@@ -407,13 +407,13 @@ Basically this snippet is equivalent to
|
|
407
407
|
allow :admin
|
408
408
|
deny :banned
|
409
409
|
</code></pre>
|
410
|
-
which means that roles in argument list
|
410
|
+
which means that roles in argument list are OR'ed for a match, and not AND'ed.
|
411
411
|
|
412
412
|
Also note that:
|
413
413
|
* You may use both strings and :symbols to specify roles (the latter get converted into strings).
|
414
414
|
* Role names are singularized before check.
|
415
415
|
|
416
|
-
|
416
|
+
Thus the snippet above can also be written as
|
417
417
|
|
418
418
|
<pre><code>
|
419
419
|
allow :managers, :admins
|
@@ -440,7 +440,7 @@ use object and class roles in the ACL block.
|
|
440
440
|
deny :hated, :by => :us
|
441
441
|
</code></pre>
|
442
442
|
|
443
|
-
|
443
|
+
To specify an object you use one of the 6 preposition options:
|
444
444
|
* :of
|
445
445
|
* :at
|
446
446
|
* :on
|
@@ -482,8 +482,6 @@ Checking against an instance variable has sense when you have another _before fi
|
|
482
482
|
end
|
483
483
|
</code></pre>
|
484
484
|
|
485
|
-
|
486
|
-
|
487
485
|
Note that the object option is applied to all of the roles you specify in the argument list.
|
488
486
|
As such,
|
489
487
|
|
@@ -589,7 +587,7 @@ Same result as a table:
|
|
589
587
|
| None of the @allow@ rules matched, some of the @deny@ rules matched. | Access is denied. | Access is denied. |
|
590
588
|
| Some of the @allow@ rules matched, some of the @deny@ rules matched. | Access is allowed. | Access is denied. |
|
591
589
|
|
592
|
-
Apparently _default deny_ mode is
|
590
|
+
Apparently _default deny_ mode is more strict, and that's because it's on by default.
|
593
591
|
|
594
592
|
h2. Actions block
|
595
593
|
|
@@ -644,11 +642,12 @@ By calling @access_control@ in your controller you can get your ACL block transl
|
|
644
642
|
First case is by default. You can catch the exception with @rescue_from@ call and do something
|
645
643
|
you like: make a redirect, or render "Access denied" template, or whatever.
|
646
644
|
|
647
|
-
Second case is obtained with
|
648
|
-
|
645
|
+
Second case is obtained with specifying method name as an argument to
|
646
|
+
@access_control@ (or using @:as_method@ option, see below) and may be helpful
|
647
|
+
if you want to use @skip_before_filter@ somewhere in the derived controller.
|
649
648
|
|
650
|
-
Third case will take place if you
|
651
|
-
method which you can call anywhere you want.
|
649
|
+
Third case will take place if you supply @:filter => false@ along with method
|
650
|
+
name. You'll get an ordinary method which you can call anywhere you want.
|
652
651
|
|
653
652
|
h3. :subject_method
|
654
653
|
|
@@ -694,14 +693,30 @@ In the case
|
|
694
693
|
|
695
694
|
access control checks will be added as @acl@ method onto MyController, with @before_filter :acl@ call thereafter.
|
696
695
|
|
696
|
+
Instead of using @:as_method@ you may specify the name of the method as a positional argument
|
697
|
+
to @access_control@:
|
698
|
+
|
699
|
+
<pre><code>
|
700
|
+
class MyController < ApplicationController
|
701
|
+
access_control :acl do
|
702
|
+
# ...
|
703
|
+
end
|
704
|
+
|
705
|
+
# ...
|
706
|
+
end
|
707
|
+
</code></pre>
|
708
|
+
|
709
|
+
|
697
710
|
h3. :filter
|
698
711
|
|
699
|
-
If you set @:filter@ to @false@ (it's @true@ by default) and also use
|
700
|
-
|
712
|
+
If you set @:filter@ to @false@ (it's @true@ by default) and also use
|
713
|
+
@:as_method@ (or method name as 1st argument to @access_control@, you'll get a
|
714
|
+
method which won't raise @Acl9::AccessDenied@ exception, but rather return
|
715
|
+
@true@ or @false@ (access allowed/denied).
|
701
716
|
|
702
717
|
<pre><code>
|
703
718
|
class SecretController < ApplicationController
|
704
|
-
access_control :
|
719
|
+
access_control :secret_access?, :filter => false do
|
705
720
|
allow :james_bond
|
706
721
|
# ...
|
707
722
|
end
|
@@ -728,6 +743,26 @@ which won't raise @Acl9::AccessDenied@ exception, but rather return @true@ or @f
|
|
728
743
|
end
|
729
744
|
</code></pre>
|
730
745
|
|
746
|
+
The generated method can receive an objects hash as an argument. In this example,
|
747
|
+
|
748
|
+
<pre><code>
|
749
|
+
class LolController < ApplicationController
|
750
|
+
access_control :lolcats?, :filter => false do
|
751
|
+
allow :cats, :by => :lol
|
752
|
+
# ...
|
753
|
+
end
|
754
|
+
end
|
755
|
+
</code></pre>
|
756
|
+
|
757
|
+
you may not only call @lolcats?@ with no arguments, which will basically return
|
758
|
+
|
759
|
+
<pre><code>
|
760
|
+
current_user.has_role?('cats', @lol)
|
761
|
+
</code></pre>
|
762
|
+
|
763
|
+
but also as @lolcats?(:lol => Lol.find(params[:lol]))@. The hash will be looked into first,
|
764
|
+
even if you have an instance variable @lol@.
|
765
|
+
|
731
766
|
h3. Other options
|
732
767
|
|
733
768
|
Other options will be passed to @before_filter@. As such, you may use @:only@ and @:except@ to narrow
|
@@ -762,4 +797,6 @@ is basically equivalent to
|
|
762
797
|
</code></pre>
|
763
798
|
|
764
799
|
|
765
|
-
Copyright (c) 2009 Oleg Dashevskii, released under the MIT license
|
800
|
+
Copyright (c) 2009 Oleg Dashevskii, released under the MIT license.
|
801
|
+
|
802
|
+
Contact me at "#{%w(Oleg Dashevskii).join('').downcase}@gmail.com"
|
data/acl9.gemspec
CHANGED
@@ -2,15 +2,15 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{acl9}
|
5
|
-
s.version = "0.9.
|
5
|
+
s.version = "0.9.2"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Oleg Dashevskii"]
|
9
|
-
s.date = %q{2009-01-
|
9
|
+
s.date = %q{2009-01-14}
|
10
10
|
s.description = %q{Yet another role-based authorization system for Rails with a nice DSL for access control lists.}
|
11
11
|
s.email = %q{olegdashevskii@gmail.com}
|
12
|
-
s.extra_rdoc_files = ["lib/acl9/
|
13
|
-
s.files = ["lib/acl9/
|
12
|
+
s.extra_rdoc_files = ["lib/acl9/model_extensions.rb", "lib/acl9/version.rb", "lib/acl9/model_extensions/subject.rb", "lib/acl9/model_extensions/object.rb", "lib/acl9/controller_extensions/generators.rb", "lib/acl9/controller_extensions/dsl_base.rb", "lib/acl9/config.rb", "lib/acl9/controller_extensions.rb", "lib/acl9.rb", "README.textile", "CHANGELOG.textile"]
|
13
|
+
s.files = ["init.rb", "Manifest", "lib/acl9/model_extensions.rb", "lib/acl9/version.rb", "lib/acl9/model_extensions/subject.rb", "lib/acl9/model_extensions/object.rb", "lib/acl9/controller_extensions/generators.rb", "lib/acl9/controller_extensions/dsl_base.rb", "lib/acl9/config.rb", "lib/acl9/controller_extensions.rb", "lib/acl9.rb", "README.textile", "acl9.gemspec", "CHANGELOG.textile", "MIT-LICENSE", "Rakefile", "spec/db/schema.rb", "spec/dsl_base_spec.rb", "spec/spec_helper.rb", "spec/access_control_spec.rb", "spec/roles_spec.rb", "spec/models.rb"]
|
14
14
|
s.has_rdoc = true
|
15
15
|
s.homepage = %q{http://github.com/be9/acl9}
|
16
16
|
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Acl9", "--main", "README.textile"]
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), 'controller_extensions', '
|
1
|
+
require File.join(File.dirname(__FILE__), 'controller_extensions', 'generators')
|
2
2
|
|
3
3
|
module Acl9
|
4
4
|
module ControllerExtensions
|
@@ -7,30 +7,54 @@ module Acl9
|
|
7
7
|
end
|
8
8
|
|
9
9
|
module ClassMethods
|
10
|
-
def access_control(
|
10
|
+
def access_control(*args, &block)
|
11
|
+
opts = if args.last.is_a? Hash
|
12
|
+
args.pop
|
13
|
+
else
|
14
|
+
{}
|
15
|
+
end
|
16
|
+
|
17
|
+
case args.size
|
18
|
+
when 0 then true
|
19
|
+
when 1
|
20
|
+
meth = args.first
|
21
|
+
|
22
|
+
if meth.is_a? Symbol
|
23
|
+
opts[:as_method] = meth
|
24
|
+
else
|
25
|
+
raise ArgumentError, "access control argument must be a :symbol!"
|
26
|
+
end
|
27
|
+
else
|
28
|
+
raise ArgumentError, "Invalid arguments for access_control"
|
29
|
+
end
|
30
|
+
|
11
31
|
subject_method = opts.delete(:subject_method) || Acl9::config[:default_subject_method]
|
12
32
|
|
13
33
|
raise ArgumentError, "Block must be supplied to access_control" unless block
|
14
34
|
|
15
|
-
producer = Acl9::FilterProducer.new(subject_method)
|
16
|
-
producer.acl(&block)
|
17
|
-
|
18
35
|
filter = opts.delete(:filter)
|
19
36
|
filter = true if filter.nil?
|
20
37
|
|
38
|
+
method = opts.delete(:as_method)
|
39
|
+
|
40
|
+
generator = case
|
41
|
+
when method && filter
|
42
|
+
Acl9::Dsl::Generators::FilterMethod.new(subject_method, method)
|
43
|
+
when method && !filter
|
44
|
+
Acl9::Dsl::Generators::BooleanMethod.new(subject_method, method)
|
45
|
+
else
|
46
|
+
Acl9::Dsl::Generators::FilterLambda.new(subject_method)
|
47
|
+
end
|
48
|
+
|
49
|
+
generator.acl_block!(&block)
|
50
|
+
|
21
51
|
if opts.delete(:debug)
|
22
52
|
Rails::logger.debug "=== Acl9 access_control expression dump (#{self.to_s})"
|
23
|
-
Rails::logger.debug
|
53
|
+
Rails::logger.debug generator.to_s
|
24
54
|
Rails::logger.debug "======"
|
25
55
|
end
|
26
56
|
|
27
|
-
|
28
|
-
class_eval producer.to_method_code(method, filter)
|
29
|
-
|
30
|
-
before_filter(method, opts) if filter
|
31
|
-
else
|
32
|
-
before_filter(opts, &producer.to_proc)
|
33
|
-
end
|
57
|
+
generator.install_on(self, opts)
|
34
58
|
end
|
35
59
|
end
|
36
60
|
end
|
@@ -0,0 +1,212 @@
|
|
1
|
+
module Acl9
|
2
|
+
module Dsl
|
3
|
+
class Base
|
4
|
+
attr_reader :allows, :denys
|
5
|
+
|
6
|
+
def initialize(*args)
|
7
|
+
@default_action = nil
|
8
|
+
|
9
|
+
@allows = []
|
10
|
+
@denys = []
|
11
|
+
|
12
|
+
@original_args = args
|
13
|
+
end
|
14
|
+
|
15
|
+
def acl_block!(&acl_block)
|
16
|
+
self.instance_eval(&acl_block)
|
17
|
+
end
|
18
|
+
|
19
|
+
def default_action
|
20
|
+
@default_action.nil? ? :deny : @default_action
|
21
|
+
end
|
22
|
+
|
23
|
+
def allowance_expression
|
24
|
+
allowed_expr = if @allows.size > 0
|
25
|
+
@allows.map { |clause| "(#{clause})" }.join(' || ')
|
26
|
+
else
|
27
|
+
"false"
|
28
|
+
end
|
29
|
+
|
30
|
+
not_denied_expr = if @denys.size > 0
|
31
|
+
@denys.map { |clause| "!(#{clause})" }.join(' && ')
|
32
|
+
else
|
33
|
+
"true"
|
34
|
+
end
|
35
|
+
|
36
|
+
[allowed_expr, not_denied_expr].
|
37
|
+
map { |expr| "(#{expr})" }.
|
38
|
+
join(default_action == :deny ? ' && ' : ' || ')
|
39
|
+
end
|
40
|
+
|
41
|
+
alias to_s allowance_expression
|
42
|
+
|
43
|
+
protected
|
44
|
+
|
45
|
+
def default(default_action)
|
46
|
+
raise ArgumentError, "default can only be called once in access_control block" if @default_action
|
47
|
+
|
48
|
+
unless [:allow, :deny].include? default_action
|
49
|
+
raise ArgumentError, "invalid value for default (can be :allow or :deny)"
|
50
|
+
end
|
51
|
+
|
52
|
+
@default_action = default_action
|
53
|
+
end
|
54
|
+
|
55
|
+
def allow(*args)
|
56
|
+
@current_rule = :allow
|
57
|
+
_parse_and_add_rule(*args)
|
58
|
+
end
|
59
|
+
|
60
|
+
def deny(*args)
|
61
|
+
@current_rule = :deny
|
62
|
+
_parse_and_add_rule(*args)
|
63
|
+
end
|
64
|
+
|
65
|
+
def actions(*args, &block)
|
66
|
+
raise ArgumentError, "actions should receive at least 1 action as argument" if args.size < 1
|
67
|
+
|
68
|
+
subsidiary = self.class.new(*@original_args)
|
69
|
+
|
70
|
+
class <<subsidiary
|
71
|
+
def actions(*args)
|
72
|
+
raise ArgumentError, "You cannot use actions inside another actions block"
|
73
|
+
end
|
74
|
+
|
75
|
+
def default(*args)
|
76
|
+
raise ArgumentError, "You cannot use default inside an actions block"
|
77
|
+
end
|
78
|
+
|
79
|
+
def _set_action_clause(to, except)
|
80
|
+
raise ArgumentError, "You cannot use :to/:except inside actions block" if to || except
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
subsidiary.acl_block!(&block)
|
85
|
+
|
86
|
+
action_check = _action_check_expression(args)
|
87
|
+
|
88
|
+
squash = lambda do |rules|
|
89
|
+
_either_of(rules) + ' && ' + action_check
|
90
|
+
end
|
91
|
+
|
92
|
+
@allows << squash.call(subsidiary.allows) if subsidiary.allows.size > 0
|
93
|
+
@denys << squash.call(subsidiary.denys) if subsidiary.denys.size > 0
|
94
|
+
end
|
95
|
+
|
96
|
+
alias action actions
|
97
|
+
|
98
|
+
def anonymous; nil end
|
99
|
+
def all; true end
|
100
|
+
def logged_in; false end
|
101
|
+
|
102
|
+
def _parse_and_add_rule(*args)
|
103
|
+
options = if args.last.is_a? Hash
|
104
|
+
args.pop
|
105
|
+
else
|
106
|
+
{}
|
107
|
+
end
|
108
|
+
|
109
|
+
_set_action_clause(options.delete(:to), options.delete(:except))
|
110
|
+
|
111
|
+
object = _role_object(options)
|
112
|
+
|
113
|
+
role_checks = args.map do |who|
|
114
|
+
case who
|
115
|
+
when nil then "#{_subject_ref}.nil?" # anonymous
|
116
|
+
when false then "!#{_subject_ref}.nil?" # logged_in
|
117
|
+
when true then "true" # all
|
118
|
+
else
|
119
|
+
"!#{_subject_ref}.nil? && #{_subject_ref}.has_role?('#{who.to_s.singularize}', #{object})"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
_add_rule case role_checks.size
|
124
|
+
when 0
|
125
|
+
raise ArgumentError, "allow/deny should have at least 1 argument"
|
126
|
+
when 1 then role_checks.first
|
127
|
+
else
|
128
|
+
_either_of(role_checks)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def _either_of(exprs)
|
133
|
+
exprs.map { |expr| "(#{expr})" }.join(' || ')
|
134
|
+
end
|
135
|
+
|
136
|
+
def _add_rule(what)
|
137
|
+
what = "(#{what}) && #{@action_clause}" if @action_clause
|
138
|
+
|
139
|
+
(@current_rule == :allow ? @allows : @denys) << what
|
140
|
+
end
|
141
|
+
|
142
|
+
def _set_action_clause(to, except)
|
143
|
+
raise ArgumentError, "both :to and :except cannot be specified in the rule" if to && except
|
144
|
+
|
145
|
+
@action_clause = nil
|
146
|
+
|
147
|
+
action_list = to || except
|
148
|
+
return unless action_list
|
149
|
+
|
150
|
+
expr = _action_check_expression(action_list)
|
151
|
+
|
152
|
+
@action_clause = if to
|
153
|
+
"#{expr}"
|
154
|
+
else
|
155
|
+
"!#{expr}"
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def _action_check_expression(action_list)
|
160
|
+
unless action_list.is_a?(Array)
|
161
|
+
action_list = [ action_list.to_s ]
|
162
|
+
end
|
163
|
+
|
164
|
+
case action_list.size
|
165
|
+
when 0 then "true"
|
166
|
+
when 1 then "(#{_action_ref} == '#{action_list.first}')"
|
167
|
+
else
|
168
|
+
set_of_actions = "Set.new([" + action_list.map { |act| "'#{act}'"}.join(',') + "])"
|
169
|
+
|
170
|
+
"#{set_of_actions}.include?(#{_action_ref})"
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
VALID_PREPOSITIONS = %w(of for in on at by).freeze unless defined? VALID_PREPOSITIONS
|
175
|
+
|
176
|
+
def _role_object(options)
|
177
|
+
object = nil
|
178
|
+
|
179
|
+
VALID_PREPOSITIONS.each do |prep|
|
180
|
+
if options[prep.to_sym]
|
181
|
+
raise ArgumentError, "You may only use one preposition to specify object" if object
|
182
|
+
|
183
|
+
object = options[prep.to_sym]
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
case object
|
188
|
+
when Class
|
189
|
+
object.to_s
|
190
|
+
when Symbol
|
191
|
+
_object_ref object
|
192
|
+
when nil
|
193
|
+
"nil"
|
194
|
+
else
|
195
|
+
raise ArgumentError, "object specified by preposition can only be a Class or a Symbol"
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
def _subject_ref
|
200
|
+
raise
|
201
|
+
end
|
202
|
+
|
203
|
+
def _object_ref(object)
|
204
|
+
raise
|
205
|
+
end
|
206
|
+
|
207
|
+
def _action_ref
|
208
|
+
raise
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|