signet 0.3.1 → 0.3.2

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.
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ # 0.3.2
2
+
3
+ * Added audience security check for ID tokens
4
+
1
5
  # 0.3.1
2
6
 
3
7
  * Fixed a warning while determining grant type
@@ -535,7 +535,14 @@ module Signet
535
535
  #
536
536
  # @return [String] The decoded ID token.
537
537
  def decoded_id_token(public_key=nil)
538
- JWT.decode(self.id_token, public_key, !!public_key)
538
+ decoded = JWT.decode(self.id_token, public_key, !!public_key)
539
+ if !decoded.has_key?('aud')
540
+ raise Signet::UnsafeOperationError, 'No ID token audience declared.'
541
+ elsif decoded['aud'] != self.client_id
542
+ raise Signet::UnsafeOperationError,
543
+ 'ID token audience did not match Client ID.'
544
+ end
545
+ return decoded
539
546
  end
540
547
 
541
548
  ##
@@ -18,7 +18,7 @@ unless defined? Signet::VERSION
18
18
  module VERSION
19
19
  MAJOR = 0
20
20
  MINOR = 3
21
- TINY = 1
21
+ TINY = 2
22
22
 
23
23
  STRING = [MAJOR, MINOR, TINY].join('.')
24
24
  end
@@ -513,17 +513,18 @@ describe Signet::OAuth1::Client, 'configured' do
513
513
  @client.generate_authenticated_request(
514
514
  :request => []
515
515
  )
516
- end).should raise_error(ArgumentError)
516
+ end).should raise_error
517
517
  end
518
518
 
519
- it 'should raise an error if a request is provided without a connection' do
519
+ it 'should not raise an error if a request is ' +
520
+ 'provided without a connection' do
520
521
  (lambda do
521
522
  @client.generate_authenticated_request(
522
523
  :request => Faraday::Request.new(:get) do |req|
523
524
  req.url('http://www.example.com/')
524
525
  end
525
526
  )
526
- end).should raise_error(ArgumentError)
527
+ end).should_not raise_error(ArgumentError)
527
528
  end
528
529
 
529
530
  it 'should raise an error if no URI is provided' do
@@ -460,7 +460,8 @@ JSON
460
460
  request.headers['Authorization'].should == 'Bearer 12345, realm="Example"'
461
461
  end
462
462
 
463
- it 'should raise an error if Faraday::Request is used without connection' do
463
+ it 'should not raise an error if a request is ' +
464
+ 'provided without a connection' do
464
465
  @client.client_id = 'client-12345'
465
466
  @client.client_secret = 'secret-12345'
466
467
  @client.access_token = '12345'
@@ -471,7 +472,7 @@ JSON
471
472
  req.url('https://www.googleapis.com/oauth2/v1/userinfo?alt=json')
472
473
  end
473
474
  )
474
- end).should raise_error(ArgumentError)
475
+ end).should_not raise_error
475
476
  end
476
477
 
477
478
  it 'should raise an error if not enough information ' +
@@ -554,7 +555,7 @@ JSON
554
555
  stubs.verify_stubbed_calls
555
556
  end
556
557
 
557
- it 'should correctly handle an id token' do
558
+ it 'should correctly handle an ID token' do
558
559
  @client.client_id = 'client-12345'
559
560
  @client.client_secret = 'secret-12345'
560
561
  stubs = Faraday::Adapter::Test::Stubs.new do |stub|
@@ -564,14 +565,11 @@ JSON
564
565
  'refresh_token' => '54321',
565
566
  'expires_in' => '3600',
566
567
  'id_token' => (
567
- 'eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJhY2NvdW50cy5nb29nbGUuY29tIiwiY' +
568
- 'XVkIjoiMTA2MDM1Nzg5MTY4OC5hcHBzLmdvb2dsZXVzZXJjb250ZW50LmNvbSI' +
569
- 'sImNpZCI6IjEwNjAzNTc4OTE2ODguYXBwcy5nb29nbGV1c2VyY29udGVudC5jb' +
570
- '20iLCJpZCI6IjExNjQ1MjgyNDMwOTg1Njc4MjE2MyIsInRva2VuX2hhc2giOiJ' +
571
- '0Z2hEOUo4bjhWME4ydmN3NmVNaWpnIiwiaWF0IjoxMzIwNjcwOTc4LCJleHAiO' +
572
- 'jEzMjA2NzQ4Nzh9.D8x_wirkxDElqKdJBcsIws3Ogesk38okz6MN7zqC7nEAA7' +
573
- 'wcy1PxsROY1fmBvXSer0IQesAqOW-rPOCNReSn-eY8d53ph1x2HAF-AzEi3GOl' +
574
- '6hFycH8wj7Su6JqqyEbIVLxE7q7DkAZGaMPkxbTHs1EhSd5_oaKQ6O4xO3ZnnT4'
568
+ 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl9oYXNoIjoidGdoRD' +
569
+ 'lKN244VjBOMnZjdzZlTWlqZyIsImF1ZCI6ImNsaWVudC0xMjM0NSIsImlkIjoiM' +
570
+ 'TIzNDUiLCJpYXQiOjEzMjA2NzA5NzgsImV4cCI6MTMyMDY3NDg3OCwiY2lkIjoi' +
571
+ 'Y2xpZW50LTEyMzQ1IiwiaXNzIjoiZXhhbXBsZS5jb20ifQ.tsF3srlBaAh6pV3U' +
572
+ 'wfRrHSA3-jwnvOw6MMsQ6sO4kjc'
575
573
  )
576
574
  })]
577
575
  end
@@ -585,18 +583,87 @@ JSON
585
583
  @client.access_token.should == '12345'
586
584
  @client.refresh_token.should == '54321'
