Commit 7bec363d authored by Rafael Monnerat's avatar Rafael Monnerat

erp5_certificate_authority: Introduce Cerficate Login Document

   This is an alternetive way to login using Certificates. Probably this format
   will evolve into use caucase;  however this only introduce some most basic features.

   Use Certificate Login for store login definitions
parent 7d20dd79
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ActionInformation" module="Products.CMFCore.ActionInformation"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>action</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/object_view</string>
</tuple>
</value>
</item>
<item>
<key> <string>category</string> </key>
<value> <string>object_view</string> </value>
</item>
<item>
<key> <string>condition</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>icon</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>view</string> </value>
</item>
<item>
<key> <string>permissions</string> </key>
<value>
<tuple>
<string>View</string>
</tuple>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Action Information</string> </value>
</item>
<item>
<key> <string>priority</string> </key>
<value> <float>1.0</float> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>View</string> </value>
</item>
<item>
<key> <string>visible</string> </key>
<value> <int>1</int> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Expression" module="Products.CMFCore.Expression"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>string:${object_url}/CertificateLogin_view</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
from AccessControl import ClassSecurityInfo, Unauthorized, getSecurityManager from AccessControl import ClassSecurityInfo, Unauthorized, getSecurityManager
from erp5.component.document.erp5_version.Person import Person as ERP5Person from erp5.component.document.erp5_version.Person import Person as ERP5Person
from Products.ERP5Type import Permissions
class Person(ERP5Person): class Person(ERP5Person):
security = ClassSecurityInfo() security = ClassSecurityInfo()
security.declarePublic('getCertificate') security.declarePublic('getCertificate')
def _getCertificateLoginDocument(self):
for _erp5_login in self.objectValues(
portal_type=["ERP5 Login"]):
if _erp5_login.getValidationState() == "validated" and \
_erp5_login.getReference() == self.getUserId():
# The user already created a Login document as UserId, so
# So just use this one.
return _erp5_login
for _certificate_login in self.objectValues(
portal_type=["Certificate Login"]):
if _certificate_login.getValidationState() == "validated":
return _certificate_login
certificate_login = self.newContent(
portal_type="Certificate Login",
# For now use UserId as easy way.
reference=self.getUserId()
)
certificate_login.validate()
return certificate_login
def _checkCertificateRequest(self): def _checkCertificateRequest(self):
try: try:
self.checkUserCanChangePassword() self.checkUserCanChangePassword()
...@@ -12,7 +36,7 @@ class Person(ERP5Person): ...@@ -12,7 +36,7 @@ class Person(ERP5Person):
# in ERP5 user has no SetOwnPassword permission on Person document # in ERP5 user has no SetOwnPassword permission on Person document
# referring himself, so implement "security" by checking that currently # referring himself, so implement "security" by checking that currently
# logged in user is trying to get/revoke his own certificate # logged in user is trying to get/revoke his own certificate
user_id = self.Person_getUserId() user_id = self.getUserId()
if not user_id: if not user_id:
raise raise
if getSecurityManager().getUser().getId() != user_id: if getSecurityManager().getUser().getId() != user_id:
...@@ -20,11 +44,11 @@ class Person(ERP5Person): ...@@ -20,11 +44,11 @@ class Person(ERP5Person):
def _getCertificate(self): def _getCertificate(self):
return self.getPortalObject().portal_certificate_authority\ return self.getPortalObject().portal_certificate_authority\
.getNewCertificate(self.Person_getUserId()) .getNewCertificate(self._getCertificateLoginDocument().getReference())
def _revokeCertificate(self): def _revokeCertificate(self):
return self.getPortalObject().portal_certificate_authority\ return self.getPortalObject().portal_certificate_authority\
.revokeCertificateByCommonName(self.Person_getUserId()) .revokeCertificateByCommonName(self._getCertificateLoginDocument().getReference())
def getCertificate(self): def getCertificate(self):
"""Returns new SSL certificate""" """Returns new SSL certificate"""
...@@ -36,3 +60,17 @@ class Person(ERP5Person): ...@@ -36,3 +60,17 @@ class Person(ERP5Person):
"""Revokes existing certificate""" """Revokes existing certificate"""
self._checkCertificateRequest() self._checkCertificateRequest()
self._revokeCertificate() self._revokeCertificate()
security.declareProtected(Permissions.AccessContentsInformation,
'getTitle')
def getTitle(self, **kw):
"""
Returns the title if it exists or a combination of
first name and last name
"""
title = ERP5Person.getTitle(self, **kw)
test_title = title.replace(' ', '')
if test_title == '':
return self.getDefaultEmailCoordinateText(test_title)
else:
return title
<allowed_content_type_list>
<portal_type id="Person">
<item>Certificate Login</item>
</portal_type>
</allowed_content_type_list>
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Base Type" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>content_icon</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>group_list</string> </key>
<value>
<tuple>
<string>login</string>
</tuple>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Certificate Login</string> </value>
</item>
<item>
<key> <string>init_script</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>permission</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Base Type</string> </value>
</item>
<item>
<key> <string>searchable_text_property_id</string> </key>
<value>
<tuple>
<string>reference</string>
</tuple>
</value>
</item>
<item>
<key> <string>type_class</string> </key>
<value> <string>Login</string> </value>
</item>
<item>
<key> <string>type_interface</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>type_mixin</string> </key>
<value>
<tuple/>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<workflow_chain>
<chain>
<type>Certificate Login</type>
<workflow>edit_workflow, login_validation_workflow</workflow>
</chain>
</workflow_chain>
\ No newline at end of file
...@@ -9,7 +9,18 @@ ...@@ -9,7 +9,18 @@
<item> <item>
<key> <string>_local_properties</string> </key> <key> <string>_local_properties</string> </key>
<value> <value>
<tuple/> <tuple>
<dictionary>
<item>
<key> <string>id</string> </key>
<value> <string>business_template_skin_layer_priority</string> </value>
</item>
<item>
<key> <string>type</string> </key>
<value> <string>float</string> </value>
</item>
</dictionary>
</tuple>
</value> </value>
</item> </item>
<item> <item>
...@@ -18,6 +29,10 @@ ...@@ -18,6 +29,10 @@
<tuple/> <tuple/>
</value> </value>
</item> </item>
<item>
<key> <string>business_template_skin_layer_priority</string> </key>
<value> <float>1.0</float> </value>
</item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>erp5_certificate_authority</string> </value> <value> <string>erp5_certificate_authority</string> </value>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ERP5 Form" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<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/>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_objects</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>action</string> </key>
<value> <string>Base_edit</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>edit_order</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>encoding</string> </key>
<value> <string>UTF-8</string> </value>
</item>
<item>
<key> <string>enctype</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>group_list</string> </key>
<value>
<list>
<string>left</string>
<string>right</string>
<string>center</string>
<string>bottom</string>
<string>hidden</string>
</list>
</value>
</item>
<item>
<key> <string>groups</string> </key>
<value>
<dictionary>
<item>
<key> <string>bottom</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>center</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>hidden</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>left</string> </key>
<value>
<list>
<string>my_translated_portal_type</string>
<string>my_reference</string>
</list>
</value>
</item>
<item>
<key> <string>right</string> </key>
<value>
<list>
<string>my_translated_validation_state_title</string>
</list>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>CertificateLogin_view</string> </value>
</item>
<item>
<key> <string>method</string> </key>
<value> <string>POST</string> </value>
</item>
<item>
<key> <string>name</string> </key>
<value> <string>Login_view</string> </value>
</item>
<item>
<key> <string>pt</string> </key>
<value> <string>form_view</string> </value>
</item>
<item>
<key> <string>row_length</string> </key>
<value> <int>4</int> </value>
</item>
<item>
<key> <string>stored_encoding</string> </key>
<value> <string>UTF-8</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Login</string> </value>
</item>
<item>
<key> <string>unicode_mode</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>update_action</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>update_action_title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>description</string>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_reference</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>description</string> </key>
<value> <string>The username this person will use to log in the system. The system will check that there isn\'t another user with the same username.</string> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_string_field</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>User Login</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>id</string> </key>
<value> <string>my_translated_portal_type</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_view_mode_translated_portal_type</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewBaseFieldLibrary</string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_translated_validation_state_title</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_translated_workflow_state_title</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
portal_type = context.getPortalType()
# Define backward compatibility for do not duplicate Certificate and ERP5 Login
if portal_type in ("ERP5 Login", "Certificate Login"):
portal_type = ("ERP5 Login", "Certificate Login")
return context.getPortalObject().Base_checkLoginExistence(
portal_type=portal_type,
reference=context.getReference(),
ignore_uid=context.getUid(),
ignore_user_uid=context.getParentValue().getUid(),
)
<?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>id</string> </key>
<value> <string>Login_checkExistence</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -31,6 +31,7 @@ import os ...@@ -31,6 +31,7 @@ import os
import random import random
import unittest import unittest
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
from Products.DCWorkflow.DCWorkflow import ValidationFailed
from AccessControl import Unauthorized from AccessControl import Unauthorized
class TestCertificateAuthority(ERP5TypeTestCase): class TestCertificateAuthority(ERP5TypeTestCase):
...@@ -39,8 +40,9 @@ class TestCertificateAuthority(ERP5TypeTestCase): ...@@ -39,8 +40,9 @@ class TestCertificateAuthority(ERP5TypeTestCase):
return "Test Certificate Authority" return "Test Certificate Authority"
def afterSetUp(self): def afterSetUp(self):
self.portal.portal_certificate_authority.certificate_authority_path = \ if "TEST_CA_PATH" in os.environ:
os.environ['TEST_CA_PATH'] self.portal.portal_certificate_authority.certificate_authority_path = \
os.environ['TEST_CA_PATH']
def getBusinessTemplateList(self): def getBusinessTemplateList(self):
return ('erp5_base', 'erp5_certificate_authority') return ('erp5_base', 'erp5_certificate_authority')
...@@ -59,6 +61,30 @@ class TestCertificateAuthority(ERP5TypeTestCase): ...@@ -59,6 +61,30 @@ class TestCertificateAuthority(ERP5TypeTestCase):
self.loginByUserName(login) self.loginByUserName(login)
person = self.portal.portal_membership.getAuthenticatedMember().getUserValue() person = self.portal.portal_membership.getAuthenticatedMember().getUserValue()
certificate = person.getCertificate() certificate = person.getCertificate()
certificate_login_list = person.objectValues(
portal_type="Certificate Login"
)
self.assertEquals(len(certificate_login_list), 1)
certificate_login = certificate_login_list[0]
self.assertEquals(certificate_login.getReference(), user_id)
self.assertEquals(certificate_login.getValidationState(), "validated")
self.assertTrue('CN=%s' % user_id in certificate['certificate'])
def test_person_duplicated_login(self):
user_id, login = self._createPerson()
self.loginByUserName(login)
person = self.portal.portal_membership.getAuthenticatedMember().getUserValue()
person.newContent(portal_type='ERP5 Login', reference=user_id).validate()
self.tic()
certificate = person.getCertificate()
certificate_login_list = person.objectValues(
portal_type="Certificate Login"
)
# If a erp5_login is already using the User ID, just reuse it for now
self.assertEquals(len(certificate_login_list), 0)
self.assertTrue('CN=%s' % user_id in certificate['certificate']) self.assertTrue('CN=%s' % user_id in certificate['certificate'])
def test_person_revoke_certificate(self): def test_person_revoke_certificate(self):
...@@ -72,6 +98,14 @@ class TestCertificateAuthority(ERP5TypeTestCase): ...@@ -72,6 +98,14 @@ class TestCertificateAuthority(ERP5TypeTestCase):
self.loginByUserName(login) self.loginByUserName(login)
person = self.portal.portal_membership.getAuthenticatedMember().getUserValue() person = self.portal.portal_membership.getAuthenticatedMember().getUserValue()
certificate = person.getCertificate() certificate = person.getCertificate()
certificate_login_list = person.objectValues(
portal_type="Certificate Login"
)
self.assertEquals(len(certificate_login_list), 1)
certificate_login = certificate_login_list[0]
self.assertEquals(certificate_login.getReference(), user_id)
self.assertEquals(certificate_login.getValidationState(), "validated")
self.assertTrue('CN=%s' % user_id in certificate['certificate']) self.assertTrue('CN=%s' % user_id in certificate['certificate'])
person.revokeCertificate() person.revokeCertificate()
...@@ -80,9 +114,56 @@ class TestCertificateAuthority(ERP5TypeTestCase): ...@@ -80,9 +114,56 @@ class TestCertificateAuthority(ERP5TypeTestCase):
self.loginByUserName(login) self.loginByUserName(login)
person = self.portal.portal_membership.getAuthenticatedMember().getUserValue() person = self.portal.portal_membership.getAuthenticatedMember().getUserValue()
certificate = person.getCertificate() certificate = person.getCertificate()
certificate_login_list = person.objectValues(
portal_type="Certificate Login"
)
self.assertEquals(len(certificate_login_list), 1)
certificate_login = certificate_login_list[0]
self.assertEquals(certificate_login.getReference(), user_id)
self.assertTrue('CN=%s' % user_id in certificate['certificate']) self.assertTrue('CN=%s' % user_id in certificate['certificate'])
self.assertEquals(certificate_login.getValidationState(), "validated")
self.assertRaises(ValueError, person.getCertificate) self.assertRaises(ValueError, person.getCertificate)
# Ensure it don't create a second object
certificate_login_list = person.objectValues(
portal_type="Certificate Login"
)
self.assertEquals(len(certificate_login_list), 1)
certificate_login = certificate_login_list[0]
self.assertEquals(certificate_login.getReference(), user_id)
self.assertEquals(certificate_login.getValidationState(), "validated")
def test_person_request_revoke_request_certificate(self):
user_id, login = self._createPerson()
self.loginByUserName(login)
person = self.portal.portal_membership.getAuthenticatedMember().getUserValue()
certificate = person.getCertificate()
certificate_login_list = person.objectValues(
portal_type="Certificate Login"
)
self.assertEquals(len(certificate_login_list), 1)
certificate_login = certificate_login_list[0]
self.assertEquals(certificate_login.getReference(), user_id)
self.assertTrue('CN=%s' % user_id in certificate['certificate'])
self.assertEquals(certificate_login.getValidationState(), "validated")
person.revokeCertificate()
certificate = person.getCertificate()
# Ensure it don't create a second object
certificate_login_list = person.objectValues(
portal_type="Certificate Login"
)
self.assertEquals(len(certificate_login_list), 1)
certificate_login = certificate_login_list[0]
self.assertEquals(certificate_login.getReference(), user_id)
self.assertEquals(certificate_login.getValidationState(), "validated")
def test_person_request_certificate_for_another(self): def test_person_request_certificate_for_another(self):
_, login = self._createPerson() _, login = self._createPerson()
_, login2 = self._createPerson() _, login2 = self._createPerson()
...@@ -91,6 +172,25 @@ class TestCertificateAuthority(ERP5TypeTestCase): ...@@ -91,6 +172,25 @@ class TestCertificateAuthority(ERP5TypeTestCase):
self.loginByUserName(login2) self.loginByUserName(login2)
self.assertRaises(Unauthorized, person.getCertificate) self.assertRaises(Unauthorized, person.getCertificate)
def test_person_duplicated_login_from_another_user(self):
user_id, login = self._createPerson()
person = self.portal.person_module.newContent(portal_type='Person',
reference=str(random.random()), password=login)
person.newContent(portal_type='Assignment').open()
# Try to create a login with other person user_id to cheat the system
person.newContent(portal_type='ERP5 Login', reference=user_id).validate()
self.tic()
self.loginByUserName(login)
person = self.portal.portal_membership.getAuthenticatedMember().getUserValue()
self.assertRaises(ValidationFailed, person.getCertificate)
certificate_login_list = [ i for i in person.objectValues(
portal_type="Certificate Login"
) if i.getValidationState() == "validated"]
self.assertEquals(len(certificate_login_list), 0)
def test_person_revoke_certificate_for_another(self): def test_person_revoke_certificate_for_another(self):
user_id, login = self._createPerson() user_id, login = self._createPerson()
_, login2 = self._createPerson() _, login2 = self._createPerson()
...@@ -104,4 +204,4 @@ class TestCertificateAuthority(ERP5TypeTestCase): ...@@ -104,4 +204,4 @@ class TestCertificateAuthority(ERP5TypeTestCase):
def test_suite(): def test_suite():
suite = unittest.TestSuite() suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestCertificateAuthority)) suite.addTest(unittest.makeSuite(TestCertificateAuthority))
return suite return suite
\ No newline at end of file
Certificate Login | view
Person | get_certificate Person | get_certificate
Person | revoke_certificate Person | revoke_certificate
\ No newline at end of file
Certificate Authority Tool Certificate Authority Tool
\ No newline at end of file Certificate Login
Certificate Login | edit_workflow
Certificate Login | login_validation_workflow
\ No newline at end of file
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