firebase-admin-sdk 0.1.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 +7 -0
- data/.github/workflows/main.yml +38 -0
- data/.gitignore +15 -0
- data/.rspec +2 -0
- data/.ruby-version +1 -0
- data/Gemfile +5 -0
- data/LICENSE.txt +21 -0
- data/README.md +52 -0
- data/Rakefile +10 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/firebase-admin-sdk.gemspec +36 -0
- data/lib/firebase-admin-sdk.rb +17 -0
- data/lib/firebase/admin/app.rb +34 -0
- data/lib/firebase/admin/auth/certificates_fetcher.rb +62 -0
- data/lib/firebase/admin/auth/client.rb +116 -0
- data/lib/firebase/admin/auth/error.rb +23 -0
- data/lib/firebase/admin/auth/token_verifier.rb +114 -0
- data/lib/firebase/admin/auth/user_info.rb +60 -0
- data/lib/firebase/admin/auth/user_manager.rb +92 -0
- data/lib/firebase/admin/auth/user_record.rb +70 -0
- data/lib/firebase/admin/auth/utils.rb +93 -0
- data/lib/firebase/admin/config.rb +57 -0
- data/lib/firebase/admin/credentials.rb +79 -0
- data/lib/firebase/admin/error.rb +9 -0
- data/lib/firebase/admin/gce.rb +42 -0
- data/lib/firebase/admin/internal/http_client.rb +78 -0
- data/lib/firebase/admin/version.rb +7 -0
- metadata +230 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 943bc48f322900cf959c1a0ec6342f3fbfb8f40af3ef971bf19e63d65b5a0fd4
|
4
|
+
data.tar.gz: fbf64b91cc0a3d98425db69fddf5382086df4652fded37178e87c312ec8d2669
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 05d47f8bdc6b33ba5d3902e42ddc54f4438c3c13f3b5d048237244e3f71ad1006f86798804cb5ad8e5c8e24a5a10996c2033dddea118972ecf6556209e646fbd
|
7
|
+
data.tar.gz: 067d29dc598a88f7825c1b00487bdcb0969c5153962505a935458c9c8c27ff972a8684b99eb7b960b250777335fc31d6a6d4586c26f523f6b50899540401a774
|
@@ -0,0 +1,38 @@
|
|
1
|
+
name: ruby
|
2
|
+
on: push
|
3
|
+
|
4
|
+
jobs:
|
5
|
+
test:
|
6
|
+
runs-on: ubuntu-latest
|
7
|
+
|
8
|
+
steps:
|
9
|
+
- name: Checkout code
|
10
|
+
uses: actions/checkout@v2
|
11
|
+
|
12
|
+
- name: Setup Ruby
|
13
|
+
uses: ruby/setup-ruby@v1
|
14
|
+
with:
|
15
|
+
bundler-cache: true
|
16
|
+
|
17
|
+
- name: Run standard
|
18
|
+
run: bundle exec rake standard
|
19
|
+
|
20
|
+
- name: Run unit tests
|
21
|
+
run: bundle exec rake spec
|
22
|
+
|
23
|
+
- name: Cache firebase tools
|
24
|
+
uses: actions/cache@v2
|
25
|
+
id: cache-firebase
|
26
|
+
with:
|
27
|
+
path: tools/firebase
|
28
|
+
key: ${{ runner.os }}-firebase-tools
|
29
|
+
|
30
|
+
- name: Install firebase tools
|
31
|
+
if: steps.cache-firebase.outputs.cache-hit != 'true'
|
32
|
+
run: |
|
33
|
+
mkdir -p tools
|
34
|
+
curl -o tools/firebase -L https://firebase.tools/bin/linux/latest
|
35
|
+
chmod +rx tools/firebase
|
36
|
+
|
37
|
+
- name: Run integration tests
|
38
|
+
run: tools/firebase emulators:exec --only auth --project test-adminsdk-project 'bundle exec rake integration'
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
3.0.1
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2021 Cheddar Payments B.V.
|
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.
|
data/README.md
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
# Firebase Admin Ruby SDK
|
2
|
+
|
3
|
+
The Firebase Admin Ruby SDK enables access to Firebase services from privileged environments (such as servers or cloud)
|
4
|
+
in Ruby.
|
5
|
+
|
6
|
+
For more information, visit the
|
7
|
+
[Firebase Admin SDK setup guide](https://firebase.google.com/docs/admin/setup/).
|
8
|
+
|
9
|
+
This gem is currently in alpha and not recommended for production use (yet).
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
Add this line to your application's Gemfile:
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
gem 'firebase-admin-sdk'
|
17
|
+
```
|
18
|
+
|
19
|
+
And then execute:
|
20
|
+
|
21
|
+
$ bundle install
|
22
|
+
|
23
|
+
Or install it yourself as:
|
24
|
+
|
25
|
+
$ gem install firebase-admin-sdk
|
26
|
+
|
27
|
+
## Usage
|
28
|
+
|
29
|
+
### Application Default Credentials
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
gem 'firebase-admin-sdk'
|
33
|
+
|
34
|
+
app = Firebase::Admin::App.new
|
35
|
+
```
|
36
|
+
|
37
|
+
### Using a service account
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
gem 'firebase-admin-sdk'
|
41
|
+
|
42
|
+
creds = Firebase::Admin::Credentials.from_file('service_account.json')
|
43
|
+
app = Firebase::Admin::App.new(credentials: creds)
|
44
|
+
```
|
45
|
+
|
46
|
+
## Contributing
|
47
|
+
|
48
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/cheddar-me/firebase-admin-sdk.
|
49
|
+
|
50
|
+
## License
|
51
|
+
|
52
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "bundler/gem_tasks"
|
4
|
+
require "standard/rake"
|
5
|
+
require "rspec/core/rake_task"
|
6
|
+
|
7
|
+
RSpec::Core::RakeTask.new(:spec).pattern = "spec/unit/**{,/*/**}/*_spec.rb"
|
8
|
+
RSpec::Core::RakeTask.new(:integration).pattern = "spec/integration/**{,/*/**}/*_spec.rb"
|
9
|
+
|
10
|
+
task default: %i[standard spec]
|
data/bin/console
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "bundler/setup"
|
5
|
+
require "firebase-admin-sdk"
|
6
|
+
|
7
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
8
|
+
# with your gem easier. You can also use a different console, if you like.
|
9
|
+
|
10
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
11
|
+
# require "pry"
|
12
|
+
# Pry.start
|
13
|
+
|
14
|
+
require "irb"
|
15
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "lib/firebase/admin/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "firebase-admin-sdk"
|
7
|
+
spec.version = Firebase::Admin::VERSION
|
8
|
+
spec.authors = ["Tariq Zaid"]
|
9
|
+
spec.email = ["tariq@cheddar.me"]
|
10
|
+
|
11
|
+
spec.summary = "Firebase Admin SDK for Ruby"
|
12
|
+
spec.homepage = "https://github.com/cheddar-me/firebase-admin-sdk-ruby"
|
13
|
+
spec.license = "MIT"
|
14
|
+
spec.required_ruby_version = "> 2.7"
|
15
|
+
|
16
|
+
# Specify which files should be added to the gem when it is released.
|
17
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
18
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
19
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
|
20
|
+
end
|
21
|
+
spec.bindir = "bin"
|
22
|
+
spec.require_paths = ["lib"]
|
23
|
+
|
24
|
+
spec.add_runtime_dependency "googleauth", "~> 0.16.2"
|
25
|
+
spec.add_runtime_dependency "faraday", "< 2"
|
26
|
+
spec.add_runtime_dependency "faraday_middleware", "~> 1.0"
|
27
|
+
spec.add_runtime_dependency "jwt", ">= 1.5", "< 3.0"
|
28
|
+
|
29
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
30
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
31
|
+
spec.add_development_dependency "webmock", "~> 3.13"
|
32
|
+
spec.add_development_dependency "fakefs", "~> 1.3.2"
|
33
|
+
spec.add_development_dependency "climate_control"
|
34
|
+
spec.add_development_dependency "standard"
|
35
|
+
spec.add_development_dependency "activesupport"
|
36
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "firebase/admin/version"
|
4
|
+
require_relative "firebase/admin/error"
|
5
|
+
require_relative "firebase/admin/config"
|
6
|
+
require_relative "firebase/admin/gce"
|
7
|
+
require_relative "firebase/admin/credentials"
|
8
|
+
require_relative "firebase/admin/internal/http_client"
|
9
|
+
require_relative "firebase/admin/auth/error"
|
10
|
+
require_relative "firebase/admin/auth/utils"
|
11
|
+
require_relative "firebase/admin/auth/certificates_fetcher"
|
12
|
+
require_relative "firebase/admin/auth/token_verifier"
|
13
|
+
require_relative "firebase/admin/auth/user_info"
|
14
|
+
require_relative "firebase/admin/auth/user_record"
|
15
|
+
require_relative "firebase/admin/auth/user_manager"
|
16
|
+
require_relative "firebase/admin/auth/client"
|
17
|
+
require_relative "firebase/admin/app"
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "error"
|
4
|
+
require_relative "config"
|
5
|
+
require_relative "credentials"
|
6
|
+
require_relative "auth/client"
|
7
|
+
|
8
|
+
module Firebase
|
9
|
+
module Admin
|
10
|
+
# An App holds configuration and state common to all Firebase services that are exposed from the SDK.
|
11
|
+
class App
|
12
|
+
attr_reader :project_id, :service_account_id, :credentials
|
13
|
+
|
14
|
+
# Constructs a new App.
|
15
|
+
#
|
16
|
+
# @param [Credentials] credentials
|
17
|
+
# Credentials for authenticating with Firebase.
|
18
|
+
# @param [Config] config
|
19
|
+
# Firebase configuration options.
|
20
|
+
def initialize(credentials: nil, config: nil)
|
21
|
+
@config = config || Config.from_env
|
22
|
+
@credentials = credentials || Credentials.from_default
|
23
|
+
@service_account_id = @config.service_account_id
|
24
|
+
@project_id = @config.project_id || @credentials.project_id
|
25
|
+
end
|
26
|
+
|
27
|
+
# Gets the auth client for this App.
|
28
|
+
# @return [Firebase::Admin::Auth::Client]
|
29
|
+
def auth
|
30
|
+
@auth_client ||= Auth::Client.new(self)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require "time"
|
2
|
+
require "monitor"
|
3
|
+
|
4
|
+
module Firebase
|
5
|
+
module Admin
|
6
|
+
module Auth
|
7
|
+
# Fetches public key certificates used for signature verification.
|
8
|
+
class CertificatesFetcher
|
9
|
+
include Utils
|
10
|
+
|
11
|
+
# Constructs a new certificates fetcher.
|
12
|
+
#
|
13
|
+
# @param [String] url
|
14
|
+
# The certificates url to use when fetching public keys.
|
15
|
+
def initialize(url)
|
16
|
+
raise ArgumentError "url is invalid" unless validate_url(url)
|
17
|
+
@url = url
|
18
|
+
@certificates = {}
|
19
|
+
@certificates_expire_at = Time.now
|
20
|
+
@monitor = Monitor.new
|
21
|
+
@client = Firebase::Admin::Internal::HTTPClient.new
|
22
|
+
end
|
23
|
+
|
24
|
+
# Fetches certificates.
|
25
|
+
#
|
26
|
+
# @note
|
27
|
+
# Certificates are cached in memory and refreshed according to the cache-control header if present
|
28
|
+
# in the response.
|
29
|
+
#
|
30
|
+
# @return [Hash]
|
31
|
+
def fetch_certificates!
|
32
|
+
@monitor.synchronize do
|
33
|
+
return @certificates unless should_refresh?
|
34
|
+
keys, ttl = refresh
|
35
|
+
@certificates_expire_at = Time.now + ttl
|
36
|
+
@certificates = keys
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
# Refreshes and returns the certificates
|
43
|
+
def refresh
|
44
|
+
res = @client.get(@url)
|
45
|
+
match = res.headers["cache-control"]&.match(/max-age=([0-9]+)/)
|
46
|
+
ttl = match&.captures&.first&.to_i || 0
|
47
|
+
certificates = res.body
|
48
|
+
[certificates, ttl]
|
49
|
+
rescue => e
|
50
|
+
raise CertificateRequestError, e.message
|
51
|
+
end
|
52
|
+
|
53
|
+
# Checks if keys need to be refreshed.
|
54
|
+
#
|
55
|
+
# @return [Boolean]
|
56
|
+
def should_refresh?
|
57
|
+
@certificates.nil? || @certificates.empty? || @certificates_expire_at < Time.now
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
module Firebase
|
2
|
+
module Admin
|
3
|
+
module Auth
|
4
|
+
# A client for communicating with the Firebase Auth service.
|
5
|
+
class Client
|
6
|
+
# Constructs a new client
|
7
|
+
#
|
8
|
+
# @param [Firebase::Admin::App] app The app the client is configured with.
|
9
|
+
def initialize(app)
|
10
|
+
@project_id = app.project_id
|
11
|
+
@service_account_id = app.service_account_id
|
12
|
+
@credentials = app.credentials
|
13
|
+
|
14
|
+
@emulated = Utils.is_emulated?
|
15
|
+
v1_url_override = Utils.get_emulator_v1_url
|
16
|
+
@credentials = EmulatorCredentials.new if @emulated
|
17
|
+
|
18
|
+
@id_token_verifier = IDTokenVerifier.new(app)
|
19
|
+
@user_manager = UserManager.new(@project_id, @credentials, v1_url_override)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Checks if the auth client is configured to use the Firebase Auth Emulator.
|
23
|
+
# @ return [Boolean] true if configured for the auth emulator, false otherwise.
|
24
|
+
def emulated?
|
25
|
+
@emulated
|
26
|
+
end
|
27
|
+
|
28
|
+
# Creates a new user account with the specified properties.
|
29
|
+
#
|
30
|
+
# @param [String, nil] uid The id to assign to the newly created user.
|
31
|
+
# @param [String, nil] display_name The user’s display name.
|
32
|
+
# @param [String, nil] email The user’s primary email.
|
33
|
+
# @param [Boolean, nil] email_verified A boolean indicating whether or not the user’s primary email is verified.
|
34
|
+
# @param [String, nil] phone_number The user’s primary phone number.
|
35
|
+
# @param [String, nil] photo_url The user’s photo URL.
|
36
|
+
# @param [String, nil] password The user’s raw, unhashed password.
|
37
|
+
# @param [Boolean, nil] disabled A boolean indicating whether or not the user account is disabled.
|
38
|
+
#
|
39
|
+
# @raise [CreateUserError] if a user cannot be created.
|
40
|
+
#
|
41
|
+
# @return [UserRecord]
|
42
|
+
def create_user(uid: nil, display_name: nil, email: nil, email_verified: nil, phone_number: nil, photo_url: nil, password: nil, disabled: nil)
|
43
|
+
@user_manager.create_user(
|
44
|
+
uid: uid,
|
45
|
+
display_name: display_name,
|
46
|
+
email: email,
|
47
|
+
email_verified: email_verified,
|
48
|
+
phone_number: phone_number,
|
49
|
+
photo_url: photo_url,
|
50
|
+
password: password,
|
51
|
+
disabled: disabled
|
52
|
+
)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Gets the user corresponding to the specified user id.
|
56
|
+
#
|
57
|
+
# @param [String] uid
|
58
|
+
# The id of the user.
|
59
|
+
#
|
60
|
+
# @return [UserRecord]
|
61
|
+
def get_user(uid)
|
62
|
+
@user_manager.get_user_by(uid: uid)
|
63
|
+
end
|
64
|
+
|
65
|
+
# Gets the user corresponding to the specified email address.
|
66
|
+
#
|
67
|
+
# @param [String] email
|
68
|
+
# An email address.
|
69
|
+
#
|
70
|
+
# @return [UserRecord]
|
71
|
+
def get_user_by_email(email)
|
72
|
+
@user_manager.get_user_by(email: email)
|
73
|
+
end
|
74
|
+
|
75
|
+
# Gets the user corresponding to the specified phone number.
|
76
|
+
#
|
77
|
+
# @param [String] phone_number A phone number, in international E.164 format.
|
78
|
+
def get_user_by_phone_number(phone_number)
|
79
|
+
@user_manager.get_user_by(phone_number: phone_number)
|
80
|
+
end
|
81
|
+
|
82
|
+
# Deletes the user corresponding to the specified user id.
|
83
|
+
#
|
84
|
+
# @param [String] uid
|
85
|
+
# The id of the user.
|
86
|
+
def delete_user(uid)
|
87
|
+
@user_manager.delete_user(uid)
|
88
|
+
end
|
89
|
+
|
90
|
+
# Verifies the signature and data for the provided JWT.
|
91
|
+
#
|
92
|
+
# Accepts a signed token string, verifies that it is current, was issued to this project, and that
|
93
|
+
# it was correctly signed by Google.
|
94
|
+
#
|
95
|
+
# @param [String] token A string of the encoded JWT.
|
96
|
+
# @param [Boolean] check_revoked (false) If true, checks whether the token has been revoked.
|
97
|
+
# @return [Hash] A hash of key-value pairs parsed from the decoded JWT.
|
98
|
+
def verify_id_token(token, check_revoked = false)
|
99
|
+
verified_claims = @id_token_verifier.verify(token, is_emulator: emulated?)
|
100
|
+
revoked = check_revoked && !id_token_revoked?(verified_claims)
|
101
|
+
verified_claims unless revoked
|
102
|
+
end
|
103
|
+
|
104
|
+
private
|
105
|
+
|
106
|
+
# Checks if an ID token has been revoked.
|
107
|
+
#
|
108
|
+
# @param [Hash] claims The verified claims needed to perform the check.
|
109
|
+
# @return [Boolean] true if the id token has been revoked, false otherwise.
|
110
|
+
def id_token_revoked?(claims)
|
111
|
+
raise NotImplementedError
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|