signet 0.5.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,11 +1,11 @@
1
1
  # Copyright (C) 2010 Google Inc.
2
- #
2
+ #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
5
5
  # You may obtain a copy of the License at
6
- #
6
+ #
7
7
  # http://www.apache.org/licenses/LICENSE-2.0
8
- #
8
+ #
9
9
  # Unless required by applicable law or agreed to in writing, software
10
10
  # distributed under the License is distributed on an "AS IS" BASIS,
11
11
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -18,7 +18,7 @@ unless defined? Signet::VERSION
18
18
  module VERSION
19
19
  MAJOR = 0
20
20
  MINOR = 5
21
- TINY = 0
21
+ TINY = 1
22
22
 
23
23
  STRING = [MAJOR, MINOR, TINY].join('.')
24
24
  end
@@ -66,6 +66,15 @@ describe Signet::OAuth1::Client, 'unconfigured' do
66
66
  )
67
67
  end
68
68
 
69
+ it 'should allow the authorization_uri to be set to a Hash' do
70
+ @client.authorization_uri = {
71
+ :scheme => 'http', :host => 'example.com', :path => '/authorize'
72
+ }
73
+ @client.authorization_uri.to_s.should include(
74
+ 'http://example.com/authorize'
75
+ )
76
+ end
77
+
69
78
  it 'should allow the authorization_uri to be set to a URI' do
70
79
  @client.authorization_uri =
71
80
  Addressable::URI.parse('http://example.com/authorize')
@@ -83,6 +92,13 @@ describe Signet::OAuth1::Client, 'unconfigured' do
83
92
  @client.token_credential_uri.should === "http://example.com/"
84
93
  end
85
94
 
95
+ it 'should allow the token_credential_uri to be set to a Hash' do
96
+ @client.token_credential_uri = {
97
+ :scheme => 'http', :host => 'example.com', :path => '/token'
98
+ }
99
+ @client.token_credential_uri.to_s.should === 'http://example.com/token'
100
+ end
101
+
86
102
  it 'should allow the token_credential_uri to be set to a URI' do
87
103
  @client.token_credential_uri =
88
104
  Addressable::URI.parse("http://example.com/")
@@ -398,6 +414,26 @@ describe Signet::OAuth1::Client, 'configured' do
398
414
  @client.token_credential_secret = 'pfkkdhi9sl3r4s00'
399
415
  end
400
416
 
417
+ it 'should generate a JSON representation of the client' do
418
+ json = @client.to_json
419
+ json.should_not == nil
420
+
421
+ deserialized = MultiJson.load(json)
422
+ deserialized["temporary_credential_uri"].should ==
423
+ 'http://example.com/temporary_credentials'
424
+ deserialized["authorization_uri"].should include(
425
+ 'http://example.com/authorize')
426
+ deserialized["token_credential_uri"].should ==
427
+ 'http://example.com/token_credentials'
428
+ deserialized["callback"].should == 'http://example.com/callback'
429
+ deserialized["client_credential_key"].should == 'dpf43f3p2l4k3l03'
430
+ deserialized["client_credential_secret"].should == 'kd94hf93k423kf44'
431
+ deserialized["temporary_credential_key"].should == 'hh5s93j4hdidpola'
432
+ deserialized["temporary_credential_secret"].should == 'hdhd0244k9j7ao03'
433
+ deserialized["token_credential_key"].should == 'nnch734d00sl2jdk'
434
+ deserialized["token_credential_secret"].should == 'pfkkdhi9sl3r4s00'
435
+ end
436
+
401
437
  it 'should generate an authorization URI with a callback' do
402
438
  @client.temporary_credential_key = nil
403
439
  @client.authorization_uri.should ===
@@ -0,0 +1,66 @@
1
+ # Copyright (C) 2010 Google Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ spec_dir = File.expand_path(File.join(File.dirname(__FILE__), "../../.."))
16
+ $:.unshift(spec_dir)
17
+ $:.uniq!
18
+
19
+ require 'spec_helper'
20
+
21
+ require 'signet'
22
+ require 'signet/oauth_1/signature_methods/plaintext'
23
+
24
+ describe Signet::OAuth1::PLAINTEXT do
25
+ it 'should correctly generate a signature' do
26
+ method = "GET"
27
+ uri = "http://photos.example.net/photos"
28
+ parameters = {
29
+ "oauth_consumer_key" => "dpf43f3p2l4k3l03",
30
+ "oauth_token" => "nnch734d00sl2jdk",
31
+ "oauth_signature_method" => "HMAC-SHA1",
32
+ "oauth_timestamp" => "1191242096",
33
+ "oauth_nonce" => "kllo9940pd9333jh",
34
+ "oauth_version" => "1.0",
35
+ "file" => "vacation.jpg",
36
+ "size" => "original"
37
+ }
38
+ client_credential_secret = "kd94hf93k423kf44"
39
+ token_credential_secret = "pfkkdhi9sl3r4s00"
40
+ base_string = Signet::OAuth1.generate_base_string(method, uri, parameters)
41
+ Signet::OAuth1::PLAINTEXT.generate_signature(
42
+ base_string, client_credential_secret, token_credential_secret
43
+ ).should == "kd94hf93k423kf44%26pfkkdhi9sl3r4s00"
44
+ end
45
+
46
+ it 'should correctly generate a signature' do
47
+ method = "GET"
48
+ uri = "http://photos.example.net/photos"
49
+ parameters = {
50
+ "oauth_consumer_key" => "www.example.com",
51
+ "oauth_token" => "4/QL2GT6b5uznYem1ZGH6v+-9mMvRL",
52
+ "oauth_signature_method" => "HMAC-SHA1",
53
+ "oauth_timestamp" => "1191242096",
54
+ "oauth_nonce" => "kllo9940pd9333jh",
55
+ "oauth_version" => "1.0",
56
+ "file" => "vacation.jpg",
57
+ "size" => "original"
58
+ }
59
+ client_credential_secret = "Kv+o2XXL/9RxkQW3lO3QTVlH"
60
+ token_credential_secret = "QllSuL9eQ5FXFO1Z/HcgL4ON"
61
+ base_string = Signet::OAuth1.generate_base_string(method, uri, parameters)
62
+ Signet::OAuth1::PLAINTEXT.generate_signature(
63
+ base_string, client_credential_secret, token_credential_secret
64
+ ).should == "Kv%252Bo2XXL%252F9RxkQW3lO3QTVlH%26QllSuL9eQ5FXFO1Z%252FHcgL4ON"
65
+ end
66
+ end
@@ -0,0 +1,132 @@
1
+ # Copyright (C) 2010 Google Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ spec_dir = File.expand_path(File.join(File.dirname(__FILE__), "../../.."))
16
+ $:.unshift(spec_dir)
17
+ $:.uniq!
18
+
19
+ require 'spec_helper'
20
+
21
+ require 'signet'
22
+ require 'signet/oauth_1/signature_methods/rsa_sha1'
23
+
24
+ describe Signet::OAuth1::RSASHA1 do
25
+ it 'should correctly generate a signature' do
26
+ method = "GET"
27
+ uri = "http://term.ie/oauth/example/request_token.php"
28
+ parameters = {
29
+ "oauth_consumer_key" => "key",
30
+ "oauth_signature_method" => "RSA-SHA1",
31
+ "oauth_timestamp" => "1377815426",
32
+ "oauth_nonce" => "c3839c47cb204a20e042b11a5cc9f971",
33
+ "oauth_version" => "1.0"
34
+ }
35
+ client_credential_secret = "-----BEGIN PRIVATE KEY-----
36
+ MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALRiMLAh9iimur8V
37
+ A7qVvdqxevEuUkW4K+2KdMXmnQbG9Aa7k7eBjK1S+0LYmVjPKlJGNXHDGuy5Fw/d
38
+ 7rjVJ0BLB+ubPK8iA/Tw3hLQgXMRRGRXXCn8ikfuQfjUS1uZSatdLB81mydBETlJ
39
+ hI6GH4twrbDJCR2Bwy/XWXgqgGRzAgMBAAECgYBYWVtleUzavkbrPjy0T5FMou8H
40
+ X9u2AC2ry8vD/l7cqedtwMPp9k7TubgNFo+NGvKsl2ynyprOZR1xjQ7WgrgVB+mm
41
+ uScOM/5HVceFuGRDhYTCObE+y1kxRloNYXnx3ei1zbeYLPCHdhxRYW7T0qcynNmw
42
+ rn05/KO2RLjgQNalsQJBANeA3Q4Nugqy4QBUCEC09SqylT2K9FrrItqL2QKc9v0Z
43
+ zO2uwllCbg0dwpVuYPYXYvikNHHg+aCWF+VXsb9rpPsCQQDWR9TT4ORdzoj+Nccn
44
+ qkMsDmzt0EfNaAOwHOmVJ2RVBspPcxt5iN4HI7HNeG6U5YsFBb+/GZbgfBT3kpNG
45
+ WPTpAkBI+gFhjfJvRw38n3g/+UeAkwMI2TJQS4n8+hid0uus3/zOjDySH3XHCUno
46
+ cn1xOJAyZODBo47E+67R4jV1/gzbAkEAklJaspRPXP877NssM5nAZMU0/O/NGCZ+
47
+ 3jPgDUno6WbJn5cqm8MqWhW1xGkImgRk+fkDBquiq4gPiT898jusgQJAd5Zrr6Q8
48
+ AO/0isr/3aa6O6NLQxISLKcPDk2NOccAfS/xOtfOz4sJYM3+Bs4Io9+dZGSDCA54
49
+ Lw03eHTNQghS0A==
50
+ -----END PRIVATE KEY-----"
51
+ token_credential_secret = "pfkkdhi9sl3r4s00"
52
+ base_string = Signet::OAuth1.generate_base_string(method, uri, parameters)
53
+
54
+ Signet::OAuth1::RSASHA1.generate_signature(
55
+ base_string, client_credential_secret, token_credential_secret
56
+ ).should == "P72T4RS8dVBneQPJSY71D3iLEjge2tiivxEasPVoaoDldDgPdwpQfhS1q0th19jB3B3+9P6tBWjpWaVPxrNZe3ssBCiwS/EmXZ/6VCJGU3YoDHMtz+0jCd36NjHj5I6TpLVQ8/rtfy6+EzpdUMz7ydnhKXYqJFPOWnNv8HM1W7I="
57
+ end
58
+ end
59
+
60
+ describe Signet::OAuth1::RSASHA1 do
61
+ it 'should correctly generate a signature' do
62
+ method = "GET"
63
+ uri = "http://photos.example.net/photos"
64
+ parameters = {
65
+ "oauth_consumer_key" => "dpf43f3p2l4k3l03",
66
+ "oauth_signature_method" => "RSA-SHA1",
67
+ "oauth_timestamp" => "1196666512",
68
+ "oauth_nonce" => "13917289812797014437",
69
+ "oauth_version" => "1.0",
70
+ "file" => "vacaction.jpg",
71
+ "size" => "original"
72
+ }
73
+ client_credential_secret = "-----BEGIN PRIVATE KEY-----
74
+ MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALRiMLAh9iimur8V
75
+ A7qVvdqxevEuUkW4K+2KdMXmnQbG9Aa7k7eBjK1S+0LYmVjPKlJGNXHDGuy5Fw/d
76
+ 7rjVJ0BLB+ubPK8iA/Tw3hLQgXMRRGRXXCn8ikfuQfjUS1uZSatdLB81mydBETlJ
77
+ hI6GH4twrbDJCR2Bwy/XWXgqgGRzAgMBAAECgYBYWVtleUzavkbrPjy0T5FMou8H
78
+ X9u2AC2ry8vD/l7cqedtwMPp9k7TubgNFo+NGvKsl2ynyprOZR1xjQ7WgrgVB+mm
79
+ uScOM/5HVceFuGRDhYTCObE+y1kxRloNYXnx3ei1zbeYLPCHdhxRYW7T0qcynNmw
80
+ rn05/KO2RLjgQNalsQJBANeA3Q4Nugqy4QBUCEC09SqylT2K9FrrItqL2QKc9v0Z
81
+ zO2uwllCbg0dwpVuYPYXYvikNHHg+aCWF+VXsb9rpPsCQQDWR9TT4ORdzoj+Nccn
82
+ qkMsDmzt0EfNaAOwHOmVJ2RVBspPcxt5iN4HI7HNeG6U5YsFBb+/GZbgfBT3kpNG
83
+ WPTpAkBI+gFhjfJvRw38n3g/+UeAkwMI2TJQS4n8+hid0uus3/zOjDySH3XHCUno
84
+ cn1xOJAyZODBo47E+67R4jV1/gzbAkEAklJaspRPXP877NssM5nAZMU0/O/NGCZ+
85
+ 3jPgDUno6WbJn5cqm8MqWhW1xGkImgRk+fkDBquiq4gPiT898jusgQJAd5Zrr6Q8
86
+ AO/0isr/3aa6O6NLQxISLKcPDk2NOccAfS/xOtfOz4sJYM3+Bs4Io9+dZGSDCA54
87
+ Lw03eHTNQghS0A==
88
+ -----END PRIVATE KEY-----"
89
+ token_credential_secret = "pfkkdhi9sl3r4s00"
90
+ base_string = Signet::OAuth1.generate_base_string(method, uri, parameters)
91
+
92
+ Signet::OAuth1::RSASHA1.generate_signature(
93
+ base_string, client_credential_secret, token_credential_secret
94
+ ).should == "jvTp/wX1TYtByB1m+Pbyo0lnCOLIsyGCH7wke8AUs3BpnwZJtAuEJkvQL2/9n4s5wUmUl4aCI4BwpraNx4RtEXMe5qg5T1LVTGliMRpKasKsW//e+RinhejgCuzoH26dyF8iY2ZZ/5D1ilgeijhV/vBka5twt399mXwaYdCwFYE="
95
+ end
96
+
97
+
98
+ it 'should correctly generate a signature' do
99
+ method = "GET"
100
+ uri = "http://term.ie/oauth/example/access_token.php"
101
+ parameters = {
102
+ "oauth_consumer_key" => "key",
103
+ "oauth_token" => "requestkey",
104
+ "oauth_signature_method" => "RSA-SHA1",
105
+ "oauth_timestamp" => "1377815426",
106
+ "oauth_nonce" => "8ae9ac8192dd3cd7372e0324bf879602",
107
+ "oauth_version" => "1.0",
108
+ }
109
+ client_credential_secret = "-----BEGIN PRIVATE KEY-----
110
+ MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALRiMLAh9iimur8V
111
+ A7qVvdqxevEuUkW4K+2KdMXmnQbG9Aa7k7eBjK1S+0LYmVjPKlJGNXHDGuy5Fw/d
112
+ 7rjVJ0BLB+ubPK8iA/Tw3hLQgXMRRGRXXCn8ikfuQfjUS1uZSatdLB81mydBETlJ
113
+ hI6GH4twrbDJCR2Bwy/XWXgqgGRzAgMBAAECgYBYWVtleUzavkbrPjy0T5FMou8H
114
+ X9u2AC2ry8vD/l7cqedtwMPp9k7TubgNFo+NGvKsl2ynyprOZR1xjQ7WgrgVB+mm
115
+ uScOM/5HVceFuGRDhYTCObE+y1kxRloNYXnx3ei1zbeYLPCHdhxRYW7T0qcynNmw
116
+ rn05/KO2RLjgQNalsQJBANeA3Q4Nugqy4QBUCEC09SqylT2K9FrrItqL2QKc9v0Z
117
+ zO2uwllCbg0dwpVuYPYXYvikNHHg+aCWF+VXsb9rpPsCQQDWR9TT4ORdzoj+Nccn
118
+ qkMsDmzt0EfNaAOwHOmVJ2RVBspPcxt5iN4HI7HNeG6U5YsFBb+/GZbgfBT3kpNG
119
+ WPTpAkBI+gFhjfJvRw38n3g/+UeAkwMI2TJQS4n8+hid0uus3/zOjDySH3XHCUno
120
+ cn1xOJAyZODBo47E+67R4jV1/gzbAkEAklJaspRPXP877NssM5nAZMU0/O/NGCZ+
121
+ 3jPgDUno6WbJn5cqm8MqWhW1xGkImgRk+fkDBquiq4gPiT898jusgQJAd5Zrr6Q8
122
+ AO/0isr/3aa6O6NLQxISLKcPDk2NOccAfS/xOtfOz4sJYM3+Bs4Io9+dZGSDCA54
123
+ Lw03eHTNQghS0A==
124
+ -----END PRIVATE KEY-----"
125
+ token_credential_secret = "QllSuL9eQ5FXFO1Z/HcgL4ON"
126
+ base_string = Signet::OAuth1.generate_base_string(method, uri, parameters)
127
+ Signet::OAuth1::RSASHA1.generate_signature(
128
+ base_string, client_credential_secret, token_credential_secret
129
+ ).should == "Q1O7Ovi0jdacl/OTJoH3MAyOO/9H/tTXmoJzP/YqiKEJ+/wfShXo1RXX0xmlcjDR1XYxB1RMgHkFWQYYwz1qGCUhkXlH1c/to2qxPksptfPHRe7PJTxRClrdqLFOlhN7w2kO7tHVCeEp8IJIKON9q7cdXroTP7ctPPS+Q883SS0="
130
+ end
131
+
132
+ end
@@ -28,7 +28,12 @@ describe Signet::OAuth2::Client, 'unconfigured' do
28
28
  before do
