Commit fe27a9c3 authored by Vincent Pelletier's avatar Vincent Pelletier

Reduce reliance on Person.reference as a user id.

To prepare for moving user id to a different property.
Mostly replacing getReference on Persons with Person_getUserId, and
catalog searches with PAS API when it is meant to search for a user and
not really a person by reference.
parent eaa72c7c
......@@ -14,7 +14,7 @@ if access_token_document.getValidationState() == 'validated':
agent_document = access_token_document.getAgentValue()
if agent_document is not None:
result = agent_document.getReference(None)
result = agent_document.Person_getUserId()
comment = "Token usage accepted"
access_token_document.invalidate(comment=comment)
......
......@@ -22,6 +22,6 @@ if access_token_document.getValidationState() == 'validated':
agent_document = access_token_document.getAgentValue()
if agent_document is not None:
result = agent_document.getReference(None)
result = agent_document.Person_getUserId()
return result
......@@ -91,7 +91,7 @@ class TestERP5AccessTokenSkins(ERP5TypeTestCase):
self.portal.REQUEST.form["access_token_secret"] = access_token.getReference()
result = self._getTokenCredential(self.portal.REQUEST)
self.assertEqual(result.get('external_login'), person.getReference())
self.assertEqual(result.get('external_login'), person.Person_getUserId())
def test_bad_token(self):
person = self.person = self._createPerson(self.new_id)
......@@ -129,7 +129,7 @@ class TestERP5AccessTokenSkins(ERP5TypeTestCase):
result = access_token.RestrictedAccessToken_getExternalLogin()
self.assertEqual(result, person.getReference())
self.assertEqual(result, person.Person_getUserId())
self.assertEqual(access_token.getValidationState(), 'validated')
def test_RestrictedAccessToken_getExternalLogin_access_token_secret(self):
......@@ -156,7 +156,7 @@ class TestERP5AccessTokenSkins(ERP5TypeTestCase):
result = access_token.RestrictedAccessToken_getExternalLogin()
self.assertEqual(result, person.getReference())
self.assertEqual(result, person.Person_getUserId())
self.assertEqual(access_token.getValidationState(), 'validated')
def test_RestrictedAccessToken_getExternalLogin_no_agent(self):
......@@ -226,7 +226,7 @@ class TestERP5AccessTokenSkins(ERP5TypeTestCase):
result = access_token.OneTimeRestrictedAccessToken_getExternalLogin()
self.assertEqual(result, person.getReference())
self.assertEqual(result, person.Person_getUserId())
self.assertEqual(access_token.getValidationState(), 'invalidated')
def test_OneTimeRestrictedAccessToken_getExternalLogin_wrong_values(self):
......
......@@ -22,7 +22,7 @@ context.activate().AccountingTransactionModule_viewFrenchAccountingTransactionFi
at_date,
simulation_state,
ledger,
user_name=person_value.getReference(),
user_name=person_value.Person_getUserId(),
tag=tag,
aggregate_tag=aggregate_tag)
......
......@@ -35,6 +35,6 @@ for person, failure_list in all_blocked_user_login_dict.items():
person.getTitle(),
**{'title': person.getTitle(),
'count':len(failure_list),
'reference': person.getReference(),
'reference': person.Person_getUserId(),
'url': person.absolute_url()}))
return blocked_user_login_list
......@@ -9,7 +9,7 @@ if not portal.Base_checkPermission('portal_preferences', 'Add portal content'):
try:
preference = portal.portal_preferences.createPreferenceForUser(
context.getReference(),
context.Person_getUserId(),
enable=True,
)
except ValueError:
......
......@@ -46,7 +46,7 @@ select_expression = {'date' : 'DATE_FORMAT(creation_date, "%s")'%sql_format, 'po
group_by = ['DATE_FORMAT(creation_date, "%s")' % sql_format, 'portal_type']
# count number of object created by the user for each type of document
reference = kw.get('person_reference_list', context.getReference())
reference = kw.get('person_reference_list', context.Person_getUserId())
result_list = context.portal_catalog.countResults(select_expression=select_expression,
portal_type=portal_type_list,limit=None,
owner=reference,query=query,
......
......@@ -24,7 +24,7 @@ if context.getPortalObject().hasObject('event_module'):
form_id='Person_viewPersonDetailedEventList'))
# contributions list
if context.getReference() not in (None, ""):
if context.Person_getUserId() not in (None, ""):
# list only if user has a login defined
aggregation_level = context.REQUEST.get('aggregation_level')
from_date = context.REQUEST.get('from_date')
......
<?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></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>Person_getUserId</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -48,7 +48,7 @@ group_by = ['DATE_FORMAT(creation_date, "%s")' % sql_format,]
# count number of object created by the user for each type of document
result_list = context.portal_catalog.countResults(select_expression=select_expression,
portal_type=portal_type_list,limit=None,
owner=context.getReference(),query=query,
owner=context.Person_getUserId(),query=query,
group_by_expression=group_by)
# build result dict per portal_type then period
......
# XXX-Luke: Seb pointed out that this is very bad idea to clear cache.
document = state_change['object']
if document.getReference() is not None:
if document.Person_getUserId() is not None:
cache_tool = document.getPortalObject().portal_caches
cache_tool.clearCache(cache_factory_list=('erp5_content_short', ),
before_commit=True)
person = sci['object']
if sci['object'].getReference():
if person.Person_getUserId():
person.activate(after_path_and_method_id=(person.getPath(),
('immediateReindexObject',
'recursiveImmediateReindexObject'))).Person_createUserPreference()
......@@ -8,13 +8,12 @@ catalog.
from Products.ERP5Type.Log import log
object = sci['object']
portal = sci.getPortal()
portal = object.getPortalObject()
translateString = portal.Base_translateString
portal_catalog = portal.portal_catalog
# Get the owner
owner = object.getViewPermissionOwner()
owner_value = portal_catalog.getResultValue(portal_type='Person', reference=owner)
owner_value = portal.Base_getUserValueByUserId(owner)
# Get the authenticated user
user_value = portal.portal_membership.getAuthenticatedMember().getUserValue()
......
......@@ -9,7 +9,7 @@ if not key:
token = {
'expiration_timestamp': addToDate(DateTime(), to_add={'hour': 1}).timeTime(),
'reference': context.getReference(),
'reference': context.Person_getUserId(),
'user-agent': context.REQUEST.getHeader('User-Agent'),
'remote-addr': context.REQUEST.get('REMOTE_ADDR')
}
......
......@@ -68,7 +68,7 @@ class TestERP5BearerToken(ERP5TypeTestCase):
token, expiration_time = self.person.Person_getBearerToken()
self.portal.REQUEST._auth = 'Bearer %s' % token
reference = self.getTokenCredential(self.portal.REQUEST)
self.assertEqual(reference, self.person.getReference())
self.assertEqual(reference, self.person.Person_getUserId())
def test_different_user_agent(self):
token, expiration_time = self.person.Person_getBearerToken()
......@@ -103,7 +103,7 @@ class TestERP5BearerToken(ERP5TypeTestCase):
# they are not allowing to pass arguments, so lets hack in test
token = {
'expiration_timestamp': DateTime()-1,
'reference': self.person.getReference(),
'reference': self.person.Person_getUserId(),
'user-agent': self.portal.REQUEST.getHeader('User-Agent'),
'remote-addr': self.portal.REQUEST.get('REMOTE_ADDR')
}
......
......@@ -12,19 +12,19 @@ class Person(ERP5Person):
# in ERP5 user has no SetOwnPassword permission on Person document
# referring himself, so implement "security" by checking that currently
# logged in user is trying to get/revoke his own certificate
reference = self.getReference()
if not reference:
user_id = self.Person_getUserId()
if not user_id:
raise
if getSecurityManager().getUser().getId() != reference:
if getSecurityManager().getUser().getId() != user_id:
raise
def _getCertificate(self):
return self.getPortalObject().portal_certificate_authority\
.getNewCertificate(self.getReference())
.getNewCertificate(self.Person_getUserId())
def _revokeCertificate(self):
return self.getPortalObject().portal_certificate_authority\
.revokeCertificateByCommonName(self.getReference())
.revokeCertificateByCommonName(self.Person_getUserId())
def getCertificate(self):
"""Returns new SSL certificate"""
......
......@@ -78,7 +78,7 @@ for gadget in context.portal_gadgets.objectValues():
# Add a tab and a gadget for everyone
portal = context.getPortalObject()
for person in context.person_module.objectValues():
user_name = person.getReference()
user_name = person.Person_getUserId()
tag = '%s_%s_%s' %(user_name,
'erp5_front',
None)
......
......@@ -263,7 +263,7 @@ class TestRunMyDocsConfiguratorWorkflowFranceLanguage(TestRunMyDocsConfiguratorW
self._stepSetupMultipleUserAccountThree(sequence, user_list)
def stepCheckKnowledgePadRole(self, sequence=None, sequence_list=None, **kw):
self.login("french_creator")
self.loginByUserName("french_creator")
self._stepCheckKnowledgePadRole()
......@@ -312,5 +312,5 @@ class TestRunMyDocsConfiguratorWorkflowBrazilLanguage(TestRunMyDocsConfiguratorW
self._stepSetupMultipleUserAccountThree(sequence, user_list)
def stepCheckKnowledgePadRole(self, sequence=None, sequence_list=None, **kw):
self.login("person_creator")
self.loginByUserName("person_creator")
self._stepCheckKnowledgePadRole()
......@@ -765,9 +765,9 @@ class StandardConfigurationMixin(TestLiveConfiguratorWorkflowMixin):
self.assertEqual('2008', period.getShortTitle())
# security on this period has been initialised
for username in self.accountant_username_list:
for user_id in self._getUserIdList(self.accountant_username_list):
self.failUnlessUserCanPassWorkflowTransition(
username, 'cancel_action', period)
user_id, 'cancel_action', period)
def stepCheckSaleTradeCondition(self, sequence=None, sequence_list=None, **kw):
"""
......
......@@ -390,15 +390,15 @@ class TestUNGConfiguratorWorkflowFranceLanguage(TestUNGConfiguratorWorkflowMixin
def stepCheckWebSiteRoles(self, sequence=None, sequence_list=None, **kw):
""" Check permission of Web Site with normal user """
self.login("french_assignor")
self.loginByUserName("french_assignor")
self._stepCheckWebSiteRoles()
def stepCheckKnowledgePadRole(self, sequence=None, sequence_list=None, **kw):
self.login("french_creator")
self.loginByUserName("french_creator")
self._stepCheckKnowledgePadRole()
def stepCheckCreateNewEvent(self, sequence=None, sequence_list=None, **kw):
self.login("french_assignee")
self.loginByUserName("french_assignee")
self._stepCheckCreateNewEvent()
......@@ -485,13 +485,13 @@ class TestUNGConfiguratorWorkflowBrazilLanguage(TestUNGConfiguratorWorkflowMixin
def stepCheckWebSiteRoles(self, sequence=None, sequence_list=None, **kw):
""" Check permission of Web Site with normal user """
self.login("person_assignor")
self.loginByUserName("person_assignor")
self._stepCheckWebSiteRoles()
def stepCheckKnowledgePadRole(self, sequence=None, sequence_list=None, **kw):
self.login("person_creator")
self.loginByUserName("person_creator")
self._stepCheckKnowledgePadRole()
def stepCheckCreateNewEvent(self, sequence=None, sequence_list=None, **kw):
self.login("person_assignee")
self.loginByUserName("person_assignee")
self._stepCheckCreateNewEvent()
......@@ -13,8 +13,9 @@ portal_preferences = context.portal_preferences
person = context.getDestinationDecisionValue(portal_type="Person")
# Create user of the person only if not exist
if person.hasReference() and person.getPassword():
return person.getReference(), None
user_id = person.Person_getUserId()
if user_id and person.hasPassword():
return user_id, None
# Set login
login = context.getReference()
......
......@@ -3,29 +3,29 @@
Proxy : this required a manager proxy role to be able to search in all persons
'''
portal = context.getPortalObject()
person_module = portal.getDefaultModule('Person')
request = context.REQUEST
web_site = context.getWebSiteValue()
if web_site:
request.set("came_from", web_site.absolute_url())
if choice == "password":
request.set('reference', reference)
portal_preferences = context.portal_preferences
result = person_module.searchFolder(reference={'query': reference, 'key': 'ExactMatch'})
if len(result) != 1:
user_id = portal.Base_getUserIdByUserName(reference)
if user_id is None:
person = None
else:
person = portal.Base_getUserValueByUserId(user_id)
if person is None:
portal_status_message = context.Base_translateString("Could not find your user account.")
if web_site:
return web_site.Base_redirect('login_form', keep_items = dict(portal_status_message=portal_status_message ))
return portal.Base_redirect('login_form', keep_items = dict(portal_status_message=portal_status_message ))
person = result[0]
#If any question, we can create directly the credential recovery
question_free_text = person.getDefaultCredentialQuestionQuestionFreeText()
question_title = person.getDefaultCredentialQuestionQuestionTitle()
if not (question_free_text or question_title) or \
not portal_preferences.isPreferredAskCredentialQuestion():
not portal.portal_preferences.isPreferredAskCredentialQuestion():
return context.ERP5Site_newCredentialRecovery(reference=reference)
web_section = context.getWebSectionValue()
......
......@@ -45,7 +45,11 @@ else:
username = person.getReference()
if password and username == str(portal.portal_membership.getAuthenticatedMember()):
credential_update.accept()
portal.cookie_authentication.credentialsChanged(username, username, password)
portal.cookie_authentication.credentialsChanged(
person.Person_getUserId(),
username,
password,
)
portal_status_message = "Password changed."
portal_status_message = context.Base_translateString(portal_status_message)
......
##############################################################################
#
# Copyright (c) 2006-2007 Nexedi SA and Contributors. All Rights Reserved.
# Copyright (c) 2006-2007,2016 Nexedi SA and Contributors. All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
......@@ -30,8 +30,7 @@ def getPersonRoleList(self, person, object):
"""
Get list of local roles for user.
"""
acl_users = self.getPortalObject().acl_users
if person.getReference() is not None:
user = acl_users.getUserById(person.getReference()).__of__(acl_users)
user_role_list = user.getRolesInContext(object)
return user_role_list
user_id = person.Person_getUserId()
if user_id is not None:
acl_users = self.getPortalObject().acl_users
return acl_users.getUserById(user_id).__of__(acl_users).getRolesInContext(object)
......@@ -13,22 +13,12 @@ from Products.ERP5Type.Log import log
category_list = []
person_module = context.portal_url.getPortalObject().getDefaultModule('Person')
# It is better to keep getObject(), in this script this
# prevent a very strange bug, sometimes without getObject the
# assignment is not found
person_object_list = [x.getObject() for x in person_module.searchFolder(portal_type='Person', reference=user_name)]
if len(person_object_list) != 1:
if len(person_object_list) > 1:
raise ConsistencyError, "Error: There is more than one Person with reference '%s'" % user_name
else:
# if a person_object was not found in the module, we do nothing more
# this happens for example when a manager with no associated person object
# creates a person_object for a new user
return []
person_object = person_object_list[0]
person_object = context.Base_getUserValueByUserId(user_name)
if person_object is None:
# if a person_object was not found in the module, we do nothing more
# this happens for example when a manager with no associated person object
# creates a person_object for a new user
return []
# We look for valid assignments of this user
for assignment in person_object.contentValues(filter={'portal_type': 'Assignment'}):
......
......@@ -5,21 +5,12 @@ XXX I'm not sure it is used anywhere at the moment.
category_list = []
person_module = context.portal_url.getPortalObject().getDefaultModule('Person')
# It is better to keep getObject(), in this script this
# prevent a very strange bug, sometimes without getObject the
# assignment is not found
person_object_list = [x.getObject() for x in person_module.searchFolder(portal_type='Person', reference=user_name)]
if len(person_object_list) != 1:
if len(person_object_list) > 1:
raise ConsistencyError, "Error: There is more than one Person with reference '%s'" % user_name
else:
# if a person_object was not found in the module, we do nothing more
# this happens for example when a manager with no associated person object
# creates a person_object for a new user
return []
person_object = person_object_list[0]
person_object = context.Base_getUserValueByUserId(user_name)
if person_object is None:
# if a person_object was not found in the module, we do nothing more
# this happens for example when a manager with no associated person object
# creates a person_object for a new user
return []
category_dict = {}
for base_category in base_category_list:
......
......@@ -6,6 +6,8 @@ class TestDiscussionThread(SecurityTestCase):
A Sample Test Class
"""
user_id_dict = {}
def getTitle(self):
return "TestDiscussionThread"
......@@ -27,7 +29,9 @@ class TestDiscussionThread(SecurityTestCase):
]
# now we create the users
for user in user_list:
self.createSimpleUser(**user)
if not self.portal.acl_users.searchUsers(login=user['reference'], exact_match=True):
self.user_id_dict[user['reference']] = \
self.createSimpleUser(**user).Person_getUserId()
self.commit()
self.tic()
......@@ -52,19 +56,19 @@ class TestDiscussionThread(SecurityTestCase):
- that user can reply to his thread
"""
# forum_user should be able to access/view the forum module
self.assertUserCanAccessDocument('forum_user', self.forum_module)
self.assertUserCanViewDocument('forum_user', self.forum_module)
self.assertUserCanAddDocument('forum_user', self.forum_module)
self.assertUserCanAccessDocument(self.user_id_dict['forum_user'], self.forum_module)
self.assertUserCanViewDocument(self.user_id_dict['forum_user'], self.forum_module)
self.assertUserCanAddDocument(self.user_id_dict['forum_user'], self.forum_module)
self.login('forum_user')
self.login(self.user_id_dict['forum_user'])
thread_content='Hey, lets create a new thread!'
thread = self._newThread(content=thread_content)
# user should be able to access/view the created thread
self.assertUserCanViewDocument('forum_user', thread)
self.assertUserCanAccessDocument('forum_user', thread)
self.assertUserCanAddDocument('forum_user', thread)
self.assertUserCanViewDocument(self.user_id_dict['forum_user'], thread)
self.assertUserCanAccessDocument(self.user_id_dict['forum_user'], thread)
self.assertUserCanAddDocument(self.user_id_dict['forum_user'], thread)
# get thread posts
thread_posts = thread.objectValues()
......@@ -89,8 +93,8 @@ class TestDiscussionThread(SecurityTestCase):
batch_mode=True,
)
self.assertUserCanViewDocument('forum_user', post)
self.assertUserCanAccessDocument('forum_user', post)
self.assertUserCanViewDocument(self.user_id_dict['forum_user'], post)
self.assertUserCanAccessDocument(self.user_id_dict['forum_user'], post)
self.tic()
......@@ -110,22 +114,22 @@ class TestDiscussionThread(SecurityTestCase):
- outsiders can't read the thread
- visitor can read the thread
"""
self.login('forum_user')
self.login(self.user_id_dict['forum_user'])
thread = self._newThread()
self.failIfUserCanViewDocument('spy', thread)
self.failIfUserCanAccessDocument('spy', thread)
self.failIfUserCanViewDocument(self.user_id_dict['spy'], thread)
self.failIfUserCanAccessDocument(self.user_id_dict['spy'], thread)
self.assertUserCanViewDocument('visitor', thread)
self.assertUserCanAccessDocument('visitor', thread)
self.assertUserCanViewDocument(self.user_id_dict['visitor'], thread)
self.assertUserCanAccessDocument(self.user_id_dict['visitor'], thread)
# Check that visitor has permissions on related objects
# for example, if visitor has no permissions on the Person
# module, the above checks will pass, but the view
# will not work, because Person.getTitle() will fail
self.assertUserCanViewDocument('visitor', self.portal.person_module)
self.assertUserCanAccessDocument('visitor', self.portal.person_module)
self.assertUserCanViewDocument(self.user_id_dict['visitor'], self.portal.person_module)
self.assertUserCanAccessDocument(self.user_id_dict['visitor'], self.portal.person_module)
response = self.publish('/%s/%s' % \
(self.portal.getId(), thread.getRelativeUrl()),
......@@ -140,13 +144,13 @@ class TestDiscussionThread(SecurityTestCase):
- visitor cannot reply
- visitor cannot post a new thread
"""
self.login('forum_user')
self.login(self.user_id_dict['forum_user'])
thread = self._newThread()
# visitor cannot reply to a thread
self.failIfUserCanAddDocument('visitor', thread)
self.failIfUserCanAddDocument(self.user_id_dict['visitor'], thread)
# visitor cannot create a new thread
self.failIfUserCanAddDocument('visitor', self.forum_module)
self.failIfUserCanAddDocument(self.user_id_dict['visitor'], self.forum_module)
def testAdminCanModerate(self):
"""
......@@ -157,16 +161,16 @@ class TestDiscussionThread(SecurityTestCase):
- admin can display it
- admin reopens it
"""
self.login('admin')
self.login(self.user_id_dict['admin'])
thread = self._newThread()
self.assertUserCanPassWorkflowTransition('admin', 'close_action', thread)
self.assertUserCanPassWorkflowTransition(self.user_id_dict['admin'], 'close_action', thread)
thread.close()
self.commit()
self.assertUserCanViewDocument('admin', thread)
self.assertUserCanAccessDocument('admin', thread)
self.assertUserCanPassWorkflowTransition('admin', 'unclose_action', thread)
self.assertUserCanViewDocument(self.user_id_dict['admin'], thread)
self.assertUserCanAccessDocument(self.user_id_dict['admin'], thread)
self.assertUserCanPassWorkflowTransition(self.user_id_dict['admin'], 'unclose_action', thread)
def testUserCannotModerate(self):
"""
......@@ -174,11 +178,11 @@ class TestDiscussionThread(SecurityTestCase):
- user creates thread
- user cannot close it
"""
self.login('forum_user')
self.login(self.user_id_dict['forum_user'])
thread = self._newThread()
self.assertUserCanPassWorkflowTransition('forum_user', 'close_action', thread)