Ticket #18852: 18852-aggregate-python-3-port-changes.diff

File 18852-aggregate-python-3-port-changes.diff, 4.7 KB (added by Aymeric Augustin, 12 years ago)
  • django/core/signing.py

    diff --git a/django/core/signing.py b/django/core/signing.py
    index cd9759e..61faee2 100644
    a b start of the base64 JSON.  
    3232There are 65 url-safe characters: the 64 used by url-safe base64 and the ':'.
    3333These functions make use of all of them.
    3434"""
     35
     36from __future__ import unicode_literals
     37
    3538import base64
    3639import json
    3740import time
    from django.conf import settings  
    4144from django.core.exceptions import ImproperlyConfigured
    4245from django.utils import baseconv
    4346from django.utils.crypto import constant_time_compare, salted_hmac
    44 from django.utils.encoding import force_unicode, smart_str
     47from django.utils.encoding import force_str, force_text
    4548from django.utils.importlib import import_module
    4649
    4750
    class SignatureExpired(BadSignature):  
    6063
    6164
    6265def b64_encode(s):
    63     return base64.urlsafe_b64encode(s).strip('=')
     66    return base64.urlsafe_b64encode(s).strip(b'=')
    6467
    6568
    6669def b64_decode(s):
    67     pad = '=' * (-len(s) % 4)
     70    pad = b'=' * (-len(s) % 4)
    6871    return base64.urlsafe_b64decode(s + pad)
    6972
    7073
    def dumps(obj, key=None, salt='django.core.signing', serializer=JSONSerializer,  
    114117    value or re-using a salt value across different parts of your
    115118    application without good cause is a security risk.
    116119    """
    117     data = serializer().dumps(obj)
     120    data = serializer().dumps(obj).encode()
    118121
    119122    # Flag for if it's been compressed or not
    120123    is_compressed = False
    def dumps(obj, key=None, salt='django.core.signing', serializer=JSONSerializer,  
    127130            is_compressed = True
    128131    base64d = b64_encode(data)
    129132    if is_compressed:
    130         base64d = '.' + base64d
     133        base64d = b'.' + base64d
    131134    return TimestampSigner(key, salt=salt).sign(base64d)
    132135
    133136
    def loads(s, key=None, salt='django.core.signing', serializer=JSONSerializer, ma  
    135138    """
    136139    Reverse of dumps(), raises BadSignature if signature fails
    137140    """
    138     base64d = smart_str(
    139         TimestampSigner(key, salt=salt).unsign(s, max_age=max_age))
     141    # TimestampSigner.unsign always returns unicode but base64 and zlib
     142    # compression operate on bytes, so we  decode() here.
     143    base64d = TimestampSigner(key, salt=salt).unsign(s, max_age=max_age).encode()
    140144    decompress = False
    141     if base64d[0] == '.':
     145    if base64d[0] == b'.':
    142146        # It's compressed; uncompress it first
    143147        base64d = base64d[1:]
    144148        decompress = True
    145149    data = b64_decode(base64d)
    146150    if decompress:
    147151        data = zlib.decompress(data)
    148     return serializer().loads(data)
     152    return serializer().loads(data.decode())
    149153
    150154
    151155class Signer(object):
     156
    152157    def __init__(self, key=None, sep=':', salt=None):
    153         self.sep = sep
    154         self.key = key or settings.SECRET_KEY
    155         self.salt = salt or ('%s.%s' %
    156             (self.__class__.__module__, self.__class__.__name__))
     158        # Use of native strings in all versions of Python
     159        self.sep = str(sep)
     160        self.key = str(key or settings.SECRET_KEY)
     161        self.salt = str(salt or
     162            '%s.%s' % (self.__class__.__module__, self.__class__.__name__))
    157163
    158164    def signature(self, value):
    159         return base64_hmac(self.salt + 'signer', value, self.key)
     165        signature = base64_hmac(self.salt + 'signer', value, self.key)
     166        # Convert the signature from bytes to str only on Python 3
     167        return force_str(signature)
    160168
    161169    def sign(self, value):
    162         value = smart_str(value)
    163         return '%s%s%s' % (value, self.sep, self.signature(value))
     170        value = force_str(value)
     171        return str('%s%s%s') % (value, self.sep, self.signature(value))
    164172
    165173    def unsign(self, signed_value):
    166         signed_value = smart_str(signed_value)
     174        signed_value = force_str(signed_value)
    167175        if not self.sep in signed_value:
    168176            raise BadSignature('No "%s" found in value' % self.sep)
    169177        value, sig = signed_value.rsplit(self.sep, 1)
    170178        if constant_time_compare(sig, self.signature(value)):
    171             return force_unicode(value)
     179            return force_text(value)
    172180        raise BadSignature('Signature "%s" does not match' % sig)
    173181
    174182
    class TimestampSigner(Signer):  
    178186        return baseconv.base62.encode(int(time.time()))
    179187
    180188    def sign(self, value):
    181         value = smart_str('%s%s%s' % (value, self.sep, self.timestamp()))
    182         return '%s%s%s' % (value, self.sep, self.signature(value))
     189        value = force_str(value)
     190        value = str('%s%s%s') % (value, self.sep, self.timestamp())
     191        return super(TimestampSigner, self).sign(value)
    183192
    184193    def unsign(self, value, max_age=None):
    185194        result =  super(TimestampSigner, self).unsign(value)
Back to Top