Commit e50e45e4 authored by Nicolas Wavrant's avatar Nicolas Wavrant

erp5_core: Password Tool should not leak info on users

for security reasons, info on users, or existence of usernames shouldn't be leaked from the system.
parent 5560a450
No related merge requests found
...@@ -428,8 +428,11 @@ class TestPasswordTool(ERP5TypeTestCase): ...@@ -428,8 +428,11 @@ class TestPasswordTool(ERP5TypeTestCase):
self.logout() self.logout()
ret = self.portal.portal_password.mailPasswordResetRequest( ret = self.portal.portal_password.mailPasswordResetRequest(
user_login='user-login', REQUEST=self.portal.REQUEST) user_login='user-login', REQUEST=self.portal.REQUEST)
self.assertTrue("portal_status_message=User+user-login+does+not+have+an+email+"\
"address%2C+please+contact+site+administrator+directly" in str(ret)) # For security reasons, the message should always be the same
self.assertTrue("portal_status_message=An+email+has+been+sent+to+you." in str(ret))
# But no mail has been sent
self.stepCheckNoMailSent()
def test_acquired_email_on_person(self): def test_acquired_email_on_person(self):
organisation = self.portal.organisation_module.newContent( organisation = self.portal.organisation_module.newContent(
...@@ -452,8 +455,11 @@ class TestPasswordTool(ERP5TypeTestCase): ...@@ -452,8 +455,11 @@ class TestPasswordTool(ERP5TypeTestCase):
self.logout() self.logout()
ret = self.portal.portal_password.mailPasswordResetRequest( ret = self.portal.portal_password.mailPasswordResetRequest(
user_login='user-login', REQUEST=self.portal.REQUEST) user_login='user-login', REQUEST=self.portal.REQUEST)
self.assertTrue("portal_status_message=User+user-login+does+not+have+an+email+"\
"address%2C+please+contact+site+administrator+directly" in str(ret)) # For security reasons, the message should always be the same
self.assertTrue("portal_status_message=An+email+has+been+sent+to+you." in str(ret))
# But no mail has been sent
self.stepCheckNoMailSent()
def test_suite(): def test_suite():
suite = unittest.TestSuite() suite = unittest.TestSuite()
......
...@@ -6,6 +6,12 @@ ...@@ -6,6 +6,12 @@
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
<item>
<key> <string>_recorded_property_dict</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item> <item>
<key> <string>default_reference</string> </key> <key> <string>default_reference</string> </key>
<value> <string>testPasswordTool</string> </value> <value> <string>testPasswordTool</string> </value>
...@@ -53,13 +59,28 @@ ...@@ -53,13 +59,28 @@
<item> <item>
<key> <string>workflow_history</string> </key> <key> <string>workflow_history</string> </key>
<value> <value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent> <persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
<record id="2" aka="AAAAAAAAAAI="> <record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle> <pickle>
<global name="PersistentMapping" module="Persistence.mapping"/> <global name="PersistentMapping" module="Persistence.mapping"/>
</pickle> </pickle>
...@@ -72,7 +93,7 @@ ...@@ -72,7 +93,7 @@
<item> <item>
<key> <string>component_validation_workflow</string> </key> <key> <string>component_validation_workflow</string> </key>
<value> <value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent> <persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value> </value>
</item> </item>
</dictionary> </dictionary>
...@@ -81,7 +102,7 @@ ...@@ -81,7 +102,7 @@
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
<record id="3" aka="AAAAAAAAAAM="> <record id="4" aka="AAAAAAAAAAQ=">
<pickle> <pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/> <global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle> </pickle>
......
...@@ -1404,7 +1404,7 @@ class TestERP5Credential(ERP5TypeTestCase): ...@@ -1404,7 +1404,7 @@ class TestERP5Credential(ERP5TypeTestCase):
# Execute alarm, it will fail because this person has no email # Execute alarm, it will fail because this person has no email
with self.assertRaisesRegexp( with self.assertRaisesRegexp(
RuntimeError, RuntimeError,
"User .* does not have an email address, please contact site administrator directly"): "An email has been sent to you"):
self.tic() self.tic()
# run alarm again, this does not cause another activity failure. # run alarm again, this does not cause another activity failure.
......
...@@ -126,6 +126,8 @@ class PasswordTool(BaseTool): ...@@ -126,6 +126,8 @@ class PasswordTool(BaseTool):
substitution_method_parameter_dict -- additional substitution dict for substitution_method_parameter_dict -- additional substitution dict for
creating an email. creating an email.
""" """
error_encountered = False
msg = translateString("An email has been sent to you.")
if REQUEST is None: if REQUEST is None:
REQUEST = get_request() REQUEST = get_request()
...@@ -136,15 +138,18 @@ class PasswordTool(BaseTool): ...@@ -136,15 +138,18 @@ class PasswordTool(BaseTool):
if REQUEST and 'came_from' in REQUEST: if REQUEST and 'came_from' in REQUEST:
site_url = REQUEST.came_from site_url = REQUEST.came_from
msg = None error_encountered = False
# check user exists, and have an email # check user exists, and have an email
user_path_set = {x['path'] for x in self.getPortalObject().acl_users.searchUsers( user_path_set = {x['path'] for x in self.getPortalObject().acl_users.searchUsers(
login=user_login, login=user_login,
exact_match=True, exact_match=True,
) if 'path' in x} ) if 'path' in x}
if len(user_path_set) == 0: if len(user_path_set) == 0:
msg = translateString("User ${user} does not exist.", error_encountered = True
mapping={'user':user_login}) LOG(
'ERP5.PasswordTool', INFO,
"User {user} does not exist.".format(user=user_login)
)
else: else:
# We use checked_permission to prevent errors when trying to acquire # We use checked_permission to prevent errors when trying to acquire
# email from organisation # email from organisation
...@@ -154,10 +159,12 @@ class PasswordTool(BaseTool): ...@@ -154,10 +159,12 @@ class PasswordTool(BaseTool):
email_value = user_value.getDefaultEmailValue( email_value = user_value.getDefaultEmailValue(
checked_permission='Access content information') checked_permission='Access content information')
if email_value is None or not email_value.asText(): if email_value is None or not email_value.asText():
msg = translateString( error_encountered = True
"User ${user} does not have an email address, please contact site " LOG(
"administrator directly", mapping={'user':user_login}) 'ERP5.PasswordTool', INFO,
if msg: "User {user} does not have an email address".format(user=user_login)
)
if error_encountered:
if batch: if batch:
raise RuntimeError(msg) raise RuntimeError(msg)
else: else:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment