signet 0.2.4 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,10 @@
1
+ == 0.3.0
2
+
3
+ * Replaced httpadapter gem dependency with faraday
4
+ * Replaced json gem dependency with multi_json
5
+ * Updated to OAuth 2.0 draft 22
6
+ * Complete test coverage
7
+
1
8
  == 0.2.4
2
9
 
3
10
  * Updated to incorporate changes to the Google OAuth endpoints
@@ -25,18 +32,18 @@
25
32
 
26
33
  == 0.1.3
27
34
 
28
- * fixed issue with headers passed in as a Hash
29
- * fixed incompatibilities with Ruby 1.8.6
35
+ * Fixed issue with headers passed in as a Hash
36
+ * Fixed incompatibilities with Ruby 1.8.6
30
37
 
31
38
  == 0.1.2
32
39
 
33
- * fixed bug with overzealous normalization
40
+ * Fixed bug with overzealous normalization
34
41
 
35
42
  == 0.1.1
36
43
 
37
- * fixed bug with missing StringIO require
38
- * fixed issue with dependency on unreleased features of addressable
44
+ * Fixed bug with missing StringIO require
45
+ * Fixed issue with dependency on unreleased features of addressable
39
46
 
40
47
  == 0.1.0
41
48
 
42
- * initial release
49
+ * Initial release
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Signet
2
2
 
3
3
  <dl>
4
- <dt>Homepage</dt><dd><a href="http://signet.rubyforge.org/">signet.rubyforge.org</a></dd>
4
+ <dt>Homepage</dt><dd><a href="http://code.google.com/p/oauth-signet/">http://code.google.com/p/oauth-signet/</a></dd>
5
5
  <dt>Author</dt><dd><a href="mailto:bobaman@google.com">Bob Aman</a></dd>
6
6
  <dt>Copyright</dt><dd>Copyright © 2010 Google, Inc.</dd>
7
7
  <dt>License</dt><dd>Apache 2.0</dd>
@@ -40,8 +40,6 @@ Signet is an OAuth 1.0 / OAuth 2.0 implementation.
40
40
  response = client.fetch_protected_resource(
41
41
  :uri => 'https://mail.google.com/mail/feed/atom'
42
42
  )
43
- # The Rack response format is used here
44
- status, headers, body = response
45
43
 
46
44
  ## Install
47
45
 
data/Rakefile CHANGED
@@ -46,7 +46,7 @@ PKG_FILES = FileList[
46
46
  "[A-Z]*", "Rakefile"
47
47
  ].exclude(/database\.yml/).exclude(/[_\.]git$/)
48
48
 
49
- RCOV_ENABLED = (RUBY_PLATFORM != "java" && RUBY_VERSION =~ /^1\.8/)
49
+ RCOV_ENABLED = !!(RUBY_PLATFORM != "java" && RUBY_VERSION =~ /^1\.8/)
50
50
  if RCOV_ENABLED
51
51
  task :default => "spec:verify"
52
52
  else
@@ -37,9 +37,9 @@ module Signet
37
37
  # @param [Hash] options
38
38
  # The configuration parameters for the request.
39
39
  # - <code>:request</code> —
40
- # A tuple of method, uri, headers, and body. Optional.
40
+ # A Faraday::Request object. Optional.
41
41
  # - <code>:response</code> —
42
- # A tuple of status, headers, and body. Optional.
42
+ # A Faraday::Response object. Optional.
43
43
  # - <code>:code</code> —
44
44
  # An error code.
45
45
  # - <code>:description</code> —
@@ -12,6 +12,10 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
+ gem 'faraday', '~> 0.7.0'
16
+ require 'faraday'
17
+ require 'faraday/utils'
18
+
15
19
  require 'stringio'
16
20
  require 'addressable/uri'
17
21
  require 'signet'
@@ -536,7 +540,7 @@ module Signet
536
540
  :additional_parameters => [],
537
541
  :realm => nil
538
542
  }.merge(options)
539
- method = 'POST'
543
+ method = :post
540
544
  parameters = ::Signet::OAuth1.unsigned_temporary_credential_parameters(
541
545
  :client_credential_key => self.client_credential_key,
542
546
  :callback => self.callback,
@@ -557,15 +561,14 @@ module Signet
557
561
  )
558
562
  ]
559
563
  headers = [authorization_header]
