Module: ControllerCommands::Concern

Extended by:
ActiveSupport::Concern
Defined in:
lib/controller_commands/concern.rb

Instance Method Summary collapse

Instance Method Details

#construct_command(incoming_params, context, command_klass = nil) ⇒ Object



45
46
47
48
49
50
51
52
53
54
# File 'lib/controller_commands/concern.rb', line 45

def construct_command(incoming_params, context, command_klass = nil)
  unless command_klass
    # this should be fine given that the permissible action names are controlled by routing definitions
    command_klass_name = params.fetch(:action).camelize
    command_klass =
      "#{self.class.name}::#{command_klass_name}".safe_constantize or
      raise ActionController::RoutingError.new('Invalid Command')
  end
  command_klass.new(incoming_params, context)
end

#handle_command(options = {}) ⇒ Object



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/controller_commands/concern.rb', line 11

def handle_command(options = {})
  command_params = parse_params(options.fetch(:incoming_key_transformer, :transform_camel_to_underscore))
  context = options.fetch(:context, {})
  command = construct_command(command_params, context, options[:command_klass])

  # Validate & potentially execute the command
  is_command_valid = command.validate_params
  result =
    if is_command_valid
      flash[:notice] = command.success_message
      {data: command.perform}
    else
      {errors: command.errors}
    end

  # Render the results
  validation_failed_status_code = options.fetch(:validation_failed_status_code, :ok)
  status_code = (is_command_valid ? :ok : validation_failed_status_code)
  render status: status_code, json: HashKeyTransformer.transform_underscore_to_camel(result)
end

#parse_params(key_transformer_strategy) ⇒ Object



32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/controller_commands/concern.rb', line 32

def parse_params(key_transformer_strategy)
  # We need to be cautious accepting array fields as input. Refer to CVE-2013-0155 for more details about the danger
  # of malicious users crafting JSON using an array for a where clause field:
  #
  #   https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-0155
  #
  # The default JSON parsing in Rails replaces empty arrays with nil as a part of their solution to the CVE above.
  # This is the reason we are manually parsing the JSON request body. Consistent use of dry-validation schema types
  # should protect us from this CVE and also provide the same protection as Rails strong parameters.
  parsed_params = JSON.parse(request.body.read)
  HashKeyTransformer.send(key_transformer_strategy, parsed_params)
end