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 +4 -4
- data/.travis.yml +2 -2
- data/CHANGELOG.md +105 -0
- data/README.md +1 -1
- data/docker-compose.yml +9 -0
- data/firebase_id_token.gemspec +2 -2
- data/lib/firebase_id_token.rb +2 -1
- data/lib/firebase_id_token/certificates.rb +25 -4
- data/lib/firebase_id_token/exceptions/certificate_not_found.rb +8 -0
- data/lib/firebase_id_token/signature.rb +31 -11
- data/lib/firebase_id_token/testing/certificates.rb +2 -2
- data/lib/firebase_id_token/version.rb +1 -1
- data/spec/firebase_id_token/certificates_spec.rb +22 -0
- data/spec/firebase_id_token/signature_spec.rb +24 -4
- metadata +21 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: eef2d227ba8e21f033a7d4c68f7d973a6d25b26e1c1900f43784606f1020332c
|
4
|
+
data.tar.gz: 2899b73b48998f8e14337eada01a76980e02fd1994821afd8a902f23ec40dfd5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7f64121a625def6dd48f7090fd5bfe25ed3ca754510a993b3dc9124b865e92c5610010a156c5520359c9c93d7301e8dfe9c4a46630f99df50b84742a61129fbf
|
7
|
+
data.tar.gz: 6b0fd92129b034f482fe8ed910a23e9f7201d42d510b03100f974e7adc919d9125915885c5211cf1c1cbf42363c72a987e3a1b493047aec27193317e2569d4f8
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
ADDED
@@ -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
data/docker-compose.yml
ADDED
data/firebase_id_token.gemspec
CHANGED
@@ -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', '~>
|
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'
|
data/lib/firebase_id_token.rb
CHANGED
@@ -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
|
-
|
120
|
-
|
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
|
@@ -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
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
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
|
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
|
@@ -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
|
8
|
-
allow(Certificates)
|
9
|
-
|
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.
|
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
|
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:
|
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:
|
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: '
|
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: '
|
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
|