From 910c7185af0b9feb3ff77acbb6ad0b6fd611d889 Mon Sep 17 00:00:00 2001 From: jr conlin Date: Mon, 19 Jun 2017 13:01:43 -0700 Subject: [PATCH] bug: Return 400 if routing token is blank or unspecified closes #921 --- autopush/tests/test_integration.py | 34 ++++++++++++++++++++++++++++-- autopush/web/registration.py | 33 ++++++++++++++++++++++++++--- 2 files changed, 62 insertions(+), 5 deletions(-) diff --git a/autopush/tests/test_integration.py b/autopush/tests/test_integration.py index 225577d5..0e407aa6 100644 --- a/autopush/tests/test_integration.py +++ b/autopush/tests/test_integration.py @@ -1865,6 +1865,23 @@ def test_registration(self): eq_(ca_data['enc'], salt) eq_(ca_data['body'], base64url_encode(data)) + @inlineCallbacks + def test_registration_no_token(self): + self._add_router() + # get the senderid + url = "{}/v1/{}/{}/registration".format( + self.ep.settings.endpoint_url, + "gcm", + self.senderID, + ) + response, body = yield _agent('POST', url, body=json.dumps( + { + "chid": str(uuid.uuid4()), + "token": '', + } + )) + eq_(response.code, 400) + class TestFCMBridgeIntegration(IntegrationBase): @@ -1986,8 +2003,7 @@ def test_registration(self): "firefox", ) response, body = yield _agent('POST', url, body=json.dumps( - {"token": uuid.uuid4().hex, - } + {"token": uuid.uuid4().hex} )) eq_(response.code, 200) jbody = json.loads(body) @@ -2027,6 +2043,20 @@ def test_registration(self): eq_(ca_data['aps']['alert']['body'], " ") eq_(ca_data['body'], base64url_encode(data)) + @inlineCallbacks + def test_registration_no_token(self): + self._add_router() + # get the senderid + url = "{}/v1/{}/{}/registration".format( + self.ep.settings.endpoint_url, + "apns", + "firefox", + ) + response, body = yield _agent('POST', url, body=json.dumps( + {"token": ''} + )) + eq_(response.code, 400) + @inlineCallbacks def test_registration_aps_override(self): self._add_router() diff --git a/autopush/web/registration.py b/autopush/web/registration.py index 783f1295..5715e449 100644 --- a/autopush/web/registration.py +++ b/autopush/web/registration.py @@ -1,5 +1,7 @@ import re import uuid + +from marshmallow_polyfield import PolyField from typing import ( # noqa Optional, Set, @@ -15,8 +17,9 @@ fields, pre_load, post_load, + validate, validates, - validates_schema + validates_schema, ) from twisted.internet.defer import Deferred # noqa from twisted.internet.threads import deferToThread @@ -71,7 +74,21 @@ def convert_chid(self, data): class TokenSchema(SubInfoSchema): """Filters allowed values from body data""" token = fields.Str(allow_none=True) - # Temporarily allow 'aps' definition data for iOS. + + +valid_token = validate.Regexp("^[^ ]{8,}$") + + +class GCMTokenSchema(SubInfoSchema): + token = fields.Str(allow_none=False, + validate=valid_token, + error="Missing required token value") + + +class APNSTokenSchema(SubInfoSchema): + token = fields.Str(allow_none=False, + validate=valid_token, + error="Missing required token value") aps = fields.Dict(allow_none=True) @@ -158,8 +175,18 @@ def validate_auth(self, data): headers=request_pref_header) +def conditional_token_check(object_dict, parent_dict): + if parent_dict['path_kwargs']['type'] in ['gcm', 'fcm']: + return GCMTokenSchema() + if parent_dict['path_kwargs']['type'] == 'apns': + return APNSTokenSchema() + return TokenSchema() + + class RouterDataSchema(Schema): - router_data = fields.Nested(TokenSchema, load_from="body") + router_data = PolyField( + load_from="body", + deserialization_schema_selector=conditional_token_check) @validates_schema(skip_on_field_errors=True) def register_router(self, data):