Skip to content

Commit

Permalink
server: host list tabs for versioninfo and vulnsearch
Browse files Browse the repository at this point in the history
  • Loading branch information
bodik committed Oct 31, 2023
1 parent c8b63c6 commit 7926d8d
Show file tree
Hide file tree
Showing 8 changed files with 125 additions and 11 deletions.
6 changes: 6 additions & 0 deletions sner/server/static/sner/sner.storage.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ class SnerStorageComponent extends SnerComponentBase {
}
return '#';
},
/* generate url for cveid */
'url_for_cveid': function(cveid) {
return 'https://cve.circl.lu/cve/' + cveid;
},
/* generate text for ref */
'text_for_ref': function(ref) {
if (ref.startsWith('URL-')) { return 'URL'; }
Expand Down Expand Up @@ -210,6 +214,8 @@ class SnerStorageComponent extends SnerComponentBase {
</div>`,
'note_list_filter_xtype_link': `<a href="{{note_list_route_filter_xtype xtype}}">{{xtype}}</a>`,

'vulnsearch_cveid_link': `<a href="{{url_for_cveid cveid}}">{{cveid}}</a>`,

'modal_freetag_multiid': `
<form>
<div class="form-group row">
Expand Down
89 changes: 89 additions & 0 deletions sner/server/templates/storage/host/view.html
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ <h6 class="dropdown-header">More data</h6>
<li class="nav-item"><a class="nav-link" href="#host_view_service_tab" data-toggle="tab">Services <span class="badge badge-pill badge-secondary">{{ host.services|length }}</span></a></li>
<li class="nav-item"><a class="nav-link" href="#host_view_vuln_tab" data-toggle="tab">Vulns <span class="badge badge-pill badge-secondary">{{ host.vulns|length }}</span></a></li>
<li class="nav-item"><a class="nav-link" href="#host_view_note_tab" data-toggle="tab">Notes <span class="badge badge-pill badge-secondary">{{ host.notes|length }}</span></a></li>
<li class="nav-item"><a class="nav-link" href="#host_view_versioninfo_tab" data-toggle="tab">VersionInfos <span id="host_view_tabs_versioninfos_count" class="badge badge-pill badge-secondary">?</span></a></li>
<li class="nav-item"><a class="nav-link" href="#host_view_vulnsearch_tab" data-toggle="tab">Vulnsearches <span id="host_view_tabs_vulnsearches_count" class="badge badge-pill badge-secondary">?</span></a></li>
</ul>

<div class="tab-content">
Expand Down Expand Up @@ -296,5 +298,92 @@ <h6 class="dropdown-header">More data</h6>
});
</script>
</div>

<div id="host_view_versioninfo_tab" class="tab-pane">
<div id="host_view_versioninfo_table_toolbar" class="dt_toolbar">
<div id="host_view_versioninfo_table_toolbox" class="dt_toolbar_toolbox">
</div>
</div>
<div class="alert alert-warning" role="alert">Pre-computed view, host links might be incorrect.</div>
<table id="host_view_versioninfo_table" class="table table-hover table-sm" width="100%"></table>
<script type="text/javascript">
var dt_host_view_versioninfo_table_options = {
'ajax': {'url': "{{ url_for('storage.versioninfo_list_json_route', filter='VersionInfo.host_id=="%d"'|format(host.id)) }}", 'method': 'POST'},
'columns': [
Sner.dt.column('id', {'visible': false}),
Sner.dt.column('host_id', {'visible': false}),
Sner.dt.column('host_address', {'visible': false}),
Sner.dt.column('host_hostname', {'visible': false}),
Sner.dt.column('service_proto', {'visible': false}),
Sner.dt.column('service_port', {'visible': false}),
Sner.dt.column('service', {
'className': 'service_endpoint_dropdown',
'render': function(data, type, row, meta) {
return Sner.storage.hbs.service_endpoint_dropdown({...row, 'value': row['service']});
}
}),
Sner.dt.column('via_target', {'visible': JSON.parse(sessionStorage.getItem('dt_viatarget_column_visible'))}),
Sner.dt.column('product'),
Sner.dt.column('version'),
Sner.dt.column('extra'),
],
'order': [[6, 'asc']],
'drawCallback': function (settings) {
Sner.dt.ajax_options['drawCallback'].call(this, settings); // call parent
$('#host_view_tabs_versioninfos_count').text(this.api().rows().data().length);
}
};
$(document).ready(function() {
var dt_host_view_versioninfo_table = Sner.dt.init_datatable('#host_view_versioninfo_table', dt_host_view_versioninfo_table_options);
});
</script>
</div>