29
29
  @client = Signet::OAuth2::Client.new
30
30
  end
31
-
31
+ it 'should allow additional paraemters to be set.' do
32
+ @client.additional_parameters['type'] =
33
+ 'web_server'
34
+ @client.additional_parameters.should ==
35
+ {'type' => 'web_server'}
36
+ end
32
37
  it 'should raise an error if a bogus scope is provided' do
33
38
  (lambda do
34
39
  @client = Signet::OAuth2::Client.new(:scope => :bogus)
@@ -69,14 +74,23 @@ describe Signet::OAuth2::Client, 'unconfigured' do
69
74
  @client = Signet::OAuth2::Client.new(:redirect_uri => '/relative/path')
70
75
  end).should raise_error(ArgumentError)
71
76
  end
72
-
77
+
73
78
  it 'should allow "postmessage" as a redirect URI (Google hack)' do
74
79
  @client.authorization_uri = 'https://example.com/authorize'
75
80
  @client.client_id = 's6BhdRkqt3'
76
81
  @client.redirect_uri = 'postmessage'
77
82
  @client.authorization_uri.query_values['redirect_uri'].should == 'postmessage'
78
83
  end
79
-
84
+
85
+ it 'should allow oob values as a redirect URI (for installed apps)' do
86
+ @client.authorization_uri = 'https://example.com/authorize'
87
+ @client.client_id = 's6BhdRkqt3'
88
+ @client.redirect_uri = 'urn:ietf:wg:oauth:2.0:oob'
89
+ @client.authorization_uri.query_values['redirect_uri'].should == 'urn:ietf:wg:oauth:2.0:oob'
90
+ @client.redirect_uri = 'oob'
91
+ @client.authorization_uri.query_values['redirect_uri'].should == 'oob'
92
+ end
93
+
80
94
  it 'should have no authorization_uri' do
