Skip to content

Commit

Permalink
remove html and css in favor of a more dynamic system
Browse files Browse the repository at this point in the history
To be capable of using html or pdf you need to upload the html template
as well as the css for the formats:

```
> curl -X PUT localhost:8000/parameter\
    -H 'x-api-key: SECRET_KEY_missing_using_default_not_suitable_in_production'\
    --form vulnerability_report_html_css=@path_to_css_template\
    --form vulnerability_report_pdf_css=@path_to_css_template\
    --form vulnerability_report=@path_to_html_template
```
  • Loading branch information
nichtsfrei committed Oct 20, 2020
1 parent d28b328 commit 2a499f2
Show file tree
Hide file tree
Showing 13 changed files with 138 additions and 435 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -134,3 +134,4 @@ start.sh
generate.sh
# to prevent accidental uploads of default parameter
static/parameter.json
example.sh
24 changes: 22 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,31 @@ E.g.:
The returned identifier can be used to generate the actual report.

So far a report can be either in:
- application/json
- application/xml
- text/csv
E.g.

```
> curl -v 'http://localhost:8000/report/scanreport-nvt-9a233b0d-713c-4f22-9e15-f6e5090873e3' -H 'Accept: application/csv'
```

For visual report like

- application/pdf
- text/html
- application/json

E.g.
the corresponding css and html template needs to be put into pheme first:

```
> curl -X PUT localhost:8000/parameter\
-H 'x-api-key: SECRET_KEY_missing_using_default_not_suitable_in_production'\
--form vulnerability_report_html_css=@path_to_css_template\
--form vulnerability_report_pdf_css=@path_to_css_template\
--form vulnerability_report=@path_to_html_template
```

afterwards it can be get as usual:

