Removed the various philo.validators URL validators since they served no real purpose...
authorStephen Burrows <stephen.r.burrows@gmail.com>
Wed, 11 May 2011 21:12:49 +0000 (17:12 -0400)
committerStephen Burrows <stephen.r.burrows@gmail.com>
Wed, 11 May 2011 21:12:49 +0000 (17:12 -0400)
docs/index.rst
docs/validators.rst [new file with mode: 0644]
philo/contrib/shipherd/models.py
philo/contrib/sobol/models.py
philo/models/nodes.py
philo/validators.py

index a1490b3..36470fb 100644 (file)
@@ -16,6 +16,7 @@ Contents:
    exceptions
    middleware
    signals
    exceptions
    middleware
    signals
+   validators
 
 Indices and tables
 ==================
 
 Indices and tables
 ==================
diff --git a/docs/validators.rst b/docs/validators.rst
new file mode 100644 (file)
index 0000000..f91818b
--- /dev/null
@@ -0,0 +1,5 @@
+Validators
+==========
+
+.. automodule:: philo.validators
+       :members:
index 3ff5c44..a09f385 100644 (file)
@@ -8,7 +8,6 @@ from django.db import models
 from django.forms.models import model_to_dict
 
 from philo.models import TreeEntity, Node, TreeManager, Entity, TargetURLModel
 from django.forms.models import model_to_dict
 
 from philo.models import TreeEntity, Node, TreeManager, Entity, TargetURLModel
-from philo.validators import RedirectValidator
 
 
 DEFAULT_NAVIGATION_DEPTH = 3
 
 
 DEFAULT_NAVIGATION_DEPTH = 3
index 2cb1651..dbf37ef 100644 (file)
@@ -4,6 +4,7 @@ from django.conf import settings
 from django.conf.urls.defaults import patterns, url
 from django.contrib import messages
 from django.core.exceptions import ValidationError
 from django.conf.urls.defaults import patterns, url
 from django.contrib import messages
 from django.core.exceptions import ValidationError
+from django.core.validators import URLValidator
 from django.db import models
 from django.http import HttpResponseRedirect, Http404, HttpResponse
 from django.utils import simplejson as json
 from django.db import models
 from django.http import HttpResponseRedirect, Http404, HttpResponse
 from django.utils import simplejson as json
@@ -15,7 +16,6 @@ from philo.contrib.sobol.utils import HASH_REDIRECT_GET_KEY, URL_REDIRECT_GET_KE
 from philo.exceptions import ViewCanNotProvideSubpath
 from philo.models import MultiView, Page
 from philo.models.fields import SlugMultipleChoiceField
 from philo.exceptions import ViewCanNotProvideSubpath
 from philo.models import MultiView, Page
 from philo.models.fields import SlugMultipleChoiceField
-from philo.validators import RedirectValidator
 
 eventlet = None
 if getattr(settings, 'SOBOL_USE_EVENTLET', False):
 
 eventlet = None
 if getattr(settings, 'SOBOL_USE_EVENTLET', False):
@@ -83,7 +83,7 @@ class Search(models.Model):
 
 class ResultURL(models.Model):
        search = models.ForeignKey(Search, related_name='result_urls')
 
 class ResultURL(models.Model):
        search = models.ForeignKey(Search, related_name='result_urls')
-       url = models.TextField(validators=[RedirectValidator()])
+       url = models.TextField(validators=[URLValidator()])
        
        def __unicode__(self):
                return self.url
        
        def __unicode__(self):
                return self.url
index 899303f..a9b77fb 100644 (file)
@@ -15,7 +15,6 @@ from philo.exceptions import MIDDLEWARE_NOT_CONFIGURED, ViewCanNotProvideSubpath
 from philo.models.base import TreeEntity, Entity, QuerySetMapper, register_value_model
 from philo.models.fields import JSONField
 from philo.utils import ContentTypeSubclassLimiter
 from philo.models.base import TreeEntity, Entity, QuerySetMapper, register_value_model
 from philo.models.fields import JSONField
 from philo.utils import ContentTypeSubclassLimiter
-from philo.validators import RedirectValidator
 from philo.signals import view_about_to_render, view_finished_rendering
 
 
 from philo.signals import view_about_to_render, view_finished_rendering
 
 
@@ -291,8 +290,8 @@ class TargetURLModel(models.Model):
        """An abstract parent class for models which deal in targeting a url."""
        #: An optional :class:`ForeignKey` to a :class:`Node`. If provided, that node will be used as the basis for the redirect.
        target_node = models.ForeignKey(Node, blank=True, null=True, related_name="%(app_label)s_%(class)s_related")
        """An abstract parent class for models which deal in targeting a url."""
        #: An optional :class:`ForeignKey` to a :class:`Node`. If provided, that node will be used as the basis for the redirect.
        target_node = models.ForeignKey(Node, blank=True, null=True, related_name="%(app_label)s_%(class)s_related")
