diff --git a/flockos/event_handler_client.py b/flockos/event_handler_client.py index 28a262c..72d2f3c 100644 --- a/flockos/event_handler_client.py +++ b/flockos/event_handler_client.py @@ -1,4 +1,3 @@ -import json import jwt from token_verifier_filter import TokenVerifierFilter from utils import send_200_response, send_403_response, send_404_response @@ -6,7 +5,7 @@ class Event(object): def __init__(self, dictionary): - self.__dict__ = json.loads(dictionary) + self.__dict__ = dictionary class EventHandlerClient(object): @@ -71,16 +70,19 @@ def send_response(handler, event, start_response): def handle(self, environ, start_response): if 'event_token_payload' not in environ: try: - payload, event_json = TokenVerifierFilter.decode_and_verify_request(environ, - self.app_secret, - self.app_id) - event = Event(event_json) + TokenVerifierFilter.decode_and_verify_request(environ, + self.app_secret, + self.app_id) except jwt.DecodeError: send_403_response(start_response) return {} - else: - payload, event = environ['event_token_payload'], Event(environ['request_body']) + event_dictionary = environ.get(TokenVerifierFilter.EVENT_BODY) + if environ.get(TokenVerifierFilter.EVENT_TOKEN_PAYLOAD) is None or event_dictionary is None: + send_403_response(start_response) + return {} + + event = Event(event_dictionary) if event.name == "app.install": return EventHandlerClient.send_response(self.on_app_install_handler, event, start_response) elif event.name == "app.uninstall": diff --git a/flockos/token_verifier_filter.py b/flockos/token_verifier_filter.py index e276326..001528e 100644 --- a/flockos/token_verifier_filter.py +++ b/flockos/token_verifier_filter.py @@ -1,31 +1,47 @@ import jwt from utils import send_403_response +import json +from urlparse import parse_qs class TokenVerifierFilter: - def __init__(self, app, app_secret, appId): + EVENT_BODY = 'event_body' + EVENT_TOKEN_PAYLOAD = 'event_token_payload' + + def __init__(self, app, app_secret, app_id): self.app = app self.app_secret = app_secret - self.appId = appId + self.app_id = app_id + + @staticmethod + def decode_and_verify_request(environ, app_secret, app_id): + payload, body = TokenVerifierFilter.get_token_and_body(environ, app_secret) + event = json.loads(body) + if payload is not None and body is not None and payload.get('appId') == app_id and event.get( + 'userId') == payload.get('userId'): + environ[TokenVerifierFilter.EVENT_TOKEN_PAYLOAD] = payload + environ[TokenVerifierFilter.EVENT_BODY] = event @staticmethod - def decode_and_verify_request(environ, app_secret, appId): - payload = jwt.decode(environ['HTTP_X_FLOCK_EVENT_TOKEN'], app_secret, algorithm='HS256') - request_body_size = int(environ.get('CONTENT_LENGTH', 0)) - body = environ['wsgi.input'].read(request_body_size).decode("utf-8") - if payload['appId'] == appId: - environ['event_token_payload'] = payload - environ['request_body'] = body - return payload, body - else: - return None, None + def get_token_and_body(environ, app_secret): + payload, body = None, None + if environ['REQUEST_METHOD'] == 'GET': + query_params = parse_qs(environ['QUERY_STRING']) + token = query_params.get('flockEventToken') + body = query_params.get('flockEvent') + elif environ['REQUEST_METHOD'] == 'POST' and environ['CONTENT_TYPE'].startswith('application/json'): + token = environ.get('HTTP_X_FLOCK_EVENT_TOKEN') + request_body_size = int(environ.get('CONTENT_LENGTH', 0)) + body = environ.get('wsgi.input').read(request_body_size).decode("utf-8") + payload = jwt.decode(token, app_secret, algorithm='HS256') + return payload, body def __call__(self, environ, start_response): try: - (event_token_payload, request_body) = TokenVerifierFilter.decode_and_verify_request(environ, - self.app_secret, - self.appId) - if event_token_payload is None or request_body is None: + TokenVerifierFilter.decode_and_verify_request(environ, + self.app_secret, + self.app_id) + if environ.get(TokenVerifierFilter.EVENT_TOKEN_PAYLOAD) is None: send_403_response(start_response) else: return self.app(environ, start_response)