virtuatable 0.5.0 → 3.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/lib/virtuatable/api/errors/base.rb +2 -0
  3. data/lib/virtuatable/api/responses.rb +20 -5
  4. data/lib/virtuatable/builders/base.rb +15 -20
  5. data/lib/virtuatable/builders/helpers/environment.rb +6 -2
  6. data/lib/virtuatable/builders/helpers/folders.rb +1 -0
  7. data/lib/virtuatable/builders/helpers/mongoid.rb +2 -0
  8. data/lib/virtuatable/builders/helpers/registration.rb +0 -7
  9. data/lib/virtuatable/builders/helpers/tests.rb +4 -1
  10. data/lib/virtuatable/builders/helpers.rb +1 -0
  11. data/lib/virtuatable/builders/tests.rb +5 -0
  12. data/lib/virtuatable/controllers/base.rb +22 -3
  13. data/lib/virtuatable/enhancers/base.rb +56 -0
  14. data/lib/virtuatable/enhancers/helpers/declarations.rb +34 -0
  15. data/lib/virtuatable/enhancers/helpers.rb +11 -0
  16. data/lib/virtuatable/enhancers.rb +13 -0
  17. data/lib/virtuatable/helpers/accounts.rb +8 -5
  18. data/lib/virtuatable/helpers/applications.rb +12 -8
  19. data/lib/virtuatable/helpers/declarators.rb +14 -11
  20. data/lib/virtuatable/helpers/parameters.rb +29 -0
  21. data/lib/virtuatable/helpers/routes.rb +3 -0
  22. data/lib/virtuatable/helpers/sessions.rb +20 -9
  23. data/lib/virtuatable/helpers.rb +1 -0
  24. data/lib/virtuatable/specs/factories/accounts.rb +54 -0
  25. data/lib/virtuatable/specs/factories/applications.rb +48 -0
  26. data/lib/virtuatable/specs/factories/groups.rb +50 -0
  27. data/lib/virtuatable/specs/factories/sessions.rb +38 -0
  28. data/lib/virtuatable/specs/factories.rb +15 -0
  29. data/lib/virtuatable/specs/shared/controllers.rb +195 -0
  30. data/lib/virtuatable/specs/shared.rb +11 -0
  31. data/lib/virtuatable/specs.rb +4 -85
  32. data/lib/virtuatable.rb +4 -0
  33. metadata +82 -114
  34. data/lib/virtuatable/helpers/gateways.rb +0 -23
  35. data/lib/virtuatable/version.rb +0 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 514569bd58f7fea17204a3f89f5d0404286204311430bfe72c9d54e4c5c40886
4
- data.tar.gz: 53c6187ab3c547bf9ce3ab5213db35606626cbc374eddc7ac65b6eef6e9361db
3
+ metadata.gz: 6aef88eba041258b63ed6c79ce0e3046642e3a8555ffbbabb9e0dfee5f061c2e
4
+ data.tar.gz: 38abd6f714841c8e0e3984075ac7e2b699f688ccb3760652a0011a07f83b8106
5
5
  SHA512:
6
- metadata.gz: 2d4890c76a8ee25542c82a16c77bbb5b17e289f6c7ce2c4d2d5b1a3a3e91469f66f3db60f58dc35115dd76eba3713077f3b4e0a9b2758bc7a73aa3497c6a0a8c
7
- data.tar.gz: 160aadc26b64faf46c7c3cb62a127db92b31888a5acea04497eaae1911c684a4848405c233af1517d9a67e0a56e37df2035c6c8b383dc42b5866329adc49e850
6
+ metadata.gz: 27c96cc009bc195c21c6dd1f97d9779e7adfb956a76e3e36a497a32e709ebc19c429f23ac1ffa1b2447ac12d848c3eda22ebd70b75a6c1cd79e0ee35754a47bf
7
+ data.tar.gz: d15814d7745b08a1c2c4eb9b68fe2671c444fbc0f5d805665398953a40786612a09967e137948e828adb79d4d7a04c8e73befbca73830e7ebd881f8e45320ae1
@@ -25,6 +25,8 @@ module Virtuatable
25
25
  @status = status
26
26
  end
27
27
 
