Class: Virtuaservices::Utils::Controllers::Base

Inherits:
Sinatra::Base
  • Object
show all
Defined in:
lib/virtuaservices/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/virtuaservices/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/virtuaservices/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.



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
58
59
# File 'lib/virtuaservices/utils/controllers/base.rb', line 33

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

  unless service.nil? || !service.routes.where(path: path, verb: verb).first.nil?
    route = Virtuaservices::Monitoring::Route.create(path: path, verb: verb, premium: premium, service: service)
    if !options.nil? && !options[:authenticated].nil?
      route.update_attribute(:authenticated, false)
    end
    Virtuaservices::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
    logger.info "#{verb} #{complete_path}"
    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__



63
64
65
# File 'lib/virtuaservices/utils/controllers/base.rb', line 63

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.



123
124
125
126
127
128
129
130
131
# File 'lib/virtuaservices/utils/controllers/base.rb', line 123

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



67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/virtuaservices/utils/controllers/base.rb', line 67

def before_checks
  add_body_to_params

  check_presence('token', 'app_key', route: 'common')

  gateway = Virtuaservices::Monitoring::Gateway.where(token: params['token']).first
  @application = Virtuaservices::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



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

def check_application(action)
  check_presence('app_key', route: action)
  application = Virtuaservices::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.



95
96
97
98
99
100
# File 'lib/virtuaservices/utils/controllers/base.rb', line 95

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.



85
86
87
88
89
# File 'lib/virtuaservices/utils/controllers/base.rb', line 85

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) ⇒ Virtuaservices::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:



105
106
107
108
109
110
111
112
# File 'lib/virtuaservices/utils/controllers/base.rb', line 105

def check_session(action)
  check_presence('session_id', route: action)
  session = Virtuaservices::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.



143
144
145
146
147
# File 'lib/virtuaservices/utils/controllers/base.rb', line 143

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 Virtuaservices exception class.

Parameters:

  • exception (StandardError)

    the exception to transform in a usable error.



167
168
169
# File 'lib/virtuaservices/utils/controllers/base.rb', line 167

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



152
153
154
155
156
# File 'lib/virtuaservices/utils/controllers/base.rb', line 152

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

#parse_current_routeVirtuaservices::Monitoring::Route

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

Returns:



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

def parse_current_route
  splitted = request.env['sinatra.route'].split(' ')
  return Virtuaservices::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.



161
162
163
# File 'lib/virtuaservices/utils/controllers/base.rb', line 161

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