blob: b6612caf35f68f72d63e59ebc8b0a9e67f1d53e2 [file] [log] [blame]
# Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Define a stateless pattern for validating url query parameters (?k=v&k=v...).
The common Validate function accepts a list of xValidator classes against
which the request will be checked. The xValidator classes must each
include the following class variables: required, supported and
match_patterns.
Note, Django request objects support multiple instances of a query
parameter in an url.
e.g. http:/x/y?mykey=foo&mykey=bar ==> {'mykey': ['foo', 'bar']
"""
import re
from autotest_lib.frontend.croschart.charterrors import ChartInputError
BOOL_PATTERN = re.compile('((?i)(true|false)$)')
BUILD_PATTERN1 = re.compile('([\d]+\.[\d]+\.[\d]+\.[\d]+$)')
BUILD_PATTERN2 = re.compile('(R[\d]+-[\d]+\.[\d]+\.[\d]+$)')
DATE_PATTERN = re.compile('([\d]{4}-[\d]{1,2}-[\d]{1,2}$)')
DIM_PATTERN = re.compile('([\d]+$)')
INTERVAL_PATTERN = re.compile('([\d]+\,(?i)(day|week|month)$)')
TESTKEY_PATTERN = re.compile('([\w\.]+,[\w\.\,-]+$)')
def Validate(request, validator_list):
"""Run through the parameter validations."""
for validator in validator_list:
for p in validator.supported:
value_list = request.GET.getlist(p)
# Required parameters must be provided.
if p in validator.required and not value_list:
raise ChartInputError("Parameter '%s' is required." % p)
if not p in request.GET:
continue
# Do not allow any empty parameter values.
if '' in value_list:
raise ChartInputError("Parameter '%s' cannot be empty." % p)
# Check format where supplied.
patterns = validator.match_patterns.get(p, None)
if patterns:
for v in value_list:
found = False
for pattern in patterns:
if re.match(pattern, v):
found = True
break
if not found:
raise ChartInputError("Parameter '%s' is improperly formatted." % p)
class CrosChartValidator(object):
"""Common parameter expectations for Chrome OS charts."""
required = ['board', 'system', 'testkey']
supported = required + ['width', 'height', 'chromeversion', 'updatecache']
match_patterns = {'testkey': [TESTKEY_PATTERN], 'width': [DIM_PATTERN],
'height': [DIM_PATTERN], 'chromeversion': [BOOL_PATTERN],
'updatecache': [BOOL_PATTERN]}
class CrosPlatformsValidator(object):
"""Common parameter expectations for Chrome OS platforms reports."""
required = ['platform']
supported = required + ['testkey', 'width', 'height', 'chromeversion',
'updatecache']
match_patterns = {'testkey': [TESTKEY_PATTERN], 'width': [DIM_PATTERN],
'height': [DIM_PATTERN], 'chromeversion': [BOOL_PATTERN],
'updatecache': [BOOL_PATTERN]}
class CrosReportValidator(object):
"""Common parameter expectations for Chrome OS reports."""
required = ['board', 'system']
supported = required + ['testkey', 'width', 'height', 'chromeversion',
'updatecache']
match_patterns = {'testkey': [TESTKEY_PATTERN], 'width': [DIM_PATTERN],
'height': [DIM_PATTERN], 'chromeversion': [BOOL_PATTERN],
'updatecache': [BOOL_PATTERN]}
class BuildRangeValidator(object):
"""Chrome OS build range URL parameters."""
required = ['from_build', 'to_build']
supported = required
match_patterns = {'from_build': [BUILD_PATTERN1, BUILD_PATTERN2],
'to_build': [BUILD_PATTERN1, BUILD_PATTERN2]}
class DateRangeValidator(object):
"""Chrome OS date range URL parameters."""
required = ['from_date', 'to_date']
supported = required
match_patterns = {'from_date': [DATE_PATTERN], 'to_date': [DATE_PATTERN]}
class IntervalRangeValidator(object):
"""Chrome OS interval range URL parameters."""
required = ['interval']
supported = required
match_patterns = {'interval': [INTERVAL_PATTERN]}