81
95
  @client.authorization_uri.should == nil
82
96
  end
@@ -94,6 +108,21 @@ describe Signet::OAuth2::Client, 'unconfigured' do
94
108
  )
95
109
  end
96
110
 
111
+ it 'should allow the authorization_uri to be set to a Hash' do
112
+ @client.authorization_uri = {
113
+ :scheme => 'https', :host => 'example.com', :path => '/authorize'
114
+ }
115
+ @client.client_id = 's6BhdRkqt3'
116
+ @client.redirect_uri = 'https://example.client.com/callback'
117
+ @client.authorization_uri.to_s.should include(
118
+ 'https://example.com/authorize'
119
+ )
120
+ @client.authorization_uri.query_values['client_id'].should == 's6BhdRkqt3'
121
+ @client.authorization_uri.query_values['redirect_uri'].should == (
122
+ 'https://example.client.com/callback'
123
+ )
124
+ end
125
+
97
126
  it 'should allow the authorization_uri to be set to a URI' do
98
127
  @client.authorization_uri =
99
128
  Addressable::URI.parse('https://example.com/authorize')
@@ -137,6 +166,13 @@ describe Signet::OAuth2::Client, 'unconfigured' do
137
166
  @client.token_credential_uri.should === "https://example.com/token"
138
167
  end
