class ArtemisApi::Client

Attributes

access_token[R]
expires_at[R]
oauth_client[R]
oauth_token[R]
objects[R]
on_token_failed[R]
on_token_refreshed[R]
options[R]
refresh_token[R]

Public Class Methods

new( access_token: nil, refresh_token: nil, expires_at: nil, auth_code: nil, redirect_uri: nil, on_token_refreshed: nil, on_token_failed: nil, options: {} ) click to toggle source
# File lib/artemis_api/client.rb, line 9
def initialize(
  access_token: nil,
  refresh_token: nil,
  expires_at: nil,
  auth_code: nil,
  redirect_uri: nil,
  on_token_refreshed: nil,
  on_token_failed: nil,
  options: {}
)
  unless (access_token && refresh_token && expires_at) || auth_code
    raise ArgumentError.new('You must either provide your access token, refresh token & expires at time, or an authorization code.')
  end

  options[:app_id] ||= ENV['ARTEMIS_OAUTH_APP_ID']
  options[:app_secret] ||= ENV['ARTEMIS_OAUTH_APP_SECRET']
  options[:base_uri] ||= ENV['ARTEMIS_BASE_URI']
  @options = options
  @objects = {}

  @on_token_refreshed = on_token_refreshed
  @on_token_failed = on_token_failed

  @oauth_client = OAuth2::Client.new(@options[:app_id], @options[:app_secret], site: @options[:base_uri])

  if auth_code
    redirect_uri ||= 'urn:ietf:wg:oauth:2.0:oob'

    @oauth_token = @oauth_client.auth_code.get_token(auth_code, redirect_uri: redirect_uri)

    @access_token = @oauth_token.token
    @refresh_token = @oauth_token.refresh_token
    @expires_at = @oauth_token.expires_at
  else
    set_oauth_token_from_parts(
      access_token: access_token,
      refresh_token: refresh_token,
      expires_at: expires_at
    )
  end
end

Public Instance Methods

auto_refresh!() click to toggle source
# File lib/artemis_api/client.rb, line 131
def auto_refresh!
  refresh! if @oauth_token.expired?
end
build_url(path:, query: nil) click to toggle source
# File lib/artemis_api/client.rb, line 113
def build_url(path:, query: nil)
  uri = URI::Generic.build(path: path, query: query)
  @options[:base_uri] + uri.to_s
end
current_user(include: nil) click to toggle source
# File lib/artemis_api/client.rb, line 169
def current_user(include: nil)
  ArtemisApi::User.get_current(client: self, include: include)
end
facilities(include: nil) click to toggle source
# File lib/artemis_api/client.rb, line 153
def facilities(include: nil)
  find_all('facilities', include: include)
end
facility(id, include: nil, force: false) click to toggle source
# File lib/artemis_api/client.rb, line 157
def facility(id, include: nil, force: false)
  find_one('facilities', id, include: include, force: force)
end
find_all(type, facility_id: nil, batch_id: nil, include: nil, filters: nil, page: nil) click to toggle source
# File lib/artemis_api/client.rb, line 87
def find_all(type, facility_id: nil, batch_id: nil, include: nil, filters: nil, page: nil)
  records = []
  auto_refresh!

  path = if facility_id && batch_id
           "/api/v3/facilities/#{facility_id}/batches/#{batch_id}/#{type}"
         elsif facility_id && batch_id.nil?
           "/api/v3/facilities/#{facility_id}/#{type}"
         else
           "/api/v3/#{type}"
         end

  query = {}
  query[:include] = include if include
  format_filters(filters, query) if filters
  format_pagination(page, query) if page

  url = build_url(path: path, query: URI.encode_www_form(query))

  response = @oauth_token.get(url)
  if response.status == 200
    records = process_array(response, type, records)
  end
  records
end
find_one(type, id, facility_id: nil, include: nil, force: false) click to toggle source
# File lib/artemis_api/client.rb, line 65
def find_one(type, id, facility_id: nil, include: nil, force: false)
  obj = get_record(type, id)
  if !obj || force
    auto_refresh!

    path = if facility_id
             "/api/v3/facilities/#{facility_id}/#{type}/#{id}"
           else
             "/api/v3/#{type}/#{id}"
           end

    query = {}
    query[:include] = include if include

    url = build_url(path: path, query: URI.encode_www_form(query))

    response = @oauth_token.get(url)
    obj = process_response(response, type) if response.status == 200
  end
  obj
