Skip to content
This repository has been archived by the owner on May 10, 2024. It is now read-only.

Commit

Permalink
make everything static
Browse files Browse the repository at this point in the history
  • Loading branch information
Invincibear committed Jan 23, 2024
1 parent e2aed61 commit 8612db1
Showing 1 changed file with 20 additions and 25 deletions.
45 changes: 20 additions & 25 deletions src/Notification/PaddleSignature.py
Original file line number Diff line number Diff line change
@@ -1,62 +1,57 @@
from src import log
from hmac import HMAC, compare_digest, new as hmac_new
from hashlib import sha256
from src import log
from src.Notification.Secret import Secret
from hmac import HMAC, compare_digest, new as hmac_new
from hashlib import sha256


class PaddleSignature:
HEADER: str = 'Paddle-Signature'
TIMESTAMP: str = 'ts'
HASH: str = 'h1'
HASH_ALGORITHM: str = sha256
ENCODING: str = 'utf-8'

def __init__(self):
"""
Verifies the integrity of a Paddle signature
"""


def parse_headers_for_paddle_signature(self, headers) -> str:
"""
TODO
:param headers:
:return:
"""
pass
@staticmethod
def HEADER(self): # noqa N802
return 'Paddle-Signature'


def parse_paddle_signature_header(self, signature_header: str) -> tuple:
@staticmethod
def parse(signature_header: str) -> tuple:
"""
Parse the Paddle-Signature header to extract the timestamp and signature
@param signature_header: The Paddle-Signature key=value from the webhook event's headers
@return: A tuple containing (timestamp, signature)
"""
timestamp, signature = signature_header.split(";")
return timestamp.lstrip(f"{self.TIMESTAMP}="), signature.lstrip(f"{self.HASH}=")
return timestamp.lstrip(f"ts="), signature.lstrip(f"h1=")


def calculate_hmac(self, secret_key: str, data: bytes) -> HMAC:
return hmac_new(secret_key.encode(self.ENCODING), data, self.HASH_ALGORITHM)
@staticmethod
def calculate_hmac(secret_key: str, data: bytes) -> HMAC:
return hmac_new(secret_key.encode('utf-8'), data, sha256)


def verify(self, signature_header: str, raw_body: str, secret_key: str) -> bool:
@staticmethod
def verify(signature_header: str, raw_body: str, secret_key: Secret) -> bool:
"""
https://developer.paddle.com/webhooks/signature-verification
Performs an integrity check on a Paddle webhook's signature
@param signature_header: The Paddle-Signature header
@param raw_body: Raw body of the webhook request
@param secret_key: Our Paddle secret key
@param secret_key: Your Paddle secret key: https://developer.paddle.com/webhooks/signature-verification#get-secret-key
@return: True on verification success, False on verification failure
"""
log.info(f"Verifying Paddle signature integrity")

timestamp, signature = self.parse_paddle_signature_header(signature_header)
new_body_to_verify = f"{timestamp}:{raw_body}".encode(self.ENCODING)
generated_signature = self.calculate_hmac(secret_key, new_body_to_verify).hexdigest()
timestamp, signature = PaddleSignature.parse(signature_header)
new_body_to_verify = f"{timestamp}:{raw_body}".encode('utf-8')
generated_signature = PaddleSignature.calculate_hmac(secret_key.secret_key, new_body_to_verify).hexdigest()

integrity_result = compare_digest(generated_signature, signature)
log.debug(f"Comparing received Paddle signature '{signature}' to our calculated signature: '{generated_signature}'")
log.info(f"Paddle signature integrity {'passed' if integrity_result else 'failed'}")

return integrity_result

0 comments on commit 8612db1

Please sign in to comment.