class Signet::OAuth2::Client

Attributes

sub[RW]

The target “sub” when issuing assertions. Used in some Admin SDK APIs.

Public Class Methods

new(options={}) click to toggle source

Creates an OAuth 2.0 client.

@param [Hash] options

The configuration parameters for the client.
- <code>:authorization_uri</code> -
  The authorization server's HTTP endpoint capable of
  authenticating the end-user and obtaining authorization.
- <code>:token_credential_uri</code> -
  The authorization server's HTTP endpoint capable of issuing
  tokens and refreshing expired tokens.
- <code>:client_id</code> -
  A unique identifier issued to the client to identify itself to the
  authorization server.
- <code>:client_secret</code> -
  A shared symmetric secret issued by the authorization server,
  which is used to authenticate the client.
- <code>:scope</code> -
  The scope of the access request, expressed either as an Array
  or as a space-delimited String.
- <code>:state</code> -
  An arbitrary string designed to allow the client to maintain state.
- <code>:code</code> -
  The authorization code received from the authorization server.
- <code>:redirect_uri</code> -
  The redirection URI used in the initial request.
- <code>:username</code> -
  The resource owner's username.
- <code>:password</code> -
  The resource owner's password.
- <code>:issuer</code> -
  Issuer ID when using assertion profile
- <code>:person</code> -
  Target user for assertions
- <code>:expiry</code> -
  Number of seconds assertions are valid for
- <code>:signing_key</code> -
  Signing key when using assertion profile
- <code>:refresh_token</code> -
  The refresh token associated with the access token
  to be refreshed.
- <code>:access_token</code> -
  The current access token for this client.
- <code>:id_token</code> -
  The current ID token for this client.
- <code>:extension_parameters</code> -
  When using an extension grant type, this the set of parameters used
  by that extension.

@example

client = Signet::OAuth2::Client.new(
  :authorization_endpoint_uri =>
    'https://example.server.com/authorization',
  :token_endpoint_uri =>
    'https://example.server.com/token',
  :client_id => 'anonymous',
  :client_secret => 'anonymous',
  :scope => 'example',
  :redirect_uri => 'https://example.client.com/oauth'
)

@see #update!

# File lib/signet/oauth_2/client.rb, line 91
def initialize(options={})
  self.update!(options)
end

Public Instance Methods

access_token() click to toggle source

Returns the access token associated with this client.

@return [String] The access token.

# File lib/signet/oauth_2/client.rb, line 655
def access_token
  return @access_token ||= nil
end
access_token=(new_access_token) click to toggle source

Sets the access token associated with this client.

@param [String] new_access_token

The access token.
# File lib/signet/oauth_2/client.rb, line 664
def access_token=(new_access_token)
  @access_token = new_access_token
end
additional_parameters() click to toggle source

Returns the set of additional (non standard) parameters to be used by the client.

@return [Hash] The pass through parameters.

# File lib/signet/oauth_2/client.rb, line 616
def additional_parameters
  return @additional_parameters ||= {}
end
additional_parameters=(new_additional_parameters) click to toggle source

Sets additional (non standard) parameters to be used by the client.

@param [Hash] new_additional_parameters

The parameters.
# File lib/signet/oauth_2/client.rb, line 625
def additional_parameters=(new_additional_parameters)
  if new_additional_parameters.respond_to?(:to_hash)
    @additional_parameters = new_additional_parameters.to_hash
  else
    raise TypeError,
          "Expected Hash, got #{new_additional_parameters.class}."
  end
end
audience() click to toggle source

Returns the issuer ID associated with this client. Used only by the assertion grant type.

@return [String] Target audience ID.

# File lib/signet/oauth_2/client.rb, line 500
def audience
  return @audience
end
audience=(new_audience) click to toggle source

Sets the target audience ID when issuing assertions. Used only by the assertion grant type.

@param [String] new_audience

Target audience ID
# File lib/signet/oauth_2/client.rb, line 510
def audience=(new_audience)
  @audience = new_audience
end
authorization_uri(options={}) click to toggle source

Returns the authorization URI that the user should be redirected to.

@return [Addressable::URI] The authorization URI.

@see Signet::OAuth2.generate_authorization_uri

