stonewall 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/lib/rails/active_record.rb +14 -0
- data/lib/stonewall/access_controller.rb +32 -3
- data/lib/stonewall/helpers.rb +30 -4
- data/lib/stonewall/parser.rb +20 -23
- data/lib/stonewall/user_extensions.rb +0 -11
- data/lib/stonewall.rb +2 -1
- metadata +3 -2
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0
|
1
|
+
0.1.0
|
@@ -0,0 +1,14 @@
|
|
1
|
+
ActiveRecord::Base.class_eval do
|
2
|
+
|
3
|
+
def method_missing_with_stonewall(symb, *args)
|
4
|
+
method_name = symb.to_s
|
5
|
+
if method_name =~ /^may_(.+?)[\!\?]$/
|
6
|
+
args.first.class.stonewall.actions[$1.to_sym].call(args.first, self)
|
7
|
+
else
|
8
|
+
method_missing_without_stonewall(symb, *args)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
alias_method_chain :method_missing, :stonewall
|
13
|
+
|
14
|
+
end
|
@@ -7,7 +7,7 @@ module StoneWall
|
|
7
7
|
attr_reader :guarded_class
|
8
8
|
attr_reader :variant_field
|
9
9
|
attr_accessor :actions
|
10
|
-
|
10
|
+
attr_reader :guarded_methods
|
11
11
|
attr_accessor :method_groups
|
12
12
|
|
13
13
|
# the matrix is the money-shot of the access controller. You can set it
|
@@ -42,6 +42,14 @@ module StoneWall
|
|
42
42
|
matrix[r] && matrix[r][v] && matrix[r][v].include?(m)
|
43
43
|
end
|
44
44
|
|
45
|
+
# This is similar to, but not the same as, the guard method on the parser.
|
46
|
+
# The parser has to wait until the methods are reified. Since this is
|
47
|
+
# got adding guards at runtime, we don't have that restruction here.
|
48
|
+
def guard(method)
|
49
|
+
StoneWall::Helpers.guard(@guarded_class, method)
|
50
|
+
StoneWall::Helpers.fix_alias_for(@guarded_class, method)
|
51
|
+
end
|
52
|
+
|
45
53
|
# --------------
|
46
54
|
# This is 1/3rd of the magic in this gem. Every method you guard is
|
47
55
|
# checked by this method. It looks at the matrix of permissions you built
|
@@ -49,10 +57,31 @@ module StoneWall
|
|
49
57
|
# and the method being accessed. #should we fail secure?
|
50
58
|
def allowed?(guarded_object, user, method)
|
51
59
|
return true if (guarded_object.nil? || user.nil? || method.nil?)
|
52
|
-
|
60
|
+
return true unless @guarded_methods.include?(method)
|
61
|
+
|
62
|
+
# if they can always view it, no need to check variant.
|
63
|
+
always = user.stonepath_role_info.detect do |r|
|
64
|
+
granted?(r, :all, :all) || granted?(r, :all, method)
|
65
|
+
end
|
66
|
+
return always if always
|
67
|
+
|
68
|
+
v = guarded_object.send(variant_field) &&
|
69
|
+
guarded_object.send(variant_field).to_sym
|
53
70
|
user.stonepath_role_info.detect do |r|
|
54
|
-
granted?(r, v, method)
|
71
|
+
granted?(r, v, :all) || granted?(r, v, method)
|
55
72
|
end || false
|
56
73
|
end
|
74
|
+
|
75
|
+
def grants
|
76
|
+
grants = Array.new
|
77
|
+
@matrix.each do |r, vm|
|
78
|
+
vm.each do |v, methods|
|
79
|
+
methods.each do |m|
|
80
|
+
grants << [r, v, m]
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
return grants
|
85
|
+
end
|
57
86
|
end
|
58
87
|
end
|
data/lib/stonewall/helpers.rb
CHANGED
@@ -5,6 +5,13 @@ module StoneWall
|
|
5
5
|
[String, Symbol].include?(role.class) ? role.to_sym : role.name.to_sym
|
6
6
|
end
|
7
7
|
|
8
|
+
|
9
|
+
def self.fix_aliases_for(guarded_class)
|
10
|
+
guarded_class.stonewall.guarded_methods.each do |m|
|
11
|
+
fix_alias_for(guarded_class, m)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
8
15
|
# --------------
|
9
16
|
# This is 1/3rd of the magic in this gem. We earlier built a
|
10
17
|
# 'schpoo_with_stonepath' method on your class, and now we use
|
@@ -14,11 +21,30 @@ module StoneWall
|
|
14
21
|
# We have to do this after ActoveRecord synthesizes the attribute methods
|
15
22
|
# with a call to 'define_attribute_methods'; you'll see some magic in the
|
16
23
|
# base.instance_eval in the other file to make that magic happen.
|
17
|
-
def self.
|
18
|
-
guarded_class.
|
19
|
-
|
24
|
+
def self.fix_alias_for(guarded_class, m)
|
25
|
+
guarded_class.send(:alias_method_chain, m, :stonewall)
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
def self.guard(guarded_class, m)
|
30
|
+
guarded_class.stonewall.guarded_methods << m
|
31
|
+
aliased_target, punctuation = m.to_s.sub(/([?!=])$/, ''), $1
|
32
|
+
checked_method = "#{aliased_target}_with_stonewall#{punctuation}"
|
33
|
+
unchecked_method = "#{aliased_target}_without_stonewall#{punctuation}"
|
34
|
+
# --------------
|
35
|
+
# This method is defined on the guarded class, so it is callable on
|
36
|
+
# objects of that class. This is 1/3rd of the magic of this gem-
|
37
|
+
# if you declare 'schpoo' a guarded method, we generate this
|
38
|
+
# 'schpoo_with_stonewall' method. Elsewhere, we use alias_method_chain
|
39
|
+
# to wrap your original 'schpoo' method.
|
40
|
+
guarded_class.send(:define_method, checked_method) do |*args|
|
41
|
+
if stonewall.allowed?(self, User.current, m)
|
42
|
+
self.send(unchecked_method, *args)
|
43
|
+
else
|
44
|
+
raise "Access Violation"
|
45
|
+
end
|
20
46
|
end
|
47
|
+
# -------------- end of bizzaro meta-juju
|
21
48
|
end
|
22
|
-
|
23
49
|
end
|
24
50
|
end
|
data/lib/stonewall/parser.rb
CHANGED
@@ -5,16 +5,28 @@ module StoneWall
|
|
5
5
|
@method_groups = Hash.new
|
6
6
|
end
|
7
7
|
|
8
|
-
def allowed_method(
|
9
|
-
|
8
|
+
def allowed_method(*methods)
|
9
|
+
methods.flatten.each do |m|
|
10
|
+
@parent.stonewall.add_grant(@role, @variant, m)
|
11
|
+
end
|
10
12
|
end
|
11
13
|
|
12
|
-
def allowed_methods(
|
13
|
-
|
14
|
-
|
14
|
+
def allowed_methods(*methods)
|
15
|
+
allowed_method(*methods)
|
16
|
+
end
|
17
|
+
|
18
|
+
def allowed_method_group(*group_names)
|
19
|
+
group_names.flatten.each do |group_name|
|
20
|
+
@parent.stonewall.method_groups[group_name].each do |m|
|
21
|
+
allowed_method m
|
22
|
+
end
|
15
23
|
end
|
16
24
|
end
|
17
25
|
|
26
|
+
def allowed_method_groups(*group_names)
|
27
|
+
allowed_method_group(group_names)
|
28
|
+
end
|
29
|
+
|
18
30
|
def method_group(name, methods)
|
19
31
|
@parent.stonewall.method_groups[name] = methods
|
20
32
|
end
|
@@ -35,25 +47,10 @@ module StoneWall
|
|
35
47
|
yield Parser.new(@parent, @role, variant_name)
|
36
48
|
end
|
37
49
|
|
38
|
-
def guard(
|
39
|
-
|
40
|
-
|
41
|
-
checked_method = "#{aliased_target}_with_stonewall#{punctuation}"
|
42
|
-
unchecked_method = "#{aliased_target}_without_stonewall#{punctuation}"
|
43
|
-
# --------------
|
44
|
-
# This method is defined on the guarded class, so it is callable on
|
45
|
-
# objects of that class. This is 1/3rd of the magic of this gem-
|
46
|
-
# if you declare 'schpoo' a guarded method, we generate this
|
47
|
-
# 'schpoo_with_stonewall' method. Elsewhere, we use alias_method_chain
|
48
|
-
# to wrap your original 'schpoo' method.
|
49
|
-
@parent.send(:define_method, checked_method) do |*args|
|
50
|
-
if stonewall.allowed?(self, User.current, method)
|
51
|
-
self.send(unchecked_method, *args)
|
52
|
-
else
|
53
|
-
raise "Access Violation"
|
54
|
-
end
|
50
|
+
def guard(*methods)
|
51
|
+
methods.each do |m|
|
52
|
+
StoneWall::Helpers.guard(@parent, m)
|
55
53
|
end
|
56
|
-
# -------------- end of bizzaro meta-juju
|
57
54
|
end
|
58
55
|
|
59
56
|
end
|
@@ -33,16 +33,5 @@ module StoneWall
|
|
33
33
|
object.class.stonewall.allowed?(object, self, method)
|
34
34
|
end
|
35
35
|
|
36
|
-
def method_missing_with_stonewall(symb, *args)
|
37
|
-
method_name = symb.to_s
|
38
|
-
if method_name =~ /^may_(.+?)[\!\?]$/
|
39
|
-
args.first.class.stonewall.actions[$1.to_sym].call(args.first, self)
|
40
|
-
else
|
41
|
-
method_missing_without_stonewall(symb, *args)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
alias_method_chain :method_missing, :stonewall
|
46
|
-
|
47
36
|
end
|
48
37
|
end
|
data/lib/stonewall.rb
CHANGED
@@ -3,4 +3,5 @@ $:.unshift(File.dirname(__FILE__)) unless
|
|
3
3
|
$:.include?(File.expand_path(File.dirname(__FILE__)))
|
4
4
|
|
5
5
|
require File.expand_path(File.dirname(__FILE__)) + "/stonewall/stonewall.rb"
|
6
|
-
require File.expand_path(File.dirname(__FILE__)) + "/stonewall/user_extensions.rb"
|
6
|
+
require File.expand_path(File.dirname(__FILE__)) + "/stonewall/user_extensions.rb"
|
7
|
+
require 'rails/active_record'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stonewall
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- bokmann
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-03-
|
12
|
+
date: 2010-03-25 00:00:00 -04:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -59,6 +59,7 @@ files:
|
|
59
59
|
- Rakefile
|
60
60
|
- VERSION
|
61
61
|
- design_notes.txt
|
62
|
+
- lib/rails/active_record.rb
|
62
63
|
- lib/stonewall.rb
|
63
64
|
- lib/stonewall/access_controller.rb
|
64
65
|
- lib/stonewall/helpers.rb
|