# frozen_string_literal: true require 'drillbit/tokens/json_web_tokens/invalid' require 'drillbit/tokens/json_web_token' module Drillbit module Requests class Base BASE64_PATTERN = %r{[A-Za-z0-9_/\+\=\-\.]} BASE64_TOKEN_PARAM_NAME = 'token_b64' JSON_WEB_TOKEN_PARAM_NAME = 'token_jwt' JSON_WEB_TOKEN_PATTERN = /(#{BASE64_PATTERN}+?\.){4}#{BASE64_PATTERN}+?/ BASE64_TOKEN_HEADER_PATTERN = /\A(?:Basic|Bearer)\s+(.*)\z/ JSON_WEB_TOKEN_HEADER_PATTERN = /\AToken\s+(.*)\z/ attr_accessor :token_private_key, :request def initialize(token_private_key: Drillbit.configuration.token_private_key, request:) self.token_private_key = token_private_key self.request = request end def accept_header if accept_header_from_header.valid? || accept_header_from_params.invalid? accept_header_from_header else accept_header_from_params end end # rubocop:disable Style/ClosingParenthesisIndentation def authorization_token if ( !authorization_token_from_header.blank? && authorization_token_from_header.valid? ) \ || ( authorization_token_from_params.blank? || !authorization_token_from_params.valid? ) authorization_token_from_header else authorization_token_from_params end end # rubocop:enable Style/ClosingParenthesisIndentation def application_name raw_request_application_name || Drillbit.configuration.application_name end def subdomain @subdomain ||= raw_host[/\A([a-z\-]+)/i, 1] end def self.resolve(original_request) if original_request.is_a? self original_request elsif original_request.respond_to? :headers rails_request_class.new(request: original_request) else rack_request_class.new(request: original_request) end end def self.rails_request_class require 'drillbit/requests/rails' Object.const_get('Drillbit::Requests::Rails') end def self.rack_request_class require 'drillbit/requests/rack' Object.const_get('Drillbit::Requests::Rack') end private def accept_header_from_header AcceptHeader.new(application: application_name, header: raw_accept_header_from_header || '') end def accept_header_from_params AcceptHeader.new(application: application_name, header: raw_accept_header_from_params || '') end def authorization_token_from_header case raw_authorization_header when JSON_WEB_TOKEN_HEADER_PATTERN Tokens::JsonWebToken.__send__( "from_#{Drillbit.configuration.token_type.downcase}", raw_authorization_header[JSON_WEB_TOKEN_HEADER_PATTERN, 1], private_key: token_private_key, ) when BASE64_TOKEN_HEADER_PATTERN Tokens::Base64.convert( raw_token: raw_authorization_header[BASE64_TOKEN_HEADER_PATTERN, 1], ) else Tokens::Null.instance end end def raw_host request.fetch('HTTP_HOST', '') end end end end