# File lib/signet/oauth_2/client.rb, line 234
def authorization_uri(options={})
  # Normalize external input
  options = deep_hash_normalize(options)

  return nil if @authorization_uri == nil
  unless options[:response_type]
    options[:response_type] = :code
  end
  unless options[:access_type]
    options[:access_type] = :offline
  end
  options[:client_id] ||= self.client_id
  options[:redirect_uri] ||= self.redirect_uri
  if options[:prompt] && options[:approval_prompt]
    raise ArgumentError, "prompt and approval_prompt are mutually exclusive parameters"
  end
  if !options[:client_id]
    raise ArgumentError, "Missing required client identifier."
  end
  unless options[:redirect_uri]
    raise ArgumentError, "Missing required redirect URI."
  end
  if !options[:scope] && self.scope
    options[:scope] = self.scope.join(' ')
  end
  options[:state] = self.state unless options[:state]
  options.merge!(self.additional_parameters.merge(options[:additional_parameters] || {}))
  options.delete(:additional_parameters)
  uri = Addressable::URI.parse(
    ::Signet::OAuth2.generate_authorization_uri(
      @authorization_uri, options
    )
  )
  if uri.normalized_scheme != 'https'
    raise Signet::UnsafeOperationError,
      'Authorization endpoint must be protected by TLS.'
  end
  return uri
end
authorization_uri=(new_authorization_uri) click to toggle source

Sets the authorization URI for this client.

@param [Addressable::URI, Hash, String, to_str] new_authorization_uri

The authorization URI.
# File lib/signet/oauth_2/client.rb, line 279
def authorization_uri=(new_authorization_uri)
  @authorization_uri = coerce_uri(new_authorization_uri)
end
clear_credentials!() click to toggle source

Removes all credentials from the client.

# File lib/signet/oauth_2/client.rb, line 777
def clear_credentials!
  @access_token = nil
  @refresh_token = nil
  @id_token = nil
  @username = nil
  @password = nil
  @code = nil
  @issued_at = nil
  @expires_in = nil
end
client_id() click to toggle source

Returns the client identifier for this client.

@return [String] The client identifier.

# File lib/signet/oauth_2/client.rb, line 314
def client_id
  return @client_id
end
client_id=(new_client_id) click to toggle source

Sets the client identifier for this client.

@param [String] new_client_id

The client identifier.
# File lib/signet/oauth_2/client.rb, line 323
def client_id=(new_client_id)
  @client_id = new_client_id
end
client_secret() click to toggle source

Returns the client secret for this client.

@return [String] The client secret.

# File lib/signet/oauth_2/client.rb, line 331
def client_secret
  return @client_secret
end
client_secret=(new_client_secret) click to toggle source

Sets the client secret for this client.

@param [String] new_client_secret

The client secret.
# File lib/signet/oauth_2/client.rb, line 340
def client_secret=(new_client_secret)
  @client_secret = new_client_secret
end
code() click to toggle source

Returns the authorization code issued to this client. Used only by the authorization code access grant type.

@return [String] The authorization code.

# File lib/signet/oauth_2/client.rb, line 401
def code
  return @code
end
code=(new_code) click to toggle source

Sets the authorization code issued to this client. Used only by the authorization code access grant type.

@param [String] new_code

The authorization code.
# File lib/signet/oauth_2/client.rb, line 411
def code=(new_code)
  @code = new_code
end
coerce_uri(incoming_uri) click to toggle source

Addressable expects URIs formatted as hashes to come in with symbols as keys. Returns nil implicitly for the nil case.

# File lib/signet/oauth_2/client.rb, line 302
def coerce_uri(incoming_uri)
  if incoming_uri.is_a? Hash
    Addressable::URI.new(deep_hash_normalize(incoming_uri))
  elsif incoming_uri
    Addressable::URI.parse(incoming_uri)
  end
end
decoded_id_token(public_key=nil) click to toggle source

Returns the decoded ID token associated with this client.

@param [OpenSSL::PKey::RSA, Object] public_key

The public key to use to verify the ID token. Skips verification if
omitted.

@return [String] The decoded ID token.

# File lib/signet/oauth_2/client.rb, line 693
def decoded_id_token(public_key=nil)
  payload, header = JWT.decode(self.id_token, public_key, !!public_key)
  if !payload.has_key?('aud')
    raise Signet::UnsafeOperationError, 'No ID token audience declared.'
  elsif payload['aud'] != self.client_id
    raise Signet::UnsafeOperationError,
      'ID token audience did not match Client ID.'
  end
  return payload
end
expired?() click to toggle source

Returns true if the access token has expired.

@return [TrueClass, FalseClass]

The expiration state of the access token.
# File lib/signet/oauth_2/client.rb, line 770
def expired?
  return self.expires_at != nil && Time.now >= self.expires_at
