Move Config attributes to a separate class

This allows to modify the target URL, the environment or any attribute
for a specific TPE or use default config.
master
Guillaume DOTT 2014-04-09 14:24:13 +02:00
parent fd565f3e6f
commit e77eb75f07
5 changed files with 76 additions and 57 deletions

View File

@ -16,7 +16,7 @@ It's a Ruby on Rails port of the connexion kits published by the bank.
### in an initializer (`config/initializers/paiement_cic.rb`) : ### in an initializer (`config/initializers/paiement_cic.rb`) :
```ruby ```ruby
PaiementCic.configure do |config| PaiementCic.default_config.configure do |config|
# here the hmac key calculated with the js calculator given by CIC # here the hmac key calculated with the js calculator given by CIC
config.hmac_key = "########################################" config.hmac_key = "########################################"
# Here the TPE number # Here the TPE number
@ -32,19 +32,20 @@ PaiementCic.configure do |config|
end end
``` ```
You can also specify `hmac_key`, `tpe` and `societe` when initializing `PaiementCic::TPE` and with `paiement_cic_hidden_fields` helper by passing an hash. You can also specify different attributes when initializing `PaiementCic::TPE` and with `paiement_cic_hidden_fields` helper by passing an hash.
```ruby ```ruby
{ {
hmac_key: "########################################", hmac_key: "########################################",
tpe: "#######", tpe: "#######",
societe: "xxxxxxxxxxxxx", societe: "xxxxxxxxxxxxx",
env: :test,
} }
``` ```
### in the payment by card view : ### in the payment by card view :
``` ```
- form_tag PaiementCic.target_url do - form_tag PaiementCic.default_config.target_url do
= paiement_cic_hidden_fields(@order.reference, @order.amount, mail: 'email@example.com', url_retour: edit_order_url(order), url_retour_ok: bank_ok_order_transaction_url(order_transaction), url_retour_err: bank_err_order_transaction_url(order_transaction)) = paiement_cic_hidden_fields(@order.reference, @order.amount, mail: 'email@example.com', url_retour: edit_order_url(order), url_retour_ok: bank_ok_order_transaction_url(order_transaction), url_retour_err: bank_err_order_transaction_url(order_transaction))
= submit_tag "Accéder au site de la banque", :style => "font-weight: bold;" = submit_tag "Accéder au site de la banque", :style => "font-weight: bold;"
= image_tag "reassuring_pictograms.jpg", :alt => "Pictogrammes rassurants", :style => "width: 157px;" = image_tag "reassuring_pictograms.jpg", :alt => "Pictogrammes rassurants", :style => "width: 157px;"

View File

@ -1,3 +1,4 @@
require 'paiement_cic/config'
require 'paiement_cic/tpe' require 'paiement_cic/tpe'
require 'paiement_cic/railtie' if defined?(Rails) require 'paiement_cic/railtie' if defined?(Rails)
@ -31,50 +32,23 @@ module PaiementCic
DEFAULT_BANK = :cm DEFAULT_BANK = :cm
DEFAULT_ENV = :test DEFAULT_ENV = :test
class << self def self.default_config
attr_accessor :hmac_key, :tpe, :societe @@default_config ||= PaiementCic::Config.new
attr_writer :target_url end
def configure(&block) def self.hmac_sha1(key, data)
yield(self) if block_given? length = 64
if (key.length > length)
key = [Digest::SHA1.hexdigest(key)].pack("H*")
end end
def bank key = key.ljust(length, 0.chr)
@bank || DEFAULT_BANK
end
def bank=(value) k_ipad = key ^ ''.ljust(length, 54.chr)
raise UnknownBankError unless END_POINTS.keys.include?(value.to_sym) k_opad = key ^ ''.ljust(length, 92.chr)
@bank = value
end
def env Digest::SHA1.hexdigest(k_opad + [Digest::SHA1.hexdigest(k_ipad + data)].pack("H*"))
@env || DEFAULT_ENV
end
def env=(value)
raise UnknownEnvError unless END_POINTS.first.last.include?(value.to_sym)
@env = value
end
def target_url
@target_url || END_POINTS[self.bank][self.env]
end
def hmac_sha1(key, data)
length = 64
if (key.length > length)
key = [Digest::SHA1.hexdigest(key)].pack("H*")
end
key = key.ljust(length, 0.chr)
k_ipad = key ^ ''.ljust(length, 54.chr)
k_opad = key ^ ''.ljust(length, 92.chr)
Digest::SHA1.hexdigest(k_opad + [Digest::SHA1.hexdigest(k_ipad + data)].pack("H*"))
end
end end
class UnknownBankError < Exception; end class UnknownBankError < Exception; end

View File

