Skip to content

Commit d18165d

Browse files
author
Colin Harris
committed
Expose service_account_email and service_account_provide_key as config options
1 parent da8470f commit d18165d

7 files changed

Lines changed: 73 additions & 53 deletions

File tree

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
firebase-admin.iml
22
out
33
coverage
4+
vendor/bundle
5+
.idea
6+
.run

Gemfile.lock

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
PATH
22
remote: .
33
specs:
4-
firebase-admin (0.1.6)
4+
firebase-admin (0.2.0)
55
addressable (~> 2.7)
66
faraday (~> 1.3)
77
faraday_middleware (~> 1.0)
@@ -85,6 +85,7 @@ GEM
8585
hashdiff (>= 0.4.0, < 2.0.0)
8686

8787
PLATFORMS
88+
arm64-darwin-21
8889
x86_64-darwin-20
8990

9091
DEPENDENCIES
@@ -95,4 +96,4 @@ DEPENDENCIES
9596
webmock (~> 3.11)
9697

9798
BUNDLED WITH
98-
2.2.22
99+
2.3.17

lib/firebase-admin/client/accounts.rb

Lines changed: 11 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,16 @@ def sign_in_for_uid(uid)
117117
# @example
118118
# FirebaseAdmin.create_custom_token('...')
119119
def create_custom_token(uid)
120+
if service_account_email.nil? || service_account_email == ''
121+
raise InvalidCredentials,
122+
"No client email provided via options, 'GOOGLE_APPLICATION_CREDENTIALS' or 'GOOGLE_CLIENT_EMAIL'"
123+
end
124+
125+
if service_account_private_key.nil? || service_account_private_key == ''
126+
raise InvalidCredentials,
127+
"No private key provided via options, 'GOOGLE_APPLICATION_CREDENTIALS' or 'GOOGLE_PRIVATE_KEY'"
128+
end
129+
120130
now_seconds = Time.now.to_i
121131
payload = {
122132
iss: service_account_email,
@@ -126,7 +136,7 @@ def create_custom_token(uid)
126136
exp: now_seconds + (60 * 60), # Maximum expiration time is one hour
127137
uid: uid
128138
}
129-
JWT.encode(payload, private_key, 'RS256')
139+
JWT.encode(payload, OpenSSL::PKey::RSA.new(unescape(service_account_private_key)), 'RS256')
130140
end
131141

132142
# Get user by email/phone/uid
@@ -163,42 +173,6 @@ def unescape(str)
163173
str = str[1..-2] if str.start_with?('"') && str.end_with?('"')
164174
str
165175
end
166-
167-
def service_account_email
168-
email = default_credentials.fetch('client_email') { ENV['GOOGLE_CLIENT_EMAIL'] }
169-
if email.nil? || email == ''
170-
raise InvalidCredentials,
171-
"No client email provided via 'GOOGLE_APPLICATION_CREDENTIALS' or 'GOOGLE_CLIENT_EMAIL'"
172-
end
173-
174-
email
175-
end
176-
177-
def private_key
178-
key = default_credentials.fetch('private_key') { unescape(ENV['GOOGLE_PRIVATE_KEY']) }
179-
if key.nil? || key == ''
180-
raise InvalidCredentials,
181-
"No private key provided via 'GOOGLE_APPLICATION_CREDENTIALS' or 'GOOGLE_PRIVATE_KEY'"
182-
end
183-
184-
OpenSSL::PKey::RSA.new(key)
185-
end
186-
187-
def default_credentials
188-
@default_credentials ||= read_default_credentials
189-
end
190-
191-
def read_default_credentials
192-
credentials_path = ENV['GOOGLE_APPLICATION_CREDENTIALS']
193-
if credentials_path && File.exist?(credentials_path)
194-
JSON.parse(File.read(credentials_path))
195-
else
196-
{}
197-
end
198-
rescue StandardError => e
199-
raise InvalidCredentials,
200-
"Failed reading credentials from '#{ENV['GOOGLE_APPLICATION_CREDENTIALS']}'. Error: #{e.message}"
201-
end
202176
end
203177
end
204178
end

lib/firebase-admin/configuration.rb

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ module Configuration
1313
user_agent
1414
project_id
1515
loud_logger
16+
service_account_email
17+
service_account_private_key
1618
].freeze
1719

1820
# By default, don't set a user access token
@@ -47,6 +49,18 @@ module Configuration
4749
# @private
4850
attr_accessor(*VALID_OPTIONS_KEYS)
4951

52+
def service_account_email
53+
@service_account_email ||= service_account_credentials.fetch('client_email') do
54+
ENV['GOOGLE_CLIENT_EMAIL']
55+
end
56+
end
57+
58+
def service_account_private_key
59+
@service_account_private_key ||= service_account_credentials.fetch('private_key') do
60+
ENV['GOOGLE_PRIVATE_KEY']
61+
end
62+
end
63+
5064
# When this module is extended, set all configuration options to their default values
5165
def self.extended(base)
5266
base.reset
@@ -64,6 +78,23 @@ def options
6478
end
6579
end
6680

81+
def service_account_credentials
82+
return {} unless ENV['GOOGLE_APPLICATION_CREDENTIALS']
83+
84+
@service_account_credentials ||= read_service_account_credentials(ENV['GOOGLE_APPLICATION_CREDENTIALS'])
85+
end
86+
87+
def read_service_account_credentials(credentials_path)
88+
if credentials_path && File.exist?(credentials_path)
89+
JSON.parse(File.read(credentials_path))
90+
else
91+
{}
92+
end
93+
rescue StandardError => e
94+
raise InvalidCredentials,
95+
"Failed reading credentials from '#{ENV['GOOGLE_APPLICATION_CREDENTIALS']}'. Error: #{e.message}"
96+
end
97+
6798
# Reset all configuration options to defaults
6899
def reset
69100
self.access_token = DEFAULT_ACCESS_TOKEN
@@ -73,6 +104,9 @@ def reset
73104
self.user_agent = DEFAULT_USER_AGENT
74105
self.project_id = DEFAULT_PROJECT_ID
75106
self.loud_logger = DEFAULT_LOUD_LOGGER
107+
@service_account_credentials = nil
108+
self.service_account_email = nil
109+
self.service_account_private_key = nil
76110
end
77111
end
78112
end

