firebase_id_token 2.3.2 → 2.4.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 04e416cf72a26dfef4ba1555005cce301af06b10d68c34cb31873e4de4204307
4
- data.tar.gz: b35dbae1fcb4f1da7e6a240be49662ec090e70f22e9e940a2173583c35a3e91b
3
+ metadata.gz: eef2d227ba8e21f033a7d4c68f7d973a6d25b26e1c1900f43784606f1020332c
4
+ data.tar.gz: 2899b73b48998f8e14337eada01a76980e02fd1994821afd8a902f23ec40dfd5
5
5
  SHA512:
6
- metadata.gz: 59a99e199abc3b4280500cc6202b78d125cb89874c7e4c0fc19956c25f89362ec8262af785fcfd1efd38c8a429dc5a231c6cca39b0a170c007cf7d2962c84429
7
- data.tar.gz: c3654c443865086ba7aaaa66a5851ea6cf6549fc590ae24055491c0b44619a22399ea148d34e7e245dd5fc7ccf0bad0e04a2c3a3d1746ba1b40088db212e8f0b
6
+ metadata.gz: 7f64121a625def6dd48f7090fd5bfe25ed3ca754510a993b3dc9124b865e92c5610010a156c5520359c9c93d7301e8dfe9c4a46630f99df50b84742a61129fbf
7
+ data.tar.gz: 6b0fd92129b034f482fe8ed910a23e9f7201d42d510b03100f974e7adc919d9125915885c5211cf1c1cbf42363c72a987e3a1b493047aec27193317e2569d4f8
@@ -1,7 +1,7 @@
1
1
  sudo: false
2
2
  language: ruby
3
3
  rvm:
4
- - 2.4.0
5
- before_install: gem install bundler -v 1.14.6
4
+ - 2.6.3
5
+ before_install: gem install bundler -v 1.17.2
6
6
  services:
7
7
  - redis-server
