reso_api 1.5.13 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c60f3b7a93a8fdff58458cb3ceedc48021d007bf88c65fc81455fde74002da9e
4
- data.tar.gz: 97509b32ddd67a2d5ee5857d25fb322e55f3d1e3cb4246c451c0b02f1865fd36
3
+ metadata.gz: 152e24a12afdb9af2c9385a365335df67b58704676b313c886a1833417ae8763
4
+ data.tar.gz: 88ca57e2199877808138e07f96999376541c40a138b90a920bf56940e786d212
5
5
  SHA512:
6
- metadata.gz: eaa3ebf09faee81c40d59063d77468e716f14377a6ae3fd5bb8b59423831b7c3008b0d968cf91962948d828150680caadb7c4fc5f3a2997fa7710527dae9e2b3
7
- data.tar.gz: 196d66437d0ceb577aa3521fb2bee7ae7fb996c2a3b46520ee5ea7268d2cda33751744c314939f57c1676db8657942a52d12f1711ace54e55c7010cef318fcc2
6
+ metadata.gz: 0e5c6750cddd94f0dc296e64baf3d008157754360c58c2350feb5df96fa4301f272ad4c1b81a3f20b809523bd16858fc018e38e0a190f71eb2b10f6b2b0552d5
7
+ data.tar.gz: 1a21eb60cd03e7e39a6cd33123f7635dd194f1cd4bb2e03d326788fecdc187316e9bfc79469f60847fe7d013d286611ef8e4dee49d0524a37d5b2bd3e1814912
data/README.md CHANGED
@@ -26,23 +26,47 @@ Or install it yourself as:
26
26
 
27
27
  ### Authentication and Access
28
28
 
29
- To set up an API client and access a service, you need three pieces of information:
29
+ This gem supports two types of authentication:
30
+
31
+ - OAuth2
32
+ - Access Token
33
+
34
+ #### OAuth2
35
+
36
+ To set up an API client using OAuth2 authentication, you need four pieces of information:
30
37
 
31
38
  - Client ID
32
39
  - Client Secret
33
- - Base API endpoint
34
40
  - Authentication URL
41
+ - Base URL
42
+ - Scope
35
43
 
36
- You'll recognize the base API endpoint by it ending with /odata, and the authentication URL by it likely ending with /token.
44
+ Often, the base URL ends with `/odata`, and the authentication URL often ends with `/token`.
45
+
46
+ Scope defaults to "api" and only needs to be included if it is "OData" or something else.
37
47
 
38
48
  You pass these four pieces of information to create an instance of an API client:
39
49
 
40
50
  ```ruby
41
- client = RESO::API::Client.new(client_id: client_id, client_secret: client_secret, auth_url: auth_url, base_url: base_url)
51
+ client = RESO::API::Client.new(client_id: client_id, client_secret: client_secret, auth_url: auth_url, base_url: base_url, scope: scope)
42
52
  ```
43
53
 
44
54
  When calling API endpoints using the initialized client, it will automatically fetch and manage access and authentication tokens transparently in the background.
45
55
 
56
+ #### Access Token
57
+
58
+ Some systems, like MLSGRID and Spark/Flexmls provides a persistent Access Token. In these cases, you need these two pieces of information to set up an API client:
59
+
60
+ - Access Token
61
+ - Base API endpoint
62
+
63
+ You pass these two pieces of information to create an instance of an API client:
64
+
65
+ ```ruby
66
+ client = RESO::API::Client.new(access_token: access_token, base_url: base_url)
67
+ ```
68
+
69
+
46
70
  ### Resources
47
71
 
48
72
  #### Supported Resources
@@ -7,18 +7,22 @@ module RESO
7
7
  require 'json'
8
8
  require 'tmpdir'
9
9
 
10
- attr_accessor :client_id, :client_secret, :auth_url, :base_url
10
+ attr_accessor :access_token, :client_id, :client_secret, :auth_url, :base_url, :scope
11
11
 
12
12
  def initialize(**opts)
13
- @client_id, @client_secret, @auth_url, @base_url = opts.values_at(:client_id, :client_secret, :auth_url, :base_url)
13
+ @access_token, @client_id, @client_secret, @auth_url, @base_url, @scope = opts.values_at(:access_token, :client_id, :client_secret, :auth_url, :base_url, :scope)
14
14
  validate!