<div id="host_view_vulnsearch_tab" class="tab-pane">
<div id="host_view_vulnsearch_table_toolbar" class="dt_toolbar">
<div id="host_view_vulnsearch_table_toolbox" class="dt_toolbar_toolbox">
</div>
</div>
<div class="alert alert-warning" role="alert">Pre-computed view, host links might be incorrect.</div>
<table id="host_view_vulnsearch_table" class="table table-hover table-sm" width="100%"></table>
<script type="text/javascript">
var dt_host_view_vulnsearch_table_options = {
'ajax': {'url': "{{ url_for('storage.vulnsearch_list_json_route', filter='Vulnsearch.host_id=="%d"'|format(host.id)) }}", 'method': 'POST'},
'columns': [
Sner.dt.column('id', {'visible': false}),
Sner.dt.column('host_id', {'visible': false}),
Sner.dt.column('host_address', {'visible': false}),
Sner.dt.column('host_hostname', {'visible': false}),
Sner.dt.column('service_proto', {'visible': false}),
Sner.dt.column('service_port', {'visible': false}),
Sner.dt.column('service', {
'className': 'service_endpoint_dropdown',
'render': function(data, type, row, meta) {
return Sner.storage.hbs.service_endpoint_dropdown({...row, 'value': row['service']});
}
}),
Sner.dt.column('via_target', {'visible': JSON.parse(sessionStorage.getItem('dt_viatarget_column_visible'))}),
Sner.dt.column('cveid', {
'render': function(data, type, row, meta) {
return Sner.storage.hbs.vulnsearch_cveid_link({'cveid': row['cveid']});
}
}),
Sner.dt.column('cvss'),
Sner.dt.column('cvss3'),
Sner.dt.column('attack_vector'),
Sner.dt.column('cpe_full'),
Sner.dt.column('name'),
],
'order': [[6, 'asc']],
'drawCallback': function (settings) {
Sner.dt.ajax_options['drawCallback'].call(this, settings); // call parent
$('#host_view_tabs_vulnsearches_count').text(this.api().rows().data().length);
}
};
$(document).ready(function() {
var dt_host_view_vulnsearch_table = Sner.dt.init_datatable('#host_view_vulnsearch_table', dt_host_view_vulnsearch_table_options);
});
</script>
</div>
</div>
{% endblock %}
6 changes: 5 additions & 1 deletion sner/server/templates/storage/vulnsearch/list.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@
}
}),
Sner.dt.column('via_target', {'visible': JSON.parse(sessionStorage.getItem('dt_viatarget_column_visible'))}),
Sner.dt.column('cveid'),
Sner.dt.column('cveid', {
'render': function(data, type, row, meta) {
return Sner.storage.hbs.vulnsearch_cveid_link({'cveid': row['cveid']});
}
}),
Sner.dt.column('cvss'),
Sner.dt.column('cvss3'),
Sner.dt.column('attack_vector'),
Expand Down
7 changes: 4 additions & 3 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from sner.server.extensions import db
from sner.server.dbx_command import db_remove
from sner.server.password_supervisor import PasswordSupervisor as PWS
from sner.server.storage.models import VersionInfo, Vulnsearch
from sner.server.storage.versioninfo import VersionInfoManager
from sner.server.storage.vulnsearch import LocaldbWriter as VulnsearchLocaldbWriter
from tests.server.auth.models import UserFactory, WebauthnCredentialFactory
Expand Down Expand Up @@ -125,11 +126,11 @@ def versioninfo_notes(host, service_factory, note_factory):


@pytest.fixture
def versioninfo(versioninfo_notes): # pylint: disable=redefined-outer-name,unused-argument
def versioninfos(versioninfo_notes): # pylint: disable=redefined-outer-name,unused-argument
"""prepare versioninfo map snap"""

VersionInfoManager.rebuild()
return versioninfo_notes
return VersionInfo.query.all()


