Class: Signet::OAuth2::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/signet/oauth_2/client.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Client

Creates an OAuth 2.0 client.

Examples:

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'
)

Parameters:

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

    The configuration parameters for the client.

    • :authorization_uri - The authorization server’s HTTP endpoint capable of authenticating the end-user and obtaining authorization.

    • :token_credential_uri - The authorization server’s HTTP endpoint capable of issuing tokens and refreshing expired tokens.

    • :client_id - A unique identifier issued to the client to identify itself to the authorization server.

    • :client_secret - A shared symmetric secret issued by the authorization server, which is used to authenticate the client.

    • :scope - The scope of the access request, expressed either as an Array or as a space-delimited String.

    • :state - An arbitrary string designed to allow the client to maintain state.

    • :code - The authorization code received from the authorization server.

    • :redirect_uri - The redirection URI used in the initial request.

    • :username - The resource owner’s username.

    • :password - The resource owner’s password.

    • :issuer - Issuer ID when using assertion profile

    • :person - Target user for assertions

    • :expiry - Number of seconds assertions are valid for

    • :signing_key - Signing key when using assertion profile

    • :refresh_token - The refresh token associated with the access token to be refreshed.

    • :access_token - The current access token for this client.

    • :id_token - The current ID token for this client.

    • :extension_parameters - When using an extension grant type, this the set of parameters used by that extension.

See Also:



91
92
93
# File 'lib/signet/oauth_2/client.rb', line 91

def initialize(options={})
  self.update!(options)
end

Instance Attribute Details

#subObject

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



540
541
542
# File 'lib/signet/oauth_2/client.rb', line 540

def sub
  @sub
end

Instance Method Details

#access_tokenString

Returns the access token associated with this client.

Returns:

  • (String)

    The access token.



655
656
657
# File 'lib/signet/oauth_2/client.rb', line 655

def access_token
  return @access_token ||= nil
end

#access_token=(new_access_token) ⇒ Object

Sets the access token associated with this client.

Parameters:

  • new_access_token (String)

    The access token.



664
665
666
# File 'lib/signet/oauth_2/client.rb', line 664

def access_token=(new_access_token)
  @access_token = new_access_token
end

#additional_parametersHash

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

Returns:

  • (Hash)

    The pass through parameters.



616
617
618
# File 'lib/signet/oauth_2/client.rb', line 616

def additional_parameters
  return @additional_parameters ||= {}
end

#additional_parameters=(new_additional_parameters) ⇒ Object

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

Parameters:

  • new_additional_parameters (Hash)

    The parameters.



625
626
627
628
629
630
631
632
# 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

#audienceString

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

Returns:

  • (String)

    Target audience ID.



500
501
502
# File 'lib/signet/oauth_2/client.rb', line 500

def audience
  return @audience
end

#audience=(new_audience) ⇒ Object

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

Parameters:

  • new_audience (String)

    Target audience ID



510
511
512
# File 'lib/signet/oauth_2/client.rb', line 510

def audience=(new_audience)
  @audience = new_audience
end

#authorization_uri(options = {}) ⇒ Addressable::URI

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

Returns:

  • (Addressable::URI)

    The authorization URI.

See Also:



234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
# 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) ⇒ Object

Sets the authorization URI for this client.