end
expires_at() click to toggle source

Returns the timestamp the access token will expire at.

@return [Integer] The access token lifetime.

# File lib/signet/oauth_2/client.rb, line 748
def expires_at
  if @expires_at
    @expires_at
  elsif @issued_at && @expires_in
    return @issued_at + @expires_in
  else
    return nil
  end
end
expires_at=(new_expires_at) click to toggle source

Limits the lifetime of the access token as number of seconds since the Epoch

# File lib/signet/oauth_2/client.rb, line 761
def expires_at=(new_expires_at)
  @expires_at = Time.at new_expires_at
end
expires_in() click to toggle source

Returns the lifetime of the access token in seconds.

@return [Integer] The access token lifetime.

# File lib/signet/oauth_2/client.rb, line 708
def expires_in
  return @expires_in
end
expires_in=(new_expires_in) click to toggle source

Sets the lifetime of the access token in seconds. Resets the issued timestamp.

@param [String] new_expires_in

The access token lifetime.
# File lib/signet/oauth_2/client.rb, line 718
def expires_in=(new_expires_in)
  if new_expires_in != nil
    @expires_in = new_expires_in.to_i
    @issued_at = Time.now
  else
    @expires_in, @issued_at = nil, nil
  end
end
expiry() click to toggle source

Returns the number of seconds assertions are valid for Used only by the assertion grant type.

@return [Fixnum] Assertion expiry, in seconds

# File lib/signet/oauth_2/client.rb, line 547
def expiry
  return @expiry
end
expiry=(new_expiry) click to toggle source

Sets the number of seconds assertions are valid for Used only by the assertion grant type.

@param [String] new_expiry

Assertion expiry, in seconds
# File lib/signet/oauth_2/client.rb, line 557
def expiry=(new_expiry)
  @expiry = new_expiry
end
extension_parameters() click to toggle source

Returns the set of extension parameters used by the client. Used only by extension access grant types.

@return [Hash] The extension parameters.

# File lib/signet/oauth_2/client.rb, line 593
def extension_parameters
  return @extension_parameters ||= {}
end
extension_parameters=(new_extension_parameters) click to toggle source

Sets extension parameters used by the client. Used only by extension access grant types.

@param [Hash] new_extension_parameters

The parameters.
# File lib/signet/oauth_2/client.rb, line 603
def extension_parameters=(new_extension_parameters)
  if new_extension_parameters.respond_to?(:to_hash)
    @extension_parameters = new_extension_parameters.to_hash
  else
    raise TypeError,
      "Expected Hash, got #{new_extension_parameters.class}."
  end
end
fetch_access_token(options={}) click to toggle source
# File lib/signet/oauth_2/client.rb, line 931
def fetch_access_token(options={})
  options = deep_hash_normalize(options)

  options[:connection] ||= Faraday.default_connection
  request = self.generate_access_token_request(options)
  request_env = request.to_env(options[:connection])
  request_env[:request] ||= request
  response = options[:connection].app.call(request_env)
  if response.status.to_i == 200
    content_type = response.headers['content-type']
    return ::Signet::OAuth2.parse_credentials(response.body, content_type)
  elsif [400, 401, 403].include?(response.status.to_i)
    message = 'Authorization failed.'
    if response.body.to_s.strip.length > 0
      message += "  Server message:\n#{response.body.to_s.strip}"
    end
    raise ::Signet::AuthorizationError.new(
      message, :request => request, :response => response
    )
  else
    message = "Unexpected status code: #{response.status}."
    if response.body.to_s.strip.length > 0
      message += "  Server message:\n#{response.body.to_s.strip}"
    end
    raise ::Signet::AuthorizationError.new(
      message, :request => request, :response => response
    )
  end
end
fetch_access_token!(options={}) click to toggle source
# File lib/signet/oauth_2/client.rb, line 961
def fetch_access_token!(options={})
  options = deep_hash_normalize(options)

  token_hash = self.fetch_access_token(options)
  if token_hash
    # No-op for grant types other than `authorization_code`.
    # An authorization code is a one-time use token and is immediately
    # revoked after usage.
    self.code = nil
    self.issued_at = Time.now
    self.update_token!(token_hash)
  end
  return token_hash
end
fetch_protected_resource(options={}) click to toggle source

Transmits a request for a protected resource.

@param [Hash] options

The configuration parameters for the request.
- <code>:request</code> -
  A pre-constructed request.  An OAuth 2 Authorization header
  will be added to it, as well as an explicit Cache-Control
  `no-store` directive.
