roleful 0.0.2 → 0.0.3
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/lib/core_ext/array.rb +5 -0
- data/lib/core_ext/object.rb +21 -0
- data/lib/roleful.rb +12 -4
- data/lib/roleful/inclusion.rb +7 -4
- data/lib/roleful/role.rb +24 -17
- metadata +5 -12
@@ -0,0 +1,21 @@
|
|
1
|
+
# http://eigenclass.org/hiki/bounded+space+instance_exec
|
2
|
+
class Object
|
3
|
+
module InstanceExecHelper; end
|
4
|
+
include InstanceExecHelper
|
5
|
+
def instance_exec(*args, &block)
|
6
|
+
begin
|
7
|
+
old_critical, Thread.critical = Thread.critical, true
|
8
|
+
n = 0
|
9
|
+
n += 1 while respond_to?(mname="__instance_exec#{n}")
|
10
|
+
InstanceExecHelper.module_eval{ define_method(mname, &block) }
|
11
|
+
ensure
|
12
|
+
Thread.critical = old_critical
|
13
|
+
end
|
14
|
+
begin
|
15
|
+
ret = send(mname, *args)
|
16
|
+
ensure
|
17
|
+
InstanceExecHelper.module_eval{ remove_method(mname) } rescue nil
|
18
|
+
end
|
19
|
+
ret
|
20
|
+
end
|
21
|
+
end
|
data/lib/roleful.rb
CHANGED
@@ -1,11 +1,19 @@
|
|
1
1
|
$LOAD_PATH << File.dirname(__FILE__) + '/roleful'
|
2
|
+
$LOAD_PATH << File.dirname(__FILE__) + '/core_ext'
|
2
3
|
|
3
|
-
|
4
|
-
require '
|
5
|
-
require '
|
4
|
+
# Core extensions
|
5
|
+
require 'object' unless respond_to?(:instance_exec)
|
6
|
+
require 'array' unless [].respond_to?(:extract_options!)
|
7
|
+
|
8
|
+
# Project files
|
6
9
|
require 'role'
|
7
10
|
require 'inclusion'
|
8
11
|
|
12
|
+
# Other libraries
|
13
|
+
require 'rubygems'
|
14
|
+
require 'metaid'
|
15
|
+
require 'set'
|
16
|
+
|
9
17
|
module Roleful
|
10
|
-
VERSION = '0.0.
|
18
|
+
VERSION = '0.0.3'
|
11
19
|
end
|
data/lib/roleful/inclusion.rb
CHANGED
@@ -10,10 +10,12 @@ module Roleful
|
|
10
10
|
end
|
11
11
|
|
12
12
|
module InstanceMethods
|
13
|
+
# Gives an object temporary roles for the duration of the block.
|
13
14
|
def with_role(*tmp_roles)
|
14
|
-
|
15
|
+
old_role = method(:role)
|
16
|
+
meta_def(:role) { tmp_roles }
|
15
17
|
result = yield
|
16
|
-
meta_eval {
|
18
|
+
meta_eval { define_method(:role, old_role) }
|
17
19
|
result
|
18
20
|
end
|
19
21
|
|
@@ -44,9 +46,10 @@ module Roleful
|
|
44
46
|
roles.each { |name| define_role(name.to_sym, options, &block) }
|
45
47
|
end
|
46
48
|
|
47
|
-
#
|
49
|
+
# Delegates method calls to the object's #role_proxy, accounting for
|
50
|
+
# cases when there are multiple roles for the given object.
|
48
51
|
def delegate_permission(*methods)
|
49
|
-
options = methods.pop
|
52
|
+
options = methods.pop
|
50
53
|
raise ArgumentError, "Delegation needs a target." unless options.is_a?(Hash) && to = options[:to]
|
51
54
|
|
52
55
|
methods.each do |method|
|
data/lib/roleful/role.rb
CHANGED
@@ -9,22 +9,20 @@ module Roleful
|
|
9
9
|
define_predicates
|
10
10
|
end
|
11
11
|
|
12
|
-
def can(
|
13
|
-
|
12
|
+
def can(sym, &block)
|
13
|
+
handlers[sym] = block || proc { true }
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
def can?(target, permission, *args)
|
23
|
-
superuser? ?
|
24
|
-
@klass::PERMISSIONS.include?(permission) :
|
25
|
-
handle(target, permission, *args)
|
15
|
+
metaclass.class_eval(<<-END, __FILE__, __LINE__)
|
16
|
+
def can_#{sym}?(target, *args)
|
17
|
+
handle(target, #{sym.inspect}, *args)
|
18
|
+
end
|
19
|
+
END
|
20
|
+
|
21
|
+
register_permission(sym)
|
26
22
|
end
|
27
23
|
|
24
|
+
# Used when the permission in question is granted for the
|
25
|
+
# role in question. TODO: Is this really necessary?
|
28
26
|
def method_missing(sym, *args)
|
29
27
|
method_id = sym.to_s
|
30
28
|
match_permission_or_predicate?(method_id) ? superuser? : super
|
@@ -32,6 +30,12 @@ module Roleful
|
|
32
30
|
|
33
31
|
private
|
34
32
|
|
33
|
+
def can?(target, permission, *args)
|
34
|
+
superuser? ?
|
35
|
+
@klass::PERMISSIONS.include?(permission) :
|
36
|
+
handle(target, permission, *args)
|
37
|
+
end
|
38
|
+
|
35
39
|
def handle(target, permission, *args)
|
36
40
|
return false if handlers[permission].nil?
|
37
41
|
target.instance_exec(*args, &handlers[permission])
|
@@ -41,10 +45,12 @@ module Roleful
|
|
41
45
|
options[:superuser] || false # returns false, not nil
|
42
46
|
end
|
43
47
|
|
48
|
+
# TODO memoize the generated regex
|
44
49
|
def permission?(method)
|
45
50
|
method.match(/can_(#{@klass::PERMISSIONS.to_a.join('|')})+\?/)
|
46
51
|
end
|
47
52
|
|
53
|
+
# TODO memoize the generated regex
|
48
54
|
def predicate?(method)
|
49
55
|
method.match(/(#{@klass::ROLES.keys.join('|')})\?/)
|
50
56
|
end
|
@@ -55,17 +61,18 @@ module Roleful
|
|
55
61
|
|
56
62
|
def define_predicates
|
57
63
|
meta_def("#{name}?") { true }
|
58
|
-
|
59
|
-
|
64
|
+
delegate_predicate("#{name}?")
|
65
|
+
delegate_predicate("can?")
|
60
66
|
end
|
61
67
|
|
62
|
-
def
|
68
|
+
def register_permission(permission)
|
63
69
|
permission = permission.to_sym
|
64
70
|
@permissions.add(permission)
|
65
71
|
@klass::PERMISSIONS.merge(@permissions)
|
72
|
+
delegate_predicate("can_#{permission}?")
|
66
73
|
end
|
67
74
|
|
68
|
-
def
|
75
|
+
def delegate_predicate(name)
|
69
76
|
@klass.delegate_permission name, :to => :role_proxy
|
70
77
|
end
|
71
78
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: roleful
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pat Nakajima
|
@@ -22,16 +22,6 @@ dependencies:
|
|
22
22
|
- !ruby/object:Gem::Version
|
23
23
|
version: "0"
|
24
24
|
version:
|
25
|
-
- !ruby/object:Gem::Dependency
|
26
|
-
name: nakajima-nakajima
|
27
|
-
type: :runtime
|
28
|
-
version_requirement:
|
29
|
-
version_requirements: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: "0"
|
34
|
-
version:
|
35
25
|
description:
|
36
26
|
email: patnakajima@gmail.com
|
37
27
|
executables: []
|
@@ -41,6 +31,9 @@ extensions: []
|
|
41
31
|
extra_rdoc_files: []
|
42
32
|
|
43
33
|
files:
|
34
|
+
- lib/core_ext
|
35
|
+
- lib/core_ext/array.rb
|
36
|
+
- lib/core_ext/object.rb
|
44
37
|
- lib/roleful
|
45
38
|
- lib/roleful/inclusion.rb
|
46
39
|
- lib/roleful/role.rb
|
@@ -67,7 +60,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
67
60
|
requirements: []
|
68
61
|
|
69
62
|
rubyforge_project:
|
70
|
-
rubygems_version: 1.3.
|
63
|
+
rubygems_version: 1.3.1
|
71
64
|
signing_key:
|
72
65
|
specification_version: 2
|
73
66
|
summary: Generic roles for you and your objects
|