Parameters:

  • new_authorization_uri (Addressable::URI, Hash, String, #to_str)

    The authorization URI.



279
280
281
# 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!Object

Removes all credentials from the client.



777
778
779
780
781
782
783
784
785
786
# 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_idString

Returns the client identifier for this client.

Returns:

  • (String)

    The client identifier.



314
315
316
# File 'lib/signet/oauth_2/client.rb', line 314

def client_id
  return @client_id
end

#client_id=(new_client_id) ⇒ Object

Sets the client identifier for this client.

Parameters:

  • new_client_id (String)

    The client identifier.



323
324
325
# File 'lib/signet/oauth_2/client.rb', line 323

def client_id=(new_client_id)
  @client_id = new_client_id
end

#client_secretString

Returns the client secret for this client.

Returns:

  • (String)

    The client secret.



331
332
333
# File 'lib/signet/oauth_2/client.rb', line 331

def client_secret
  return @client_secret
end

#client_secret=(new_client_secret) ⇒ Object

Sets the client secret for this client.

Parameters:

  • new_client_secret (String)

    The client secret.



340
341
342
# File 'lib/signet/oauth_2/client.rb', line 340

def client_secret=(new_client_secret)
  @client_secret = new_client_secret
end

#codeString

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

Returns:

  • (String)

    The authorization code.



401
402
403
# File 'lib/signet/oauth_2/client.rb', line 401

def code
  return @code
end

#code=(new_code) ⇒ Object

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

Parameters:

  • new_code (String)

    The authorization code.



411
412
413
# File 'lib/signet/oauth_2/client.rb', line 411

def code=(new_code)
  @code = new_code
end

#coerce_uri(incoming_uri) ⇒ Object

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



302
303
304
305
306
307
308
# 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) ⇒ String

Returns the decoded ID token associated with this client.

Parameters:

  • public_key (OpenSSL::PKey::RSA, Object) (defaults to: nil)

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

Returns:

  • (String)

    The decoded ID token.



693
694
695
696
697
698
699
700
701
702
# 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?TrueClass, FalseClass

Returns true if the access token has expired.

Returns:

  • (TrueClass, FalseClass)

    The expiration state of the access token.



770
771
772
# File 'lib/signet/oauth_2/client.rb', line 770

def expired?
  return self.expires_at != nil && Time.now >= self.expires_at
end

#expires_atInteger

Returns the timestamp the access token will expire at.

Returns:

  • (Integer)

    The access token lifetime.



748
749
750
751
752
753
754
755
756
# 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) ⇒ Object

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



761
762
763
# File 'lib/signet/oauth_2/client.rb', line 761

def expires_at=(new_expires_at)
  @expires_at = Time.at new_expires_at
end

#expires_inInteger

Returns the lifetime of the access token in seconds.

Returns:

  • (Integer)

    The access token lifetime.



708
709
710
# File 'lib/signet/oauth_2/client.rb', line 708

def expires_in
  return @expires_in
end

#expires_in=(new_expires_in) ⇒ Object

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

Parameters:

  • new_expires_in (String)

    The access token lifetime.



718
719
720
721
722
723
724
725
# 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

#expiryFixnum

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

Returns:

  • (Fixnum)

    Assertion expiry, in seconds



547
548
549
# File 'lib/signet/oauth_2/client.rb', line 547

def expiry
  return @expiry
end

#expiry=(new_expiry) ⇒ Object

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

Parameters:

  • new_expiry (String)

    Assertion expiry, in seconds



557
558
559
# File 'lib/signet/oauth_2/client.rb', line 557

def expiry=(new_expiry)
  @expiry = new_expiry
end

#extension_parametersHash

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

Returns:

  • (Hash)

    The extension parameters.



593
594
595
# File 'lib/signet/oauth_2/client.rb', line 593

def extension_parameters
  return @extension_parameters ||= {}
end

#extension_parameters=(new_extension_parameters) ⇒ Object

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

Parameters:

  • new_extension_parameters (Hash)

    The parameters.



603
604
605
606
607
608
609
610
# 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 = {}) ⇒ Object



931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
# 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 = {}) ⇒ Object



961
962
963
964
965
966
967
968
969
970
971
972
973
974
# 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 = {}) ⇒ Array

Transmits a request for a protected resource.

Examples:

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

Parameters:

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

    The configuration parameters for the request.

    • :request - A pre-constructed request. An OAuth 2 Authorization header will be added to it, as well as an explicit Cache-Control ‘no-store` directive.

    • :method - The HTTP method for the request. Defaults to ‘GET’.

    • :uri - The URI for the request.

    • :headers - The HTTP headers for the request.

    • :body - The HTTP body for the request.

    • :realm - The Authorization realm. See RFC 2617.

    • :connection - The HTTP connection to use. Must be of type Faraday::Connection.

Returns:

  • (Array)

    The response object.



1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
# 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 = {}) ⇒ Array

Generates a request for token credentials.

Parameters:

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

    The configuration parameters for the request.

    • :code - The authorization code.

Returns:

  • (Array)

    The request object.



884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
# 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 = {}) ⇒ Faraday::Request

Generates an authenticated request for protected resources.

Parameters:

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

    The configuration parameters for the request.

    • :request - A pre-constructed request. An OAuth 2 Authorization header will be added to it, as well as an explicit Cache-Control ‘no-store` directive.

    • :method - The HTTP method for the request. Defaults to ‘GET’.

    • :uri - The URI for the request.

    • :headers - The HTTP headers for the request.

    • :body - The HTTP body for the request.

    • :realm - The Authorization realm. See RFC 2617.

Returns:

  • (Faraday::Request)

    The request object.



1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
# 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_typeString

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.

Returns:

  • (String)

    The inferred grant type.



796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
# 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) ⇒ Object



818
819
820
821
822
823
824
825
826
# 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_tokenString

Returns the ID token associated with this client.

Returns:

  • (String)

    The ID token.



672
673
674
# File 'lib/signet/oauth_2/client.rb', line 672

def id_token
  return @id_token ||= nil
end

#id_token=(new_id_token) ⇒ Object

Sets the ID token associated with this client.

Parameters:

  • new_id_token (String)

    The ID token.



681
682
683
# File 'lib/signet/oauth_2/client.rb', line 681

def id_token=(new_id_token)
  @id_token = new_id_token
end

#issued_atInteger

Returns the timestamp the access token was issued at.

Returns:

  • (Integer)

    The access token issuance time.



731
732
733
# File 'lib/signet/oauth_2/client.rb', line 731

def issued_at
  return @issued_at
end

#issued_at=(new_issued_at) ⇒ Object

Sets the timestamp the access token was issued at.

Parameters:

  • new_issued_at (String)

    The access token issuance time.



740
741
742
# File 'lib/signet/oauth_2/client.rb', line 740

def issued_at=(new_issued_at)
  @issued_at = new_issued_at
end

#issuerString

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

Returns:

  • (String)

    Issuer id.



481
482
483
# File 'lib/signet/oauth_2/client.rb', line 481

def issuer
  return @issuer
end

#issuer=(new_issuer) ⇒ Object

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

Parameters:

  • new_issuer (String)

    Issuer ID (typical in email adddress form).



491
492
493
# File 'lib/signet/oauth_2/client.rb', line 491

def issuer=(new_issuer)
  @issuer = new_issuer
end

#passwordString

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

Returns:

  • (String)

    The password.



462
463
464
# File 'lib/signet/oauth_2/client.rb', line 462

def password
  return @password
end

#password=(new_password) ⇒ Object

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

Parameters:

  • new_password (String)

    The password.



472
473
474
# File 'lib/signet/oauth_2/client.rb', line 472

def password=(new_password)
  @password = new_password
end

#principalString Also known as: person

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

Returns:

  • (String)

    Target user for impersonation.



519
520
521
# File 'lib/signet/oauth_2/client.rb', line 519

def principal
  return @principal
end

#principal=(new_person) ⇒ Object Also known as: person=

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

Parameters:

  • new_person (String)

    Target user for impersonation



529
530
531
# File 'lib/signet/oauth_2/client.rb', line 529

def principal=(new_person)
  @principal = new_person
end

#redirect_uriString

Returns the redirect URI for this client.

Returns:

  • (String)

    The redirect URI.



419
420
421
# File 'lib/signet/oauth_2/client.rb', line 419

def redirect_uri
  return @redirect_uri
end

#redirect_uri=(new_redirect_uri) ⇒ Object

Sets the redirect URI for this client.

Parameters:

  • new_redirect_uri (String)

    The redirect URI.



428
429
430
431
432
433
434
435
436
# 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 = {}) ⇒ Object

Refresh the access token, if possible



978
979
980
981
982
# File 'lib/signet/oauth_2/client.rb', line 978

def refresh!(options={})
  options = deep_hash_normalize(options)

  self.fetch_access_token!(options)
end

#refresh_tokenString

Returns the refresh token associated with this client.

Returns:

  • (String)

    The refresh token.



638
639
640
# File 'lib/signet/oauth_2/client.rb', line 638

def refresh_token
  return @refresh_token ||= nil
end

#refresh_token=(new_refresh_token) ⇒ Object

Sets the refresh token associated with this client.

Parameters:

  • new_refresh_token (String)

    The refresh token.



647
648
649
# File 'lib/signet/oauth_2/client.rb', line 647

def refresh_token=(new_refresh_token)
  @refresh_token = new_refresh_token
end

#scopeArray

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

Returns:

  • (Array)

    The scope of access the client is requesting.



349
350
351
# File 'lib/signet/oauth_2/client.rb', line 349

def scope
  return @scope
end

#scope=(new_scope) ⇒ Object

Sets the scope for this client.

Parameters:

  • new_scope (Array, String)

    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.



360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
# 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_algorithmString

Algorithm used for signing JWTs

Returns:

  • (String)

    Signing algorithm



584
585
586
# File 'lib/signet/oauth_2/client.rb', line 584

def signing_algorithm
  self.signing_key.is_a?(String) ? "HS256" : "RS256"
end

#signing_keyString, OpenSSL::PKey

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

Returns:

  • (String, OpenSSL::PKey)

    Signing key



567
568
569
# File 'lib/signet/oauth_2/client.rb', line 567

def signing_key
  return @signing_key
end

#signing_key=(new_key) ⇒ Object

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

Parameters:

  • new_key (String, OpenSSL::Pkey)

    Signing key. Either private key for RSA or string for HMAC algorithm



577
578
579
# File 'lib/signet/oauth_2/client.rb', line 577

def signing_key=(new_key)
  @signing_key = new_key
end

#stateString

Returns the client’s current state value.

Returns:

  • (String)

    The state value.



383
384
385
# File 'lib/signet/oauth_2/client.rb', line 383

def state
  return @state
end

#state=(new_state) ⇒ Object

Sets the client’s current state value.

Parameters:

  • new_state (String)

    The state value.



392
393
394
# File 'lib/signet/oauth_2/client.rb', line 392

def state=(new_state)
  @state = new_state
end

#to_jsonString

Note:

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

Serialize the client object to JSON.

Returns:

  • (String)

    A serialized JSON representation of the client.



851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
# 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 = {}) ⇒ Object



828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
# 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_uriAddressable::URI

Returns the token credential URI for this client.

Returns:

  • (Addressable::URI)

    The token credential URI.



287
288
289
# 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) ⇒ Object

Sets the token credential URI for this client.

Parameters:

  • new_token_credential_uri (Addressable::URI, Hash, String, #to_str)

    The token credential URI.



296
297
298
# 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 = {}) ⇒ Object

Updates an OAuth 2.0 client.

Examples:

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

Parameters:

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

    The configuration parameters for the client.

    • :authorization_uri - The authorization server’s HTTP endpoint capable of authenticating the end-user and obtaining authorization.

    • :token_credential_uri - The authorization server’s HTTP endpoint capable of issuing tokens and refreshing expired tokens.

    • :client_id - A unique identifier issued to the client to identify itself to the authorization server.

    • :client_secret - A shared symmetric secret issued by the authorization server, which is used to authenticate the client.

    • :scope - The scope of the access request, expressed either as an Array or as a space-delimited String.

    • :state - An arbitrary string designed to allow the client to maintain state.

    • :code - The authorization code received from the authorization server.

    • :redirect_uri - The redirection URI used in the initial request.

    • :username - The resource owner’s username.

    • :password - The resource owner’s password.

    • :issuer - Issuer ID when using assertion profile

    • :audience - Target audience for assertions

    • :person - Target user for assertions

    • :expiry - Number of seconds assertions are valid for

    • :signing_key - Signing key when using assertion profile

    • :refresh_token - The refresh token associated with the access token to be refreshed.

    • :access_token - The current access token for this client.

    • :id_token - The current ID token for this client.

    • :extension_parameters - When using an extension grant type, this is the set of parameters used by that extension.

See Also:



155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# 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 = {}) ⇒ Object

Updates an OAuth 2.0 client.

Examples:

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

Parameters:

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

    The configuration parameters related to the token.

    • :refresh_token - The refresh token associated with the access token to be refreshed.

    • :access_token - The current access token for this client.

    • :id_token - The current ID token for this client.

    • :expires_in - The time in seconds until access token expiration.

    • :expires_at - The time as an integer number of seconds since the Epoch

    • :issued_at - The timestamp that the token was issued at.

See Also:



209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
# 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

#usernameString

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

Returns:

  • (String)

    The username.



443
444
445
# File 'lib/signet/oauth_2/client.rb', line 443

def username
  return @username
end

#username=(new_username) ⇒ Object

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

Parameters:

  • new_username (String)

    The username.



453
454
455
# File 'lib/signet/oauth_2/client.rb', line 453

def username=(new_username)
  @username = new_username
end