firefighter 0.1.0 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d80549aec3125f214030d98787d105c9c650c2ad
4
- data.tar.gz: 6b36a29cf7599efa0ef62e9fbf2e88d0e6dbc78f
3
+ metadata.gz: d70d5902e9171a3dc50294cd10eb0f65fb855ad2
4
+ data.tar.gz: 945163b9cbb335a032c3ade37e37550f19c09ace
5
5
  SHA512:
6
- metadata.gz: 6d5edc84be85b2052aa4aacfa1dbad325726716df41a6292071a46d2fbd015a03124d59b7de0c7e71bf50d77f18aef9e83d7ca2ac7919005fa447fc379973e24
7
- data.tar.gz: 2638acf2cd12b408f77d52c449ab59b9f4724689f4f953476af09e66029d1cde7aaeb2d35c49afe5204cecf24b5407ca42a4035d3c5d7cf19eed94ac0c0439aa
6
+ metadata.gz: '08c6c1f4ffa81d6df98c7b70d2f8c053fe17ce1fc3fd835656e2e8a2ae50a6c9bc6915fefd9507e6867b25ef708043d16791e87a5b28539c47650f30b35ccb41'
7
+ data.tar.gz: 5200e36e5eb5f86be345824414b2670ed9e1695151f5a44e60933b67230dc362858bbf4f15b8382ccfab75a349ddf389da6c79af1cf7b0be61aacd4c4d4aa73b
@@ -0,0 +1,32 @@
1
+ version: 2
2
+ jobs:
3
+ build:
4
+ working_directory: ~/repo
5
+
6
+ docker:
7
+ - image: circleci/ruby:2.4
8
+
9
+ steps:
10
+ - checkout
11
+
12
+ # Download and cache dependencies
13
+ - restore_cache:
14
+ keys:
15
+ - v1-dependencies-{{ checksum "Gemfile.lock" }}
16
+ # fallback to using the latest cache if no exact match is found
17
+ - v1-dependencies-
18
+
19
+ - run:
20
+ name: install dependencies
21
+ command: |
22
+ bundle install --jobs=4 --retry=3 --path vendor/bundle
23
+
24
+ - save_cache:
25
+ paths:
26
+ - ./vendor/bundle
27
+ key: v1-dependencies-{{ checksum "Gemfile.lock" }}
28
+
29
+ - run:
30
+ name: Run tests
31
+ command: |
32
+ bundle exec rake
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- firefighter (0.1.0)
4
+ firefighter (0.2.0)
5
5
  http (~> 3.0)
6
6
  jwt (~> 2.0)
7
7
 
@@ -26,21 +26,21 @@ GEM
26
26
  http-form_data (2.1.1)
27
27
  http_parser.rb (0.6.0)
28
28
  jwt (2.1.0)
29
- public_suffix (3.0.2)
29
+ public_suffix (3.0.3)
30
30
  rake (10.5.0)
31
- rspec (3.7.0)
32
- rspec-core (~> 3.7.0)
33
- rspec-expectations (~> 3.7.0)
34
- rspec-mocks (~> 3.7.0)
35
- rspec-core (3.7.1)
36
- rspec-support (~> 3.7.0)
37
- rspec-expectations (3.7.0)
31
+ rspec (3.8.0)
32
+ rspec-core (~> 3.8.0)
33
+ rspec-expectations (~> 3.8.0)
34
+ rspec-mocks (~> 3.8.0)
35
+ rspec-core (3.8.0)
36
+ rspec-support (~> 3.8.0)
37
+ rspec-expectations (3.8.2)
38
38
  diff-lcs (>= 1.2.0, < 2.0)
39
- rspec-support (~> 3.7.0)
40
- rspec-mocks (3.7.0)
39
+ rspec-support (~> 3.8.0)
40
+ rspec-mocks (3.8.0)
41
41
  diff-lcs (>= 1.2.0, < 2.0)
42
- rspec-support (~> 3.7.0)
43
- rspec-support (3.7.1)
42
+ rspec-support (~> 3.8.0)
43
+ rspec-support (3.8.0)
44
44
  safe_yaml (1.0.4)
45
45
  timecop (0.9.1)
46
46
  unf (0.1.4)
@@ -34,7 +34,7 @@ Gem::Specification.new do |spec|
34
34
  spec.add_development_dependency "bundler", "~> 1.16"
35
35
  spec.add_development_dependency "rake", "~> 10.0"
36
36
  spec.add_development_dependency "rspec", "~> 3.0"
37
- spec.add_development_dependency "timecop", "~> 0.9"
38
37
  spec.add_development_dependency "vcr", "~> 4.0"
39
38
  spec.add_development_dependency "webmock", "~> 3.4"
39
+ spec.add_development_dependency "timecop", "~> 0.9"
40
40
  end
@@ -1,3 +1,5 @@
1
1
  require "firefighter/version"
2
+ require "firefighter/web"
3
+ require "firefighter/identitytoolkit"
2
4
  require "firefighter/realtime_database"