139
168
 
169
+ it 'should allow the token_credential_uri to be set to a Hash' do
170
+ @client.token_credential_uri = {
171
+ :scheme => 'https', :host => 'example.com', :path => '/token'
172
+ }
173
+ @client.token_credential_uri.to_s.should === 'https://example.com/token'
174
+ end
175
+
140
176
  it 'should allow the token_credential_uri to be set to a URI' do
141
177
  @client.token_credential_uri =
142
178
  Addressable::URI.parse("https://example.com/token")
@@ -145,7 +181,7 @@ describe Signet::OAuth2::Client, 'unconfigured' do
145
181
  end
146
182
 
147
183
  describe Signet::OAuth2::Client, 'configured for assertions profile' do
148
-
184
+
149
185
  describe 'when using RSA keys' do
150
186
  before do
151
187
  @key = OpenSSL::PKey::RSA.new 2048
@@ -181,7 +217,6 @@ describe Signet::OAuth2::Client, 'configured for assertions profile' do
181
217
  claim["aud"].should == 'https://accounts.google.com/o/oauth2/token'
182
218
  end
183
219
 
184
-
185
220
  it 'should generate valid JWTs for impersonation using deprecated person attribute' do
186
221
  @client.person = 'user@example.com'
187
222
  jwt = @client.to_jwt