- <code>:method</code> -
  The HTTP method for the request.  Defaults to 'GET'.
- <code>:uri</code> -
  The URI for the request.
- <code>:headers</code> -
  The HTTP headers for the request.
- <code>:body</code> -
  The HTTP body for the request.
- <code>:realm</code> -
  The Authorization realm.  See RFC 2617.
- <code>:connection</code> -
  The HTTP connection to use.
  Must be of type <code>Faraday::Connection</code>.

@example

# Using Net::HTTP
response = client.fetch_protected_resource(
  :uri => 'http://www.example.com/protected/resource'
)

@example

# Using Typhoeus
response = client.fetch_protected_resource(
  :request => Typhoeus::Request.new(
    'http://www.example.com/protected/resource'
  ),
  :adapter => HTTPAdapter::TyphoeusAdapter.new,
  :connection => connection
)

@return [Array] The response object.

# File lib/signet/oauth_2/client.rb, line 1095
def fetch_protected_resource(options={})
  options = deep_hash_normalize(options)

  options[:connection] ||= Faraday.default_connection
  request = self.generate_authenticated_request(options)
  request_env = request.to_env(options[:connection])
  request_env[:request] ||= request
  response = options[:connection].app.call(request_env)
  if response.status.to_i == 401
    # When accessing a protected resource, we only want to raise an
    # error for 401 responses.
    message = 'Authorization failed.'
    if response.body.to_s.strip.length > 0
      message += "  Server message:\n#{response.body.to_s.strip}"
    end
    raise ::Signet::AuthorizationError.new(
      message, :request => request, :response => response
    )
  else
    return response
  end
end
generate_access_token_request(options={}) click to toggle source

Generates a request for token credentials.

@param [Hash] options

The configuration parameters for the request.
- <code>:code</code> -
  The authorization code.

@return [Array] The request object.

# File lib/signet/oauth_2/client.rb, line 884
def generate_access_token_request(options={})
  options = deep_hash_normalize(options)

  if self.token_credential_uri == nil
    raise ArgumentError, 'Missing token endpoint URI.'
  end

  options[:connection] ||= Faraday.default_connection
  method = 'POST'
  parameters = {"grant_type" => self.grant_type}
  case self.grant_type
  when 'authorization_code'
    parameters['code'] = self.code
    parameters['redirect_uri'] = self.redirect_uri
  when 'password'
    parameters['username'] = self.username
    parameters['password'] = self.password
  when 'refresh_token'
    parameters['refresh_token'] = self.refresh_token
  when 'urn:ietf:params:oauth:grant-type:jwt-bearer'
    parameters['assertion'] = self.to_jwt(options)
  else
    if self.redirect_uri
      # Grant type was intended to be `authorization_code` because of
      # the presence of the redirect URI.
      raise ArgumentError, 'Missing authorization code.'
    end
    parameters.merge!(self.extension_parameters)
  end
  parameters['client_id'] = self.client_id unless self.client_id.nil?
  parameters['client_secret'] = self.client_secret unless self.client_secret.nil?
  headers = [
    ['Cache-Control', 'no-store'],
    ['Content-Type', 'application/x-www-form-urlencoded']
  ]
  parameters.merge!(self.additional_parameters.merge(options[:additional_parameters] || {}))
  return options[:connection].build_request(
    method.to_s.downcase.to_sym
  ) do |req|
    req.url(Addressable::URI.parse(
      self.token_credential_uri
    ).normalize.to_s)
    req.headers = Faraday::Utils::Headers.new(headers)
    req.body = Addressable::URI.form_encode(parameters)
  end
end
generate_authenticated_request(options={}) click to toggle source

Generates an authenticated request for protected resources.

@param [Hash] options

The configuration parameters for the request.
- <code>:request</code> -
  A pre-constructed request.  An OAuth 2 Authorization header
  will be added to it, as well as an explicit Cache-Control
  `no-store` directive.
- <code>:method</code> -
  The HTTP method for the request.  Defaults to 'GET'.
- <code>:uri</code> -
  The URI for the request.
- <code>:headers</code> -
  The HTTP headers for the request.
- <code>:body</code> -
  The HTTP body for the request.
- <code>:realm</code> -
  The Authorization realm.  See RFC 2617.

@return [Faraday::Request] The request object.

