def authenticate(data): """ Checks for a valid combination of ``unit_id`` and ``secret_key`` values in `data`. Also removes the ``secret_key`` for enhanced security. """ invalid = pipe | 'Authentication failed ({0}).' | InvalidRequest valid, error = validate( required('unit_id', valid_int), required('secret_key', valid_string), )(data) if not valid: raise invalid(error) unit = unless(CarUnit.DoesNotExist, CarUnit.objects.get)( unit_id=data['unit_id'], secret_key=data['secret_key'], ) if not unit: raise invalid('wrong "unit_id" and/or "secret_key"') if not unit.enabled: raise invalid('unit is disabled') return data.iteritems() > where(KEY != 'secret_key') | dict
class StoreLog(APICall): """ An API method to store one or more log-entries from a car unit. """ rules = ( required('unit_id', valid_int), required('entries'), X['entries'] | validate_each( required('timestamp', valid_timestamp), required('location', valid_location), optional('event', valid_string), optional('user_id', valid_user_id), optional('odometer', valid_float), optional('velocity', valid_float), optional('consumption', valid_float), optional('fuel_remaining', valid_float), optional('altitude', valid_float), optional('engine_temp', valid_float), optional('engine_rpm', valid_float), optional('throttle', valid_float), optional('gps_accuracy', valid_float), ), ) @process_request(pipe | parse_json | authenticate | (validate_request, rules)) def post(self, request, data): store(data['unit_id'], data['entries']) return {'status': 'ok'}
def test_invalid(self): data = {'some_field': []} self.assertEqual(validate( required('some_field', valid_int), )(data), (False, '"some_field" should be an integer, not "[]"'))
def test_missing(self): data = {} self.assertEqual(validate( required('some_field', valid_int), )(data), (False, 'missing "some_field" field'))
def test_valid(self): data = {'some_field': 3} self.assertEqual(validate( required('some_field', valid_int), )(data), OK)