587
585
  @client.decoded_id_token.should == {
588
- "token_hash" => "tghD9J8n8V0N2vcw6eMijg",
589
- "id" => "116452824309856782163",
590
- "aud" => "1060357891688.apps.googleusercontent.com",
586
+ "token_hash" => "tghD9J7n8V0N2vcw6eMijg",
587
+ "id" => "12345",
588
+ "aud" => "client-12345",
591
589
  "iat" => 1320670978,
592
590
  "exp" => 1320674878,
593
- "cid" => "1060357891688.apps.googleusercontent.com",
594
- "iss" => "accounts.google.com"
591
+ "cid" => "client-12345",
592
+ "iss" => "example.com"
595
593
  }
596
594
  @client.expires_in.should == 3600
597
595
  stubs.verify_stubbed_calls
598
596
  end
599
597
 
598
+ it 'should raise an error decoding an ID token if ' +
599
+ 'audience does not match client ID' do
600
+ @client.client_id = 'client-54321'
601
+ @client.client_secret = 'secret-12345'
602
+ stubs = Faraday::Adapter::Test::Stubs.new do |stub|
603
+ stub.post('/o/oauth2/token') do
604
+ [200, {}, MultiJson.encode({
605
+ 'access_token' => '12345',
606
+ 'refresh_token' => '54321',
607
+ 'expires_in' => '3600',
608
+ 'id_token' => (
609
+ 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl9oYXNoIjoidGdoRD' +
610
+ 'lKN244VjBOMnZjdzZlTWlqZyIsImF1ZCI6ImNsaWVudC0xMjM0NSIsImlkIjoiM' +
611
+ 'TIzNDUiLCJpYXQiOjEzMjA2NzA5NzgsImV4cCI6MTMyMDY3NDg3OCwiY2lkIjoi' +
612
+ 'Y2xpZW50LTEyMzQ1IiwiaXNzIjoiZXhhbXBsZS5jb20ifQ.tsF3srlBaAh6pV3U' +
613
+ 'wfRrHSA3-jwnvOw6MMsQ6sO4kjc'
614
+ )
615
+ })]
616
+ end
617
+ end
618
+ connection = Faraday.new(:url => 'https://www.google.com') do |builder|
619
+ builder.adapter(:test, stubs)
620
+ end
621
+ @client.fetch_access_token!(
622
+ :connection => connection
623
+ )
624
+ @client.access_token.should == '12345'
625
+ @client.refresh_token.should == '54321'
626
+ @client.expires_in.should == 3600
627
+ (lambda do
628
+ @client.decoded_id_token
629
+ end).should raise_error(Signet::UnsafeOperationError)
630
+ stubs.verify_stubbed_calls
631
+ end
632
+
633
+ it 'should raise an error decoding an ID token if ' +
634
+ 'audience is missing' do
635
+ @client.client_id = 'client-12345'
636
+ @client.client_secret = 'secret-12345'
637
+ stubs = Faraday::Adapter::Test::Stubs.new do |stub|
638
+ stub.post('/o/oauth2/token') do
639
+ [200, {}, MultiJson.encode({
640
+ 'access_token' => '12345',
641
+ 'refresh_token' => '54321',
642
+ 'expires_in' => '3600',
643
+ 'id_token' => (
644
+ 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl9oYXNoIjoidGdoRD' +
645
+ 'lKN244VjBOMnZjdzZlTWlqZyIsImlkIjoiMTIzNDUiLCJpYXQiOjEzMjA2NzA5N' +
646
+ 'zgsImV4cCI6MTMyMDY3NDg3OCwiY2lkIjoiY2xpZW50LTEyMzQ1IiwiaXNzIjoi' +
647
+ 'ZXhhbXBsZS5jb20ifQ.7qj85CKbQyVdDe5y2ScdJAZNkEeKMPW9LIonLxG1vu8'
648
+ )
649
+ })]
650
+ end
651
+ end
652
+ connection = Faraday.new(:url => 'https://www.google.com') do |builder|
653
+ builder.adapter(:test, stubs)
654
+ end
655
+ @client.fetch_access_token!(
656
+ :connection => connection
657
+ )
658
+ @client.access_token.should == '12345'
659
+ @client.refresh_token.should == '54321'
660
+ @client.expires_in.should == 3600
661
+ (lambda do
662
+ @client.decoded_id_token
663
+ end).should raise_error(Signet::UnsafeOperationError)
664
+ stubs.verify_stubbed_calls
665
+ end
666
+
600
667
  it 'should raise an error if the id token cannot be verified' do
601
668
  @client.client_id = 'client-12345'
602
669
  @client.client_secret = 'secret-12345'
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: signet
3
3
  version: !ruby/object:Gem::Version
4
- hash: 17
5
- prerelease:
4
+ hash: 23
5
+ prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 3
9
- - 1
10
- version: 0.3.1
9
+ - 2
10
+ version: 0.3.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Bob Aman
@@ -15,7 +15,8 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-01-30 00:00:00 Z
18
+ date: 2012-01-31 00:00:00 +03:00
19
+ default_executable:
19
20
  dependencies:
20
21
  - !ruby/object:Gem::Dependency
21
22
  name: addressable
@@ -193,6 +194,7 @@ files:
193
194
  - LICENSE
194
195
  - Rakefile
195
196
  - README.md
197
+ has_rdoc: true
196
198
  homepage: http://signet.rubyforge.org/
197
199
  licenses: []
198
200
 
@@ -223,7 +225,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
223
225
  requirements: []
224
226
 
225
227
  rubyforge_project: signet
226
- rubygems_version: 1.8.15
228
+ rubygems_version: 1.3.7
227
229
  signing_key:
228
230
  specification_version: 3
229
231
  summary: Package Summary