560
- if method == 'POST'
564
+ if method == :post
561
565
  headers << ['Content-Type', 'application/x-www-form-urlencoded']
566
+ headers << ['Content-Length', '0']
567
+ end
568
+ return Faraday::Request.create(method.to_s.downcase.to_sym) do |req|
569
+ req.url(Addressable::URI.parse(self.temporary_credential_uri.to_str))
570
+ req.headers = Faraday::Utils::Headers.new(headers)
562
571
  end
563
- return [
564
- method,
565
- self.temporary_credential_uri.to_str,
566
- headers,
567
- ['']
568
- ]
569
572
  end
570
573
  alias_method(
571
574
  :generate_request_token_request,
@@ -584,14 +587,9 @@ module Signet
584
587
  # Non-standard additional parameters.
585
588
  # - <code>:realm</code> —
586
589
  # The Authorization realm. See RFC 2617.
587
- # - <code>:adapter</code> —
588
- # The HTTP adapter.
589
- # Defaults to <code>HTTPAdapter::NetHTTPAdapter.new</code>.
590
590
  # - <code>:connection</code> —
591
- # An open, manually managed HTTP connection.
592
- # Must be of type <code>HTTPAdapter::Connection</code> and the
593
- # internal connection representation must match the HTTP adapter
594
- # being used.
591
+ # The HTTP connection to use.
592
+ # Must be of type <code>Faraday::Connection</code>.
595
593
  #
596
594
  # @return [Signet::OAuth1::Credential] The temporary credential.
597
595
  #
@@ -602,35 +600,24 @@ module Signet
602
600
  # }
603
601
  # )
604
602
  def fetch_temporary_credential(options={})
605
- adapter = options[:adapter]
606
- unless adapter
607
- require 'httpadapter'
608
- require 'httpadapter/adapters/net_http'
609
- adapter = HTTPAdapter::NetHTTPAdapter.new
610
- end
611
- connection = options[:connection]
603
+ options[:connection] ||= Faraday.default_connection
612
604
  request = self.generate_temporary_credential_request(options)
613
- response = adapter.transmit(request, connection)
614
- status, headers, body = response
615
- merged_body = StringIO.new
616
- body.each do |chunk|
617
- merged_body.write(chunk)
618
- end
619
- body = merged_body.string
620
- if status.to_i == 200
621
- return ::Signet::OAuth1.parse_form_encoded_credentials(body)
622
- elsif [400, 401, 403].include?(status.to_i)
605
+ request_env = request.to_env(options[:connection])
606
+ response = options[:connection].app.call(request_env)
607
+ if response.status.to_i == 200
608
+ return ::Signet::OAuth1.parse_form_encoded_credentials(response.body)
609
+ elsif [400, 401, 403].include?(response.status.to_i)
623
610
  message = 'Authorization failed.'
624
- if body.strip.length > 0
625
- message += " Server message:\n#{body.strip}"
611
+ if response.body.to_s.strip.length > 0
612
+ message += " Server message:\n#{response.body.to_s.strip}"
626
613
  end
627
614
  raise ::Signet::AuthorizationError.new(
628
615
  message, :request => request, :response => response
629
616
  )
630
617
  else
631
- message = "Unexpected status code: #{status}."
632
- if body.strip.length > 0
633
- message += " Server message:\n#{body.strip}"
618
+ message = "Unexpected status code: #{response.status}."
619
+ if response.body.to_s.strip.length > 0
620
+ message += " Server message:\n#{response.body.to_s.strip}"
634
621
  end
635
622
  raise ::Signet::AuthorizationError.new(
636
623
  message, :request => request, :response => response
@@ -654,14 +641,9 @@ module Signet
654
641
  # Non-standard additional parameters.
655
642
  # - <code>:realm</code> —
656
643
  # The Authorization realm. See RFC 2617.
657
- # - <code>:adapter</code> —
658
- # The HTTP adapter.
659
- # Defaults to <code>HTTPAdapter::NetHTTPAdapter.new</code>.
660
644
  # - <code>:connection</code> —
661
- # An open, manually managed HTTP connection.
662
- # Must be of type <code>HTTPAdapter::Connection</code> and the
663
- # internal connection representation must match the HTTP adapter
664
- # being used.
645
+ # The HTTP connection to use.
646
+ # Must be of type <code>Faraday::Connection</code>.
665
647
  #
666
648
  # @return [Signet::OAuth1::Credential] The temporary credential.
667
649
  #
@@ -709,7 +691,7 @@ module Signet
709
691
  :signature_method => 'HMAC-SHA1',
710
692
  :realm => nil
711
693
  }.merge(options)
712
- method = 'POST'
694
+ method = :post
713
695
  parameters = ::Signet::OAuth1.unsigned_token_credential_parameters(
714
696
  :client_credential_key => self.client_credential_key,
715
697
  :temporary_credential_key => self.temporary_credential_key,
@@ -732,15 +714,14 @@ module Signet
732
714
  ]
733
715
  headers = [authorization_header]
734
716
  headers << ['Cache-Control', 'no-store']
735
- if method == 'POST'
717
+ if method == :post
736
718
  headers << ['Content-Type', 'application/x-www-form-urlencoded']
719
+ headers << ['Content-Length', '0']
720
+ end
721
+ return Faraday::Request.create(method.to_s.downcase.to_sym) do |req|
722
+ req.url(Addressable::URI.parse(self.token_credential_uri.to_str))
723
+ req.headers = Faraday::Utils::Headers.new(headers)
737
724
  end
738
- return [
739
- method,
740
- self.token_credential_uri.to_str,
741
- headers,
742
- ['']
743
- ]
744
725
  end
745
726
  alias_method(
746
727
  :generate_access_token_request,
@@ -759,14 +740,9 @@ module Signet
759
740
  # The signature method. Defaults to <code>'HMAC-SHA1'</code>.
760
741
  # - <code>:realm</code> —
761
742
  # The Authorization realm. See RFC 2617.
762
- # - <code>:adapter</code> —
763
- # The HTTP adapter.
764
- # Defaults to <code>HTTPAdapter::NetHTTPAdapter.new</code>.
765
743
  # - <code>:connection</code> —
766
- # An open, manually managed HTTP connection.
767
- # Must be of type <code>HTTPAdapter::Connection</code> and the
768
- # internal connection representation must match the HTTP adapter
769
- # being used.
744
+ # The HTTP connection to use.
745
+ # Must be of type <code>Faraday::Connection</code>.
770
746
  #
771
747
  # @return [Signet::OAuth1::Credential] The token credential.
772
748
  #
@@ -775,35 +751,24 @@ module Signet
775
751
  # :verifier => '12345'
776
752
  # )
777
753
  def fetch_token_credential(options={})
778
- adapter = options[:adapter]
779
- unless adapter
780
- require 'httpadapter'
781
- require 'httpadapter/adapters/net_http'
782
- adapter = HTTPAdapter::NetHTTPAdapter.new
783
- end
784
- connection = options[:connection]
754
+ options[:connection] ||= Faraday.default_connection
785
755
  request = self.generate_token_credential_request(options)
786
- response = adapter.transmit(request, connection)
787
- status, headers, body = response
788
- merged_body = StringIO.new
789
- body.each do |chunk|
790
- merged_body.write(chunk)
791
- end
792
- body = merged_body.string
793
- if status.to_i == 200
794
- return ::Signet::OAuth1.parse_form_encoded_credentials(body)
795
- elsif [400, 401, 403].include?(status.to_i)
756
+ request_env = request.to_env(options[:connection])
757
+ response = options[:connection].app.call(request_env)
758
+ if response.status.to_i == 200
759
+ return ::Signet::OAuth1.parse_form_encoded_credentials(response.body)
760
+ elsif [400, 401, 403].include?(response.status.to_i)
796
761
  message = 'Authorization failed.'
797
- if body.strip.length > 0
798
- message += " Server message:\n#{body.strip}"
762
+ if response.body.to_s.strip.length > 0
763
+ message += " Server message:\n#{response.body.to_s.strip}"
799
764
  end
800
765
  raise ::Signet::AuthorizationError.new(
801
766
  message, :request => request, :response => response
802
767
  )
803
768
  else
804
- message = "Unexpected status code: #{status}."
805
- if body.strip.length > 0
806
- message += " Server message:\n#{body.strip}"
769
+ message = "Unexpected status code: #{response.status}."
770
+ if response.body.to_s.strip.length > 0
771
+ message += " Server message:\n#{response.body.to_s.strip}"
807
772
  end
808
773
  raise ::Signet::AuthorizationError.new(
809
774
  message, :request => request, :response => response
@@ -827,14 +792,9 @@ module Signet
827
792
  # Non-standard additional parameters.
828
793
  # - <code>:realm</code> —
829
794
  # The Authorization realm. See RFC 2617.
830
- # - <code>:adapter</code> —
831
- # The HTTP adapter.
832
- # Defaults to <code>HTTPAdapter::NetHTTPAdapter.new</code>.
833
795
  # - <code>:connection</code> —
834
- # An open, manually managed HTTP connection.
835
- # Must be of type <code>HTTPAdapter::Connection</code> and the
836
- # internal connection representation must match the HTTP adapter
837
- # being used.
796
+ # The HTTP connection to use.
797
+ # Must be of type <code>Faraday::Connection</code>.
838
798
  #
839
799
  # @return [Signet::OAuth1::Credential] The token credential.
840
800
  #
@@ -857,7 +817,7 @@ module Signet
857
817
  # - <code>:request</code> —
858
818
  # A pre-constructed request to sign.
859
819
  # - <code>:method</code> —
860
- # The HTTP method for the request. Defaults to 'GET'.
820
+ # The HTTP method for the request. Defaults to :get.
861
821
  # - <code>:uri</code> —
862
822
  # The URI for the request.
863
823
  # - <code>:headers</code> —
@@ -893,13 +853,21 @@ module Signet
893
853
  }.merge(options)
894
854
  if options[:request]
895
855
  if options[:request].kind_of?(Array)
896
- request = options[:request]
897
- elsif options[:adapter]
898
- request = options[:adapter].adapt_request(options[:request])
856
+ method, uri, headers, body = options[:request]
857
+ elsif options[:request].kind_of?(Faraday::Request)
858
+ unless options[:connection]
859
+ raise ArgumentError,
860
+ "Faraday::Request used, requires a connection to be provided."
861
+ end
862
+ method = options[:request].method.to_s.downcase.to_sym
863
+ uri = options[:connection].build_url(
864
+ options[:request].path, options[:request].params
865
+ )
866
+ headers = options[:request].headers || {}
867
+ body = options[:request].body || ''
899
868
  end
900
- method, uri, headers, body = request
901
869
  else
902
- method = options[:method] || 'GET'
870
+ method = options[:method] || :get
903
871
  uri = options[:uri]
904
872
  headers = options[:headers] || []
905
873
  body = options[:body] || ''
@@ -928,7 +896,7 @@ module Signet
928
896
  if !body.kind_of?(String)
929
897
  raise TypeError, "Expected String, got #{body.class}."
930
898
  end
931
- method = method.to_s.upcase
899
+ method = method.to_s.downcase.to_sym
932
900
  parameters = ::Signet::OAuth1.unsigned_resource_parameters(
933
901
  :client_credential_key => self.client_credential_key,
934
902
  :token_credential_key => self.token_credential_key,
@@ -941,7 +909,7 @@ module Signet
941
909
  media_type = value.gsub(/^([^;]+)(;.*?)?$/, '\1')
942
910
  end
943
911
  end
944
- if method == 'POST' &&
912
+ if method == :post &&
945
913
  media_type == 'application/x-www-form-urlencoded'
946
914
  post_parameters = Addressable::URI.form_unencode(body)
947
915
  else
@@ -966,7 +934,11 @@ module Signet
966
934
  ]
967
935
  headers << authorization_header
968
936
  headers << ['Cache-Control', 'no-store']
969
- return [method, uri.to_str, headers, [body]]
937
+ return Faraday::Request.create(method.to_s.downcase.to_sym) do |req|
938
+ req.url(Addressable::URI.parse(uri))
939
+ req.headers = Faraday::Utils::Headers.new(headers)
940
+ req.body = body
941
+ end
970
942
  end
971
943
 
972
944
  ##
@@ -977,7 +949,7 @@ module Signet
977
949
  # - <code>:request</code> —
978
950
  # A pre-constructed request to sign.
979
951
  # - <code>:method</code> —
980
- # The HTTP method for the request. Defaults to 'GET'.
952
+ # The HTTP method for the request. Defaults to :get.
981
953
  # - <code>:uri</code> —
982
954
  # The URI for the request.
983
955
  # - <code>:headers</code> —
@@ -988,21 +960,15 @@ module Signet
988
960
  # The signature method. Defaults to <code>'HMAC-SHA1'</code>.
989
961
  # - <code>:realm</code> —
990
962
  # The Authorization realm. See RFC 2617.
991
- # - <code>:adapter</code> —
992
- # The HTTP adapter.
993
- # Defaults to <code>HTTPAdapter::NetHTTPAdapter.new</code>.
994
963
  # - <code>:connection</code> —
995
- # An open, manually managed HTTP connection.
996
- # Must be of type <code>HTTPAdapter::Connection</code> and the
997
- # internal connection representation must match the HTTP adapter
998
- # being used.
964
+ # The HTTP connection to use.
965
+ # Must be of type <code>Faraday::Connection</code>.
999
966
  #
1000
967
  # @example
1001
968
  # # Using Net::HTTP
1002
969
  # response = client.fetch_protected_resource(
1003
970
  # :uri => 'http://www.example.com/protected/resource'
1004
971
  # )
1005
- # status, headers, body = response
1006
972
  #
1007
973
  # @example
1008
974
  # # Using Typhoeus
@@ -1010,34 +976,21 @@ module Signet
1010
976
  # :request => Typhoeus::Request.new(
1011
977
  # 'http://www.example.com/protected/resource'
1012
978
  # ),
1013
- # :adapter => HTTPAdapter::TyphoeusAdapter.new,
1014
979
  # :connection => connection
1015
980
  # )
1016
- # status, headers, body = response
1017
981
  #
1018
982
  # @return [Array] The response object.
1019
983
  def fetch_protected_resource(options={})
1020
- adapter = options[:adapter]
1021
- unless adapter
1022
- require 'httpadapter'
1023
- require 'httpadapter/adapters/net_http'
1024
- adapter = HTTPAdapter::NetHTTPAdapter.new
1025
- end
1026
- connection = options[:connection]
984
+ options[:connection] ||= Faraday.default_connection
1027
985
  request = self.generate_authenticated_request(options)
1028
- response = adapter.transmit(request, connection)
1029
- status, headers, body = response
1030
- merged_body = StringIO.new
1031
- body.each do |chunk|
1032
- merged_body.write(chunk)
1033
- end
1034
- body = merged_body.string
1035
- if status.to_i == 401
986
+ request_env = request.to_env(options[:connection])
987
+ response = options[:connection].app.call(request_env)
988
+ if response.status.to_i == 401
1036
989
  # When accessing a protected resource, we only want to raise an
1037
990
  # error for 401 responses.
1038
991
  message = 'Authorization failed.'
1039
- if body.strip.length > 0
1040
- message += " Server message:\n#{body.strip}"
992
+ if response.body.to_s.strip.length > 0
993
+ message += " Server message:\n#{response.body.to_s.strip}"
1041
994
  end
1042
995
  raise ::Signet::AuthorizationError.new(
1043
996
  message, :request => request, :response => response
@@ -14,7 +14,7 @@
14
14
 
15
15
  require 'base64'
16
16
  require 'signet'
17
- require 'json'
17
+ require 'multi_json'
18
18
 
19
19
  module Signet #:nodoc:
20
20
  ##
@@ -76,7 +76,7 @@ module Signet #:nodoc:
76
76
  if !body.kind_of?(String)
77
77
  raise TypeError, "Expected String, got #{body.class}."
78
78
  end
79
- return JSON.parse(body)
79
+ return MultiJson.decode(body)
80
80
  end
81
81
 
82
82
  ##
@@ -114,13 +114,13 @@ module Signet #:nodoc:
114
114
  def self.generate_bearer_authorization_header(
115
115
  access_token, auth_params=nil)
116
116
  # TODO: escaping?
117
- header = "OAuth #{access_token}"
117
+ header = "Bearer #{access_token}"
118
118
  if auth_params && !auth_params.empty?
119
119
  header += (", " +
120
- auth_params.inject('') do |accu, (key, value)|
121
- accu += "#{key}=\"#{value}\""
120
+ (auth_params.inject([]) do |accu, (key, value)|
121
+ accu << "#{key}=\"#{value}\""
122
122
  accu
123
- end
123
+ end).join(", ")
124
124
  )
125
125
  end
126
126
  return header