Skip to content

Commit

Permalink
Merge pull request #71 from italia/dev
Browse files Browse the repository at this point in the history
v0.9.6
  • Loading branch information
peppelinux committed Jul 28, 2021
2 parents 454fa71 + 0453449 commit 12d72a9
Show file tree
Hide file tree
Showing 9 changed files with 58 additions and 47 deletions.
13 changes: 9 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,13 @@ Examples
Run `spid_sp_test -h` for inline documentation.

````
usage: spid_sp_test [-h] [--metadata-url METADATA_URL] [--idp-metadata] [-l [LIST [LIST ...]]] [--extra] [--authn-url AUTHN_URL] [-tr] [-nsr] [-tp TEMPLATE_PATH] [-tn [TEST_NAMES [TEST_NAMES ...]]]
[-tj [TEST_JSONS [TEST_JSONS ...]]] [-aj ATTR_JSON] [-report] [-o O] [-d {CRITICAL,ERROR,WARNING,INFO,DEBUG}] [-xp XMLSEC_PATH] [--production] [--html-path HTML_PATH] [--exit-zero]
usage: spid_sp_test [-h] [--metadata-url METADATA_URL] [--idp-metadata] [-l [LIST [LIST ...]]] [--extra] [--authn-url AUTHN_URL] [-tr] [-nsr]
[-tp TEMPLATE_PATH] [-tn [TEST_NAMES [TEST_NAMES ...]]] [-tj [TEST_JSONS [TEST_JSONS ...]]] [-aj ATTR_JSON]
[-o REPORT_OUTPUT_FILE] [-rf {json,html}] [-d {CRITICAL,ERROR,WARNING,INFO,DEBUG}] [-xp XMLSEC_PATH] [--production]
[--response-html-dumps RESPONSE_HTML_DUMPS] [--exit-zero]
[-pr {saml2-sp,spid-sp-public,spid-sp-private,spid-sp-ag-public-full,spid-sp-ag-public-lite,spid-sp-op-public-full,spid-sp-op-public-lite,cie-sp-public,cie-sp-private}]
[-ap AUTHN_PLUGIN] [-rm REQUEST_METHOD] [-rb REQUEST_BODY] [-rct REQUEST_CONTENT_TYPE]
src/spid_sp_test/spid_sp_test -h for help
````
Expand All @@ -98,7 +103,7 @@ spid_sp_test --metadata-url http://localhost:8000/spid/metadata --authn-url http

JSON report, add `-o filename.json` to write to a file, `-rf html -o html_report/` to export to a HTML page
````
spid_sp_test --metadata-url http://localhost:8000/spid/metadata --authn-url http://localhost:8000/spid/login/?idp=https://localhost:8080 --extra --debug CRITICAL -json
spid_sp_test --metadata-url http://localhost:8000/spid/metadata --authn-url http://localhost:8000/spid/login/?idp=https://localhost:8080 --extra -rf json
````

Given a metadata file and a authn file (see `tests/metadata` and `tests/authn` for example) export all the test response without sending them to SP:
Expand Down Expand Up @@ -153,7 +158,7 @@ The container working directory is set to `/spid` therefore, local files should
Test Responses and html dumps
-----------------------------

By enabling the response dump with the `--html-path HTML_PATH` option, you will get N html files (page of your SP) as follows:
By enabling the response dump with the `--response-html-dumps HTML_PATH` option, you will get N html files (page of your SP) as follows:

- test description, commented
- SAML Response sent, commented
Expand Down
2 changes: 1 addition & 1 deletion build_pypi.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/bash