@ -0,0 +1,44 @@
module PaiementCic
class Config
attr_accessor :hmac_key, :tpe, :societe
attr_writer :target_url
def initialize(attributes = {}, &block)
if block_given?
configure(&block)
else
attributes.each do |name, value|
setter = "#{name}="
next unless respond_to?(setter)
send(setter, value)
end
end
end
def configure(&block)
yield self
end
def bank
@bank || DEFAULT_BANK
end
def bank=(value)
raise UnknownBankError unless END_POINTS.keys.include?(value.to_sym)
@bank = value
end
def env
@env || DEFAULT_ENV
end
def env=(value)
raise UnknownEnvError unless END_POINTS.first.last.include?(value.to_sym)
@env = value
end
def target_url
@target_url || END_POINTS[self.bank][self.env]
end
end
end

View File

@ -1,9 +1,9 @@
module PaiementCic::FormHelper module PaiementCic::FormHelper
def paiement_cic_hidden_fields(reference, price, options = {}) def paiement_cic_hidden_fields(reference, price, options = {})
oMac = PaiementCic::TPE.new(options) oMac = PaiementCic::TPE.new(options)
oa = oMac.config(reference, price, options) oa = oMac.attributes(reference, price, options)
chaineMAC = oMac.computeHMACSHA1(oa.values.join('*')) chaineMAC = oMac.compute_hmac_sha1(oa.values.join('*'))
url_retour = options[:url_retour] url_retour = options[:url_retour]
url_retour_ok = options[:url_retour_ok] url_retour_ok = options[:url_retour_ok]

View File

@ -1,23 +1,22 @@
module PaiementCic module PaiementCic
class TPE class TPE
attr_accessor :hmac_key, :tpe, :societe attr_accessor :config
def initialize(options = {}) def initialize(options = nil)
self.hmac_key = options[:hmac_key] || PaiementCic.hmac_key self.config = options.nil? ? PaiementCic.default_config :
self.tpe = options[:tpe] || PaiementCic.tpe PaiementCic::Config.new(options)
self.societe = options[:societe] || PaiementCic.societe
end end
def config(reference, amount_in_cents, options = {}) def attributes(reference, amount_in_cents, options = {})
{ {
'TPE' => tpe, 'TPE' => config.tpe,
'date' => Time.now.strftime(PaiementCic::DATE_FORMAT), 'date' => Time.now.strftime(PaiementCic::DATE_FORMAT),
'montant' => ("%.2f" % amount_in_cents) + "EUR", 'montant' => ("%.2f" % amount_in_cents) + "EUR",
'reference' => reference.to_s, 'reference' => reference.to_s,
'texte-libre' => '', 'texte-libre' => '',
'version' => PaiementCic::API_VERSION, 'version' => PaiementCic::API_VERSION,
'lgue' => 'FR', 'lgue' => 'FR',
'societe' => societe, 'societe' => config.societe,
'mail' => options[:mail].to_s, 'mail' => options[:mail].to_s,
'nbrech' => options[:nbrech].to_s, 'nbrech' => options[:nbrech].to_s,
'dateech1' => options[:dateech1].to_s, 'dateech1' => options[:dateech1].to_s,
@ -34,7 +33,7 @@ module PaiementCic
def mac_string params def mac_string params
[ [
tpe, params["date"], params['montant'], params['reference'], params['texte-libre'], config.tpe, params['date'], params['montant'], params['reference'], params['texte-libre'],
PaiementCic::API_VERSION, params['code-retour'], params['cvx'], params['vld'], params['brand'], PaiementCic::API_VERSION, params['code-retour'], params['cvx'], params['vld'], params['brand'],
params['status3ds'], params['numauto'], params['motifrefus'], params['originecb'], params['status3ds'], params['numauto'], params['motifrefus'], params['originecb'],
params['bincb'], params['hpancb'], params['ipclient'], params['originetr'], params['bincb'], params['hpancb'], params['ipclient'], params['originetr'],
@ -48,20 +47,21 @@ module PaiementCic
# Check if the HMAC matches the HMAC of the data string # Check if the HMAC matches the HMAC of the data string
def valid_hmac?(mac_string, sent_mac) def valid_hmac?(mac_string, sent_mac)
computeHMACSHA1(mac_string) == sent_mac.downcase compute_hmac_sha1(mac_string) == sent_mac.downcase
end end
# Return the HMAC for a data string # Return the HMAC for a data string
def computeHMACSHA1(data) def compute_hmac_sha1(data)
PaiementCic.hmac_sha1(usable_key, data).downcase PaiementCic.hmac_sha1(usable_key, data).downcase
end end
alias_method :computeHMACSHA1, :compute_hmac_sha1
private private
# Return the key to be used in the hmac function # Return the key to be used in the hmac function
def usable_key def usable_key
hex_string_key = hmac_key[0..37] hex_string_key = config.hmac_key[0..37]
hex_final = hmac_key[38..40] + "00"; hex_final = config.hmac_key[38..40] + "00";
cca0 = hex_final[0].ord cca0 = hex_final[0].ord