28
+ # Returns the formatted message for this exception.
29
+ # @return [String] a message indicating what field fails, and why.
28
30
  def message
29
31
  "#{field}.#{error}"
30
32
  end
@@ -10,10 +10,10 @@ module Virtuatable
10
10
  # - :count will hold the number of items displayed in the list
11
11
  # - :items will hold the list of items.
12
12
  # @param items [Array] the items to format as a standard API response.
13
- def api_list(items)
13
+ def api_list(items, mapper = :to_h)
14
14
  halt 200, {
15
15
  count: items.count,
16
- items: items.map(&:to_h)
16
+ items: items.map { |item| enhanced_h(item, mapper.to_sym) }
17
17
  }.to_json
18
18
  end
19
19
 
@@ -21,19 +21,34 @@ module Virtuatable
21
21
  # returning the informations about the created item.
22
22
  # @param item [Object] any object that responds to #to_h to display to the user.
23
23
  def api_created(item)
24
- halt 201, item.to_h.to_json
24
+ halt 201, enhanced_json(item)
25
25
  end
26
26
 
27
27
  # Displays an item with the standards of the API.
28
28
  # @param item [Object] the item to display as a JSON formatted hash.
29
29
  def api_item(item)
30
- halt 200, item.to_h.to_json
30
+ halt 200, enhanced_json(item)
31
31
  end
32
32
 
33
33
  # Displays a message with a 200 status code
34
34
  # @param message [String] the message to display with the API standards.
35
35
  def api_ok(message)
36
- api_item({message: message})
36
+ api_item message: message
37
+ end
38
+
39
+ # Displays an empty body with a 204 status code
40
+ def api_empty
41
+ halt 204, ''
42
+ end
43
+
44
+ private
45
+
46
+ def enhanced_h(item, mapper = :to_h)
47
+ (item.respond_to?(:enhance) ? item.enhance : item).send(mapper)
48
+ end
49
+
50
+ def enhanced_json(item)
51
+ enhanced_h(item).to_json
37
52
  end
38
53
  end
39
54
  end
@@ -33,47 +33,42 @@ module Virtuatable
33
33
  attr_accessor :name
34
34
 
35
35
  # Constructor of the builder, initializing needed attributes.
36
- # @param directory [String] the directory from which load the application.
36
+ # @param locations [Array<String>] you should not modify this parameter, it
37
+ # determines from which folder the application is supposed to be loaded.
38
+ # @param path [String] the path from the loaded directory that leads to
39
+ # the root of the application (to find all other files and folders)
40
+ # @param name [String] the name of the loaded service, determining its url.
37
41
  def initialize(locations: caller_locations, path: '.', name:)
38
42
  # The base folder of the file calling the builder
39
43
  filedir = File.dirname(locations.first.absolute_path)
40
44
  @directory = File.absolute_path(File.join(filedir, path))
41
- @mode = :development
45
+ @mode = (ENV['RACK_ENV'] || 'development').to_sym
42
46
  @name = name.to_s
43
47
  end
44
48
 
49
+ # Main method to load the application. This method is called after creating
50
+ # a builder in the Virtuatable::Application class.
45
51
  def load!
46
52
  all_loaders.each do |loader|
47
53
  send(:"load_#{loader[:name]}!")
48
54
  end
49
55
  end
50
56
 
51
- # Checks the presence of all the needed environment variables.
52
- # @raise [Virtuatable::Builders::Errors::MissingEnv] if a variable is not present,
53
- # for a variable to be present she has to be a key of the ENV constant.
54
- def check_variables!
55
- names = ['INSTANCE_TYPE']
56
- names.each do |varname|
57
- exception_klass = Virtuatable::Builders::Errors::MissingEnv
58
- raise exception_klass.new(variable: varname) unless ENV.key?(varname)
59
- end
60
- end
61
-
62
- # Returns the type of the instance, default being a UNIX server
63
- # @return [Symbol] the type of instance currently loading.
64
- def type
65
- ENV['INSTANCE_TYPE'].nil? ? :unix : ENV['INSTANCE_TYPE'].to_sym
66
- end
67
-
68
57
  # Loads a list of folders given as method parameters
