Class: Arkaan::Utils::ControllerWithoutFilter

Inherits:
Sinatra::Base
  • Object
show all
Defined in:
lib/arkaan/utils/controller_without_filter.rb

Overview

Base controller to handle the standard error when accessing the API.

Author:

Direct Known Subclasses

Controller

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.declare_premium_route(verb, path, options: {}, &block) ⇒ Object

Creates a non premium route whithin the Sinatra application, and registers it in the database if it does not already exists.

Parameters:

  • verb (String)

    the HTTP method used to create this route.

  • path (String)

    the path, beginning with a /, of the route to create.



24
25
26
# File 'lib/arkaan/utils/controller_without_filter.rb', line 24

def self.declare_premium_route(verb, path, options: {}, &block)
  self.declare_route_with(verb, path, true, options, &block)
end

.declare_route(verb, path, options: {}, &block) ⇒ Object

Creates a premium route whithin the Sinatra application, and registers it in the database if it does not already exists.

Parameters:

  • verb (String)

    the HTTP method used to create this route.

  • path (String)

    the path, beginning with a /, of the route to create.



17
18
19
# File 'lib/arkaan/utils/controller_without_filter.rb', line 17

def self.declare_route(verb, path, options: {}, &block)
  self.declare_route_with(verb, path, false, options, &block)
end

.declare_route_with(verb, path, premium, options, &block) ⇒ Object

Creates a route whithin the Sinatra application, and registers it in the database if it does not already exists.

Parameters:

  • verb (String)

    the HTTP method used to create this route.

  • path (String)

    the path, beginning with a /, of the route to create.

  • premium (Boolean)

    TRUE to make the route premium, FALSE otherwise.



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/arkaan/utils/controller_without_filter.rb', line 32

def self.declare_route_with(verb, path, premium, options, &block)
  service = Arkaan::Utils::MicroService.instance.service
  complete_path = "#{Arkaan::Utils::MicroService.instance.path}#{path == '/' ? '' : path}"

  unless service.nil? || !service.routes.where(path: path, verb: verb).first.nil?
    route = Arkaan::Monitoring::Route.create(path: path, verb: verb, premium: premium, service: service)
    if !options.nil? && !options[:authenticated].nil?
      route.update_attribute(:authenticated, false)
    end
    Arkaan::Permissions::Group.where(is_superuser: true).each do |group|
      group.routes << route
      group.save!
    end
  end
  if premium
    self.public_send(verb, complete_path) do
      @sinatra_route = parse_current_route
      if !@application.premium?
        custom_error(403, 'common.app_key.forbidden')
      end
      instance_eval(&block)
    end
  else
    self.public_send(verb, complete_path, &block)
  end
end

.load_errors_from(file) ⇒ Object

Loads the errors configuration file from the config folder.

Parameters:

  • file (String)

    send __FILE__



61
62
63
# File 'lib/arkaan/utils/controller_without_filter.rb', line 61

def self.load_errors_from(file)
  config_file File.join(File.dirname(file), '..', 'config', 'errors.yml')
end

Instance Method Details

#add_body_to_paramsObject

Adds the parsed body to the parameters, overwriting the parameters of the querystring with the values of the SON body if they have similar keys.



120
121
122
123
124
125
# File 'lib/arkaan/utils/controller_without_filter.rb', line 120

def add_body_to_params
  parsed_body = JSON.parse(request.body.read.to_s) rescue {}
  parsed_body.keys.each do |key|
    params[key] = parsed_body[key]
  end
end

#before_checksObject



65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/arkaan/utils/controller_without_filter.rb', line 65

def before_checks
  add_body_to_params
  check_presence('token', 'app_key', route: 'common')

  gateway = Arkaan::Monitoring::Gateway.where(token: params['token']).first
  @application = Arkaan::OAuth::Application.where(key: params['app_key']).first
  
  if gateway.nil?
    custom_error(404, 'common.token.unknown')
  elsif @application.nil?
    custom_error(404, 'common.app_key.unknown')
  end
end

#check_application(action) ⇒ Object



111
112
113
114
115
116
# File 'lib/arkaan/utils/controller_without_filter.rb', line 111