-       #: A :class:`CharField` which may contain an absolute or relative URL. This will be validated with :class:`philo.validators.RedirectValidator`.
-       url_or_subpath = models.CharField(max_length=200, validators=[RedirectValidator()], blank=True, help_text="Point to this url or, if a node is defined and accepts subpaths, this subpath of the node.")
+       #: A :class:`CharField` which may contain an absolute or relative URL, or the name of a node's subpath.
+       url_or_subpath = models.CharField(max_length=200, blank=True, help_text="Point to this url or, if a node is defined and accepts subpaths, this subpath of the node.")
        #: A :class:`~philo.models.fields.JSONField` instance. If the value of :attr:`reversing_parameters` is not None, the :attr:`url_or_subpath` will be treated as the name of a view to be reversed. The value of :attr:`reversing_parameters` will be passed into the reversal as args if it is a list or as kwargs if it is a dictionary. Otherwise it will be ignored.
        reversing_parameters = JSONField(blank=True, help_text="If reversing parameters are defined, url_or_subpath will instead be interpreted as the view name to be reversed.")
        
        #: A :class:`~philo.models.fields.JSONField` instance. If the value of :attr:`reversing_parameters` is not None, the :attr:`url_or_subpath` will be treated as the name of a view to be reversed. The value of :attr:`reversing_parameters` will be passed into the reversal as args if it is a list or as kwargs if it is a dictionary. Otherwise it will be ignored.
        reversing_parameters = JSONField(blank=True, help_text="If reversing parameters are defined, url_or_subpath will instead be interpreted as the view name to be reversed.")
        
index 144699e..349dd56 100644 (file)
@@ -1,7 +1,6 @@
 import re
 
 from django.core.exceptions import ValidationError
 import re
 
 from django.core.exceptions import ValidationError
-from django.core.validators import RegexValidator
 from django.template import Template, Parser, Lexer, TOKEN_BLOCK, TOKEN_VAR, TemplateSyntaxError
 from django.utils import simplejson as json
 from django.utils.html import escape, mark_safe
 from django.template import Template, Parser, Lexer, TOKEN_BLOCK, TOKEN_VAR, TemplateSyntaxError
 from django.utils import simplejson as json
 from django.utils.html import escape, mark_safe
@@ -10,6 +9,7 @@ from django.utils.translation import ugettext_lazy as _
 from philo.utils import LOADED_TEMPLATE_ATTR
 
 
 from philo.utils import LOADED_TEMPLATE_ATTR
 
 
+#: Tags which are considered insecure and are therefore always disallowed by secure :class:`TemplateValidator` instances.
 INSECURE_TAGS = (
        'load',
        'extends',
 INSECURE_TAGS = (
        'load',
        'extends',
@@ -18,34 +18,8 @@ INSECURE_TAGS = (
 )
 
 
 )
 
 
-class RedirectValidator(RegexValidator):
-       """Based loosely on the URLValidator, but no option to verify_exists"""
-       regex = re.compile(
-               r'^(?:https?://' # http:// or https://
-               r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?|' #domain...
-               r'localhost|' #localhost...
-               r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' # ...or ip
-               r'(?::\d+)?' # optional port
-               r'(?:/?|[/?#]?\S+)|'
-               r'[^?#\s]\S*)$',
-               re.IGNORECASE)
-       message = _(u'Enter a valid absolute or relative redirect target')
-
-
-class URLLinkValidator(RegexValidator):
-       """Based loosely on the URLValidator, but no option to verify_exists"""
-       regex = re.compile(
-               r'^(?:https?://' # http:// or https://
-               r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?|' #domain...
-               r'localhost|' #localhost...
-               r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' # ...or ip
-               r'(?::\d+)?' # optional port
-               r'|)' # also allow internal links
-               r'(?:/?|[/?#]?\S+)$', re.IGNORECASE)
-       message = _(u'Enter a valid absolute or relative redirect target')
-
-
 def json_validator(value):
 def json_validator(value):
+       """Validates whether ``value`` is a valid json string."""
        try:
                json.loads(value)
        except Exception, e:
        try:
                json.loads(value)
        except Exception, e:
@@ -130,6 +104,14 @@ def linebreak_iter(template_source):
 
 
 class TemplateValidator(object): 
 
 
 class TemplateValidator(object): 
+       """
+       Validates whether a string represents valid Django template code.
+       
+       :param allow: ``None`` or an iterable of tag names which are explicitly allowed. If provided, tags whose names are not in the iterable will cause a ValidationError to be raised if they are used in the template code.
+       :param disallow: ``None`` or an iterable of tag names which are explicitly allowed. If provided, tags whose names are in the iterable will cause a ValidationError to be raised if they are used in the template code. If a tag's name is in ``allow`` and ``disallow``, it will be disallowed.
+       :param secure: If the validator is set to secure, it will automatically disallow the tag names listed in :const:`INSECURE_TAGS`. Defaults to ``True``.
+       
+       """
        def __init__(self, allow=None, disallow=None, secure=True):
                self.allow = allow
                self.disallow = disallow
        def __init__(self, allow=None, disallow=None, secure=True):
                self.allow = allow
                self.disallow = disallow