signet 0.3.1 → 0.3.2

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