lib/firebase-admin/version.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
module FirebaseAdmin
2-
VERSION = '0.1.6'.freeze unless defined?(::FirebaseAdmin::VERSION)
2+
VERSION = '0.2.0'.freeze unless defined?(::FirebaseAdmin::VERSION)
33
end

spec/firebase-admin/api_spec.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@
3434
endpoint: 'http://tumblr.com/',
3535
user_agent: 'Custom User Agent',
3636
project_id: 'test-project',
37-
loud_logger: true
37+
loud_logger: true,
38+
service_account_email: 'example@gmail.com',
39+
service_account_private_key: '===private key==='
3840
}
3941
end
4042

spec/firebase-admin/client/accounts_spec.rb

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
require File.expand_path('../../spec_helper', __dir__)
22

33
describe FirebaseAdmin::Client do
4-
before do
5-
@client = FirebaseAdmin::Client.new(project_id: 'test-project')
6-
end
4+
let(:client) { FirebaseAdmin::Client.new(project_id: 'test-project') }
75

86
describe '.create_account' do
97
before do
@@ -12,7 +10,7 @@
1210
end
1311

1412
it 'should get the correct resource' do
15-
@client.create_account(email: 'john@smith.com', password: 'supersecret')
13+
client.create_account(email: 'john@smith.com', password: 'supersecret')
1614
expect(
1715
a_post('v1/projects/test-project/accounts')
1816
.with(body: { email: 'john@smith.com', password: 'supersecret' }.to_json)
@@ -28,7 +26,7 @@
2826
end
2927

3028
it 'should post to the update endpoint' do
31-
@client.update_account(email: 'john@smith.com', password: 'supersecret')
29+
client.update_account(email: 'john@smith.com', password: 'supersecret')
3230
expect(
3331
a_post('v1/projects/test-project/accounts:update')
3432
.with(body: { email: 'john@smith.com', password: 'supersecret' }.to_json)
@@ -41,10 +39,11 @@
4139
context 'when credentials are set via GOOGLE_APPLICATION_CREDENTIALS' do
4240
before do
4341
ENV['GOOGLE_APPLICATION_CREDENTIALS'] = fixture('google_credentials.json').path
42+
FirebaseAdmin.reset
4443
end
4544

4645
it 'returns a valid JWT token' do
47-
token = @client.create_custom_token('user-123')
46+
token = client.create_custom_token('user-123')
4847
token_data, _alg = JWT.decode(token, nil, false)
4948
expect(token_data['uid']).to eq('user-123')
5049
end
@@ -53,10 +52,13 @@
5352
context 'when GOOGLE_APPLICATION_CREDENTIALS points to an invalid file' do
5453
before do
5554
ENV['GOOGLE_APPLICATION_CREDENTIALS'] = fixture('google_credentials_invalid.json').path
55+
FirebaseAdmin.reset
5656
end
5757

5858
it 'raises an error' do
59-
expect { @client.create_custom_token('user-123') }.to raise_error FirebaseAdmin::InvalidCredentials
59+
expect {
60+
client.create_custom_token('user-123')
61+
}.to raise_error FirebaseAdmin::InvalidCredentials
6062
end
6163
end
6264

@@ -68,10 +70,11 @@
6870
ENV['GOOGLE_APPLICATION_CREDENTIALS'] = nil
6971
ENV['GOOGLE_CLIENT_EMAIL'] = email
7072
ENV['GOOGLE_PRIVATE_KEY'] = private_key
73+
FirebaseAdmin.reset
7174
end
7275

7376
it 'returns a valid JWT token' do
74-
token = @client.create_custom_token('user-123')
77+
token = client.create_custom_token('user-123')
7578
token_data, _alg = JWT.decode(token, nil, false)
7679
expect(token_data['uid']).to eq('user-123')
7780
end
@@ -82,19 +85,22 @@
8285
ENV['GOOGLE_APPLICATION_CREDENTIALS'] = nil
8386
ENV['GOOGLE_CLIENT_EMAIL'] = nil
8487
ENV['GOOGLE_PRIVATE_KEY'] = nil
88+
FirebaseAdmin.reset
8589
end
8690

8791
it 'raises an error' do
88-
expect { @client.create_custom_token('user-123') }.to raise_error FirebaseAdmin::InvalidCredentials
92+
expect {
93+
client.create_custom_token('user-123')
94+
}.to raise_error FirebaseAdmin::InvalidCredentials
8995
end
9096
end
9197
end
9298

9399
describe '.sign_in_for_uid' do
94100
it 'should post to the update endpoint' do
95-
expect(@client).to receive(:create_custom_token).with('user-123').and_return('token')
96-
expect(@client).to receive(:sign_in_with_custom_token).with('token').and_return('result')
97-
result = @client.sign_in_for_uid('user-123')
101+
expect(client).to receive(:create_custom_token).with('user-123').and_return('token')
102+
expect(client).to receive(:sign_in_with_custom_token).with('token').and_return('result')
103+
result = client.sign_in_for_uid('user-123')
98104
expect(result).to eq('result')
99105
end
100106
end

0 commit comments

Comments
 (0)