Skip to content

Commit

Permalink
create script to change parameter
Browse files Browse the repository at this point in the history
To be capapble of easily changing supported keywords within the default
template pheme/scripts/parameter.py gets repurposed to change parameter
for a running pheme instance.
  • Loading branch information
nichtsfrei committed Dec 8, 2020
1 parent a536d6b commit 7aa0d59
Show file tree
Hide file tree
Showing 5 changed files with 354 additions and 42 deletions.
171 changes: 171 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
.. role:: raw-html-m2r(raw)
:format: html



.. image:: https://www.greenbone.net/wp-content/uploads/gb_logo_resilience_horizontal.png
:target: https://www.greenbone.net/wp-content/uploads/gb_logo_resilience_horizontal.png
:alt: Greenbone Logo


Pheme - Greenbone Static Report Generator :raw-html-m2r:`<!-- omit in toc -->`
==================================================================================

**pheme** is a service to create scan reports. It is maintained by `Greenbone Networks <https://www.greenbone.net/>`_.

`Pheme <https://en.wikipedia.org/wiki/Pheme>`_ is the personification of fame and renown.

Or in this case personification of a service to generate reports.

Table of Contents :raw-html-m2r:`<!-- omit in toc -->`
----------------------------------------------------------


* `Installation <#installation>`_

* `Requirements <#requirements>`_

* `Development <#development>`_
* `API overview <#api-overview>`_
* `Maintainer <#maintainer>`_
* `Contributing <#contributing>`_
* `License <#license>`_

Installation
------------

Requirements
^^^^^^^^^^^^

Python 3.7 and later is supported.

Besides python ``pheme`` also needs to have


* libcairo2-dev
* pango1.0

installed.

Development
-----------

**pheme** uses `poetry <https://python-poetry.org/>`_ for its own dependency management and build
process.

First install poetry via pip

.. code-block::
python3 -m pip install --user poetry
Afterwards run

.. code-block::
poetry install
in the checkout directory of **pheme** (the directory containing the
``pyproject.toml`` file) to install all dependencies including the packages only
required for development.

Afterwards activate the git hooks for auto-formatting and linting via
`autohooks <https://github.com/greenbone/autohooks>`_.

.. code-block::
poetry run autohooks activate
Validate the activated git hooks by running

.. code-block::
poetry run autohooks check
API overview
------------

To get an overview of the API you can start this project

.. code-block::
poetry run python manage.py runserver
and then go to `swagger <http://localhost:8000/docs/>`_

Usage
-----

In order to prepare the data structure the XML report data needs to be posted to ``pheme`` with a grouping indicator (either by host or nvt).

E.g.:

.. code-block::
> curl -X POST 'http://localhost:8000/transform?grouping=nvt'\
-H 'Content-Type: application/xml'\
-H 'Accept: application/json'\
-d @test_data/longer_report.xml
"scanreport-nvt-9a233b0d-713c-4f22-9e15-f6e5090873e3"⏎
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.

.. code-block::
> 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

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

.. code-block::
> 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:

.. code-block::
> curl -v 'http://localhost:8000/report/scanreport-nvt-9a233b0d-713c-4f22-9e15-f6e5090873e3' -H 'Accept: application/pdf'
Maintainer
----------

This project is maintained by `Greenbone Networks GmbH <https://www.greenbone.net/>`_

Contributing
------------

Your contributions are highly appreciated. Please
`create a pull request <https://github.com/greenbone/pheme/pulls>`_
on GitHub. Bigger changes need to be discussed with the development team via the
`issues section at GitHub <https://github.com/greenbone/pheme/issues>`_
first.

License
-------

Copyright (C) 2020 `Greenbone Networks GmbH <https://www.greenbone.net/>`_

Licensed under the `GNU Affero General Public License v3.0 or later <LICENSE>`_.
119 changes: 88 additions & 31 deletions pheme/scripts/parameter.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# pheme/scripts/parameter-json-from-dir.py
# pheme/scripts/parameter.py
# Copyright (C) 2020 Greenbone Networks GmbH
#
# SPDX-License-Identifier: AGPL-3.0-or-later
Expand All @@ -19,50 +19,107 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.


# Usage: pheme-parameter-json-from-dir $path > parameter.json

# Usage: pheme-parameter $path
import os
import json
import mimetypes
import sys
from pathlib import Path
from argparse import ArgumentParser
from urllib.parse import urlparse, ParseResult
from typing import Dict
import http.client
import pathlib

from pheme.datalink import as_datalink

from pheme.settings import SECRET_KEY

PHEME_URL = os.getenv('PHEME_URL', 'https://localhost:8443/pheme')
COLOR_KEYS = ['main_color']
PICTURE_KEYS = ['logo', 'background']
ALLOWED_KEYS = COLOR_KEYS + PICTURE_KEYS