69
- # @param *folders [Array<String>] the folders names passed as parameters.
58
+ # @param folders [Array<String>] the folders names passed as parameters.
70
59
  def require_folders(*folders)
71
60
  folders.each do |folder|
61
+ base_path = File.join('.', folder, 'base.rb')
62
+ require base_path if File.exist?(base_path)
72
63
  path = File.join(directory, folder)
73
64
  require_all(path) if File.directory?(path)
74
65
  end
75
66
  end
76
67
 
68
+ # Returns the ancestors of this class without the included modules.
69
+ # Ruby puts the included modules in the ancestors and we don't want to
70
+ # search for the loaders in it as we know it won't be there.
71
+ # @return [Array<Class>] the ancestors of the class without included modules.
77
72
  def sanitized_ancestors
78
73
  self.class.ancestors - self.class.included_modules
79
74
  end
@@ -12,9 +12,13 @@ module Virtuatable
12
12
  declare_loader(:environment, priority: 0)
13
13
  end
14
14
 
15
+ # Loads the environment variables used in the application.
15
16
  def load_environment!
16
- Dotenv.load('.env', "#{mode}.env")
17
- Virtuatable::Specs.include_shared_examples
17
+ Dotenv.load(env_file, env_file(mode))
18
+ end
19
+
20
+ def env_file(name = '')
21
+ File.join(directory, "#{name}.env")
18
22
  end
19
23
  end
20
24
  end
@@ -13,6 +13,7 @@ module Virtuatable
13
13
  declare_loader(:folders, priority: 3)
14
14
  end
15
15
 
16
+ # Requires the main folders to run the application.
16
17
  def load_folders!
17
18
  require_folders('controllers', 'services', 'decorators')
18
19
  end
@@ -12,8 +12,10 @@ module Virtuatable
12
12
  declare_loader(:mongoid, priority: 1)
13
13
  end
14
14
 
15
+ # Loads Mongoid configuration file from the standard path.
15
16
  def load_mongoid!
16
17
  filepath = File.join(@directory, 'config', 'mongoid.yml')
18
+ filepath = File.readlink(filepath) while File.symlink?(filepath)
17
19
  ::Mongoid.load!(filepath, @mode)
18
20
  end
19
21
  end
@@ -12,9 +12,6 @@ module Virtuatable
12
12
  # @!attribute [r] service
13
13
  # @return [Arkaan::Monitoring::Service] the service linked to this application.
14
14
  attr_reader :service
15
- # @!attribute [r] instance
16
- # @return [Arkaan::Monitoring::Instance] the instance of this application.
17
- attr_reader :instance
18
15
 
19
16
  included do
20
17
  declare_loader(:registration, priority: 2)
@@ -27,10 +24,6 @@ module Virtuatable
27
24
  key: @name,
28
25
  path: "/#{@name}"
29
26
  )
30
- @instance = service.instances.first_or_create!(
31
- type: type,
32
- url: ENV['SERVICE_URL']
33
- )
34
27
  end
35
28
  end
36
29
  end
@@ -9,9 +9,12 @@ module Virtuatable
9
9
  extend ActiveSupport::Concern
10
10
 
11
11
  included do
12
- declare_loader(:tests, priority: 4)
12
+ declare_loader(:tests, priority: 5)
13
13
  end
14
14
 
15
+ # Loads the folders containing files related to the tests.
16
+ # - spec/support contains files used to confiture each test module
17
+ # - spec/shared contain all rspec shared examples and contexts
15
18
  def load_tests!
16
19
  require_folders('spec/support', 'spec/shared')
17
20
  end
@@ -11,6 +11,7 @@ module Virtuatable
11
11
  autoload :Loaders, 'virtuatable/builders/helpers/loaders'
12
12
  autoload :Mongoid, 'virtuatable/builders/helpers/mongoid'
13
13
  autoload :Registration, 'virtuatable/builders/helpers/registration'
14
+ autoload :Specs, 'virtuatable/builders/helpers/specs'
14
15
  autoload :Tests, 'virtuatable/builders/helpers/tests'
15
16
  end
16
17
  end
@@ -7,6 +7,11 @@ module Virtuatable
7
7
  # @author Vincent Courtois <courtois.vincent@outlook.com>
8
8
  class Tests < Virtuatable::Builders::Base