3
5
  require "firefighter/token_generator"
@@ -0,0 +1,85 @@
1
+ module Firefighter
2
+ class Identitytoolkit
3
+ include Web
4
+
5
+ def self.from_env
6
+ config = {
7
+ api_key: ENV['FIREBASE_WEB_API_KEY'],
8
+ service_account_email: ENV['FIREBASE_SERVICE_ACCOUNT_EMAIL'],
9
+ service_account_private_key_data: ENV['FIREBASE_PRIVATE_KEY_DATA'],
10
+ }
11
+ new(config)
12
+ end
13
+
14
+ def initialize(api_key:, service_account_email:, service_account_private_key_data:, token_generator: TokenGenerator.from_env)
15
+ @api_key = api_key
16
+ @service_account_email = service_account_email
17
+ @service_account_private_key_data = service_account_private_key_data
18
+ @token_generator = token_generator
19
+ end
20
+
21
+ def signup(email, password)
22
+ url = endpoint('signupNewUser')
23
+ data = {
24
+ email: email,
25
+ password: password,
26
+ returnSecureToken: true
27
+ }
28
+ call(:post, url, data)
29
+ end
30
+
31
+ def account_info(id_token, local_ids: [], emails: [])
32
+ url = endpoint('getAccountInfo')
33
+ data = {
34
+ idToken: id_token,
35
+ localId: local_ids,
36
+ email: emails,
37
+ }
38
+ call(:post, url, data)
39
+ end
40
+
41
+ def download_accounts
42
+ url = endpoint('downloadAccount')
43
+
44
+ headers = {Authorization: "Bearer #{fetch_access_token}" }
45
+
46
+ users = []
47
+ paginate(url, headers: headers) { |data| users << data['users'] }
48
+ users.flatten.compact
49
+ end
50
+
51
+ def fetch_access_token
52
+ url = 'https://accounts.google.com/o/oauth2/token'
53
+ data = {
54
+ assertion: @token_generator.create_access_token,
55
+ grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer'
56
+ }
57
+ response = call(:post, url, data)
58
+ response['access_token']
59
+ end
60
+
61
+ private
62
+
63
+ def paginate(url, method: :post, headers: {}, page_size: 100, max_iterations: 1000)
64
+ next_page_token = nil
65
+
66
+ max_iterations.times do
67
+ data = {
68
+ nextPageToken: next_page_token,
69
+ maxResults: page_size,
70
+ }
71
+ data = call(method, url, data, headers)
72
+
73
+ yield data
74
+
75
+ return if data['nextPageToken']&.empty? || data['nextPageToken'] == next_page_token
76
+
77
+ next_page_token = data['nextPageToken']
78
+ end
79
+ end
80
+
81
+ def endpoint(path)
82
+ "https://www.googleapis.com/identitytoolkit/v3/relyingparty/#{path}?key=#{@api_key}"
83
+ end
84
+ end
85
+ end
@@ -1,33 +1,18 @@
1
- require 'logger'
2
- require 'json'
3
- require 'http'
4
-
5
1
  module Firefighter
6
2
  class RealtimeDatabase
3
+ include Web
4
+
7
5
  def self.from_env
8
6
  config = {
9
- api_key: ENV['FIREBASE_WEB_API_KEY'],
10
7
  db_name: ENV['FIREBASE_WEB_DB_NAME'],
11
8
  db_secret: ENV['FIREBASE_WEB_DB_SECRET']
12
9
  }
13
10
  new(config)
14
11
  end
15
12
 
16
- def initialize(api_key:, db_name:, db_secret:, logger: Logger.new(STDOUT))
17
- @api_key = api_key
13
+ def initialize(db_name:, db_secret:)
18
14
  @db_name = db_name
19
15
  @db_secret = db_secret
20
- @logger = logger
21
- end
22
-
23
- def signup(email, password)
24
- url = "https://www.googleapis.com/identitytoolkit/v3/relyingparty/signupNewUser?key=#{@api_key}"
25
- data = {
26
- email: email,
27
- password: password,
28
- returnSecureToken: true
29
- }
30
- call(:post, url, data)
31
16
  end
32
17
 
33
18
  def write(path, data)
@@ -42,31 +27,11 @@ module Firefighter
42
27
 
43
28
  def read(path)
44
29
  url = endpoint(path)
45
- get(url)
30
+ call(:get, url)
46
31
  end
47
32
 
48
33
  private
49
34
 
50
- def call(method, url, data)
51
- response = HTTP.send(method, url, headers: {'Content-Type' => 'application/json'}, body: JSON.dump(data))
52
- if response.status == 200
53
- JSON.parse(response.body)
54
- else
55
- @logger.warn "firebase #{method} failed #{url} #{response.body}"
56
- raise "firebase #{method} failed #{url} #{response.body}"
57
- end
58
- end
59
-
60
- def get(url)
61
- response = HTTP.get(url, headers: {'Content-Type' => 'application/json'})
62
- if response.status == 200
63
- JSON.parse(response.body)
64
- else
65
- @logger.warn "firebase get failed #{url} #{response.body}"
66
- raise "firebase get failed #{url} #{response.body}"
67
- end
68
- end
69
-
70
35
  def endpoint(path)
