tuersteher 0.2.2 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/lib/tuersteher.rb +12 -20
- data/samples/access_rules.rb +15 -11
- data/spec/access_rules_spec.rb +0 -2
- data/spec/model_access_rule_spec.rb +43 -21
- data/spec/path_access_rule_spec.rb +118 -80
- data/tuersteher.gemspec +5 -5
- metadata +7 -7
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.3.0
|
data/lib/tuersteher.rb
CHANGED
@@ -94,16 +94,6 @@ module Tuersteher
|
|
94
94
|
# definiert Model-basierende Zugriffsregel
|
95
95
|
#
|
96
96
|
# model_class: Model-Klassenname oder :all fuer alle
|
97
|
-
# access_type: Zugriffsart (:create, :update, :destroy, :all o.A. selbst definierte Typen)
|
98
|
-
# roles Aufzählung der erforderliche Rolen (:all für ist egal),
|
99
|
-
# hier ist auch ein Array von Symbolen möglich
|
100
|
-
# block optionaler Block, wird mit model und user aufgerufen und muss true oder false liefern
|
101
|
-
# hier ein Beispiel mit Block:
|
102
|
-
# <code>
|
103
|
-
# # Regel, in der sich jeder User selbst aendern darf
|
104
|
-
# grant_model(User, :update, :all){|model,user| model.id==user.id}
|
105
|
-
# </code>
|
106
|
-
#
|
107
97
|
def model model_class
|
108
98
|
if block_given?
|
109
99
|
@current_model_class = model_class
|
@@ -152,7 +142,7 @@ module Tuersteher
|
|
152
142
|
end
|
153
143
|
Tuersteher::TLogger.logger.debug("Tuersteher: path_access?(#{path}, #{method}) => #{s}")
|
154
144
|
end
|
155
|
-
rule
|
145
|
+
!(rule.nil? || rule.deny?)
|
156
146
|
end
|
157
147
|
|
158
148
|
|
@@ -270,6 +260,7 @@ module Tuersteher
|
|
270
260
|
|
271
261
|
end
|
272
262
|
|
263
|
+
|
273
264
|
# Astracte base class for Access-Rules
|
274
265
|
class BaseAccessRule
|
275
266
|
|
@@ -304,14 +295,19 @@ module Tuersteher
|
|
304
295
|
@deny
|
305
296
|
end
|
306
297
|
|
298
|
+
def not
|
299
|
+
@not = true
|
300
|
+
self
|
301
|
+
end
|
302
|
+
|
307
303
|
protected
|
308
304
|
|
309
305
|
def grant_role? user
|
310
306
|
return true if @roles.empty?
|
311
307
|
return false if user.nil?
|
312
|
-
@roles.
|
313
|
-
|
314
|
-
|
308
|
+
role = @roles.detect{|r| user.has_role?(r)}
|
309
|
+
role = !role if @not
|
310
|
+
return true if role
|
315
311
|
false
|
316
312
|
end
|
317
313
|
|
@@ -358,7 +354,7 @@ module Tuersteher
|
|
358
354
|
# path / method fuer den current_user erlaubt ist
|
359
355
|
#
|
360
356
|
# user ist ein Object (meist der Loginuser),
|
361
|
-
# welcher die Methode 'has_role?(
|
357
|
+
# welcher die Methode 'has_role?(role)' besitzen muss.
|
362
358
|
# *roles ist dabei eine Array aus Symbolen
|
363
359
|
#
|
364
360
|
def fired?(path, method, user)
|
@@ -372,11 +368,7 @@ module Tuersteher
|
|
372
368
|
return false
|
373
369
|
end
|
374
370
|
|
375
|
-
|
376
|
-
#Tuersteher::TLogger.logger.debug("#{to_s}.has_access? => false why #{@roles.first}!=:all && #{!user.has_role?(*@roles)}")
|
377
|
-
return false
|
378
|
-
end
|
379
|
-
|
371
|
+
return false unless grant_role?(user)
|
380
372
|
return false unless grant_extension?(user)
|
381
373
|
|
382
374
|
true
|
data/samples/access_rules.rb
CHANGED
@@ -8,10 +8,11 @@
|
|
8
8
|
#
|
9
9
|
# Pfad-Zugriffsregeln
|
10
10
|
# Aufbau:
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
11
|
+
# path(<path>).grant[.method(<methode>)][.not][.role(<role>)][.extension(<ext_method>[, <expected_value>)]
|
12
|
+
# or
|
13
|
+
# path(<path>).deny[.method(<methode>)][.not][.role(<role>)][.extension(<ext_method>[, <expected_value>)]
|
14
|
+
# with
|
15
|
+
# <method>: HTTP-Method name as Symbol (:get, :put, :post, :delete) or :all
|
15
16
|
|
16
17
|
path('/').grant.method(:get)
|
17
18
|
path(:all).grant.role(:ADMIN)
|
@@ -21,14 +22,16 @@ path('/special').grant.extension(:special?, :area1)
|
|
21
22
|
#
|
22
23
|
# Model-Object-Zugriffsregeln
|
23
24
|
# Aufbau:
|
24
|
-
#
|
25
|
-
#
|
26
|
-
#
|
27
|
-
#
|
25
|
+
# model(<ModelClass>).grant.permission(<permission>)[.role(<role>)][.extension(<method>[, <expected_value>])]
|
26
|
+
# or
|
27
|
+
# model(<ModelClass>).deny.permission(<permission>)[.not][.role(<role>)][.extension(<method>[, <expected_value>])]
|
28
|
+
# or
|
29
|
+
# model(<ModelClass> do
|
30
|
+
# grant..permission(<permission>)[.role(<role>)][.extension(<method>[, <expected_value>])]
|
31
|
+
# deny.permission(<permission>)[.role(<role>)][.extension(<method>[, <expected_value>])]
|
32
|
+
# ...
|
33
|
+
# end
|
28
34
|
|
29
|
-
#grant_model String, :view, :all
|
30
|
-
#grant_model String, :view, :ADMIN, :EDITOR
|
31
|
-
#grant_model String, :update, :EDITOR do |model, user| model == user.name end
|
32
35
|
|
33
36
|
model(Dashboard).grant.permission(:view)
|
34
37
|
|
@@ -36,4 +39,5 @@ model(Todo) do
|
|
36
39
|
grant.permission(:view)
|
37
40
|
grant.permission(:full_view).role(:ADMIN)
|
38
41
|
grant.permission(:update).role(:EDITOR).extension(:owned_by?) # calls Todo.owned_by?(current_user)
|
42
|
+
grant-permission(:delete).not.role(:ADMIN)
|
39
43
|
end
|
data/spec/access_rules_spec.rb
CHANGED
@@ -4,39 +4,61 @@ module Tuersteher
|
|
4
4
|
|
5
5
|
describe ModelAccessRule do
|
6
6
|
|
7
|
-
|
8
|
-
@rule = ModelAccessRule.new(String).grant.permission(:read).role(:sysadmin).role(:admin)
|
9
|
-
end
|
7
|
+
context "grant with roles" do
|
10
8
|
|
11
|
-
|
12
|
-
|
13
|
-
@user = stub('user')
|
14
|
-
@user.stub(:has_role?){|role| role==:admin}
|
9
|
+
before(:all) do
|
10
|
+
@rule = ModelAccessRule.new(String).grant.permission(:read).role(:sysadmin).role(:admin)
|
15
11
|
end
|
16
12
|
|
17
|
-
|
18
|
-
|
19
|
-
|
13
|
+
context "for User with role :admin" do
|
14
|
+
before do
|
15
|
+
@user = stub('user')
|
16
|
+
@user.stub(:has_role?) { |role| role==:admin }
|
17
|
+
end
|
20
18
|
|
21
|
-
|
22
|
-
|
19
|
+
it "should be fired for String-Object and access-type :read" do
|
20
|
+
@rule.fired?("test", :read, @user).should be_true
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should not be fired for Non-String-Object" do
|
24
|
+
@rule.fired?(12345, :read, @user).should_not be_true
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should not be fired for String-Object and other access-type as :read" do
|
28
|
+
@rule.fired?("test", :delete, @user).should_not be_true
|
29
|
+
end
|
23
30
|
end
|
24
31
|
|
25
|
-
|
26
|
-
|
32
|
+
context "for User without role :admin" do
|
33
|
+
before do
|
34
|
+
@user = stub('user')
|
35
|
+
@user.stub(:has_role?).and_return(false)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should not be fired for String-Object and access-type :read" do
|
39
|
+
@rule.fired?("test", :read, @user).should_not be_true
|
40
|
+
end
|
27
41
|
end
|
28
|
-
end
|
42
|
+
end # of context "grant with roles"
|
29
43
|
|
30
|
-
|
31
|
-
|
44
|
+
|
45
|
+
context "deny with not.role" do
|
46
|
+
before(:all) do
|
47
|
+
@rule = ModelAccessRule.new(String).deny.permission(:append).not.role(:admin)
|
32
48
|
@user = stub('user')
|
33
|
-
@user.stub(:has_role?).and_return(false)
|
34
49
|
end
|
35
50
|
|
36
|
-
it "should not
|
37
|
-
@
|
51
|
+
it "should not fired for user with role :admin" do
|
52
|
+
@user.stub(:has_role?){|role| role==:admin}
|
53
|
+
@rule.fired?("/admin", :append, @user).should_not be_true
|
38
54
|
end
|
39
|
-
|
55
|
+
|
56
|
+
it "should fired for user with role :user" do
|
57
|
+
@user.stub(:has_role?){|role| role==:user}
|
58
|
+
@rule.fired?("/admin", :append, @user).should be_true
|
59
|
+
end
|
60
|
+
end # of context "deny with not.role"
|
61
|
+
|
40
62
|
end
|
41
63
|
|
42
64
|
end
|
@@ -4,126 +4,164 @@ module Tuersteher
|
|
4
4
|
|
5
5
|
describe PathAccessRule do
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
context "grant" do
|
8
|
+
before(:all) do
|
9
|
+
@rule = PathAccessRule.new('/admin').grant.method(:get).role(:sysadmin).role(:admin)
|
10
|
+
end
|
10
11
|
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
13
|
+
context "for User with role :admin" do
|
14
|
+
before do
|
15
|
+
@user = stub('user')
|
16
|
+
@user.stub(:has_role?){|role| role==:admin}
|
17
|
+
end
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
|
19
|
+
it "should be fired for path='/admin/xyz' and method :get" do
|
20
|
+
@rule.fired?("/admin/xyz", :get, @user).should be_true
|
21
|
+
end
|
21
22
|
|
22
|
-
|
23
|
-
|
24
|
-
|
23
|
+
it "should not be fired for other path" do
|
24
|
+
@rule.fired?('/todos/admin', :get, @user).should_not be_true
|
25
|
+
end
|
25
26
|
|
26
|
-
|
27
|
-
|
27
|
+
it "should not be fired for other method as :get" do
|
28
|
+
@rule.fired?("/admin/xyz", :post, @user).should_not be_true
|
29
|
+
end
|
28
30
|
end
|
29
|
-
end
|
30
31
|
|
31
32
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
33
|
+
context "for User without role :admin" do
|
34
|
+
before do
|
35
|
+
@user = stub('user')
|
36
|
+
@user.stub(:has_role?).and_return(false)
|
37
|
+
end
|
37
38
|
|
38
|
-
|
39
|
-
|
39
|
+
it "should not be fired for correct path and method" do
|
40
|
+
@rule.fired?("/admin/xyz", :get, @user).should_not be_true
|
41
|
+
end
|
40
42
|
end
|
41
|
-
end
|
42
43
|
|
43
44
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
45
|
+
context "Rule with :all as Path-Matcher" do
|
46
|
+
before(:all) do
|
47
|
+
@rule = PathAccessRule.new(:all).method(:get).role(:sysadmin).role(:admin)
|
48
|
+
@user = stub('user')
|
49
|
+
@user.stub(:has_role?).and_return(true)
|
50
|
+
end
|
50
51
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
52
|
+
it "should fired for several paths" do
|
53
|
+
@rule.fired?("/admin/xyz", :get, @user).should be_true
|
54
|
+
@rule.fired?("/xyz", :get, @user).should be_true
|
55
|
+
@rule.fired?("/", :get, @user).should be_true
|
56
|
+
end
|
56
57
|
|
57
|
-
|
58
|
-
|
58
|
+
it "should not be fired with other method" do
|
59
|
+
@rule.fired?("/admin/xyz", :post, @user).should_not be_true
|
60
|
+
end
|
59
61
|
end
|
60
|
-
end
|
61
62
|
|
62
63
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
64
|
+
context "Rule with no Methode spezifed => all methods allowed" do
|
65
|
+
before(:all) do
|
66
|
+
@rule = PathAccessRule.new('/admin').role(:sysadmin).role(:admin)
|
67
|
+
@user = stub('user')
|
68
|
+
@user.stub(:has_role?).and_return(true)
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should fired for several methods" do
|
72
|
+
@rule.fired?("/admin/xyz", :get, @user).should be_true
|
73
|
+
@rule.fired?("/admin/xyz", :post, @user).should be_true
|
74
|
+
@rule.fired?("/admin/xyz", :put, @user).should be_true
|
75
|
+
@rule.fired?("/admin/xyz", :delete, @user).should be_true
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should not be fired with other path" do
|
79
|
+
@rule.fired?("/xyz", :post, @user).should_not be_true
|
80
|
+
end
|
68
81
|
end
|
69
82
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
83
|
+
|
84
|
+
context "Rule with no role spezifed => now role needed" do
|
85
|
+
before(:all) do
|
86
|
+
@rule = PathAccessRule.new('/admin').method(:get)
|
87
|
+
@user = stub('user')
|
88
|
+
@user.stub(:has_role?).and_return(false)
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should fired for user with no roles" do
|
92
|
+
@rule.fired?("/admin/xyz", :get, @user).should be_true
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should not be fired with other path" do
|
96
|
+
@rule.fired?("/xyz", :get, @user).should_not be_true
|
97
|
+
end
|
75
98
|
end
|
76
99
|
|
77
|
-
|
78
|
-
|
100
|
+
|
101
|
+
context "Rule with extension" do
|
102
|
+
before(:all) do
|
103
|
+
@rule = PathAccessRule.new('/admin').method(:get).extension(:modul_function?, :testvalue)
|
104
|
+
@rule2 = PathAccessRule.new('/admin').method(:get).extension(:modul_function2?)
|
105
|
+
@user = stub('user')
|
106
|
+
@user.stub(:has_role?).and_return(false)
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should not be fired with user have not the check_extension" do
|
110
|
+
@rule.fired?("/admin", :get, @user).should_not be_true
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should fired for user with true for check-extension" do
|
114
|
+
@user.should_receive(:modul_function?).with(:testvalue).and_return(true)
|
115
|
+
@rule.fired?("/admin/xyz", :get, @user).should be_true
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should not be fired for user with false for check-extension" do
|
119
|
+
@user.should_receive(:modul_function?).with(:testvalue).and_return(false)
|
120
|
+
@rule.fired?("/admin/xyz", :get, @user).should_not be_true
|
121
|
+
end
|
122
|
+
|
123
|
+
it "should fired for rule2 and user with true for check-extension" do
|
124
|
+
@user.should_receive(:modul_function2?).and_return(true)
|
125
|
+
@rule2.fired?("/admin/xyz", :get, @user).should be_true
|
126
|
+
end
|
79
127
|
end
|
80
|
-
end
|
128
|
+
end # of context "grant" do
|
81
129
|
|
82
130
|
|
83
|
-
context "
|
131
|
+
context "deny" do
|
84
132
|
before(:all) do
|
85
|
-
@rule = PathAccessRule.new('/admin').
|
133
|
+
@rule = PathAccessRule.new('/admin').deny.role(:user)
|
86
134
|
@user = stub('user')
|
87
|
-
@user.stub(:has_role?).and_return(false)
|
88
135
|
end
|
89
136
|
|
90
|
-
it "should fired for user with
|
91
|
-
@
|
137
|
+
it "should fired for user with role :user" do
|
138
|
+
@user.stub(:has_role?){|role| role==:user}
|
139
|
+
@rule.fired?("/admin", :get, @user).should be_true
|
92
140
|
end
|
93
141
|
|
94
|
-
it "should not
|
95
|
-
@
|
142
|
+
it "should not fired for user with role :admin" do
|
143
|
+
@user.stub(:has_role?){|role| role==:admin}
|
144
|
+
@rule.fired?("/admin", :get, @user).should_not be_true
|
96
145
|
end
|
97
|
-
end
|
146
|
+
end # of context "deny" do
|
98
147
|
|
99
148
|
|
100
|
-
context "
|
149
|
+
context "with not as role prefix" do
|
101
150
|
before(:all) do
|
102
|
-
@rule = PathAccessRule.new('/admin').
|
103
|
-
@rule2 = PathAccessRule.new('/admin').method(:get).extension(:modul_function2?)
|
151
|
+
@rule = PathAccessRule.new('/admin').deny.not.role(:admin)
|
104
152
|
@user = stub('user')
|
105
|
-
@user.stub(:has_role?).and_return(false)
|
106
153
|
end
|
107
154
|
|
108
|
-
it "should not
|
155
|
+
it "should not fired for user with role :admin" do
|
156
|
+
@user.stub(:has_role?){|role| role==:admin}
|
109
157
|
@rule.fired?("/admin", :get, @user).should_not be_true
|
110
158
|
end
|
111
159
|
|
112
|
-
it "should fired for user with
|
113
|
-
@user.
|
114
|
-
@rule.fired?("/admin
|
115
|
-
end
|
116
|
-
|
117
|
-
it "should not be fired for user with false for check-extension" do
|
118
|
-
@user.should_receive(:modul_function?).with(:testvalue).and_return(false)
|
119
|
-
@rule.fired?("/admin/xyz", :get, @user).should_not be_true
|
160
|
+
it "should fired for user with role :user" do
|
161
|
+
@user.stub(:has_role?){|role| role==:user}
|
162
|
+
@rule.fired?("/admin", :get, @user).should be_true
|
120
163
|
end
|
121
|
-
|
122
|
-
|
123
|
-
@user.should_receive(:modul_function2?).and_return(true)
|
124
|
-
@rule2.fired?("/admin/xyz", :get, @user).should be_true
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
164
|
+
end # of context "not" do
|
165
|
+
|
128
166
|
end
|
129
167
|
end
|
data/tuersteher.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{tuersteher}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.3.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Bernd Ledig"]
|
12
|
-
s.date = %q{2010-08-
|
12
|
+
s.date = %q{2010-08-30}
|
13
13
|
s.description = %q{Security-Layer for Rails-Application acts like a firewall.}
|
14
14
|
s.email = %q{bernd@ledig.info}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -40,11 +40,11 @@ Gem::Specification.new do |s|
|
|
40
40
|
s.rubygems_version = %q{1.3.7}
|
41
41
|
s.summary = %q{Security-Layer for Rails-Application}
|
42
42
|
s.test_files = [
|
43
|
-
"spec/
|
44
|
-
"spec/access_rules_spec.rb",
|
43
|
+
"spec/acces_rules_storage_spec.rb",
|
45
44
|
"spec/path_access_rule_spec.rb",
|
46
45
|
"spec/model_access_rule_spec.rb",
|
47
|
-
"spec/
|
46
|
+
"spec/access_rules_spec.rb",
|
47
|
+
"spec/spec_helper.rb"
|
48
48
|
]
|
49
49
|
|
50
50
|
if s.respond_to? :specification_version then
|
metadata
CHANGED
@@ -5,9 +5,9 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 3
|
9
|
+
- 0
|
10
|
+
version: 0.3.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Bernd Ledig
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-08-
|
18
|
+
date: 2010-08-30 00:00:00 +02:00
|
19
19
|
default_executable:
|
20
20
|
dependencies: []
|
21
21
|
|
@@ -80,8 +80,8 @@ signing_key:
|
|
80
80
|
specification_version: 3
|
81
81
|
summary: Security-Layer for Rails-Application
|
82
82
|
test_files:
|
83
|
-
- spec/
|
84
|
-
- spec/access_rules_spec.rb
|
83
|
+
- spec/acces_rules_storage_spec.rb
|
85
84
|
- spec/path_access_rule_spec.rb
|
86
85
|
- spec/model_access_rule_spec.rb
|
87
|
-
- spec/
|
86
|
+
- spec/access_rules_spec.rb
|
87
|
+
- spec/spec_helper.rb
|