9
9
  include Virtuatable::Builders::Helpers::Tests
10
+ include Virtuatable::Specs::Factories::Accounts
11
+ include Virtuatable::Specs::Factories::Applications
12
+ include Virtuatable::Specs::Factories::Groups
13
+ include Virtuatable::Specs::Factories::Sessions
14
+ include Virtuatable::Specs::Shared::Controllers
10
15
 
11
16
  def initialize(path: '..', name:, locations: caller_locations)
12
17
  super(locations: locations, path: path, name: name)
@@ -1,5 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'sinatra/config_file'
4
+ require 'sinatra/custom_logger'
5
+
3
6
  module Virtuatable
4
7
  module Controllers
5
8
  # This class represents a base controller for the system, giving access
@@ -13,8 +16,6 @@ module Virtuatable
13
16
  include Virtuatable::API::Responses
14
17
  # Includes the checking methods for sessions.
15
18
  include Virtuatable::Helpers::Sessions
16
- # Include the checkers and getters for the API gateway.
17
- include Virtuatable::Helpers::Gateways
18
19
  # Include the checkers and getters for OAuth apps
19
20
  include Virtuatable::Helpers::Applications
20
21
  # Include checkers for field requirement and check
@@ -23,10 +24,16 @@ module Virtuatable
23
24
  include Virtuatable::Helpers::Routes
24
25
  # Include the getter and checkers for accounts.
25
26
  include Virtuatable::Helpers::Accounts
27
+ # Include the loading of the parameters from the JSON body
28
+ include Virtuatable::Helpers::Parameters
26
29
  # This module is extended, not included, because it provides routes
27
30
  # declaration methods used in class declarations.
28
31
  extend Virtuatable::Helpers::Declarators
29
32
 
33
+ def service
34
+ Virtuatable::Application.instance.builder.service
35
+ end
36
+
30
37
  configure do
31
38
  set :logger, Logger.new(STDOUT)
32
39
  logger.level = Logger::ERROR if ENV['RACK_ENV'] == 'test'
@@ -36,7 +43,19 @@ module Virtuatable
36
43
  end
37
44
 
38
45
  error Mongoid::Errors::Validations do |errors|
39
- api_bad_request errors.document.errors.messages.keys.first
46
+ key = errors.document.errors.messages.keys.first
47
+ message = errors.document.errors.messages[key][0]
48
+ api_bad_request key, message: message
49
+ end
50
+
51
+ error Mongoid::Errors::DocumentNotFound do |exception|
52
+ # If it's an array, it's IDs that have not been found, else it's
53
+ # another attribute given as key of the hash.
54
+ if exception.params.is_a? Array
55
+ api_not_found 'id.unknown'
56
+ else
57
+ api_not_found "#{exception.params.keys.first}.unknown"
58
+ end
40
59
  end
41
60
 
