ephemeral_calc 0.2.0 → 0.3.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 +4 -4
- data/ephemeral_calc.gemspec +2 -0
- data/exe/ephemeral_calc +23 -27
- data/lib/ephemeral_calc/registration.rb +89 -0
- data/lib/ephemeral_calc/version.rb +1 -1
- data/lib/ephemeral_calc.rb +3 -4
- metadata +17 -6
- data/lib/ephemeral_calc/google_api/client.rb +0 -82
- data/lib/ephemeral_calc/google_api/credentials.rb +0 -39
- data/lib/ephemeral_calc/google_api/oauth.rb +0 -87
- data/lib/ephemeral_calc/google_api/request.rb +0 -69
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d66ed2f2feb08b61474d5e99d9906de5702b409a
|
4
|
+
data.tar.gz: 448f9eb5dbad2eb1cc99e097f384d0041a60ebcc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0f4e472ea04511a2406a17897c2571a4337dbffef92796661d8b66de8e5a26ce4a834859b0e6352cda6e26d147535cd27cf8ab55c994e533822e9b7979eb8914
|
7
|
+
data.tar.gz: f0a98210f4e975c70ef30de5beb8c2dc6af80b2837eb9d6969f7d5afec7e938883467b38c6907d3daa7ec44733d4057d4d6d8ab049e255b6ca1c2da05bceb686
|
data/ephemeral_calc.gemspec
CHANGED
@@ -20,6 +20,8 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.extensions = %w[ext/curve25519/extconf.rb]
|
21
21
|
spec.require_paths = ["lib"]
|
22
22
|
|
23
|
+
spec.add_runtime_dependency "proximity_beacon", "~> 0.1.3"
|
24
|
+
|
23
25
|
spec.add_development_dependency "bundler", "~> 1.10"
|
24
26
|
spec.add_development_dependency "rake", "~> 10.0"
|
25
27
|
spec.add_development_dependency "rspec"
|
data/exe/ephemeral_calc
CHANGED
@@ -53,11 +53,13 @@ Commands:
|
|
53
53
|
access the API.
|
54
54
|
|
55
55
|
register:
|
56
|
-
ephemeral_calc register <
|
56
|
+
ephemeral_calc register <beacon_description> [<rotation_exp> [<namespace> [<instance]]]
|
57
57
|
|
58
|
-
Registers an EID beacon with Google's Proximity Beacon API. All
|
59
|
-
|
60
|
-
|
58
|
+
Registers an EID beacon with Google's Proximity Beacon API. All byte strings should be in hex. If you
|
59
|
+
do not supply a namespace it will use the following: 'e3dd811dd3bbe49e630a'. If you do not supply an
|
60
|
+
instance it will randomly generate one. Uses environment variables "GOOGLE_CLIENT_ID" and
|
61
|
+
"GOOGLE_CLIENT_SECRET" to do the neccessary OAuth in order to access the API. Outputs YAML which
|
62
|
+
contains all the information necessary to advertise as this registered beacon.
|
61
63
|
|
62
64
|
keygen:
|
63
65
|
ephemeral_calc keygen
|
@@ -135,18 +137,17 @@ eos
|
|
135
137
|
eid_hex = ARGV.shift
|
136
138
|
api_key = ENV["GOOGLE_API_KEY"]
|
137
139
|
|
140
|
+
client = ProximityBeacon::Client.new
|
138
141
|
if api_key
|
139
|
-
client = EphemeralCalc::GoogleAPI::Client.new(nil) # don't try oauth
|
140
142
|
response = client.getforobserved(eid_hex, api_key)
|
141
143
|
beacons = response["beacons"]
|
142
144
|
beacon = beacons[0] if beacons
|
143
145
|
else
|
144
146
|
beacon_name = "beacons/4!#{eid_hex.downcase}"
|
145
147
|
begin
|
146
|
-
beacon =
|
147
|
-
attachments =
|
148
|
-
|
149
|
-
rescue EphemeralCalc::GoogleAPI::RequestError => e
|
148
|
+
beacon = client.beacons.get(beacon_name).as_json
|
149
|
+
beacon["attachments"] = client.attachments.list(beacon_name).map(&:as_json)
|
150
|
+
rescue ProximityBeacon::Client::RequestError => e
|
150
151
|
# if we get a 404, the EID doesn't resolve
|
151
152
|
raise e unless e.code == 404
|
152
153
|
end
|
@@ -161,7 +162,7 @@ eos
|
|
161
162
|
|
162
163
|
def eidparams
|
163
164
|
require 'yaml'
|
164
|
-
eidparams =
|
165
|
+
eidparams = ProximityBeacon::Client.new.eidparams
|
165
166
|
key_hex = to_hex(Base64.decode64(eidparams["serviceEcdhPublicKey"]))
|
166
167
|
eidparams["serviceEcdhPublicKeyHex"] = key_hex
|
167
168
|
puts eidparams.to_yaml
|
@@ -177,15 +178,18 @@ eos
|
|
177
178
|
|
178
179
|
def register
|
179
180
|
require 'yaml'
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
181
|
+
name = ARGV.shift
|
182
|
+
rotation_exp = ARGV.shift
|
183
|
+
namespace = ARGV.shift
|
184
|
+
instance = ARGV.shift
|
185
|
+
registration = EphemeralCalc::Registration.new(
|
186
|
+
name: name,
|
187
|
+
rotation_exp: rotation_exp,
|
188
|
+
namespace: namespace,
|
189
|
+
instance: instance
|
190
|
+
)
|
191
|
+
registration.register
|
192
|
+
puts registration.to_yaml
|
189
193
|
end
|
190
194
|
|
191
195
|
def keygen
|
@@ -207,14 +211,6 @@ eos
|
|
207
211
|
end
|
208
212
|
end
|
209
213
|
|
210
|
-
def oauth_client
|
211
|
-
@oauth_client ||=
|
212
|
-
begin
|
213
|
-
client = EphemeralCalc::GoogleAPI::Client.new
|
214
|
-
client.credentials.save
|
215
|
-
client
|
216
|
-
end
|
217
|
-
end
|
218
214
|
end
|
219
215
|
|
220
216
|
app = App.new
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module EphemeralCalc
|
2
|
+
class Registration
|
3
|
+
|
4
|
+
DEFAULT_NAMESPACE = "e3dd811dd3bbe49e630a"
|
5
|
+
DEFAULT_ROTATION_EXP = 12 # 2^12 = ~68 minutes
|
6
|
+
|
7
|
+
attr_reader :name,
|
8
|
+
:rotation_exp,
|
9
|
+
:namespace,
|
10
|
+
:instance,
|
11
|
+
:beacon_private_key,
|
12
|
+
:beacon_keypair,
|
13
|
+
:beacon_time_zero
|
14
|
+
|
15
|
+
def initialize(name:,
|
16
|
+
rotation_exp: nil,
|
17
|
+
namespace: nil,
|
18
|
+
instance: nil,
|
19
|
+
beacon_private_key: nil)
|
20
|
+
@name = name
|
21
|
+
@rotation_exp = (rotation_exp || DEFAULT_ROTATION_EXP).to_i
|
22
|
+
@namespace = namespace || DEFAULT_NAMESPACE
|
23
|
+
@instance = instance || random_instance
|
24
|
+
@beacon_private_key = beacon_private_key || EphemeralCalc::KeyPair.generate_private_key
|
25
|
+
@beacon_keypair = EphemeralCalc::KeyPair.new(@beacon_private_key)
|
26
|
+
end
|
27
|
+
|
28
|
+
def api_client
|
29
|
+
@api_client ||= ProximityBeacon::Client.new
|
30
|
+
end
|
31
|
+
|
32
|
+
def eid_params
|
33
|
+
@eid_params ||= api_client.eidparams
|
34
|
+
end
|
35
|
+
|
36
|
+
def resolver_public_key
|
37
|
+
Base64.decode64(eid_params["serviceEcdhPublicKey"])
|
38
|
+
end
|
39
|
+
|
40
|
+
def identity_key
|
41
|
+
beacon_keypair.identity_key(resolver_public_key: resolver_public_key)
|
42
|
+
end
|
43
|
+
|
44
|
+
def encryptor
|
45
|
+
@encryptor ||= EphemeralCalc::Encryptor.new(identity_key, rotation_exp)
|
46
|
+
end
|
47
|
+
|
48
|
+
def initial_eid
|
49
|
+
[encryptor.get_identifier(0)].pack("H*")
|
50
|
+
end
|
51
|
+
|
52
|
+
def register
|
53
|
+
beacon = ProximityBeacon::Beacon.new(
|
54
|
+
ephemeral_id_registration: {
|
55
|
+
beaconEcdhPublicKey: Base64.strict_encode64(beacon_keypair.public_key),
|
56
|
+
serviceEcdhPublicKey: eid_params["serviceEcdhPublicKey"],
|
57
|
+
rotationPeriodExponent: rotation_exp,
|
58
|
+
initialClockValue: encryptor.beacon_time,
|
59
|
+
initialEid: Base64.strict_encode64(initial_eid)
|
60
|
+
},
|
61
|
+
advertised_id: ProximityBeacon::AdvertisedId.new(
|
62
|
+
eddystone_ids: [namespace, instance]
|
63
|
+
),
|
64
|
+
status: "ACTIVE",
|
65
|
+
description: self.name,
|
66
|
+
)
|
67
|
+
api_client.beacons.register(beacon)
|
68
|
+
end
|
69
|
+
|
70
|
+
def as_yaml
|
71
|
+
{
|
72
|
+
identity_key: identity_key,
|
73
|
+
rotation_exp: rotation_exp,
|
74
|
+
initial_time: encryptor.initial_time,
|
75
|
+
}
|
76
|
+
end
|
77
|
+
|
78
|
+
def to_yaml
|
79
|
+
as_yaml.to_yaml
|
80
|
+
end
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
def random_instance
|
85
|
+
SecureRandom.random_bytes(6).unpack("H*")[0]
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
data/lib/ephemeral_calc.rb
CHANGED
@@ -1,11 +1,10 @@
|
|
1
|
+
require "proximity_beacon"
|
2
|
+
|
1
3
|
require "ephemeral_calc/version"
|
2
4
|
require "ephemeral_calc/curve25519"
|
3
5
|
require "ephemeral_calc/encryptor"
|
4
6
|
require "ephemeral_calc/key_pair"
|
5
|
-
require "ephemeral_calc/
|
6
|
-
require "ephemeral_calc/google_api/credentials"
|
7
|
-
require "ephemeral_calc/google_api/request"
|
8
|
-
require "ephemeral_calc/google_api/client"
|
7
|
+
require "ephemeral_calc/registration"
|
9
8
|
|
10
9
|
module EphemeralCalc
|
11
10
|
# Your code goes here...
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ephemeral_calc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Radius Networks
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-08-
|
11
|
+
date: 2016-08-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: proximity_beacon
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.1.3
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.1.3
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: bundler
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -106,11 +120,8 @@ files:
|
|
106
120
|
- ext/curve25519/extconf.rb
|
107
121
|
- lib/ephemeral_calc.rb
|
108
122
|
- lib/ephemeral_calc/encryptor.rb
|
109
|
-
- lib/ephemeral_calc/google_api/client.rb
|
110
|
-
- lib/ephemeral_calc/google_api/credentials.rb
|
111
|
-
- lib/ephemeral_calc/google_api/oauth.rb
|
112
|
-
- lib/ephemeral_calc/google_api/request.rb
|
113
123
|
- lib/ephemeral_calc/key_pair.rb
|
124
|
+
- lib/ephemeral_calc/registration.rb
|
114
125
|
- lib/ephemeral_calc/version.rb
|
115
126
|
homepage: https://github.com/RadiusNetworks/ephemeral_calc
|
116
127
|
licenses: []
|
@@ -1,82 +0,0 @@
|
|
1
|
-
require 'json'
|
2
|
-
require 'uri'
|
3
|
-
require 'net/http'
|
4
|
-
require 'base64'
|
5
|
-
|
6
|
-
module EphemeralCalc
|
7
|
-
module GoogleAPI
|
8
|
-
class Client
|
9
|
-
|
10
|
-
PROXIMITY_BEACON_ROOT = "https://proximitybeacon.googleapis.com/v1beta1/"
|
11
|
-
EIDPARAMS_URI = URI(PROXIMITY_BEACON_ROOT + "eidparams")
|
12
|
-
BEACON_REGISTER_URI = URI(PROXIMITY_BEACON_ROOT + "beacons:register")
|
13
|
-
|
14
|
-
attr_accessor :credentials
|
15
|
-
|
16
|
-
def initialize(credentials = OAuth.new.get_credentials)
|
17
|
-
self.credentials = credentials
|
18
|
-
end
|
19
|
-
|
20
|
-
def eidparams
|
21
|
-
response = Request.get(EIDPARAMS_URI, credentials)
|
22
|
-
# response = request(:get, EIDPARAMS_URI, credentials.access_token)
|
23
|
-
return JSON.parse(response.body)
|
24
|
-
end
|
25
|
-
|
26
|
-
def register_eid(beacon_public_key, rotation_exp, initial_eid, initial_clock, uid_bytes)
|
27
|
-
service_public_key_base64 = get_eidparams["serviceEcdhPublicKey"]
|
28
|
-
response = Request.post(BEACON_REGISTER_URI, credentials) {|request|
|
29
|
-
request.add_field "Content-Type", "application/json"
|
30
|
-
request.body = {
|
31
|
-
ephemeralIdRegistration: {
|
32
|
-
beaconEcdhPublicKey: Base64.strict_encode64(beacon_public_key),
|
33
|
-
serviceEcdhPublicKey: service_public_key_base64,
|
34
|
-
rotationPeriodExponent: rotation_exp,
|
35
|
-
initialClockValue: initial_clock,
|
36
|
-
initialEid: Base64.strict_encode64(initial_eid)
|
37
|
-
},
|
38
|
-
advertisedId: {
|
39
|
-
type: "EDDYSTONE",
|
40
|
-
id: Base64.strict_encode64(uid_bytes)
|
41
|
-
},
|
42
|
-
status: "ACTIVE",
|
43
|
-
description: "EphemeralCalc Registered EID"
|
44
|
-
}.to_json
|
45
|
-
}
|
46
|
-
JSON.parse(response.body)
|
47
|
-
end
|
48
|
-
|
49
|
-
def get_resource(resource_name)
|
50
|
-
uri = URI(PROXIMITY_BEACON_ROOT + resource_name)
|
51
|
-
response = Request.get(uri, credentials)
|
52
|
-
JSON.parse(response.body)
|
53
|
-
end
|
54
|
-
|
55
|
-
def getforobserved(eids, api_key = ENV["GOOGLE_API_KEY"])
|
56
|
-
uri = URI("#{PROXIMITY_BEACON_ROOT}beaconinfo:getforobserved?key=#{api_key}")
|
57
|
-
response = Request.post(uri) {|request|
|
58
|
-
observations = Array(eids).map {|eid|
|
59
|
-
{advertisedId: {type: "EDDYSTONE_EID", id: base64_eid(eid)}}
|
60
|
-
}
|
61
|
-
request.body = {
|
62
|
-
observations: observations,
|
63
|
-
namespacedTypes: "*",
|
64
|
-
}.to_json
|
65
|
-
request.add_field "Content-Type", "application/json"
|
66
|
-
}
|
67
|
-
JSON.parse(response.body)
|
68
|
-
end
|
69
|
-
|
70
|
-
private
|
71
|
-
|
72
|
-
def base64_eid(eid)
|
73
|
-
if eid.size == 16
|
74
|
-
Base64.strict_encode64([eid].pack("H*"))
|
75
|
-
else
|
76
|
-
Base64.strict_encode64(eid)
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
@@ -1,39 +0,0 @@
|
|
1
|
-
require 'yaml'
|
2
|
-
|
3
|
-
module EphemeralCalc
|
4
|
-
module GoogleAPI
|
5
|
-
class Credentials
|
6
|
-
|
7
|
-
DEFAULT_FILE_STORE = File.expand_path("~/.ephemeral_calc_google_credentials.yaml")
|
8
|
-
attr_accessor :access_token, :refresh_token, :expires_at
|
9
|
-
|
10
|
-
def self.from_file(file = DEFAULT_FILE_STORE)
|
11
|
-
return nil unless File.exist?(file)
|
12
|
-
self.new YAML.load_file(file)
|
13
|
-
end
|
14
|
-
|
15
|
-
def initialize(opts = {})
|
16
|
-
# convert string keys to symbols
|
17
|
-
opts = opts.inject({}){|memo,(k,v)| memo[k.to_sym] = v; memo}
|
18
|
-
|
19
|
-
self.access_token = opts[:access_token]
|
20
|
-
self.refresh_token = opts[:refresh_token]
|
21
|
-
self.expires_at = opts[:expires_at] || (Time.now + opts[:expires_in].to_i)
|
22
|
-
end
|
23
|
-
|
24
|
-
def save(file = DEFAULT_FILE_STORE)
|
25
|
-
data = {
|
26
|
-
access_token: access_token,
|
27
|
-
refresh_token: refresh_token,
|
28
|
-
expires_at: expires_at
|
29
|
-
}.to_yaml
|
30
|
-
File.open(file, 'w') {|f| f.write(data) }
|
31
|
-
end
|
32
|
-
|
33
|
-
def expired?
|
34
|
-
self.expires_at < Time.now
|
35
|
-
end
|
36
|
-
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
@@ -1,87 +0,0 @@
|
|
1
|
-
require 'json'
|
2
|
-
require 'uri'
|
3
|
-
require 'net/http'
|
4
|
-
|
5
|
-
module EphemeralCalc
|
6
|
-
module GoogleAPI
|
7
|
-
class OAuth
|
8
|
-
|
9
|
-
SCOPES = [
|
10
|
-
"https://www.googleapis.com/auth/userlocation.beacon.registry",
|
11
|
-
"https://www.googleapis.com/auth/cloud-platform",
|
12
|
-
]
|
13
|
-
|
14
|
-
REDIRECT_URI = "urn:ietf:wg:oauth:2.0:oob"
|
15
|
-
TOKEN_URI = URI("https://www.googleapis.com/oauth2/v4/token")
|
16
|
-
|
17
|
-
attr_accessor :client_id, :secret
|
18
|
-
|
19
|
-
def initialize(client_id = ENV["GOOGLE_CLIENT_ID"], secret = ENV["GOOGLE_CLIENT_SECRET"])
|
20
|
-
if client_id.nil? || secret.nil?
|
21
|
-
raise ArgumentError, "No Google Client ID or Secret was set. These can set in the environment variables \"GOOGLE_CLIENT_ID\" and \"GOOGLE_CLIENT_SECRET\" respectively. Credentials must be created for your project at \"https://console.developers.google.com/apis/credentials\"."
|
22
|
-
end
|
23
|
-
self.client_id = client_id
|
24
|
-
self.secret = secret
|
25
|
-
end
|
26
|
-
|
27
|
-
def get_code
|
28
|
-
puts("Performing OAuth with Google...")
|
29
|
-
if RUBY_PLATFORM =~ /darwin/
|
30
|
-
system("open \"#{url}\"")
|
31
|
-
else
|
32
|
-
puts("Open this URL in your browser: \"#{url}\"\n\n")
|
33
|
-
end
|
34
|
-
printf "Copy and paste code from web browser here: "
|
35
|
-
_code = STDIN.gets.chomp
|
36
|
-
end
|
37
|
-
|
38
|
-
def get_credentials(old_credentials = Credentials.from_file)
|
39
|
-
return old_credentials if old_credentials && !old_credentials.expired?
|
40
|
-
response = Request.post(TOKEN_URI) {|request|
|
41
|
-
request.body = hash_to_params( token_request_params(old_credentials) )
|
42
|
-
}
|
43
|
-
json = JSON.parse(response.body)
|
44
|
-
credentials = Credentials.new(json)
|
45
|
-
if old_credentials
|
46
|
-
credentials.refresh_token = old_credentials.refresh_token
|
47
|
-
end
|
48
|
-
return credentials
|
49
|
-
end
|
50
|
-
|
51
|
-
def url
|
52
|
-
params = hash_to_params(
|
53
|
-
scope: SCOPES.join("%20"),
|
54
|
-
redirect_uri: REDIRECT_URI,
|
55
|
-
response_type: "code",
|
56
|
-
client_id: client_id,
|
57
|
-
)
|
58
|
-
"https://accounts.google.com/o/oauth2/v2/auth?#{params}"
|
59
|
-
end
|
60
|
-
|
61
|
-
def token_request_params(old_credentials)
|
62
|
-
if old_credentials == nil
|
63
|
-
{
|
64
|
-
code: get_code,
|
65
|
-
client_id: client_id,
|
66
|
-
client_secret: secret,
|
67
|
-
redirect_uri: REDIRECT_URI,
|
68
|
-
grant_type: "authorization_code",
|
69
|
-
}
|
70
|
-
else
|
71
|
-
# this is a refresh of the old credentials
|
72
|
-
{
|
73
|
-
refresh_token: old_credentials.refresh_token,
|
74
|
-
client_id: client_id,
|
75
|
-
client_secret: secret,
|
76
|
-
grant_type: "refresh_token",
|
77
|
-
}
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
def hash_to_params(hash)
|
82
|
-
hash.map {|k,v| "#{k}=#{v}"}.join("&")
|
83
|
-
end
|
84
|
-
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
@@ -1,69 +0,0 @@
|
|
1
|
-
require 'forwardable'
|
2
|
-
require 'uri'
|
3
|
-
require 'net/http'
|
4
|
-
require 'base64'
|
5
|
-
|
6
|
-
module EphemeralCalc
|
7
|
-
module GoogleAPI
|
8
|
-
class Request
|
9
|
-
extend Forwardable
|
10
|
-
|
11
|
-
attr_accessor :method, :uri, :credentials
|
12
|
-
def_delegators :request, :add_field, :body=
|
13
|
-
|
14
|
-
def self.get(uri, credentials = nil)
|
15
|
-
result = self.new(:get, uri, credentials)
|
16
|
-
result.perform {|r| yield r if block_given? }
|
17
|
-
end
|
18
|
-
|
19
|
-
def self.post(uri, credentials = nil)
|
20
|
-
result = self.new(:post, uri, credentials)
|
21
|
-
result.perform {|r| yield r if block_given? }
|
22
|
-
end
|
23
|
-
|
24
|
-
def initialize(method, uri, credentials = nil)
|
25
|
-
self.method = method
|
26
|
-
self.uri = uri
|
27
|
-
self.credentials = credentials
|
28
|
-
yield self if block_given?
|
29
|
-
end
|
30
|
-
|
31
|
-
def perform
|
32
|
-
http_opts = {use_ssl: true}
|
33
|
-
response = Net::HTTP.start(uri.host, uri.port, http_opts) do |http|
|
34
|
-
add_field "Authorization", "Bearer #{credentials.access_token}" if credentials
|
35
|
-
add_field "Accept", "application/json"
|
36
|
-
yield self if block_given?
|
37
|
-
http.request request
|
38
|
-
end
|
39
|
-
if (200..299).include?(response.code.to_i)
|
40
|
-
return response
|
41
|
-
else
|
42
|
-
raise RequestError.new(response.code.to_i), "Error #{response.code} (#{response.msg}) - #{uri}\n#{response.body}"
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
private
|
47
|
-
|
48
|
-
def request
|
49
|
-
@request ||=
|
50
|
-
begin
|
51
|
-
case method
|
52
|
-
when :get
|
53
|
-
Net::HTTP::Get.new uri.request_uri
|
54
|
-
when :post
|
55
|
-
Net::HTTP::Post.new uri.request_uri
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
class RequestError < StandardError
|
62
|
-
attr_accessor :code
|
63
|
-
def initialize(code)
|
64
|
-
self.code = code
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
end
|
69
|
-
end
|