@@ -194,6 +229,33 @@ describe Signet::OAuth2::Client, 'configured for assertions profile' do
194
229
  claim["aud"].should == 'https://accounts.google.com/o/oauth2/token'
195
230
  end
196
231
 
232
+ it 'should generate valid JWTs for impersonation using the sub attribute' do
233
+ @client.sub = 'user@example.com'
234
+ jwt = @client.to_jwt
235
+ jwt.should_not == nil
236
+
237
+ claim = JWT.decode(jwt, @key.public_key, true)
238
+ claim["iss"].should == 'app@example.com'
239
+ claim["sub"].should == 'user@example.com'
240
+ claim["scope"].should == 'https://www.googleapis.com/auth/userinfo.profile'
241
+ claim["aud"].should == 'https://accounts.google.com/o/oauth2/token'
242
+ end
243
+
244
+ it 'should generate a JSON representation of the client' do
245
+ @client.principal = 'user@example.com'
246
+ json = @client.to_json
247
+ json.should_not == nil
248
+
249
+ deserialized = MultiJson.load(json)
250
+ deserialized["token_credential_uri"].should ==
251
+ 'https://accounts.google.com/o/oauth2/token'
252
+ deserialized["scope"].should ==
253
+ ['https://www.googleapis.com/auth/userinfo.profile']
254
+ deserialized["issuer"].should == 'app@example.com'
255
+ deserialized["audience"].should == 'https://accounts.google.com/o/oauth2/token'
256
+ deserialized["signing_key"].should == @key.to_s
257
+ end
258
+
197
259
  it 'should send valid access token request' do
198
260
  stubs = Faraday::Adapter::Test::Stubs.new do |stub|
199
261
  stub.post('/o/oauth2/token') do |env|
@@ -213,10 +275,10 @@ describe Signet::OAuth2::Client, 'configured for assertions profile' do
213
275
 
214
276
  @client.fetch_access_token!(:connection => connection)
215
277
  @client.access_token.should == "1/abcdef1234567890"
216
- stubs.verify_stubbed_calls
278
+ stubs.verify_stubbed_calls
217
279
  end
218
280
  end
219
-
281
+
220
282
  describe 'when using shared secrets' do
221
283
  before do
222
284
  @key = 'my secret key'
@@ -304,12 +366,12 @@ describe Signet::OAuth2::Client, 'configured for Google userinfo API' do
304
366
  @client.grant_type = 'urn:ietf:params:oauth:grant-type:saml2-bearer'
305
367
  @client.extension_parameters['assertion'] =
306
368
  'PEFzc2VydGlvbiBJc3N1ZUluc3RhbnQ9IjIwMTEtMDU'
307
-
369
+
308
370
  request = @client.generate_access_token_request
309
371
  params = Addressable::URI.form_unencode(request.body)
310
372
  params.should include(['assertion', 'PEFzc2VydGlvbiBJc3N1ZUluc3RhbnQ9IjIwMTEtMDU'])
311
373
  end
312
-
374
+
313
375
  it 'should allow the token to be updated' do
