Class: Module

Inherits:
Object
  • Object
show all
Defined in:
lib/sandboxed_erb/sandbox_methods.rb

Overview

Adds the sandboxed_methods and not_sandboxed_methods to Module class so it is avialble to all classes.

Instance Method Summary collapse

Instance Method Details

#not_sandboxed_methods(include_superclasses = false, allowed_mixins = [], *disallowed_methods) ⇒ Object

Shortcut to allow everything except a few methods

This will not include any superclass methods unless include_superclasses = true

Example class SomeClass

not_sandboxed_methods :unsafe_method
def some_method
  "this is ok to call"
end
def unsafe_method
  "this is NOT ok to call"
end

end



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/sandboxed_erb/sandbox_methods.rb', line 72

def not_sandboxed_methods(include_superclasses = false, allowed_mixins=[], *disallowed_methods)

  __the_methods_to_check = public_instance_methods(false)
  puts "#{self.name}: direct: #{__the_methods_to_check.inspect}" if $DEBUG
  if include_superclasses
    clz = self.superclass
    while !clz.nil?
      unless clz == Object || (defined? BasicObject && clz == BasicObject)
        puts "#{self.name}: #{clz.name}: #{clz.public_instance_methods(false).inspect}" if $DEBUG
        __the_methods_to_check += clz.public_instance_methods(false)
      end
      clz = clz.superclass
    end
    
    if allowed_mixins.length > 0
      #we include any mixins
      for m in self.included_modules
        if allowed_mixins.include?(m)
          puts "#{self.name}: #{m.name}: #{m.public_instance_methods(false).inspect}" if $DEBUG
          __the_methods_to_check += m.public_instance_methods(false)
        end
      end
    end
  end
  
  __the_methods_to_check << "nil?".intern
  
  __the_methods_to_check.uniq!
  
  unless disallowed_methods.nil? || disallowed_methods.length == 0
    not_bang = false
    if disallowed_methods.include?(:bang_methods) #just remove all xxx! methods that modify in place
      __the_methods_to_check.reject! { |meth| meth.to_s[-1, 1] == "!"}
      not_bang = true
    end
    unless not_bang || disallowed_methods.length > 1
      __the_methods_to_check.reject! { |meth| disallowed_methods.include?(meth)}
    end
  end
  
  puts "#{self.name}: #{__the_methods_to_check.inspect}" if $DEBUG
   
  sandboxed_methods(*__the_methods_to_check)
  
  
  
end

#sandboxed_methods(*allowed_methods) ⇒ Object

Specify what methods you want to be accessable from the sandbox.

Example class SomeClass

sandboxed_methods :some_method
def some_method
  "this is ok to call"
end

end

If the object has a method called set_sandbox_context, it will be passed the sandbox_context, which is a map containing the context passed to SandboxedErb::Template.run, as well as another entry keys to :locals which contains the locals map passed to run.



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/sandboxed_erb/sandbox_methods.rb', line 36

def sandboxed_methods(*allowed_methods)
  _sb_allowed_methods_map = {}
  allowed_methods.each { |meth|
    _sb_allowed_methods_map[meth.to_s.intern] = true
  }

  define_method :_sbm do |meth, sandbox_context, *args|
    if _sb_allowed_methods_map[meth]
      self.set_sandbox_context(sandbox_context) if self.respond_to?(:set_sandbox_context)
      begin
        self.__send__(meth, *args)
      rescue Exception=>e
        raise "Error calling #{meth}: #{e.message}"
      end
    else
      puts _sb_allowed_methods_map.inspect if $DEBUG
      raise SandboxedErb::MissingMethodError, "Unknown method '#{meth}' on object '#{self.class.name}'"
    end
  end
end