Skip to content

Commit

Permalink
Update rules for setting usernames from emails
Browse files Browse the repository at this point in the history
If an email has a valid username we will use it to set the username
  • Loading branch information
FrankApiyo committed Sep 18, 2024
1 parent 6f005ce commit 33292ed
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 4 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ OPENID_CONNECT_VIEWSET_CONFIG = {
# that's used to validate all field inputs retrieved for the particular key
"FIELD_VALIDATION_REGEX": {
"username": {
"regex": "^(?!\d+$).{4,}$",
"regex": "^(?!\d+$)[a-zA-Z0-9]{3,}$",
"help_text": "Username should only contain alpha numeric characters",
}
},
Expand Down
2 changes: 1 addition & 1 deletion oidc/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"JWT_ALGORITHM": "HS256",
"FIELD_VALIDATION_REGEX": {
"username": {
"regex": "^(?!\d+$).{4,}$", # noqa
"regex": "^(?!\d+$)[a-zA-Z0-9_]{3,}$", # noqa
"help_text": "Username should only contain alpha numeric characters",
}
},
Expand Down
3 changes: 2 additions & 1 deletion oidc/viewsets.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,8 @@ def _clean_user_data(self, user_data) -> Tuple[dict, Optional[list]]:
and username_regex.search(username)
):
user_data["username"] = username
missing_fields.remove("username")
if "username" in missing_fields:
missing_fields.remove("username")

return user_data, missing_fields

Expand Down
74 changes: 73 additions & 1 deletion tests/test_viewsets.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,10 @@
"SSO_COOKIE_DATA": "email",
"JWT_ALGORITHM": "HS256",
"JWT_SECRET_KEY": "abc",
"REPLACE_USERNAME_CHARACTERS": "-.",
"FIELD_VALIDATION_REGEX": {
"username": {
"regex": "^(?!\d+$).{4,}$",
"regex": "^(?!\d+$)[a-zA-Z0-9_]{3,}$",
"help_text": "Username should only contain word characters & numbers i.e datatester23",
},
},
Expand Down Expand Up @@ -84,6 +85,77 @@ def test_returns_data_entry_template_on_missing_username_claim(self):
self.assertEqual(response.status_code, 200)
self.assertEqual(response.template_name, "oidc/oidc_user_data_entry.html")

@override_settings(OPENID_CONNECT_VIEWSET_CONFIG=OPENID_CONNECT_VIEWSET_CONFIG)
def test_user_created_successfully_when_email_has_a_valid_username(self):
"""
Test that the user is created ok when
username is not present in decoded token but email has a valid username
"""
view = UserModelOpenIDConnectViewset.as_view({"post": "callback"})
with patch(
"oidc.viewsets.OpenIDClient.verify_and_decode_id_token"
) as mock_func:
mock_func.return_value = {
"family_name": "bob",
"given_name": "just bob",
"username": "[email protected]",
"email": "[email protected]",
}

data = {"id_token": "sadsdaio3209lkasdlkas0d.sdojdsiad.iosdadia"}
request = self.factory.post("/", data=data)
response = view(request, auth_server="default")
self.assertEqual(response.status_code, 302)
user = User.objects.get(username="boby")
self.assertEqual(user.email, "[email protected]")

@override_settings(OPENID_CONNECT_VIEWSET_CONFIG=OPENID_CONNECT_VIEWSET_CONFIG)
def test_returns_data_entry_template_on_invalid_username(self):
"""
Test that users are redirected to the data entry
page when username is not present in decoded token and
provided email also does not provide a valid username
"""
view = UserModelOpenIDConnectViewset.as_view({"post": "callback"})
with patch(
"oidc.viewsets.OpenIDClient.verify_and_decode_id_token"
) as mock_func:
mock_func.return_value = {
"family_name": "bob",
"given_name": "just bob",
"email": "[email protected]",
}

data = {"id_token": "sadsdaio3209lkasdlkas0d.sdojdsiad.iosdadia"}
request = self.factory.post("/", data=data)
response = view(request, auth_server="default")
self.assertEqual(response.status_code, 200)
self.assertEqual(response.template_name, "oidc/oidc_user_data_entry.html")

@override_settings(OPENID_CONNECT_VIEWSET_CONFIG=OPENID_CONNECT_VIEWSET_CONFIG)
def test_returns_data_entry_template_on_invalid_username_and_bad_email(self):
"""
Test that users are redirected to the data entry
page when username is not present in decoded token and
provided email also does not provide a valid username
"""
view = UserModelOpenIDConnectViewset.as_view({"post": "callback"})
with patch(
"oidc.viewsets.OpenIDClient.verify_and_decode_id_token"
) as mock_func:
mock_func.return_value = {
"family_name": "bob",
"given_name": "just bob",
"username": "[email protected]",
"email": "[email protected]",
}

data = {"id_token": "sadsdaio3209lkasdlkas0d.sdojdsiad.iosdadia"}
request = self.factory.post("/", data=data)
response = view(request, auth_server="default")
self.assertEqual(response.status_code, 400)
self.assertEqual(response.template_name, "oidc/oidc_user_data_entry.html")

def test_unrecoverable_error_on_missing_claim(self):
"""
Test that an error is returned when a required claim field other than the
Expand Down

0 comments on commit 33292ed

Please sign in to comment.