<commit_before>require 'base64'
require 'sinatra/base'
require 'jwt'

def encode(payload, secret)
  ::JWT.encode(payload, secret, 'HS256')
end

def decode(token, secret, verify, options)
  ::JWT.decode(token, secret, verify, options)
end

def check_token(env)
  secret = OpenBEL::Settings[:auth][:secret]
  secret = Base64.decode64(secret)
  # whether we should verify the token
  verify = true
  # JWT options passed to decode
  options = {}

  auth_hdr = env['HTTP_AUTHORIZATION']
  if auth_hdr.nil?
    raise 'missing authorization header'
  elsif not auth_hdr.start_with?('Bearer ')
    raise 'malformed authorization header'
  end

  token = auth_hdr.split(' ')[-1]
  begin
    decoded_token = decode(token, secret, verify, options)
  rescue ::JWT::VerificationError => ve
    raise 'invalid authorization token'
  rescue ::JWT::DecodeError => je
    puts je.inspect
    raise 'malformed authorization token'
  end
  env['jwt.header'] = decoded_token.last unless decoded_token.nil?
  env['jwt.payload'] = decoded_token.first unless decoded_token.nil?

  exp = env['jwt.payload']['exp']
  now = Time.now.to_i
  if now > exp
    raise 'token expired'
  end

  env['email'] = env['jwt.payload']['email']
end

module OpenBEL
  module Middleware
    module JWT

      class Authentication
        def initialize(app, opts = {})
          @app          = app
          @paths       = opts.fetch(:paths, [])
        end

        def call(env)
          check = false
          if @paths.size == 0
            # w/out paths, always check for token
            check = true
          else
            path = env['PATH_INFO']
            # w/ paths, only check for token iff matched
            if @paths.any? {|x| path.start_with?(x)}
              check = true
            end
          end

          if check
            begin
              check_token(env)
            rescue Exception => e
              return _401(e.message)
            end
            @app.call(env)
          end
        end

        private

        def _401(message)
          hdrs = {'Content-Type' => 'application/json'}
          msg = {error: message }
          [401, hdrs, [msg.to_json]]
        end
      end
    end
  end
end<commit_msg>cleanup JWT middleware pollution; use cookies<commit_after>require 'base64'
require 'sinatra/base'
require 'jwt'

module OpenBEL
  module JWTMiddleware

    def self.encode(payload, secret)
      ::JWT.encode(payload, secret, 'HS256')
    end

    def self.decode(token, secret, verify, options)
      ::JWT.decode(token, secret, verify, options)
    end

    def self.check_cookie(env)
      cookie_hdr = env['HTTP_COOKIE']
      if cookie_hdr.nil?
        raise 'missing authorization cookie'
      end

      cookies = cookie_hdr.split('; ')
      selected = cookies.select {|x| x.start_with?('jwt=') }
      if selected.size > 0
        tokens = selected[0].split('=')
        if tokens.size > 1
          token = tokens[1]
        end
      end
      if token.nil?
        raise 'missing authorization cookie'
      end

      secret = OpenBEL::Settings[:auth][:secret]
      secret = Base64.decode64(secret)
      # whether we should verify the token
      verify = true
      # JWT options passed to decode
      options = {}

      begin
        decoded_token = decode(token, secret, verify, options)
      rescue ::JWT::VerificationError => ve
        raise 'invalid authorization token'
      rescue ::JWT::DecodeError => je
        puts je.inspect
        raise 'malformed authorization token'
      end
      env['jwt.header'] = decoded_token.last unless decoded_token.nil?
      env['jwt.payload'] = decoded_token.first unless decoded_token.nil?

      exp = env['jwt.payload']['exp']
      now = Time.now.to_i
      if now > exp
        raise 'token expired'
      end

      env['email'] = env['jwt.payload']['email']
    end

    class Authentication
      def initialize(app, opts = {})
        @app          = app
        @paths       = opts.fetch(:paths, [])
      end

      def call(env)
        check = false
        if @paths.size == 0
          # w/out paths, always check for token
          check = true
        else
          path = env['PATH_INFO']
          # w/ paths, only check for token iff matched
          if @paths.any? {|x| path.start_with?(x)}
            check = true
          end
        end

        if check
          begin
            JWTMiddleware.check_cookie(env)
          rescue Exception => e
            return _401(e.message)
          end
          @app.call(env)
        end
      end

      private

      def _401(message)
        hdrs = {'Content-Type' => 'application/json'}
        msg = {error: message }
        [401, hdrs, [msg.to_json]]
      end
    end
  end
end
{'fraction_non_alphanumeric': 0.10532968190436065, 'fraction_numerical': 0.009058352643775016, 'mean_word_length': 2.0031625553447183, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1191828', 'n_tokens_mistral': 1465, 'n_tokens_neox': 1408, 'n_words': 390}