15
15
  end
16
16
 
17
17
  def validate!
18
- raise 'Missing Client ID `client_id`' if client_id.nil?
19
- raise 'Missing Client Secret `client_secret`' if client_secret.nil?
20
- raise 'Missing Authentication URL `auth_url`' if auth_url.nil?
21
- raise 'Missing API Base URL `base_url`' if base_url.nil?
18
+ if access_token.nil?
19
+ raise 'Missing Client ID `client_id`' if client_id.nil?
20
+ raise 'Missing Client Secret `client_secret`' if client_secret.nil?
21
+ raise 'Missing Authentication URL `auth_url`' if auth_url.nil?
22
+ raise 'Missing API Base URL `base_url`' if base_url.nil?
23
+ else
24
+ raise 'Missing API Base URL `base_url`' if base_url.nil?
25
+ end
22
26
  end
23
27
 
24
28
  RESOURCE_KEYS = {
@@ -96,12 +100,16 @@ module RESO
96
100
  end
97
101
  end
98
102
 
103
+ def auth_token
104
+ access_token.presence ? access_token : oauth2_token
105
+ end
106
+
99
107
  def oauth2_client
100
108
  OAuth2::Client.new(
101
109
  client_id,
102
110
  client_secret,
103
111
  token_url: auth_url,
104
- scope: "api",
112
+ scope: scope.presence || "api",
105
113
  grant_type: "client_credentials"
106
114
  )
107
115
  end
@@ -120,7 +128,7 @@ module RESO
120
128
  end
121
129
 
122
130
  def fresh_oauth2_payload
123
- @oauth2_payload = oauth2_client.client_credentials.get_token('client_id' => client_id, 'client_secret' => client_secret)
131
+ @oauth2_payload = oauth2_client.client_credentials.get_token('client_id' => client_id, 'client_secret' => client_secret, 'scope' => scope || "api")
124
132
  File.write(oauth2_token_path, @oauth2_payload.to_hash.to_json)
125
133
  return @oauth2_payload
126
134
  end
@@ -138,7 +146,7 @@ module RESO
138
146
  persisted = File.read(oauth2_token_path)
139
147
  payload = OAuth2::AccessToken.from_hash(oauth2_client, JSON.parse(persisted))
140
148
  else
141
- payload = oauth2_client.client_credentials.get_token('client_id' => client_id, 'client_secret' => client_secret)
149
+ payload = oauth2_client.client_credentials.get_token('client_id' => client_id, 'client_secret' => client_secret, 'scope' => scope || "api")
142
150
  File.write(oauth2_token_path, payload.to_hash.to_json)
143
151
  end
144
152
  return payload
@@ -158,7 +166,7 @@ module RESO
158
166
  end
159
167
  begin
160
168
  req = Net::HTTP::Get.new(uri.request_uri)
161
- req['Authorization'] = "Bearer #{oauth2_token}"
169
+ req['Authorization'] = "Bearer #{auth_token}"
162
170
  res = Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http|
163
171
  http.request(req)
164
172
  end
@@ -171,7 +179,7 @@ module RESO
171
179
  fresh_oauth2_payload
172
180
  raise StandardError
173
181
  elsif response.is_a?(Hash) && response.has_key?("error")
174
- puts "Error."
182
+ puts "Error: #{response.inspect}"
175
183
  raise StandardError
176
184
  elsif response.is_a?(Hash) && response.has_key?("retry-after")
177
185
  puts "Error: Retrying in #{response["retry-after"].to_i}} seconds."
@@ -1,3 +1,3 @@
1
1
  module ResoApi
2
- VERSION = "1.5.13"
2
+ VERSION = "1.7.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: reso_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.13
4
+ version: 1.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Edlund
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-07-17 00:00:00.000000000 Z
11
+ date: 2024-04-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -123,7 +123,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0'
125
125
  requirements: []
126
- rubygems_version: 3.4.16
126
+ rubygems_version: 3.5.9
127
127
  signing_key:
128
128
  specification_version: 4
129
129
  summary: RESO Web API Wrapper