# File lib/signet/oauth_2/client.rb, line 1005
def generate_authenticated_request(options={})
  options = deep_hash_normalize(options)

  if self.access_token == nil
    raise ArgumentError, 'Missing access token.'
  end
  options = {
    :realm => nil
  }.merge(options)

  if options[:request].kind_of?(Faraday::Request)
    request = options[:request]
  else
    if options[:request].kind_of?(Array)
      method, uri, headers, body = options[:request]
    else
      method = options[:method] || :get
      uri = options[:uri]
      headers = options[:headers] || []
      body = options[:body] || ''
    end
    headers = headers.to_a if headers.kind_of?(Hash)
    request_components = {
      :method => method,
      :uri => uri,
      :headers => headers,
      :body => body
    }
    # Verify that we have all pieces required to return an HTTP request
    request_components.each do |(key, value)|
      unless value
        raise ArgumentError, "Missing :#{key} parameter."
      end
    end
    method = method.to_s.downcase.to_sym
    request = options[:connection].build_request(method.to_s.downcase.to_sym) do |req|
      req.url(Addressable::URI.parse(uri).normalize.to_s)
      req.headers = Faraday::Utils::Headers.new(headers)
      req.body = body
    end
  end

  request['Authorization'] = ::Signet::OAuth2.generate_bearer_authorization_header(
    self.access_token,
    options[:realm] ? [['realm', options[:realm]]] : nil
  )
  request['Cache-Control'] = 'no-store'
  return request
end
grant_type() click to toggle source

Returns the inferred grant type, based on the current state of the client object. Returns `“none”` if the client has insufficient information to make an in-band authorization request.

@return [String]

The inferred grant type.
# File lib/signet/oauth_2/client.rb, line 796
def grant_type
  @grant_type ||= nil
  if @grant_type
    return @grant_type
  else
    if self.code && self.redirect_uri
      'authorization_code'
    elsif self.refresh_token
      'refresh_token'
    elsif self.username && self.password
      'password'
    elsif self.issuer && self.signing_key
      'urn:ietf:params:oauth:grant-type:jwt-bearer'
    else
      # We don't have sufficient auth information, assume an out-of-band
      # authorization arrangement between the client and server, or an
      # extension grant type.
      nil
    end
  end
end
grant_type=(new_grant_type) click to toggle source
# File lib/signet/oauth_2/client.rb, line 818
def grant_type=(new_grant_type)
  case new_grant_type
  when 'authorization_code', 'refresh_token',
      'password', 'client_credentials'
    @grant_type = new_grant_type
  else
    @grant_type = Addressable::URI.parse(new_grant_type)
  end
end
id_token() click to toggle source

Returns the ID token associated with this client.

@return [String] The ID token.

# File lib/signet/oauth_2/client.rb, line 672
def id_token
  return @id_token ||= nil
end
id_token=(new_id_token) click to toggle source

Sets the ID token associated with this client.

@param [String] new_id_token

The ID token.
# File lib/signet/oauth_2/client.rb, line 681
def id_token=(new_id_token)
  @id_token = new_id_token
end
issued_at() click to toggle source

Returns the timestamp the access token was issued at.

@return [Integer] The access token issuance time.

# File lib/signet/oauth_2/client.rb, line 731
def issued_at
  return @issued_at
end
issued_at=(new_issued_at) click to toggle source

Sets the timestamp the access token was issued at.

@param [String] new_issued_at

The access token issuance time.
# File lib/signet/oauth_2/client.rb, line 740
def issued_at=(new_issued_at)
  @issued_at = new_issued_at
end
issuer() click to toggle source

Returns the issuer ID associated with this client. Used only by the assertion grant type.

@return [String] Issuer id.

# File lib/signet/oauth_2/client.rb, line 481
def issuer
  return @issuer
end
issuer=(new_issuer) click to toggle source

Sets the issuer ID associated with this client. Used only by the assertion grant type.

@param [String] new_issuer

Issuer ID (typical in email adddress form).
# File lib/signet/oauth_2/client.rb, line 491
def issuer=(new_issuer)
  @issuer = new_issuer
end
password() click to toggle source

Returns the password associated with this client. Used only by the resource owner password credential access grant type.

@return [String] The password.

# File lib/signet/oauth_2/client.rb, line 462
def password
  return @password
end
password=(new_password) click to toggle source

Sets the password associated with this client. Used only by the resource owner password credential access grant type.

@param [String] new_password

The password.
# File lib/signet/oauth_2/client.rb, line 472
def password=(new_password)
  @password = new_password
