module GrapeTokenAuth::OmniAuthAPICore

Module that contains the majority of the OmniAuth functionality. This module can be included in a Grape::API class that defines a resource_scope and therefore have all of the functionality with a given resource (mapping).

Public Class Methods

included(base) click to toggle source
# File lib/grape_token_auth/apis/omniauth_api.rb, line 7
    def self.included(base)
      base.helpers do
        def auth_hash
          @auth_hash ||= begin
            hash = request.env['rack.session'].delete('gta.omniauth.auth')

            # While using Grape on Rails, #session is an ActionDispatch::Request::Session class,
            # which does not preserve OmniAuth::AuthHash class @ 'gta.omniauth.auth' key,
            # converting it to Hash. Restoring
            hash.kind_of?(::OmniAuth::AuthHash) ? hash : ::OmniAuth::AuthHash.new(hash)
          end
        end

        def omniauth_params
          @omniauth_params ||= request.env['rack.session']
                               .delete('gta.omniauth.params')
        end

        def render_html(html)
          env['api.format'] = :html
          content_type 'text/html; charset=utf-8'
          html
        end

        def redirect_or_render(success_html)
          if %w(inAppBrowser newWindow).include?(success_html.window_type)
            render_html(success_html.render_html)
          elsif success_html.auth_origin_url
            # default to same-window implementation, which forwards back to
            # auth_origin_url build and redirect to destination url
            redirect success_html.full_redirect_url
          else
            # there SHOULD always be an auth_origin_url, but if someone does
            # something silly like coming straight to this url or refreshing the
            # page at the wrong time, there may not be one. In that case, just
            # render in plain text the error message if there is one or
            # otherwisei a generic message.
            fallback_render 'An error occurred'
          end
        end

        def fallback_render(text)
          render_html <<-EOD
            <html>
                    <head></head>
                    <body>
                            #{text}
                    </body>
            </html>
          EOD
        end
      end

      base.desc 'resource redirector for initial auth attempt' do
        detail <<-EOD
        Sets up the proper resource classes as a query parameter that is then
        passed along to the proper OmniAuth provider app.
        EOD
      end
      base.get ':provider' do
        qs = CGI.parse(request.env['QUERY_STRING'])
        qs['resource_class'] = [base.resource_scope]
        query_params = qs.each_with_object({}) do |args, hsh|
          hsh[args[0]] = args[1].first
        end.to_param
        omni_prefix = ::OmniAuth.config.path_prefix
        path = "#{omni_prefix}/#{params[:provider]}?#{query_params}"
        redirect path
      end

      base.desc 'OmniAuth success endpoint'
      base.get ':provider/callback' do
        fail unless omniauth_params
        fail unless auth_hash
        resource_class = GrapeTokenAuth.configuration
                         .scope_to_class(base.resource_scope)
        success_html = OmniAuthSuccessHTML.build(resource_class,
                                                 auth_hash,
                                                 omniauth_params)
        if success_html.persist_oauth_attributes!
          data = AuthorizerData.load_from_env_or_create(env)
          data.store_resource(success_html.resource, base.resource_scope)
          redirect_or_render(success_html)
        else
          status 500
        end
      end
    end

Public Instance Methods

auth_hash() click to toggle source
# File lib/grape_token_auth/apis/omniauth_api.rb, line 9
def auth_hash
  @auth_hash ||= begin
    hash = request.env['rack.session'].delete('gta.omniauth.auth')

    # While using Grape on Rails, #session is an ActionDispatch::Request::Session class,
    # which does not preserve OmniAuth::AuthHash class @ 'gta.omniauth.auth' key,
    # converting it to Hash. Restoring
    hash.kind_of?(::OmniAuth::AuthHash) ? hash : ::OmniAuth::AuthHash.new(hash)
  end
end
fallback_render(text) click to toggle source
# File lib/grape_token_auth/apis/omniauth_api.rb, line 48
        def fallback_render(text)
          render_html <<-EOD
            <html>
                    <head></head>
                    <body>
                            #{text}
                    </body>
            </html>
          EOD
        end
omniauth_params() click to toggle source
# File lib/grape_token_auth/apis/omniauth_api.rb, line 20
def omniauth_params
  @omniauth_params ||= request.env['rack.session']
                       .delete('gta.omniauth.params')
end
redirect_or_render(success_html) click to toggle source
# File lib/grape_token_auth/apis/omniauth_api.rb, line 31
def redirect_or_render(success_html)
  if %w(inAppBrowser newWindow).include?(success_html.window_type)
    render_html(success_html.render_html)
  elsif success_html.auth_origin_url
    # default to same-window implementation, which forwards back to
    # auth_origin_url build and redirect to destination url
    redirect success_html.full_redirect_url
  else
    # there SHOULD always be an auth_origin_url, but if someone does
    # something silly like coming straight to this url or refreshing the
    # page at the wrong time, there may not be one. In that case, just
    # render in plain text the error message if there is one or
    # otherwisei a generic message.
    fallback_render 'An error occurred'
  end
end
render_html(html) click to toggle source
# File lib/grape_token_auth/apis/omniauth_api.rb, line 25
def render_html(html)
  env['api.format'] = :html
  content_type 'text/html; charset=utf-8'
  html
end