Commit 47c4e226 authored by Rafael Monnerat's avatar Rafael Monnerat

Introduce Cerficate Login Document

See merge request nexedi/erp5!1486
parents 34ee4bdc 563ee3a1
Pipeline #18050 failed with stage
in 0 seconds
<?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 erp5.component.document.erp5_version.Person import Person as ERP5Person
from Products.ERP5Type import Permissions
class Person(ERP5Person):
security = ClassSecurityInfo()
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):
try:
self.checkUserCanChangePassword()
......@@ -12,7 +36,7 @@ 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
user_id = self.Person_getUserId()
user_id = self.getUserId()
if not user_id:
raise
if getSecurityManager().getUser().getId() != user_id:
......@@ -20,11 +44,11 @@ class Person(ERP5Person):
def _getCertificate(self):
return self.getPortalObject().portal_certificate_authority\
.getNewCertificate(self.Person_getUserId())
.getNewCertificate(self._getCertificateLoginDocument().getReference())
def _revokeCertificate(self):
return self.getPortalObject().portal_certificate_authority\
.revokeCertificateByCommonName(self.Person_getUserId())
.revokeCertificateByCommonName(self._getCertificateLoginDocument().getReference())
def getCertificate(self):
"""Returns new SSL certificate"""
......@@ -36,3 +60,17 @@ class Person(ERP5Person):
"""Revokes existing certificate"""
self._checkCertificateRequest()
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 @@
<item>
<key> <string>_local_properties</string> </key>
<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>
</item>
<item>
......@@ -18,6 +29,10 @@
<tuple/>
</value>
</item>
<item>
<key> <string>business_template_skin_layer_priority</string> </key>
<value> <float>1.0</float> </value>
</item>
<item>
<key> <string>id</string> </key>
<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
import random
import unittest
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
from Products.DCWorkflow.DCWorkflow import ValidationFailed
from AccessControl import Unauthorized
class TestCertificateAuthority(ERP5TypeTestCase):
......@@ -39,6 +40,16 @@ class TestCertificateAuthority(ERP5TypeTestCase):
return "Test Certificate Authority"
def afterSetUp(self):
if getattr(self.portal.portal_types.Person,
'user_can_see_himself', None) is None:
self.portal.portal_types.Person.newContent(
id="user_can_see_himself",
title="The User Himself",
role_name=("Assignee",),
role_base_category_script_id="ERP5Type_getSecurityCategoryFromSelf",
role_base_category="group",
portal_type="Role Information")
if "TEST_CA_PATH" in os.environ:
self.portal.portal_certificate_authority.certificate_authority_path = \
os.environ['TEST_CA_PATH']
......@@ -51,6 +62,7 @@ class TestCertificateAuthority(ERP5TypeTestCase):
reference=login, password=login)
person.newContent(portal_type='Assignment').open()
person.newContent(portal_type='ERP5 Login', reference=login).validate()
person.updateLocalRolesOnSecurityGroups()
self.tic()
return person.getUserId(), login
......@@ -59,6 +71,30 @@ class TestCertificateAuthority(ERP5TypeTestCase):
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.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'])
def test_person_revoke_certificate(self):
......@@ -72,6 +108,14 @@ class TestCertificateAuthority(ERP5TypeTestCase):
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.assertEquals(certificate_login.getValidationState(), "validated")
self.assertTrue('CN=%s' % user_id in certificate['certificate'])
person.revokeCertificate()
......@@ -80,9 +124,56 @@ class TestCertificateAuthority(ERP5TypeTestCase):
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")
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):
_, login = self._createPerson()
_, login2 = self._createPerson()
......@@ -91,6 +182,25 @@ class TestCertificateAuthority(ERP5TypeTestCase):
self.loginByUserName(login2)
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):
user_id, login = self._createPerson()
_, login2 = self._createPerson()
......
Certificate Login | view
Person | get_certificate
Person | revoke_certificate
\ No newline at end of file
Certificate Login | edit_workflow
Certificate Login | login_validation_workflow
\ No newline at end of file
......@@ -42,10 +42,10 @@ manage_addERP5ExternalAuthenticationPluginForm = PageTemplateFile(
__name__='manage_addERP5ExternalAuthenticationPluginForm')
def addERP5ExternalAuthenticationPlugin(dispatcher, id, title=None, user_id_key='',
REQUEST=None):
login_portal_type_list=None, REQUEST=None):
""" Add a ERP5ExternalAuthenticationPlugin to a Pluggable Auth Service. """
plugin = ERP5ExternalAuthenticationPlugin(id, title, user_id_key)
plugin = ERP5ExternalAuthenticationPlugin(id, title, user_id_key, login_portal_type_list)
dispatcher._setObject(plugin.getId(), plugin)
if REQUEST is not None:
......@@ -76,16 +76,28 @@ class ERP5ExternalAuthenticationPlugin(BasePlugin):
'mode':'w',
'label':'HTTP request header key where the user_id is stored'
},
{'id': 'login_portal_type_list',
'type':'lines',
'mode':'w',
'label': 'List of Login Portal Types to search'
},
)
+ BasePlugin._properties[:]
)
def __init__(self, id, title=None, user_id_key=''):
def __init__(self, id, title=None, user_id_key='', login_portal_type_list=None):
#Register value
self._setId(id)
self.title = title
self.user_id_key = user_id_key
if login_portal_type_list is None:
# Keep at least one portal type as Login
login_portal_type_list = ["ERP5 Login"]
self.login_portal_type_list = login_portal_type_list
####################################
#ILoginPasswordHostExtractionPlugin#
####################################
......@@ -97,9 +109,10 @@ class ERP5ExternalAuthenticationPlugin(BasePlugin):
if getHeader is None:
# use get_header instead for Zope-2.8
getHeader = request.get_header
user_id = getHeader(self.user_id_key)
if user_id is not None:
creds['external_login'] = user_id
external_login = getHeader(self.user_id_key)
if external_login is not None:
creds['external_login'] = external_login
creds['login_portal_type'] = self.login_portal_type_list
else:
# fallback to default way
return DumbHTTPExtractor().extractCredentials(request)
......@@ -125,7 +138,7 @@ class ERP5ExternalAuthenticationPlugin(BasePlugin):
__name__='manage_editERP5ExternalAuthenticationPluginForm')
security.declareProtected(ManageUsers, 'manage_editERP5ExternalAuthenticationPlugin')
def manage_editERP5ExternalAuthenticationPlugin(self, user_id_key, RESPONSE=None):
def manage_editERP5ExternalAuthenticationPlugin(self, user_id_key, login_portal_type_list, RESPONSE=None):
"""Edit the object"""
error_message = ''
......@@ -135,6 +148,11 @@ class ERP5ExternalAuthenticationPlugin(BasePlugin):
else:
self.user_id_key = user_id_key
if login_portal_type_list == '' or login_portal_type_list is None:
error_message += 'Invalid portal type value '
else:
self.login_portal_type_list = login_portal_type_list
#Redirect
if RESPONSE is not None:
if error_message != '':
......
......@@ -36,6 +36,17 @@
<input type="text" name="user_id_key" size="40" />
</td>
</tr>
<tr>
<td align="left" valign="top">
<div class="form-label">
List of Login Portal Types (One per line)
</div>
</td>
<td align="left" valign="top">
<textarea name="login_portal_type_list:lines" rows="6" cols="35">ERP5 Login
</textarea>
</td>
</tr>
<tr>
<td colspan="2"> <input type="submit" value="add plugin"/>
</td>
......
......@@ -7,7 +7,9 @@
<form action="manage_editERP5ExternalAuthenticationPlugin" method="POST">
<table tal:define="user_id_key request/user_id_key|context/user_id_key|string:;">
<table tal:define="user_id_key request/user_id_key|context/user_id_key|string:;
login_portal_type_list_ request/login_portal_type_list|context/login_portal_type_list|string:;
login_portal_type_list python: '\n'.join(login_portal_type_list_)">
<tr>
<td>HTTP request header key where the user_id is stored</td>
......@@ -16,6 +18,14 @@
tal:attributes="value user_id_key;" />
</td>
</tr>
<tr>
<td>List of Login Portal Types (One per Line)</td>
<td>
<textarea name="login_portal_type_list:lines" rows="6" cols="35"
tal:content="login_portal_type_list">
</textarea>
</td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="save"/>
......
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