end
person()
Alias for: principal
person=(new_person)
Alias for: principal=
principal() click to toggle source

Returns the target resource owner for impersonation. Used only by the assertion grant type.

@return [String] Target user for impersonation.

# File lib/signet/oauth_2/client.rb, line 519
def principal
  return @principal
end
Also aliased as: person
principal=(new_person) click to toggle source

Sets the target resource owner for impersonation. Used only by the assertion grant type.

@param [String] new_person

Target user for impersonation
# File lib/signet/oauth_2/client.rb, line 529
def principal=(new_person)
  @principal = new_person
end
Also aliased as: person=
redirect_uri() click to toggle source

Returns the redirect URI for this client.

@return [String] The redirect URI.

# File lib/signet/oauth_2/client.rb, line 419
def redirect_uri
  return @redirect_uri
end
redirect_uri=(new_redirect_uri) click to toggle source

Sets the redirect URI for this client.

@param [String] new_redirect_uri

The redirect URI.
# File lib/signet/oauth_2/client.rb, line 428
def redirect_uri=(new_redirect_uri)
  new_redirect_uri = Addressable::URI.parse(new_redirect_uri)
  #TODO - Better solution to allow google postmessage flow. For now, make an exception to the spec.
  if new_redirect_uri == nil|| new_redirect_uri.absolute? || uri_is_postmessage?(new_redirect_uri) || uri_is_oob?(new_redirect_uri)
    @redirect_uri = new_redirect_uri
  else
    raise ArgumentError, "Redirect URI must be an absolute URI."
  end
end
refresh!(options={}) click to toggle source

Refresh the access token, if possible

# File lib/signet/oauth_2/client.rb, line 978
def refresh!(options={})
  options = deep_hash_normalize(options)

  self.fetch_access_token!(options)
end
refresh_token() click to toggle source

Returns the refresh token associated with this client.

@return [String] The refresh token.

# File lib/signet/oauth_2/client.rb, line 638
def refresh_token
  return @refresh_token ||= nil
end
refresh_token=(new_refresh_token) click to toggle source

Sets the refresh token associated with this client.

@param [String] new_refresh_token

The refresh token.
# File lib/signet/oauth_2/client.rb, line 647
def refresh_token=(new_refresh_token)
  @refresh_token = new_refresh_token
end
scope() click to toggle source

Returns the scope for this client. Scope is a list of access ranges defined by the authorization server.

@return [Array] The scope of access the client is requesting.

# File lib/signet/oauth_2/client.rb, line 349
def scope
  return @scope
end
scope=(new_scope) click to toggle source

Sets the scope for this client.

@param [Array, String] new_scope

The scope of access the client is requesting.  This may be
expressed as either an Array of String objects or as a
space-delimited String.
# File lib/signet/oauth_2/client.rb, line 360
def scope=(new_scope)
  case new_scope
  when Array
    new_scope.each do |scope|
      if scope.include?(' ')
        raise ArgumentError,
          "Individual scopes cannot contain the space character."
      end
    end
    @scope = new_scope
  when String
    @scope = new_scope.split(' ')
  when nil
    @scope = nil
  else
    raise TypeError, "Expected Array or String, got #{new_scope.class}"
  end
end
signing_algorithm() click to toggle source

Algorithm used for signing JWTs @return [String] Signing algorithm

# File lib/signet/oauth_2/client.rb, line 584
def signing_algorithm
  self.signing_key.is_a?(String) ? "HS256" : "RS256"
end
signing_key() click to toggle source

Returns the signing key associated with this client. Used only by the assertion grant type.

@return [String,OpenSSL::PKey] Signing key

# File lib/signet/oauth_2/client.rb, line 567
def signing_key
  return @signing_key
end
signing_key=(new_key) click to toggle source

Sets the signing key when issuing assertions. Used only by the assertion grant type.

@param [String, OpenSSL::Pkey] new_key

Signing key. Either private key for RSA or string for HMAC algorithm
# File lib/signet/oauth_2/client.rb, line 577
def signing_key=(new_key)
  @signing_key = new_key
end
state() click to toggle source

Returns the client's current state value.

@return [String] The state value.

# File lib/signet/oauth_2/client.rb, line 383
def state
  return @state
end
state=(new_state) click to toggle source

Sets the client's current state value.

@param [String] new_state

The state value.
# File lib/signet/oauth_2/client.rb, line 392
def state=(new_state)
  @state = new_state
end
to_json() click to toggle source

Serialize the client object to JSON.

