Class: Caren::Api
- Inherits:
-
Object
- Object
- Caren::Api
- Defined in:
- lib/caren/caren.rb
Constant Summary collapse
- DIGEST_ALGORITHMS =
[OpenSSL::Digest::SHA256.new, OpenSSL::Digest::SHA1.new]
Class Attribute Summary collapse
-
.session ⇒ Object
Returns the value of attribute session.
Instance Attribute Summary collapse
-
#caren_public_key ⇒ Object
The user_agent is an optional identifier.
-
#private_key ⇒ Object
The user_agent is an optional identifier.
-
#url ⇒ Object
The user_agent is an optional identifier.
-
#user_agent ⇒ Object
The user_agent is an optional identifier.
Class Method Summary collapse
-
.generate_private_key(size = 2048) ⇒ Object
Generate a new private key.
-
.key_from_path(path) ⇒ Object
Read a file and create key from string.
-
.key_from_string(string) ⇒ Object
Create key from string.
-
.supported_incoming_objects ⇒ Object
These types of Caren objects are supported by the Caren::Api.incoming method.
-
.supported_incoming_single_objects ⇒ Object
These types of Caren objects are supported by the Caren::Api.incoming method.
Instance Method Summary collapse
-
#check_signature(response) ⇒ Object
Check the signature of the response from rest-client.
- #create_photo_signature(url_shortcut, external_or_caren_id, private_key = self.private_key) ⇒ Object
- #delete(path) ⇒ Object
- #get(path) ⇒ Object
-
#incoming(xml, signature, timestamp) ⇒ Object
Pass an XML string to be handled.
-
#initialize(private_key, url, caren_public_key = nil) ⇒ Api
constructor
Initialize new API session.
- #parse(xml) ⇒ Object
- #parse_object(xml) ⇒ Object
- #post(path, xml) ⇒ Object
- #put(path, xml) ⇒ Object
-
#sign(timestamp, path = nil, string = nil, private_key = self.private_key) ⇒ Object
Sign your string and timestamp using private key Timestamp is UNIX timestamp seconds since 1970.
- #sign_string(provided_string, key = self.private_key) ⇒ Object
-
#url_for(path) ⇒ Object
URL from path using session base url.
-
#verify_photo_signature(signature, url_shortcut, external_id, public_key = self.caren_public_key) ⇒ Object
Verify photo url signature using the caren public key.
-
#verify_signature(signature, timestamp, path, string = nil, public_key = self.caren_public_key) ⇒ Object
Verify the signature using the caren public key.
- #verify_string(provided_string, expected_string, key = self.caren_public_key, options = {}) ⇒ Object
Constructor Details
#initialize(private_key, url, caren_public_key = nil) ⇒ Api
Initialize new API session. Specify your private key to sign outgoing messages and your care provider url. Optionally you can pass the caren public key used to verify incoming requests.
37 38 39 40 41 |
# File 'lib/caren/caren.rb', line 37 def initialize private_key, url, caren_public_key=nil self.url = url self.private_key = private_key.is_a?(String) ? Caren::Api.key_from_string(private_key) : private_key self.caren_public_key = caren_public_key || Caren::Api.key_from_path("#{File.dirname(__FILE__)}/../../certs/caren-api.pub") end |
Class Attribute Details
.session ⇒ Object
Returns the value of attribute session.
29 30 31 |
# File 'lib/caren/caren.rb', line 29 def session @session end |
Instance Attribute Details
#caren_public_key ⇒ Object
The user_agent is an optional identifier
33 34 35 |
# File 'lib/caren/caren.rb', line 33 def caren_public_key @caren_public_key end |
#private_key ⇒ Object
The user_agent is an optional identifier
33 34 35 |
# File 'lib/caren/caren.rb', line 33 def private_key @private_key end |
#url ⇒ Object
The user_agent is an optional identifier
33 34 35 |
# File 'lib/caren/caren.rb', line 33 def url @url end |
#user_agent ⇒ Object
The user_agent is an optional identifier
33 34 35 |
# File 'lib/caren/caren.rb', line 33 def user_agent @user_agent end |
Class Method Details
.generate_private_key(size = 2048) ⇒ Object
Generate a new private key
54 55 56 |
# File 'lib/caren/caren.rb', line 54 def self.generate_private_key size=2048 OpenSSL::PKey::RSA.generate( size ) end |
.key_from_path(path) ⇒ Object
Read a file and create key from string
49 50 51 |
# File 'lib/caren/caren.rb', line 49 def self.key_from_path path self.key_from_string( File.read(path) ) end |
.key_from_string(string) ⇒ Object
Create key from string
44 45 46 |
# File 'lib/caren/caren.rb', line 44 def self.key_from_string string OpenSSL::PKey::RSA.new(string) end |
.supported_incoming_objects ⇒ Object
These types of Caren objects are supported by the Caren::Api.incoming method
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/caren/caren.rb', line 120 def self.supported_incoming_objects { :links => Caren::Link, :external_messages => Caren::ExternalMessage, :chat_sessions => Caren::ChatSession, :chat_session_messages => Caren::ChatSessionMessage, :care_providers => Caren::CareProvider, :dossier_entries => Caren::Dossier::DossierEntry, :billable_categories => Caren::Store::BillableCategory, :billables => Caren::Store::Billable, :invoices => Caren::Store::Invoice, :payments => Caren::Store::Payment, :line_items => Caren::Store::LineItem, :accounts => Caren::Store::Account, :account_entries => Caren::Store::AccountEntry } end |
.supported_incoming_single_objects ⇒ Object
These types of Caren objects are supported by the Caren::Api.incoming method
138 139 140 141 142 143 144 |
# File 'lib/caren/caren.rb', line 138 def self.supported_incoming_single_objects singles = {} self.supported_incoming_objects.each do |object,klass| singles[ klass.node_root ] = klass end return singles end |
Instance Method Details
#check_signature(response) ⇒ Object
Check the signature of the response from rest-client
186 187 188 189 |
# File 'lib/caren/caren.rb', line 186 def check_signature response return response if self.verify_signature( response.headers[:signature], response.headers[:timestamp], nil, response ) raise Caren::Exceptions::SignatureMismatch.new end |
#create_photo_signature(url_shortcut, external_or_caren_id, private_key = self.private_key) ⇒ Object
197 198 199 |
# File 'lib/caren/caren.rb', line 197 def create_photo_signature url_shortcut, external_or_caren_id, private_key=self.private_key return sign_string(url_shortcut.to_s + external_or_caren_id.to_s, private_key) end |
#delete(path) ⇒ Object
91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/caren/caren.rb', line 91 def delete path begin = DateTime.now.to_i response = RestClient.delete url_for(path), :content_type => :xml, :accept => :xml, :timestamp => , :signature => sign(,path), :user_agent => user_agent return check_signature(response) rescue RestClient::Exception => e handle_error(e.response,e.http_code) end end |
#get(path) ⇒ Object
105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/caren/caren.rb', line 105 def get path begin = DateTime.now.to_i response = RestClient.get url_for(path), :content_type => :xml, :accept => :xml, :timestamp => , :signature => sign(,path), :user_agent => user_agent return check_signature(response) rescue RestClient::Exception => e handle_error(e.response,e.http_code) end end |
#incoming(xml, signature, timestamp) ⇒ Object
Pass an XML string to be handled. Only a valid caren_objects xml hash will be parsed.
147 148 149 150 151 152 153 |
# File 'lib/caren/caren.rb', line 147 def incoming xml, signature, if self.verify_signature(signature,, xml) return parse(xml) else raise Caren::Exceptions::SignatureMismatch.new end end |
#parse(xml) ⇒ Object
155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/caren/caren.rb', line 155 def parse xml objects = [] hash = Hash.from_xml(xml) if hash["caren_objects"] hash = hash["caren_objects"] end Caren::Api.supported_incoming_objects.each do |key,klass| objects << (hash[key]||hash[key.to_s]||[]).map{ |h| klass.init_dependent_objects(klass.new(h,xml)) } end return objects.flatten end |
#parse_object(xml) ⇒ Object
167 168 169 170 171 172 173 174 175 176 |
# File 'lib/caren/caren.rb', line 167 def parse_object xml hash = Hash.from_xml(xml) #todo: rewrite so we lookup the xml tag in the supported_incoming_single_objects hash, faster :) Caren::Api.supported_incoming_single_objects.each do |key, klass| object = hash[key] || hash[key.to_s] if object return klass.init_dependent_objects(klass.new(object,xml)) end end end |
#post(path, xml) ⇒ Object
77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/caren/caren.rb', line 77 def post path, xml begin = DateTime.now.to_i response = RestClient.post url_for(path), xml, :content_type => :xml, :accept => :xml, :timestamp => , :signature => sign(,path,xml), :user_agent => user_agent return check_signature(response) rescue RestClient::Exception => e handle_error(e.response,e.http_code) end end |
#put(path, xml) ⇒ Object
63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/caren/caren.rb', line 63 def put path, xml begin = DateTime.now.to_i response = RestClient.put url_for(path), xml, :content_type => :xml, :accept => :xml, :timestamp => , :signature => sign(,path,xml), :user_agent => user_agent return check_signature(response) rescue RestClient::Exception => e handle_error(e.response,e.http_code) end end |
#sign(timestamp, path = nil, string = nil, private_key = self.private_key) ⇒ Object
Sign your string and timestamp using private key Timestamp is UNIX timestamp seconds since 1970
180 181 182 183 |
# File 'lib/caren/caren.rb', line 180 def sign , path=nil, string=nil, private_key=self.private_key path = URI.parse(path).path if path return sign_string("#{path}#{string}#{}",private_key) end |
#sign_string(provided_string, key = self.private_key) ⇒ Object
207 208 209 210 |
# File 'lib/caren/caren.rb', line 207 def sign_string provided_string, key=self.private_key digest = OpenSSL::PKey::RSA.new(key).sign( DIGEST_ALGORITHMS.first, provided_string.strip ) return CGI.escape(Base64.encode64(digest)) end |
#url_for(path) ⇒ Object
URL from path using session base url
59 60 61 |
# File 'lib/caren/caren.rb', line 59 def url_for path "#{self.url}#{path}" end |
#verify_photo_signature(signature, url_shortcut, external_id, public_key = self.caren_public_key) ⇒ Object
Verify photo url signature using the caren public key
202 203 204 205 |
# File 'lib/caren/caren.rb', line 202 def verify_photo_signature signature, url_shortcut, external_id, public_key=self.caren_public_key return false unless public_key verify_string(signature, url_shortcut.to_s + external_id.to_s, public_key) end |
#verify_signature(signature, timestamp, path, string = nil, public_key = self.caren_public_key) ⇒ Object
Verify the signature using the caren public key
192 193 194 195 |
# File 'lib/caren/caren.rb', line 192 def verify_signature signature, , path, string=nil, public_key=self.caren_public_key return false unless public_key verify_string(signature, "#{path}#{string}#{}", public_key) end |
#verify_string(provided_string, expected_string, key = self.caren_public_key, options = {}) ⇒ Object
212 213 214 215 216 217 218 219 |
# File 'lib/caren/caren.rb', line 212 def verify_string provided_string, expected_string, key=self.caren_public_key, ={} if [:skip_cgi_unescape] provided_string = Base64.decode64(provided_string.to_s) else provided_string = Base64.decode64(CGI.unescape(provided_string.to_s)) end DIGEST_ALGORITHMS.map{ |algorithm| key.verify( algorithm, provided_string, expected_string.strip ) }.any? end |