diff --git a/ask/__init__.py b/ask/__init__.py index 44652c0..112f0e2 100644 --- a/ask/__init__.py +++ b/ask/__init__.py @@ -1,4 +1,5 @@ from . import alexa_io +from alexa_io import InvalidAppIdException ''' Setting up some nice abstractions around good object oritented code. diff --git a/ask/alexa_io.py b/ask/alexa_io.py index a96688c..7a4230c 100644 --- a/ask/alexa_io.py +++ b/ask/alexa_io.py @@ -13,15 +13,20 @@ }""" +class InvalidAppIdException(Exception): + pass + + class Request(object): """ Simple wrapper around the JSON request received by the module """ - def __init__(self, request_dict, metadata=None): + def __init__(self, request_dict, metadata=None, supported_app_ids=None): self.request = request_dict self.metadata = metadata or {} self.session = self.request.get('session', {}).get('attributes', {}) + self.supported_app_ids = supported_app_ids if self.intent_name(): self.slots = self.get_slot_map() @@ -50,6 +55,19 @@ def access_token(self): def session_id(self): return self.request["session"]["sessionId"] + def application_id(self): + try: + return self.request['session']['application']['applicationId'] + except: + return None + + def has_valid_app_id(self): + if not self.supported_app_ids: + return True + if not self.application_id(): + return False + return self.application_id() in self.supported_app_ids + def get_slot_value(self, slot_name): try: return self.request["request"]["intent"]["slots"][slot_name]["value"] @@ -192,11 +210,18 @@ def _handler(func): return _handler - def route_request(self, request_json, metadata=None): + def route_request(self, request_json, metadata=None, app_ids=None): ''' Route the request object to the right handler function ''' request = Request(request_json) + request.supported_app_ids = app_ids request.metadata = metadata + + # before we do anything, lets verify the application id + # if app_ids is not passed in, verification does not occur + if not request.has_valid_app_id(): + raise InvalidAppIdException('Invalid ApplicationId: %s' % request.application_id()) + # add reprompt handler or some such for default? handler_fn = self._handlers[self._default] # Set default handling for noisy requests diff --git a/tests/test_alexa.py b/tests/test_alexa.py index 2b6e944..bed5150 100644 --- a/tests/test_alexa.py +++ b/tests/test_alexa.py @@ -1,4 +1,4 @@ -from nose.tools import assert_equal, assert_dict_equal, assert_true +from nose.tools import assert_equal, assert_dict_equal, assert_true, raises from .context import ask from .fixtures.requests import (TEST_SESSION_ENDED_REQUEST, TEST_LAUNCH_REQUEST, @@ -83,3 +83,14 @@ def test_routes_to_request_handler(self): response = ask.alexa.route_request(req_json) assert_true(response['request_handler_called']) + + @raises(ask.InvalidAppIdException) + def test_raises_invalid_app_id(self): + req_json = TEST_INTENT_REQUEST + ids = ['supported_id', 'another_bad_id'] + ask.alexa.route_request(req_json, app_ids=ids) + + def test_valid_app_id(self): + req_json = TEST_INTENT_REQUEST + ids = ['amzn1.echo-sdk-ams.app.000000-d0ed-0000-ad00-000000d00ebe'] + ask.alexa.route_request(req_json, app_ids=ids) diff --git a/tests/test_request.py b/tests/test_request.py index 58d4c03..ff7fcac 100644 --- a/tests/test_request.py +++ b/tests/test_request.py @@ -57,6 +57,27 @@ def test_request_returns_session_id(self): assert_equal(session_id, "SessionId.d461672c-2997-4d9d-9a8c-a67834acb9aa") + def test_request_returns_application_id(self): + application_id = self.example.application_id() + + assert_equal(application_id, "amzn1.echo-sdk-ams.app.a306b3a3-3331-43c1-87bd-87d29d16fac8") + + def test_request_has_valid_application_id_empty_app_ids(self): + assert_true(self.example.has_valid_app_id()) + + def test_request_has_valid_application_id(self): + self.example.supported_app_ids = ['amzn1.echo-sdk-ams.app.a306b3a3-3331-43c1-87bd-87d29d16fac8'] + + assert_true(self.example.has_valid_app_id()) + + def test_request_has_invalid_application_id(self): + def app_id_mock(): + return 'bad_app_id' + + self.example.supported_app_ids = ['amzn1.echo-sdk-ams.app.a306b3a3-3331-43c1-87bd-87d29d16fac8'] + self.example.application_id = app_id_mock + assert_false(self.example.has_valid_app_id()) + def test_request_returns_slot_value(self): val1 = self.example.get_slot_value("example1") val2 = self.example.get_slot_value("example2")