From 348c3642adca2ff1b912b0d460c17711fff06d86 Mon Sep 17 00:00:00 2001 From: George Waters Date: Mon, 9 May 2022 17:49:38 -0400 Subject: [PATCH] Add option to pass Auth Key as base64 string Pass the base64 encoded Auth Key string to TokenCredentials rather than the file path. This can be useful when the Auth Key is not stored in a file for security reasons. --- apns2/credentials.py | 14 +++++++++++++- test/test_credentials.py | 5 +++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/apns2/credentials.py b/apns2/credentials.py index 028093e..7e3a426 100644 --- a/apns2/credentials.py +++ b/apns2/credentials.py @@ -1,5 +1,6 @@ import time from typing import Optional, Tuple, TYPE_CHECKING +from base64 import b64decode import jwt @@ -43,9 +44,13 @@ def __init__(self, cert_file: Optional[str] = None, password: Optional[str] = No # Credentials subclass for JWT token based authentication class TokenCredentials(Credentials): def __init__(self, auth_key_path: str, auth_key_id: str, team_id: str, + auth_key_base64: Optional[str] = None, encryption_algorithm: str = DEFAULT_TOKEN_ENCRYPTION_ALGORITHM, token_lifetime: int = DEFAULT_TOKEN_LIFETIME) -> None: - self.__auth_key = self._get_signing_key(auth_key_path) + if auth_key_base64 is not None: + self.__auth_key = self._decode_signing_key(auth_key_base64) + else: + self.__auth_key = self._get_signing_key(auth_key_path) self.__auth_key_id = auth_key_id self.__team_id = team_id self.__encryption_algorithm = encryption_algorithm @@ -71,6 +76,13 @@ def _get_signing_key(key_path: str) -> str: secret = f.read() return secret + @staticmethod + def _decode_signing_key(key_base64: str) -> str: + secret = '' + if key_base64: + secret = b64decode(key_base64).decode() + return secret + def _get_or_create_topic_token(self) -> str: # dict of topic to issue date and JWT token token_pair = self.__jwt_token diff --git a/test/test_credentials.py b/test/test_credentials.py index 21b1eab..c97614a 100644 --- a/test/test_credentials.py +++ b/test/test_credentials.py @@ -4,6 +4,7 @@ # - timing out of the token # - creating multiple tokens for different topics +from base64 import b64encode import pytest from freezegun import freeze_time @@ -21,6 +22,10 @@ def token_credentials(): token_lifetime=30, # seconds ) +def test_auth_key_base64(): + with open('test/eckey.pem', 'rb') as f: + auth_key_base64 = b64encode(f.read()) + assert TokenCredentials._get_signing_key('test/eckey.pem') == TokenCredentials._decode_signing_key(auth_key_base64) def test_token_expiration(token_credentials): with freeze_time('2012-01-14 12:00:00'):