def check_application(action)
  check_presence('app_key', route: action)
  application = Arkaan::OAuth::Application.where(key: params['app_key']).first
  custom_error(404, "#{action}.app_key.unknown") if application.nil?
  return application
end

#check_either_presence(*fields, route:, key:) ⇒ Object

Checks the presence of either fields given in parameters. It halts with an error only if ALL parameters are not given.

Parameters:

  • fields (Array<String>)

    an array of fields names to search in the parameters

  • route (String)

    the name of the route you’re requiring to put in the error message.

  • key (String)

    the key to search in the errors configuration file.



92
93
94
95
96
97
# File 'lib/arkaan/utils/controller_without_filter.rb', line 92

def check_either_presence(*fields, route:, key:)
  fields.each do |field|
    return true if !params[field].nil? && params[field] != ''
  end
  custom_error 400, "#{route}.#{key}.required"
end

#check_presence(*fields, route:) ⇒ Object

Checks the presence of several fields given as parameters and halts the execution if it’s not present.

Parameters:

  • fields (Array<String>)

    an array of fields names to search in the parameters

  • route (String)

    the name of the route you’re requiring to put in the error message.



82
83
84
85
86
# File 'lib/arkaan/utils/controller_without_filter.rb', line 82

def check_presence(*fields, route:)
  fields.each do |field|
    custom_error(400, "#{route}.#{field}.required") if params[field].nil? || params[field] == ''
  end
end

#check_session(action) ⇒ Arkaan::Authentication::Session

Checks if the session ID is given in the parameters and if the session exists.

Parameters:

  • action (String)

    the action used to get the errors from the errors file.

Returns:



102
103
104
105
106
107
108
109
# File 'lib/arkaan/utils/controller_without_filter.rb', line 102

def check_session(action)
  check_presence('session_id', route: action)
  session = Arkaan::Authentication::Session.where(token: params['session_id']).first
  if session.nil?
    custom_error(404, "#{action}.session_id.unknown")
  end
  return session
end

#custom_error(status, path) ⇒ Object

Halts the application and creates the returned body from the parameters and the errors config file.

Parameters:

  • status (Integer)

    the HTTP status to halt the application with.

  • path (String)

    the path in the configuration file to access the URL.



137
138
139
140
141
142
# File 'lib/arkaan/utils/controller_without_filter.rb', line 137

def custom_error(status, path)

  route, field, error = path.split('.')
  docs = settings.errors[route][field][error] rescue ''
  halt status, {status: status, field: field, error: error, docs: docs}.to_json
end

#handle_arkaan_exception(exception) ⇒ Object

Creates a custom error from an existing Arkaan exception class.

Parameters:

  • exception (StandardError)

    the exception to transform in a usable error.



162
163
164
# File 'lib/arkaan/utils/controller_without_filter.rb', line 162

def handle_arkaan_exception(exception)
  custom_error(exception.status, "#{exception.action}.#{exception.field}.#{exception.error}")
end

#model_error(instance, route) ⇒ Object

Halts the application with a Bad Request error affecting a field of a model.

Parameters:

  • instance (Mongoid::Document)

    the document having a field in error.

  • route (String)

    the type of action you’re currently doing (e.g: ‘creation’)



147
148
149
150
151
# File 'lib/arkaan/utils/controller_without_filter.rb', line 147

def model_error(instance, route)
  messages = instance.errors.messages
  field = messages.keys.first
  custom_error(400, "#{route}.#{field}.#{messages[field].first}")
end

#parse_current_routeArkaan::Monitoring::Route

Gets the current route in the database from the sinatra route.

Returns:



129
130
131
132
# File 'lib/arkaan/utils/controller_without_filter.rb', line 129

def parse_current_route
  splitted = request.env['sinatra.route'].split(' ')
  return Arkaan::Monitoring::Route.where(verb: splitted.first.downcase, path: splitted.last).first
end

#select_params(*fields) ⇒ Hash

Select parameters in the params hash, by its keys.

Parameters:

  • fields (Array<String>)

    the keys to select in the params hash.

Returns:

  • (Hash)

    the selected chunk of the params hash.



156
157
158
# File 'lib/arkaan/utils/controller_without_filter.rb', line 156

def select_params(*fields)
  return params.select { |key, value| fields.include?(key) }
end