# This code is free software; you can redistribute it and/or modify it under # the terms of the new BSD License. # # Copyright (c) 2010, Sebastian Staudt module Rubikon module Application # The application sandbox is a wrapper used to secure internal Rubikon # logic from access by user generated application code. # # This is mostly to prevent accidental execution or change of Rubikon's # internal code. But it also helps to prevent possible security problems # depending on the code used inside the application logic. # # @see Application::InstanceMethods # @since 0.4.0 class Sandbox # Create a new application sandbox # # @param [Application::Base] app The application to be sandboxed def initialize(app) raise ArgumentError unless app.is_a? Application::Base @__app__ = app end # Method calls on the sandbox wrapper will be relayed to the singleton # instance. Methods defined in InstanceMethods are protected and will # raise a NoMethodError. # # @param (see ClassMethods#method_missing) # @raise [NoMethodError] if a method is called that is defined inside # InstanceMethods and should therefore be protected # @see InstanceMethods def method_missing(name, *args, &block) if @__app__.class.instance_methods(false).include?(name.to_s) || !(InstanceMethods.method_defined?(name) || InstanceMethods.private_method_defined?(name)) @__app__.send(name, *args, &block) else raise NoMethodError.new("Method `#{name}' is protected by the application sandbox", name) end end # Relay putc to the instance method # # This is used to hide Kernel#putc so that the application's # output IO object is used for printing characters # # @param [String, Numeric] char The character to write into the output # stream def putc(text) @__app__.send(:putc, text) end # Relay puts to the instance method # # This is used to hide Kernel#puts so that the application's # output IO object is used for printing text # # @param [String] text The text to write into the output stream def puts(text) @__app__.send(:puts, text) end end end end