shikashi 0.1.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.
@@ -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