Class: RESO::API::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/reso_api/app/models/reso/api/client.rb

Constant Summary collapse

RESOURCE_KEYS =
{
  media: "MediaKey",
  members: "MemberKey",
  offices: "OfficeKey",
  properties: "ListingKey"
}
DETAIL_ENDPOINTS =
{
  medium: "odata/Media",
  member: "odata/Member",
  office: "odata/Office",
  property: "odata/Property"
}
FILTERABLE_ENDPOINTS =
{
  media: "odata/Media",
  members: "odata/Member",
  offices: "odata/Office",
  properties: "odata/Property"
}
PASSTHROUGH_ENDPOINTS =
{
  metadata: "odata/$metadata"
}

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(**opts) ⇒ Client

Returns a new instance of Client.



12
13
14
15
# File 'lib/reso_api/app/models/reso/api/client.rb', line 12

def initialize(**opts)
  @client_id, @client_secret, @base_url = opts.values_at(:client_id, :client_secret, :base_url)
  validate!
end

Instance Attribute Details

#base_urlObject

Returns the value of attribute base_url.



10
11
12
# File 'lib/reso_api/app/models/reso/api/client.rb', line 10

def base_url
  @base_url
end

#client_idObject

Returns the value of attribute client_id.



10
11
12
# File 'lib/reso_api/app/models/reso/api/client.rb', line 10

def client_id
  @client_id
end

#client_secretObject

Returns the value of attribute client_secret.



10
11
12
# File 'lib/reso_api/app/models/reso/api/client.rb', line 10

def client_secret
  @client_secret
end

Instance Method Details

#get_oauth2_payloadObject



111
112
113
114
115
116
117
118
119
120
# File 'lib/reso_api/app/models/reso/api/client.rb', line 111

def get_oauth2_payload
  if File.exist?(oauth2_token_path)
    persisted = File.read(oauth2_token_path)
    payload = OAuth2::AccessToken.from_hash(oauth2_client, JSON.parse(persisted))
  else
    payload = oauth2_client.client_credentials.get_token
    File.write(oauth2_token_path, payload.to_hash.to_json)
  end
  return payload
end

#oauth2_clientObject



81
82
83
84
85
86
87
# File 'lib/reso_api/app/models/reso/api/client.rb', line 81

def oauth2_client
  OAuth2::Client.new(
    client_id,
    client_secret,
    token_url: [base_url, "oauth2/token"].join
  )
end

#oauth2_payloadObject



107
108
109
# File 'lib/reso_api/app/models/reso/api/client.rb', line 107

def oauth2_payload
  @oauth2_payload ||= get_oauth2_payload
end

#oauth2_tokenObject



89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/reso_api/app/models/reso/api/client.rb', line 89

def oauth2_token
  payload = oauth2_payload
  token = JWT.decode(payload.token, nil, false)
  exp_timestamp = Hash(token.try(:first))["exp"].to_s
  expiration = DateTime.strptime(exp_timestamp, '%s').utc rescue DateTime.now.utc
  if expiration > DateTime.now.utc
    return payload.token
  else
    @oauth2_payload = oauth2_client.client_credentials.get_token
    File.write(oauth2_token_path, @oauth2_payload.to_hash.to_json)
    return @oauth2_payload.token
  end
end

#oauth2_token_pathObject



103
104
105
# File 'lib/reso_api/app/models/reso/api/client.rb', line 103

def oauth2_token_path
  File.join(Dir.tmpdir, [base_url.parameterize, "-oauth-token.json"].join)
end

#perform_call(endpoint, params) ⇒ Object



126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/reso_api/app/models/reso/api/client.rb', line 126

def perform_call(endpoint, params)
  uri = uri_for_endpoint(endpoint)
  if params.present?
    query = params.present? ? URI.encode_www_form(params).gsub("+", " ") : ""
    uri.query && uri.query.length > 0 ? uri.query += '&' + query : uri.query = query
    return URI::decode(uri.request_uri) if params.dig(:$debug).present?
  end
  request = Net::HTTP::Get.new(uri.request_uri)
  request['Authorization'] = "Bearer #{oauth2_token}"
  response = Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http|
    http.request(request)
  end
  return JSON(response.body) rescue response.body
end

#uri_for_endpoint(endpoint) ⇒ Object



122
123
124
# File 'lib/reso_api/app/models/reso/api/client.rb', line 122

def uri_for_endpoint endpoint
  return URI([base_url, endpoint].join)
end

#validate!Object



17
18
19
20
21
# File 'lib/reso_api/app/models/reso/api/client.rb', line 17

def validate!
  raise 'Missing Client ID `client_id`' if client_id.nil?
  raise 'Missing Client Secret `client_secret`' if client_secret.nil?
  raise 'Missing API Base URL `base_url`' if base_url.nil?
end