chg: Improve hostname popup

pull/79/head
Raphaël Vinot 2020-05-27 12:38:25 +02:00
parent e1f9238bac
commit ccad142dd0
2 changed files with 66 additions and 7 deletions

View File

@ -17,7 +17,7 @@ from lookyloo.lookyloo import Lookyloo
from lookyloo.exceptions import NoValidHarFile from lookyloo.exceptions import NoValidHarFile
from .proxied import ReverseProxied from .proxied import ReverseProxied
from typing import Optional, Dict, Any, List from typing import Optional, Dict, Any, List, Tuple
import logging import logging
@ -164,11 +164,12 @@ def hostnode_popup(tree_uuid: str, node_uuid: str):
'request_cookie': "/static/cookie_read.png", 'request_cookie': "/static/cookie_read.png",
} }
urls = []
sanejs_lookups: Dict[str, List[str]] = {} sanejs_lookups: Dict[str, List[str]] = {}
if hasattr(lookyloo, 'sanejs') and lookyloo.sanejs.available: if hasattr(lookyloo, 'sanejs') and lookyloo.sanejs.available:
to_lookup = [url.body_hash for url in hostnode.urls if hasattr(url, 'body_hash')] to_lookup = [url.body_hash for url in hostnode.urls if hasattr(url, 'body_hash')]
sanejs_lookups = lookyloo.sanejs.hashes_lookup(to_lookup) sanejs_lookups = lookyloo.sanejs.hashes_lookup(to_lookup)
urls: List[Tuple[bool, str, str]] = []
for url in hostnode.urls: for url in hostnode.urls:
if hasattr(url, 'body_hash') and url.body_hash in sanejs_lookups: if hasattr(url, 'body_hash') and url.body_hash in sanejs_lookups:
url.add_feature('sane_js_details', sanejs_lookups[url.body_hash]) url.add_feature('sane_js_details', sanejs_lookups[url.body_hash])
@ -180,7 +181,12 @@ def hostnode_popup(tree_uuid: str, node_uuid: str):
else: else:
# Predefined generic file # Predefined generic file
url.add_feature('sane_js_details_to_print', sanejs_lookups[url.body_hash]) url.add_feature('sane_js_details_to_print', sanejs_lookups[url.body_hash])
urls.append(url)
# For the popup, we need:
# * https vs http
# * everything after the domain
# * the full URL
urls.append((url.name.startswith('https'), url.name.split('/', 3)[-1], url))
return render_template('hostname_popup.html', return render_template('hostname_popup.html',
tree_uuid=tree_uuid, tree_uuid=tree_uuid,
hostname_uuid=node_uuid, hostname_uuid=node_uuid,

View File

@ -3,11 +3,42 @@
{% block title %}Details for {{ hostname }} {% endblock %} {% block title %}Details for {{ hostname }} {% endblock %}
{% block scripts %} {% block scripts %}
{{ super() }}
<script> <script>
function whereAmI() { function whereAmI() {
window.opener.ProcessChildMessage("{{ hostname_uuid }}"); window.opener.ProcessChildMessage("{{ hostname_uuid }}");
}; };
</script> </script>
<script>
// Source: https://codepen.io/nathanlong/pen/ZpAmjv
function copyToClipboard(text, el) {
var elOriginalText = el.attr('data-original-title');
var copyTextArea = document.createElement("textarea");
copyTextArea.value = text;
document.body.appendChild(copyTextArea);
copyTextArea.select();
var successful = document.execCommand('copy');
var msg = successful ? 'Copied!' : 'Whoops, not copied!';
el.attr('data-original-title', msg).tooltip('show');
document.body.removeChild(copyTextArea);
el.attr('data-original-title', elOriginalText);
}
$(document).ready(function() {
// Copy to clipboard
// Grab any text in the attribute 'data-copy' and pass it to the copy function
$('.js-copy').tooltip();
$('.js-copy').click(function() {
var text = $(this).attr('data-copy');
var el = $(this);
copyToClipboard(text, el);
});
});
</script>
{% endblock %} {% endblock %}
{% block content %} {% block content %}
@ -18,9 +49,27 @@
</center> </center>
<p>Click on the URL to get the content of the response</p> <p>Click on the URL to get the content of the response</p>
<ul class="list-group-flush"> <ul class="list-group-flush">
{% for url in urls %} {% for secure, path, url in urls %}
<li class="list-group-item"> <li class="list-group-item">
<p class="h3">{{ url.name }}</p> <div class="h3">
<button type="button" class="btn btn-default btn-copy js-copy"
data-toggle="tooltip" data-placement="bottom" data-copy="{{url.name}}" title="Copy to clipboard">
<svg class="bi bi-clipboard" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M4 1.5H3a2 2 0 0 0-2 2V14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3.5a2 2 0 0 0-2-2h-1v1h1a1 1 0 0 1 1 1V14a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V3.5a1 1 0 0 1 1-1h1v-1z"/>
<path fill-rule="evenodd" d="M9.5 1h-3a.5.5 0 0 0-.5.5v1a.5.5 0 0 0 .5.5h3a.5.5 0 0 0 .5-.5v-1a.5.5 0 0 0-.5-.5zm-3-1A1.5 1.5 0 0 0 5 1.5v1A1.5 1.5 0 0 0 6.5 4h3A1.5 1.5 0 0 0 11 2.5v-1A1.5 1.5 0 0 0 9.5 0h-3z"/>
</svg>
</button>
{% if secure %}
<svg class="bi bi-lock" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M11.5 8h-7a1 1 0 0 0-1 1v5a1 1 0 0 0 1 1h7a1 1 0 0 0 1-1V9a1 1 0 0 0-1-1zm-7-1a2 2 0 0 0-2 2v5a2 2 0 0 0 2 2h7a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2h-7zm0-3a3.5 3.5 0 1 1 7 0v3h-1V4a2.5 2.5 0 0 0-5 0v3h-1V4z"/>
</svg>
{% else %}
<svg class="bi bi-unlock" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M9.655 8H2.333c-.264 0-.398.068-.471.121a.73.73 0 0 0-.224.296 1.626 1.626 0 0 0-.138.59V14c0 .342.076.531.14.635.064.106.151.18.256.237a1.122 1.122 0 0 0 .436.127l.013.001h7.322c.264 0 .398-.068.471-.121a.73.73 0 0 0 .224-.296 1.627 1.627 0 0 0 .138-.59V9c0-.342-.076-.531-.14-.635a.658.658 0 0 0-.255-.237A1.122 1.122 0 0 0 9.655 8zm.012-1H2.333C.5 7 .5 9 .5 9v5c0 2 1.833 2 1.833 2h7.334c1.833 0 1.833-2 1.833-2V9c0-2-1.833-2-1.833-2zM8.5 4a3.5 3.5 0 1 1 7 0v3h-1V4a2.5 2.5 0 0 0-5 0v3h-1V4z"/>
</svg>
{%endif%}
... /{{ path }}
</div>
<ul class="list-group"> <ul class="list-group">
<li class="list-group-item"> <li class="list-group-item">
<p class="h4">Response</p> <p class="h4">Response</p>
@ -37,16 +86,20 @@
{%endif%} {%endif%}
{% endfor %} {% endfor %}
</div> </div>
{% if not url.empty_response %}
<div> <div>
{% if not url.empty_response %}
<a href="{{ url_for('urlnode_details', tree_uuid=tree_uuid, node_uuid=url.uuid) }}"> <a href="{{ url_for('urlnode_details', tree_uuid=tree_uuid, node_uuid=url.uuid) }}">
Download response body. Download response body.
</a></br> </a></br>
Body size: {{ sizeof_fmt(url.body.getbuffer().nbytes) }} Body size: {{ sizeof_fmt(url.body.getbuffer().nbytes) }}
</div>
{% else %} {% else %}
Empty body. Empty body.
{%endif%} {%endif%}
</div>
<div>
Status Code: {{ url.response['status'] }}
</div>
{% if url.sane_js_details_to_print %} {% if url.sane_js_details_to_print %}
<div> <div>
{% if url.sane_js_details_to_print is string %} {% if url.sane_js_details_to_print is string %}