shikashi 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,23 @@
1
+ =begin
2
+
3
+ This file is part of the shikashi project, http://github.com/tario/shikashi
4
+
5
+ Copyright (c) 2009-2010 Roberto Dario Seminara <robertodarioseminara@gmail.com>
6
+
7
+ shikashi is free software: you can redistribute it and/or modify
8
+ it under the terms of the gnu general public license as published by
9
+ the free software foundation, either version 3 of the license, or
10
+ (at your option) any later version.
11
+
12
+ shikashi is distributed in the hope that it will be useful,
13
+ but without any warranty; without even the implied warranty of
14
+ merchantability or fitness for a particular purpose. see the
15
+ gnu general public license for more details.
16
+
17
+ you should have received a copy of the gnu general public license
18
+ along with shikashi. if not, see <http://www.gnu.org/licenses/>.
19
+
20
+ =end
21
+ require "shikashi/sandbox"
22
+
23
+
@@ -0,0 +1,81 @@
1
+ =begin
2
+
3
+ This file is part of the shikashi project, http://github.com/tario/shikashi
4
+
5
+ Copyright (c) 2009-2010 Roberto Dario Seminara <robertodarioseminara@gmail.com>
6
+
7
+ shikashi is free software: you can redistribute it and/or modify
8
+ it under the terms of the gnu general public license as published by
9
+ the free software foundation, either version 3 of the license, or
10
+ (at your option) any later version.
11
+
12
+ shikashi is distributed in the hope that it will be useful,
13
+ but without any warranty; without even the implied warranty of
14
+ merchantability or fitness for a particular purpose. see the
15
+ gnu general public license for more details.
16
+
17
+ you should have received a copy of the gnu general public license
18
+ along with shikashi. if not, see <http://www.gnu.org/licenses/>.
19
+
20
+ =end
21
+ module Arguments
22
+ module NoDefault
23
+ end
24
+ end
25
+ class Array
26
+
27
+ def pick_by_class(klass)
28
+ klassary = self.select{|x| x.instance_of? klass}
29
+ if klassary.size > 1
30
+ raise ArgumentError, "ambiguous parameters of class #{klass}"
31
+ elsif klassary.size == 1
32
+ klassary.first
33
+ else
34
+ nil
35
+ end
36
+
37
+ end
38
+
39
+ def pick(*args)
40
+
41
+ klass = args.pick_by_class Class
42
+ hash_key = args.pick_by_class Symbol
43
+
44
+ ary = []
45
+
46
+ if klass
47
+ ary = self.select{|x| x.instance_of? klass}
48
+
49
+ if ary.size > 1
50
+ raise ArgumentError, "ambiguous parameters of class #{klass}"
51
+ end
52
+ else
53
+ ary = []
54
+ end
55
+
56
+ if hash_key
57
+ each do |x|
58
+ if x.instance_of? Hash
59
+ if x[hash_key]
60
+ ary << x[hash_key]
61
+ end
62
+ end
63
+ end
64
+
65
+ if ary.size > 1
66
+ raise ArgumentError, "ambiguous parameters of class #{klass} and key '#{hash_key}'"
67
+ end
68
+
69
+ end
70
+
71
+ if ary.size == 1
72
+ return ary.first
73
+ end
74
+
75
+ unless block_given?
76
+ raise ArgumentError, "missing mandatory argument '#{hash_key}' or of class #{klass}"
77
+ end
78
+
79
+ yield
80
+ end
81
+ end
@@ -0,0 +1,294 @@
1
+ =begin
2
+
3
+ This file is part of the shikashi project, http://github.com/tario/shikashi
4
+
5
+ Copyright (c) 2009-2010 Roberto Dario Seminara <robertodarioseminara@gmail.com>
6
+
7
+ shikashi is free software: you can redistribute it and/or modify
8
+ it under the terms of the gnu general public license as published by
9
+ the free software foundation, either version 3 of the license, or
10
+ (at your option) any later version.
11
+
12
+ shikashi is distributed in the hope that it will be useful,
13
+ but without any warranty; without even the implied warranty of
14
+ merchantability or fitness for a particular purpose. see the
15
+ gnu general public license for more details.
16
+
17
+ you should have received a copy of the gnu general public license
18
+ along with shikashi. if not, see <http://www.gnu.org/licenses/>.
19
+
20
+ =end
21
+ require "find"
22
+
23
+ module Shikashi
24
+ #
25
+ #The Privileges class represent permissions about methods and objects
26
+ #
27
+ class Privileges
28
+
29
+ private
30
+ def self.load_privilege_packages
31
+ Find.find(__FILE__.split("/")[0..-2].join("/") + "/privileges" ) do |path|
32
+ if path =~ /\.rb$/
33
+ require path
34
+ end
35
+ end
36
+ end
37
+
38
+ load_privilege_packages
39
+ public
40
+
41
+ # Used in Privileges to store information about specified method permissions
42
+ class AllowedMethods
43
+ def initialize
44
+ @allowed_methods = Array.new
45
+ @redirect_hash = Hash.new
46
+ @all = false
47
+ end
48
+
49
+ #return true if the method named method_name is allowed
50
+ #Example
51
+ #
52
+ # allowed_methods = AllowedMethods.new
53
+ # allowed_methods.allowed? :foo # => false
54
+ # allowed_methods.allow :foo
55
+ # allowed_methods.allowed? :foo # => true
56
+ # allowed_methods.allow_all
57
+ # allowed_methods.allowed? :bar # => true
58
+ #
59
+ # Privileges#instance_of, Privileges#methods_of and Privileges#object returns the corresponding
60
+ # instance of AllowedMethods
61
+ def allowed?(method_name)
62
+ if @all
63
+ true
64
+ else
65
+ @allowed_methods.include?(method_name)
66
+ end
67
+ end
68
+
69
+ #Specifies that a method or list of methods are allowed
70
+ #Example
71
+ #
72
+ # allowed_methods = AllowedMethods.new
73
+ # allowed_methods.allow :foo
74
+ # allowed_methods.allow :foo, :bar
75
+ # allowed_methods.allow :foo, :bar, :test
76
+ #
77
+ def allow(*method_names)
78
+ method_names.each do |mn|
79
+ @allowed_methods << mn
80
+ end
81
+ end
82
+
83
+ #Specifies that any method is allowed
84
+ def allow_all
85
+ @all = true
86
+ end
87
+
88
+ def redirect(method_name, method_wrapper_class)
89
+ allow method_name
90
+ @redirect_hash[method_name] = method_wrapper_class
91
+ end
92
+
93
+ def handle_redirection(klass, recv, method_id, sandbox)
94
+
95
+ method_name = method_id.id2name
96
+ return nil unless method_name
97
+
98
+ rclass = @redirect_hash[method_name.to_sym]
99
+
100
+ if rclass
101
+ if block_given?
102
+ rclass.redirect_handler(klass, recv, method_name, method_id, sandbox) do |mh|
103
+ yield(mh)
104
+ end
105
+ else
106
+ rclass.redirect_handler(klass, recv, method_name, method_id, sandbox)
107
+ end
108
+ else
109
+ nil
110
+ end
111
+ end
112
+ end
113
+
114
+ def initialize
115
+ @allowed_objects = Hash.new
116
+ @allowed_kinds = Hash.new
117
+ @allowed_classes = Hash.new
118
+ @allowed_instances = Hash.new
119
+ @allowed_methods = Array.new
120
+ @allowed_klass_methods = Hash.new
121
+ end
122
+
123
+ private
124
+ def hash_entry(hash, key)
125
+ tmp = hash[key]
126
+ unless tmp
127
+ tmp = AllowedMethods.new
128
+ hash[key] = tmp
129
+ end
130
+ tmp
131
+ end
132
+ public
133
+
134
+ #
135
+ #Specifies the methods allowed for an specific object
136
+ #
137
+ #Example 1:
138
+ # privileges.object(Hash).allow :new
139
+ #
140
+
141
+ def object(obj)
142
+ hash_entry(@allowed_objects, obj.object_id)
143
+ end
144
+
145
+ #
146
+ #Specifies the methods allowed for the instances of a class
147
+ #
148
+ #Example 1:
149
+ # privileges.instances_of(Array).allow :each # allow calls of methods named "each" over instances of Array
150
+ #
151
+ #Example 2:
152
+ # privileges.instances_of(Array).allow :select, map # allow calls of methods named "each" and "map" over instances of Array
153
+ #
154
+ #Example 3:
155
+ # privileges.instances_of(Hash).allow_all # allow any method call over instances of Hash
156
+
157
+ def instances_of(klass)
158
+ hash_entry(@allowed_instances, klass.object_id)
159
+ end
160
+
161
+ #
162
+ #Specifies the methods allowed for an implementation in specific class
163
+ #
164
+ #Example 1:
165
+ # privileges.methods_of(X).allow :foo
166
+ #
167
+ # ...
168
+ # class X
169
+ # def foo # allowed :)
170
+ # end
171
+ # end
172
+ #
173
+ # class Y < X
174
+ # def foo # disallowed
175
+ # end
176
+ # end
177
+ #
178
+ # X.new.foo # allowed
179
+ # Y.new.foo # disallowed: SecurityError
180
+ # ...
181
+ #
182
+ def methods_of(klass)
183
+ hash_entry(@allowed_klass_methods, klass.object_id)
184
+ end
185
+
186
+ #allow the execution of method named method_name whereever
187
+ #
188
+ #Example:
189
+ # privileges.allow_method(:foo)
190
+ #
191
+
192
+ def allow_method(method_name)
193
+ @allowed_methods << method_name
194
+ end
195
+
196
+ def handle_redirection(klass, recv, method_id, sandbox)
197
+ if @last_allowed
198
+
199
+ if block_given?
200
+ @last_allowed.handle_redirection(klass, recv, method_id, sandbox) do |mh|
201
+ yield(mh)
202
+ end
203
+ else
204
+ @last_allowed.handle_redirection(klass, recv, method_id, sandbox)
205
+ end
206
+ else
207
+ nil
208
+ end
209
+
210
+ end
211
+
212
+ def allow?(klass, recv, method_name, method_id)
213
+
214
+ m = nil
215
+ m = klass.shadow.instance_method(method_name) if method_name
216
+
217
+ begin
218
+ return true if @allowed_methods.include?(method_name)
219
+
220
+ tmp = @allowed_objects[recv.object_id]
221
+ if tmp
222
+ if tmp.allowed?(method_name)
223
+ @last_allowed = tmp
224
+ return true
225
+ end
226
+ end
227
+
228
+ if m
229
+ tmp = @allowed_klass_methods[m.owner.object_id]
230
+ if tmp
231
+ if tmp.allowed?(method_name)
232
+ @last_allowed = tmp
233
+ return true
234
+ end
235
+ end
236
+ end
237
+
238
+ if recv.instance_of? Class
239
+ last_class = recv
240
+
241
+ while true
242
+ tmp = @allowed_classes[last_class.object_id]
243
+ if tmp
244
+ if tmp.allowed?(method_name)
245
+ @last_allowed = tmp
246
+ return true
247
+ end
248
+ end
249
+ if last_class
250
+ break if last_class == Object
251
+ last_class = last_class.superclass
252
+ else
253
+ break
254
+ end
255
+ end
256
+ end
257
+
258
+ last_class = recv.class
259
+ while true
260
+ tmp = @allowed_kinds[last_class.object_id]
261
+ if tmp
262
+ if tmp.allowed?(method_name)
263
+ @last_allowed = tmp
264
+ return true
265
+ end
266
+ end
267
+ if last_class
268
+ break if last_class == Object
269
+ last_class = last_class.superclass
270
+ else
271
+ break
272
+ end
273
+ end
274
+
275
+ tmp = @allowed_instances[recv.class.object_id]
276
+ if tmp
277
+ if tmp.allowed?(method_name)
278
+ @last_allowed = tmp
279
+ return true
280
+ end
281
+ end
282
+
283
+ false
284
+ rescue Exception => e
285
+ print "ERROR: #{e}\n"
286
+ print e.backtrace.join("\n")
287
+ false
288
+ end
289
+ end
290
+
291
+ end
292
+
293
+ end
294
+
@@ -0,0 +1,28 @@
1
+ =begin
2
+
3
+ This file is part of the shikashi project, http://github.com/tario/shikashi
4
+
5
+ Copyright (c) 2009-2010 Roberto Dario Seminara <robertodarioseminara@gmail.com>
6
+
7
+ shikashi is free software: you can redistribute it and/or modify
8
+ it under the terms of the gnu general public license as published by
9
+ the free software foundation, either version 3 of the license, or
10
+ (at your option) any later version.
11
+
12
+ shikashi is distributed in the hope that it will be useful,
13
+ but without any warranty; without even the implied warranty of
14
+ merchantability or fitness for a particular purpose. see the
15
+ gnu general public license for more details.
16
+
17
+ you should have received a copy of the gnu general public license
18
+ along with shikashi. if not, see <http://www.gnu.org/licenses/>.
19
+
20
+ =end
21
+ module Shikashi
22
+ class Privileges
23
+ #Defines the permissions needed to declare classes within the sandbox
24
+ def allow_class_definitions
25
+ instances_of(Class).allow nil, :inherited, :method_added
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,29 @@
1
+ =begin
2
+
3
+ This file is part of the shikashi project, http://github.com/tario/shikashi
4
+
5
+ Copyright (c) 2009-2010 Roberto Dario Seminara <robertodarioseminara@gmail.com>
6
+
7
+ shikashi is free software: you can redistribute it and/or modify
8
+ it under the terms of the gnu general public license as published by
9
+ the free software foundation, either version 3 of the license, or
10
+ (at your option) any later version.
11
+
12
+ shikashi is distributed in the hope that it will be useful,
13
+ but without any warranty; without even the implied warranty of
14
+ merchantability or fitness for a particular purpose. see the
15
+ gnu general public license for more details.
16
+
17
+ you should have received a copy of the gnu general public license
18
+ along with shikashi. if not, see <http://www.gnu.org/licenses/>.
19
+
20
+ =end
21
+ module Shikashi
22
+ class Privileges
23
+ #Define the permissions needed to raise exceptions within the sandbox
24
+ def allow_exceptions
25
+ allow_method :raise
26
+ methods_of(Exception).allow :backtrace, :set_backtrace, :exception
27
+ end
28
+ end
29
+ end