Commit dcb154ea authored by Rafael Monnerat's avatar Rafael Monnerat

slapos_cloud: Generate/Revoke only invalidate/create the Certificate Login

   This issues SSL Certificates and use Certificate Login, rather them require to revoke it.
parent 6dd413bf
...@@ -6,12 +6,6 @@ ...@@ -6,12 +6,6 @@
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
<item>
<key> <string>_recorded_property_dict</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item> <item>
<key> <string>default_reference</string> </key> <key> <string>default_reference</string> </key>
<value> <string>testSlapOSCloudComputeNodeSlapInterfaceWorkflow</string> </value> <value> <string>testSlapOSCloudComputeNodeSlapInterfaceWorkflow</string> </value>
...@@ -61,28 +55,13 @@ ...@@ -61,28 +55,13 @@
<item> <item>
<key> <string>workflow_history</string> </key> <key> <string>workflow_history</string> </key>
<value> <value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent> <persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
<record id="2" aka="AAAAAAAAAAI="> <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> <pickle>
<global name="PersistentMapping" module="Persistence.mapping"/> <global name="PersistentMapping" module="Persistence.mapping"/>
</pickle> </pickle>
...@@ -95,7 +74,7 @@ ...@@ -95,7 +74,7 @@
<item> <item>
<key> <string>component_validation_workflow</string> </key> <key> <string>component_validation_workflow</string> </key>
<value> <value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent> <persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value> </value>
</item> </item>
</dictionary> </dictionary>
...@@ -104,7 +83,7 @@ ...@@ -104,7 +83,7 @@
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
<record id="4" aka="AAAAAAAAAAQ="> <record id="3" aka="AAAAAAAAAAM=">
<pickle> <pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/> <global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle> </pickle>
......
...@@ -1140,68 +1140,88 @@ class TestSlapOSCoreInstanceSlapInterfaceWorkflowTransfer(SlapOSTestCaseMixin): ...@@ -1140,68 +1140,88 @@ class TestSlapOSCoreInstanceSlapInterfaceWorkflowTransfer(SlapOSTestCaseMixin):
def test_generateCertificate(self): def test_generateCertificate(self):
self.login() self.login()
self.software_instance.setSslKey(None)
self.software_instance.setSslCertificate(None)
self.software_instance.setDestinationReference(None) self.software_instance.setDestinationReference(None)
self.software_instance.getSslKey(None)
self.software_instance.getSslCertificate(None)
self.software_instance.generateCertificate() self.software_instance.generateCertificate()
self.assertNotEqual(self.software_instance.getDestinationReference(), None)
self.assertNotEqual(self.software_instance.getSslKey(), None) self.assertNotEqual(self.software_instance.getSslKey(), None)
self.assertNotEqual(self.software_instance.getSslCertificate(), 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) self.assertRaises(ValueError, self.software_instance.generateCertificate)
def test_revokeCertificate(self): def test_revokeCertificate(self):
self.login() 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) 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): def test_revokeAndGenerateCertificate(self):
self.login() self.login()
destination_reference = self.software_instance.getDestinationReference()
ssl_key = self.software_instance.getSslKey() ssl_key = self.software_instance.getSslKey()
ssl_certificate = self.software_instance.getSslCertificate() 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.getSslKey(), None)
self.assertNotEqual(self.software_instance.getSslCertificate(), None) self.assertNotEqual(self.software_instance.getSslCertificate(), None)
self.software_instance.revokeCertificate() self.assertRaises(ValueError, self.software_instance.revokeCertificate)
self.software_instance.generateCertificate() self.software_instance.generateCertificate()
self.assertNotEqual(self.software_instance.getDestinationReference(), None)
self.assertNotEqual(self.software_instance.getSslKey(), None) self.assertNotEqual(self.software_instance.getSslKey(), None)
self.assertNotEqual(self.software_instance.getSslCertificate(), None) self.assertNotEqual(self.software_instance.getSslCertificate(), None)
self.assertNotEqual(self.software_instance.getDestinationReference(), certificate_login_list = self.software_instance.objectValues(portal_type="Certificate Login")
destination_reference) 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(), self.assertNotEqual(self.software_instance.getSslKey(),
ssl_key) ssl_key)
self.assertNotEqual(self.software_instance.getSslCertificate(), self.assertNotEqual(self.software_instance.getSslCertificate(),
ssl_certificate) ssl_certificate)
destination_reference = self.software_instance.getDestinationReference()
ssl_key = self.software_instance.getSslKey() ssl_key = self.software_instance.getSslKey()
ssl_certificate = self.software_instance.getSslCertificate() ssl_certificate = self.software_instance.getSslCertificate()
self.software_instance.revokeCertificate() self.software_instance.revokeCertificate()
self.software_instance.generateCertificate() self.software_instance.generateCertificate()
self.assertNotEqual(self.software_instance.getDestinationReference(), None)
self.assertNotEqual(self.software_instance.getSslKey(), None) self.assertNotEqual(self.software_instance.getSslKey(), None)
self.assertNotEqual(self.software_instance.getSslCertificate(), None) self.assertNotEqual(self.software_instance.getSslCertificate(), None)
self.assertNotEqual(self.software_instance.getDestinationReference(),
destination_reference)
self.assertNotEqual(self.software_instance.getSslKey(), self.assertNotEqual(self.software_instance.getSslKey(),
ssl_key) ssl_key)
self.assertNotEqual(self.software_instance.getSslCertificate(), self.assertNotEqual(self.software_instance.getSslCertificate(),
ssl_certificate) 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 @@ ...@@ -6,12 +6,6 @@
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
<item>
<key> <string>_recorded_property_dict</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item> <item>
<key> <string>default_reference</string> </key> <key> <string>default_reference</string> </key>
<value> <string>testSlapOSCloudInstanceSlapInterfaceWorkflow</string> </value> <value> <string>testSlapOSCloudInstanceSlapInterfaceWorkflow</string> </value>
...@@ -61,28 +55,13 @@ ...@@ -61,28 +55,13 @@
<item> <item>
<key> <string>workflow_history</string> </key> <key> <string>workflow_history</string> </key>
<value> <value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent> <persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
<record id="2" aka="AAAAAAAAAAI="> <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> <pickle>
<global name="PersistentMapping" module="Persistence.mapping"/> <global name="PersistentMapping" module="Persistence.mapping"/>
</pickle> </pickle>
...@@ -95,7 +74,7 @@ ...@@ -95,7 +74,7 @@
<item> <item>
<key> <string>component_validation_workflow</string> </key> <key> <string>component_validation_workflow</string> </key>
<value> <value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent> <persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value> </value>
</item> </item>
</dictionary> </dictionary>
...@@ -104,7 +83,7 @@ ...@@ -104,7 +83,7 @@
</dictionary> </dictionary>
</pickle> </pickle>
</record> </record>
<record id="4" aka="AAAAAAAAAAQ="> <record id="3" aka="AAAAAAAAAAM=">
<pickle> <pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/> <global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle> </pickle>
......
...@@ -8,10 +8,4 @@ compute_node.edit( ...@@ -8,10 +8,4 @@ compute_node.edit(
capacity_scope='open' 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') portal.portal_workflow.doActionFor(compute_node, 'validate_action')
compute_node = state_change['object'] compute_node = state_change['object']
if compute_node.getDestinationReference() is not None: 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_certificate", None)
context.REQUEST.set("compute_node_key", None) context.REQUEST.set("compute_node_key", None)
raise ValueError('Certificate still active.') raise ValueError('Certificate still active.')
ca = context.getPortalObject().portal_certificate_authority certificate_login = compute_node.newContent(
certificate_dict = ca.getNewCertificate(compute_node.getReference()) portal_type="Certificate Login")
certificate_dict = certificate_login.getCertificate()
compute_node.setDestinationReference(certificate_dict["id"]) certificate_login.validate()
context.REQUEST.set("compute_node_certificate", certificate_dict["certificate"]) context.REQUEST.set("compute_node_certificate", certificate_dict["certificate"])
context.REQUEST.set("compute_node_key", certificate_dict["key"]) context.REQUEST.set("compute_node_key", certificate_dict["key"])
...@@ -52,6 +52,12 @@ ...@@ -52,6 +52,12 @@
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string>state_change</string> </value> <value> <string>state_change</string> </value>
</item> </item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>script_ComputeNode_generateCertificate</string> </value> <value> <string>script_ComputeNode_generateCertificate</string> </value>
......
compute_node = state_change['object'] compute_node = state_change['object']
context.REQUEST.set('compute_node_certificate', None) context.REQUEST.set('compute_node_certificate', None)
context.REQUEST.set('compute_node_key', 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') raise ValueError('No certificate')
context.getPortalObject().portal_certificate_authority.revokeCertificate(destination_reference)
compute_node.setDestinationReference(None)
...@@ -52,6 +52,12 @@ ...@@ -52,6 +52,12 @@
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string>state_change</string> </value> <value> <string>state_change</string> </value>
</item> </item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>script_ComputeNode_revokeCertificate</string> </value> <value> <string>script_ComputeNode_revokeCertificate</string> </value>
......
instance = state_change['object'] instance = state_change['object']
if instance.getDestinationReference() is not None:
raise ValueError("Certificate still active.")
if instance.getPortalType() != "Software Instance": if instance.getPortalType() != "Software Instance":
# Skip if the instance isn't a Software Instance, # Skip if the instance isn't a Software Instance,
# since Shared Instances cannot find the object. # since Shared Instances cannot find the object.
return return
ca = context.getPortalObject().portal_certificate_authority for certificate_login in instance.objectValues(
certificate_dict = ca.getNewCertificate(instance.getReference()) portal_type=["Certificate Login"]):
if certificate_login.getValidationState() == "validated":
raise ValueError('Certificate still active.')
edit_kw = {'destination_reference' : certificate_dict['id'], # Include Certificate Login so Instance become a User
'ssl_key' : certificate_dict['key'], certificate_login = instance.newContent(
'ssl_certificate': certificate_dict['certificate'] 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.edit(**edit_kw)
instance = state_change['object'] instance = state_change['object']
portal = instance.getPortalObject()
if instance.getSslKey() is not None or instance.getSslCertificate() is not None: if instance.getSslKey() is not None or instance.getSslCertificate() is not None:
instance.edit(ssl_key=None, ssl_certificate=None) instance.edit(ssl_key=None, ssl_certificate=None)
destination_reference = instance.getDestinationReference() no_certificate = True
if destination_reference is None: for certificate_login in instance.objectValues(
raise ValueError('No certificate') portal_type=["Certificate Login"]):
if certificate_login.getValidationState() == "validated":
certificate_login.invalidate()
no_certificate = False
try: if no_certificate:
portal.portal_certificate_authority\ raise ValueError('No certificate')
.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)
...@@ -68,9 +68,7 @@ ...@@ -68,9 +68,7 @@
</item> </item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
<value> <value> <string>None</string> </value>
<none/>
</value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
...@@ -93,14 +93,9 @@ if (request_software_instance is None): ...@@ -93,14 +93,9 @@ if (request_software_instance is None):
reference=reference, reference=reference,
activate_kw={'tag': tag} activate_kw={'tag': tag}
) )
if software_instance_portal_type == "Software Instance":
request_software_instance.generateCertificate() request_software_instance.generateCertificate()
request_software_instance.validate() 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()
graph[request_software_instance.getUid()] = [] graph[request_software_instance.getUid()] = []
......
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