def load_data(parent: Path) -> Dict:
def __init_argument_parser() -> ArgumentParser:
value_description = """The value for given key.
If key is in {color} than it must represent color (e.g. #66c430).
If the key is in {pics} than it must be a path to a svg, png or jpeg file.
""".format(
color=COLOR_KEYS, pics=PICTURE_KEYS
)
parser = ArgumentParser(
description='Adds parameter to pheme.',
prog='pheme-parameter',
)
parser.add_argument(
'--key',
help='Identifier of a parameter to set. Valid keys are: {}'.format(
ALLOWED_KEYS
),
required=True,
)
parser.add_argument(
'--value',
help=value_description,
required=True,
)
return parser


def __load_data(parent: pathlib.Path) -> Dict:
data = {}
for i in parent.glob("*"):
file_type, _ = mimetypes.guess_type(i.name)
key = (
i.name[: -len(i.suffix)]
if not 'css' in i.suffix
else "{}_css".format(i.name[: -len(i.suffix)])
file_type, _ = mimetypes.guess_type(parent.name)
key = parent.name[: -len(parent.suffix)]
if file_type and file_type.startswith('image'):
data[key] = as_datalink(parent.read_bytes(), file_type)
else:
raise ValueError(
"Unknown mimetype {} for {}.".format(file_type, parent)
)
if i.is_dir():
data = {**data, **load_data(i)}
elif file_type and file_type.startswith('image'):
data[key] = as_datalink(i.read_bytes(), file_type)
elif file_type and file_type.startswith('text'):
data[key] = i.read_text()
elif file_type and file_type == 'application/json':
data = {**data, **json.loads(i.read_text())}
else:
sys.stderr.write("skipping {} -> {}".format(i, file_type))
return data


def main():
if len(sys.argv) != 2:
sys.stderr.write("need exactly one one path parameter. Aborting.")
sys.exit(1)
def __put(data: Dict) -> (ParseResult, Dict):
def connection():
parsed = urlparse(PHEME_URL)
if parsed.scheme == 'https':
return parsed, http.client.HTTPSConnection(parsed.netloc)
else:
return parsed, http.client.HTTPConnection(parsed.netloc)

url, conn = connection()
headers = {
'Content-Type': 'application/json',
'x-api-key': SECRET_KEY,
}
params = json.dumps(data)
conn.request('PUT', url.path + '/parameter', params, headers)
response = conn.getresponse()
if response.status != 200:
raise ValueError(
"failed to upload parameter. Response code is {}.".format(
response.status
)
)
response_txt = response.read()
response.close()
conn.close()
return json.loads(response_txt)


def main(args=None):
data = {}
paths = sys.argv[1:]
for i in paths:
parent = Path(i)
data = {**data, **load_data(parent)}
print(json.dumps(data))
parser = __init_argument_parser()
arguments = parser.parse_args(args)
if arguments.key in COLOR_KEYS:
data[arguments.key] = arguments.value
elif arguments.key in PICTURE_KEYS:
parent = pathlib.Path(arguments.value)
data = {**data, **__load_data(parent)}
else:
raise ValueError("{} is not defined".format(arguments.key))
return __put(data)


if __name__ == "__main__":
main()
print("success")
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ mode = "poetry"
version-module-file = "pheme/version/__version__.py"

[tool.poetry.scripts]
pheme-create-parameter-json = 'pheme.scripts.parameter:main'
pheme-parameter = 'pheme.scripts.parameter:main'

[build-system]
requires = ["poetry>=0.12"]
Expand Down
35 changes: 25 additions & 10 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
# -*- coding: utf-8 -*-

# DO NOT EDIT THIS FILE!
# This file has been autogenerated by dephell <3
# https://github.com/dephell/dephell

try:
from setuptools import setup, find_packages
from setuptools import setup
except ImportError:
from distutils.core import setup


import os.path

readme = ''
here = os.path.abspath(os.path.dirname(__file__))
readme_path = os.path.join(here, 'README.rst')
if os.path.exists(readme_path):
with open(readme_path, 'rb') as stream:
readme = stream.read().decode('utf8')


setup(
long_description=readme,
Expand All @@ -30,17 +40,23 @@
'Topic :: Internet :: WWW/HTTP :: WSGI :: Server',
],
entry_points={
"console_scripts": [
"pheme-create-parameter-json = pheme.scripts.parameter:main"
]
"console_scripts": ["pheme-parameter = pheme.scripts.parameter:main"]
},
packages=find_packages(exclude=['tests']),
include_package_data=True,
packages=[
'pheme',
'pheme.parser',
'pheme.templatetags',
'pheme.templatetags.charts',
'pheme.transformation',
'pheme.transformation.scanreport',
'pheme.version',
],
package_dir={"": "."},
package_data={},
install_requires=[
'coreapi==2.*,>=2.3.3',
'django==3.*,>=3.1.0',
'djangorestframework==3.*,>=3.11.1',
'djangorestframework-dataclasses<0.9,>=0.6',
'django==2.2.2',
'djangorestframework==3.9.0',
'matplotlib==3.0.2',
'pyyaml==5.*,>=5.3.1',
'rope<0.19,>=0.17',
Expand All @@ -63,5 +79,4 @@
"pytest-env==0.*,>=0.6.2",
]
},
test_suite="tests",
)
Loading

0 comments on commit 7aa0d59

Please sign in to comment.