Commit 34b7099c authored by Nicolas Wavrant's avatar Nicolas Wavrant

erp5_antivirus_clammit: support secure connection to clammit

The CA certificate can be stored on the connector (it is obtained from
the clammit instance).
parent c5225a6d
...@@ -31,6 +31,7 @@ from Products.ERP5Type import Permissions ...@@ -31,6 +31,7 @@ from Products.ERP5Type import Permissions
from Products.ERP5Type.XMLObject import XMLObject from Products.ERP5Type.XMLObject import XMLObject
import requests import requests
import tempfile
class ClammitConnector(XMLObject): class ClammitConnector(XMLObject):
# CMF Type Definition # CMF Type Definition
...@@ -45,12 +46,27 @@ class ClammitConnector(XMLObject): ...@@ -45,12 +46,27 @@ class ClammitConnector(XMLObject):
_INFECTED_HTTP_STATUS_CODE = 418 _INFECTED_HTTP_STATUS_CODE = 418
_DEFAULT_TIMEOUT = 30 # In seconds _DEFAULT_TIMEOUT = 30 # In seconds
def _query(self, *args, **kw):
def _request(*args, **kw):
return requests.request(*args, **kw)
kw.setdefault("timeout", self.getTimeout(self._DEFAULT_TIMEOUT))
ca_certificate = self.getCertificateAuthorityCertificate()
if ca_certificate:
with tempfile.NamedTemporaryFile() as certificate_authoritity_certificate:
certificate_authoritity_certificate.write(ca_certificate)
certificate_authoritity_certificate.seek(0)
kw["verify"] = certificate_authoritity_certificate.name
return _request(*args, **kw)
return _request(*args, **kw)
def isSafe(self, data): def isSafe(self, data):
response = requests.post( response = self._query(
self.getUrlString() + '/scan', "POST",
files={'file': data}, self.getUrlString() + "/scan",
timeout=self.getTimeout(self._DEFAULT_TIMEOUT), files={"file": data},
verify=False, # TODO: how to do self-certs correctly ?
) )
if response.status_code == self._SANE_HTTP_STATUS_CODE: if response.status_code == self._SANE_HTTP_STATUS_CODE:
return True return True
...@@ -60,10 +76,10 @@ class ClammitConnector(XMLObject): ...@@ -60,10 +76,10 @@ class ClammitConnector(XMLObject):
raise ValueError("Unknown status code") raise ValueError("Unknown status code")
def isReady(self): def isReady(self):
response = requests.get( response = self._query(
self.getUrlString() + '/readyz', "GET",
timeout=self.getTimeout(self._DEFAULT_TIMEOUT), self.getUrlString() + "/readyz",
verify=False, # TODO: how to do self-certs correctly ? timeout=3, # The timeout is much shorter as it is a light query
) )
if response.status_code == 200: if response.status_code == 200:
return True return True
......
...@@ -3,5 +3,6 @@ ...@@ -3,5 +3,6 @@
<item>Reference</item> <item>Reference</item>
<item>SocketClient</item> <item>SocketClient</item>
<item>Url</item> <item>Url</item>
<item>X509</item>
</portal_type> </portal_type>
</property_sheet_list> </property_sheet_list>
\ No newline at end of file
...@@ -90,6 +90,7 @@ ...@@ -90,6 +90,7 @@
<value> <value>
<list> <list>
<string>my_description</string> <string>my_description</string>
<string>my_ssl_certificate_authority_certificate</string>
</list> </list>
</value> </value>
</item> </item>
......
...@@ -9,9 +9,7 @@ ...@@ -9,9 +9,7 @@
<item> <item>
<key> <string>delegated_list</string> </key> <key> <string>delegated_list</string> </key>
<value> <value>
<list> <list/>
<string>title</string>
</list>
</value> </value>
</item> </item>
<item> <item>
...@@ -73,7 +71,7 @@ ...@@ -73,7 +71,7 @@
<dictionary> <dictionary>
<item> <item>
<key> <string>field_id</string> </key> <key> <string>field_id</string> </key>
<value> <string>my_text_area_field</string> </value> <value> <string>my_view_mode_description</string> </value>
</item> </item>
<item> <item>
<key> <string>form_id</string> </key> <key> <string>form_id</string> </key>
...@@ -83,10 +81,6 @@ ...@@ -83,10 +81,6 @@
<key> <string>target</string> </key> <key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value> <value> <string>Click to edit the target</string> </value>
</item> </item>
<item>
<key> <string>title</string> </key>
<value> <string>Private Key</string> </value>
</item>
</dictionary> </dictionary>
</value> </value>
</item> </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>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_ssl_certificate_authority_certificate</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>
</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>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_text_area_field</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>CA Certificate</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -61,7 +61,7 @@ class TestClammitAntivirus(ERP5TypeTestCase): ...@@ -61,7 +61,7 @@ class TestClammitAntivirus(ERP5TypeTestCase):
portal_type="Clammit Connector", portal_type="Clammit Connector",
reference="clammit_test_connector", reference="clammit_test_connector",
url_string="https://localhost:3000/clammit", url_string="https://localhost:3000/clammit",
timeout=30, timeout=5,
) )
@mock.patch("requests.request") @mock.patch("requests.request")
......
Clammit Connector | Reference Clammit Connector | Reference
Clammit Connector | SocketClient Clammit Connector | SocketClient
Clammit Connector | Url Clammit Connector | Url
\ No newline at end of file Clammit Connector | X509
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment