class AllscriptsUnityClient::JSONClientDriver

A ClientDriver that supports Unity’s JSON endpoints.

Constants

TOKEN_REGEX
UBIQUITY_JSON_ENDPOINT
UNITY_JSON_ENDPOINT

Attributes

connection[RW]
json_base_url[RW]
security_token[RW]

Public Class Methods

new(options) click to toggle source
# File lib/allscripts_unity_client/json_client_driver.rb, line 14
def initialize(options)
  super

  @connection = HTTPClient.new(
    proxy: @options.proxy,
    default_header: {'Content-Type' => 'application/json'}
  )

  set_http_client_ssl_config
  set_http_client_timeouts
end

Public Instance Methods

build_uri(request_location) click to toggle source
# File lib/allscripts_unity_client/json_client_driver.rb, line 43
def build_uri(request_location)
  endpoint = @options.use_ubiquity ? UBIQUITY_JSON_ENDPOINT : UNITY_JSON_ENDPOINT
  "#{@options.base_unity_url}#{[endpoint, request_location].join('/')}"
end
client_type() click to toggle source
# File lib/allscripts_unity_client/json_client_driver.rb, line 48
def client_type
  :json
end
get_security_token!(parameters = {}) click to toggle source

See Client#get_security_token!.

# File lib/allscripts_unity_client/json_client_driver.rb, line 97
def get_security_token!(parameters = {})
  username = parameters[:username] || @options.username
  password = parameters[:password] || @options.password
  appname = parameters[:appname] || @options.appname

  request_data = {
    'Username' => username,
    'Password' => password,
    'Appname' => appname
  }

  start_timer
  response = @connection.post(build_uri('GetToken'), MultiJson.dump(request_data.to_hash))
  end_timer

  log_get_security_token
  log_info("Response Status: #{response.status}")

  if response.status != 200 || TOKEN_REGEX.match(response.body).nil?
    raise make_get_security_token_error
  else
    raise_if_response_error(response.body)

    @security_token = response.body
  end
end
get_user_authentication(parameters = {}) click to toggle source

See Client#get_user_authentication.

# File lib/allscripts_unity_client/json_client_driver.rb, line 77
def get_user_authentication(parameters = {})
  response = magic({
                     action: 'GetUserAuthentication',
                     userid: parameters[:ehr_userid] || @options.ehr_userid,
                     parameter1: parameters[:ehr_password] || @options.ehr_password
                   })

  if response[:valid_user] == 'YES'
    @user_authentication = response
    log_info("allscripts_unity_client authentication attempt: success #{@options.base_unity_url}")
    return true
  elsif response[:valid_user] == 'NO'
    log_warn("allscripts_unity_client authentication attempt: failure #{@options.base_unity_url}")
    return false
  else
    raise StandardError.new('Unexpected response from the server')
  end
end
magic(parameters = {}) click to toggle source
# File lib/allscripts_unity_client/json_client_driver.rb, line 52
def magic(parameters = {})
  request = JSONUnityRequest.new(parameters, @options.timezone, @options.appname, @security_token, @options.raw_dates)
  request_hash = request.to_hash
  request_data = MultiJson.dump(request_hash)

  start_timer
  response = @connection.post(build_uri('MagicJson'), request_data)
  end_timer

  # NOTE: ClientDriver#log_magic uses ClientDriver#log_info, which
  # appends timing info (if end_timer has been called previously),
  # and then resets the timer.
  #
  # It would be nice if future work made this less stateful.
  log_magic(request)
  log_info("Response Status: #{response.status}")

  response = MultiJson.load(response.body)
  raise_if_response_error(response)

  response = JSONUnityResponse.new(response, @options.timezone)
  response.to_hash
end
retire_security_token!(parameters = {}) click to toggle source

See Client#retire_security_token!.

# File lib/allscripts_unity_client/json_client_driver.rb, line 125
def retire_security_token!(parameters = {})
  token = parameters[:token] || @security_token
  appname = parameters[:appname] || @options.appname

  request_data = {
    'Token' => token,
    'Appname' => appname
  }

  start_timer
  response = @connection.post(build_uri('RetireSecurityToken'), MultiJson.dump(request_data.to_hash))
  end_timer

  raise_if_response_error(response.body)
  log_retire_security_token

  @security_token = nil
  revoke_authentication
end
revoke_authentication() click to toggle source
# File lib/allscripts_unity_client/json_client_driver.rb, line 149
def revoke_authentication
  @user_authentication = nil
end
set_http_client_ssl_config() click to toggle source
# File lib/allscripts_unity_client/json_client_driver.rb, line 32
def set_http_client_ssl_config
  ssl_options = OpenSSL::SSL::OP_ALL
  ssl_options &= ~OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS if defined?(OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGMENTS)
  ssl_options |= OpenSSL::SSL::OP_NO_COMPRESSION if defined?(OpenSSL::SSL::OP_NO_COMPRESSION)
  ssl_options |= OpenSSL::SSL::OP_NO_SSLv2 if defined?(OpenSSL::SSL::OP_NO_SSLv2)
  ssl_options |= OpenSSL::SSL::OP_NO_SSLv3 if defined?(OpenSSL::SSL::OP_NO_SSLv3)

  @connection.ssl_config.options = ssl_options
  @connection.ssl_config.ciphers = "ALL:!aNULL:!eNULL:!SSLv2"
end
set_http_client_timeouts() click to toggle source
# File lib/allscripts_unity_client/json_client_driver.rb, line 26
def set_http_client_timeouts
  @connection.connect_timeout = @options.timeout || 90
  @connection.send_timeout = @options.timeout || 90
  @connection.receive_timeout = @options.timeout || 90
end
user_authenticated?() click to toggle source
# File lib/allscripts_unity_client/json_client_driver.rb, line 145
def user_authenticated?
  @user_authentication.present?
end

Private Instance Methods

raise_if_response_error(response) click to toggle source

@param [Array,String,nil] response

@return [nil]

@todo This method should be responsible creating an ‘APIError` not raising it. The sender should be responsible for raising the error so the stack trace starts in the method where the failure occured.

# File lib/allscripts_unity_client/json_client_driver.rb, line 163
def raise_if_response_error(response)
  if response.nil?
    raise APIError, 'Response was empty'
  elsif response.is_a?(Array) && !response[0].nil? && !response[0]['Error'].nil?
    raise APIError, response[0]['Error']
  elsif response.is_a?(String) && response.include?('error:')
    raise APIError, response
  end
end