71
36
  "https://#{@db_name}.firebaseio.com/#{path}.json?auth=#{@db_secret}"
72
37
  end
@@ -7,19 +7,30 @@ module Firefighter
7
7
  config = {
8
8
  service_account_email: ENV['FIREBASE_SERVICE_ACCOUNT_EMAIL'],
9
9
  private_key: OpenSSL::PKey::RSA.new(ENV['FIREBASE_PRIVATE_KEY_DATA']),
10
- algorithm: 'RS256',
11
10
  }
12
11
  new(config)
13
12
  end
14
13
 
15
- def initialize(service_account_email:, private_key:, algorithm:, logger: Logger.new(STDOUT))
14
+ def initialize(service_account_email:, private_key:, algorithm: 'RS256')
16
15
  @service_account_email = service_account_email
17
16
  @private_key = private_key
18
17
  @algorithm = algorithm
19
- @logger = logger
20
18
  end
21
19
 
22
- def create_token(uid, data: {}, expiration: 60 * 60)
20
+
21
+ def create_access_token(expiration: 60 * 60)
22
+ now_seconds = Time.now.to_i
23
+ payload = {
24
+ iss: @service_account_email,
25
+ scope: 'https://www.googleapis.com/auth/identitytoolkit',
26
+ aud: 'https://accounts.google.com/o/oauth2/token',
27
+ iat: now_seconds,
28
+ exp: now_seconds + expiration, # Maximum expiration time is one hour
29
+ }
30
+ ::JWT.encode(payload, @private_key, @algorithm)
31
+ end
32
+
33
+ def create_custom_token(uid, data: {}, expiration: 60 * 60)
23
34
  now_seconds = Time.now.to_i
24
35
  payload = {
25
36
  iss: @service_account_email,
@@ -1,3 +1,3 @@
1
1
  module Firefighter
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -0,0 +1,28 @@
1
+ require 'logger'
2
+ require 'json'
3
+ require 'http'
4
+
5
+ module Firefighter
6
+ module Web
7
+ def logger
8
+ @logger ||= Logger.new(STDOUT)
9
+ end
10
+
11
+ def call(method, url, data = {}, headers = {})
12
+ if method == :get
13
+ response = HTTP.get(url, headers: headers)
14
+ elsif method == :form
15
+ response = HTTP.send(:post, url, form: data, headers: headers)
16
+ else
17
+ response = HTTP.send(method, url, json: data, headers: headers)
18
+ end
19
+
20
+ if response.status == 200
21
+ JSON.parse(response.body)
22
+ else
23
+ logger.warn "firebase #{method} failed #{url} #{response.body}"
24
+ raise "firebase #{method} failed #{url} #{response.body}"
25
+ end
26
+ end
27
+ end
28
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: firefighter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - phoet
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-07-12 00:00:00.000000000 Z
11
+ date: 2018-11-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: http
@@ -81,47 +81,47 @@ dependencies:
81
81
  - !ruby/object:Gem::Version
82
82
  version: '3.0'
83
83
  - !ruby/object:Gem::Dependency
84
- name: timecop
84
+ name: vcr
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: '0.9'
89
+ version: '4.0'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: '0.9'
96
+ version: '4.0'
97
97
  - !ruby/object:Gem::Dependency
98
- name: vcr
98
+ name: webmock
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: '4.0'
103
+ version: '3.4'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: '4.0'
110
+ version: '3.4'
111
111
  - !ruby/object:Gem::Dependency
112
- name: webmock
112
+ name: timecop
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
115
  - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: '3.4'
117
+ version: '0.9'
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
- version: '3.4'
124
+ version: '0.9'
125
125
  description: Firebase API Wrapper
126
126
  email:
127
127
  - phoetmail@googlemail.com
@@ -129,6 +129,7 @@ executables: []
129
129
  extensions: []
130
130
  extra_rdoc_files: []
131
131
  files:
132
+ - ".circleci/config.yml"
132
133
  - ".gitignore"
133
134
  - ".rspec"
134
135
  - CODE_OF_CONDUCT.md
@@ -140,9 +141,11 @@ files:
140
141
  - bin/setup
141
142
  - firefighter.gemspec
142
143
  - lib/firefighter.rb
144
+ - lib/firefighter/identitytoolkit.rb
143
145
  - lib/firefighter/realtime_database.rb
144
146
  - lib/firefighter/token_generator.rb
145
147
  - lib/firefighter/version.rb
148
+ - lib/firefighter/web.rb
146
149
  homepage: http://github.com/penseo/firefighter
147
150
  licenses: []
148
151
  metadata: