Rails.application.config.middleware.use OmniAuth::Builder do
  provider :ping_federate_auth, Settings.secrets.openid.client_id, Settings.secrets.openid.client_secret
end

OmniAuth.config.logger = Rails.logger if Rails.env.development?

OmniAuth.config.on_failure = proc { |env|
  failure = OmniAuth::FailureEndpoint.new(env)

  begin
    failure.raise_out!
  rescue Exception => e
    raise e unless e.class.name.index("OmniAuth")
    failure.redirect_to_failure
  end
}

module OmniAuth
  module Strategies
    class PingFederateAuth < OmniAuth::Strategies::OAuth2
      option :name, "ping_federate_oauth2"

      option :authorize_params, {:scope => 'openid profile'}

      option :client_options, {:site => Settings.secrets.openid.host,
                               :authorize_url => Settings.secrets.openid.authorize_url,
                               :token_url => Settings.secrets.openid.token_url, }

      # omniauth attaches the query string to the callback_url by default, which triggers a redirect URL mismatch
      # on the second call to ping-federate we can drop the query_string of the redirect URL supplied to the access
      # token call to work around this.

      def callback_url
        full_host + script_name + callback_path
      end

      # uid is set after the access token is successfully retrieved from the oauth server, before omniauth
      # returns control back to the regular rails routing

      uid { raw_info['sub'] }

      info do
        {
          :realm => raw_info['domain'],
        }
      end

      extra do
        {
          'raw_info' => raw_info
        }
      end

      def raw_info
        @raw_info ||= access_token.get('/idp/userinfo.openid').parsed
      end

    end
  end
end