@pytest.fixture
Expand All @@ -138,4 +139,4 @@ def vulnsearch(vulnsearch_temp_factory): # pylint: disable=redefined-outer-name

vulnsearch_temp = vulnsearch_temp_factory.create()
VulnsearchLocaldbWriter().refresh_view()
yield vulnsearch_temp
return Vulnsearch.query.all()
18 changes: 16 additions & 2 deletions tests/selenium/storage/test_host.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
)


def get_host_view_tab(sclnt, host_id, model):
def get_host_view_tab(sclnt, host_id, model, wait_attr_value='comment'):
"""switches host view tab and waits until dt is rendered"""

model_name = model.__class__.__name__.lower()
Expand All @@ -33,7 +33,7 @@ def get_host_view_tab(sclnt, host_id, model):
).click()

webdriver_waituntil(sclnt, EC.visibility_of_element_located((By.ID, dt_name)))
dt_rendered(sclnt, dt_name, model.comment)
dt_rendered(sclnt, dt_name, getattr(model, wait_attr_value))


def test_host_list_route(live_server, sl_operator, host): # pylint: disable=unused-argument
Expand Down Expand Up @@ -323,3 +323,17 @@ def test_host_view_route_notes_list_freetag(live_server, sl_operator, notes_mult
sl_operator.execute_script("window.sessionStorage.setItem('dt_toolboxes_visible', '\"true\"');")
get_host_view_tab(sl_operator, notes_multiaction[0].host_id, notes_multiaction[-1])
check_dt_toolbox_freetag(sl_operator, 'storage.host_view_route', 'host_view_note_table', Note, load_route=False)


def test_host_view_route_versioninfos_list(live_server, sl_operator, versioninfos): # pylint: disable=unused-argument
"""host view tabbed versioninfo"""

test_versioninfo = versioninfos[0]
get_host_view_tab(sl_operator, test_vinfo.host_id, test_versioninfo, 'product')


def test_host_view_route_vulnsearch_list(live_server, sl_operator, vulnsearch): # pylint: disable=unused-argument
"""host view tabbed vulnsearch"""

test_vulnsearch = versioninfos[0]
get_host_view_tab(sl_operator, test_vulnsearch.host_id, test_vulnsearch, 'cveid')
4 changes: 2 additions & 2 deletions tests/server/api/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -341,14 +341,14 @@ def test_v2_public_storage_notelist_route(api_user, note_factory):
assert response.status_code == HTTPStatus.BAD_REQUEST


def test_v2_public_storage_versioninfo_route_nonetworks(api_user_nonetworks, versioninfo): # pylint: disable=unused-argument
def test_v2_public_storage_versioninfo_route_nonetworks(api_user_nonetworks, versioninfos): # pylint: disable=unused-argument
"""test queries with user without any configured networks"""

response = api_user_nonetworks.post_json(url_for('api.v2_public_storage_versioninfo_route'))
assert not response.json


def test_v2_public_storage_versioninfo_route(api_user, versioninfo): # pylint: disable=unused-argument
def test_v2_public_storage_versioninfo_route(api_user, versioninfos): # pylint: disable=unused-argument
"""test public versioninfo query api"""

response = api_user.post_json(url_for('api.v2_public_storage_versioninfo_route'))
Expand Down
4 changes: 2 additions & 2 deletions tests/server/storage/views/test_versioninfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ def test_versioninfo_list_route(cl_operator):
assert response.status_code == HTTPStatus.OK


def test_versioninfo_list_json_route(cl_operator, versioninfo):
def test_versioninfo_list_json_route(cl_operator, versioninfos):
"""versioninfo list_json route test"""

expected_product = json.loads(versioninfo[0].data)["product"].lower()
expected_product = versioninfos[0].product

response = cl_operator.post(
url_for('storage.versioninfo_list_json_route'),
Expand Down
2 changes: 1 addition & 1 deletion tests/server/storage/views/test_vulnsearch.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def test_vulnsearch_list_route(cl_operator):
def test_vulnsearch_list_json_route(cl_operator, vulnsearch):
"""vulnsearch list_json route test"""

expected_cveid = vulnsearch.cveid
expected_cveid = vulnsearch[0].cveid

response = cl_operator.post(
url_for('storage.vulnsearch_list_json_route'),
Expand Down

0 comments on commit 7926d8d

Please sign in to comment.