Class: MetaRPC::Interpreter
- Inherits:
-
Object
- Object
- MetaRPC::Interpreter
- Defined in:
- lib/metarpc/interpreter.rb
Overview
Used to interpret RPC requests and execute them securely
Instance Attribute Summary collapse
-
#input ⇒ Object
readonly
Returns the value of attribute input.
Instance Method Summary collapse
- #execute(executor) ⇒ Object
- #execute_method(executor, inp) ⇒ Object
-
#initialize(raw_request) ⇒ Interpreter
constructor
A new instance of Interpreter.
- #raise_error(code) ⇒ Object
- #valid_id(id) ⇒ Object
- #valid_method_name(method) ⇒ Object
- #valid_params(params) ⇒ Object
- #validate_json_rpc_call(item) ⇒ Object
Constructor Details
#initialize(raw_request) ⇒ Interpreter
Returns a new instance of Interpreter.
6 7 8 9 10 11 12 13 14 15 16 |
# File 'lib/metarpc/interpreter.rb', line 6 def initialize(raw_request) raw_input = JSON.parse(raw_request) @input = if raw_input.is_a?(Array) raw_input.map(&method(:validate_json_rpc_call)) else validate_json_rpc_call(raw_input) end rescue JSON::ParserError raise_error(:parse_error) end |
Instance Attribute Details
#input ⇒ Object (readonly)
Returns the value of attribute input.
4 5 6 |
# File 'lib/metarpc/interpreter.rb', line 4 def input @input end |
Instance Method Details
#execute(executor) ⇒ Object
18 19 20 21 22 |
# File 'lib/metarpc/interpreter.rb', line 18 def execute(executor) return input.map { |inp| execute_method(executor, inp) } if input.is_a?(Array) execute_method(executor, input) end |
#execute_method(executor, inp) ⇒ Object
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/metarpc/interpreter.rb', line 24 def execute_method(executor, inp) raise_error(:method_not_found) unless executor.class.json_rpc_methods.key?(inp[:method]) result = if inp[:params].is_a?(Array) executor.public_send(inp[:method], *inp[:params]) elsif inp[:params].is_a?(Hash) executor.public_send(inp[:method], inp[:params]) elsif inp[:params].nil? executor.public_send(inp[:method]) else raise_error(:internal_error) end { jsonrpc: '2.0', result: result, id: inp[:id] } rescue RPCError => err { jsonrpc: '2.0', error: err.to_h, id: inp[:id] } end |
#raise_error(code) ⇒ Object
92 93 94 |
# File 'lib/metarpc/interpreter.rb', line 92 def raise_error(code) raise RPCError.new(code), "Error on interpreter : #{code}" end |
#valid_id(id) ⇒ Object
76 77 78 79 80 |
# File 'lib/metarpc/interpreter.rb', line 76 def valid_id(id) return true if id.nil? id.is_a?(String) || id.nil? || id.is_a?(Integer) || id.is_a?(Float) end |
#valid_method_name(method) ⇒ Object
88 89 90 |
# File 'lib/metarpc/interpreter.rb', line 88 def valid_method_name(method) method.is_a?(String) && !method.start_with?('rpc.') end |
#valid_params(params) ⇒ Object
82 83 84 85 86 |
# File 'lib/metarpc/interpreter.rb', line 82 def valid_params(params) return true if params.nil? params.is_a?(Array) || params.is_a?(Hash) end |
#validate_json_rpc_call(item) ⇒ Object
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/metarpc/interpreter.rb', line 50 def validate_json_rpc_call(item) # Containing the required key valid = item.key?('jsonrpc') && item.key?('method') # Does not contain unknown keys valid &&= (item.keys - %w[jsonrpc method params id]).empty? # Defining the correct JSONRPC version valid &&= item['jsonrpc'] == '2.0' # Defining a correct ID valid &&= valid_id(item['id']) # Defining a correct params object valid &&= valid_params(item['params']) # Defining a correct method name valid &&= valid_method_name(item['method']) raise_error(:invalid_request) unless valid item.deep_symbolize_keys.tap do |h| h[:method] = h[:method].to_sym end end |