Commit 62a2f19e authored by Rafael Monnerat's avatar Rafael Monnerat

Extend Certificate login implementation

See merge request nexedi/slapos.core!558
parents 693c8c5c 6e41423d
<?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_certificate_login</string> </value>
</item>
<item>
<key> <string>permissions</string> </key>
<value>
<tuple>
<string>View</string>
</tuple>
</value>
</item>
<item>
<key> <string>priority</string> </key>
<value> <float>6.1</float> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Certificate</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}/Base_viewCertificateLoginList</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?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_certificate_login</string> </value>
</item>
<item>
<key> <string>permissions</string> </key>
<value>
<tuple>
<string>View</string>
</tuple>
</value>
</item>
<item>
<key> <string>priority</string> </key>
<value> <float>6.1</float> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Certificate</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}/Base_viewCertificateLoginList</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -109,8 +109,8 @@ class SlapOSCacheMixin:
return self._setAccessStatus("%s %s" % (BUILDING, text), state, reindex)
def _setAccessStatus(self, text, state="", reindex=0):
user_reference = self.getPortalObject().portal_membership.getAuthenticatedMember()\
.getUserName()
user = self.getPortalObject().portal_membership.getAuthenticatedMember()\
.getUserValue()
previous = self._getCachedAccessInfo()
created_at = rfc1123_date(DateTime())
......@@ -125,6 +125,11 @@ class SlapOSCacheMixin:
if state == "":
state = previous_json.get("state", "")
if user is not None:
user_reference = user.getReference()
else:
user_reference = self.getPortalObject().portal_membership.getAuthenticatedMember()\
.getUserName()
value = json.dumps({
'user': '%s' % user_reference,
'created_at': '%s' % created_at,
......
......@@ -157,8 +157,14 @@ class SlapOSComputeNodeMixin(object):
def _getComputeNodeInformation(self, user, refresh_etag):
portal = self.getPortalObject()
user_document = _assertACI(portal.portal_catalog.unrestrictedGetResultValue(
reference=user, portal_type=['Person', 'Compute Node', 'Software Instance']))
login = portal.portal_catalog.unrestrictedGetResultValue(
reference=user, portal_type="Certificate Login",
parent_portal_type=['Person', 'Compute Node', 'Software Instance'])
if not login:
raise Unauthorized('User %s not found!' % user)
user_document = _assertACI(login.getParentValue())
user_type = user_document.getPortalType()
if user_type in ('Compute Node', 'Person'):
......
<allowed_content_type_list>
<portal_type id="Compute Node">
<item>Certificate Login</item>
<item>ERP5 Login</item>
</portal_type>
<portal_type id="Hosting Subscription Module">
<item>Hosting Subscription</item>
......@@ -14,7 +13,6 @@
</portal_type>
<portal_type id="Software Instance">
<item>Certificate Login</item>
<item>ERP5 Login</item>
</portal_type>
<portal_type id="Software Instance Module">
<item>Slave Instance</item>
......
......@@ -24,7 +24,6 @@
<tuple>
<string>ssl_certificate</string>
<string>ssl_key</string>
<string>destination_reference</string>
</tuple>
</value>
</item>
......
<?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="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
<global name="object" module="__builtin__"/>
<none/>
</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></string> </value>
</item>
<item>
<key> <string>action_title</string> </key>
<value> <string></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>center</string>
<string>left</string>
<string>right</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>
<string>listbox</string>
</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_title</string>
</list>
</value>
</item>
<item>
<key> <string>right</string> </key>
<value>
<list>
<string>my_reference</string>
<string>my_user_id</string>
</list>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Base_viewCertificateLoginList</string> </value>
</item>
<item>
<key> <string>method</string> </key>
<value> <string>POST</string> </value>
</item>
<item>
<key> <string>name</string> </key>
<value> <string>General</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>Certificate Login List</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>columns</string>
<string>portal_types</string>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>listbox</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>columns</string> </key>
<value> <string></string> </value>
</item>
<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>portal_types</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>Base_viewSearchResultList</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>all_editable_columns</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>columns</string> </key>
<value>
<list>
<tuple>
<string>reference</string>
<string>Login</string>
</tuple>
<tuple>
<string>translated_validation_state_title</string>
<string>State</string>
</tuple>
</list>
</value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_view_mode_listbox</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewBaseFieldLibrary</string> </value>
</item>
<item>
<key> <string>height</string> </key>
<value> <int>5</int> </value>
</item>
<item>
<key> <string>list_cookie</string> </key>
<value> <string>CONTACT_LIST</string> </value>
</item>
<item>
<key> <string>portal_types</string> </key>
<value>
<list>
<tuple>
<string>ERP5 Login</string>
<string>ERP5 Login</string>
</tuple>
</list>
</value>
</item>
<item>
<key> <string>reverse</string> </key>
<value> <int>0</int> </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>Certificate Logins</string> </value>
</item>
<item>
<key> <string>width</string> </key>
<value> <int>40</int> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>python: [(x, x) for x in here.getPortalLoginTypeList()]</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/>
</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>field_id</string> </key>
<value> <string>my_view_mode_read_only_reference</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>
......@@ -10,13 +10,13 @@
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>title</string>
<string>editable</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_destination_reference</string> </value>
<value> <string>my_title</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
......@@ -71,9 +71,13 @@
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>editable</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_view_mode_read_only_reference</string> </value>
<value> <string>my_title</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
......@@ -83,10 +87,6 @@
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Authorisation Identity</string> </value>
</item>
</dictionary>
</value>
</item>
......
<?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>default</string>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_user_id</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>default</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<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>default</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_view_mode_read_only_reference</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 ID</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>python: context.Person_getUserId()</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -107,7 +107,6 @@
<list>
<string>my_title</string>
<string>my_reference</string>
<string>my_destination_reference</string>
<string>my_source_reference</string>
</list>
</value>
......
......@@ -202,6 +202,14 @@ class SlapOSTestCaseMixin(testSlapOSMixin):
login.validate()
return login
def _addCertificateLogin(self, document, **kw):
login = document.newContent(
portal_type="Certificate Login",
reference=document.getReference(),
**kw)
login.validate()
return login
def makePerson(self, new_id=None, index=True, user=True):
if new_id is None:
......
......@@ -502,8 +502,7 @@ class TestSlapOSCloudSlapOSComputeNodeMixin_getCacheComputeNodeInformation(
source_administration_value=getattr(self, "person", None),
)
self.compute_node.validate()
self._addERP5Login(self.compute_node)
self._addCertificateLogin(self.compute_node)
self.tic()
......
......@@ -52,10 +52,15 @@ class TestSlapOSCoreComputeNodeSlapInterfaceWorkflow(SlapOSTestCaseMixin):
compute_node_certificate = self.portal.REQUEST.get('compute_node_certificate')
self.assertNotEqual(None, compute_node_key)
self.assertNotEqual(None, compute_node_certificate)
self.assertNotEqual(None, self.compute_node.getDestinationReference())
serial = '0x%x' % int(self.compute_node.getDestinationReference(), 16)
certificate_login_list = self.compute_node.objectValues(portal_type="Certificate Login")
self.assertEqual(len(certificate_login_list), 1)
certificate_login = certificate_login_list[0]
self.assertEqual(certificate_login.getValidationState(), 'validated')
self.assertNotEqual(certificate_login.getReference(), None)
self.assertNotEqual(certificate_login.getDestinationReference(), None)
serial = '0x%x' % int(certificate_login.getDestinationReference(), 16)
self.assertTrue(serial in compute_node_certificate)
self.assertTrue(self.compute_node.getReference() in compute_node_certificate.decode('string_escape'))
self.assertTrue(certificate_login.getReference() in compute_node_certificate.decode('string_escape'))
def test_generateCertificate_twice(self):
self.login(self.compute_node.getUserId())
......@@ -64,10 +69,17 @@ class TestSlapOSCoreComputeNodeSlapInterfaceWorkflow(SlapOSTestCaseMixin):
compute_node_certificate = self.portal.REQUEST.get('compute_node_certificate')
self.assertNotEqual(None, compute_node_key)
self.assertNotEqual(None, compute_node_certificate)
self.assertNotEqual(None, self.compute_node.getDestinationReference())
serial = '0x%x' % int(self.compute_node.getDestinationReference(), 16)
self.assertEqual(None, self.compute_node.getDestinationReference())
certificate_login_list = self.compute_node.objectValues(portal_type="Certificate Login")
self.assertEqual(len(certificate_login_list), 1)
certificate_login = certificate_login_list[0]
self.assertEqual(certificate_login.getValidationState(), 'validated')
self.assertNotEqual(certificate_login.getReference(), None)
self.assertNotEqual(certificate_login.getDestinationReference(), None)
serial = '0x%x' % int(certificate_login.getDestinationReference(), 16)
self.assertTrue(serial in compute_node_certificate)
self.assertTrue(self.compute_node.getReference() in compute_node_certificate.decode('string_escape'))
self.assertTrue(certificate_login.getReference() in compute_node_certificate.decode('string_escape'))
self.assertRaises(ValueError, self.compute_node.generateCertificate)
self.assertEqual(None, self.portal.REQUEST.get('compute_node_key'))
......@@ -252,16 +264,23 @@ class TestSlapOSCoreComputeNodeSlapInterfaceWorkflow(SlapOSTestCaseMixin):
compute_node_certificate = self.portal.REQUEST.get('compute_node_certificate')
self.assertNotEqual(None, compute_node_key)
self.assertNotEqual(None, compute_node_certificate)
self.assertNotEqual(None, self.compute_node.getDestinationReference())
serial = '0x%x' % int(self.compute_node.getDestinationReference(), 16)
certificate_login_list = self.compute_node.objectValues(portal_type="Certificate Login")
self.assertEqual(len(certificate_login_list), 1)
certificate_login = certificate_login_list[0]
self.assertEqual(certificate_login.getValidationState(), 'validated')
self.assertNotEqual(certificate_login.getReference(), None)
self.assertNotEqual(certificate_login.getDestinationReference(), None)
serial = '0x%x' % int(certificate_login.getDestinationReference(), 16)
self.assertTrue(serial in compute_node_certificate)
self.assertTrue(self.compute_node.getReference() in compute_node_certificate.decode('string_escape'))
self.assertTrue(certificate_login.getReference() in compute_node_certificate.decode('string_escape'))
self.assertNotEqual(certificate_login.getReference(),
self.compute_node.getReference())
self.compute_node.revokeCertificate()
self.assertEqual(None, self.portal.REQUEST.get('compute_node_key'))
self.assertEqual(None, self.portal.REQUEST.get('compute_node_certificate'))
self.assertEqual(None, self.compute_node.getDestinationReference())
self.assertEqual(certificate_login.getValidationState(), 'invalidated')
def test_revokeCertificateNoCertificate(self):
self.login(self.compute_node.getUserId())
......@@ -269,6 +288,8 @@ class TestSlapOSCoreComputeNodeSlapInterfaceWorkflow(SlapOSTestCaseMixin):
self.assertEqual(None, self.portal.REQUEST.get('compute_node_key'))
self.assertEqual(None, self.portal.REQUEST.get('compute_node_certificate'))
self.assertEqual(None, self.compute_node.getDestinationReference())
certificate_login_list = self.compute_node.objectValues(portal_type="Certificate Login")
self.assertEqual(len(certificate_login_list), 0)
def test_revokeCertificate_twice(self):
self.login(self.compute_node.getUserId())
......@@ -277,84 +298,188 @@ class TestSlapOSCoreComputeNodeSlapInterfaceWorkflow(SlapOSTestCaseMixin):
compute_node_certificate = self.portal.REQUEST.get('compute_node_certificate')
self.assertNotEqual(None, compute_node_key)
self.assertNotEqual(None, compute_node_certificate)
self.assertNotEqual(None, self.compute_node.getDestinationReference())
serial = '0x%x' % int(self.compute_node.getDestinationReference(), 16)
certificate_login_list = self.compute_node.objectValues(portal_type="Certificate Login")
self.assertEqual(len(certificate_login_list), 1)
certificate_login = certificate_login_list[0]
self.assertEqual(certificate_login.getValidationState(), 'validated')
self.assertNotEqual(certificate_login.getReference(), None)
self.assertNotEqual(certificate_login.getDestinationReference(), None)
serial = '0x%x' % int(certificate_login.getDestinationReference(), 16)
self.assertTrue(serial in compute_node_certificate)
self.assertTrue(self.compute_node.getReference() in compute_node_certificate.decode('string_escape'))
self.assertTrue(certificate_login.getReference() in compute_node_certificate.decode('string_escape'))
self.assertNotEqual(certificate_login.getReference(),
self.compute_node.getReference())
self.compute_node.revokeCertificate()
self.assertEqual(None, self.portal.REQUEST.get('compute_node_key'))
self.assertEqual(None, self.portal.REQUEST.get('compute_node_certificate'))
self.assertEqual(None, self.compute_node.getDestinationReference())
self.assertEqual(certificate_login.getValidationState(), 'invalidated')
self.assertRaises(ValueError, self.compute_node.revokeCertificate)
self.assertEqual(None, self.portal.REQUEST.get('compute_node_key'))
self.assertEqual(None, self.portal.REQUEST.get('compute_node_certificate'))
self.assertEqual(None, self.compute_node.getDestinationReference())
certificate_login_list = self.compute_node.objectValues(portal_type="Certificate Login")
self.assertEqual(len(certificate_login_list), 1)
self.assertEqual(certificate_login.getValidationState(), 'invalidated')
def test_renewCertificate(self):
self.login(self.compute_node.getUserId())
self.compute_node.generateCertificate()
compute_node_key = self.portal.REQUEST.get('compute_node_key')
compute_node_certificate = self.portal.REQUEST.get('compute_node_certificate')
destination_reference = self.compute_node.getDestinationReference()
self.assertNotEqual(None, compute_node_key)
self.assertNotEqual(None, compute_node_certificate)
self.assertNotEqual(None, destination_reference)
serial = '0x%x' % int(self.compute_node.getDestinationReference(), 16)
certificate_login_list = self.compute_node.objectValues(portal_type="Certificate Login")
self.assertEqual(len(certificate_login_list), 1)
certificate_login = certificate_login_list[0]
destination_reference = certificate_login.getDestinationReference()
self.assertEqual(certificate_login.getValidationState(), 'validated')
self.assertNotEqual(certificate_login.getReference(), None)
self.assertNotEqual(certificate_login.getDestinationReference(), None)
serial = '0x%x' % int(certificate_login.getDestinationReference(), 16)
self.assertTrue(serial in compute_node_certificate)
self.assertTrue(self.compute_node.getReference() in compute_node_certificate.decode('string_escape'))
self.assertTrue(certificate_login.getReference() in compute_node_certificate.decode('string_escape'))
self.assertNotEqual(certificate_login.getReference(),
self.compute_node.getReference())
self.assertNotEqual(None, destination_reference)
self.compute_node.revokeCertificate()
self.compute_node.generateCertificate()
self.assertNotEqual(None, self.portal.REQUEST.get('compute_node_key'))
self.assertNotEqual(None, self.portal.REQUEST.get('compute_node_certificate'))
self.assertNotEqual(None, self.compute_node.getDestinationReference())
self.assertNotEqual(compute_node_key, self.portal.REQUEST.get('compute_node_key'))
self.assertNotEqual(compute_node_certificate, self.portal.REQUEST.get('compute_node_certificate'))
self.assertNotEqual(destination_reference, self.compute_node.getDestinationReference())
self.assertEqual(certificate_login.getValidationState(), 'invalidated')
self.assertEqual(certificate_login.getDestinationReference(), destination_reference)
self.assertNotEqual(certificate_login.getReference(), None)
certificate_login_list = self.compute_node.objectValues(portal_type="Certificate Login")
self.assertEqual(len(certificate_login_list), 2)
new_certificate_login = [i for i in certificate_login_list \
if i.getId() != certificate_login.getId()][0]
destination_reference = certificate_login.getDestinationReference()
self.assertEqual(new_certificate_login.getValidationState(), 'validated')
self.assertNotEqual(new_certificate_login.getReference(), None)
self.assertNotEqual(new_certificate_login.getReference(),
certificate_login.getReference())
self.assertNotEqual(new_certificate_login.getDestinationReference(), None)
self.assertNotEqual(new_certificate_login.getDestinationReference(),
certificate_login.getDestinationReference())
serial = '0x%x' % int(new_certificate_login.getDestinationReference(), 16)
compute_node_certificate = self.portal.REQUEST.get('compute_node_certificate')
self.assertTrue(serial in compute_node_certificate)
self.assertTrue(new_certificate_login.getReference() in compute_node_certificate.decode('string_escape'))
self.assertFalse(certificate_login.getReference() in compute_node_certificate.decode('string_escape'))
self.assertNotEqual(certificate_login.getReference(),
self.compute_node.getReference())
def test_renewCertificate_twice(self):
self.login(self.compute_node.getUserId())
self.compute_node.generateCertificate()
compute_node_key = self.portal.REQUEST.get('compute_node_key')
compute_node_certificate = self.portal.REQUEST.get('compute_node_certificate')
destination_reference = self.compute_node.getDestinationReference()
self.assertNotEqual(None, compute_node_key)
self.assertNotEqual(None, compute_node_certificate)
self.assertNotEqual(None, self.compute_node.getDestinationReference())
serial = '0x%x' % int(self.compute_node.getDestinationReference(), 16)
certificate_login_list = self.compute_node.objectValues(portal_type="Certificate Login")
self.assertEqual(len(certificate_login_list), 1)
certificate_login = certificate_login_list[0]
destination_reference = certificate_login.getDestinationReference()
self.assertEqual(certificate_login.getValidationState(), 'validated')
self.assertNotEqual(certificate_login.getReference(), None)
self.assertNotEqual(certificate_login.getDestinationReference(), None)
serial = '0x%x' % int(certificate_login.getDestinationReference(), 16)
self.assertTrue(serial in compute_node_certificate)
self.assertTrue(self.compute_node.getReference() in compute_node_certificate.decode('string_escape'))
self.assertTrue(certificate_login.getReference() in compute_node_certificate.decode('string_escape'))
self.assertNotEqual(certificate_login.getReference(),
self.compute_node.getReference())
self.assertNotEqual(None, destination_reference)
self.compute_node.revokeCertificate()
self.compute_node.generateCertificate()
self.assertNotEqual(None, self.portal.REQUEST.get('compute_node_key'))
self.assertNotEqual(None, self.portal.REQUEST.get('compute_node_certificate'))
self.assertNotEqual(None, self.compute_node.getDestinationReference())
self.assertNotEqual(compute_node_key, self.portal.REQUEST.get('compute_node_key'))
self.assertNotEqual(compute_node_certificate, self.portal.REQUEST.get('compute_node_certificate'))
self.assertNotEqual(destination_reference, self.compute_node.getDestinationReference())
compute_node_key = self.portal.REQUEST.get('compute_node_key')
self.assertEqual(certificate_login.getValidationState(), 'invalidated')
self.assertEqual(certificate_login.getDestinationReference(), destination_reference)
self.assertNotEqual(certificate_login.getReference(), None)
certificate_login_list = self.compute_node.objectValues(portal_type="Certificate Login")
self.assertEqual(len(certificate_login_list), 2)
new_certificate_login = [i for i in certificate_login_list \
if i.getId() != certificate_login.getId()][0]
destination_reference = certificate_login.getDestinationReference()
self.assertEqual(new_certificate_login.getValidationState(), 'validated')
self.assertNotEqual(new_certificate_login.getReference(), None)
self.assertNotEqual(new_certificate_login.getReference(),
certificate_login.getReference())
self.assertNotEqual(new_certificate_login.getDestinationReference(), None)
self.assertNotEqual(new_certificate_login.getDestinationReference(),
certificate_login.getDestinationReference())
serial = '0x%x' % int(new_certificate_login.getDestinationReference(), 16)
compute_node_certificate = self.portal.REQUEST.get('compute_node_certificate')
destination_reference = self.compute_node.getDestinationReference()
self.assertTrue(serial in compute_node_certificate)
self.assertTrue(new_certificate_login.getReference() in compute_node_certificate.decode('string_escape'))
self.assertFalse(certificate_login.getReference() in compute_node_certificate.decode('string_escape'))
self.assertNotEqual(certificate_login.getReference(),
self.compute_node.getReference())
self.compute_node.revokeCertificate()
self.compute_node.generateCertificate()
self.assertNotEqual(None, self.portal.REQUEST.get('compute_node_key'))
self.assertNotEqual(None, self.portal.REQUEST.get('compute_node_certificate'))
self.assertNotEqual(None, self.compute_node.getDestinationReference())
self.assertNotEqual(compute_node_key, self.portal.REQUEST.get('compute_node_key'))
self.assertNotEqual(compute_node_certificate, self.portal.REQUEST.get('compute_node_certificate'))
self.assertNotEqual(destination_reference, self.compute_node.getDestinationReference())
self.assertEqual(new_certificate_login.getValidationState(), 'invalidated')
self.assertNotEqual(new_certificate_login.getDestinationReference(), destination_reference)
self.assertNotEqual(new_certificate_login.getReference(), None)
certificate_login_list = self.compute_node.objectValues(portal_type="Certificate Login")
self.assertEqual(len(certificate_login_list), 3)
third_certificate_login = [i for i in certificate_login_list \
if i.getId() not in [certificate_login.getId(), new_certificate_login.getId()]][0]
destination_reference = new_certificate_login.getDestinationReference()
self.assertEqual(third_certificate_login.getValidationState(), 'validated')
self.assertNotEqual(third_certificate_login.getReference(), None)
self.assertNotEqual(third_certificate_login.getReference(),
certificate_login.getReference())
self.assertNotEqual(third_certificate_login.getDestinationReference(), None)
self.assertNotEqual(third_certificate_login.getDestinationReference(),
new_certificate_login.getDestinationReference())
serial = '0x%x' % int(third_certificate_login.getDestinationReference(), 16)
compute_node_certificate = self.portal.REQUEST.get('compute_node_certificate')
self.assertTrue(serial in compute_node_certificate)
self.assertTrue(third_certificate_login.getReference() in compute_node_certificate.decode('string_escape'))
self.assertFalse(new_certificate_login.getReference() in compute_node_certificate.decode('string_escape'))
self.assertNotEqual(third_certificate_login.getReference(),
self.compute_node.getReference())
self.assertNotEqual(new_certificate_login.getReference(),
self.compute_node.getReference())
class TestSlapOSCoreComputeNodeSlapInterfaceWorkflowSupply(SlapOSTestCaseMixin):
......
......@@ -6,12 +6,6 @@
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_recorded_property_dict</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>testSlapOSCloudComputeNodeSlapInterfaceWorkflow</string> </value>
......@@ -61,28 +55,13 @@
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<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>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
......@@ -95,7 +74,7 @@
<item>
<key> <string>component_validation_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
</dictionary>
......@@ -104,7 +83,7 @@
</dictionary>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
......
......@@ -36,7 +36,7 @@ class TestSlapOSCoreComputePartitionSlapInterfaceWorkflow(SlapOSTestCaseMixin):
)
self.compute_node.validate()
login = self.compute_node.newContent(
portal_type="ERP5 Login",
portal_type="Certificate Login",
reference=self.compute_node.getReference()
)
login.validate()
......
......@@ -6,12 +6,6 @@
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_recorded_property_dict</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>testSlapOSCloudComputePartitionSlapInterfaceWorkflow</string> </value>
......@@ -55,28 +49,13 @@
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<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>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
......@@ -89,7 +68,7 @@
<item>
<key> <string>component_validation_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
</dictionary>
......@@ -98,7 +77,7 @@
</dictionary>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
......
......@@ -175,12 +175,6 @@ class TestSlapOSSoftwareInstanceConstraint(TestSlapOSConstraintMixin):
self.assertFalse(consistency_message in self.getMessageList(self.software_instance))
self.assertSameSet(current_message_list, self.getMessageList(self.software_instance))
def test_property_existence_destination_reference(self):
self._test_property_existence(self.software_instance,
'destination_reference',
'Property existence error for property destination_reference, this document'
' has no such property or the property has never been set')
def test_property_existence_source_reference(self):
property_id = 'source_reference'
consistency_message = 'Property existence error for property '\
......
......@@ -1140,68 +1140,88 @@ class TestSlapOSCoreInstanceSlapInterfaceWorkflowTransfer(SlapOSTestCaseMixin):
def test_generateCertificate(self):
self.login()
self.software_instance.setSslKey(None)
self.software_instance.setSslCertificate(None)
self.software_instance.setDestinationReference(None)
self.software_instance.getSslKey(None)
self.software_instance.getSslCertificate(None)
self.software_instance.generateCertificate()
self.assertNotEqual(self.software_instance.getDestinationReference(), None)
self.assertNotEqual(self.software_instance.getSslKey(), None)
self.assertNotEqual(self.software_instance.getSslCertificate(), None)
self.assertEqual(self.software_instance.getDestinationReference(), None)
certificate_login_list = self.software_instance.objectValues(portal_type="Certificate Login")
self.assertEqual(len(certificate_login_list), 1)
certificate_login = certificate_login_list[0]
self.assertEqual(certificate_login.getValidationState(), 'validated')
self.assertNotEqual(certificate_login.getReference(), None)
self.assertNotEqual(certificate_login.getDestinationReference(), None)
serial = '0x%x' % int(certificate_login.getDestinationReference(), 16)
self.assertTrue(serial in self.software_instance.getSslCertificate())
self.assertTrue(certificate_login.getReference() in \
self.software_instance.getSslCertificate().decode('string_escape'))
self.assertRaises(ValueError, self.software_instance.generateCertificate)
def test_revokeCertificate(self):
self.login()
self.assertNotEqual(self.software_instance.getDestinationReference(), None)
self.assertNotEqual(self.software_instance.getSslKey(), None)
self.assertNotEqual(self.software_instance.getSslCertificate(), None)
self.software_instance.revokeCertificate()
self.assertEqual(self.software_instance.getDestinationReference(), None)
self.assertEqual(self.software_instance.getSslKey(), None)
self.assertEqual(self.software_instance.getSslCertificate(), None)
self.assertRaises(ValueError, self.software_instance.revokeCertificate)
certificate_login_list = self.software_instance.objectValues(portal_type="Certificate Login")
self.assertEqual(len(certificate_login_list), 0)
def test_revokeAndGenerateCertificate(self):
self.login()
destination_reference = self.software_instance.getDestinationReference()
ssl_key = self.software_instance.getSslKey()
ssl_certificate = self.software_instance.getSslCertificate()
self.assertNotEqual(self.software_instance.getDestinationReference(), None)
self.assertNotEqual(self.software_instance.getSslKey(), None)
self.assertNotEqual(self.software_instance.getSslCertificate(), None)
self.software_instance.revokeCertificate()
self.assertRaises(ValueError, self.software_instance.revokeCertificate)
self.software_instance.generateCertificate()
self.assertNotEqual(self.software_instance.getDestinationReference(), None)
self.assertNotEqual(self.software_instance.getSslKey(), None)
self.assertNotEqual(self.software_instance.getSslCertificate(), None)
self.assertNotEqual(self.software_instance.getDestinationReference(),
destination_reference)
certificate_login_list = self.software_instance.objectValues(portal_type="Certificate Login")
self.assertEqual(len(certificate_login_list), 1)
certificate_login = certificate_login_list[0]
self.assertEqual(certificate_login.getValidationState(), 'validated')
self.assertNotEqual(certificate_login.getReference(), None)
self.assertNotEqual(certificate_login.getDestinationReference(), None)
self.assertNotEqual(self.software_instance.getSslKey(),
ssl_key)
self.assertNotEqual(self.software_instance.getSslCertificate(),
ssl_certificate)
destination_reference = self.software_instance.getDestinationReference()
ssl_key = self.software_instance.getSslKey()
ssl_certificate = self.software_instance.getSslCertificate()
self.software_instance.revokeCertificate()
self.software_instance.generateCertificate()
self.assertNotEqual(self.software_instance.getDestinationReference(), None)
self.assertNotEqual(self.software_instance.getSslKey(), None)
self.assertNotEqual(self.software_instance.getSslCertificate(), None)
self.assertNotEqual(self.software_instance.getDestinationReference(),
destination_reference)
self.assertNotEqual(self.software_instance.getSslKey(),
ssl_key)
self.assertNotEqual(self.software_instance.getSslCertificate(),
ssl_certificate)
certificate_login_list = self.software_instance.objectValues(portal_type="Certificate Login")
self.assertEqual(len(certificate_login_list), 2)
another_certificate_login = [ i for i in certificate_login_list
if i.getId() != certificate_login.getId()][0]
self.assertEqual(another_certificate_login.getValidationState(), 'validated')
self.assertNotEqual(another_certificate_login.getReference(), None)
self.assertNotEqual(another_certificate_login.getDestinationReference(), None)
self.assertEqual(certificate_login.getValidationState(), 'invalidated')
self.assertNotEqual(certificate_login.getReference(),
another_certificate_login.getReference())
self.assertNotEqual(certificate_login.getDestinationReference(),
another_certificate_login.getDestinationReference())
......@@ -6,12 +6,6 @@
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_recorded_property_dict</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>testSlapOSCloudInstanceSlapInterfaceWorkflow</string> </value>
......@@ -61,28 +55,13 @@
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<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>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
......@@ -95,7 +74,7 @@
<item>
<key> <string>component_validation_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
</dictionary>
......@@ -104,7 +83,7 @@
</dictionary>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
......
......@@ -59,7 +59,7 @@ class TestSlapOSCoreSlapOSCloudInteractionWorkflow(SlapOSTestCaseMixin):
specialise_value=hs)
if portal_type == "Software Instance":
self._addERP5Login(instance)
self._addCertificateLogin(instance)
self.tic()
def verify_activeSense_call(self):
......@@ -130,7 +130,7 @@ class TestSlapOSCoreSlapOSCloudInteractionWorkflow(SlapOSTestCaseMixin):
portal_type='Compute Node',
title="Compute Node %s for %s" % (self.new_id, self.person_user.getReference()),
reference="TESTCOMP-%s" % self.new_id)
self._addERP5Login(compute_node)
self._addCertificateLogin(compute_node)
installation = self.portal.software_installation_module.newContent(
portal_type='Software Installation',
......@@ -173,7 +173,7 @@ class TestSlapOSCoreSlapOSCloudInteractionWorkflow(SlapOSTestCaseMixin):
portal_type='Compute Node',
title="Compute Node %s for %s" % (new_id, self.person_user.getReference()),
reference="TESTCOMP-%s" % new_id)
self._addERP5Login(compute_node)
self._addCertificateLogin(compute_node)
partition = compute_node.newContent(
portal_type='Compute Partition',
title="Partition Compute Node %s for %s" % (new_id,
......
......@@ -6,12 +6,6 @@
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_recorded_property_dict</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>testSlapOSCloudInteractionWorkflow</string> </value>
......@@ -61,28 +55,13 @@
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<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>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
......@@ -95,7 +74,7 @@
<item>
<key> <string>component_validation_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
</dictionary>
......@@ -104,7 +83,7 @@
</dictionary>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
......
......@@ -117,12 +117,6 @@ class TestSlapOSComputeNodeSecurity(TestSlapOSSecurityMixin):
self._assertUserDoesNotExists(user_id, reference, None)
def test_active_backward_compatibility_with_erp5_login(self):
self.test_active(login_portal_type="ERP5 Login")
def test_inactive_backward_compatibility_with_erp5_login(self):
self.test_inactive(login_portal_type="ERP5 Login")
class TestSlapOSSoftwareInstanceSecurity(TestSlapOSSecurityMixin):
portal_type = 'Software Instance'
def test_active(self, login_portal_type="Certificate Login"):
......@@ -175,12 +169,6 @@ class TestSlapOSSoftwareInstanceSecurity(TestSlapOSSecurityMixin):
self._assertUserDoesNotExists(user_id, reference, None)
def test_active_backward_compatibility_with_erp5_login(self):
self.test_active(login_portal_type="ERP5 Login")
def test_inactive_backward_compatibility_with_erp5_login(self):
self.test_inactive(login_portal_type="ERP5 Login")
class TestSlapOSPersonSecurity(TestSlapOSSecurityMixin):
def test_active(self, login_portal_type="Certificate Login"):
......
......@@ -6,12 +6,6 @@
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_recorded_property_dict</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>testSlapOSCloudSecurityGroup</string> </value>
......@@ -55,28 +49,13 @@
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<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>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
......@@ -89,7 +68,7 @@
<item>
<key> <string>component_validation_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
</dictionary>
......@@ -98,7 +77,7 @@
</dictionary>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
......
......@@ -84,7 +84,7 @@ class TestSlapOSShadowComputeNode(TestSlapOSSecurityMixin):
reference=reference)
compute_node.setUserId(user_id)
compute_node.newContent(portal_type='ERP5 Login',
compute_node.newContent(portal_type='Certificate Login',
reference=reference).validate()
compute_node.validate()
......@@ -125,7 +125,7 @@ class TestSlapOSShadowSoftwareInstance(TestSlapOSSecurityMixin):
instance = self.portal.getDefaultModule(portal_type=self.portal_type)\
.newContent(portal_type=self.portal_type, reference=reference)
instance.setUserId(user_id)
instance.newContent(portal_type='ERP5 Login',
instance.newContent(portal_type='Certificate Login',
reference=reference).validate()
instance.validate()
self.tic()
......
......@@ -6,12 +6,6 @@
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_recorded_property_dict</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>testSlapOSCloudShadow</string> </value>
......@@ -55,28 +49,13 @@
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<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>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
......@@ -89,7 +68,7 @@
<item>
<key> <string>component_validation_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
</dictionary>
......@@ -98,7 +77,7 @@
</dictionary>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
......
......@@ -8,10 +8,4 @@ compute_node.edit(
capacity_scope='open'
)
erp5_login = compute_node.newContent(
portal_type="Certificate Login",
reference=compute_node.getReference()
)
erp5_login.validate()
portal.portal_workflow.doActionFor(compute_node, 'validate_action')
compute_node = state_change['object']
if compute_node.getDestinationReference() is not None:
context.REQUEST.set("compute_node_certificate", None)
context.REQUEST.set("compute_node_key", None)
raise ValueError('Certificate still active.')
ca = context.getPortalObject().portal_certificate_authority
certificate_dict = ca.getNewCertificate(compute_node.getReference())
compute_node.setDestinationReference(certificate_dict["id"])
for certificate_login in compute_node.objectValues(
portal_type=["Certificate Login"]):
if certificate_login.getValidationState() == "validated":
context.REQUEST.set("compute_node_certificate", None)
context.REQUEST.set("compute_node_key", None)
raise ValueError('Certificate still active.')
certificate_login = compute_node.newContent(
portal_type="Certificate Login")
certificate_dict = certificate_login.getCertificate()
certificate_login.validate()
context.REQUEST.set("compute_node_certificate", certificate_dict["certificate"])
context.REQUEST.set("compute_node_key", certificate_dict["key"])
......@@ -52,6 +52,12 @@
<key> <string>_params</string> </key>
<value> <string>state_change</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>script_ComputeNode_generateCertificate</string> </value>
......
compute_node = state_change['object']
context.REQUEST.set('compute_node_certificate', None)
context.REQUEST.set('compute_node_key', None)
destination_reference = compute_node.getDestinationReference()
if destination_reference is None:
no_certificate = True
for certificate_login in compute_node.objectValues(
portal_type=["Certificate Login"]):
if certificate_login.getValidationState() == "validated":
certificate_login.invalidate()
no_certificate = False
if no_certificate:
raise ValueError('No certificate')
context.getPortalObject().portal_certificate_authority.revokeCertificate(destination_reference)
compute_node.setDestinationReference(None)
......@@ -52,6 +52,12 @@
<key> <string>_params</string> </key>
<value> <string>state_change</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>script_ComputeNode_revokeCertificate</string> </value>
......
instance = state_change['object']
if instance.getDestinationReference() is not None:
raise ValueError("Certificate still active.")
if instance.getPortalType() != "Software Instance":
# Skip if the instance isn't a Software Instance,
# since Shared Instances cannot find the object.
return
ca = context.getPortalObject().portal_certificate_authority
certificate_dict = ca.getNewCertificate(instance.getReference())
edit_kw = {'destination_reference' : certificate_dict['id'],
'ssl_key' : certificate_dict['key'],
'ssl_certificate': certificate_dict['certificate']
}
for certificate_login in instance.objectValues(
portal_type=["Certificate Login"]):
if certificate_login.getValidationState() == "validated":
raise ValueError('Certificate still active.')
# Include Certificate Login so Instance become a User
certificate_login = instance.newContent(
portal_type="Certificate Login")
certificate_dict = certificate_login.getCertificate()
certificate_login.validate()
# Keep this here?
edit_kw = {'ssl_key' : certificate_dict['key'],
'ssl_certificate': certificate_dict['certificate']}
instance.edit(**edit_kw)
instance = state_change['object']
portal = instance.getPortalObject()
if instance.getSslKey() is not None or instance.getSslCertificate() is not None:
instance.edit(ssl_key=None, ssl_certificate=None)
destination_reference = instance.getDestinationReference()
if destination_reference is None:
raise ValueError('No certificate')
no_certificate = True
for certificate_login in instance.objectValues(
portal_type=["Certificate Login"]):
if certificate_login.getValidationState() == "validated":
certificate_login.invalidate()
no_certificate = False
try:
portal.portal_certificate_authority\
.revokeCertificate(instance.getDestinationReference())
except ValueError:
# Ignore already revoked certificates, as OpenSSL backend is
# non transactional, so it is ok to allow multiple tries to destruction
# even if certificate was already revoked
pass
instance.setDestinationReference(None)
if no_certificate:
raise ValueError('No certificate')
......@@ -68,9 +68,7 @@
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</value>
<value> <string>None</string> </value>
</item>
</dictionary>
</pickle>
......
......@@ -93,14 +93,9 @@ if (request_software_instance is None):
reference=reference,
activate_kw={'tag': tag}
)
request_software_instance.generateCertificate()
request_software_instance.validate()
if software_instance_portal_type == "Software Instance":
# Include Certificate Login so Instance become a User
certificate_login = request_software_instance.newContent(
portal_type="Certificate Login",
reference=request_software_instance.getReference())
certificate_login.validate()
request_software_instance.generateCertificate()
request_software_instance.validate()
graph[request_software_instance.getUid()] = []
......
Compute Node | compute_node_usage
Compute Node | tracking
Compute Node | view_capacity
Compute Node | view_certificate_login
Compute Partition | unfiltered_tracking_list
Computer Model | view_capacity
Computer Network | view_compute_node_list
......@@ -30,6 +31,7 @@ Software Instance | jump_to_instance_tree
Software Instance | jump_to_software_instance
Software Instance | unfiltered_tracking_list
Software Instance | view
Software Instance | view_certificate_login
Software Instance | view_rename_and_request_destroy
Software Instance | view_rename_and_request_stop
Software Release | usable_compute_node
......
Compute Node | Certificate Login
Compute Node | ERP5 Login
Hosting Subscription Module | Hosting Subscription
Instance Tree Module | Instance Tree
Software Installation Module | Software Installation
Software Instance Module | Slave Instance
Software Instance Module | Software Instance
Software Instance | Certificate Login
Software Instance | ERP5 Login
\ No newline at end of file
Software Instance | Certificate Login
\ No newline at end of file
......@@ -7,8 +7,21 @@
<multi_property id='base_category'>aggregate</multi_property>
</role>
<role id='Assignee'>
<property id='title'>The User Himself</property>
<property id='condition'>python: here.getParentValue().getPortalType() in ("Person", "Software Instance", "Compute Node")</property>
<property id='title'>Compute Node Agent</property>
<property id='base_category_script'>ERP5Type_getSecurityCategoryFromParentContent</property>
<multi_property id='categories'>local_role_group/user</multi_property>
<multi_property id='base_category'>source_administration</multi_property>
</role>
<role id='Assignee'>
<property id='title'>The User Himself (Compute Node)</property>
<property id='condition'>python: here.getParentValue().getPortalType() in ( "Compute Node", "Software Instance")</property>
<property id='base_category_script'>ERP5Type_getSecurityCategoryFromParent</property>
<multi_property id='categories'>local_role_group/computer</multi_property>
<multi_property id='base_category'>group</multi_property>
</role>
<role id='Assignee'>
<property id='title'>The User Himself (Person)</property>
<property id='condition'>python: here.getParentValue().getPortalType() == "Person"</property>
<property id='base_category_script'>ERP5Type_getSecurityCategoryFromParent</property>
<multi_property id='categories'>local_role_group/user</multi_property>
<multi_property id='base_category'>group</multi_property>
......
......@@ -45,6 +45,8 @@ url_list = [
"gadget_erp5_page_slap_facebook_login_view.html",
"gadget_erp5_page_slap_google_login_view.html",
"gadget_erp5_page_slap_erp5_login_view.html",
"gadget_erp5_page_slap_certificate_login_view.html",
"gadget_erp5_page_slap_certificate_login_view.js",
"gadget_erp5_page_slap_google_login_view.js",
"gadget_erp5_page_slap_facebook_login_view.js",
"gadget_erp5_page_slap_erp5_login_view.js",
......@@ -104,8 +106,6 @@ url_list = [
"gadget_erp5_page_slap_person_add_organisation.html",
"gadget_erp5_page_slap_person_request_certificate.html",
"gadget_erp5_page_slap_person_request_certificate.js",
"gadget_erp5_page_slap_person_revoke_certificate.html",
"gadget_erp5_page_slap_person_revoke_certificate.js",
"gadget_erp5_page_slap_person_view.html",
"gadget_erp5_page_slap_person_view.js",
"gadget_erp5_page_slap_project_list.html",
......
"""
This script returns a list of dictionaries which represent
the security groups which a person is member of. It extracts
the categories from the current content. It is useful in the
following cases:
- calculate a security group based on a given
category of the current object (ex. group). This
is used for example in ERP5 DMS to calculate
document security.
- assign local roles to a document based on
the person which the object related to through
a given base category (ex. destination). This
is used for example in ERP5 Project to calculate
Task / Task Report security.
The parameters are
base_category_list -- list of category values we need to retrieve
user_name -- string obtained from getSecurityManager().getUser().getId()
object -- object which we want to assign roles to
portal_type -- portal type of object
NOTE: for now, this script requires proxy manager
"""
category_list = []
if ob is None:
return []
for base_category in base_category_list:
category_list.append({base_category: [x.getRelativeUrl() for x in ob.getParentValue().getValueList(base_category)]})
return category_list
......@@ -50,11 +50,11 @@
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>*args, **kwargs</string> </value>
<value> <string>base_category_list, user_name, ob, portal_type</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Person_revokeCertificate</string> </value>
<value> <string>ERP5Type_getSecurityCategoryFromParentContent</string> </value>
</item>
</dictionary>
</pickle>
......
......@@ -108,17 +108,6 @@ class TestSlapOSAuthenticationPolicyL(SlapOSTestCaseMixin):
document=person,
login_portal_type="ERP5 Login")
def test_block_ERP5Login_without_password_on_compute_node(self):
self._test_login_block_if_password_is_set(
document=self._makeComputeNode()[0],
login_portal_type="ERP5 Login"
)
def test_block_ERP5Login_without_password_on_software_instance(self):
self._test_login_block_if_password_is_set(
document=self._makeDummySoftwareInstance(),
login_portal_type="ERP5 Login")
def test_block_CertificateLogin_without_password_on_person(self):
person = self.makePerson(user=0)
person.edit(
......@@ -223,17 +212,6 @@ class TestSlapOSAuthenticationPolicyL(SlapOSTestCaseMixin):
document=person,
login_portal_type="ERP5 Login")
def test_expire_ERP5Login_without_password_on_compute_node(self):
self._test_expire_when_passoword_is_set(
document=self._makeComputeNode()[0],
login_portal_type="ERP5 Login"
)
def test_expire_ERP5Login_without_password_on_software_instance(self):
self._test_expire_when_passoword_is_set(
document=self._makeDummySoftwareInstance(),
login_portal_type="ERP5 Login")
def test_expire_CertificateLogin_without_password_on_person(self):
person = self.makePerson(user=0)
person.edit(
......
......@@ -6,12 +6,6 @@
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_recorded_property_dict</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>testSlapOSAuthenticationPolicy</string> </value>
......@@ -55,28 +49,13 @@
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<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>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
......@@ -89,7 +68,7 @@
<item>
<key> <string>component_validation_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
</dictionary>
......@@ -98,7 +77,7 @@
</dictionary>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
......
......@@ -18,6 +18,7 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
##############################################################################
from erp5.component.test.SlapOSTestCaseDefaultScenarioMixin import DefaultScenarioMixin
from DateTime import DateTime
import re
......@@ -48,6 +49,7 @@ class TestSlapOSDefaultScenario(DefaultScenarioMixin):
self.setAccessToMemcached(public_server)
self.assertNotEqual(None, public_server)
self.setServerOpenPublic(public_server)
public_server.generateCertificate()
personal_server_title = 'Personal Server for %s' % owner_reference
personal_server_id = self.requestComputeNode(personal_server_title)
......@@ -56,6 +58,7 @@ class TestSlapOSDefaultScenario(DefaultScenarioMixin):
self.setAccessToMemcached(personal_server)
self.assertNotEqual(None, personal_server)
self.setServerOpenPersonal(personal_server)
personal_server.generateCertificate()
# and install some software on them
public_server_software = self.generateNewSoftwareReleaseUrl()
......
......@@ -682,11 +682,8 @@ class TestPerson(TestSlapOSGroupRoleSecurityMixin):
self.assertRoles(person, project.getReference(), ['Auditor'])
self.assertRoles(person, self.user_id, ['Owner'])
class TestERP5Login(TestSlapOSGroupRoleSecurityMixin):
login_portal_type = "ERP5 Login"
class TestCertificateLogin(TestSlapOSGroupRoleSecurityMixin):
login_portal_type = "Certificate Login"
def test_PersonCanAccessLoginDocument(self):
person = self.portal.person_module.newContent(portal_type='Person')
......@@ -699,6 +696,27 @@ class TestERP5Login(TestSlapOSGroupRoleSecurityMixin):
self.assertRoles(login, person.getUserId(), ['Assignee'])
self.assertRoles(login, self.user_id, ['Owner'])
def test_ComputeNodeCanAccessSoftwareInstanceLoginDocument(self):
software_instance = self.portal.software_instance_module.newContent(portal_type='Software Instance')
login = software_instance.newContent(portal_type=self.login_portal_type)
compute_node_reference = 'TESTCOMP-%s' % self.generateNewId()
compute_node = self.portal.compute_node_module.template_compute_node\
.Base_createCloneDocument(batch_mode=1)
compute_node.edit(reference=compute_node_reference)
partition = compute_node.newContent(portal_type='Compute Partition')
software_instance.edit(aggregate=partition.getRelativeUrl())
compute_node.updateLocalRolesOnSecurityGroups()
software_instance.updateLocalRolesOnSecurityGroups()
login.updateLocalRolesOnSecurityGroups()
self.assertSecurityGroup(login,
[self.user_id, software_instance.getUserId(),
compute_node.getUserId()], False)
self.assertRoles(login, software_instance.getUserId(), ['Assignee'])
self.assertRoles(login, self.user_id, ['Owner'])
self.assertRoles(login, compute_node.getUserId(), ['Assignor'])
def test_ComputeNodeCanAccessLoginDocument(self):
compute_node = self.portal.compute_node_module.newContent(portal_type='Compute Node')
login = compute_node.newContent(portal_type=self.login_portal_type)
......@@ -710,6 +728,21 @@ class TestERP5Login(TestSlapOSGroupRoleSecurityMixin):
self.assertRoles(login, compute_node.getUserId(), ['Assignee'])
self.assertRoles(login, self.user_id, ['Owner'])
def test_ComputeNodeSourceAdministrationCanAccessLoginDocument(self):
person = self.portal.person_module.newContent(portal_type='Person')
compute_node = self.portal.compute_node_module.newContent(
portal_type='Compute Node', source_administration=person.getRelativeUrl())
login = compute_node.newContent(portal_type=self.login_portal_type)
compute_node.updateLocalRolesOnSecurityGroups()
login.updateLocalRolesOnSecurityGroups()
self.assertSecurityGroup(login,
[self.user_id, compute_node.getUserId(),
person.getUserId()], False)
self.assertRoles(login, compute_node.getUserId(), ['Assignee'])
self.assertRoles(login, self.user_id, ['Owner'])
self.assertRoles(login, person.getUserId(), ['Assignee'])
def test_SoftwareInstanceCanAccessLoginDocument(self):
software_instance = self.portal.software_instance_module.newContent(portal_type='Software Instance')
login = software_instance.newContent(portal_type=self.login_portal_type)
......@@ -721,48 +754,25 @@ class TestERP5Login(TestSlapOSGroupRoleSecurityMixin):
self.assertRoles(login, software_instance.getUserId(), ['Assignee'])
self.assertRoles(login, self.user_id, ['Owner'])
class TestCertificateLogin(TestERP5Login):
login_portal_type = "Certificate Login"
def test_ComputeNodeCanAccessSoftwareInstanceLoginDocument(self):
software_instance = self.portal.software_instance_module.newContent(portal_type='Software Instance')
login = software_instance.newContent(portal_type=self.login_portal_type)
compute_node_reference = 'TESTCOMP-%s' % self.generateNewId()
compute_node = self.portal.compute_node_module.template_compute_node\
.Base_createCloneDocument(batch_mode=1)
compute_node.edit(reference=compute_node_reference)
partition = compute_node.newContent(portal_type='Compute Partition')
software_instance.edit(aggregate=partition.getRelativeUrl())
class TestERP5Login(TestSlapOSGroupRoleSecurityMixin):
login_portal_type = "ERP5 Login"
compute_node.updateLocalRolesOnSecurityGroups()
software_instance.updateLocalRolesOnSecurityGroups()
def test_PersonCanAccessLoginDocument(self):
person = self.portal.person_module.newContent(portal_type='Person')
login = person.newContent(portal_type=self.login_portal_type)
person.updateLocalRolesOnSecurityGroups()
login.updateLocalRolesOnSecurityGroups()
self.assertSecurityGroup(login,
[self.user_id, software_instance.getUserId(), compute_node.getUserId()], False)
self.assertRoles(login, software_instance.getUserId(), ['Assignee'])
[self.user_id, person.getUserId()], False)
self.assertRoles(login, person.getUserId(), ['Assignee'])
self.assertRoles(login, self.user_id, ['Owner'])
self.assertRoles(login, compute_node.getUserId(), ['Assignor'])
class TestGoogleLogin(TestERP5Login):
login_portal_type = "Google Login"
def test_ComputeNodeCanAccessLoginDocument(self):
# Not supported to add google login inside Compute Node
pass
def test_SoftwareInstanceCanAccessLoginDocument(self):
# Not supported to add google login inside SoftwareInstance
pass
class TestFacebookLogin(TestERP5Login):
login_portal_type = "Facebook Login"
def test_ComputeNodeCanAccessLoginDocument(self):
# Not supported to add google login inside Compute Node
pass
def test_SoftwareInstanceCanAccessLoginDocument(self):
# Not supported to add google login inside SoftwareInstance
pass
class TestPersonModule(TestSlapOSGroupRoleSecurityMixin):
def test(self):
......
<?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_jio_view</string>
</tuple>
</value>
</item>
<item>
<key> <string>category</string> </key>
<value> <string>object_jio_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>slaposjs_view</string> </value>
</item>
<item>
<key> <string>permissions</string> </key>
<value>
<tuple>
<string>View</string>
</tuple>
</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}/Login_viewAsHateoas</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<!doctype html>
<!DOCTYPE html>
<html>
<!--
data-i18n=Certificate is Revoked.
data-i18n=This person has no certificate to revoke.
data-i18n=Parent Relative Url
data-i18n=Revoke Person Certificate
data-i18n=Data updated.
data-i18n=Reference
data-i18n=Info
-->
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, user-scalable=no" />
<title>Certificate Login</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- renderjs -->
<script src="rsvp.js" type="text/javascript"></script>
<script src="renderjs.js" type="text/javascript"></script>
<title>OfficeJS Add Text Document</title>
<script src="rsvp.js"></script>
<script src="renderjs.js"></script>
<script src="gadget_erp5_page_slap_person_revoke_certificate.js"></script>
<!-- custom script -->
<script src="gadget_erp5_page_slap_certificate_login_view.js" type="text/javascript"></script>
</head>
<body>
<form class="save_form ui-body-c" novalidate>
<form class="save_form ui-body-c" novalidate>
<button type="submit" class="ui-btn ui-btn-b ui-btn-inline
ui-icon-edit ui-btn-icon-right ui-screen-hidden"></button>
<div data-gadget-url="gadget_erp5_form.html"
data-gadget-scope="form_view"
data-gadget-sandbox="public">
</div>
</form>
</form>
</body>
</html>
......@@ -16,7 +16,6 @@
<string>Associate</string>
<string>Auditor</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
......@@ -59,15 +58,6 @@
<string>Associate</string>
<string>Auditor</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>contributor/person_module/1</string>
</tuple>
</value>
</item>
......@@ -81,17 +71,9 @@
<key> <string>content_type</string> </key>
<value> <string>text/html</string> </value>
</item>
<item>
<key> <string>creators</string> </key>
<value>
<tuple>
<string>cedric.le.ninivin</string>
</tuple>
</value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>gadget_erp5_page_slap_person_revoke_certificate.html</string> </value>
<value> <string>gadget_erp5_page_slap_certificate_login_view.html</string> </value>
</item>
<item>
<key> <string>description</string> </key>
......@@ -101,34 +83,11 @@
</item>
<item>
<key> <string>id</string> </key>
<value> <string>rjs_gadget_erp5_page_slap_person_revoke_certificate_html</string> </value>
<value> <string>rjs_gadget_erp5_page_slap_certificate_login_view_html</string> </value>
</item>
<item>
<key> <string>language</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>modification_date</string> </key>
<value>
<object>
<klass>
<global name="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="DateTime" module="DateTime.DateTime"/>
<global name="object" module="__builtin__"/>
<none/>
</tuple>
<state>
<tuple>
<float>1455284351.46</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
<value> <string>en</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
......@@ -142,17 +101,11 @@
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Slap Person Revoke Certificate</string> </value>
</item>
<item>
<key> <string>url_string</string> </key>
<value>
<none/>
</value>
<value> <string>Gadget SlapOS Certificate Login View</string> </value>
</item>
<item>
<key> <string>version</string> </key>
<value> <string>001</string> </value>
<value> <string>003</string> </value>
</item>
<item>
<key> <string>workflow_history</string> </key>
......@@ -238,7 +191,7 @@
</tuple>
<state>
<tuple>
<float>1509386436.45</float>
<float>1691431457.39</float>
<string>UTC</string>
</tuple>
</state>
......@@ -287,7 +240,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>982.21236.17255.51438</string> </value>
<value> <string>1010.19506.37963.38263</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -307,7 +260,7 @@
</tuple>
<state>
<tuple>
<float>1583423335.96</float>
<float>1691432940.96</float>
<string>UTC</string>
</tuple>
</state>
......@@ -370,7 +323,7 @@
</tuple>
<state>
<tuple>
<float>1509386361.74</float>
<float>1691430967.31</float>
<string>UTC</string>
</tuple>
</state>
......
/*global window, rJS, RSVP */
/*global window, rJS, RSVP, jIO, Blob */
/*jslint nomen: true, indent: 2, maxerr: 3 */
(function (window, rJS, RSVP) {
"use strict";
......@@ -9,20 +9,28 @@
/////////////////////////////////////////////////////////////////
.declareAcquiredMethod("updateHeader", "updateHeader")
.declareAcquiredMethod("updatePanel", "updatePanel")
.declareAcquiredMethod("getSetting", "getSetting")
.declareAcquiredMethod("getUrlParameter", "getUrlParameter")
.declareAcquiredMethod("getUrlFor", "getUrlFor")
.declareAcquiredMethod("redirect", "redirect")
.declareAcquiredMethod("jio_post", "jio_post")
.declareAcquiredMethod("getSetting", "getSetting")
.declareAcquiredMethod("updateDocument", "updateDocument")
.declareAcquiredMethod("jio_getAttachment", "jio_getAttachment")
.declareAcquiredMethod("jio_putAttachment", "jio_putAttachment")
.declareAcquiredMethod("notifySubmitting", "notifySubmitting")
.declareAcquiredMethod("notifySubmitted", 'notifySubmitted')
.declareAcquiredMethod("jio_allDocs", "jio_allDocs")
.declareAcquiredMethod("getTranslationList", "getTranslationList")
/////////////////////////////////////////////////////////////////
// declared methods
/////////////////////////////////////////////////////////////////
.allowPublicAcquisition('notifySubmit', function () {
return this.triggerSubmit();
.declareMethod("render", function (options) {
return this.changeState({
jio_key: options.jio_key,
doc: options.doc,
editable: 1
});
})
.onEvent('submit', function () {
......@@ -34,26 +42,11 @@
.push(function (form_gadget) {
return form_gadget.getContent();
})
.push(function (doc) {
return gadget.getSetting("hateoas_url")
.push(function (url) {
return gadget.jio_getAttachment(doc.relative_url,
url + doc.relative_url + "/Person_revokeCertificate");
});
.push(function (content) {
return gadget.updateDocument(content);
})
.push(function (result) {
var msg;
if (result) {
msg = gadget.msg1_translation;
} else {
msg = gadget.msg2_translation;
}
return gadget.notifySubmitted({message: msg, status: 'success'})
.push(function () {
// Workaround, find a way to open document without break gadget.
return gadget.redirect({"command": "change",
"options": {"page": "slap_controller"}});
});
.push(function () {
return gadget.notifySubmitted({message: gadget.message_translation, status: 'success'});
});
})
......@@ -61,38 +54,37 @@
return this.element.querySelector('button[type="submit"]').click();
})
.declareMethod("render", function (options) {
.onStateChange(function () {
var gadget = this,
page_title_translation,
translation_list = [
"Certificate is Revoked.",
"This person has no certificate to revoke.",
"Parent Relative Url",
"Revoke Person Certificate"
"Data updated.",
"Reference",
"Certificate Login:"
];
return new RSVP.Queue()
.push(function () {
return RSVP.all([
gadget.getDeclaredGadget('form_view'),
gadget.getSetting("hateoas_url"),
gadget.getTranslationList(translation_list)
]);
})
.push(function (result) {
page_title_translation = result[1][3];
gadget.msg1_translation = result[1][0];
gadget.msg2_translation = result[1][1];
gadget.message_translation = result[2][0];
page_title_translation = result[2][2];
return result[0].render({
erp5_document: {
"_embedded": {"_view": {
"my_relative_url": {
"my_reference": {
"description": "",
"title": result[1][2],
"default": options.jio_key,
"title": result[2][1],
"default": gadget.state.doc.reference,
"css_class": "",
"required": 1,
"editable": 1,
"key": "relative_url",
"hidden": 1,
"editable": 0,
"key": "reference",
"hidden": 0,
"type": "StringField"
}
}},
......@@ -106,7 +98,7 @@
form_definition: {
group_list: [[
"left",
[["my_relative_url"]]
[["my_reference"]]
]]
}
});
......@@ -118,15 +110,17 @@
})
.push(function () {
return RSVP.all([
gadget.getUrlFor({command: 'change', options: {page: 'slap_person_view'}})
gadget.getUrlFor({command: 'history_previous'}),
gadget.getUrlFor({command: "change", options: {page: "slap_invalidate_login"}})
]);
})
.push(function (url_list) {
var header_dict = {
page_title: page_title_translation,
submit_action: true,
selection_url: url_list[0]
selection_url: url_list[0],
page_title: page_title_translation + " " + gadget.state.doc.reference,
delete_url: url_list[1]
};
return gadget.updateHeader(header_dict);
});
});
......
......@@ -16,7 +16,6 @@
<string>Associate</string>
<string>Auditor</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
......@@ -39,6 +38,17 @@
</tuple>
</value>
</item>
<item>
<key> <string>_Copy_or_Move_Permission</string> </key>
<value>
<list>
<string>Manager</string>
<string>Authenticated</string>
<string>Developer</string>
<string>Owner</string>
</list>
</value>
</item>
<item>
<key> <string>_Modify_portal_content_Permission</string> </key>
<value>
......@@ -59,15 +69,6 @@
<string>Associate</string>
<string>Auditor</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>contributor/person_module/1</string>
</tuple>
</value>
</item>
......@@ -77,17 +78,9 @@
<none/>
</value>
</item>
<item>
<key> <string>creators</string> </key>
<value>
<tuple>
<string>cedric.le.ninivin</string>
</tuple>
</value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>gadget_erp5_page_slap_person_revoke_certificate.js</string> </value>
<value> <string>gadget_erp5_page_slap_certificate_login_view.js</string> </value>
</item>
<item>
<key> <string>description</string> </key>
......@@ -97,34 +90,11 @@
</item>
<item>
<key> <string>id</string> </key>
<value> <string>rjs_gadget_erp5_page_slap_person_revoke_certificate_js</string> </value>
<value> <string>rjs_gadget_erp5_page_slap_certificate_login_view_js</string> </value>
</item>
<item>
<key> <string>language</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>modification_date</string> </key>
<value>
<object>
<klass>
<global name="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="DateTime" module="DateTime.DateTime"/>
<global name="object" module="__builtin__"/>
<none/>
</tuple>
<state>
<tuple>
<float>1455284351.49</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
<value> <string>en</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
......@@ -138,17 +108,11 @@
</item>
<item>
<key> <string>title</string> </key>
<value> <string>SlapOS Revoke Certificate JS</string> </value>
</item>
<item>
<key> <string>url_string</string> </key>
<value>
<none/>
</value>
<value> <string>Gadget SlapOS Certificate Login View</string> </value>
</item>
<item>
<key> <string>version</string> </key>
<value> <string>001</string> </value>
<value> <string>003</string> </value>
</item>
<item>
<key> <string>workflow_history</string> </key>
......@@ -234,7 +198,7 @@
</tuple>
<state>
<tuple>
<float>1509386632.79</float>
<float>1691431608.83</float>
<string>UTC</string>
</tuple>
</state>
......@@ -283,7 +247,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>986.45437.22132.61764</string> </value>
<value> <string>1010.19559.12294.65348</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -303,7 +267,7 @@
</tuple>
<state>
<tuple>
<float>1602258980.64</float>
<float>1691437353.66</float>
<string>UTC</string>
</tuple>
</state>
......@@ -366,7 +330,7 @@
</tuple>
<state>
<tuple>
<float>1509386579.96</float>
<float>1691431315.97</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -401,14 +401,14 @@
page_title: page_title_translation + " " + gadget.state.doc.title,
ticket_url: url_list[1],
supply_url: url_list[2],
request_certificate_url: url_list[3],
revoke_certificate_url: url_list[4],
rss_url: url_list[5],
selection_url: url_list[7],
save_action: true
};
if (gadget.state.doc.is_owner !== undefined) {
header_dict.transfer_url = url_list[6];
header_dict.request_certificate_url = url_list[3];
header_dict.revoke_certificate_url = url_list[4];
}
if (!gadget.state.editable) {
header_dict.edit_content = url_list[0];
......
......@@ -267,7 +267,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>1008.51160.9059.61542</string> </value>
<value> <string>1009.49086.48551.49459</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -287,7 +287,7 @@
</tuple>
<state>
<tuple>
<float>1687464494.14</float>
<float>1690911267.44</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -7,17 +7,19 @@
data-i18n=Your Certificate
data-i18n=Your Key
data-i18n=Request New Certificate
data-i18n=Title
-->
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>OfficeJS Add Text Document</title>
<title>Request New Certificate</title>
<script src="rsvp.js"></script>
<script src="renderjs.js"></script>
<script src="gadget_erp5_page_slap_person_request_certificate.js"></script>
<script src="rsvp.js" type="text/javascript"></script>
<script src="renderjs.js" type="text/javascript"></script>
<script src="gadget_erp5_page_slap_person_request_certificate.js" type="text/javascript"></script>
</head>
......
......@@ -287,7 +287,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>982.32516.46874.3959</string> </value>
<value> <string>1010.21499.31843.44083</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -307,7 +307,7 @@
</tuple>
<state>
<tuple>
<float>1584350630.01</float>
<float>1691552889.43</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -11,8 +11,8 @@
.declareAcquiredMethod("updatePanel", "updatePanel")
.declareAcquiredMethod("getSetting", "getSetting")
.declareAcquiredMethod("getUrlFor", "getUrlFor")
.declareAcquiredMethod("jio_get", "jio_get")
.declareAcquiredMethod("redirect", "redirect")
.declareAcquiredMethod("jio_post", "jio_post")
.declareAcquiredMethod("jio_getAttachment", "jio_getAttachment")
.declareAcquiredMethod("notifySubmitting", "notifySubmitting")
.declareAcquiredMethod("notifySubmitted", 'notifySubmitted')
......@@ -52,7 +52,12 @@
.push(function () {
// Workaround, find a way to open document without break gadget.
result.jio_key = doc.relative_url;
return gadget.render(result);
return gadget.changeState({
jio_key: doc.relative_url,
certificate: result.certificate,
key: result.key,
title: doc.title
});
});
});
});
......@@ -63,6 +68,24 @@
})
.declareMethod("render", function (options) {
var gadget = this,
jio_key;
return new RSVP.Queue()
.push(function () {
jio_key = options.jio_key;
return gadget.jio_get(jio_key);
})
.push(function (doc) {
return gadget.changeState({
jio_key: jio_key,
doc: doc,
editable: 1
});
});
})
.onStateChange(function () {
var gadget = this,
page_title_translation,
translation_list = [
......@@ -71,7 +94,8 @@
"Parent Relative Url",
"Your Certificate",
"Your Key",
"Request New Certificate"
"Request New Certificate",
"Title"
];
return new RSVP.Queue()
.push(function () {
......@@ -84,13 +108,16 @@
gadget.msg1_translation = result[1][0];
gadget.msg2_translation = result[1][1];
page_title_translation = result[1][5];
if (gadget.state.title === undefined) {
gadget.state.title = gadget.state.doc.first_name + " " + gadget.state.doc.last_name;
}
return result[0].render({
erp5_document: {
"_embedded": {"_view": {
"my_relative_url": {
"description": "",
"title": result[1][2],
"default": options.jio_key,
"default": gadget.state.jio_key,
"css_class": "",
"required": 1,
"editable": 1,
......@@ -98,26 +125,37 @@
"hidden": 1,
"type": "StringField"
},
"my_title": {
"description": "",
"title": result[1][6],
"default": gadget.state.title,
"css_class": "",
"required": 0,
"editable": 0,
"key": "title",
"hidden": 0,
"type": "StringField"
},
"my_certificate": {
"description": "",
"title": result[1][3],
"default": options.certificate,
"default": gadget.state.certificate,
"css_class": "",
"required": 1,
"editable": 1,
"key": "certificate",
"hidden": (options.certificate === undefined) ? 1 : 0,
"hidden": (gadget.state.certificate === undefined) ? 1 : 0,
"type": "TextAreaField"
},
"my_key": {
"description": "",
"title": result[1][4],
"default": options.key,
"default": gadget.state.key,
"css_class": "",
"required": 1,
"editable": 1,
"key": "key",
"hidden": (options.key === undefined) ? 1 : 0,
"hidden": (gadget.state.key === undefined) ? 1 : 0,
"type": "TextAreaField"
}
}},
......@@ -130,9 +168,13 @@
},
form_definition: {
group_list: [[
"center",
[["my_key"], ["my_certificate"], ["my_relative_url"]]
]]
"left",
[["my_title"]]
],
[
"center",
[["my_key"], ["my_certificate"], ["my_relative_url"]]
]]
}
});
})
......@@ -149,9 +191,12 @@
.push(function (url_list) {
var header_dict = {
page_title: page_title_translation,
submit_action: true,
selection_url: url_list[0]
};
if (gadget.state.key === undefined) {
header_dict.submit_action = true;
}
return gadget.updateHeader(header_dict);
});
});
......
......@@ -283,7 +283,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>986.45437.22132.61764</string> </value>
<value> <string>1010.21512.39856.6519</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -303,7 +303,7 @@
</tuple>
<state>
<tuple>
<float>1602259006.04</float>
<float>1691553296.49</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -197,11 +197,11 @@
"key": "slap_person_login_listbox",
"lines": 20,
"list_method": "portal_catalog",
"query": "urn:jio:allDocs?query=%28portal_type%3A%28%22" +
"ERP5 Login" + "%22%20OR%20%22" +
"Google Login" + "%22%20OR%20%22" +
"Facebook Login" + "%22%29%20AND%20" +
"validation_state%3Avalidated%29",
"query": "urn:jio:allDocs?query=portal_type%3A%28%22ERP5 Login%22%20" +
"OR%20%22Certificate Login%22%20" +
"OR%20%22Google Login%22%20" +
"OR%20%22Facebook Login%22%29%20" +
"AND%20validation_state%3Avalidated",
"portal_type": [],
"search_column_list": column_list,
"sort_column_list": column_list,
......@@ -314,8 +314,6 @@
})
.push(function (setting_list) {
return RSVP.all([
gadget.getUrlFor({command: "change", options: {editable: true}}),
gadget.getUrlFor({command: "change", options: {jio_key: setting_list[0], page: "slap_person_revoke_certificate"}}),
gadget.getUrlFor({command: "change", options: {jio_key: setting_list[0], page: "slap_person_request_certificate"}}),
gadget.getUrlFor({command: "change", options: {jio_key: setting_list[0], page: "slap_person_get_token"}}),
gadget.getUrlFor({command: "change", options: {jio_key: setting_list[0], page: "slap_person_add_erp5_login"}}),
......@@ -329,18 +327,14 @@
var header_dict = {
page_title: gadget.account_translation + " : " + gadget.state.doc.first_name + " " + gadget.state.doc.last_name,
save_action: true,
request_certificate_url: result[2],
revoke_certificate_url: result[1],
token_url: result[3],
add_login_url: result[4],
add_organisation_url: result[5],
selection_url: result[6]
request_certificate_url: result[0],
token_url: result[1],
add_login_url: result[2],
add_organisation_url: result[3],
selection_url: result[4]
};
if (gadget.state.doc.contract_relative_url) {
header_dict.contract_url = result[7];
}
if (!gadget.state.editable) {
header_dict.edit_content = result[0];
header_dict.contract_url = result[6];
}
return gadget.updateHeader(header_dict);
});
......
......@@ -247,7 +247,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>1001.59425.29682.52855</string> </value>
<value> <string>1010.19458.9837.34030</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -267,7 +267,7 @@
</tuple>
<state>
<tuple>
<float>1659068534.69</float>
<float>1691430088.29</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -3,12 +3,6 @@ import json
portal = context.getPortalObject()
person = portal.portal_membership.getAuthenticatedMember().getUserValue()
# Revoke user certificate
try:
person.revokeCertificate()
except ValueError:
pass
web_site = context.getWebSiteValue()
request_url = "%s/%s" % (
web_site.getLayoutProperty(
......
......@@ -11,7 +11,7 @@ if person is None:
return {}
try:
return json.dumps(person.getCertificate())
return json.dumps(person.generateCertificate())
# Certificate is Created
except ValueError:
# Certificate was already requested, please revoke existing one.
......
""" This script is required due the ValueError, should be more HTTP friendly.
"""
portal = context.getPortalObject()
person = portal.portal_membership.getAuthenticatedMember().getUserValue()
request = context.REQUEST
response = request.RESPONSE
import json
if person is None:
response.setStatus(403)
else:
try:
person.revokeCertificate()
return json.dumps(True)
except ValueError:
return json.dumps(False)
......@@ -727,7 +727,7 @@ class TestPerson_newLogin(TestSlapOSHalJsonStyleMixin):
self.assertEqual(self.portal.REQUEST.RESPONSE.getStatus(), 200)
self.assertIn(person.getRelativeUrl(), result)
class TestPerson_get_revoke_Certificate(TestSlapOSHalJsonStyleMixin):
class TestPerson_get_Certificate(TestSlapOSHalJsonStyleMixin):
def test_Person_getCertificate_unauthorized(self):
person = self._makePerson(user=1)
self.assertEqual(1 , len(person.objectValues( portal_type="ERP5 Login")))
......@@ -735,38 +735,43 @@ class TestPerson_get_revoke_Certificate(TestSlapOSHalJsonStyleMixin):
self.assertEqual(person.Person_getCertificate(), {})
self.assertEqual(self.portal.REQUEST.RESPONSE.getStatus(), 403)
def test_Person_revokeCertificate_unauthorized(self):
def test_Person_get_Certificate(self):
person = self._makePerson(user=1)
self.assertEqual(1 , len(person.objectValues( portal_type="ERP5 Login")))
self.assertEqual(person.Person_revokeCertificate(), None)
self.assertEqual(self.portal.REQUEST.RESPONSE.getStatus(), 403)
def test_Person_get_revoke_Certificate(self):
person = self._makePerson(user=1)
self.assertEqual(1 , len(person.objectValues( portal_type="ERP5 Login")))
self.assertEqual(1 , len(person.objectValues(portal_type="ERP5 Login")))
self.login(person.getUserId())
response_dict = json.loads(person.Person_getCertificate())
self.assertSameSet(response_dict.keys(), ["common_name", "certificate", "id", "key"])
self.assertEqual(response_dict["common_name"], person.getUserId())
self.assertEqual(self.portal.REQUEST.RESPONSE.getStatus(), 200)
self.assertEqual(1 , len(person.objectValues(portal_type="Certificate Login")))
login = person.objectValues(portal_type="Certificate Login")[0]
self.assertEqual("validated" , login.getValidationState())
response_false = json.loads(person.Person_getCertificate())
self.assertFalse(response_false)
self.assertSameSet(response_dict.keys(), ["common_name", "certificate", "id", "key"])
response_true = json.loads(person.Person_revokeCertificate())
self.assertTrue(response_true)
self.assertEqual(response_dict["id"], login.getDestinationReference())
self.assertEqual(response_dict["common_name"], login.getReference())
self.assertEqual(self.portal.REQUEST.RESPONSE.getStatus(), 200)
response_false = json.loads(person.Person_revokeCertificate())
self.assertFalse(response_false)
new_response_dict = json.loads(person.Person_getCertificate())
self.assertTrue(new_response_dict)
response_dict = json.loads(person.Person_getCertificate())
self.assertEqual(2 , len(person.objectValues(portal_type="Certificate Login")))
new_login = [i for i in person.objectValues(portal_type="Certificate Login")
if i.getUid() != login.getUid()][0]
self.assertEqual("validated" , login.getValidationState())
self.assertEqual("validated" , new_login.getValidationState())
self.assertNotEqual(login.getReference(), new_login.getReference())
self.assertNotEqual(login.getDestinationReference(), new_login.getDestinationReference())
self.assertSameSet(new_response_dict.keys(), ["common_name", "certificate", "id", "key"])
self.assertEqual(new_response_dict["common_name"], new_login.getReference())
self.assertEqual(new_response_dict["id"], new_login.getDestinationReference())
self.assertNotEqual(new_response_dict["common_name"], response_dict["common_name"])
self.assertNotEqual(new_response_dict["id"], response_dict["id"])
self.assertNotEqual(new_response_dict["key"], response_dict["key"])
self.assertNotEqual(new_response_dict["certificate"], response_dict["certificate"])
self.assertSameSet(response_dict.keys(), ["common_name", "certificate", "id", "key"])
self.assertEqual(response_dict["common_name"], person.getUserId())
self.assertEqual(self.portal.REQUEST.RESPONSE.getStatus(), 200)
class TestPerson_testLoginExistence(TestSlapOSHalJsonStyleMixin):
......
Accounting Transaction Module | slaposjs_view
Category | slaposjs_view
Certificate Login | slaposjs_view
Cloud Contract | slaposjs_view
Compute Node Module | slaposjs_view
Compute Node | slaposjs_view
......
......@@ -38,6 +38,8 @@ web_page_module/rjs_gadget_erp5_page_slap_all_invoice_list_html
web_page_module/rjs_gadget_erp5_page_slap_all_invoice_list_js
web_page_module/rjs_gadget_erp5_page_slap_all_ticket_list_html
web_page_module/rjs_gadget_erp5_page_slap_all_ticket_list_js
web_page_module/rjs_gadget_erp5_page_slap_certificate_login_view_html
web_page_module/rjs_gadget_erp5_page_slap_certificate_login_view_js
web_page_module/rjs_gadget_erp5_page_slap_close_ticket_html
web_page_module/rjs_gadget_erp5_page_slap_close_ticket_js
web_page_module/rjs_gadget_erp5_page_slap_compute_node_get_token_html
......
......@@ -38,6 +38,8 @@ web_page_module/rjs_gadget_erp5_page_slap_all_invoice_list_html
web_page_module/rjs_gadget_erp5_page_slap_all_invoice_list_js
web_page_module/rjs_gadget_erp5_page_slap_all_ticket_list_html
web_page_module/rjs_gadget_erp5_page_slap_all_ticket_list_js
web_page_module/rjs_gadget_erp5_page_slap_certificate_login_view_html
web_page_module/rjs_gadget_erp5_page_slap_certificate_login_view_js
web_page_module/rjs_gadget_erp5_page_slap_close_ticket_html
web_page_module/rjs_gadget_erp5_page_slap_close_ticket_js
web_page_module/rjs_gadget_erp5_page_slap_compute_node_get_token_html
......@@ -98,8 +100,6 @@ web_page_module/rjs_gadget_erp5_page_slap_person_get_token_html
web_page_module/rjs_gadget_erp5_page_slap_person_get_token_js
web_page_module/rjs_gadget_erp5_page_slap_person_request_certificate_html
web_page_module/rjs_gadget_erp5_page_slap_person_request_certificate_js
web_page_module/rjs_gadget_erp5_page_slap_person_revoke_certificate_html
web_page_module/rjs_gadget_erp5_page_slap_person_revoke_certificate_js
web_page_module/rjs_gadget_erp5_page_slap_person_view_html
web_page_module/rjs_gadget_erp5_page_slap_person_view_js
web_page_module/rjs_gadget_erp5_page_slap_project_get_invitation_link_html
......
......@@ -28,7 +28,6 @@
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_listbox_pagination_text" />
</tal:block>
<tr>
<td colspan="3"><b> Request User Certificate</b> </td>
</tr>
......@@ -75,34 +74,11 @@
</tal:block>
<tr>
<td colspan="3"><b> Request User Certificate</b> </td>
<td colspan="3"><b> Request User Certificate (Again)</b> </td>
</tr>
<tal:block define="menu_action python: 'Request Certificate'">
<tr>
<td colspan="3"><b tal:content="python: 'Click on %s' % menu_action"> Menu Item </b></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td
tal:content="python: '//div[contains(@data-gadget-url, \'gadget_slapos_header.html\')]//a[@data-i18n=\'%s\']' % menu_action">
</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td
tal:content="python: '//div[contains(@data-gadget-url, \'gadget_slapos_header.html\')]//a[@data-i18n=\'%s\']' % menu_action">
</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td
tal:content="python: '//div[contains(@data-gadget-url, \'gadget_slapos_header.html\')]//a[@data-i18n=\'%s\']' % menu_action">
</td>
<td></td>
</tr>
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/click_submenu_action" />
</tal:block>
<tal:block define="header python: 'Request New Certificate'; ">
......@@ -111,34 +87,94 @@
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/click_proceed" />
<tal:block
tal:define="notification_configuration python: {'class': 'success',
'text': 'This person already has one certificate, please revoke it before request a new one..'}">
<tal:block tal:define="notification_configuration python: {'class': 'success',
'text': 'Certificate is Requested.'}">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/wait_for_notification" />
</tal:block>
<tr>
<td>waitForElementPresent</td>
<td>//textarea[@name="certificate"]</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//textarea[@name="certificate"]</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//textarea[@name="key"]</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//textarea[@name="key"]</td>
<td></td>
</tr>
<tal:block define="header python: 'Request New Certificate'; ">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/assert_page_header" />
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/click_page_header" />
</tal:block>
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_wait_for_activities_and_front_page" />
<tal:block define="person_name python: 'Demo User Functional'">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/access_menu_item_account" />
</tal:block>
<tal:block tal:define="pagination_configuration python: {'header': '(3)', 'footer': '${count} Records'};
dummy python: context.REQUEST.set('mapping', {'count': '3'})">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_listbox_pagination_text" />
</tal:block>
<!-- We cannot assert title since we UI is generated automatically -->
<tr>
<td>verifyTextPresent</td>
<td>Certificate Login</td>
<td></td>
</tr>
<tr>
<td colspan="3"><b> Revoke Certificate</b></td>
<td>verifyTextPresent</td>
<td>Certificate Login</td>
<td></td>
</tr>
<tr>
<td>verifyTextPresent</td>
<td>CERTLOGIN-</td>
<td></td>
</tr>
<tal:block define="menu_action python: 'Revoke Certificate'">
<tr>
<td>verifyTextPresent</td>
<td>CERTLOGIN-</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//a[text()="Certificate Login"]</td>
<td></td>
</tr>
<tal:block define="header python: 'Certificate Login: ${title}';
dummy python: context.REQUEST.set('mapping', {'title' : ''})">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/assert_page_header_contains" />
</tal:block>
<tal:block define="menu_action python: 'Delete'">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/click_submenu_action" />
</tal:block>
<tal:block define="header python: 'Revoke Person Certificate'; ">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/assert_page_header" />
<tal:block define="header python: 'Disable Login: ${title}';
dummy python: context.REQUEST.set('mapping', {'title' : ''})">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/assert_page_header_contains" />
</tal:block>
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/click_proceed" />
<tal:block tal:define="notification_configuration python: {'class': 'success',
'text': 'Certificate is Revoked.'}">
'text': 'Login is Disabled.'}">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/wait_for_notification" />
</tal:block>
......@@ -147,74 +183,106 @@
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/assert_page_header" />
</tal:block>
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_wait_for_activities_and_front_page" />
<tal:block define="person_name python: 'Demo User Functional'">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/access_menu_item_account" />
</tal:block>
<tal:block tal:define="pagination_configuration python: {'header': '(2)', 'footer': '${count} Records'};
dummy python: context.REQUEST.set('mapping', {'count': '2'})">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_listbox_pagination_text" />
</tal:block>
<!-- We cannot assert title since we UI is generated automatically -->
<tr>
<td>verifyTextPresent</td>
<td>Certificate Login</td>
<td></td>
</tr>
<tr>
<td>verifyTextPresent</td>
<td>Certificate Login</td>
<td></td>
</tr>
<tr>
<td colspan="3"><b> Request User Certificate again</b> </td>
<td>verifyTextPresent</td>
<td>CERTLOGIN-</td>
<td></td>
</tr>
<tal:block define="menu_action python: 'Request Certificate'">
<tr>
<td colspan="3"><b tal:content="python: 'Click on %s' % menu_action"> Menu Item </b></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td
tal:content="python: '//div[contains(@data-gadget-url, \'gadget_slapos_header.html\')]//a[@data-i18n=\'%s\']' % menu_action">
</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td
tal:content="python: '//div[contains(@data-gadget-url, \'gadget_slapos_header.html\')]//a[@data-i18n=\'%s\']' % menu_action">
</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td
tal:content="python: '//div[contains(@data-gadget-url, \'gadget_slapos_header.html\')]//a[@data-i18n=\'%s\']' % menu_action">
</td>
<td></td>
</tr>
<tr>
<td>verifyTextPresent</td>
<td>CERTLOGIN-</td>
<td></td>
</tr>
<tr>
<td>click</td>
<td>//a[text()="Certificate Login"]</td>
<td></td>
</tr>
<tal:block define="header python: 'Certificate Login: ${title}';
dummy python: context.REQUEST.set('mapping', {'title' : ''}) ">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/assert_page_header_contains" />
</tal:block>
<tal:block define="header python: 'Request New Certificate'; ">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/assert_page_header" />
<tal:block define="menu_action python: 'Delete'">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/click_submenu_action" />
</tal:block>
<tal:block define="header python: 'Disable Login: ${title}';
dummy python: context.REQUEST.set('mapping', {'title' : ''}) ">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/assert_page_header_contains" />
</tal:block>
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/click_proceed" />
<tal:block tal:define="notification_configuration python: {'class': 'success',
'text': 'Certificate is Requested.'}">
'text': 'Login is Disabled.'}">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/wait_for_notification" />
</tal:block>
<tal:block tal:define="header python: 'Your Account : ${title}';
dummy python: context.REQUEST.set('mapping', {'title': 'Demo User Functional'}) ">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/assert_page_header" />
</tal:block>
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_wait_for_activities_and_front_page" />
<tal:block define="person_name python: 'Demo User Functional'">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/access_menu_item_account" />
</tal:block>
<tal:block tal:define="pagination_configuration python: {'header': '(1)', 'footer': '${count} Records'};
dummy python: context.REQUEST.set('mapping', {'count': '1'})">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/check_listbox_pagination_text" />
</tal:block>
<!-- We cannot assert title since we UI is generated automatically -->
<tr>
<td>waitForElementPresent</td>
<td>//textarea[@name="certificate"]</td>
<td>verifyTextNotPresent</td>
<td>Certificate Login</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//textarea[@name="certificate"]</td>
<td>verifyTextNotPresent</td>
<td>Certificate Login</td>
<td></td>
</tr>
<tr>
<td>waitForElementPresent</td>
<td>//textarea[@name="key"]</td>
<td>verifyTextNotPresent</td>
<td>CERTLOGIN-</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//textarea[@name="key"]</td>
<td>verifyTextNotPresent</td>
<td>CERTLOGIN-</td>
<td></td>
</tr>
<tal:block define="header python: 'Request New Certificate'; ">
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/assert_page_header" />
</tal:block>
<tal:block metal:use-macro="here/Zuite_SlapOSCommonTemplate/macros/slapos_logout" />
</tbody>
......
......@@ -147,11 +147,6 @@ function redirect us to the login page -->
<td>//a[@data-i18n="Request Certificate"]</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td>//a[@data-i18n="Revoke Certificate"]</td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td tal:content="python: '//label[contains(text(), \'%s\')]' % (here.Base_translateString('First Name', lang=lang))"></td>
......
......@@ -462,6 +462,22 @@
</tal:block>
</tal:block>
<tal:block metal:define-macro="assert_page_header_contains">
<tal:block tal:define="header_translation python: here.Base_translateString(header, mapping=context.REQUEST.get('mapping', {}), lang=lang);
dummy python:context.REQUEST.set('mapping', {})">
<tr>
<td>waitForElementPresent</td>
<td tal:content="python: '//div[contains(@data-gadget-url, \'gadget_slapos_header.html\')]//a[contains(@data-i18n, \'%s\')]' % header_translation"></td>
<td></td>
</tr>
<tr>
<td>assertElementPresent</td>
<td tal:content="python: '//div[contains(@data-gadget-url, \'gadget_slapos_header.html\')]//a[contains(@data-i18n, \'%s\')]' % header_translation"></td>
<td></td>
</tr>
</tal:block>
</tal:block>
<tal:block metal:define-macro="click_page_header">
<tal:block tal:define="header_translation python: here.Base_translateString(header, mapping=context.REQUEST.get('mapping', {}), lang=lang);
dummy python:context.REQUEST.set('mapping', {})">
......
......@@ -57,8 +57,7 @@ class TestSlapOSSlapToolMixin(SlapOSTestCaseMixin):
source_administration_value=getattr(self, "person", None),
)
self.compute_node.validate()
self._addERP5Login(self.compute_node)
self._addCertificateLogin(self.compute_node)
self.tic()
......
......@@ -173,9 +173,9 @@ class SlapTool(BaseTool):
Reuses slap library for easy marshalling.
"""
portal = self.getPortalObject()
user = portal.portal_membership.getAuthenticatedMember().getUserName()
if str(user) == computer_id:
compute_node = portal.portal_membership.getAuthenticatedMember().getUserValue()
user_value = portal.portal_membership.getAuthenticatedMember().getUserValue()
if user_value is not None and user_value.getReference() == computer_id:
compute_node = user_value
compute_node.setAccessStatus(computer_id)
else:
# Don't use getDocument because we don't want use _assertACI here, but
......@@ -186,11 +186,18 @@ class SlapTool(BaseTool):
refresh_etag = compute_node._calculateRefreshEtag()
user = portal.portal_membership.getAuthenticatedMember().getUserName()
# Keep compatibility with older clients that relies on marshalling.
# This code is an adaptation of SlapOSComputeNodeMixin._getComputeNodeInformation
# To comply with cache capability.
user_document = _assertACI(portal.portal_catalog.unrestrictedGetResultValue(
reference=user, portal_type=['Person', 'Compute Node', 'Software Instance']))
login = portal.portal_catalog.unrestrictedGetResultValue(
reference=user, portal_type="Certificate Login",
parent_portal_type=['Person', 'Compute Node', 'Software Instance'])
if not login:
raise Unauthorized('User %s not found!' % user)
user_document = _assertACI(login.getParentValue())
user_type = user_document.getPortalType()
if user_type in ('Compute Node', 'Person'):
if not compute_node._isTestRun():
......
......@@ -1186,6 +1186,9 @@ return dict(vads_url_already_registered="%s/already_registered" % (payment_trans
# format the compute_nodes
self.formatComputeNode(subscription_server)
# Without certificate computer isnt a user yet.
subscription_server.generateCertificate()
self.tic()
self.logout()
return subscription_server
......
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