firebase_auth_ruby 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: e67c7096cdd959d57fe0018262f5d9eacc8b60d7af65f86d76376ee973f4a440
4
+ data.tar.gz: f840ca046b42ae6573c68be346bce03fcd6ac9bc27b805b046af1b238d6cfe82
5
+ SHA512:
6
+ metadata.gz: a003c3c879ae030ff20bfdc43cd764c211b263f5dce6abbec112708aaccb323676a3d4d92fa11fa76305d583e82a5c6cfb78a15ec19edbf95429610f512ff482
7
+ data.tar.gz: 669413ca5ddf990aaa21e1490c0dda6e80a73c7cda40dc62992db9fb0af4d02a088e2f17e5efcbfbac3db5ce5b19c07fd94df817059b829fe48c78d1e15e85aa
@@ -0,0 +1,20 @@
1
+ name: ci
2
+
3
+ on: [push]
4
+
5
+ jobs:
6
+ build:
7
+
8
+ runs-on: ubuntu-latest
9
+
10
+ steps:
11
+ - uses: actions/checkout@v1
12
+ - name: Set up Ruby
13
+ uses: actions/setup-ruby@v1
14
+ with:
15
+ ruby-version: 2.6.x
16
+ - name: Build and test with Rake
17
+ run: |
18
+ gem install bundler
19
+ bundle install --jobs 4 --retry 3
20
+ bundle exec rake
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ Gemfile.lock
@@ -0,0 +1 @@
1
+ noop
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in firebase_auth_ruby.gemspec
4
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2019 Yukito Ito
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,39 @@
1
+ # FirebaseAuthRuby
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/firebase_auth_ruby`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'firebase_auth_ruby'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install firebase_auth_ruby
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/firebase_auth_ruby.
36
+
37
+ ## License
38
+
39
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList["test/**/*_test.rb"]
8
+ end
9
+
10
+ task :default => :test
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "firebase_auth_ruby"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,35 @@
1
+ lib = File.expand_path("lib", __dir__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require "firebase_auth_ruby/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "firebase_auth_ruby"
7
+ spec.version = FirebaseAuthRuby::VERSION
8
+ spec.authors = ["Yukito Ito"]
9
+ spec.email = ["yukibukiyou@gmail.com"]
10
+
11
+ spec.summary = %q{Firebase Auth with Ruby}
12
+ spec.description = %q{Verify ID Token}
13
+ spec.homepage = "https://github.com/ykpythemind/firebase_auth_ruby"
14
+ spec.license = "MIT"
15
+
16
+ spec.metadata["homepage_uri"] = spec.homepage
17
+ spec.metadata["source_code_uri"] = "https://github.com/ykpythemind/firebase_auth_ruby"
18
+ spec.metadata["changelog_uri"] = "https://github.com/ykpythemind/firebase_auth_ruby/CHANGELOG.md"
19
+
20
+ # Specify which files should be added to the gem when it is released.
21
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
22
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
23
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
24
+ end
25
+ spec.bindir = "exe"
26
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
27
+ spec.require_paths = ["lib"]
28
+
29
+ spec.add_dependency "jwt", ">= 2.2"
30
+ spec.add_dependency "activesupport"
31
+
32
+ spec.add_development_dependency "bundler", "~> 2.0"
33
+ spec.add_development_dependency "rake", "~> 10.0"
34
+ spec.add_development_dependency "minitest", "~> 5.0"
35
+ end
@@ -0,0 +1,17 @@
1
+ require 'active_support/core_ext/module/attribute_accessors'
2
+ require "jwt"
3
+
4
+ module FirebaseAuthRuby
5
+ class Error < StandardError; end
6
+
7
+ mattr_accessor :cache_store
8
+ end
9
+
10
+ require "firebase_auth_ruby/version"
11
+
12
+ require "firebase_auth_ruby/util"
13
+ require "firebase_auth_ruby/public_key_fetcher"
14
+
15
+ require "firebase_auth_ruby/verifier/base"
16
+ require "firebase_auth_ruby/verifier/id_token_verifier"
17
+ require "firebase_auth_ruby/verifier/cookie_session_verifier"
@@ -0,0 +1,60 @@
1
+ require "forwardable"
2
+ require 'json'
3
+ require 'net/http'
4
+ require 'uri'
5
+
6
+ module FirebaseAuthRuby
7
+ class PublicKeyFetcher
8
+ extend Forwardable
9
+
10
+ def_delegator ::FirebaseAuthRuby, :cache_store
11
+ def_delegators :cache_store, :read, :write
12
+
13
+ def initialize
14
+ @cache_hit = false
15
+ end
16
+
17
+ def fetch(url)
18
+ @cache_hit = false
19
+
20
+ public_keys = read(public_keys_cache_key(url))
21
+ public_keys_expire_at = read(expire_at_cache_key(url))
22
+
23
+ public_keys_still_valid = public_keys && public_keys_expire_at && Time.now.to_i < public_keys_expire_at.to_i
24
+
25
+ if public_keys_still_valid
26
+ @cache_hit = true
27
+ return public_keys
28
+ end
29
+
30
+ res = Util.get!(url)
31
+
32
+ cache_control_header = res['cache-control']
33
+ if cache_control_header
34
+ parts = cache_control_header.split(',')
35
+ parts.each { |part|
36
+ subpart = part.strip.split('=')
37
+ if subpart[0] == 'max-age'
38
+ max_age = subpart[1].to_i
39
+ write(expire_at_cache_key(url), Time.now.to_i + (max_age * 1000))
40
+ end
41
+ }
42
+ end
43
+
44
+ public_keys = JSON.parse(res.body)
45
+ write(public_keys_cache_key(url), public_keys)
46
+
47
+ public_keys
48
+ end
49
+
50
+ private
51
+
52
+ def public_keys_cache_key(url)
53
+ "firebase_auth_ruby/public_keys/#{url}"
54
+ end
55
+
56
+ def expire_at_cache_key(url)
57
+ "firebase_auth_ruby/public_keys_expire_at/#{url}"
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,16 @@
1
+ require 'net/https'
2
+
3
+ module FirebaseAuthRuby
4
+ module Util
5
+ def self.get!(url)
6
+ uri = URI.parse(url)
7
+ http = Net::HTTP.new(uri.host, 443)
8
+ http.use_ssl = true
9
+
10
+ res = http.get(uri.path)
11
+ raise Error unless res.is_a? Net::HTTPSuccess
12
+
13
+ res
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,69 @@
1
+
2
+ module FirebaseAuthRuby::Verifier
3
+ class Base
4
+ def self.verify!(token:, project_id:, public_key_fetcher: PublicKeyFetcher.new)
5
+ new(
6
+ token: token,
7
+ project_id: project_id,
8
+ public_key_fetcher: public_key_fetcher
9
+ ).verify!
10
+ end
11
+
12
+ def initialize(token:, project_id:, public_key_fetcher:)
13
+ @token = token
14
+ @project_id = project_id
15
+ @public_key_fetcher = public_key_fetcher
16
+ end
17
+
18
+ def verify!
19
+ public_key = fetch_and_check_public_key!
20
+
21
+ decode_with_pubkey!(public_key)
22
+ end
23
+
24
+ private
25
+
26
+ attr_reader :token, :project_id, :public_key_fetcher
27
+
28
+ def fetch_and_check_public_key!
29
+ public_keys = public_key_fetcher.fetch(public_key_url)
30
+
31
+ decoded =
32
+ JWT.decode token,
33
+ nil,
34
+ false,
35
+ verify_iat: true,
36
+ verify_aud: true, aud: project_id,
37
+ verify_iss: true, iss: iss
38
+
39
+ headers = decoded[1]
40
+ kid = headers['kid'] || raise(Error, %("kid" not found in JWT header))
41
+
42
+ raise Error, %("kid" claim does not correspond to a known public key.) unless public_keys.key?(kid)
43
+
44
+ public_keys[kid]
45
+ end
46
+
47
+ def decode_with_pubkey!(public_key)
48
+ cert = OpenSSL::X509::Certificate.new(public_key)
49
+ decoded =
50
+ JWT.decode token,
51
+ cert.public_key,
52
+ true,
53
+ algorithm: 'RS256',
54
+ iss: iss, verify_iss: true,
55
+ aud: project_id, verify_aud: true,
56
+ verify_iat: true
57
+
58
+ decoded[0]
59
+ end
60
+
61
+ def iss
62
+ raise NotImplementedError
63
+ end
64
+
65
+ def public_key_url
66
+ raise NotImplementedError
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,15 @@
1
+ module FirebaseAuthRuby::Verifier
2
+ class CookieSessionVerifier < Base
3
+ # https://firebase.google.com/docs/auth/admin/manage-cookies#verify_session_cookie_and_check_permissions
4
+
5
+ private
6
+
7
+ def iss
8
+ "https://session.firebase.google.com/#{project_id}"
9
+ end
10
+
11
+ def public_key_url
12
+ "https://www.googleapis.com/identitytoolkit/v3/relyingparty/publicKeys"
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ module FirebaseAuthRuby::Verifier
2
+ class IdTokenVerifier < Base
3
+ # https://firebase.google.com/docs/auth/admin/verify-id-tokens
4
+
5
+ private
6
+
7
+ def iss
8
+ "https://securetoken.google.com/#{project_id}"
9
+ end
10
+
11
+ def public_key_url
12
+ "https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com"
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,3 @@
1
+ module FirebaseAuthRuby
2
+ VERSION = "0.1.0"
3
+ end
metadata ADDED
@@ -0,0 +1,133 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: firebase_auth_ruby
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Yukito Ito
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2019-10-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: jwt
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '2.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '2.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activesupport
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '2.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '2.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '10.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '10.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: minitest
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '5.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '5.0'
83
+ description: Verify ID Token
84
+ email:
85
+ - yukibukiyou@gmail.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - ".github/workflows/ci.yml"
91
+ - ".gitignore"
92
+ - CHANGELOG.md
93
+ - Gemfile
94
+ - LICENSE.txt
95
+ - README.md
96
+ - Rakefile
97
+ - bin/console
98
+ - bin/setup
99
+ - firebase_auth_ruby.gemspec
100
+ - lib/firebase_auth_ruby.rb
101
+ - lib/firebase_auth_ruby/public_key_fetcher.rb
102
+ - lib/firebase_auth_ruby/util.rb
103
+ - lib/firebase_auth_ruby/verifier/base.rb
104
+ - lib/firebase_auth_ruby/verifier/cookie_session_verifier.rb
105
+ - lib/firebase_auth_ruby/verifier/id_token_verifier.rb
106
+ - lib/firebase_auth_ruby/version.rb
107
+ homepage: https://github.com/ykpythemind/firebase_auth_ruby
108
+ licenses:
109
+ - MIT
110
+ metadata:
111
+ homepage_uri: https://github.com/ykpythemind/firebase_auth_ruby
112
+ source_code_uri: https://github.com/ykpythemind/firebase_auth_ruby
113
+ changelog_uri: https://github.com/ykpythemind/firebase_auth_ruby/CHANGELOG.md
114
+ post_install_message:
115
+ rdoc_options: []
116
+ require_paths:
117
+ - lib
118
+ required_ruby_version: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - ">="
121
+ - !ruby/object:Gem::Version
122
+ version: '0'
123
+ required_rubygems_version: !ruby/object:Gem::Requirement
124
+ requirements:
125
+ - - ">="
126
+ - !ruby/object:Gem::Version
127
+ version: '0'
128
+ requirements: []
129
+ rubygems_version: 3.0.3
130
+ signing_key:
131
+ specification_version: 4
132
+ summary: Firebase Auth with Ruby
133
+ test_files: []