diff --git a/test/test_util.py b/test/test_util.py index 93c4b7ee6..2cfe2f5cd 100644 --- a/test/test_util.py +++ b/test/test_util.py @@ -83,15 +83,24 @@ class TestUsernameGenerator(unittest.TestCase): def test_basic_ascii_names(self): self.assert_generated_output('jake', 'jake') self.assert_generated_output('frank', 'frank') + self.assert_generated_output('fra-nk', 'fra_nk') def test_names_with_caps(self): self.assert_generated_output('Jake', 'jake') self.assert_generated_output('FranK', 'frank') + def test_multiple_underscores(self): + self.assert_generated_output('ja__ke', 'ja_ke') + self.assert_generated_output('ja___ke', 'ja_ke') + + def test_trailing_underscores(self): + self.assert_generated_output('ja__', 'ja00') + self.assert_generated_output('jake__', 'jake') + def test_short_names(self): - self.assert_generated_output('a', 'a___') - self.assert_generated_output('ab', 'ab__') - self.assert_generated_output('abc', 'abc_') + self.assert_generated_output('a', 'a000') + self.assert_generated_output('ab', 'ab00') + self.assert_generated_output('abc', 'abc0') def test_long_names(self): self.assert_generated_output('abcdefghijklmnopqrstuvwxyz1234567890', @@ -108,16 +117,18 @@ class TestUsernameGenerator(unittest.TestCase): self.assert_generated_output(u'\u0985\u09ad\u09bf\u099c\u09c0\u09a4', 'abhijiit') self.assert_generated_output(u'\u0d05\u0d2d\u0d3f\u0d1c\u0d40\u0d24', 'abhijiit') self.assert_generated_output(u'\u0d2e\u0d32\u0d2f\u0d3e\u0d32\u0d2e\u0d4d', 'mlyaalm') - self.assert_generated_output(u'\ue000', '____') - self.assert_generated_output(u'\u03ff', '____') + self.assert_generated_output(u'\ue000', '0000') + self.assert_generated_output(u'\u03ff', '0000') + + self.assert_generated_output(u'\u0d2e\u0d32\u03ff\u03ff\u0d2e\u0d32', 'mlml') def test_multiple_suggestions(self): name_gen = generate_valid_usernames('a') generated_output = list(islice(name_gen, 4)) - self.assertEquals('a___', generated_output[0]) - self.assertEquals('a__0', generated_output[1]) - self.assertEquals('a__1', generated_output[2]) - self.assertEquals('a__2', generated_output[3]) + self.assertEquals('a000', generated_output[0]) + self.assertEquals('a001', generated_output[1]) + self.assertEquals('a002', generated_output[2]) + self.assertEquals('a003', generated_output[3]) if __name__ == '__main__': diff --git a/util/validation.py b/util/validation.py index e9b954281..085fb0190 100644 --- a/util/validation.py +++ b/util/validation.py @@ -6,7 +6,8 @@ import anunidecode INVALID_PASSWORD_MESSAGE = 'Invalid password, password must be at least ' + \ '8 characters and contain no whitespace.' INVALID_USERNAME_CHARACTERS = r'[^a-z0-9_]' -VALID_CHARACTERS = '_' + string.digits + string.lowercase +VALID_CHARACTERS = string.digits + string.lowercase + MIN_LENGTH = 4 MAX_LENGTH = 30 @@ -48,8 +49,13 @@ def _gen_filler_chars(num_filler_chars): def generate_valid_usernames(input_username): + # Docker's regex: [a-z0-9]+(?:[._-][a-z0-9]+)* normalized = input_username.encode('unidecode', 'ignore').strip().lower() prefix = re.sub(INVALID_USERNAME_CHARACTERS, '_', normalized)[:30] + prefix = re.sub(r'_{2,}', '_', prefix) + + if prefix.endswith('_'): + prefix = prefix[0:len(prefix) - 1] num_filler_chars = max(0, MIN_LENGTH - len(prefix))