class HealthCards::HealthCard
A HealthCard
which implements the credential claims specified by smarthealth.cards/
Constants
- FHIR_REF_REGEX
Attributes
Public Class Methods
Compress an arbitrary payload, useful for debugging @param payload [Object] Any object that responds to to_s
@return A compressed version of that payload parameter
# File lib/health_cards/health_card.rb, line 77 def compress_payload(payload) Zlib::Deflate.new(nil, -Zlib::MAX_WBITS).deflate(payload.to_s, Zlib::FINISH) end
Decompress an arbitrary payload, useful for debugging @param payload [String] compressed payload @return [Hash] Hash built from JSON contents of payload
# File lib/health_cards/health_card.rb, line 69 def decompress_payload(payload) inf = Zlib::Inflate.new(-Zlib::MAX_WBITS).inflate(payload) JSON.parse(inf) end
Sets/Gets the fhir version that will be passed through to the credential created by an instnace of this HealthCard
(sub)class @param ver [String] FHIR Version supported by this HealthCard
(sub)class. Leaving this param out will only return the current value value (used as a getter) @return [String] Current FHIR version supported
# File lib/health_cards/health_card.rb, line 87 def fhir_version(ver = nil) @fhir_version ||= ver unless ver.nil? @fhir_version end
Creates a HealthCard
from a JWS
@param jws [String] the JWS
string @param public_key [HealthCards::PublicKey] the public key associated with the JWS
@param key [HealthCards::PrivateKey] the private key associated with the JWS
@return [HealthCards::HealthCard]
# File lib/health_cards/health_card.rb, line 48 def from_jws(jws, public_key: nil, key: nil) jws = JWS.from_jws(jws, public_key: public_key, key: key) from_payload(jws.payload) end
Create a HealthCard
from a compressed payload @param payload [String] @return [HealthCards::HealthCard]
# File lib/health_cards/health_card.rb, line 56 def from_payload(payload) json = decompress_payload(payload) bundle_hash = json.dig('vc', 'credentialSubject', 'fhirBundle') raise HealthCards::InvalidCredentialError unless bundle_hash bundle = FHIR::Bundle.new(bundle_hash) new(issuer: json['iss'], bundle: bundle) end
Create a HealthCard
@param bundle [FHIR::Bundle] VerifiableCredential containing a fhir bundle @param issuer [String] The url from the Issuer
of the HealthCard
# File lib/health_cards/health_card.rb, line 103 def initialize(bundle:, issuer: nil) raise InvalidPayloadError unless bundle.is_a?(FHIR::Bundle) # && bundle.valid? @issuer = issuer @bundle = bundle end
Public Instance Methods
Processes the bundle according to smarthealth.cards/#health-cards-are-small and returns a Hash with equivalent values @return [Hash] A hash with the same content as the FHIR::Bundle, processed accoding to SMART Health Cards framework and any constraints created by subclasses
# File lib/health_cards/health_card.rb, line 143 def strip_fhir_bundle return [] unless bundle.entry new_bundle = duplicate_bundle url_map = redefine_uris(new_bundle) new_bundle.entry.each do |entry| entry.each_element do |value, metadata, _| case metadata['type'] when 'Reference' value.reference = process_reference(url_map, entry, value) when 'Resource' value.meta = nil unless value.meta&.security end handle_allowable(value) handle_disallowable(value) end end new_bundle end
A Hash matching the VC structure specified by smarthealth.cards/#health-cards-are-encoded-as-compact-serialization-json-web-signatures-jws @return [Hash]
# File lib/health_cards/health_card.rb, line 112 def to_hash { iss: issuer, nbf: Time.now.to_i, vc: { type: self.class.types, credentialSubject: { fhirVersion: self.class.fhir_version, fhirBundle: strip_fhir_bundle.to_hash } } } end
A minified JSON string matching the VC structure specified by smarthealth.cards/#health-cards-are-encoded-as-compact-serialization-json-web-signatures-jws @return [String] JSON string
# File lib/health_cards/health_card.rb, line 135 def to_json(*_args) to_hash.to_json end
A compressed version of the FHIR::Bundle based on the SMART Health Cards frame work and any other constraints defined by a subclass @return String compressed payload
# File lib/health_cards/health_card.rb, line 129 def to_s HealthCard.compress_payload(to_json) end
Private Instance Methods
# File lib/health_cards/health_card.rb, line 168 def duplicate_bundle FHIR::Bundle.new(bundle.to_hash) end
# File lib/health_cards/health_card.rb, line 185 def process_reference(url_map, entry, ref) entry_url = URI(url_map.key(entry.fullUrl)) ref_url = ref.reference return unless ref_url return url_map[ref_url] if url_map[ref_url] fhir_base_url = FHIR_REF_REGEX.match(entry_url.to_s)[1] full_url = URI.join(fhir_base_url, ref_url).to_s new_url = url_map[full_url] raise InvalidBundleReferenceError, full_url unless new_url new_url end
# File lib/health_cards/health_card.rb, line 172 def redefine_uris(bundle) url_map = {} resource_count = 0 bundle.entry.each do |entry| old_url = entry.fullUrl new_url = "resource:#{resource_count}" url_map[old_url] = new_url entry.fullUrl = new_url resource_count += 1 end url_map end