def move(self, obj, from_position, to_position, from_region, to_region): if to_position < 0: raise ValueError("Invalid target position; minimum position is 0") same_region = from_region == to_region same_position = from_position == to_position validate_region_name(from_region) validate_region_name(to_region) if same_region and same_position: raise ValueError("Cannot move `{obj!r}` because the given " "arguments wouldn't do trigger a " "movement.".format(obj=obj)) if not same_region: logger.debug("Moving into a different region") moved = self.move_between_regions( obj=obj, to_position=to_position, from_region=from_region, to_region=to_region) different_region_move_completed.send(sender=self.model, instance=obj, reflowed_previous=moved.old, reflowed_current=moved.new) else: logger.debug("Moving within the same region") moved = self.move_within_region(obj=obj, region=from_region, insert_position=to_position) same_region_move_completed.send(sender=self.model, instance=obj, reflowed=moved) move_completed.send(sender=self.model, instance=obj) return moved
def do_validate(self, region_name, content_object): validate_region_name(region_name) # somehow, a None got through. Interesting. if content_object is None: error = ttag_no_obj % { 'tagname': self.name, 'region': region_name, } logger.error(error) if settings.DEBUG: raise ImproperlyConfigured(error) return False return True
def wrapped(request, *args, **kwargs): fields_to_search = (REQUEST_VAR_CT, REQUEST_VAR_ID, REQUEST_VAR_REGION) fields = {} # By default, assume we're looking in the querystring; if it's a POST # request, fall back to looking in both GET and POST indiscriminately. lookup = request.GET if request.method.upper() == "POST": lookup = request.REQUEST # Convert content type field into an integer, because that's what # Django uses internally. content_type = lookup.get(REQUEST_VAR_CT, 0) try: fields.update({REQUEST_VAR_CT: int(content_type)}) except (ValueError, TypeError) as e: # ValueError: got string which was unconvertable to integer. # TypeError: got none, shut up! msg = 'Invalid parameter "content_type" with value: %s' % content_type logger.warning(msg, extra={"status_code": 405, "request": request}) # Content identifier can be anything as long as it isn't 0 and fits # within our DB storage max_length. content_id = str(lookup.get(REQUEST_VAR_ID, "0")) max_length = EditRegionChunk._meta.get_field_by_name(REQUEST_VAR_ID)[0].max_length if content_id != "0" and len(content_id) <= max_length: fields.update({REQUEST_VAR_ID: content_id}) else: msg = 'Invalid parameter "content_id" with value: %s' % content_type logger.warning(msg, extra={"status_code": 405, "request": request}) # Our region gets validated using the same format we always use. regionval = lookup.get(REQUEST_VAR_REGION, "__error__") try: validate_region_name(regionval) fields.update({REQUEST_VAR_REGION: regionval}) except ValidationError as e: # invalid region name logger.warning("Invalid region value: %s" % regionval, extra={"status_code": 405, "request": request}) # if we didn't collect all the fields, or the values are falsy, # we want to mark that as an error. if len(fields) < 3 or not all(fields.values()): missing_params = [x for x in fields_to_search if x not in fields] msg = ", ".join(missing_params) msg += " invalid for request" raise SuspiciousOperation(msg) else: return function(request, *args, **kwargs)
def __init__(self, opts, namespace, content_id=None, content_type=None, region=None, obj=None): """ :param opts: the `_meta` for resolving the admin view to call ... should usually be :class:`~editregions.models.EditRegionChunk` or a subclass. :param namespace: the admin site name :param content_id: The parent object id :param content_type: The parent object type :param region: string region name :param obj: The :class:`~editregions.models.EditRegionChunk` subclass :return: """ self.opts = opts self.admin_namespace = namespace self.label = opts.verbose_name self.exists = obj is not None self.chunk = obj self.content_id = content_id self.region = region self.module = opts.app_label self.verbose_name = get_app_config_verbose_name(opts.app_label) # if the object already exists in the database, we're probably safe # to assume it's data is the most trustworthy. if self.exists: self.content_type = self.chunk.content_type_id self.content_id = self.chunk.content_id self.region = self.chunk.region self.module = obj._meta.app_label self.verbose_name = get_app_config_verbose_name(obj._meta.app_label) else: try: # attempt to accept either ContentType instances or primary keys # representing them. self.content_type = int(content_type.pk) except AttributeError as e: # Not an object, instead should be an integer self.content_type = content_type if self.region is not None: validate_region_name(self.region) if hasattr(self.opts, "model_name"): model_name = self.opts.model_name else: model_name = self.opts.module_name self.url_parts = { "namespace": self.admin_namespace, "app": self.opts.app_label, "module": model_name, "view": "__error__", } self.querydict = QueryDict("", mutable=True) # update the querystring if they're not already in there. # possibly this is wrong, and should override any that are there? # I'm somewhat confused by it all now. for field in ("content_type", "content_id", "region"): if field not in self.querydict: self.querydict.update({field: getattr(self, field) or 0})
def test_bad_regex(self): error_str = "Enter a valid region name consisting of letters, " "numbers, underscores and hyphens." with self.assertRaisesRegexp(ValidationError, error_str): name = "x$y" validate_region_name(name)
def test_too_long(self): with self.assertRaises(ValidationError): name = "x" * 100 validate_region_name(name)
def test_endswith_underscore(self): with self.assertRaisesRegexp(ValidationError, r"Region names may not " r'end with "_"'): validate_region_name("x_")
def test_startswith_underscore(self): with self.assertRaisesRegexp(ValidationError, r"Region names may not " r'begin with "_"'): validate_region_name("_x")
def test_ok(self): validate_region_name("xyz")