tuersteher 0.2.2 → 0.3.0
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/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
|