Commit 9b504808 authored by Jérome Perrin's avatar Jérome Perrin

base: ensure migrated persons have a user_id

Persons created before the introduction of ERP5 Login and user_id will only
have a user_id after migration if they were already user before migration,
otherwise they will not have a user_id and creating assignments and ERP5 Login
for this person creates a user which can not log in the system.

To make it possible for these persons to login anyway, we ensure person has a
user id when validating a login

This is bc67c2c4 again, but with a proxy role
on the interaction workflow and a non regression test to cover the problem with
the first version of that commit.
parent dc7fc5e8
...@@ -41,7 +41,7 @@ ...@@ -41,7 +41,7 @@
</chain> </chain>
<chain> <chain>
<type>ERP5 Login</type> <type>ERP5 Login</type>
<workflow>edit_workflow, login_validation_workflow</workflow> <workflow>edit_workflow, login_interaction_workflow, login_validation_workflow</workflow>
</chain> </chain>
<chain> <chain>
<type>Email</type> <type>Email</type>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="InteractionWorkflowDefinition" module="Products.ERP5.InteractionWorkflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_objects</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>groups</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>login_interaction_workflow</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Interaction" module="Products.ERP5.Interaction"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_mapping</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>_objects</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>interactions</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="InteractionDefinition" module="Products.ERP5.Interaction"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>actbox_category</string> </key>
<value> <string>workflow</string> </value>
</item>
<item>
<key> <string>actbox_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>actbox_url</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>activate_script_name</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>after_script_name</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>before_commit_script_name</string> </key>
<value>
<list>
<string>Workflow_ensureUserId</string>
</list>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>guard</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>validate</string> </value>
</item>
<item>
<key> <string>method_id</string> </key>
<value>
<list>
<string>validate</string>
</list>
</value>
</item>
<item>
<key> <string>once_per_transaction</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>portal_type_filter</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>portal_type_group_filter</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>script_name</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>temporary_document_disallowed</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>trigger_type</string> </key>
<value> <int>2</int> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Scripts" module="Products.DCWorkflow.Scripts"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_mapping</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>_objects</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>scripts</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
"""Make sure the user has a user id.
Persons that were created before user id were introduced may not have a user id already.
"""
user = state_change['object'].getParentValue()
if user.getPortalType() == 'Person' and not user.hasUserId():
user.initUserId()
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>state_change</string> </value>
</item>
<item>
<key> <string>_proxy_roles</string> </key>
<value>
<tuple>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Workflow_ensureUserId</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Variables" module="Products.DCWorkflow.Variables"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_mapping</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>variables</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Worklists" module="Products.DCWorkflow.Worklists"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_mapping</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>worklists</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -22,6 +22,7 @@ Currency | validation_workflow ...@@ -22,6 +22,7 @@ Currency | validation_workflow
Delivery Type | base_type_interaction_workflow Delivery Type | base_type_interaction_workflow
Delivery Type | dynamic_class_generation_interaction_workflow Delivery Type | dynamic_class_generation_interaction_workflow
ERP5 Login | edit_workflow ERP5 Login | edit_workflow
ERP5 Login | login_interaction_workflow
ERP5 Login | login_validation_workflow ERP5 Login | login_validation_workflow
Email | coordinate_interaction_workflow Email | coordinate_interaction_workflow
Email | edit_workflow Email | edit_workflow
......
...@@ -9,6 +9,7 @@ document_conversion_interaction_workflow ...@@ -9,6 +9,7 @@ document_conversion_interaction_workflow
document_security_interaction_workflow document_security_interaction_workflow
embedded_workflow embedded_workflow
local_permission_interaction_workflow local_permission_interaction_workflow
login_interaction_workflow
login_validation_workflow login_validation_workflow
movement_resource_interaction_workflow movement_resource_interaction_workflow
notification_message_workflow notification_message_workflow
......
...@@ -5,6 +5,6 @@ ...@@ -5,6 +5,6 @@
</chain> </chain>
<chain> <chain>
<type>Facebook Login</type> <type>Facebook Login</type>
<workflow>edit_workflow, validation_workflow</workflow> <workflow>edit_workflow, login_interaction_workflow, validation_workflow</workflow>
</chain> </chain>
</workflow_chain> </workflow_chain>
\ No newline at end of file
Facebook Connector | edit_workflow Facebook Connector | edit_workflow
Facebook Connector | validation_workflow Facebook Connector | validation_workflow
Facebook Login | edit_workflow Facebook Login | edit_workflow
Facebook Login | login_interaction_workflow
Facebook Login | validation_workflow Facebook Login | validation_workflow
\ No newline at end of file
...@@ -5,6 +5,6 @@ ...@@ -5,6 +5,6 @@
</chain> </chain>
<chain> <chain>
<type>Google Login</type> <type>Google Login</type>
<workflow>edit_workflow, validation_workflow</workflow> <workflow>edit_workflow, login_interaction_workflow, validation_workflow</workflow>
</chain> </chain>
</workflow_chain> </workflow_chain>
\ No newline at end of file
Google Connector | edit_workflow Google Connector | edit_workflow
Google Connector | validation_workflow Google Connector | validation_workflow
Google Login | edit_workflow Google Login | edit_workflow
Google Login | login_interaction_workflow
Google Login | validation_workflow Google Login | validation_workflow
\ No newline at end of file
...@@ -237,6 +237,35 @@ class TestUserManagement(UserManagementTestCase): ...@@ -237,6 +237,35 @@ class TestUserManagement(UserManagementTestCase):
_, login, password = self._makePerson() _, login, password = self._makePerson()
self._assertUserExists(login, password) self._assertUserExists(login, password)
def test_AnonymousCanCreateUser(self):
"""Anonymous user can create users, as long as the user creation is done
from a security context which allows it.
(ie. there should not be interaction workflow raising Unauthorized)
"""
test_script_id = 'ERP5Site_createTestUser%s' % self.id()
createZODBPythonScript(
self.portal.portal_skins.custom,
test_script_id,
'login, password',
'''if 1:
new_person = context.getPortalObject().person_module.newContent(
portal_type='Person')
new_person.newContent(portal_type='Assignment').open()
new_person.newContent(
portal_type='ERP5 Login',
reference=login,
password=password,
).validate()
''')
script = getattr(self.portal, test_script_id)
script.manage_proxy(('Manager', 'Owner',))
self.logout()
login = 'login-%s' % self._login_generator()
script(login, 'password')
self.tic()
self._assertUserExists(login, 'password')
def test_PersonLoginCaseSensitive(self): def test_PersonLoginCaseSensitive(self):
"""Login/password are case sensitive.""" """Login/password are case sensitive."""
login = 'case_test_user' login = 'case_test_user'
...@@ -887,6 +916,22 @@ class TestMigration(UserManagementTestCase): ...@@ -887,6 +916,22 @@ class TestMigration(UserManagementTestCase):
self.portal.person_module.newContent, self.portal.person_module.newContent,
portal_type='Person',) portal_type='Person',)
def test_NonMigratedPersonCanBecomeUserLater(self):
self._enableERP5UsersPlugin()
non_migrated_person = self.portal.person_module.newContent(
portal_type='Person',
user_id=None,
)
self.tic()
self.portal.portal_templates.fixConsistency(filter={'constraint_type': 'post_upgrade'})
self.tic()
non_migrated_person.newContent(portal_type='Assignment').open()
non_migrated_person.newContent(portal_type='ERP5 Login', reference='login', password='password').validate()
self.tic()
self._assertUserExists('login', 'password')
self.assertTrue(non_migrated_person.getUserId())
class TestUserManagementExternalAuthentication(TestUserManagement): class TestUserManagementExternalAuthentication(TestUserManagement):
def getTitle(self): def getTitle(self):
......
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