Update and refactor random password generator

This commit is contained in:
Bill DeRusha
2018-04-12 17:58:11 -04:00
parent 0a65a2ff8a
commit d1ed33ac23
10 changed files with 55 additions and 61 deletions

View File

@@ -38,6 +38,7 @@ from edxmako.shortcuts import render_to_response, render_to_string
from openedx.core.djangoapps.external_auth.djangostore import DjangoOpenIDStore
from openedx.core.djangoapps.external_auth.models import ExternalAuthMap
from openedx.core.djangoapps.site_configuration.helpers import get_value
from openedx.core.djangoapps.user_api.accounts.utils import generate_password
from student.helpers import get_next_url_for_login_page
from student.models import UserProfile
from util.db import outer_atomic
@@ -78,12 +79,6 @@ def default_render_failure(request, # pylint: disable=unused-argument
# -----------------------------------------------------------------------------
def generate_password(length=12, chars=string.letters + string.digits):
"""Generate internal password for externally authenticated user"""
choice = random.SystemRandom().choice
return ''.join([choice(chars) for _i in range(length)])
@transaction.non_atomic_requests
@csrf_exempt
def openid_login_complete(request,

View File

@@ -16,7 +16,7 @@ from student.tests.factories import UserFactory
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
from ..utils import format_social_link, validate_social_link
from ..utils import format_social_link, validate_social_link, generate_password
@ddt.ddt
@@ -135,3 +135,29 @@ class CompletionUtilsTestCase(SharedModuleStoreTestCase, CompletionWaffleTestMix
)
)
self.assertEqual(empty_block_url, None)
class GeneratePasswordTest(TestCase):
"""Tests formation of randomly generated passwords."""
def test_default_args(self):
password = generate_password()
self.assertEqual(12, len(password))
self.assertTrue(any(c.isdigit for c in password))
self.assertTrue(any(c.isalpha for c in password))
def test_length(self):
length = 25
self.assertEqual(length, len(generate_password(length=length)))
def test_chars(self):
char = '!'
password = generate_password(length=12, chars=(char,))
self.assertTrue(any(c.isdigit for c in password))
self.assertTrue(any(c.isalpha for c in password))
self.assertEqual(char * 10, password[2:])
def test_min_length(self):
with self.assertRaises(ValueError):
generate_password(length=7)

View File

@@ -1,7 +1,9 @@
"""
Utility methods for the account settings.
"""
import random
import re
import string
from urlparse import urlparse
from django.conf import settings
@@ -176,3 +178,17 @@ def retrieve_last_sitewide_block_completed(username):
course_key=text_type(item.location.course_key),
location=text_type(item.location),
)
def generate_password(length=12, chars=string.letters + string.digits):
"""Generate a valid random password"""
if length < 8:
raise ValueError("password must be at least 8 characters")
choice = random.SystemRandom().choice
password = ''
password += choice(string.digits)
password += choice(string.letters)
password += ''.join([choice(chars) for _i in xrange(length - 2)])
return password