314
376
  issued_at = Time.now
315
377
  @client.update_token!(
@@ -351,19 +413,19 @@ describe Signet::OAuth2::Client, 'configured for Google userinfo API' do
351
413
  end
352
414
 
353
415
  it 'should allow the expires_at time to be updated' do
354
- expires_at = Time.now.round - 100
416
+ expires_at = Time.now
355
417
  @client.update_token!(
356
418
  :expires_at => expires_at.to_i,
357
419
  :expires_in => nil
358
420
  )
359
- @client.expires_at.should == expires_at
421
+ @client.expires_at.should be_within(1).of(expires_at)
360
422
  @client.should be_expired
361
423
  end
362
424
 
363
425
  it 'should allow setting expires_at manually' do
364
- expires_at = Time.now.round + 100
426
+ expires_at = Time.now+100
365
427
  @client.expires_at = expires_at.to_i
366
- @client.expires_at.should == expires_at
428
+ @client.expires_at.should be_within(1).of(expires_at)
367
429
  @client.should_not be_expired
368
430
  end
369
431
 
@@ -818,3 +880,62 @@ PUBKEY
818
880
  stubs.verify_stubbed_calls
819
881
  end
820
882
  end
883
+
884
+ describe Signet::OAuth2::Client, 'authorization_uri' do
885
+ before do
886
+ @client = Signet::OAuth2::Client.new(
887
+ :client_id => 's6BhdRkqt3',
888
+ :redirect_uri => 'https://example.client.com/callback',
889
+ :authorization_uri => 'https://example.com/authorize'
890
+ )
891
+ end
892
+
893
+ it 'should set access_type to offline by default' do
894
+ @client.authorization_uri.query_values['access_type'].should == 'offline'
895
+ end
896
+
897
+ it 'should set response_type to code by default' do
898
+ @client.authorization_uri.query_values['response_type'].should == 'code'
899
+ end
900
+
901
+ it 'should raise an error when setting both prompt and approval_prompt' do
902
+ (lambda do
903
+ @client.authorization_uri(:approval_prompt => 'force', :prompt => 'consent')
904
+ end).should raise_error(ArgumentError)
905
+ end
906
+ end
907
+
908
+ describe Signet::OAuth2::Client, 'configured with custom parameters' do
909
+ before do
910
+ @client = Signet::OAuth2::Client.new(
911
+ :client_id => 's6BhdRkqt3',
912
+ :redirect_uri => 'https://example.client.com/callback',
913
+ :authorization_uri => 'https://example.com/authorize',
914
+ :token_credential_uri => 'https://example.com/token',
915
+ :additional_parameters =>{'type' => 'web_server'}
916
+ )
917
+ end
918
+
919
+ it 'should allow custom parameters to be set on init' do
920
+ @client.additional_parameters.should == {'type' => 'web_server'}
921
+ end
922
+
923
+ it 'should allow custom parameters to be updated' do
924
+ @client.update!(:additional_parameters => {'type' => 'new_type'})
925
+ @client.additional_parameters.should == {'type' => 'new_type'}
926
+ end
927
+
928
+ it 'should use custom parameters when generating authorization_uri' do
929
+ @client.authorization_uri().query_values.should == {"access_type"=>"offline", "client_id"=>"s6BhdRkqt3", "redirect_uri"=>"https://example.client.com/callback", "response_type"=>"code", "type"=>"web_server"}
930
+ end
931
+ it 'should merge new authorization_uri custom parameters' do
932
+ @client.authorization_uri(:additional_parameters => {'type' => 'new_type', 'new_param' => 'new_val'}).query_values.should == {"access_type"=>"offline", "client_id"=>"s6BhdRkqt3", "new_param"=>"new_val", "response_type"=>"code","redirect_uri"=>"https://example.client.com/callback", "type"=>"new_type"}
933
+ end
934
+
935
+ it 'should merge new generate_access_token_request custom parameters' do
936
+ @client.update!(:code=>'12345')
937
+ body = @client.generate_access_token_request(:additional_parameters => {'type' => 'new_type', 'new_param' => 'new_val'}).body
938
+ body.should include("type=new_type")
939
+ body.should include("new_param=new_val")
940
+ end
941
+ end