Class: Arkaan::Utils::Controllers::Base

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

Overview

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

Author:

Direct Known Subclasses

Checked

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.



25
26
27
# File 'lib/arkaan/utils/controllers/base.rb', line 25

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.



18
19
20
# File 'lib/arkaan/utils/controllers/base.rb', line 18

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.



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/arkaan/utils/controllers/base.rb', line 53

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
  complete_path
end

.declare_status_route(path = '/status') ⇒ Object

Declares the status route of the service, used by the Vigilante to check its status

Parameters:

  • path (String) (defaults to: '/status')

    the path used to map the route on.



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/arkaan/utils/controllers/base.rb', line 31

def self.declare_status_route(path = '/status')
  self.declare_route_with('get', path, false, { authanticated: false }) do
    if params['token'].nil?
      custom_error 400, 'vigilante.token.required'
    elsif Arkaan::Monitoring::Vigilante.where(token: params[:token]).first.nil?
      custom_error 404, 'vigilante.token.unknown'
    end
    service = Arkaan::Utils::MicroService.instance.service
    informations = {
      key: service.key,
      path: service.path,
      health: 'ok'
    }
    halt 200, informations.to_json
  end
  Arkaan::Utils::MicroService.instance.service.update_attribute(:diagnostic, path)
end

.load_errors_from(file) ⇒ Object

Loads the errors configuration file from the config folder.

Parameters:

  • file (String)

    send __FILE__



83
84
85
# File 'lib/arkaan/utils/controllers/base.rb', line 83

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.



143
144
145
146
147
148
149
150
151
# File 'lib/arkaan/utils/controllers/base.rb', line 143

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

#before_checksObject



87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/arkaan/utils/controllers/base.rb', line 87

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



134
135
136
137
138
139
# File 'lib/arkaan/utils/controllers/base.rb', line 134

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.



115
116
117
118
119
120
# File 'lib/arkaan/utils/controllers/base.rb', line 115

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.



105
106
107
108
109
# File 'lib/arkaan/utils/controllers/base.rb', line 105

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:



125
126
127
128
129
130
131
132
# File 'lib/arkaan/utils/controllers/base.rb', line 125

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.



163
164
165
166
167
# File 'lib/arkaan/utils/controllers/base.rb', line 163

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.



187
188
189
# File 'lib/arkaan/utils/controllers/base.rb', line 187

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’)



172
173
174
175
176
# File 'lib/arkaan/utils/controllers/base.rb', line 172

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:



155
156
157
158
# File 'lib/arkaan/utils/controllers/base.rb', line 155

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.



181
182
183
# File 'lib/arkaan/utils/controllers/base.rb', line 181

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