Commits

Andriy Kornatskyy committed bb0f122

Added urlsafe_base64 rule.

Comments (0)

Files changed (5)

doc/userguide.rst

 * ``base64``. Ensures a valid base64 string input (supports
   alternative alphabet for ``+`` and ``/`` characters). See
   :py:class:`~wheezy.validation.rules.Base64Rule`.
+* ``urlsafe_base64``. Ensures a valid base64 string input using an alphabet,
+  which substitutes ``-`` instead of ``+`` and ``_`` instead of ``/`` in
+  the standard Base64 alphabet. The input can still contain ``=``. See
+  :py:class:`~wheezy.validation.rules.URLSafeBase64Rule`.
 * ``range``. Ensures value is in range defined by this rule. Works with any
   numbers including int, float, decimal, etc. Supported range attributes
   include: ``min``, ``max``. See

i18n/en/LC_MESSAGES/validation.po

 msgid "Required to be a valid base64 string."
 msgstr "Required to be a valid base64 string."
 
-#: src/wheezy/validation/rules.py:363
+#: src/wheezy/validation/rules.py:356
+msgid "Required to be a valid URL-safe base64 string."
+msgstr "Required to be a valid URL-safe base64 string."
+
+#: src/wheezy/validation/rules.py:381
 #, python-format
 msgid "Required to be greater or equal to %(min)s."
 msgstr "Required to be greater or equal to %(min)s."
 
-#: src/wheezy/validation/rules.py:368
+#: src/wheezy/validation/rules.py:386
 #, python-format
 msgid "The value must fall within the range %(min)s - %(max)s"
 msgstr "The value must fall within the range %(min)s - %(max)s"
 
-#: src/wheezy/validation/rules.py:375
+#: src/wheezy/validation/rules.py:393
 #, python-format
 msgid "Exceeds maximum allowed value of %(max)s."
 msgstr "Exceeds maximum allowed value of %(max)s."
 
-#: src/wheezy/validation/rules.py:501
+#: src/wheezy/validation/rules.py:519
 msgid "The value does not belong to the list of known items."
 msgstr "The value does not belong to the list of known items."
 
-#: src/wheezy/validation/rules.py:532
+#: src/wheezy/validation/rules.py:550
 msgid "Required to be above a minimum allowed."
 msgstr "Required to be above a minimum allowed."
 
-#: src/wheezy/validation/rules.py:537
+#: src/wheezy/validation/rules.py:555
 msgid "Must fall within a valid range."
 msgstr "Must fall within a valid range."
 
-#: src/wheezy/validation/rules.py:543
+#: src/wheezy/validation/rules.py:561
 msgid "Exceeds maximum allowed."
 msgstr "Exceeds maximum allowed."
 
-#: src/wheezy/validation/rules.py:694
+#: src/wheezy/validation/rules.py:712
 msgid "Required to satisfy a converter format."
 msgstr "Required to satisfy a converter format."
 
-#: src/wheezy/validation/rules.py:714
+#: src/wheezy/validation/rules.py:732
 msgid "Required to satisfy an integer format."
 msgstr "Required to satisfy an integer format."

i18n/ru/LC_MESSAGES/validation.po

 msgid "Required to be a valid base64 string."
 msgstr "Обязательно должно соответствовать строке в base64 формате."
 
+msgid "Required to be a valid URL-safe base64 string."
+msgstr "Обязательно должно соответствовать строке в URL-безопасном base64 формате."
+
 #, python-format
 msgid "Required to be greater or equal to %(min)s."
 msgstr "Должно быть больше или равно %(min)s."

src/wheezy/validation/rules.py

         return Base64Rule(altchars, message_template)
 
 
+class URLSafeBase64Rule(Base64Rule):
+    """ Ensures a valid base64 URL-safe string input using an alphabet,
+        which substitutes `-` instead of `+` and `_` instead of `/` in
+        the standard Base64 alphabet. The input can still contain `=`.
+    """
+    __slots__ = ()
+
+    def __init__(self, message_template=None):
+        super(URLSafeBase64Rule, self).__init__(
+            '-_', message_template or
+            _('Required to be a valid URL-safe base64 string.'))
+
+    def __call__(self, message_template):
+        """ Let you customize message template.
+        """
+        return URLSafeBase64Rule(message_template)
+
+
 class RangeRule(object):
     """ Ensures value is in range defined by this rule.
 
 regex = RegexRule
 relative_date = RelativeDateDeltaRule
 relative_datetime = RelativeDateTimeDeltaRule
+relative_timestamp = RelativeUnixTimeDeltaRule
 relative_tzdate = RelativeTZDateDeltaRule
 relative_tzdatetime = RelativeTZDateTimeDeltaRule
 relative_unixtime = RelativeUnixTimeDeltaRule
-relative_timestamp = RelativeUnixTimeDeltaRule
 relative_utcdate = RelativeUTCDateDeltaRule
 relative_utcdatetime = RelativeUTCDateTimeDeltaRule
+relative_utctimestamp = RelativeUTCUnixTimeDeltaRule
 relative_utcunixtime = RelativeUTCUnixTimeDeltaRule
-relative_utctimestamp = RelativeUTCUnixTimeDeltaRule
 required = RequiredRule()
 scientific = ScientificRule()
 slug = SlugRule()
+urlsafe_base64 = URLSafeBase64Rule()
 value_predicate = must = ValuePredicateRule

src/wheezy/validation/tests/test_rules.py

         assert not v('dx+/')
         assert errors
 
+    def test_urlsafe_base64(self):
+        """ Test `urlsafe_base64` rule.
+        """
+        from wheezy.validation.rules import URLSafeBase64Rule
+        from wheezy.validation.rules import urlsafe_base64
+
+        # shortcut
+        assert isinstance(urlsafe_base64, URLSafeBase64Rule)
+
+        errors = []
+        r = urlsafe_base64
+        v = lambda i: r.validate(i, None, None, errors, lambda s: s)
+
+        assert v('d2hlZXp5')
+        assert v('d2hlZXp51-==')
+        assert v('d2hlZXp51_==')
+        assert v('d2hlZXp51-_=')
+        assert not errors
+
+        assert not v('dx+/')
+        assert errors
+
+        r = urlsafe_base64(message_template='customized')
+        assert r != urlsafe_base64
+        assert 'customized' == r.message_template
+
     def test_range_strategies(self):
         """ Test `range` rule strategies.
         """