42
61
  error Virtuatable::API::Errors::NotFound do |exception|
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Virtuatable
4
+ module Enhancers
5
+ # Base class to be extended by all enhancers. It provides a way to declare
6
+ # this class as the enhancer of another class, to access the properties
7
+ # of the enhanced class as instance attributes.
8
+ #
9
+ # @author Vincent Courtois <courtois.vincent@outlook.com>
10
+ class Base
11
+ extend Virtuatable::Enhancers::Helpers::Declarations
12
+
13
+ # @!attribute [r] object
14
+ # @return [Object] the enhanced object.
15
+ attr_reader :object
16
+
17
+ def initialize(object)
18
+ @object = object
19
+ end
20
+
21
+ # That's the heart of the enhancers mecanism. This method sends the call
22
+ # to the decorated object if this one can answer it, or raises an error.
23
+ # @param name [String, Symbol] the name of the method to call on the decorated object.
24
+ # @param args [Array] the arguments passed during the call to the function.
25
+ # @param block [Block] the optional blockcode passed to the function.
26
+ def method_missing(name, *args, &block)
27
+ return enhance_association(name) if object.respond_to?(:associations) && object.associations.key?(name)
28
+
29
+ object.respond_to?(name) ? object.send(name, *args, &block) : super
30
+ end
31
+
32
+ # Determines if this object can transfer any of its calls to the decorated object.
33
+ # @param name [String] the name of the called function.
34
+ # @return [Boolean] TRUE if the decorated object can answer the call, FALSE otherwise.
35
+ def respond_to_missing?(name, _include_private = false)
36
+ object.respond_to? name
37
+ end
38
+
39
+ def enhance_association(name)
40
+ elements = object.send(name.to_sym)
41
+ return nil if elements.nil?
42
+ return enhance_collection(name, elements) if elements.is_a?(Enumerable)
43
+ return elements.enhance if elements.respond_to?(:enhance)
44
+
45
+ Virtuatable::Enhancers::Base.new(elements)
46
+ end
47
+
48
+ def enhance_collection(name, collection)
49
+ enhancable = object.associations[name].klass.respond_to?(:enhancer)
50
+ return collection.map(&:enhance) if enhancable
51
+
52
+ collection.map { |item| Virtuatable::Enhancers::Base.new(item) }
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Virtuatable
4
+ module Enhancers
5
+ module Helpers
6
+ # This module holds the static methods to declare an enhancer
7
+ # in another class, linking both and allowing to automatically
8
+ # create enhanced instances by calling the same methods in the
9
+ # enhancer that one would call on the enhanced class.
10
+ #
11
+ # @author Vincent Courtois <courtois.vincent@outlook.com>
12
+ module Declarations
13
+ # @!attribute [r] enhanced
14
+ # @return [Class] the class object of the enhanced object type.
15
+ attr_reader :enhanced
16
+
17
+ # Enhances the given class by declaring itself as its enhancer.
18
+ # @param class_object [Class] the class to enhance.
19
+ def enhances(class_object)
20
+ @enhanced = class_object
21
+ self_class = self
22
+ class_object.singleton_class.class_eval do
23
+ define_method :enhancer do
24
+ self_class
25
+ end
26
+ end
27
+ class_object.define_method :enhance do
28
+ self_class.new(self)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Virtuatable
4
+ module Enhancers
5
+ # Helpers hold the secondary modules extended or included in the base enhancer.
6
+ # @author Vincent Courtois <courtois.vincent@outlook.com>
7
+ module Helpers
8
+ autoload :Declarations, 'virtuatable/enhancers/helpers/declarations'
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Virtuatable
4
+ # The enhancers are the equivalent of a decorator.
5
+ # It provides a simple system to add features to a class
6
+ # without reopening or altering the said class.
7
+ #
8
+ # @author Vincent Courtois <courtois.vincent@outlook.com>
9
+ module Enhancers
10
+ autoload :Base, 'virtuatable/enhancers/base'
11
+ autoload :Helpers, 'virtuatable/enhancers/helpers'
12
+ end
13
+ end
@@ -5,14 +5,17 @@ module Virtuatable
5
5
  # These helpers provide methods used to get and check accounts.
6
6
  # @author Vincent Courtois <courtois.vincent@outlook.com>
7
7
  module Accounts
8
- # Gets the account linked to the current session.
9
- # @return [Arkaan::Account] the account linked to the current session.
8
+ # Raises a bad request error if the account if not found.
9
+ # @raise [Virtuatable::API::Errors::BadRequest] the error raised when the account is not found.
10
10
  def account
11
- !respond_to?(:session) || session.nil? ? nil : session.account
11
+ return @account unless @account.nil?
12
+
13
+ session_id_required if !respond_to?(:session) || session.nil?
14
+ @account = session.account
12
15
  end
13
16
 
14
- def account!
15
- api_bad_request 'session_id.required' if account.nil?
17
+ def account_id_not_found
18
+ api_bad_request('session_id.required')
16
19
  end
17
20
  end
18
21
  end
@@ -5,17 +5,21 @@ module Virtuatable
5
5
  # Helpers to get and check OAuth applications connecting the the application.
6
6
  # @author Vincent Courtois <courtois.vincent@outlook.com>
7
7
  module Applications
8
- def application
9
- Arkaan::OAuth::Application.where(key: params['app_key']).first
10
- end
11
-
12
8
  # Looks for the application sending the API's request, and raises error if not found.
13
- def application!(premium: false)
9
+ # @param [Arkaan::OAuth::Application] the application requesting the service.
10
+ def application(premium: false)
11
+ return @application unless @application.nil?
12
+
14
13
  check_presence 'app_key'
15
- api_not_found 'app_key.unknown' if application.nil?
16
- api_forbidden 'app_key.forbidden' if premium && !application.premium
14
+ @application = application_model.find_by(app_key: params['app_key'])
15
+ api_not_found 'app_key.unknown' if @application.nil?
16
+ api_forbidden 'app_key.forbidden' if premium && !@application.premium
17
+
18
+ @application
19
+ end
17
20
 
18
- application
21
+ def application_model
22
+ Arkaan::OAuth::Application
19
23
  end
20
24
  end
21
25
  end
@@ -22,10 +22,10 @@ module Virtuatable
22
22
 
23
23
  # TODO : do everything in the #send itself to avoid
24
24
  # route reload issues when premium is changed. It will
25
- # add some treatments but avoid many problems if route.premium
25
+ # add some treatments but avoid many problems if route.premium
26
26
  send(route.verb, route.path) do
27
- application!(premium: current_route.premium) && gateway!
28
- session! if current_route.authenticated
27
+ application(premium: current_route.premium)
28
+ session if current_route.authenticated
29
29
  instance_eval(&block)
30
30
  end
31
31
  end
@@ -36,7 +36,7 @@ module Virtuatable
36
36
  # @return [Arkaan::Monitoring::Route] the created route.
37
37
  def add_route(verb:, path:, options:)
