<s> import re <EOL> import base64 <EOL> import sys <EOL> from braintree . exceptions . invalid_signature_error import InvalidSignatureError <EOL> from braintree . exceptions . invalid_challenge_error import InvalidChallengeError <EOL> from braintree . util . crypto import Crypto <EOL> from braintree . util . xml_util import XmlUtil <EOL> from braintree . webhook_notification import WebhookNotification <EOL> if sys . version_info [ <NUM_LIT:0> ] == <NUM_LIT:2> : <EOL> text_type = unicode <EOL> else : <EOL> text_type = str <EOL> class WebhookNotificationGateway ( object ) : <EOL> def __init__ ( self , gateway ) : <EOL> self . gateway = gateway <EOL> self . config = gateway . config <EOL> def parse ( self , signature , payload ) : <EOL> if isinstance ( payload , text_type ) : <EOL> payload = payload . encode ( '<STR_LIT:ascii>' ) <EOL> if re . search ( b"<STR_LIT>" , payload ) : <EOL> raise InvalidSignatureError ( "<STR_LIT>" ) <EOL> self . __validate_signature ( signature , payload ) <EOL> attributes = XmlUtil . dict_from_xml ( base64 . decodestring ( payload ) ) <EOL> return WebhookNotification ( self . gateway , attributes [ '<STR_LIT>' ] ) <EOL> def verify ( self , challenge ) : <EOL> if not re . match ( "<STR_LIT>" , challenge ) : <EOL> raise InvalidChallengeError ( "<STR_LIT>" ) <EOL> digest = Crypto . sha1_hmac_hash ( self . config . private_key , challenge ) <EOL> return "<STR_LIT>" % ( self . config . public_key , digest ) <EOL> def __matching_signature ( self , signature_pairs ) : <EOL> for public_key , signature in signature_pairs : <EOL> if public_key == self . config . public_key : <EOL> return signature <EOL> return None <EOL> def __validate_signature ( self , signature_string , payload ) : <EOL> signature_pairs = [ pair . split ( "<STR_LIT:|>" ) for pair in signature_string . split ( "<STR_LIT:&>" ) if "<STR_LIT:|>" in pair ] <EOL> signature = self . __matching_signature ( signature_pairs ) <EOL> if not signature : <EOL> raise InvalidSignatureError ( "<STR_LIT>" ) <EOL> if not any ( self . __payload_matches ( signature , p ) for p in [ payload , payload + b"<STR_LIT:\n>" ] ) : <EOL> raise InvalidSignatureError ( "<STR_LIT>" ) <EOL> def __payload_matches ( self , signature , payload ) : <EOL> payload_signature = Crypto . sha1_hmac_hash ( self . config . private_key , payload ) <EOL> return Crypto . secure_compare ( payload_signature , signature ) </s>