@note A serialized client contains sensitive information. Persist or transmit with care.

@return [String] A serialized JSON representation of the client.

# File lib/signet/oauth_2/client.rb, line 851
def to_json
  return MultiJson.dump({
    'authorization_uri' => self.authorization_uri,
    'token_credential_uri' => self.token_credential_uri,
    'client_id' => self.client_id,
    'client_secret' => self.client_secret,
    'scope' => self.scope,
    'state' => self.state,
    'code' => self.code,
    'redirect_uri' => self.redirect_uri,
    'username' => self.username,
    'password' => self.password,
    'issuer' => self.issuer,
    'audience' => self.audience,
    'person' => self.person,
    'expiry' => self.expiry,
    'signing_key' => self.signing_key,
    'refresh_token' => self.refresh_token,
    'access_token' => self.access_token,
    'id_token' => self.id_token,
    'extension_parameters' => self.extension_parameters
  })
end
to_jwt(options={}) click to toggle source
# File lib/signet/oauth_2/client.rb, line 828
def to_jwt(options={})
  options = deep_hash_normalize(options)

  now = Time.new
  skew = options[:skew] || 60
  assertion = {
    "iss" => self.issuer,
    "scope" => self.scope.join(' '),
    "aud" => self.audience,
    "exp" => (now + self.expiry).to_i,
    "iat" => (now - skew).to_i
  }
  assertion['prn'] = self.person unless self.person.nil?
  assertion['sub'] = self.sub unless self.sub.nil?
  JWT.encode(assertion, self.signing_key, self.signing_algorithm)
end
token_credential_uri() click to toggle source

Returns the token credential URI for this client.

@return [Addressable::URI] The token credential URI.

# File lib/signet/oauth_2/client.rb, line 287
def token_credential_uri
  return @token_credential_uri
end
token_credential_uri=(new_token_credential_uri) click to toggle source

Sets the token credential URI for this client.

@param [Addressable::URI, Hash, String, to_str] new_token_credential_uri

The token credential URI.
# File lib/signet/oauth_2/client.rb, line 296
def token_credential_uri=(new_token_credential_uri)
  @token_credential_uri = coerce_uri(new_token_credential_uri)
end
update!(options={}) click to toggle source

Updates an OAuth 2.0 client.

@param [Hash] options

The configuration parameters for the client.
- <code>:authorization_uri</code> -
  The authorization server's HTTP endpoint capable of
  authenticating the end-user and obtaining authorization.
- <code>:token_credential_uri</code> -
  The authorization server's HTTP endpoint capable of issuing
  tokens and refreshing expired tokens.
- <code>:client_id</code> -
  A unique identifier issued to the client to identify itself to the
  authorization server.
- <code>:client_secret</code> -
  A shared symmetric secret issued by the authorization server,
  which is used to authenticate the client.
- <code>:scope</code> -
  The scope of the access request, expressed either as an Array
  or as a space-delimited String.
- <code>:state</code> -
  An arbitrary string designed to allow the client to maintain state.
- <code>:code</code> -
  The authorization code received from the authorization server.
- <code>:redirect_uri</code> -
  The redirection URI used in the initial request.
- <code>:username</code> -
  The resource owner's username.
- <code>:password</code> -
  The resource owner's password.
- <code>:issuer</code> -
  Issuer ID when using assertion profile
- <code>:audience</code> -
  Target audience for assertions
- <code>:person</code> -
  Target user for assertions
- <code>:expiry</code> -
  Number of seconds assertions are valid for
- <code>:signing_key</code> -
  Signing key when using assertion profile
- <code>:refresh_token</code> -
  The refresh token associated with the access token
  to be refreshed.
- <code>:access_token</code> -
  The current access token for this client.
- <code>:id_token</code> -
  The current ID token for this client.
- <code>:extension_parameters</code> -
  When using an extension grant type, this is the set of parameters used
  by that extension.

@example

client.update!(
  :code => 'i1WsRn1uB1',
  :access_token => 'FJQbwq9',
  :expires_in => 3600
)

@see Signet::OAuth2::Client#initialize @see #update_token!

