Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change login name after changing email in sites where "use email as login" is enabled #1836

Merged
merged 5 commits into from
Nov 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions news/1835.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix log in after changing email when "email as login" is enabled
[erral]
9 changes: 9 additions & 0 deletions src/plone/restapi/services/users/update.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,11 @@ def reply(self):
self.set_member_portrait(user, value)
user.setMemberProperties(mapping={key: value}, force_empty=True)

if security.use_email_as_login and "email" in user_settings_to_update:
value = user_settings_to_update["email"]
pas = getToolByName(self.context, "acl_users")
pas.updateLoginName(user.getId(), value)

roles = user_settings_to_update.get("roles", {})
if roles:
to_add = [key for key, enabled in roles.items() if enabled]
Expand Down Expand Up @@ -142,6 +147,10 @@ def reply(self):
self.set_member_portrait(user, value)
user.setMemberProperties(mapping={key: value}, force_empty=True)

if security.use_email_as_login and "email" in user_settings_to_update:
value = user_settings_to_update["email"]
set_own_login_name(user, value)

else:
if self._is_anonymous:
return self._error(
Expand Down
227 changes: 227 additions & 0 deletions src/plone/restapi/tests/test_services_users.py
Original file line number Diff line number Diff line change
Expand Up @@ -1436,3 +1436,230 @@ def test_siteadm_not_change_manager_email(self):
self.assertEqual(
"[email protected]", api.user.get(userid="manager").getProperty("email")
)

def test_manager_changes_email_when_login_with_email(self):
"""test that when login with email is enabled and a manager changes a user's email
they can log in with the new email
"""
# enable use_email_as_login
security_settings = getAdapter(self.portal, ISecuritySchema)
security_settings.use_email_as_login = True
transaction.commit()
# Create a user
response = self.api_session.post(
"/@users",
json={
"email": "[email protected]",
"password": TEST_USER_PASSWORD,
},
)
self.assertTrue(response.ok)
userid = response.json()["id"]

transaction.commit()
anon_response = self.anon_api_session.post(
"/@login",
json={
"login": "[email protected]",
"password": TEST_USER_PASSWORD,
},
)
self.assertTrue(anon_response.ok)

email_change_response = self.api_session.patch(
f"/@users/{userid}",
json={
"email": "[email protected]",
},
)
self.assertTrue(email_change_response.ok)
new_login_with_old_email_response = self.anon_api_session.post(
"/@login",
json={
"login": "[email protected]",
"password": TEST_USER_PASSWORD,
},
)
self.assertFalse(new_login_with_old_email_response.ok)
new_login_with_new_email_response = self.anon_api_session.post(
"/@login",
json={
"login": "[email protected]",
"password": TEST_USER_PASSWORD,
},
)
self.assertTrue(new_login_with_new_email_response.ok)

def test_user_changes_email_when_login_with_email(self):
"""test that when login with email is enabled and the user changes their email
they can log in with the new email
"""
# enable use_email_as_login
security_settings = getAdapter(self.portal, ISecuritySchema)
security_settings.use_email_as_login = True
transaction.commit()
# Create a user
response = self.api_session.post(
"/@users",
json={
"email": "[email protected]",
"password": TEST_USER_PASSWORD,
},
)
self.assertTrue(response.ok)
userid = response.json()["id"]

transaction.commit()
anon_response = self.anon_api_session.post(
"/@login",
json={
"login": "[email protected]",
"password": TEST_USER_PASSWORD,
},
)
self.assertTrue(anon_response.ok)
auth_token = anon_response.json().get("token")

user_api_session = RelativeSession(self.portal_url, test=self)
user_api_session.headers.update({"Accept": "application/json"})
user_api_session.headers.update({"Authorization": f"Bearer {auth_token}"})

email_change_response = user_api_session.patch(
f"/@users/{userid}",
json={"email": "[email protected]"},
)

self.assertTrue(email_change_response.ok)
new_login_with_old_email_response = self.anon_api_session.post(
"/@login",
json={
"login": "[email protected]",
"password": TEST_USER_PASSWORD,
},
)
self.assertFalse(new_login_with_old_email_response.ok)
new_login_with_new_email_response = self.anon_api_session.post(
"/@login",
json={
"login": "[email protected]",
"password": TEST_USER_PASSWORD,
},
)
self.assertTrue(new_login_with_new_email_response.ok)

def test_manager_changes_email_when_login_with_email_and_uuid_userids(self):
"""test that when login with email is enabled and a manager changes a user's email
they can log in with the new email.

The site is configured to save userids as uuid

"""
# enable use_email_as_login
security_settings = getAdapter(self.portal, ISecuritySchema)
security_settings.use_email_as_login = True
security_settings.use_uuid_as_userid = True
transaction.commit()
# Create a user
response = self.api_session.post(
"/@users",
json={
"email": "[email protected]",
"password": TEST_USER_PASSWORD,
},
)
self.assertTrue(response.ok)
userid = response.json()["id"]
transaction.commit()
anon_response = self.anon_api_session.post(
"/@login",
json={
"login": "[email protected]",
"password": TEST_USER_PASSWORD,
},
)
self.assertTrue(anon_response.ok)

email_change_response = self.api_session.patch(
f"/@users/{userid}",
json={
"email": "[email protected]",
},
)
self.assertTrue(email_change_response.ok)
new_login_with_old_email_response = self.anon_api_session.post(
"/@login",
json={
"login": "[email protected]",
"password": TEST_USER_PASSWORD,
},
)
self.assertFalse(new_login_with_old_email_response.ok)
new_login_with_new_email_response = self.anon_api_session.post(
"/@login",
json={
"login": "[email protected]",
"password": TEST_USER_PASSWORD,
},
)
self.assertTrue(new_login_with_new_email_response.ok)

def test_user_changes_email_when_login_with_email_and_uuid_userids(self):
"""test that when login with email is enabled and the user changes their email
they can log in with the new email

The site is configured to save userids as uuid

"""
# enable use_email_as_login
security_settings = getAdapter(self.portal, ISecuritySchema)
security_settings.use_email_as_login = True
security_settings.use_uuid_as_userid = True

transaction.commit()
# Create a user
response = self.api_session.post(
"/@users",
json={
"email": "[email protected]",
"password": TEST_USER_PASSWORD,
},
)
self.assertTrue(response.ok)
userid = response.json()["id"]
transaction.commit()
anon_response = self.anon_api_session.post(
"/@login",
json={
"login": "[email protected]",
"password": TEST_USER_PASSWORD,
},
)
self.assertTrue(anon_response.ok)
auth_token = anon_response.json().get("token")

user_api_session = RelativeSession(self.portal_url, test=self)
user_api_session.headers.update({"Accept": "application/json"})
user_api_session.headers.update({"Authorization": f"Bearer {auth_token}"})

email_change_response = user_api_session.patch(
f"/@users/{userid}",
json={"email": "[email protected]"},
)

self.assertTrue(email_change_response.ok)
new_login_with_old_email_response = self.anon_api_session.post(
"/@login",
json={
"login": "[email protected]",
"password": TEST_USER_PASSWORD,
},
)
self.assertFalse(new_login_with_old_email_response.ok)
new_login_with_new_email_response = self.anon_api_session.post(
"/@login",
json={
"login": "[email protected]",
"password": TEST_USER_PASSWORD,
},
)
self.assertTrue(new_login_with_new_email_response.ok)
Loading