@@ -0,0 +1,105 @@
1
+ # Changelog
2
+ All notable changes to this project will be documented in this file.
3
+
4
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [Unreleased]
8
+
9
+ ### Fixed
10
+ - Rake development dependency vulnerability [CVE-2020-8130](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-8130).
11
+
12
+ ### Changed
13
+ - Using Bundler 1.17.2.
14
+
15
+ ### Added
16
+ - Ability to raise errors when verifying tokens.
17
+ - `FirebaseIdToken::Certificates.find!` method.
18
+ - `FirebaseIdToken::Signatures.verify!` method.
19
+ - `FirebaseIdToken::Exceptions::CertificateNotFound` exception.
20
+ - `:raise_error` option to `FirebaseIdToken::Signature.verify`.
21
+ - `CHANGELOG.md` file.
22
+
23
+ ## [2.3.2] - 2020-02-15
24
+
25
+ ### Fixed
26
+ - Certificate fixture not accessible when packing Gem into Rails application.
27
+
28
+ ### Changed
29
+ - Bumped Bundler version to 1.14.
30
+
31
+ ## [2.3.1] - 2019-08-13
32
+
33
+ ### Fixed
34
+ - Certificate fixture reading issue.
35
+
36
+ ### Added
37
+ - Test mode.
38
+ - Test mode documentation.
39
+
40
+ ## [2.3.0] - 2018-06-18
41
+
42
+ ### Changed
43
+ - Started to use [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
44
+ - Runtime dependencies versions upgraded.
45
+ - Use Redis `>= 3.3.3`.
46
+
47
+ ## [2.2.0] - 2018-05-21
48
+ *Nothing tracked, release skipped.*
49
+
50
+ ## [2.1.0] - 2018-04-09
51
+
52
+ ### Fixed
53
+ - `FirebaseIdToken::Signature.verify` now returns `nil` for newly issued tokens.
54
+
55
+ ## [2.0.0] - 2017-12-09
56
+
57
+ ### Fixed
58
+ - Typo on Rake task `force_request` name.
59
+
60
+ ## [1.3.0] - 2017-09-15
61
+
62
+ ### Changed
63
+ - Renamed `Certificates.request_anyway` to `Certificates.request!` (`Certificates.request_anyway` was kept for backwards compatibility.
64
+
65
+ ### Fixed
66
+ - Documentaiton typos.
67
+ - Initializer typos.
68
+
69
+ ## [1.2.2] - 2017-04-29
70
+
71
+ ### Changed
72
+ - Recommended people to use cron tasks instead of background jobs.
73
+ - Set certificates TTL based on cache-control's max-age.
74
+ - Documentation now warns about request during application start in Rails.
75
+
76
+ ### Fixed
77
+ - Documentation typos.
78
+
79
+ ## [1.2.1] - 2017-04-27
80
+
81
+ ### Changed
82
+ - Small improvements on documentation.
83
+
84
+ ## [1.2.0] - 2017-04-26
85
+
86
+ ### Changed
87
+ - The Gem was marked as "ready to use".
88
+
89
+ ## [1.1.0] - 2017-04-26
90
+ *Nothing tracked.*
91
+
92
+ ## [1.0.0] - 2017-04-26
93
+ *Version removed.*
94
+
95
+ ## [0.1.0] - 2017-04-23
96
+ *Version removed.*
97
+
98
+ [2.3.2]: https://github.com/fschuindt/firebase_id_token/compare/2.3.1...2.3.2
99
+ [2.3.1]: https://github.com/fschuindt/firebase_id_token/compare/2.3.0...2.3.1
100
+ [2.3.0]: https://github.com/fschuindt/firebase_id_token/compare/2.0.0...2.3.0
101
+ [2.1.0]: https://github.com/fschuindt/firebase_id_token/compare/2.0.0...2.1.0
102
+ [2.0.0]: https://github.com/fschuindt/firebase_id_token/compare/1.3.0...2.0.0
103
+ [1.3.0]: https://github.com/fschuindt/firebase_id_token/compare/1.2.2...1.3.0
104
+ [1.2.2]: https://github.com/fschuindt/firebase_id_token/compare/1.2.1...1.2.2
105
+ [1.2.1]: https://github.com/fschuindt/firebase_id_token/compare/1.2.0...1.2.1
data/README.md CHANGED
@@ -29,7 +29,7 @@ gem install firebase_id_token
29
29
 
30
30
  or in your Gemfile
31
31
  ```
32
- gem 'firebase_id_token', '~> 2.3.1'
32
+ gem 'firebase_id_token', '~> 2.4.0'
33
33
  ```
34
34
  then
35
35
  ```
@@ -0,0 +1,9 @@
1
+ version: '3'
2
+
3
+ services:
4
+ redis:
5
+ image: redis:5-alpine
6
+ ports:
7
+ - "6379:6379"
8
+ expose:
9
+ - 6379
@@ -22,8 +22,8 @@ Gem::Specification.new do |spec|
22
22
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
23
  spec.require_paths = ['lib']
24
24
 
25
- spec.add_development_dependency 'bundler'
26
- spec.add_development_dependency 'rake', '~> 10.0'
25
+ spec.add_development_dependency 'bundler', '~> 1.17', '>= 1.17.2'
26
+ spec.add_development_dependency 'rake', '~> 12.3', '>= 12.3.3'
27
27
  spec.add_development_dependency 'rspec', '~> 3.0'
28
28
  spec.add_development_dependency 'redcarpet', '~> 3.4', '>= 3.4.0'
29
29
  spec.add_development_dependency 'simplecov', '~> 0.14.1'
@@ -7,6 +7,7 @@ require 'firebase_id_token/version'
7
7
  require 'firebase_id_token/exceptions/no_certificates_error'
8
8
  require 'firebase_id_token/exceptions/certificates_request_error'
9
9
  require 'firebase_id_token/exceptions/certificates_ttl_error'
10
+ require 'firebase_id_token/exceptions/certificate_not_found'
10
11
  require 'firebase_id_token/configuration'
11
12
  require 'firebase_id_token/certificates'
12
13
  require 'firebase_id_token/signature'
@@ -49,7 +50,7 @@ module FirebaseIdToken
49
50
 
50
51
  def self.configuration
51
52
  @configuration ||= Configuration.new
52
- end
53
+ end
53
54
 
54
55
  # Resets Configuration to defaults.
55
56
  def self.reset
@@ -111,13 +111,34 @@ module FirebaseIdToken
111
111
  # FirebaseIdToken::Certificates.request
112
112
  # cert = FirebaseIdToken::Certificates.find "1d6d01f4w7d54c7[...]"
113
113
  # #=> <OpenSSL::X509::Certificate: subject=#<OpenSSL [...]
114
- def self.find(kid)
114
+ def self.find(kid, raise_error: false)
115
115
  certs = new.local_certs
116
116
  raise Exceptions::NoCertificatesError if certs.empty?
117
117
 
118
- if certs[kid]
119
- OpenSSL::X509::Certificate.new certs[kid]
120
- end
118
+ return OpenSSL::X509::Certificate.new certs[kid] if certs[kid]
119
+
120
+ return unless raise_error
121
+
122
+ raise Exceptions::CertificateNotFound,
123
+ "Unable to find a certificate with `#{kid}`."
124
+ end
125
+
126
+ # Returns a `OpenSSL::X509::Certificate` object of the requested Key ID
127
+ # (KID) if there's one.
128
+ #
129
+ # @raise {Exceptions::CertificateNotFound} if it cannot be found.
130
+ #
131
+ # @raise {Exceptions::NoCertificatesError} if the Redis certificates
132
+ # database is empty.
133
+ #
134
+ # @param [String] kid Key ID
135
+ # @return [OpenSSL::X509::Certificate]
136
+ # @example
137
+ # FirebaseIdToken::Certificates.request
138
+ # cert = FirebaseIdToken::Certificates.find! "1d6d01f4w7d54c7[...]"
139
+ # #=> <OpenSSL::X509::Certificate: subject=#<OpenSSL [...]
140
+ def self.find!(kid)
141
+ find(kid, raise_error: true)
121
142
  end
122
143
 
123
144
  # Returns the current certificates TTL (Time-To-Live) in seconds. *Zero
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FirebaseIdToken
4
+ module Exceptions
5
+ # @see FirebaseIdToken::Certificates.find!
6
+ class CertificateNotFound < StandardError; end
7
+ end
8
+ end
@@ -42,9 +42,25 @@ module FirebaseIdToken
42
42
  # Note that it will raise a {Exceptions::NoCertificatesError} if the Redis
43
43
  # certificates database is empty. Ensure to call {Certificates.request}
44
44
  # before, ideally in a background job if you are using Rails.
45
+ #
46
+ # If you would like this to raise and error, rather than silently failing,
47
+ # you can with the `raise_error` parameter. Example:
48
+ #
49
+ # FirebaseIdToken::Signature
50
+ # .verify(token, raise_error: Rails.env.development?)
51
+ #
52
+ # @param raise_error [Boolean] default: false
45
53
  # @return [nil, Hash]
46
- def self.verify(jwt_token)
47
- new(jwt_token).verify
54
+ def self.verify(jwt_token, raise_error: false)
55
+ new(jwt_token, raise_error: raise_error).verify
56
+ end
57
+
58
+ # Equivalent to `.verify(jwt_token, raise_error: true)`.
59
+ #
60
+ # @see {Signature.verify}
61
+ # @return [Hash]
62
+ def self.verify!(jwt_token)
63
+ new(jwt_token, raise_error: true).verify
48
64
  end
49
65
 
50
66
  attr_accessor :firebase_id_token_certificates
@@ -52,21 +68,21 @@ module FirebaseIdToken
52
68
  # Loads attributes: `:project_ids` from {FirebaseIdToken::Configuration},
53
69
  # and `:kid`, `:jwt_token` from the related `jwt_token`.
54
70
  # @param [String] jwt_token Firebase ID Token
55
- def initialize(jwt_token)
71
+ def initialize(jwt_token, raise_error: false)
72
+ @raise_error = raise_error
56
73
  @project_ids = FirebaseIdToken.configuration.project_ids
57
74
  @kid = extract_kid(jwt_token)
58
75
  @jwt_token = jwt_token
59
76
  @firebase_id_token_certificates = FirebaseIdToken.configuration.certificates
60
-
61
77
  end
62
78
 
63
79
  # @see Signature.verify
64
80
  def verify
65
- certificate = firebase_id_token_certificates.find(@kid)
66
- if certificate
67
- payload = decode_jwt_payload(@jwt_token, certificate.public_key)
68
- authorize payload
69
- end
81
+ certificate = firebase_id_token_certificates.find(@kid, raise_error: @raise_error)
82
+ return unless certificate
83
+
84
+ payload = decode_jwt_payload(@jwt_token, certificate.public_key)
85
+ authorize payload
70
86
  end
71
87
 
72
88
  private
@@ -74,13 +90,17 @@ module FirebaseIdToken
74
90
  def extract_kid(jwt_token)
75
91
  JWT.decode(jwt_token, nil, false).last['kid']
76
92
  rescue StandardError
77
- 'none'
93
+ return 'none' unless @raise_error
94
+
95
+ raise
78
96
  end
79
97
 
80
98
  def decode_jwt_payload(token, cert_key)
81
99
  JWT.decode(token, cert_key, true, JWT_DEFAULTS).first
82
100
  rescue StandardError
83
- nil
101
+ return nil unless @raise_error
102
+
103
+ raise
84
104
  end
85
105
 
86
106
  def authorize(payload)
@@ -12,10 +12,10 @@ module FirebaseIdToken
12
12
  # + {Certificates.private_key}
13
13
  # + {Certificates.certificate}
14
14
  class Certificates
15
- # `.find` is stabbed to always return the same certificate.
15
+ # `.find` is stubbed to always return the same certificate.
16
16
  # @param [String] kid Key ID
17
17
  # @return [nil, OpenSSL::X509::Certificate]
18
- def self.find(kid)
18
+ def self.find(kid, raise_error: false)
19
19
  cert = certificate
20
20
  OpenSSL::X509::Certificate.new cert
21
21
  end
@@ -1,3 +1,3 @@
1
1
  module FirebaseIdToken
2
- VERSION = '2.3.2'
2
+ VERSION = '2.4.0'
3
3
  end
@@ -128,6 +128,28 @@ module FirebaseIdToken
128
128
  end
129
129
  end
130
130
 
131
+ describe '.find!' do
132
+ context 'without certificates in Redis database' do
133
+ it 'raises a exception' do
134
+ expect{ described_class.find!(kid)}.
135
+ to raise_error(Exceptions::NoCertificatesError)
136
+ end
137
+ end
138
+ context 'with certificates in Redis database' do
139
+ it 'returns a OpenSSL::X509::Certificate when it finds the kid' do
140
+ described_class.request
141
+ expect(described_class.find!(kid)).to be_a(OpenSSL::X509::Certificate)
142
+ end
143
+
144
+ it 'raises a CertificateNotFound error when it can not find the kid' do
145
+ described_class.request
146
+ expect { described_class.find!('') }
147
+ .to raise_error(Exceptions::CertificateNotFound, /Unable to find/)
148
+ end
149
+ end
150
+
151
+ end
152
+
131
153
  describe '.ttl' do
132
154
  it 'returns a positive number when has certificates in Redis' do
133
155
  described_class.request
@@ -3,11 +3,14 @@ require 'spec_helper'
3
3
  module FirebaseIdToken
4
4
  describe Signature do
5
5
  let(:jwt) { JSON.parse File.read('spec/fixtures/files/jwt.json') }
6
+ let(:raise_certificates_error) { false }
6
7
 
7
- let (:mock_certificates) {
8
- allow(Certificates).to receive(:find).with(an_instance_of(String)) {
9
- OpenSSL::X509::Certificate.new(jwt['certificate']) }
10
- }
8
+ let(:mock_certificates) do
9
+ allow(Certificates)
10
+ .to(receive(:find))
11
+ .with(an_instance_of(String), raise_error: raise_certificates_error)
12
+ .and_return(OpenSSL::X509::Certificate.new(jwt['certificate']))
13
+ end
11
14
 
12
15
  before :each do
13
16
  mock_certificates
@@ -29,5 +32,22 @@ module FirebaseIdToken
29
32
  expect(described_class.verify('aaa')).to be(nil)
30
33
  end
31
34
  end
35
+
36
+ describe '#verify!' do
37
+ let(:raise_certificates_error) { true }
38
+ it 'returns a Hash when the signature is valid' do
39
+ expect(described_class.verify!(jwt['jwt_token'])).to be_a(Hash)
40
+ end
41
+
42
+ it 'raises an error when the signature is invalid' do
43
+ expect { described_class.verify!(jwt['bad_jwt_token']) }
44
+ .to raise_error(JWT::VerificationError)
45
+ end
46
+
47
+ it 'raises an error with a invalid key format' do
48
+ expect { described_class.verify!('aaa') }
49
+ .to raise_error(JWT::DecodeError, /too many/)
50
+ end
51
+ end
32
52
  end
33
53
  end
metadata CHANGED
@@ -1,43 +1,55 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: firebase_id_token
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.2
4
+ version: 2.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fernando Schuindt
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-02-15 00:00:00.000000000 Z
11
+ date: 2020-05-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.17'
17
20
  - - ">="
18
21
  - !ruby/object:Gem::Version
19
- version: '0'
22
+ version: 1.17.2
20
23
  type: :development
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '1.17'
24
30
  - - ">="
25
31
  - !ruby/object:Gem::Version
26
- version: '0'
32
+ version: 1.17.2
27
33
  - !ruby/object:Gem::Dependency
28
34
  name: rake
29
35
  requirement: !ruby/object:Gem::Requirement
30
36
  requirements:
31
37
  - - "~>"
32
38
  - !ruby/object:Gem::Version
33
- version: '10.0'
39
+ version: '12.3'
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 12.3.3
34
43
  type: :development
35
44
  prerelease: false
36
45
  version_requirements: !ruby/object:Gem::Requirement
37
46
  requirements:
38
47
  - - "~>"
39
48
  - !ruby/object:Gem::Version
40
- version: '10.0'
49
+ version: '12.3'
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 12.3.3
41
53
  - !ruby/object:Gem::Dependency
42
54
  name: rspec
43
55
  requirement: !ruby/object:Gem::Requirement
@@ -214,6 +226,7 @@ files:
214
226
  - ".rspec"
215
227
  - ".travis.yml"
216
228
  - ".yardopts"
229
+ - CHANGELOG.md
217
230
  - CODE_OF_CONDUCT.md
218
231
  - Gemfile
219
232
  - LICENSE.txt
@@ -221,10 +234,12 @@ files:
221
234
  - Rakefile
222
235
  - bin/console
223
236
  - bin/setup
237
+ - docker-compose.yml
224
238
  - firebase_id_token.gemspec
225
239
  - lib/firebase_id_token.rb
226
240
  - lib/firebase_id_token/certificates.rb
227
241
  - lib/firebase_id_token/configuration.rb
242
+ - lib/firebase_id_token/exceptions/certificate_not_found.rb
228
243
  - lib/firebase_id_token/exceptions/certificates_request_error.rb
229
244
  - lib/firebase_id_token/exceptions/certificates_ttl_error.rb
230
245
  - lib/firebase_id_token/exceptions/no_certificates_error.rb