def put(self, request, **kwargs): user, err = self._authorize(request) if err: return err id_field, id = self._find_id(kwargs) if id is None: return create_http_error(400, 'id not provided', request) model = self.by_id(request, id_field, id, user=user) if model is None: return create_http_error(404, 'model not found', request) model_json, err = self._validate_json(request) if err: return err err = self.update_model(model, model_json, request, kwargs.get('parent', None)) if err: return err err = self.update_relationships( model, model_json, request, kwargs.get('parent', None) ) if err: return err err = self._validate_and_save(model, request) if err: return err return self._response(model)
def update_model(self, model, model_json, request, parent): try: collector_type = CollectorType.objects.get( id=model_json['type_id']) data_source = DataSource.objects.get( id=model_json['data_source_id']) data_set = DataSet.objects.get( data_group__name=model_json['data_set']['data_group'], data_type__name=model_json['data_set']['data_type']) model_json['type'] = collector_type model_json['data_source'] = data_source model_json['data_set'] = data_set add_items_to_model(model, model_json) except CollectorType.DoesNotExist: message = "No collector type with id '{}' found".format( model_json['type_id']) return create_http_error(400, message, request, logger=logger) except DataSource.DoesNotExist: message = "No data source with id '{}' found".format( model_json['data_source_id']) return create_http_error(400, message, request, logger=logger) except DataSet.DoesNotExist: message = "No data set with data group '{}' and data type '{}' " \ "found".format(model_json['data_set']['data_group'], model_json['data_set']['data_type']) return create_http_error(400, message, request, logger=logger)
def run_collector(user, request, slug): start_at = request.GET.get('start-at', None) end_at = request.GET.get('end-at', None) dry_run = request.GET.get('dry-run', "False") collector = get_object_or_404(Collector, slug=slug) if user_missing_model_permission(user, collector): return create_http_error(404, 'Not Found', request) if xor(bool(start_at), bool(end_at)): message = 'You must either specify a both start date and an end ' \ 'date for the collector run, or neither' return create_http_error(400, message, request) if start_at and end_at: try: datetime.strptime(start_at, '%Y-%m-%d') datetime.strptime(end_at, '%Y-%m-%d') except ValueError: message = "Incorrect date format, should be YYYY-MM-DD" return create_http_error(400, message, request) run_collector_task.delay( slug, start_at=start_at, end_at=end_at, dry_run=(True if dry_run.lower() == "true" else False)) return HttpResponse('', content_type='application/json')
def update_model(self, model, model_json, request, parent): try: transform_type = TransformType.objects.get( id=model_json['type_id']) except TransformType.DoesNotExist: return create_http_error(400, 'transform type was not found', request) (input_group, input_type) = resolve_data_reference(model_json['input']) if input_type is None: return create_http_error( 400, 'input requires at least a data-type (that exists)', request) (output_group, output_type) = \ resolve_data_reference(model_json['output']) if output_type is None: return create_http_error( 400, 'output requires at least a data-type (that exists)', request) model.type = transform_type model.input_group = input_group model.input_type = input_type model.query_parameters = model_json['query-parameters'] model.options = model_json['options'] model.output_group = output_group model.output_type = output_type return None
def update_relationships(self, model, model_json, request, parent): if 'parent_id' in model_json: parent_id = model_json['parent_id'] if not is_uuid(parent_id): return create_http_error(400, 'parent_id has to be a uuid', request) try: parent_node = Dashboard.objects.get(id=parent_id) except Dashboard.DoesNotExist: return create_http_error(400, 'parent not found', request) model.parents.add(parent_node)
def update_relationships(self, model, model_json, request, parent): if 'parent_id' in model_json: parent_id = model_json['parent_id'] if not is_uuid(parent_id): return create_http_error(400, 'parent_id has to be a uuid', request) try: parent_node = Dashboard.objects.get(id=parent_id) except Dashboard.DoesNotExist: return create_http_error(400, 'parent not found', request) model.parents.add(parent_node)
def post(self, request, **kwargs): user, err = self._authorize(request) if err: return err id_field, id = self._find_id(kwargs) if id is not None: if 'sub_resource' in kwargs: model = self.by_id(request, id_field, id, user=user) if model: return self._get_sub_resource(request, kwargs['sub_resource'], model) else: return create_http_error(404, 'parent resource not found', request) else: return create_http_error(405, "can't post to a resource", request) else: model_json, err = self._validate_json(request) if err: return err model = self.model() err = self.update_model(model, model_json, request, kwargs.get('parent', None)) if err: return err err = self._validate_and_save(model, request) if err: return err if hasattr(model, 'owners'): user_obj, created = User.objects.get_or_create( email=user["email"]) model.owners.add(user_obj) err = self.update_relationships( model, model_json, request, kwargs.get('parent', None) ) if err: return err err = self._validate_and_save(model, request) if err: return err return self._response(model)
def update_model(self, model, model_json, request, parent): logger.setLevel('ERROR') try: data_group = DataGroup.objects.get(name=model_json['data_group']) data_type = DataType.objects.get(name=model_json['data_type']) model_json['data_group'] = data_group model_json['data_type'] = data_type add_items_to_model(model, model_json) except DataGroup.DoesNotExist: message = "No data group with name '{}' found".format( model_json['data_group']) return create_http_error(400, message, request, logger=logger) except DataType.DoesNotExist: message = "No data type with name '{}' found".format( model_json['data_type']) return create_http_error(400, message, request, logger=logger)
def update_model(self, model, model_json, request, parent): logger.setLevel('ERROR') try: data_group = DataGroup.objects.get(name=model_json['data_group']) data_type = DataType.objects.get(name=model_json['data_type']) model_json['data_group'] = data_group model_json['data_type'] = data_type add_items_to_model(model, model_json) except DataGroup.DoesNotExist: message = "No data group with name '{}' found".format( model_json['data_group']) return create_http_error(400, message, request, logger=logger) except DataType.DoesNotExist: message = "No data type with name '{}' found".format( model_json['data_type']) return create_http_error(400, message, request, logger=logger)
def _validate_model(self, model, request): if hasattr(model, 'validate'): err = model.validate() if err: return create_http_error(400, 'validation error: {}' .format(err), request) try: model.full_clean() except DjangoValidationError as err: messages = [ '{}: {}'.format(k, ' '.join(v)) for k, v in err.message_dict.items() ] return create_http_error(400, 'validation errors:\n{}' .format('\n'.join(messages)), request)
def update_model(self, model, model_json, request, parent): if model_json.get('organisation'): org_id = model_json['organisation'] if not is_uuid(org_id): return create_http_error(400, 'Organisation must be a valid UUID', request) try: organisation = Node.objects.get(id=org_id) model.organisation = organisation except Node.DoesNotExist: return create_http_error(404, 'Organisation does not exist', request) for key, value in model_json.iteritems(): if key not in ['organisation', 'links']: setattr(model, key.replace('-', '_'), value)
def update_model(self, model, model_json, request, parent): if model_json.get('organisation'): org_id = model_json['organisation'] if not is_uuid(org_id): return create_http_error(400, 'Organisation must be a valid UUID', request) try: organisation = Node.objects.get(id=org_id) model.organisation = organisation except Node.DoesNotExist: return create_http_error(404, 'Organisation does not exist', request) for key, value in model_json.iteritems(): if key not in ['organisation', 'links']: setattr(model, key.replace('-', '_'), value)
def add_provider_to_model(model, model_json, request): try: provider = Provider.objects.get(id=model_json['provider_id']) model_json['provider'] = provider add_items_to_model(model, model_json) except Provider.DoesNotExist: message = "No provider with id '{}' found".format( model_json['provider_id']) return create_http_error(400, message, request, logger=logger)
def _validate_json(self, request): if request.META.get('CONTENT_TYPE', '').lower() != 'application/json': return None, create_http_error(415, 'bad content type', request) try: model_json = json.loads(request.body) except ValueError: return None, create_http_error(400, 'error decoding JSON: {}' .format(ValueError), request) try: jsonschema.validate( model_json, self.schema, format_checker=FORMAT_CHECKER) except ValidationError as err: message = 'options failed validation: {}'.format(err.message) return None, create_http_error(400, message, request) return model_json, None
def update_model(self, model, model_json, request, parent): try: node_type = NodeType.objects.get(id=model_json['type_id']) except NodeType.DoesNotExist: return create_http_error(400, 'no NodeType found', request) model.name = model_json['name'] model.slug = model_json.get('slug', None) model.abbreviation = model_json.get('abbreviation', None) model.typeOf = node_type
def _get_sub_resource(self, request, sub_resource, model): sub_resource = str(sub_resource.strip().lower()) sub_view = self.sub_resources.get(sub_resource, None) if sub_view is not None: sub_view_method = getattr(sub_view, request.method.lower()) return sub_view_method(request, **{ 'parent': model, }) else: return create_http_error(404, 'sub resource not found', request)
def _validate_and_save(self, model, request): err = self._validate_model(model, request) if err: return err try: model.save() except (DataError, IntegrityError) as err: return create_http_error(400, 'error saving model: {}'.format(err), request) return None
def test_create_http_error(self): status = 400 message = "Detail for 400 Bad Request" request = HttpRequest() error = create_http_error(status, message, request) err = json.loads(error.content) assert_that(error.status_code, equal_to(400)) assert_that(err["errors"][0]["detail"], equal_to("Detail for 400 Bad Request"))
def dashboard(user, request, name): try: data_set = DataSet.objects.get(name=name) except DataSet.DoesNotExist: message = "No Data Set named '{}' exists".format(name) return create_http_error(404, message, request, logger=logger) modules = data_set.module_set.distinct('dashboard') dashboards = [m.dashboard for m in modules] json_str = to_json([d.serialize() for d in dashboards]) return HttpResponse(json_str, content_type='application/json')
def dashboard(user, request, name): try: data_set = DataSet.objects.get(name=name) except DataSet.DoesNotExist: message = "No Data Set named '{}' exists".format(name) return create_http_error(404, message, request, logger=logger) modules = data_set.module_set.distinct('dashboard') dashboards = [m.dashboard for m in modules] json_str = to_json([d.serialize() for d in dashboards]) return HttpResponse(json_str, content_type='application/json')
def delete(self, request, **kwargs): user, err = self._authorize(request) if err: return err id_field, id = self._find_id(kwargs) if id is None: return create_http_error(400, 'id not provided', request) if kwargs.get('sub_resource'): return create_http_error( 405, 'cannot delete a sub_resource', request) model = self.by_id(request, id_field, id, user=user) if model is None: return create_http_error(404, 'model not found', request) try: if hasattr(model, 'published'): if not model.published: model.delete() else: return create_http_error( 400, 'cannot delete published resource', request) else: return create_http_error( 405, 'cannot delete resource', request) except (OperationalError, IntegrityError) as err: return None, create_http_error(400, 'error deleting model: {}' .format()) return self._response(model)
def update_model(self, model, model_json, request, parent): try: node_type = NodeType.objects.get(id=model_json['type_id']) except NodeType.DoesNotExist: return create_http_error(400, 'no NodeType found', request) model.name = model_json['name'] model.slug = model_json.get('slug', None) model.abbreviation = model_json.get('abbreviation', None) model.typeOf = node_type if model_json['name'] == 'save-and-fail-validation': model.save()
def get(self, request, **kwargs): user, err = self._authorize(request) if err: return err id_field, id = self._find_id(kwargs) sub_resource = kwargs.get('sub_resource', None) if id is not None: model = self.by_id(request, id_field, id, user=user) if model is None: return create_http_error(404, 'model not found', request) elif sub_resource is not None: return self._get_sub_resource(request, sub_resource, model) else: return self._response(model) else: return self._response(self.list(request, user=user, **kwargs))
def transform(request, name): try: data_set = DataSet.objects.get(name=name) except DataSet.DoesNotExist: message = "No Data Set named '{}' exists".format(name) return create_http_error(404, message, request, logger=logger) data_set_transforms = Transform.objects.filter( input_group=data_set.data_group, input_type=data_set.data_type) data_type_transforms = Transform.objects.filter( input_group=None, input_type=data_set.data_type) transforms = data_set_transforms | data_type_transforms serialized_transforms = [TransformView.serialize(t) for t in transforms] return HttpResponse(to_json(serialized_transforms), content_type='application/json')
def transform(request, name): try: data_set = DataSet.objects.get(name=name) except DataSet.DoesNotExist: message = "No Data Set named '{}' exists".format(name) return create_http_error(404, message, request, logger=logger) data_set_transforms = Transform.objects.filter( input_group=data_set.data_group, input_type=data_set.data_type) data_type_transforms = Transform.objects.filter( input_group=None, input_type=data_set.data_type) transforms = data_set_transforms | data_type_transforms serialized_transforms = [TransformView.serialize(t) for t in transforms] return HttpResponse( to_json(serialized_transforms), content_type='application/json')
def update_model(self, model, model_json, request, parent): try: module_type = ModuleType.objects.get(id=model_json['type_id']) except ModuleType.DoesNotExist: return create_http_error(404, 'module type not found', request) if parent is None: return create_http_error(404, 'no parent dashboard found', request) try: dashboard = Dashboard.objects.get(id=parent.id) except Dashboard.DoesNotExist: return create_http_error(404, 'dashboard not found', request) model.type = module_type model.dashboard = dashboard model.slug = model_json['slug'] model.title = model_json['title'] model.description = model_json['description'] model.info = model_json['info'] model.options = model_json['options'] model.order = model_json['order'] if model_json.get('data_group') and model_json.get('data_type'): try: data_set = DataSet.objects.get( data_group__name=model_json['data_group'], data_type__name=model_json['data_type'], ) except DataSet.DoesNotExist: return create_http_error(400, 'data set does not exit', request) model.data_set = data_set model.query_parameters = model_json.get('query_parameters', {}) try: model.validate_query_parameters() except ValidationError as err: msg = 'Query parameters not valid: {}'.format(err.message) return create_http_error(400, msg, request) elif model_json.get('query_parameters'): return create_http_error(400, 'query parameters but not data set', request)
def update_model(self, model, model_json, request, parent): try: module_type = ModuleType.objects.get(id=model_json['type_id']) except ModuleType.DoesNotExist: return create_http_error(404, 'module type not found', request) if parent is None: return create_http_error(404, 'no parent dashboard found', request) try: dashboard = Dashboard.objects.get(id=parent.id) except Dashboard.DoesNotExist: return create_http_error(404, 'dashboard not found', request) model.type = module_type model.dashboard = dashboard model.slug = model_json['slug'] model.title = model_json['title'] model.description = model_json['description'] model.info = model_json['info'] model.options = model_json['options'] model.order = model_json['order'] if model_json.get('data_group') and model_json.get('data_type'): try: data_set = DataSet.objects.get( data_group__name=model_json['data_group'], data_type__name=model_json['data_type'], ) except DataSet.DoesNotExist: return create_http_error(400, 'data set does not exit', request) model.data_set = data_set model.query_parameters = model_json.get('query_parameters', {}) try: model.validate_query_parameters() except ValidationError as err: msg = 'Query parameters not valid: {}'.format(err.message) return create_http_error(400, msg, request) elif model_json.get('query_parameters'): return create_http_error(400, 'query parameters but not data set', request)
def update_relationships(self, model, model_json, request, parent): if 'links' in model_json: for link_data in model_json['links']: if link_data['type'] == 'transaction': link, _ = model.link_set.get_or_create( link_type='transaction') link.url = link_data['url'] link.title = link_data['title'] link.save() else: model.link_set.create(link_type=link_data.pop('type'), **link_data) if 'modules' in model_json: current_module_ids = set([m.id for m in model.module_set.all()]) for module in model_json['modules']: try: for changed_module in self.update_module(model, module): current_module_ids.discard(changed_module.id) except ValueError as e: return create_http_error(400, e.message, request) model.module_set.filter(id__in=current_module_ids).delete()
def update_relationships(self, model, model_json, request, parent): if 'links' in model_json: for link_data in model_json['links']: if link_data['type'] == 'transaction': link, _ = model.link_set.get_or_create( link_type='transaction') link.url = link_data['url'] link.title = link_data['title'] link.save() else: model.link_set.create(link_type=link_data.pop('type'), **link_data) if 'modules' in model_json: current_module_ids = set([m.id for m in model.module_set.all()]) for module in model_json['modules']: try: for changed_module in self.update_module(model, module): current_module_ids.discard(changed_module.id) except ValueError as e: return create_http_error(400, e.message, request) model.module_set.filter(id__in=current_module_ids).delete()
def put(self, request, **kwargs): return create_http_error( 405, "Can't put to a resource," "update only supported through dashboard", request)
def forbidden(request, message): return create_http_error(403, 'Forbidden: {}'.format(message), request)
def unauthorized(request, message): response = create_http_error(401, 'Unauthorized: {}'.format(message), request) response['WWW-Authenticate'] = 'Bearer' return response
def put(self, request, **kwargs): return create_http_error( 405, "Can't put to a resource," "update only supported through dashboard", request)
def error_response(request, dashboard_slug): message = "No dashboard with slug '{}' exists".format(dashboard_slug) logger.setLevel('WARNING') return create_http_error(404, message, request, logger=logger)
def forbidden(request, message): return create_http_error(403, 'Forbidden: {}'.format(message), request)
def unauthorized(request, message): response = create_http_error( 401, 'Unauthorized: {}'.format(message), request) response['WWW-Authenticate'] = 'Bearer' return response
def error_response(request, dashboard_slug): message = "No dashboard with slug '{}' exists".format(dashboard_slug) logger.setLevel('WARNING') return create_http_error(404, message, request, logger=logger)