def test_base36(self): # reciprocity works for n in [0, 1, 1000, 1000000]: self.assertEqual(n, http.base36_to_int(http.int_to_base36(n))) if not six.PY3: self.assertEqual(sys.maxint, http.base36_to_int(http.int_to_base36(sys.maxint))) # bad input self.assertRaises(ValueError, http.int_to_base36, -1) if not six.PY3: self.assertRaises(ValueError, http.int_to_base36, sys.maxint + 1) for n in ['1', 'foo', {1: 2}, (1, 2, 3), 3.141]: self.assertRaises(TypeError, http.int_to_base36, n) for n in ['#', ' ']: self.assertRaises(ValueError, http.base36_to_int, n) for n in [123, {1: 2}, (1, 2, 3), 3.141]: self.assertRaises(TypeError, http.base36_to_int, n) # more explicit output testing for n, b36 in [(0, '0'), (1, '1'), (42, '16'), (818469960, 'django')]: self.assertEqual(http.int_to_base36(n), b36) self.assertEqual(http.base36_to_int(b36), n)
def password_reset_confirm(request, uidb36=None, token=None, template_name='registration/password_reset_confirm.html', token_generator=default_token_generator, set_password_form=SetPasswordForm, post_reset_redirect=None, current_app=None, extra_context=None): """ View that checks the hash in a password reset link and presents a form for entering a new password. """ assert uidb36 is not None and token is not None # checked by URLconf if post_reset_redirect is None: post_reset_redirect = reverse('djangocg.contrib.auth.views.password_reset_complete') try: uid_int = base36_to_int(uidb36) user = User.objects.get(id=uid_int) except (ValueError, OverflowError, User.DoesNotExist): user = None if user is not None and token_generator.check_token(user, token): validlink = True if request.method == 'POST': form = set_password_form(user, request.POST) if form.is_valid(): form.save() return HttpResponseRedirect(post_reset_redirect) else: form = set_password_form(None) else: validlink = False form = None context = { 'form': form, 'validlink': validlink, } if extra_context is not None: context.update(extra_context) return TemplateResponse(request, template_name, context, current_app=current_app)
def check_token(self, user, token): """ Check that a password reset token is correct for a given user. """ # Parse the token try: ts_b36, hash = token.split("-") except ValueError: return False try: ts = base36_to_int(ts_b36) except ValueError: return False # Check that the timestamp/uid has not been tampered with if not constant_time_compare(self._make_token_with_timestamp(user, ts), token): return False # Check the timestamp is within limit if (self._num_days(self._today()) - ts) > settings.PASSWORD_RESET_TIMEOUT_DAYS: return False return True