def __validate_signature(self, signature, payload): signature_pairs = [pair.split("|") for pair in signature.split("&") if "|" in pair] matching_signature = self.__matching_signature(signature_pairs) payload_signature = Crypto.hmac_hash(self.config.private_key, payload) if not Crypto.secure_compare(payload_signature, matching_signature): raise InvalidSignatureError
def __validate_signature(self, signature, payload): signature_pairs = [ pair.split("|") for pair in signature.split("&") if "|" in pair ] matching_signature = self.__matching_signature(signature_pairs) payload_signature = Crypto.hmac_hash(self.config.private_key, payload) if not Crypto.secure_compare(payload_signature, matching_signature): raise InvalidSignatureError
def webhook(self, url, kind, sub, trans): trans_id = trans.uid_support if trans else str(uuid.uuid4()) transaction = { 'subscription_charged_successfully': { 'id': trans_id, 'status': 'settled' }, 'subscription_charged_unsuccessfully': { 'id': trans_id, 'status': 'processor_declined' } } processor_response = { 'subscription_charged_successfully': { 'text': 'Approved', 'code': '1000' }, 'subscription_charged_unsuccessfully': { 'text': 'Invalid Secure Payment Data', 'code': '2078' } } data = { 'kind': kind, 'merchant_account_id': self.merchant, 'sub': sub, 'plan_id': sub.seller_product.public_id, 'product': products[sub.seller_product.public_id], 'now': datetime.today(), 'timestamp': datetime.today().strftime('%Y-%m-%dT%H:%M:%SZ'), # Braintree doesn't assume months are 30 days long. 'paid': datetime.today() + timedelta(days=29), 'next': datetime.today() + timedelta(days=30), 'transaction': transaction.get(kind), 'processor_response': processor_response.get(kind) } xml_blob = webhooks.sub if data['transaction'] else webhooks.no_trans xml_formatted = xml_blob.format(**data) payload = base64.encodestring(xml_formatted) res = requests.post(url, data={ 'bt_signature': self.public + '|' + Crypto.sha1_hmac_hash(self.private, payload), 'bt_payload': payload }) res.raise_for_status() if res.status_code != 200: raise CommandError( 'Server did not return a 200 response, got: {}'.format( res.status_code))
def webhook(self, url, kind, sub, trans): trans_id = trans.uid_support if trans else str(uuid.uuid4()) transaction = { 'subscription_charged_successfully': { 'id': trans_id, 'status': 'settled' }, 'subscription_charged_unsuccessfully': { 'id': trans_id, 'status': 'processor_declined' } } processor_response = { 'subscription_charged_successfully': { 'text': 'Approved', 'code': '1000' }, 'subscription_charged_unsuccessfully': { 'text': 'Invalid Secure Payment Data', 'code': '2078' } } data = { 'kind': kind, 'merchant_account_id': self.merchant, 'sub': sub, 'plan_id': sub.seller_product.public_id, 'product': products[sub.seller_product.public_id], 'now': datetime.today(), 'timestamp': datetime.today().strftime('%Y-%m-%dT%H:%M:%SZ'), # Braintree doesn't assume months are 30 days long. 'paid': datetime.today() + timedelta(days=29), 'next': datetime.today() + timedelta(days=30), 'transaction': transaction.get(kind), 'processor_response': processor_response.get(kind) } xml_blob = webhooks.sub if data['transaction'] else webhooks.no_trans xml_formatted = xml_blob.format(**data) payload = base64.encodestring(xml_formatted) res = requests.post(url, data={ 'bt_signature': self.public + '|' + Crypto.sha1_hmac_hash(self.private, payload), 'bt_payload': payload }) res.raise_for_status() if res.status_code != 200: raise CommandError( 'Server did not return a 200 response, got: {}' .format(res.status_code) )
def tr_data(self, data, redirect_url): data = self.__flatten_dictionary(data) date_string = datetime.utcnow().strftime("%Y%m%d%H%M%S") data["time"] = date_string data["redirect_url"] = redirect_url data["public_key"] = self.config.public_key data["api_version"] = self.config.api_version() tr_content = urllib.urlencode(data) tr_hash = Crypto.hmac_hash(self.config.private_key, tr_content) return tr_hash + "|" + tr_content
def tr_data(data, redirect_url): data = TransparentRedirect.__flatten_dictionary(data) date_string = datetime.utcnow().strftime("%Y%m%d%H%M%S") data["time"] = date_string data["redirect_url"] = redirect_url data["public_key"] = Configuration.public_key data["api_version"] = Configuration.api_version() tr_content = urllib.urlencode(data) tr_hash = Crypto.hmac_hash(Configuration.private_key, tr_content) return tr_hash + "|" + tr_content
def _is_valid_tr_query_string(self, query_string): content, hash = query_string.split("&hash=") return hash == Crypto.hmac_hash(self.config.private_key, content)
def verify(self, challenge): digest = Crypto.hmac_hash(self.config.private_key, challenge) return "%s|%s" % (self.config.public_key, digest)
def verify(self, challenge): if not re.match("^[a-f0-9]{20,32}$", challenge): raise InvalidChallengeError( "challenge contains non-hex characters") digest = Crypto.sha1_hmac_hash(self.config.private_key, challenge) return "%s|%s" % (self.config.public_key, digest)
def is_valid_tr_query_string(query_string): content, hash = query_string.split("&hash=") return hash == Crypto.hmac_hash(Configuration.private_key, content)
def __payload_matches(self, signature, payload): payload_signature = Crypto.sha1_hmac_hash(self.config.private_key, payload) return Crypto.secure_compare(payload_signature, signature)
def verify(self, challenge): if not re.match("^[a-f0-9]{20,32}$", challenge): raise InvalidChallengeError("challenge contains non-hex characters") digest = Crypto.sha1_hmac_hash(self.config.private_key, challenge) return "%s|%s" % (self.config.public_key, digest)
def sample_notification(self, kind, id, source_merchant_id=None): payload = encodebytes(self.__sample_xml(kind, id, source_merchant_id)) hmac_payload = Crypto.sha1_hmac_hash(self.gateway.config.private_key, payload) signature = "%s|%s" % (self.gateway.config.public_key, hmac_payload) return {'bt_signature': signature, 'bt_payload': payload}
def sample_notification(self, kind, id): payload = base64.encodestring(self.__sample_xml(kind, id)) hmac_payload = Crypto.sha1_hmac_hash(self.gateway.config.private_key, payload) signature = "%s|%s" % (self.gateway.config.public_key, hmac_payload) return signature, payload
def _is_valid_tr_query_string(self, query_string): content, hash = query_string.split("&hash=") return hash == Crypto.sha1_hmac_hash(self.config.private_key, content)
def sample_notification(self, kind, id): payload = base64.encodestring(self.__sample_xml(kind, id)) hmac_payload = Crypto.sha1_hmac_hash(self.gateway.config.private_key, payload) signature = "%s|%s" % (self.gateway.config.public_key, hmac_payload) return {'bt_signature': signature, 'bt_payload': payload}