Skip to content
This repository has been archived by the owner on Jul 13, 2023. It is now read-only.

Commit

Permalink
feat: Do not do VAPID auth on trusted connections
Browse files Browse the repository at this point in the history
Closes #938
  • Loading branch information
jrconlin committed Jul 8, 2017
1 parent 40f15e0 commit f9b375a
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 8 deletions.
20 changes: 16 additions & 4 deletions autopush/jwt.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,21 @@ def extract_signature(auth):
return payload, encoded

@staticmethod
def decode(token, key):
def extract_assertion(token):
# type (str) -> JSONDict
"""Extract the assertion dictionary from the passed token. This does
NOT do validation.
:param token: Partial or full VAPID auth token
:return dict of the VAPID claims
"""
return json.loads(
base64.urlsafe_b64decode(
repad(token.split('.')[1]).encode('utf8')))

@staticmethod
def validate_and_extract_assertion(token, key):
# type (str, str) -> JSONDict
"""Decode a web token into a assertion dictionary.
Expand Down Expand Up @@ -119,9 +133,7 @@ def decode(token, key):
signature,
sig_material.encode('utf8'),
ec.ECDSA(hashes.SHA256()))
return json.loads(
base64.urlsafe_b64decode(
repad(sig_material.split('.')[1]).encode('utf8')))
return VerifyJWT.extract_assertion(sig_material)
except InvalidSignature:
raise
except (ValueError, TypeError, binascii.Error, PyAsn1Error):
Expand Down
8 changes: 8 additions & 0 deletions autopush/tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
from mock import patch, Mock
from nose.tools import eq_

from autopush.tests.test_integration import _get_vapid


class TestUserAgentParser(unittest.TestCase):
def _makeFUT(self, *args):
Expand Down Expand Up @@ -31,6 +33,12 @@ def test_other_os_and_browser(self):
eq_(dd["ua_browser_family"], "Other")
eq_(raw["ua_browser_family"], "BlackBerry")

def test_trusted_vapid(self):
from autopush.utils import extract_jwt
vapid_info = _get_vapid(payload={'sub': 'mailto:[email protected]'})
data = extract_jwt(vapid_info['auth'], 'invalid_key', is_trusted=True)
eq_(data['sub'], 'mailto:[email protected]')

@patch("requests.get")
def test_get_ec2_instance_id_unknown(self, request_mock):
import requests
Expand Down
10 changes: 7 additions & 3 deletions autopush/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,13 +188,17 @@ def decipher_public_key(key_data):
raise ValueError("Unknown public key format specified")


def extract_jwt(token, crypto_key):
# type: (str, str) -> Dict[str, str]
def extract_jwt(token, crypto_key, is_trusted=False):
# type: (str, str, bool) -> Dict[str, str]
"""Extract the claims from the validated JWT. """
# first split and convert the jwt.
if not token or not crypto_key:
return {}
return jwt.decode(token, decipher_public_key(crypto_key.encode('utf8')))
if is_trusted:
return jwt.extract_assertion(token)
return jwt.validate_and_extract_assertion(
token,
decipher_public_key(crypto_key.encode('utf8')))


def parse_user_agent(agent_string):
Expand Down
6 changes: 5 additions & 1 deletion autopush/web/webpush.py
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,11 @@ def validate_auth(self, d):
public_key = vapid_auth['k']
else:
public_key = d["subscription"].get("public_key")
jwt = extract_jwt(token, public_key)
jwt = extract_jwt(
token,
public_key,
is_trusted=self.context['settings'].enable_tls_auth
)
except (KeyError, ValueError, InvalidSignature, TypeError,
VapidAuthException):
raise InvalidRequest("Invalid Authorization Header",
Expand Down

0 comments on commit f9b375a

Please sign in to comment.