Commit 1ad0bc4a authored by Carlos Ramos Carreño's avatar Carlos Ramos Carreño

software/cloudooo: Add `enable-scripting` param.

The `enable-scripting` parameter allows to specify a LibreOffice script
to be applied before saving the document, as per
nexedi/cloudooo@a09d87af
If false (the default), an exception will be raised instead.

This commit also adds two SlapOS integration tests classes to test the
functionality:
- TestScripting requests an instance with scripting enabled, and tests
the scripting functionality.
- TestScriptingDisabled tests that scripting fails if it is not enabled
explicitly.

See merge request nexedi/slapos!1628
parent 7a31af8e
...@@ -18,7 +18,7 @@ md5sum = d1e4d7306c39f2ebc64d0407860d4301 ...@@ -18,7 +18,7 @@ md5sum = d1e4d7306c39f2ebc64d0407860d4301
[template-cloudooo-instance] [template-cloudooo-instance]
filename = instance-cloudooo.cfg.in filename = instance-cloudooo.cfg.in
md5sum = 06dc19acd28ab412beffa61890be2095 md5sum = 1bc5c724d29337e1f35cfa60270fb08c
[template-haproxy-cfg] [template-haproxy-cfg]
filename = haproxy.cfg.in filename = haproxy.cfg.in
......
...@@ -20,6 +20,11 @@ ...@@ -20,6 +20,11 @@
"description": "The list of entry to add to the cloudooo mimetype registry. Each entry should on one line which format is: \"<source_mimetype> <destination_mimetype> <handler>\"", "description": "The list of entry to add to the cloudooo mimetype registry. Each entry should on one line which format is: \"<source_mimetype> <destination_mimetype> <handler>\"",
"textarea": true, "textarea": true,
"type": "string" "type": "string"
},
"enable-scripting": {
"description": "Enable the execution of scripts before saving a converted document. WARNING: Setting this parameter to true is unsafe, unless the CloudOoo server is private and not exposed to potential attackers",
"default": false,
"type": "boolean"
} }
} }
} }
...@@ -39,6 +39,11 @@ ...@@ -39,6 +39,11 @@
{% set apache_dict = {} -%} {% set apache_dict = {} -%}
{% do apache_dict.__setitem__(publish_url_name, (apache_port, "https", 'http://' ~ ipv4 ~ ':' ~ haproxy_port, False)) -%} {% do apache_dict.__setitem__(publish_url_name, (apache_port, "https", 'http://' ~ ipv4 ~ ':' ~ haproxy_port, False)) -%}
{% set ooo_enable_scripting = instance_parameter_dict['enable-scripting'] | string | lower -%}
{% if instance_parameter_dict.get('enable-scripting-parameter-name') -%}
{% set ooo_enable_scripting = slapparameter_dict.get(instance_parameter_dict['enable-scripting-parameter-name'], ooo_enable_scripting) | string | lower -%}
{% endif -%}
{% set bin_directory = parameter_dict['buildout-bin-directory'] -%} {% set bin_directory = parameter_dict['buildout-bin-directory'] -%}
{% set section_list = [] -%} {% set section_list = [] -%}
{% set cloudooo_section_list = [] -%} {% set cloudooo_section_list = [] -%}
...@@ -168,6 +173,7 @@ mimetype_entry_addition = ...@@ -168,6 +173,7 @@ mimetype_entry_addition =
ooo-binary-path = {{ parameter_dict['libreoffice-bin'] }}/program ooo-binary-path = {{ parameter_dict['libreoffice-bin'] }}/program
ooo-paster = {{ bin_directory }}/cloudooo_paster ooo-paster = {{ bin_directory }}/cloudooo_paster
ooo-uno-path = {{ parameter_dict['libreoffice-bin'] }}/basis-link/program ooo-uno-path = {{ parameter_dict['libreoffice-bin'] }}/basis-link/program
ooo_enable_scripting = {{ ooo_enable_scripting }}
{% for index in range(1, backend_count + 1) -%} {% for index in range(1, backend_count + 1) -%}
{% set name = 'cloudooo-' ~ index -%} {% set name = 'cloudooo-' ~ index -%}
......
...@@ -20,3 +20,5 @@ ssl-dict-parameter-name = ssl ...@@ -20,3 +20,5 @@ ssl-dict-parameter-name = ssl
mimetype-entry-addition-parameter-name = mimetype-entry-addition mimetype-entry-addition-parameter-name = mimetype-entry-addition
#mimetype-entry-addition = #mimetype-entry-addition =
# text/html application/pdf wkhtmltopdf # text/html application/pdf wkhtmltopdf
enable-scripting-parameter-name = enable-scripting
enable-scripting = false
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# #
############################################################################## ##############################################################################
from __future__ import annotations
import codecs import codecs
import csv import csv
...@@ -35,6 +36,8 @@ import urllib.parse as urllib_parse ...@@ -35,6 +36,8 @@ import urllib.parse as urllib_parse
import ssl import ssl
import base64 import base64
import io import io
import textwrap
from typing import Mapping
import requests import requests
import PIL.Image import PIL.Image
...@@ -68,6 +71,45 @@ class CloudOooTestCase(_CloudOooTestCase): ...@@ -68,6 +71,45 @@ class CloudOooTestCase(_CloudOooTestCase):
self.addCleanup(self.server('close')) self.addCleanup(self.server('close'))
def script_test_basic(server: xmlrpclib.ServerProxy) -> bytes:
"""
Tries to execute a hello world script.
Args:
server: The server used to send requests to Cloudooo.
Returns:
The file contents in base64. If the script is executed
properly, it should contain the string ``"Hello World"``,
preceded by the UTF-8 BOM and with a trailing newline.
"""
script = textwrap.dedent(
"""\
# Get the XText interface
text = Document.Text
# Create an XTextRange at the end of the document
tRange = text.End
# Set the string
tRange.String = "Hello World"
""",
)
file = server.convertFile(
base64.encodebytes(b"<html></html>").decode(),
"html",
"txt",
False, # zip
False, # refresh
{"script": script},
)
assert isinstance(file, str)
return file.encode()
def normalizeFontName(font_name): def normalizeFontName(font_name):
if '+' in font_name: if '+' in font_name:
return font_name.split('+')[1] return font_name.split('+')[1]
...@@ -345,3 +387,31 @@ class TestLibreOfficeCluster(CloudOooTestCase): ...@@ -345,3 +387,31 @@ class TestLibreOfficeCluster(CloudOooTestCase):
'cloudooo_4': 0, 'cloudooo_4': 0,
'BACKEND': 0, 'BACKEND': 0,
}) })
class TestLibreOfficeScripting(CloudOooTestCase):
"""Class with scripting enabled, to try that functionality."""
__partition_reference__ = "se"
@classmethod
def getInstanceParameterDict(cls) -> Mapping[str, object]:
"""Enable scripting for this instance."""
return {"enable-scripting": True}
def test_scripting_basic(self) -> None:
"""Test that the basic script works."""
file = script_test_basic(self.server)
self.assertEqual(
base64.decodebytes(file),
codecs.BOM_UTF8 + b"Hello World\n",
)
class TestScriptingDisabled(CloudOooTestCase):
"""Class with scripting disabled (the default), to test that."""
__partition_reference__ = "sd"
def test_scripting_disabled(self) -> None:
"""Test that the basic script raises when scripting is disabled."""
with self.assertRaisesRegex(Exception, "ooo: scripting is disabled"):
script_test_basic(self.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