fcm 2.0.1 → 2.0.2

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.
Files changed (6) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -0
  3. data/fcm.gemspec +1 -1
  4. data/lib/fcm.rb +23 -1
  5. data/spec/fcm_spec.rb +85 -6
  6. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 49ddf83437f7c8df20298ffa3f334473e0032032e7f8e88d5021185f448f4606
4
- data.tar.gz: fc79d5369ee5b22b854f49889a69de1612c4c7e2a37ec17683b8a428a0326549
3
+ metadata.gz: 2802aecc49a82a5fedf980c9cdf38c3a429f0ebfa358efef7b4fbb0097ac8295
4
+ data.tar.gz: a124f4d7b09930550d58993807e4a6c5944279c47e16f51b90c18fab7b5f54a5
5
5
  SHA512:
6
- metadata.gz: 9b37b2f37b95cc0816547c973872c8c17c3905602fe8162bff2e25e3a52c7997f7dae11c472a399c8d947e9bfdde668b3223f793b912d274f4bcd204ba827325
7
- data.tar.gz: 06f380df29d1bcc8683df25f45c099c8615609081308de79c0966c52ea9f4f887155ee77591b65ad479260d736b5e2b98f682e4616bce19cfc52c937995015ad
6
+ metadata.gz: aacdfb6460c7ce30f990119219ddaa6ef5fc3ad33efe0f8bed5095df5f4435ec93aeac604f91031a9e9db58a4b19e3499fddbc9bc230e6c6b51c20557a283015
7
+ data.tar.gz: 684c306d874a14909f7f3dd3f95355aba895a9680e2eede3fb6b9b5b568636be09e639d3cfdaf17278cab9d157954b6b917bff6f974762a56ed003641a8be8f7
data/README.md CHANGED
@@ -274,6 +274,9 @@ The guide to set up an iOS app to get notifications is here: [Setting up a FCM C
274
274
 
275
275
  ## ChangeLog
276
276
 
277
+ ### 2.0.2
278
+ - Ensure JSON key path is an actual file or IO object before opening [#134](https://github.com/spacialdb/fcm/pull/134)
279
+
277
280
  ### 2.0.1
278
281
  - Add `http_options` to `initialize` method and whitelist `timeout` option
279
282
 
data/fcm.gemspec CHANGED
@@ -3,7 +3,7 @@ $:.push File.expand_path("../lib", __FILE__)
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "fcm"
6
- s.version = "2.0.1"
6
+ s.version = "2.0.2"
7
7
  s.platform = Gem::Platform::RUBY
8
8
  s.authors = ["Kashif Rasul", "Shoaib Burq"]
9
9
  s.email = ["kashif@decision-labs.com", "shoaib@decision-labs.com"]
data/lib/fcm.rb CHANGED
@@ -4,6 +4,8 @@ require "json"
4
4
  require "googleauth"
5
5
 
6
6
  class FCM
7
+ class InvalidCredentialError < StandardError; end
8
+
7
9
  BASE_URI = "https://fcm.googleapis.com"
8
10
  BASE_URI_V1 = "https://fcm.googleapis.com/v1/projects/"
9
11
  DEFAULT_TIMEOUT = 30
@@ -291,11 +293,31 @@ class FCM
291
293
  token["access_token"]
292
294
  end
293
295
 
296
+ def raise_credentials_error(param)
297
+ error_msg = 'credentials must be an IO-like ' \
298
+ 'object or path. You passed'
299
+
300
+ param_klass = param.nil? ? 'nil' : "a #{param.class.name}"
301
+ error_msg += " #{param_klass}."
302
+ raise InvalidCredentialError, error_msg
303
+ end
304
+
305
+ def valid_json_key_path?(path)
306
+ valid_io_object = path.respond_to?(:open)
307
+ return true if valid_io_object && File.file?(path)
308
+
309
+ max_path_len = 1024
310
+ valid_path = path.is_a?(String) && path.length <= max_path_len
311
+ valid_path && File.file?(path)
312
+ end
313
+
294
314
  def json_key
295
315
  @json_key ||= if @json_key_path.respond_to?(:read)
296
316
  @json_key_path
297
- else
317
+ elsif valid_json_key_path?(@json_key_path)
298
318
  File.open(@json_key_path)
319
+ else
320
+ raise_credentials_error(@json_key_path)
299
321
  end
300
322
  end
301
323
  end
data/spec/fcm_spec.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require "spec_helper"
2
+ require 'tempfile'
2
3
 
3
4
  describe FCM do
4
5
  let(:project_name) { 'test-project' }
@@ -13,27 +14,105 @@ describe FCM do
13
14
  }
14
15
  end
15
16
 
17
+ let(:client_email) do
18
+ '83315528762cf7e0-7bbcc3aad87e0083391bc7f234d487' \
19
+ 'c8@developer.gserviceaccount.com'
20
+ end
21
+
22
+ let(:client_x509_cert_url) do
23
+ 'https://www.googleapis.com/robot/v1/metadata/x509/' \
24
+ 'fd6b61037dd2bb8585527679" + "-7bbcc3aad87e0083391b' \
25
+ 'c7f234d487c8%40developer.gserviceaccount.com'
26
+ end
27
+
28
+ let(:large_file_name) do
29
+ Array.new(1021) { 'a' }.join('') + '.txt'
30
+ end
31
+
32
+ let(:creds_error) do
33
+ FCM::InvalidCredentialError
34
+ end
35
+
36
+ let(:json_credentials) do
37
+ {
38
+ "type": 'service_account',
39
+ "project_id": 'example',
40
+ "private_key_id": 'c09c4593eee53707ca9f4208fbd6fe72b29fc7ab',
41
+ "private_key": OpenSSL::PKey::RSA.new(2048).to_s,
42
+ "client_email": client_email,
43
+ "client_id": 'acedc3c0a63b3562376386f0.apps.googleusercontent.com',
44
+ "auth_uri": 'https://accounts.google.com/o/oauth2/auth',
45
+ "token_uri": 'https://oauth2.googleapis.com/token',
46
+ "auth_provider_x509_cert_url": 'https://www.googleapis.com/oauth2/v1/certs',
47
+ "client_x509_cert_url": client_x509_cert_url,
48
+ "universe_domain": 'googleapis.com'
49
+ }.to_json
50
+ end
51
+
16
52
  before do
17
53
  allow(client).to receive(:json_key)
18
54
 
19
55
  # 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 }))
56
+ allow(Google::Auth::ServiceAccountCredentials).to receive(:make_creds)
57
+ .and_return(double(fetch_access_token!: { 'access_token' => mock_token }))
22
58
  end
23
59
 
24
- it "should initialize" do
60
+ it 'should initialize' do
25
61
  expect { client }.not_to raise_error
26
62
  end
27
63
 
28
64
  describe "credentials path" do
29
- it "can be a path to a file" do
65
+ it 'can be a path to a file' do
30
66
  fcm = FCM.new("README.md")
31
67
  expect(fcm.__send__(:json_key).class).to eq(File)
32
68
  end
33
69
 
34
- it "can be an IO object" do
35
- fcm = FCM.new(StringIO.new("hey"))
70
+ it 'raises an error when passed a large path' do
71
+ expect do
72
+ FCM.new(large_file_name).__send__(:json_key)
73
+ end.to raise_error(creds_error)
74
+ end
75
+
76
+ it 'can be an IO object' do
77
+ fcm = FCM.new(StringIO.new('hey'))
36
78
  expect(fcm.__send__(:json_key).class).to eq(StringIO)
79
+
80
+ temp_file = Tempfile.new('hello_world.json')
81
+ temp_file.write(json_credentials)
82
+ fcm_with_temp_file = FCM.new(temp_file)
83
+
84
+ expect do
85
+ fcm_with_temp_file
86
+ end.not_to raise_error
87
+ temp_file.close
88
+ temp_file.unlink
89
+ end
90
+
91
+ it 'raises an error when passed a non IO-like object' do
92
+ expect do
93
+ FCM.new(nil, '', {}).__send__(:json_key)
94
+ end.to raise_error(creds_error, 'credentials must be' \
95
+ ' an IO-like object or path. You passed nil.')
96
+
97
+ expect do
98
+ FCM.new(json_credentials, '', {}).__send__(:json_key)
99
+ end.to raise_error(creds_error, 'credentials must be' \
100
+ ' an IO-like object or path. You passed a String.')
101
+
102
+ expect do
103
+ FCM.new({}, '', {}).__send__(:json_key)
104
+ end.to raise_error(creds_error, 'credentials must be' \
105
+ ' an IO-like object or path. You passed a Hash.')
106
+ end
107
+
108
+ it 'raises an error when passed a non-existent credentials file path' do
109
+ fcm = FCM.new('spec/fake_credentials.json', '', {})
110
+ expect { fcm.__send__(:json_key) }.to raise_error(creds_error)
111
+ end
112
+
113
+ it 'raises an error when passed a string of a file that does not exist' do
114
+ fcm = FCM.new('example.txt', '', {})
115
+ expect { fcm.__send__(:json_key) }.to raise_error(creds_error)
37
116
  end
38
117
  end
39
118
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fcm
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 2.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kashif Rasul
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2024-10-21 00:00:00.000000000 Z
12
+ date: 2026-05-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: faraday