# File lib/signet/oauth_2/client.rb, line 155
def update!(options={})
  # Normalize all keys to symbols to allow indifferent access.
  options = deep_hash_normalize(options)

  self.authorization_uri = options[:authorization_uri] if options.has_key?(:authorization_uri)
  self.token_credential_uri = options[:token_credential_uri] if options.has_key?(:token_credential_uri)
  self.client_id = options[:client_id] if options.has_key?(:client_id)
  self.client_secret = options[:client_secret] if options.has_key?(:client_secret)
  self.scope = options[:scope] if options.has_key?(:scope)
  self.state = options[:state] if options.has_key?(:state)
  self.code = options[:code] if options.has_key?(:code)
  self.redirect_uri = options[:redirect_uri] if options.has_key?(:redirect_uri)
  self.username = options[:username] if options.has_key?(:username)
  self.password = options[:password] if options.has_key?(:password)
  self.issuer = options[:issuer] if options.has_key?(:issuer)
  self.person = options[:person] if options.has_key?(:person)
  self.sub = options[:sub] if options.has_key?(:sub)
  self.expiry = options[:expiry] || 60
  self.audience = options[:audience] if options.has_key?(:audience)
  self.signing_key = options[:signing_key] if options.has_key?(:signing_key)
  self.extension_parameters = options[:extension_parameters] || {}
  self.additional_parameters = options[:additional_parameters] || {}
  self.update_token!(options)
  return self
end
update_token!(options={}) click to toggle source

Updates an OAuth 2.0 client.

@param [Hash] options

The configuration parameters related to the token.
- <code>:refresh_token</code> -
  The refresh token associated with the access token
  to be refreshed.
- <code>:access_token</code> -
  The current access token for this client.
- <code>:id_token</code> -
  The current ID token for this client.
- <code>:expires_in</code> -
  The time in seconds until access token expiration.
- <code>:expires_at</code> -
  The time as an integer number of seconds since the Epoch
- <code>:issued_at</code> -
  The timestamp that the token was issued at.

@example

client.update!(
  :refresh_token => 'n4E9O119d',
  :access_token => 'FJQbwq9',
  :expires_in => 3600
)

@see Signet::OAuth2::Client#initialize @see #update!

# File lib/signet/oauth_2/client.rb, line 209
def update_token!(options={})
  # Normalize all keys to symbols to allow indifferent access internally
  options = deep_hash_normalize(options)

  self.expires_in = options[:expires] if options.has_key?(:expires)
  self.expires_in = options[:expires_in] if options.has_key?(:expires_in)
  self.expires_at = options[:expires_at] if options.has_key?(:expires_at)

  # By default, the token is issued at `Time.now` when `expires_in` is
  # set, but this can be used to supply a more precise time.
  self.issued_at = options[:issued_at] if options.has_key?(:issued_at)

  self.access_token = options[:access_token] if options.has_key?(:access_token)
  self.refresh_token = options[:refresh_token] if options.has_key?(:refresh_token)
  self.id_token = options[:id_token] if options.has_key?(:id_token)

  return self
end
username() click to toggle source

Returns the username associated with this client. Used only by the resource owner password credential access grant type.

@return [String] The username.

# File lib/signet/oauth_2/client.rb, line 443
def username
  return @username
end
username=(new_username) click to toggle source

Sets the username associated with this client. Used only by the resource owner password credential access grant type.

@param [String] new_username

The username.
# File lib/signet/oauth_2/client.rb, line 453
def username=(new_username)
  @username = new_username
end

Private Instance Methods

deep_hash_normalize(old_hash) click to toggle source
# File lib/signet/oauth_2/client.rb, line 1143
def deep_hash_normalize(old_hash)
  old_hash.inject(formatted_hash={}) do |formatted_hash,(k,v)|

    formatted_hash[k.to_sym] = recursive_hash_normalize_keys(v)
    formatted_hash
  end

  formatted_hash
end
recursive_hash_normalize_keys(val) click to toggle source

Convert all keys in this hash (nested) to symbols for uniform retrieval

# File lib/signet/oauth_2/client.rb, line 1135
def recursive_hash_normalize_keys(val)
  if val.is_a? Hash
    deep_hash_normalize(val)
  else
    val
  end
end
uri_is_oob?(uri) click to toggle source

Check if the URI is a out-of-band @private

# File lib/signet/oauth_2/client.rb, line 1130
def uri_is_oob?(uri)
  return uri.to_s == 'urn:ietf:wg:oauth:2.0:oob' || uri.to_s == 'oob'
end
uri_is_postmessage?(uri) click to toggle source

Check if URI is Google's postmessage flow (not a valid #redirect_uri by spec, but allowed) @private

# File lib/signet/oauth_2/client.rb, line 1123
def uri_is_postmessage?(uri)
  return uri.to_s.casecmp('postmessage') == 0
end