```
> curl -v 'http://localhost:8000/report/scanreport-nvt-9a233b0d-713c-4f22-9e15-f6e5090873e3' -H 'Accept: application/pdf'
Expand Down
14 changes: 13 additions & 1 deletion pheme/parameter.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import mimetypes
import logging
from typing import Dict, Callable
from pathlib import Path
import json
Expand All @@ -16,6 +18,9 @@
from pheme.authentication import SimpleApiKeyAuthentication


logger = logging.getLogger(__name__)


def load_params(from_path: str = settings.PARAMETER_FILE_ADDRESS) -> Dict:
param_file_obj = Path(from_path)
return (
Expand Down Expand Up @@ -70,7 +75,14 @@ def put_file(request: Request) -> Response:
def manipulate(data: Dict) -> Dict:
for (key, value) in request.data.items():
if isinstance(value, UploadedFile):
data[key] = filename_as_datalink(value.name, value.read())
file_type, _ = mimetypes.guess_type(value.name)
logger.info("uploaded %s for %s", file_type, key)
if file_type.startswith('image'):
data[key] = filename_as_datalink(value.name, value.read())
elif file_type.startswith('text'):
data[key] = value.read().decode()
else:
raise ValueError("Only image or text is permitted")
else:
data[key] = value
return data
Expand Down
18 changes: 15 additions & 3 deletions pheme/transformation/scanreport/gvmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,8 +191,21 @@ def modify_fig(fig: Figure):

def set_plot(ax):
ax.set_title(title)
series.plot.pie(
legend=True, ax=ax, colors=colors, autopct=raw_value_pct
wedges, _, _ = ax.pie(
series.values,
colors=colors,
autopct=raw_value_pct,
wedgeprops=dict(width=0.5),
startangle=-40,
)

keys = series.keys()
ax.legend(
wedges,
keys,
bbox_to_anchor=(1, 0, 0, 1),
loc='lower right',
fontsize='small',
)

if len(series) < 1:
Expand Down Expand Up @@ -239,7 +252,6 @@ def __create_nvt(result_series_df: DataFrame) -> CountGraph:
chart=__create_pie_chart(
counted,
colors=__severity_class_to_color(counted.keys()),
title="Total NVT",
),
counts=None,
)
Expand Down
54 changes: 31 additions & 23 deletions pheme/transformation/scanreport/renderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@


from django.core.cache import cache
from django.template import Template, Context, loader
from django.template import Template, Context
from rest_framework import renderers
from rest_framework.request import Request
from weasyprint import CSS, HTML
Expand All @@ -31,8 +31,10 @@
logger = logging.getLogger(__name__)


def _get_css(name: str) -> CSS:
return loader.get_template(name).render(load_params())
def _load_template(name: str, params: Dict = None) -> Template:
if not params:
params = load_params()
return Template(params[name])


def _enrich(name: str, data: Dict) -> Dict:
Expand All @@ -56,7 +58,7 @@ def _default_not_found_response(
return '"not data found for %s"' % report_id


class DetailScanReport(renderers.BaseRenderer):
class Report(renderers.BaseRenderer):
def render(self, data, accepted_media_type=None, renderer_context=None):
request = _get_request(renderer_context)
if not data:
Expand All @@ -77,36 +79,42 @@ def render(self, data, accepted_media_type=None, renderer_context=None):

def apply(self, name: str, data: Dict):
raise NotImplementedError(
'DetailScanReport class requires .apply() to be implemented'
'Report class requires .apply() to be implemented'
)


class DetailScanHTMLReport(DetailScanReport):
__template = 'scan_report.html'
class VulnerabilityHTMLReport(Report):
__template = 'vulnerability_report'
__css_template = 'vulnerability_report_html_css'
media_type = 'text/html'
format = 'html'

def _enrich(self, name: str, data: Dict) -> Dict:
data = _enrich(name, data)
data['css'] = _get_css('html_report.css')
return data

def apply(self, name: str, data: Dict):
return loader.get_template(self.__template).render(
self._enrich(name, data)
params = load_params()
css = _load_template(self.__css_template, params).render(
Context(params)
)
data['css'] = css
return _load_template(self.__template).render(
Context(_enrich(name, data))
)


class DetailScanPDFReport(DetailScanReport):
__template = 'scan_report.html'
class VulnerabilityPDFReport(Report):
__template = 'vulnerability_report'
__css_template = 'vulnerability_report_pdf_css'
media_type = 'application/pdf'
format = 'binary'

def apply(self, name: str, data: Dict):
logger.debug("got template: %s", self.__template)
html = loader.get_template(self.__template).render(_enrich(name, data))
params = load_params()
css = _load_template(self.__css_template, params).render(
Context(params)
)
html_template = _load_template(self.__template)
html = html_template.render(Context(_enrich(name, data)))
logger.debug("created html")
css = _get_css('pdf_report.css')
pdf = HTML(string=html).write_pdf(stylesheets=[CSS(string=css)])
logger.debug("created pdf")
return pdf
Expand All @@ -121,9 +129,9 @@ def render(self, data, accepted_media_type=None, renderer_context=None):
if not data:
return _default_not_found_response(renderer_context, request)
template = Template(data['template'])
data['scan_report']['css'] = data['html_css']
data['scan_report']['images'] = data['images']
context = Context(data['scan_report'])
data['vulnerability_report']['css'] = data['html_css']
data['vulnerability_report']['images'] = data['images']
context = Context(data['vulnerability_report'])
html = template.render(context)
logger.debug("created html")
return html
Expand All @@ -137,9 +145,9 @@ def render(self, data, accepted_media_type=None, renderer_context=None):
request = _get_request(renderer_context)
if not data:
return _default_not_found_response(renderer_context, request)
data['scan_report']['images'] = data['images']
data['vulnerability_report']['images'] = data['images']
template = Template(data['template'])
context = Context(data['scan_report'])
context = Context(data['vulnerability_report'])
html = template.render(context)
logger.debug("created html")
css = Template(data['pdf_css']).render(context)
Expand Down
6 changes: 3 additions & 3 deletions pheme/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ def load_value_of(key) -> str:
rest_framework.renderers.JSONRenderer,
scanreport.renderer.ReportFormatPDFReport,
scanreport.renderer.ReportFormatHTMLReport,
scanreport.renderer.DetailScanHTMLReport,
scanreport.renderer.DetailScanPDFReport,
scanreport.renderer.VulnerabilityHTMLReport,
scanreport.renderer.VulnerabilityPDFReport,
XMLRenderer,
CSVRenderer,
]
Expand All @@ -129,7 +129,7 @@ def load_value_of(key) -> str:
return Response(
{
"template": load_value_of("{}html_template".format(name)),
"scan_report": load(name),
"vulnerability_report": load(name),
"pdf_css": load_value_of("{}pdf_css".format(name)),
"html_css": load_value_of("{}html_css".format(name)),
"images": images,
Expand Down
1 change: 0 additions & 1 deletion static/parameter.json

This file was deleted.

2 changes: 0 additions & 2 deletions static/report_format_editor.html
Original file line number Diff line number Diff line change
Expand Up @@ -315,8 +315,6 @@ <h1>Report Format Editor</h1>
</div>
<script>
document.querySelector("#pdf").click()
fetch_set_value('/static/scan_report.html', document.querySelector('#html_template_editor'))
fetch_set_value('/static/pdf_report.css', document.querySelector('#css_template_editor'))
document.querySelector('#download_all').addEventListener('click', event => {
download_template_elements_json(`${report_key}.json`)
})
Expand Down
133 changes: 0 additions & 133 deletions template/html_report.css

This file was deleted.

Loading

0 comments on commit 2a499f2

Please sign in to comment.