signet 0.2.4 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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