Skip to content

Commit 4bbd710

Browse files
committed
Prevent Opening JSON Key Path unless It's an IO Object
1 parent ec489fa commit 4bbd710

File tree

2 files changed

+58
-7
lines changed

2 files changed

+58
-7
lines changed

lib/fcm.rb

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
require "googleauth"
55

66
class FCM
7+
class InvalidCredentialError < StandardError; end
8+
79
BASE_URI = "https://fcm.googleapis.com"
810
BASE_URI_V1 = "https://fcm.googleapis.com/v1/projects/"
911
DEFAULT_TIMEOUT = 30
@@ -291,11 +293,23 @@ def jwt_token
291293
token["access_token"]
292294
end
293295

296+
def credentials_error_msg(json_key_path)
297+
param_klass = if @json_key_path.nil?
298+
'nil'
299+
else
300+
"a #{@json_key_path.class.name}"
301+
end
302+
303+
"credentials must be an IO-like object or a path. You passed #{param_klass}"
304+
end
305+
294306
def json_key
295307
@json_key ||= if @json_key_path.respond_to?(:read)
296-
@json_key_path
297-
else
298-
File.open(@json_key_path)
299-
end
308+
@json_key_path
309+
elsif (@json_key_path.is_a?(String) || @json_key_path.respond_to?(:open)) && File.file?(@json_key_path)
310+
File.open(@json_key_path)
311+
else
312+
raise InvalidCredentialError, credentials_error_msg(@json_key_path)
313+
end
300314
end
301315
end

spec/fcm_spec.rb

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,31 @@
1313
}
1414
end
1515

16+
let(:json_credentials) do
17+
{
18+
"type": 'service_account',
19+
"project_id": 'example',
20+
"private_key_id": 'c09c4593eee53707ca9f4208fbd6fe72b29fc7ab',
21+
"private_key": OpenSSL::PKey::RSA.new(2048),
22+
"client_email": '83315528762cf7e0-7bbcc3aad87e0083391bc7f234d487c8@developer.gserviceaccount.com',
23+
"client_id": 'acedc3c0a63b3562376386f0-f3b94aafbecd0e7d60563bf7bb8bb47f.apps.googleusercontent.com',
24+
"auth_uri": 'https://accounts.google.com/o/oauth2/auth',
25+
"token_uri": 'https://oauth2.googleapis.com/token',
26+
"auth_provider_x509_cert_url": 'https://www.googleapis.com/oauth2/v1/certs',
27+
"client_x509_cert_url": 'https://www.googleapis.com/robot/v1/metadata/x509/fd6b61037dd2bb8585527679-7bbcc3aad87e0083391bc7f234d487c8%40developer.gserviceaccount.com',
28+
"universe_domain": 'googleapis.com'
29+
}.to_json
30+
end
31+
1632
before do
1733
allow(client).to receive(:json_key)
1834

1935
# Mock the Google::Auth::ServiceAccountCredentials
20-
allow(Google::Auth::ServiceAccountCredentials).to receive(:make_creds).
21-
and_return(double(fetch_access_token!: { 'access_token' => mock_token }))
36+
allow(Google::Auth::ServiceAccountCredentials).to receive(:make_creds)
37+
.and_return(double(fetch_access_token!: { 'access_token' => mock_token }))
2238
end
2339

24-
it "should initialize" do
40+
it 'should initialize' do
2541
expect { client }.not_to raise_error
2642
end
2743

@@ -35,6 +51,27 @@
3551
fcm = FCM.new(StringIO.new("hey"))
3652
expect(fcm.__send__(:json_key).class).to eq(StringIO)
3753
end
54+
55+
it "raises an error when passed a non-existent credentials file path" do
56+
fcm = FCM.new('spec/fake_credentials.json', '', {})
57+
expect { fcm.__send__(:json_key).class }.to raise_error(FCM::InvalidCredentialError)
58+
end
59+
60+
it "raises an error when passed a string of a file that does not exist" do
61+
fcm = FCM.new("fake_credentials.json", '', {})
62+
expect { fcm.__send__(:json_key).class }.to raise_error(FCM::InvalidCredentialError)
63+
end
64+
65+
it 'raises an error when passed a non IO-like object' do
66+
fcm_with_non_io_objects = [
67+
fcm_with_nil_creds = FCM.new(nil, '', {}),
68+
fcm_with_hash_creds = FCM.new({}, '', {}),
69+
fcm_with_json = FCM.new(json_credentials, '', {})
70+
]
71+
fcm_with_non_io_objects.each do |fcm_with_non_io_object|
72+
expect { fcm_with_non_io_object.__send__(:json_key).class }.to raise_error(FCM::InvalidCredentialError)
73+
end
74+
end
3875
end
3976

4077
describe "#send_v1 or #send_notification_v1" do

0 commit comments

Comments
 (0)