diff --git a/changelog/7953-username-validation.yaml b/changelog/7953-username-validation.yaml new file mode 100644 index 00000000000..3cb3cc5d925 --- /dev/null +++ b/changelog/7953-username-validation.yaml @@ -0,0 +1,4 @@ +type: Fixed +description: Added character and length validation to usernames on user creation +pr: 7953 +labels: [] diff --git a/src/fides/api/schemas/user.py b/src/fides/api/schemas/user.py index bf35a54cde7..bbc086bbe8a 100644 --- a/src/fides/api/schemas/user.py +++ b/src/fides/api/schemas/user.py @@ -15,6 +15,8 @@ from fides.api.models.fides_user import FidesUser from fides.api.models.fides_user_invite import FidesUserInvite +USERNAME_PATTERN = r"[a-zA-Z0-9._-]{1,100}" + class PrivacyRequestUser(FidesSchema): """Data we can expose via PrivacyRequest user relations (reviewer, submitter, etc.)""" @@ -38,9 +40,12 @@ class UserCreate(FidesSchema): @field_validator("username") @classmethod def validate_username(cls, username: str) -> str: - """Ensure username does not have spaces.""" - if " " in username: - raise ValueError("Usernames cannot have spaces.") + """Ensure username contains only valid characters and is within length limits.""" + if not re.fullmatch(USERNAME_PATTERN, username): + raise ValueError( + "Usernames must be 1-100 characters and may only contain " + "letters, numbers, periods, underscores, and hyphens." + ) return username @field_validator("password") diff --git a/tests/lib/test_oauth_schemas_user.py b/tests/lib/test_oauth_schemas_user.py index b6a196103eb..5463013f66b 100644 --- a/tests/lib/test_oauth_schemas_user.py +++ b/tests/lib/test_oauth_schemas_user.py @@ -30,10 +30,22 @@ def test_bad_password(password, message): assert message in str(excinfo.value) -def test_user_create_user_name_with_spaces(): - with pytest.raises(ValueError): +@pytest.mark.parametrize( + "username", + [ + "some user", + "user&name", + "user=name", + "user