mirror of
https://github.com/lucaspalomodevelop/core.git
synced 2026-03-18 10:35:27 +00:00
(captiveportal, new) add cleansing of input templates to remove all non-changed data from the user provided template.
Next stepts to implement, make fetch_template aware of the user templates, so the frontend fetch will return the right content. deploy user provided template on service reload
This commit is contained in:
parent
08b49c052e
commit
e978c50198
@ -138,19 +138,22 @@ class ServiceController extends ApiControllerBase
|
||||
$template = $mdlCP->getTemplateByName($templateName);
|
||||
}
|
||||
|
||||
// needs optimization, we don't want to store data in our config that's already in our standard system
|
||||
// (like bootstrap code)
|
||||
// cleanse input content, we only want to save changed files into our config
|
||||
if (strlen($this->request->getPost("content", "striptags", "")) > 20
|
||||
|| strlen((string)$template->content) == 0
|
||||
) {
|
||||
$temp_filename = 'cp_' . (string)$mdlCP->uuid . '.tmp';
|
||||
$temp_filename = 'cp_' . (string)$template->getAttributes()['uuid'] . '.tmp';
|
||||
file_put_contents('/tmp/'.$temp_filename, $this->request->getPost("content", "striptags", ""));
|
||||
// strip defaults from template (standard js libs, etc)
|
||||
// strip defaults and unchanged files from template (standard js libs, etc)
|
||||
$backend = new Backend();
|
||||
$response = $backend->configdpRun("captiveportal strip_template", array($temp_filename));
|
||||
// todo, handle response
|
||||
// only set data if new content is provided
|
||||
$template->content = $this->request->getPost("content", "striptags", "");
|
||||
unlink($temp_filename);
|
||||
$result = json_decode($response, true);
|
||||
if ($result != null && !array_key_exists('error', $result)) {
|
||||
$template->content = $result['payload'];
|
||||
} else {
|
||||
return array("name" => $templateName, "error" => $result['error']);
|
||||
}
|
||||
}
|
||||
|
||||
$template->name = $templateName;
|
||||
|
||||
@ -0,0 +1,10 @@
|
||||
# This list contains the filenames that may not be overwritten by the user when creating custom templates.
|
||||
# All items in this list won't be stored in the config.xml by our framework
|
||||
css/bootstrap.css.map
|
||||
css/bootstrap.min.css
|
||||
fonts/glyphicons-halflings-regular.eot
|
||||
fonts/glyphicons-halflings-regular.svg
|
||||
fonts/glyphicons-halflings-regular.ttf
|
||||
fonts/glyphicons-halflings-regular.woff
|
||||
fonts/glyphicons-halflings-regular.woff2
|
||||
#js/bootstrap.min.js
|
||||
105
src/opnsense/scripts/OPNsense/CaptivePortal/strip_template.py
Executable file
105
src/opnsense/scripts/OPNsense/CaptivePortal/strip_template.py
Executable file
@ -0,0 +1,105 @@
|
||||
#!/usr/local/bin/python2.7
|
||||
|
||||
"""
|
||||
Copyright (c) 2015 Deciso B.V. - Ad Schellevis
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
--------------------------------------------------------------------------------------
|
||||
read a user provided base64 encoded zip file and generate a new one without standard
|
||||
files. (strips javascript etc)
|
||||
Filename should be provided by user parameter and must be available in /tmp/
|
||||
"""
|
||||
import sys
|
||||
import os.path
|
||||
import binascii
|
||||
import StringIO
|
||||
import zipfile
|
||||
import ujson
|
||||
import md5
|
||||
|
||||
htdocs_default_root = '/usr/local/opnsense/scripts/OPNsense/CaptivePortal/htdocs_default'
|
||||
|
||||
def load_exclude_list():
|
||||
""" load exclude list, files that should be removed from the input stream
|
||||
"""
|
||||
result = []
|
||||
filename = '%s/exclude.list' % htdocs_default_root
|
||||
for line in open(filename, 'r').read().split('\n'):
|
||||
line = line.strip()
|
||||
if len(line) > 1 and line[0] != '#':
|
||||
result.append(line)
|
||||
return result
|
||||
|
||||
|
||||
response = dict()
|
||||
if len(sys.argv) < 2:
|
||||
response['error'] = 'Filename parameter missing'
|
||||
else:
|
||||
input_filename = '/tmp/%s' % os.path.basename(sys.argv[1])
|
||||
try:
|
||||
zip_content = open(input_filename,'r').read().decode('base64')
|
||||
except binascii.Error:
|
||||
# not in base64
|
||||
response['error'] = 'Not a base64 encoded file'
|
||||
except IOError:
|
||||
# file npt found
|
||||
response['error'] = 'Error reading file'
|
||||
|
||||
if 'error' not in response:
|
||||
exclude_list = load_exclude_list()
|
||||
input_data = StringIO.StringIO(zip_content)
|
||||
output_data = StringIO.StringIO()
|
||||
with zipfile.ZipFile(input_data, mode='r', compression=zipfile.ZIP_DEFLATED) as zf_in:
|
||||
with zipfile.ZipFile(output_data, mode='w', compression=zipfile.ZIP_DEFLATED) as zf_out:
|
||||
# the zip content may be in a folder, use index to track actual location
|
||||
index_location = None
|
||||
for zf_info in zf_in.infolist():
|
||||
if zf_info.filename.find('index.html') > -1:
|
||||
if index_location is None or len(index_location) > len(zf_info.filename):
|
||||
index_location = zf_info.filename
|
||||
if index_location is not None:
|
||||
for zf_info in zf_in.infolist():
|
||||
if zf_info.filename[-1] != '/':
|
||||
filename = zf_info.filename.replace(index_location.replace('index.html',''),'')
|
||||
# ignore internal osx metadata files, maybe we need to ignore some others (windows?) as well
|
||||
# here.
|
||||
if filename.split('/')[0] in ('__MACOSX') or filename.split('/')[-1] == '.DS_Store':
|
||||
continue
|
||||
if filename not in exclude_list:
|
||||
file_data = zf_in.read(zf_info.filename)
|
||||
src_filename = '%s/%s' % (htdocs_default_root, filename)
|
||||
if os.path.isfile(src_filename):
|
||||
md5_src = md5.new(open(src_filename, 'rb').read()).hexdigest()
|
||||
md5_new = md5.new(file_data).hexdigest()
|
||||
if md5_src != md5_new:
|
||||
# changed file
|
||||
zf_out.writestr(filename, file_data)
|
||||
else:
|
||||
# new file, always write
|
||||
zf_out.writestr(filename, file_data)
|
||||
if 'error' not in response:
|
||||
response['payload'] = output_data.getvalue().encode('base64').strip()
|
||||
response['size'] = len(response['payload'])
|
||||
|
||||
print(ujson.dumps(response))
|
||||
@ -39,3 +39,9 @@ command:/usr/local/opnsense/scripts/OPNsense/CaptivePortal/fetch_template.py
|
||||
parameters:
|
||||
type:script_output
|
||||
message:fetch captiveportal web template package
|
||||
|
||||
[strip_template]
|
||||
command:/usr/local/opnsense/scripts/OPNsense/CaptivePortal/strip_template.py
|
||||
parameters:%s
|
||||
type:script_output
|
||||
message:strip user captiveportal web template package and return new base64 encoded content
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user