# frozen_string_literal: true require 'drillbit/configuration' require 'drillbit/parameters' require 'drillbit/matchers/subdomain' require 'drillbit/matchers/accept_header' require 'drillbit/requests/base' require 'drillbit/responses/invalid_api_request' require 'drillbit/responses/invalid_subdomain' require 'drillbit/responses/invalid_token' module Drillbit module Middleware class ApiRequest JSON_API_MIME_TYPE_PATTERN = %r{application/vnd\.api\+json(?=\z|;)} def initialize(app) @app = app end # rubocop:disable Metrics/LineLength # :reek:FeatureEnvy def call(env) env['HTTP_X_APPLICATION_NAME'] = Drillbit.configuration.application_name request = Requests::Base.resolve(env) subdomain_matcher = Matchers::Subdomain.new accept_header_matcher = Matchers::AcceptHeader.new token = request.authorization_token return Responses::InvalidSubdomain.call(env) unless subdomain_matcher.matches?(request) return Responses::InvalidApiRequest.call(env) unless !subdomain_matcher.matches_api_subdomain?(request) || accept_header_matcher.matches?(request) return Responses::InvalidToken.call(env, application_name: request.application_name) \ unless token.valid? env['X_DECRYPTED_JSON_WEB_TOKEN'] = token.to_h env['QUERY_STRING'] = Parameters.process(env['QUERY_STRING']) env['CONTENT_TYPE'] = env['CONTENT_TYPE']. to_s. gsub JSON_API_MIME_TYPE_PATTERN, 'application/json' @app.call(env) end # rubocop:enable Metrics/LineLength end end end