PROJ_NAME=$(ls | grep *.egg-info | sed -e 's/.egg-info//g') ; rm -R build/ dist/* *.egg-info ; pip uninstall $PROJ_NAME ; python setup.py build sdist

twine upload dist/*
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def readme():

setup(
name=_pkg_name,
version='0.9.5',
version='0.9.6',
description="SAML2 SPID Service Provider validation tool that can be run from the command line",
long_description=readme(),
long_description_content_type='text/markdown',
Expand Down
9 changes: 5 additions & 4 deletions src/spid_sp_test/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class AbstractSpidCheck(object):
def __init__(self, *args, **kwargs):
self.results = []
self.errors = []
self.warnings = []
self.logger = logger
self.error_counter = 0
self.verify_ssl = kwargs.get("verify_ssl", False)
Expand Down Expand Up @@ -49,13 +50,13 @@ def handle_result(
elif level in ("error", "critical"):
self.handle_error(title, description, traceback)
elif level == "warning":
self.results.append(
{
data = {
"result": "warning",
"test": title,
"value": value,
}
)
}
self.results.append(data)
self.warnings.append(data)

def handle_error(self, error_message, description="", traceback: str = None):
getattr(self.logger, "error")(error_message)
Expand Down
1 change: 0 additions & 1 deletion src/spid_sp_test/html/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,6 @@ <h4><a href="#" title="Vai alla pagina: Seguici su">Seguici su</a></h4>
{% endblock footer_contacts_section %}



{% block footer_bottom_content %}
<h3 class="sr-only">Sezione Link Utili</h3>
<ul class="it-footer-small-prints-list list-inline mb-0 d-flex flex-column flex-md-row">
Expand Down
13 changes: 8 additions & 5 deletions src/spid_sp_test/response.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import logging
import random
import requests
import os
import sys
import string

Expand Down Expand Up @@ -292,16 +293,16 @@ def check_response(self, res, msg: str, attendeds=[]):
return status, status_code

def dump_html_response(self, fname, description, result, content):
url = self.authnreq_attrs["AssertionConsumerServiceURL"]
try:
content = html_absolute_paths(content, url)
content = html_absolute_paths(content, self.acs_url)
except Exception as e:
logger.critical(
f"Something went wrong making absolute links in html content: {e}"
)

content = content.decode() if isinstance(content, bytes) else content
head = f"<!-- {description} -->\n\n" f"<!-- {result} -->\n\n"
os.makedirs(self.html_path, exist_ok=True)
with open(f"{self.html_path}/{fname}.html", "w") as f:
f.write(head)
f.write(content)
Expand Down Expand Up @@ -348,7 +349,10 @@ def test_profile_spid_sp(self):
)
sys.exit(1)

if not self.no_send_response:
if self.no_send_response:
print(f"<!-- {test_display_desc} -->\n{result}")

else:
res = self.send_response(result)
status, status_msg = self.check_response(
res,
Expand All @@ -362,8 +366,7 @@ def test_profile_spid_sp(self):
result,
res.content.decode(),
)
else:
print(f"<!-- {test_display_desc} -->\n{result}")

# reset session
self.requests_session = requests.Session()

Expand Down
2 changes: 1 addition & 1 deletion src/spid_sp_test/responses/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

ATTRIBUTES_TYPES = {"dateOfBirth": "date", "expirationDate": "date"}

HTTP_STATUS_ERROR_CODES = [400, 401, 403, 500]
HTTP_STATUS_ERROR_CODES = [400, 401, 403, 422, 500]

ATTRIBUTES = {
"spidCode": "AGID-001",
Expand Down
2 changes: 1 addition & 1 deletion src/spid_sp_test/responses/templates/base.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@
Version="2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
{% endblock AssertionTag %}
{% block AssertionIssuer %}<saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">{{Issuer}}</saml:Issuer>{% endblock %}
{% block assertion_signature %}
<!-- Assertion Signature here -->
{% endblock assertion_signature %}
{% block AssertionIssuer %}<saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">{{Issuer}}</saml:Issuer>{% endblock %}
{% block SubjectTag %}
<saml:Subject>
{% block SubjectNameID %}
Expand Down
61 changes: 32 additions & 29 deletions src/spid_sp_test/spid_sp_test
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ if __name__ == '__main__':
{__file__} --metadata-url http://localhost:8000/spid/metadata --authn-url http://localhost:8000/spid/login/?idp=https://localhost:8080 --extra --debug DEBUG -aj tests/example.attributes.json
# dump SP response as html page
{__file__} --metadata-url http://localhost:8000/spid/metadata --authn-url http://localhost:8000/spid/login/?idp=https://localhost:8080 --extra --debug ERROR -tr --html-path dumps
{__file__} --metadata-url http://localhost:8000/spid/metadata --authn-url http://localhost:8000/spid/login/?idp=https://localhost:8080 --extra --debug ERROR -tr --response-html-dumps ./html
# html report
{__file__} --metadata-url http://localhost:8000/spid/metadata --authn-url http://localhost:8000/spid/login/?idp=https://localhost:8080 --extra --debug INFO --test-response -rf html -o html_report/
Expand Down Expand Up @@ -128,7 +128,7 @@ if __name__ == '__main__':
'-tn', '--test-names',
action='append', nargs='*',
required=False,
help="response test to be executed, eg: 01 02 03"
help="response test to be executed, eg: 1 2 3"
)

parser.add_argument(
Expand All @@ -146,21 +146,19 @@ if __name__ == '__main__':
)

parser.add_argument(
'-report', action="store_true",
help="json report in stdout"
)

parser.add_argument(
'-o', required=False,
help="report to file, -report is required"
'-o', '--report-output-file', required=False,
help="the report will be dumped in a specified path"
)

parser.add_argument(
'-rf', '--report_format',
required=False,
default='json',
choices=['json', 'html'],
help="Report format, json or pdf"
help=(
"Report format, json or html. "
"If html the repo will be stored to the ./html folder by default. "
"You can specificy another path using --report-output-file"
)
)

parser.add_argument(
Expand All @@ -187,7 +185,7 @@ if __name__ == '__main__':
)

parser.add_argument(
'--html-path', '-hp',
'--response-html-dumps', '-rhd',
help=("Only works with Response tests activated. "
"Path where the html response pages will "
"be dumped after by the SP")
Expand Down Expand Up @@ -295,7 +293,7 @@ if __name__ == '__main__':
# Responses
if args.test_response:
# 'html-dumps_{datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S")}'
html_path = f'{args.html_path}/'
html_path = f'{args.response_html_dumps}/'

data_tr = dict(
metadata_etree=metadata_check.doc,
Expand All @@ -307,7 +305,7 @@ if __name__ == '__main__':
test_jsons=args.test_jsons or [],
attr_json=args.attr_json,
production=args.production,
html_path=html_path if args.html_path else None,
html_path=html_path if args.response_html_dumps else None,
no_send_response = args.no_send_response,
authn_plugin = args.authn_plugin,
requests_session = authn_check.authn_request['requests_session'],
Expand All @@ -316,15 +314,15 @@ if __name__ == '__main__':
request_content_type = args.request_content_type
)

if args.html_path:
os.makedirs(html_path, exist_ok=True)

response_check = SpidSpResponseCheck(**data_tr)
selective_run(response_check, profile, args.list)
tests_done.append(response_check)

if args.response_html_dumps:
print(f"\nSAML Response html dumps are at {args.response_html_dumps}\n")

# OUTPUT - REPORT
if args.o or args.report:
if args.report_output_file or args.report_format:
data = {
"test": {
"sp": {}
Expand All @@ -335,24 +333,29 @@ if __name__ == '__main__':
data['test']['sp'][i.category] = i.report_to_dict()[i.category]

output = json.dumps(data, indent=2)
if args.o:
if args.report_format == 'json':
with open(args.o, 'w') as f:
f.write(output)
elif args.report_format == 'html':
render_html_report(data['test']['sp'],
output_folder = args.o,
display_name = args.metadata_url)

if args.report and not args.o:
if args.report_output_file and args.report_format == 'json':
with open(args.report_output_file, 'w') as f:
f.write(output)
elif args.report_format == 'html':
output_folder = args.report_output_file or os.path.join('.', 'html')
render_html_report(data['test']['sp'],
output_folder = output_folder,
display_name = args.metadata_url)
print(f"\nHTML report is at {output_folder}\n")

elif args.report_format == 'json':
print(output)

# check exit status
tests = sum([len(i.results) for i in tests_done])
tests_warnings = sum([len(i.warnings) for i in tests_done])
tests_errors = sum([len(i.errors) for i in tests_done])

if not args.no_send_response:
print(f'Spid QA: executed {tests} tests, {tests_errors} failed.')
print(
f'Spid QA: executed {tests} tests, {tests_errors} failed. '
f'{tests_warnings} warnings.'
)

if tests_errors and not args.exit_zero:
sys.exit(1)

0 comments on commit 12d72a9

Please sign in to comment.