Laurent 2 years ago
parent 47fb4d38ca
commit f855492349
  1. 2
      jwt_signed.txt
  2. 2
      pokeranalytics_backend/settings.py
  3. BIN
      subscriptions/AppleRootCA-G3.cer
  4. 59
      subscriptions/views.py
  5. 4
      token_generator.py

@ -1 +1 @@
eyJhbGciOiJFUzI1NiIsImtpZCI6IkpaQzlMNzZURFQiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiI2OWE2ZGU4My0wMmYyLTQ3ZTMtZTA1My01YjhjN2MxMWE0ZDEiLCJpYXQiOjE3MDUzMjU5OTcsImV4cCI6MTcwNTMyOTI5NywiYXVkIjoiYXBwc3RvcmVjb25uZWN0LXYxIiwiYmlkIjoic3RheC5TbGFzaFBva2VyLm5vc2VibGVlZCJ9.Vr1p1t42RS6JC99USVHo1feS-43LeCGnBU464sa2fWFH-DaxAG8p6IeH3SfXoKAnN9UVJKF2ZOWkHypzJoFXSg
eyJhbGciOiJFUzI1NiIsImtpZCI6IkpaQzlMNzZURFQiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiI2OWE2ZGU4My0wMmYyLTQ3ZTMtZTA1My01YjhjN2MxMWE0ZDEiLCJpYXQiOjE3MDUzMjk3MzIsImV4cCI6MTcwNTMzMzI3MiwiYXVkIjoiYXBwc3RvcmVjb25uZWN0LXYxIiwiYmlkIjoic3RheC5TbGFzaFBva2VyLm5vc2VibGVlZCJ9.qk7ncK1WBIZqLkFkEQkEknmd6TgpEdg5h7OflcFxc3VfE99wo6hQV33S4oXe-pw3Zyz2h3_uOlXY5spz3pl4nw

@ -22,7 +22,7 @@ BASE_DIR = Path(__file__).resolve().parent.parent
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-v9l*b^t^2eqp877kdrt%5g#y=8$e%e^sa!65(1@t+rp@avwx+@'
ASS_KEY_FILE = BASE_DIR / 'AuthKey_JZC9L76TDT.p8'
ASS_KEY_FILE = BASE_DIR / 'AppleRootCA-G3.cer'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

Binary file not shown.

@ -6,16 +6,24 @@ from django.conf import settings
import json, jwt
import base64
import logging
import logging.config
logger = logging.getLogger("main")
from OpenSSL.crypto import (
X509Store,
X509StoreContext,
X509StoreContextError,
load_certificate,
FILETYPE_ASN1,
FILETYPE_PEM
)
def index(request):
return HttpResponse("Hello, world. You're at the subs index.")
def test(request):
return HttpResponse("Test succeeded!")
KEY_FILE = settings.ASS_KEY_FILE
with open(KEY_FILE,'r') as key_file:
key = ''.join(key_file.readlines())
return HttpResponse(key)
@csrf_exempt
def app_store_webhook(request):
@ -26,15 +34,13 @@ def app_store_webhook(request):
signedPayload = fulljson['signedPayload']
content = signedPayload.split('.')[1]
jws_payload = base64.b64decode(content)
data = json.loads(jws_payload.decode())
KEY_FILE = settings.ASS_KEY_FILE
with open(KEY_FILE,'r') as key_file:
key = ''.join(key_file.readlines())
#KEY_FILE = settings.ASS_KEY_FILE
decodedPayload = _decode_jws(token, algorithms=algorithms)
#with open(KEY_FILE,'r') as key_file:
# key = ''.join(key_file.readlines())
# decodedPayload = jwt.decode(signedPayload, key, algorithms=['ES256'])
@ -42,8 +48,37 @@ def app_store_webhook(request):
#logger.debug('test getLogger' + str(key))
notification = ASSNotification(
content=jws_payload,
content=decodedPayload,
)
notification.save()
return JsonResponse({'status': 'success'})
def _decode_jws(token, root_cert_path, algorithms):
try:
header = jwt.get_unverified_header(token)
# the first cert contains the public key used to sign the jwt
first_cert_data = header["x5c"][0]
first_cert_data = add_labels(first_cert_data)
first_cert = load_certificate(FILETYPE_PEM, first_cert_data)
# the other certs are an x5c (X.509 certificate chain)
chain_datas = header["x5c"][1:]
chain_datas = [add_labels(cd) for cd in chain_datas]
chain = [load_certificate(FILETYPE_PEM, cd) for cd in chain_datas]
public_key = first_cert.get_pubkey().to_cryptography_key()
store = X509Store()
store.add_cert(_get_root_cert(root_cert_path))
ctx = X509StoreContext(store=store, certificate=first_cert, chain=chain)
ctx.verify_certificate()
return jwt.decode(token, public_key, algorithms=algorithms)
except (ValueError, KeyError, jwt.exceptions.PyJWTError, X509StoreContextError) as err:
raise InvalidTokenError from err
def add_labels(key: str) -> bytes:
return ("-----BEGIN CERTIFICATE-----\n" + key + "\n-----END CERTIFICATE-----").encode()

@ -11,7 +11,7 @@ bid = 'stax.SlashPoker.nosebleed'
# Define issue timestamp.
issued_at_timestamp = int(dt.datetime.now().timestamp())
# Define expiration timestamp. May not exceed 20 minutes from issue timestamp.
expiration_timestamp = issued_at_timestamp + 55*60
expiration_timestamp = issued_at_timestamp + 59*60
# Define JWT headers.
headers = dict()
@ -43,7 +43,7 @@ key=key
with open('jwt_signed.txt', 'w') as output:
output.write(client_secret)
# curl -X POST -v -H 'Authorization: Bearer eyJhbGciOiJFUzI1NiIsImtpZCI6IkpaQzlMNzZURFQiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiI2OWE2ZGU4My0wMmYyLTQ3ZTMtZTA1My01YjhjN2MxMWE0ZDEiLCJpYXQiOjE3MDUzMjIxMjUsImV4cCI6MTcwNTMyNTQyNSwiYXVkIjoiYXBwc3RvcmVjb25uZWN0LXYxIiwiYmlkIjoic3RheC5TbGFzaFBva2VyLm5vc2VibGVlZCJ9.dM2cM92BX7f4f8fuF72HRaOutK1POs6tQcVriXMQQIA_tA_HOayXYuTRt_cUc4HLqErkRj9NNiT0CV0ZJECqpQ' https://api.storekit-sandbox.itunes.apple.com/inApps/v1/notifications/test
# curl -X POST -v -H 'Authorization: Bearer eyJhbGciOiJFUzI1NiIsImtpZCI6IkpaQzlMNzZURFQiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiI2OWE2ZGU4My0wMmYyLTQ3ZTMtZTA1My01YjhjN2MxMWE0ZDEiLCJpYXQiOjE3MDUzMjk3MzIsImV4cCI6MTcwNTMzMzI3MiwiYXVkIjoiYXBwc3RvcmVjb25uZWN0LXYxIiwiYmlkIjoic3RheC5TbGFzaFBva2VyLm5vc2VibGVlZCJ9.qk7ncK1WBIZqLkFkEQkEknmd6TgpEdg5h7OflcFxc3VfE99wo6hQV33S4oXe-pw3Zyz2h3_uOlXY5spz3pl4nw' https://api.storekit-sandbox.itunes.apple.com/inApps/v1/notifications/test
# Usage, after run this code by python3
# get token from `client_secret.txt` and replace to [signed token]
# Remember expired time maximum is 20 minutes

Loading…
Cancel
Save