Ticket #14881: django-auth-string-pk-support.patch

File django-auth-string-pk-support.patch, 5.4 KB (added by jonash, 4 years ago)
  • django/contrib/auth/urls.py

    # HG changeset patch -- Bitbucket.org
    # Project django-nonrel
    # URL http://bitbucket.org/wkornewald/django-nonrel/overview
    # User Waldemar Kornewald <wkornewald>
    # Date 1291970757 -3600
    # Node ID a632a02c9ff26f80d0565551cb6ea8c23699dd71
    # Parent  af6be5bfdb85ce5f88467b391346b6183fd645c5
    Fixed auth app's password reset feature on DBs that have a string-based AutoField. Thanks a lot to Jonas Haag for the patch!
    
    a b urlpatterns = patterns('', 
    1111    (r'^password_change/done/$', 'django.contrib.auth.views.password_change_done'),
    1212    (r'^password_reset/$', 'django.contrib.auth.views.password_reset'),
    1313    (r'^password_reset/done/$', 'django.contrib.auth.views.password_reset_done'),
    14     (r'^reset/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/$', 'django.contrib.auth.views.password_reset_confirm'),
     14    (r'^reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>.+)/$', 'django.contrib.auth.views.password_reset_confirm'),
    1515    (r'^reset/done/$', 'django.contrib.auth.views.password_reset_complete'),
    1616)
    17 
  • django/contrib/auth/views.py

    a b from django.shortcuts import render_to_r 
    1313from django.contrib.sites.models import get_current_site
    1414from django.http import HttpResponseRedirect, Http404
    1515from django.template import RequestContext
    16 from django.utils.http import urlquote, base36_to_int
     16from django.utils.http import urlquote, urlsafe_base64_decode
    1717from django.utils.translation import ugettext as _
    1818from django.contrib.auth.models import User
    1919from django.views.decorators.cache import never_cache
    def password_reset_done(request, templat 
    131131    return render_to_response(template_name, context_instance=RequestContext(request))
    132132
    133133# Doesn't need csrf_protect since no-one can guess the URL
    134 def password_reset_confirm(request, uidb36=None, token=None, template_name='registration/password_reset_confirm.html',
     134def password_reset_confirm(request, uidb64=None, token=None, template_name='registration/password_reset_confirm.html',
    135135                           token_generator=default_token_generator, set_password_form=SetPasswordForm,
    136136                           post_reset_redirect=None):
    137137    """
    138138    View that checks the hash in a password reset link and presents a
    139139    form for entering a new password.
    140140    """
    141     assert uidb36 is not None and token is not None # checked by URLconf
     141    assert uidb64 is not None and token is not None # checked by URLconf
    142142    if post_reset_redirect is None:
    143143        post_reset_redirect = reverse('django.contrib.auth.views.password_reset_complete')
    144144    try:
    145         uid_int = base36_to_int(uidb36)
    146         user = User.objects.get(id=uid_int)
     145        uid = urlsafe_base64_decode(str(uidb64))
     146        user = User.objects.get(id=uid)
    147147    except (ValueError, User.DoesNotExist):
    148148        user = None
    149149
  • django/contrib/auth/tests/templates/registration/password_reset_email.html

    a b  
    1 {{ protocol }}://{{ domain }}/reset/{{ uid }}-{{ token }}/
     1{{ protocol }}://{{ domain }}/reset/{{ uid }}/{{ token }}/
  • django/contrib/auth/forms.py

    a b from django.contrib.sites.models import  
    55from django.template import Context, loader
    66from django import forms
    77from django.utils.translation import ugettext_lazy as _
    8 from django.utils.http import int_to_base36
     8from django.utils.http import urlsafe_base64_encode
    99
    1010class UserCreationForm(forms.ModelForm):
    1111    """
    class PasswordResetForm(forms.Form): 
    134134                'email': user.email,
    135135                'domain': domain,
    136136                'site_name': site_name,
    137                 'uid': int_to_base36(user.id),
     137                'uid': urlsafe_base64_encode(str(user.id)),
    138138                'user': user,
    139139                'token': token_generator.make_token(user),
    140140                'protocol': use_https and 'https' or 'http',
  • django/utils/http.py

    a b  
    11import re
    22import urllib
     3import base64
     4from binascii import Error as BinasciiError
    35from email.Utils import formatdate
    46
    57from django.utils.encoding import smart_str, force_unicode
    def http_date(epoch_seconds=None): 
    7375
    7476def base36_to_int(s):
    7577    """
    76     Convertd a base 36 string to an integer
     78    Converts a base 36 string to an integer
    7779    """
    7880    return int(s, 36)
    7981
    def int_to_base36(i): 
    98100        factor -= 1
    99101    return ''.join(base36)
    100102
     103def urlsafe_base64_encode(s):
     104    return base64.urlsafe_b64encode(s).rstrip('\n=')
     105
     106def urlsafe_base64_decode(s):
     107    assert isinstance(s, str)
     108    try:
     109        return base64.urlsafe_b64decode(s.ljust(len(s) + len(s) % 4, '='))
     110    except (LookupError, BinasciiError), e:
     111        raise ValueError(e)
     112
    101113def parse_etags(etag_str):
    102114    """
    103115    Parses a string with one or several etags passed in If-None-Match and
  • django/contrib/auth/tests/views.py

    a b class PasswordResetTest(AuthViewsTestCas 
    102102
    103103    def test_confirm_invalid_user(self):
    104104        # Ensure that we get a 200 response for a non-existant user, not a 404
    105         response = self.client.get('/reset/123456-1-1/')
     105        response = self.client.get('/reset/123456/1-1/')
    106106        self.assertEquals(response.status_code, 200)
    107107        self.assert_("The password reset link was invalid" in response.content)
Back to Top