end
get_record(type, id) click to toggle source
# File lib/artemis_api/client.rb, line 123
def get_record(type, id)
  @objects.dig(type, id.to_i)
end
organization(id, include: nil, force: false) click to toggle source
# File lib/artemis_api/client.rb, line 165
def organization(id, include: nil, force: false)
  find_one('organizations', id, include: include, force: force)
end
organizations(include: nil) click to toggle source
# File lib/artemis_api/client.rb, line 161
def organizations(include: nil)
  find_all('organizations', include: include)
end
process_response(response, type) click to toggle source
# File lib/artemis_api/client.rb, line 173
def process_response(response, type)
  json = JSON.parse(response.body)
  included = process_included_objects(json['included']) if json['included']
  obj = store_record(type, json['data']['id'].to_i, json['data'], included)

  obj
end
refresh!() click to toggle source
# File lib/artemis_api/client.rb, line 135
def refresh!
  old_refresh_token = @oauth_token.refresh_token

  @oauth_token = @oauth_token.refresh!

  if old_refresh_token != @oauth_token.refresh_token
    on_token_refreshed && on_token_refreshed.call(self, @oauth_token, old_refresh_token)
  end
  @oauth_token
rescue OAuth2::Error => err
  if on_token_failed
    on_token_failed.call(self, @oauth_token, err)
    @oauth_token
  else
    raise err
  end
end
remove_record(type, id) click to toggle source
# File lib/artemis_api/client.rb, line 127
def remove_record(type, id)
  @objects[type]&.delete(id.to_i)
end
set_oauth_token_from_parts(access_token:, refresh_token:, expires_at:) click to toggle source
# File lib/artemis_api/client.rb, line 51
def set_oauth_token_from_parts(access_token:, refresh_token:, expires_at:)
  if access_token && refresh_token && expires_at
    @access_token = access_token
    @refresh_token = refresh_token
    @expires_at = expires_at.to_i

    @oauth_token = OAuth2::AccessToken.from_hash(
                    oauth_client,
                    {access_token: @access_token,
                    refresh_token: @refresh_token,
                    expires_at: @expires_at})
  end
end
store_record(type, id, data, included = nil) click to toggle source
# File lib/artemis_api/client.rb, line 118
def store_record(type, id, data, included = nil)
  @objects[type] ||= {}
  @objects[type][id.to_i] = ArtemisApi::Model.instance_for(type, data, included, self)
end

Private Instance Methods

format_filters(filter_hash, query_hash) click to toggle source
# File lib/artemis_api/client.rb, line 210
def format_filters(filter_hash, query_hash)
  filter_hash.each do |k, v|
    if v.is_a?(Array)
      query_hash[:"filter[#{k}][]"] = v
    else
      query_hash[:"filter[#{k}]"] = v
    end
  end
end
format_pagination(page_hash, query_hash) click to toggle source
# File lib/artemis_api/client.rb, line 220
def format_pagination(page_hash, query_hash)
  page_hash.each do |k, v|
    query_hash[:"page[#{k}]"] = v
  end
end
process_array(response, type, records) click to toggle source
# File lib/artemis_api/client.rb, line 183
def process_array(response, type, records)
  json = JSON.parse(response.body)
  json['data'].each do |obj|
    record = store_record(type, obj['id'], obj)
    records << record
  end

  process_included_objects(json['included']) if json['included']

  records
end
process_included_objects(included_array) click to toggle source
# File lib/artemis_api/client.rb, line 195
def process_included_objects(included_array)
  included = {}
  included_array.each do |included_obj|
    type = included_obj['type']
    obj = store_record(type, included_obj['id'], included_obj)

    next unless obj

    included[type.to_sym] = [] unless included.key?(type.to_sym)
    included[type.to_sym].push(obj)
  end

  included
end