Class: Oauthio::Client

Inherits:
OAuth2::Client
  • Object
show all
Defined in:
lib/oauthio/client.rb

Instance Method Summary collapse

Constructor Details

#initialize(client_id, client_secret, opts = {}) {|builder| ... } ⇒ Client

Instantiate a new OAuth 2.0 client using the Client ID and Client Secret registered to your application.

Parameters:

  • client_id (String)

    the client_id value

  • client_secret (String)

    the client_secret value

  • opts (Hash) (defaults to: {})

    the options to create the client with

Options Hash (opts):

  • :site (String)

    the OAuth2 provider site host

  • :authorize_url (String) — default: '/oauth/authorize'

    absolute or relative URL path to the Authorization endpoint

  • :token_url (String) — default: '/oauth/token'

    absolute or relative URL path to the Token endpoint

  • :token_method (Symbol) — default: :post

    HTTP method to use to request token (:get or :post)

  • :connection_opts (Hash) — default: {}

    Hash of connection options to pass to initialize Faraday with

  • :max_redirects (FixNum) — default: 5

    maximum number of redirects to follow

  • :raise_errors (Boolean) — default: true

    whether or not to raise an OAuth2::Error on responses with 400+ status codes

Yields:

  • (builder)

    The Faraday connection builder



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/oauthio/client.rb', line 20

def initialize(client_id, client_secret, opts={}, &block)
  _opts = opts.dup
  @id = client_id
  @secret = client_secret
  @site = _opts.delete(:site)
  @state = _opts.delete(:state)
  @jwt_secret = _opts.delete(:jwt_secret)
  ssl = _opts.delete(:ssl)
  @options = {:authorize_url    => '/auth/:provider',
              :token_url        => '/auth/access_token',
              :me_url           => '/auth/:provider/me',
              :token_method     => :post,
              :connection_opts  => {},
              :connection_build => block,
              :max_redirects    => 5,
              :raise_errors     => true}.merge(_opts)
  @options[:connection_opts][:ssl] = ssl if ssl
end

Instance Method Details

#assertionObject



175
176
177
# File 'lib/oauthio/client.rb', line 175

def assertion
  @assertion ||= OAuth2::Strategy::Assertion.new(self)
end

#auth_codeObject

The Authorization Code strategy



150
151
152
# File 'lib/oauthio/client.rb', line 150

def auth_code
  @auth_code ||= Oauthio::Strategy::AuthCode.new(self)
end

#authorize_url(provider, params = nil) ⇒ Object

The authorize endpoint URL of the OAuth2 provider

Parameters:

  • params (Hash) (defaults to: nil)

    additional query parameters



47
48
49
50
# File 'lib/oauthio/client.rb', line 47

def authorize_url(provider, params=nil)
  connection.build_url(options[:authorize_url].sub(/:provider/, provider),
                       params).to_s
end

#client_credentialsObject

The Client Credentials strategy



171
172
173
# File 'lib/oauthio/client.rb', line 171

def client_credentials
  @client_credentials ||= OAuth2::Strategy::ClientCredentials.new(self)
end

#get_token(params, access_token_opts = {}, access_token_class = AccessToken) ⇒ AccessToken

Initializes an AccessToken by making a request to the token endpoint

Parameters:

  • params (Hash)

    a Hash of params for the token endpoint

  • access (Hash)

    token options, to pass to the AccessToken object

  • class (Class)

    of access token for easier subclassing OAuth2::AccessToken

Returns:



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/oauthio/client.rb', line 113

def get_token(params, access_token_opts={}, access_token_class=AccessToken)
  opts = {:raise_errors => options[:raise_errors],
          :parse => params.delete(:parse)}
  if options[:token_method] == :post
    headers = params.delete(:headers)
    opts[:body] = params
    opts[:headers] = {'Content-Type' => 'application/x-www-form-urlencoded'}
    opts[:headers].merge!(headers) if headers
  else
    opts[:params] = params
  end
  response = request(options[:token_method], token_url, opts)

  if @jwt_secret.nil?
    # Verify state in the response matches the one in the session
    if response.state != @state
      raise ::OmniAuth::Strategies::OAuth2::CallbackError.new(nil,
                                                              :csrf_detected)
    end
  else
    if JWT.decode(response.state, @jwt_secret)[0]['state'].nil?
      raise ::OmniAuth::Strategies::OAuth2::CallbackError.new(nil,
                                                              :csrf_detected)
    end
  end

  # error = Error.new(response)
  # fail(error) if options[:raise_errors] && !(response.parsed.is_a?(Hash) && response.parsed['access_token'])

  provider_client = ::Oauthio::Client.new(@id, @secret, {:site => @site})
  access_token_class.from_hash(provider_client,
                               response.merge(access_token_opts))
end

#implicitObject

The Implicit strategy



157
158
159
# File 'lib/oauthio/client.rb', line 157

def implicit
  @implicit ||= OAuth2::Strategy::Implicit.new(self)
end

#me_url(provider, params = nil) ⇒ Object



39
40
41
42
# File 'lib/oauthio/client.rb', line 39

def me_url(provider, params=nil)
  connection.build_url(options[:me_url].sub(/:provider/, provider), params).
             to_s
end

#passwordObject

The Resource Owner Password Credentials strategy



164
165
166
# File 'lib/oauthio/client.rb', line 164

def password
  @password ||= OAuth2::Strategy::Password.new(self)
end

#request(verb, url, opts = {}) {|req| ... } ⇒ Object

Makes a request relative to the specified site root.

Parameters:

  • verb (Symbol)

    one of :get, :post, :put, :delete

  • url (String)

    URL path of request

  • opts (Hash) (defaults to: {})

    the options to make the request with

Options Hash (opts):

  • :params (Hash)

    additional query parameters for the URL of the request

  • :body (Hash, String)

    the body of the request

  • :headers (Hash)

    http request headers

  • :raise_errors (Boolean)

    whether or not to raise an OAuth2::Error on 400+ status code response for this request. Will default to client option

  • :parse (Symbol)

    @see Response::initialize

Yields:

  • (req)

    The Faraday request



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/oauthio/client.rb', line 64

def request(verb, url, opts={}) # rubocop:disable CyclomaticComplexity, MethodLength
  url = connection.build_url(url, opts[:params]).to_s

  response =
    connection.run_request(verb, url, opts[:body], opts[:headers]) do |req|
      yield(req) if block_given?
    end

  # Only really care about the status and the actual return body.
  # Oauth2 strategy wraps the response in a Response object that handles parsing and whatnot. That is great when
  # support for multiple options is needed, however we only have to conform to a single interface. We will take
  # the easy route of always expecting a json response.
  status = response.status
  headers = response.headers
  response = JSON.parse(response.body)
  response['status'] = status
  response['headers'] = headers
  response = Hashie::Mash.new(response)

  case response.status
  when 301, 302, 303, 307
    opts[:redirect_count] ||= 0
    opts[:redirect_count] += 1
    return response if opts[:redirect_count] > options[:max_redirects]
    if response.status == 303
      verb = :get
      opts.delete(:body)
    end
    request(verb, response.headers['location'], opts)
  when 200..299, 300..399
    # on non-redirecting 3xx statuses, just return the response
    response
  when 400..599
    error = OAuth2::Error.new(response)
    fail(error) if opts.fetch(:raise_errors, options[:raise_errors])
    response.error = error
    response
  else
    error = OAuth2::Error.new(response)
    fail(error, "Unhandled status code value of #{response.status}")
  end
end