Skip to content

Commit 9164aa8

Browse files
authored
fix: handle nonetype on existing suffix (#308)
* fix: handle nonetype existing suffix * test: fix return value * fix: improved regex * docs: add fix changelog
1 parent 5175c04 commit 9164aa8

File tree

3 files changed

+66
-4
lines changed

3 files changed

+66
-4
lines changed
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<!--
2+
A new scriv changelog fragment.
3+
4+
Uncomment the section that is right (remove the HTML comment wrapper).
5+
For top level release notes, leave all the headers commented out.
6+
-->
7+
8+
<!--
9+
### Removed
10+
11+
- A bullet item for the Removed category.
12+
13+
-->
14+
<!--
15+
### Added
16+
17+
- A bullet item for the Added category.
18+
19+
-->
20+
<!--
21+
### Changed
22+
23+
- A bullet item for the Changed category.
24+
25+
-->
26+
<!--
27+
### Deprecated
28+
29+
- A bullet item for the Deprecated category.
30+
31+
-->
32+
33+
### Fixed
34+
35+
- Improved username collision detection regex to be more precise and avoid false matches
36+
- Added proper error handling for username suffix extraction in `_find_available_username`
37+
38+
<!--
39+
### Security
40+
41+
- A bullet item for the Security category.
42+
43+
-->

src/common/mitol/common/utils/user.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,13 +109,22 @@ def _find_available_username( # noqa: RET503
109109
]
110110
# Find usernames that match the username base and have a numerical
111111
# suffix, then find the max suffix
112-
filter_kwargs = {f"{username_field}__regex": rf"{username_base}[0-9]+"}
112+
filter_kwargs = {f"{username_field}__regex": rf"^{username_base}\d+$"}
113113
existing_usernames = model.objects.filter(**filter_kwargs).values_list(
114114
username_field, flat=True
115115
)
116-
max_suffix = max_or_none(
117-
int(re.search(r"\d+$", username).group()) for username in existing_usernames
118-
)
116+
117+
suffixes = []
118+
for username in existing_usernames:
119+
match = re.search(r"\d+$", username)
120+
if match is not None:
121+
try:
122+
suffixes.append(int(match.group()))
123+
except (ValueError, AttributeError):
124+
continue
125+
126+
max_suffix = max_or_none(suffixes) if suffixes else None
127+
119128
if max_suffix is None:
120129
return "".join([username_base, str(current_min_suffix)])
121130
else:

tests/common/utils/test_user.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,16 @@ def test_create_user_initial_username_too_short(mock_find_username, fake_user):
215215
["abcdefgh97", "abcdefgh98", "abcdefgh99"],
216216
"abcdefg100",
217217
),
218+
(
219+
"someuser",
220+
["someuser2dy"],
221+
"someuser1",
222+
),
223+
(
224+
"someuser",
225+
["someuser1", "someuser2dy", "someuser5"],
226+
"someuser6",
227+
),
218228
],
219229
)
220230
def test_find_available_username(username_base, existing_usernames, expected):

0 commit comments

Comments
 (0)