Extract data validator to own file and add tests (#12401)

This commit is contained in:
Paulus Schoutsen 2018-02-14 12:06:03 -08:00 committed by Pascal Vizeli
parent 416f64fc70
commit 78c44180f4
7 changed files with 139 additions and 46 deletions

View file

@ -0,0 +1,51 @@
"""Decorator for view methods to help with data validation."""
import asyncio
from functools import wraps
import logging
import voluptuous as vol
_LOGGER = logging.getLogger(__name__)
class RequestDataValidator:
"""Decorator that will validate the incoming data.
Takes in a voluptuous schema and adds 'post_data' as
keyword argument to the function call.
Will return a 400 if no JSON provided or doesn't match schema.
"""
def __init__(self, schema, allow_empty=False):
"""Initialize the decorator."""
self._schema = schema
self._allow_empty = allow_empty
def __call__(self, method):
"""Decorate a function."""
@asyncio.coroutine
@wraps(method)
def wrapper(view, request, *args, **kwargs):
"""Wrap a request handler with data validation."""
data = None
try:
data = yield from request.json()
except ValueError:
if not self._allow_empty or \
(yield from request.content.read()) != b'':
_LOGGER.error('Invalid JSON received.')
return view.json_message('Invalid JSON.', 400)
data = {}
try:
kwargs['data'] = self._schema(data)
except vol.Invalid as err:
_LOGGER.error('Data does not match schema: %s', err)
return view.json_message(
'Message format incorrect: {}'.format(err), 400)
result = yield from method(view, request, *args, **kwargs)
return result
return wrapper