38
38
  route = Arkaan::Monitoring::Route.find_or_create_by!(
39
- path: complete_path(path),
39
+ path: path,
40
40
  verb: verb.downcase,
41
41
  premium: options[:premium],
42
42
  service: builder.service,
@@ -55,14 +55,17 @@ module Virtuatable
55
55
  end
56
56
  end
57
57
 
58
+ # Add the default access permissions to a route. Any group tagged superuser
59
+ # can automatically access any newly declared_route.
60
+ # params route [Arkaan::Monitoring::Route] the route to add the permissions to.
58
61
  def add_permissions(route)
59
- route.groups = Arkaan::Permissions::Group.where(is_superuser: true)
60
- route.save!
61
- route
62
- end
63
-
64
- def complete_path(path)
65
- "#{builder.service.path}#{path == '/' ? '' : path}"
62
+ groups = Arkaan::Permissions::Group.where(is_superuser: true)
63
+ groups.each do |group|
64
+ unless route.groups.where(id: group.id).exists?
65
+ route.groups << group
66
+ route.save!
67
+ end
68
+ end
66
69
  end
67
70
 
68
71
  # Returns the current builder loading the application.
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Virtuatable
4
+ module Helpers
5
+ # Helpers to correctly build the parameters hash, even from the JSON body.
6
+ # @author Vincent Courtois <courtois.vincent@outlook.com>
7
+ module Parameters
8
+ # Returns the parameters depending on whether the request has a body
9
+ # or not. If it has a body, it parses it, otherwise it just returns the params.
10
+ # @return [Hash] the parameters sent with the request.
11
+ def params(*subset)
12
+ all_params = super.merge(body_params)
13
+ # If we don't want a subset of the parameters, return it all.
14
+ return all_params if subset.empty?
15
+
16
+ all_params.select { |key, _| subset.map(&:to_s).include? key }
17
+ end
18
+
19
+ # The parameters from the JSON body if it is sent.
20
+ # @return [Hash] the JSON body parsed as a dictionary.
21
+ def body_params
22
+ request.body.rewind
23
+ JSON.parse(request.body.read.to_s)
24
+ rescue JSON::ParserError
25
+ {}
26
+ end
27
+ end
28
+ end
29
+ end
@@ -6,6 +6,9 @@ module Virtuatable
6
6
  # Arkaan::Monitoring::Route object from whithin sinatra routes.
7
7
  # @author Vincent Courtois <courtois.vincent@outlook.com>
8
8
  module Routes
9
+ # The currently requested API route, used to see inside the block
10
+ # if the route is premium or not, authenticated or not.
11
+ # @return [Arkaan::Monitoring::Route] the currently requested route.
9
12
  def current_route
10
13
  splitted = request.env['sinatra.route'].split(' ')
11
14
  verb = splitted.first.downcase
@@ -5,12 +5,6 @@ module Virtuatable
5
5
  # This helper gives access to methods about user's session on the API.
6
6
  # @author Vincent Courtois <courtois.vincent@outlook.com>
7
7
  module Sessions
8
- # Returns the session of the user requesting the API.
9
- # @return [Arkaan::Authentication::Session] the session of the requester.
10
- def session
11
- Arkaan::Authentication::Session.where(token: params['session_id']).first
12
- end
13
-
14
8
  # Checks the session of the user requesting the API and returns an error
15
9
  # if it either not exists with the given token, or the token is not given.
16
10
  #
@@ -18,11 +12,28 @@ module Virtuatable
18
12
  # or the token not given in the parameters of the request.
19
13
  # @raise [Virtuatable::API::Errors::BadRequest] if the session token is
20
14
  # not correctly given in the parameters.
21
- def session!
15
+ #
16
+ # @return [Arkaan::Authentication::Session] the current session of the user.
17
+ def session
18
+ return @session unless @session.nil?
19
+
22
20
  check_presence 'session_id'
23
- api_not_found 'session_id.unknown' if session.nil?
21
+ @session = session_model.find_by(session_id: params['session_id'])
22
+ return api_not_found('session_id.unknown') if @session.nil?
23
+
24
+ check_current_route_access @session
25
+ end
26
+
27
+ def check_current_route_access(tmp_session)
28
+ tmp_session.account.groups.each do |group|
29
+ routes_ids = group.routes.map(&:_id)
30
+ return tmp_session if routes_ids.include?(current_route.id)
31
+ end
32
+ api_forbidden('session_id.forbidden')
33
+ end
24
34
 
25
- session
35
+ def session_model
36
+ Arkaan::Authentication::Session
26
37
  end
27
38
  end
28
39
  end
@@ -10,6 +10,7 @@ module Virtuatable
10
10
  autoload :Declarators, 'virtuatable/helpers/declarators'
11
11
  autoload :Fields, 'virtuatable/helpers/fields'
12
12
  autoload :Gateways, 'virtuatable/helpers/gateways'
13
+ autoload :Parameters, 'virtuatable/helpers/parameters'
13
14
  autoload :Routes, 'virtuatable/helpers/routes'
14
15
  autoload :Sessions, 'virtuatable/helpers/sessions'
15
16
  end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Virtuatable
4
+ module Specs
5
+ module Factories
6
+ # This module creates the factories concerning accounts, with or
7
+ # without rights, and with random values for each field.
8
+ # @author Vincent Courtois <courtois.vincent@outlook.com>
9
+ module Accounts
10
+ extend ActiveSupport::Concern
11
+
12
+ included do
13
+ declare_loader :accounts_factory, priority: 5
14
+ end
15
+
16
+ # rubocop:disable Metrics/MethodLength
17
+ def load_accounts_factory!
18
+ # This avoids multiple re-declarations by setting a flag.
19
+ return if self.class.class_variable_defined?(:@@accounts_declared)
20
+
21
+ FactoryBot.define do
22
+ factory :vt_empty_account, class: Arkaan::Account do
23
+ # Creates a random account with no particular right. This
24
+ # is useful to see when a user is NOT authorized to access
25
+ # a resource. Add groups to access resources.
26
+ factory :random_account do
27
+ username do
28
+ Faker::Alphanumeric.unique.alphanumeric(
29
+ number: 16,
30
+ min_alpha: 16
31
+ )
32
+ end
33
+ password { 'super_secure_pwd' }
34
+ password_confirmation { 'super_secure_pwd' }
35
+ email { Faker::Internet.unique.safe_email }
36
+
37
+ # This creates an administrator as "a user with access to
38
+ # all the routes in a group". This is NOT a superuser.
39
+ factory :random_administrator do
40
+ groups { [association(:random_admin_group)] }
41
+ end
42
+ end
43
+ end
44
+ end
45
+
46
+ # rubocop:disable Style/ClassVars
47
+ @@accounts_declared = true
48
+ # rubocop:enable Style/ClassVars
49
+ end
50
+ # rubocop:enable Metrics/MethodLength
51
+ end
52
+ end
53
+ end
54
+ end