diff --git a/src/helperFunctions/web_interface.py b/src/helperFunctions/web_interface.py index caffb78a7..fd69a0d0f 100644 --- a/src/helperFunctions/web_interface.py +++ b/src/helperFunctions/web_interface.py @@ -3,10 +3,12 @@ import os import re +from flask_security.core import AnonymousUser from common_helper_files import get_binary_from_file from itertools import chain from helperFunctions.fileSystem import get_template_dir +from web_interface.security.privileges import PRIVILEGES SPECIAL_CHARACTERS = 'ÄäÀàÁáÂâÃãÅåǍǎĄąĂăÆæĀāÇçĆćĈĉČčĎđĐďðÈèÉéÊêËëĚěĘęĖėĒēĜĝĢģĞğĤĥÌìÍíÎîÏïıĪīĮįĴĵĶķĹĺĻļŁłĽľÑñŃńŇňŅņÖöÒòÓóÔôÕõŐőØøŒœŔŕŘřẞߌśŜŝŞşŠšȘș' \ @@ -77,3 +79,11 @@ def __exit__(self, *args): def get_template_as_string(view_name): path = os.path.join(get_template_dir(), view_name) return get_binary_from_file(path).decode('utf-8') + + +def _auth_is_disabled(user): + return isinstance(user._get_current_object(), AnonymousUser) + + +def user_has_privilege(user, privilege='delete'): + return _auth_is_disabled(user) or any(user.has_role(role) for role in PRIVILEGES[privilege]) diff --git a/src/test/acceptance/test_analyze_firmware.py b/src/test/acceptance/test_analyze_firmware.py index cda9e14de..947a93768 100644 --- a/src/test/acceptance/test_analyze_firmware.py +++ b/src/test/acceptance/test_analyze_firmware.py @@ -77,6 +77,7 @@ def _show_analysis_page(self): self.assertIn(b'test_vendor', rv.data) self.assertIn(b'unknown', rv.data) self.assertIn(self.test_fw_a.file_name.encode(), rv.data, 'file name not found') + self.assertIn(b'admin options:', rv.data, 'admin options not shown with disabled auth') def _check_ajax_file_tree_routes(self): rv = self.test_client.get('/ajax_tree/{}/{}'.format(self.test_fw_a.uid, self.test_fw_a.uid)) diff --git a/src/test/unit/helperFunctions/test_web_interface.py b/src/test/unit/helperFunctions/test_web_interface.py index 0edc4e018..a7d6aa956 100644 --- a/src/test/unit/helperFunctions/test_web_interface.py +++ b/src/test/unit/helperFunctions/test_web_interface.py @@ -1,13 +1,42 @@ -import unittest +# -*- coding: utf-8 -*- +import pytest -from helperFunctions.web_interface import filter_out_illegal_characters +from flask_security.core import AnonymousUser, UserMixin, RoleMixin +from werkzeug.local import LocalProxy +from helperFunctions.web_interface import filter_out_illegal_characters, user_has_privilege -class TestHelperFunctionsWebInterface(unittest.TestCase): - def test_filter_out_illegal_characters(self): - self.assertEqual(filter_out_illegal_characters(''), '') - self.assertEqual(filter_out_illegal_characters('abc'), 'abc') - self.assertEqual(filter_out_illegal_characters('Größer 2'), 'Größer 2') - self.assertEqual(filter_out_illegal_characters('{"$test": ["test"]}'), 'test test') - self.assertEqual(filter_out_illegal_characters(None), None) +@pytest.mark.parametrize('input_data, expected', [ + ('', ''), + ('abc', 'abc'), + ('Größer 2', 'Größer 2'), + ('{"$test": ["test"]}', 'test test'), + (None, None) +]) +def test_filter_out_illegal_characters(input_data, expected): + assert filter_out_illegal_characters(input_data) == expected + + +class role_superuser(RoleMixin): + name = 'superuser' + + +class superuser_user(UserMixin): + id = 1 + roles = [role_superuser] + + +class normal_user(UserMixin): + id = 2 + roles = [] + + +@pytest.mark.parametrize('input_data, expected', [ + (AnonymousUser, True), + (superuser_user, True), + (normal_user, False) +]) +def test_is_superuser(input_data, expected): + proxied_object = LocalProxy(input_data) + assert user_has_privilege(proxied_object) == expected diff --git a/src/web_interface/components/analysis_routes.py b/src/web_interface/components/analysis_routes.py index 2b1e5145a..8042ab834 100644 --- a/src/web_interface/components/analysis_routes.py +++ b/src/web_interface/components/analysis_routes.py @@ -5,12 +5,12 @@ from common_helper_files import get_binary_from_file from flask import render_template, request, render_template_string +from flask_login.utils import current_user from helperFunctions.dataConversion import none_to_none from helperFunctions.fileSystem import get_src_dir from helperFunctions.mongo_task_conversion import check_for_errors, convert_analysis_task_to_fw_obj, create_re_analyze_task -from helperFunctions.web_interface import ConnectTo, get_template_as_string -from helperFunctions.web_interface import overwrite_default_plugins +from helperFunctions.web_interface import ConnectTo, get_template_as_string, overwrite_default_plugins, user_has_privilege from intercom.front_end_binding import InterComFrontEndBinding from objects.firmware import Firmware from storage.db_interface_admin import AdminDbInterface @@ -78,7 +78,8 @@ def _show_analysis_results(self, uid, selected_analysis=None, root_uid=None): firmware_including_this_fo=firmware_including_this_fo, analysis_plugin_dict=analysis_plugins, other_versions=other_versions, - uids_for_comparison=uids_for_comparison) + uids_for_comparison=uids_for_comparison, + user_has_admin_clearance=user_has_privilege(current_user, privilege='delete')) else: return render_template('uid_not_found.html', uid=uid) diff --git a/src/web_interface/templates/show_analysis.html b/src/web_interface/templates/show_analysis.html index ae9eb77b2..987d526bf 100644 --- a/src/web_interface/templates/show_analysis.html +++ b/src/web_interface/templates/show_analysis.html @@ -407,7 +407,7 @@

Analysis for {{ firmware.get_hid(root_uid=root_ui {# admin buttons #} - {% if firmware.vendor %} + {% if firmware.vendor and user_has_admin_clearance %}
admin options: