Merged PR 306: Fix issues with check_hash function.
## Summary The current implementation of check_hash() as triggered by NODE_FILE_CHECKHASH and NODE_FOLDER_CHECKHASH is incorrect. However, a correct implementation is a future task so the code is disabled and a deprecation warning has been added. ## Test process Disabled tests that exercise check_hash() functionality. Added tests to show that deprecation warning is present. ## Checklist - [X ] PR is linked to a **work item** - [X] **acceptance criteria** of linked ticket are met - [X] performed **self-review** of the code - [X] written **tests** for any new functionality added with this PR - [X] updated the **documentation** if this PR changes or adds functionality - [ ] written/updated **design docs** if this PR implements new functionality - [X] updated the **change log** - [X] ran **pre-commit** checks for code style - [ ] attended to any **TO-DOs** left in the code 2299: Remove calls to corrupt. Related work items: #2299
This commit is contained in:
@@ -52,7 +52,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Order of service health state
|
- Order of service health state
|
||||||
- Starting a node didn't start the services on it
|
- Starting a node didn't start the services on it
|
||||||
- Fixed an issue where the services were still able to run even though the node the service is installed on is turned off
|
- Fixed an issue where the services were still able to run even though the node the service is installed on is turned off
|
||||||
|
- The use of NODE_FILE_CHECKHASH and NODE_FOLDER_CHECKHASH in the current release is marked as 'Not Implemented'.
|
||||||
|
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
@@ -313,7 +313,7 @@ agents:
|
|||||||
folder_id: 0
|
folder_id: 0
|
||||||
file_id: 0
|
file_id: 0
|
||||||
10:
|
10:
|
||||||
action: "NODE_FILE_SCAN" # CHECKHASH replaced by SCAN - but the behaviour is the same in this context.
|
action: "NODE_FILE_CHECKHASH" # CHECKHASH replaced by SCAN - but the behaviour is the same in this context.
|
||||||
options:
|
options:
|
||||||
node_id: 2
|
node_id: 2
|
||||||
folder_id: 0
|
folder_id: 0
|
||||||
@@ -341,7 +341,7 @@ agents:
|
|||||||
node_id: 2
|
node_id: 2
|
||||||
folder_id: 0
|
folder_id: 0
|
||||||
15:
|
15:
|
||||||
action: "NODE_FOLDER_SCAN" # CHECKHASH replaced by SCAN - but the behaviour is the same in this context.
|
action: "NODE_FOLDER_CHECKHASH" # CHECKHASH replaced by SCAN - but the behaviour is the same in this context.
|
||||||
options:
|
options:
|
||||||
node_id: 2
|
node_id: 2
|
||||||
folder_id: 0
|
folder_id: 0
|
||||||
|
|||||||
@@ -477,7 +477,8 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"obs, reward, terminated, truncated, info = env.step(9) # scan database file\n",
|
"obs, reward, terminated, truncated, info = env.step(9) # scan database file\n",
|
||||||
"obs, reward, terminated, truncated, info = env.step(1) # scan webapp service\n",
|
"obs, reward, terminated, truncated, info = env.step(1) # scan webapp service\n",
|
||||||
"pprint(obs['NODES'])"
|
"\n",
|
||||||
|
"pprint(obs['NODES'])\n"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -492,7 +493,7 @@
|
|||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"Also, the NMNE outbound of either client 1 (node 6) or client 2 (node 7) increased from 0 to 1, but only right after the red attack, so we probably cannot see it now."
|
"Also, the NMNE outbound of either client 1 (node 6) or client 2 (node 7) has increased from 0 to 1. This tells us which client is being used by the red agent."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -647,7 +648,6 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"\n",
|
|
||||||
"for step in range(40):\n",
|
"for step in range(40):\n",
|
||||||
" obs, reward, terminated, truncated, info = env.step(0) # do nothing\n",
|
" obs, reward, terminated, truncated, info = env.step(0) # do nothing\n",
|
||||||
" print(f\"step: {env.game.step_counter}, Red action: {info['agent_actions']['data_manipulation_attacker'].action}, Blue reward:{reward:.2f}\" )"
|
" print(f\"step: {env.game.step_counter}, Red action: {info['agent_actions']['data_manipulation_attacker'].action}, Blue reward:{reward:.2f}\" )"
|
||||||
@@ -668,13 +668,6 @@
|
|||||||
"source": [
|
"source": [
|
||||||
"env.reset()"
|
"env.reset()"
|
||||||
]
|
]
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": null,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": []
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"metadata": {
|
"metadata": {
|
||||||
@@ -693,7 +686,7 @@
|
|||||||
"name": "python",
|
"name": "python",
|
||||||
"nbconvert_exporter": "python",
|
"nbconvert_exporter": "python",
|
||||||
"pygments_lexer": "ipython3",
|
"pygments_lexer": "ipython3",
|
||||||
"version": "3.10.12"
|
"version": "3.10.11"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nbformat": 4,
|
"nbformat": 4,
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ from __future__ import annotations
|
|||||||
import hashlib
|
import hashlib
|
||||||
import json
|
import json
|
||||||
import os.path
|
import os.path
|
||||||
|
import warnings
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Dict, Optional
|
from typing import Dict, Optional
|
||||||
|
|
||||||
@@ -145,6 +146,10 @@ class File(FileSystemItemABC):
|
|||||||
|
|
||||||
Return False if corruption is detected, otherwise True
|
Return False if corruption is detected, otherwise True
|
||||||
"""
|
"""
|
||||||
|
warnings.warn("NODE_FILE_CHECKHASH is currently not implemented.")
|
||||||
|
self.sys_log.warning("NODE_FILE_CHECKHASH is currently not implemented.")
|
||||||
|
return False
|
||||||
|
|
||||||
if self.deleted:
|
if self.deleted:
|
||||||
self.sys_log.error(f"Unable to check hash of deleted file {self.folder_name}/{self.name}")
|
self.sys_log.error(f"Unable to check hash of deleted file {self.folder_name}/{self.name}")
|
||||||
return False
|
return False
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ class FileSystemItemABC(SimComponent):
|
|||||||
@abstractmethod
|
@abstractmethod
|
||||||
def check_hash(self) -> bool:
|
def check_hash(self) -> bool:
|
||||||
"""
|
"""
|
||||||
Checks the has of the file to detect any changes.
|
Checks the hash of the file to detect any changes.
|
||||||
|
|
||||||
For current implementation, any change in file hash means it is compromised.
|
For current implementation, any change in file hash means it is compromised.
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import warnings
|
||||||
from typing import Dict, Optional
|
from typing import Dict, Optional
|
||||||
|
|
||||||
from prettytable import MARKDOWN, PrettyTable
|
from prettytable import MARKDOWN, PrettyTable
|
||||||
@@ -380,6 +381,10 @@ class Folder(FileSystemItemABC):
|
|||||||
|
|
||||||
Return False if corruption is detected, otherwise True
|
Return False if corruption is detected, otherwise True
|
||||||
"""
|
"""
|
||||||
|
warnings.warn("NODE_FOLDER_CHECKHASH is currently not implemented.")
|
||||||
|
self.sys_log.error("NODE_FOLDER_CHECKHASH is currently not implemented.")
|
||||||
|
return False
|
||||||
|
|
||||||
if self.deleted:
|
if self.deleted:
|
||||||
self.sys_log.error(f"Unable to check hash of deleted folder {self.name}")
|
self.sys_log.error(f"Unable to check hash of deleted folder {self.name}")
|
||||||
return False
|
return False
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
import warnings
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
from primaite.simulator.file_system.file import File
|
from primaite.simulator.file_system.file import File
|
||||||
from primaite.simulator.file_system.file_system_item_abc import FileSystemItemHealthStatus
|
from primaite.simulator.file_system.file_system_item_abc import FileSystemItemHealthStatus
|
||||||
from primaite.simulator.file_system.file_type import FileType
|
from primaite.simulator.file_system.file_type import FileType
|
||||||
@@ -41,6 +45,7 @@ def test_file_reveal_to_red_scan(file_system):
|
|||||||
assert file.revealed_to_red is True
|
assert file.revealed_to_red is True
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.skip(reason="NODE_FILE_CHECKHASH not implemented")
|
||||||
def test_simulated_file_check_hash(file_system):
|
def test_simulated_file_check_hash(file_system):
|
||||||
file: File = file_system.create_file(file_name="test_file.txt", folder_name="test_folder")
|
file: File = file_system.create_file(file_name="test_file.txt", folder_name="test_folder")
|
||||||
|
|
||||||
@@ -52,6 +57,7 @@ def test_simulated_file_check_hash(file_system):
|
|||||||
assert file.health_status == FileSystemItemHealthStatus.CORRUPT
|
assert file.health_status == FileSystemItemHealthStatus.CORRUPT
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.skip(reason="NODE_FILE_CHECKHASH not implemented")
|
||||||
def test_real_file_check_hash(file_system):
|
def test_real_file_check_hash(file_system):
|
||||||
file: File = file_system.create_file(file_name="test_file.txt", real=True)
|
file: File = file_system.create_file(file_name="test_file.txt", real=True)
|
||||||
|
|
||||||
@@ -80,3 +86,14 @@ def test_file_corrupt_repair_restore(file_system):
|
|||||||
|
|
||||||
file.restore()
|
file.restore()
|
||||||
assert file.health_status == FileSystemItemHealthStatus.GOOD
|
assert file.health_status == FileSystemItemHealthStatus.GOOD
|
||||||
|
|
||||||
|
|
||||||
|
def test_file_warning_triggered(file_system):
|
||||||
|
file: File = file_system.create_file(file_name="test_file.txt", folder_name="test_folder")
|
||||||
|
|
||||||
|
with warnings.catch_warnings(record=True) as w:
|
||||||
|
warnings.simplefilter("always")
|
||||||
|
file.check_hash()
|
||||||
|
# Check warning issued
|
||||||
|
assert len(w) == 1
|
||||||
|
assert "not implemented" in str(w[-1].message)
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ def test_file_scan_request(populated_file_system):
|
|||||||
assert file.visible_health_status == FileSystemItemHealthStatus.CORRUPT
|
assert file.visible_health_status == FileSystemItemHealthStatus.CORRUPT
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.skip(reason="NODE_FILE_CHECKHASH not implemented")
|
||||||
def test_file_checkhash_request(populated_file_system):
|
def test_file_checkhash_request(populated_file_system):
|
||||||
"""Test that an agent can request a file hash check."""
|
"""Test that an agent can request a file hash check."""
|
||||||
fs, folder, file = populated_file_system
|
fs, folder, file = populated_file_system
|
||||||
|
|||||||
@@ -119,6 +119,7 @@ def test_folder_corrupt_repair(file_system):
|
|||||||
assert file.health_status == FileSystemItemHealthStatus.GOOD
|
assert file.health_status == FileSystemItemHealthStatus.GOOD
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.skip(reason="NODE_FILE_CHECKHASH not implemented")
|
||||||
def test_simulated_folder_check_hash(file_system):
|
def test_simulated_folder_check_hash(file_system):
|
||||||
folder: Folder = file_system.create_folder(folder_name="test_folder")
|
folder: Folder = file_system.create_folder(folder_name="test_folder")
|
||||||
file_system.create_file(file_name="test_file.txt", folder_name="test_folder")
|
file_system.create_file(file_name="test_file.txt", folder_name="test_folder")
|
||||||
@@ -133,6 +134,7 @@ def test_simulated_folder_check_hash(file_system):
|
|||||||
assert folder.health_status == FileSystemItemHealthStatus.CORRUPT
|
assert folder.health_status == FileSystemItemHealthStatus.CORRUPT
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.skip(reason="NODE_FILE_CHECKHASH not implemented")
|
||||||
def test_real_folder_check_hash(file_system):
|
def test_real_folder_check_hash(file_system):
|
||||||
folder: Folder = file_system.create_folder(folder_name="test_folder")
|
folder: Folder = file_system.create_folder(folder_name="test_folder")
|
||||||
file_system.create_file(file_name="test_file.txt", folder_name="test_folder", real=True)
|
file_system.create_file(file_name="test_file.txt", folder_name="test_folder", real=True)
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import warnings
|
||||||
from typing import Tuple
|
from typing import Tuple
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
@@ -49,6 +50,7 @@ def test_folder_scan_request(populated_file_system):
|
|||||||
assert file2.visible_health_status == FileSystemItemHealthStatus.CORRUPT
|
assert file2.visible_health_status == FileSystemItemHealthStatus.CORRUPT
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.skip(reason="NODE_FOLDER_CHECKHASH not implemented")
|
||||||
def test_folder_checkhash_request(populated_file_system):
|
def test_folder_checkhash_request(populated_file_system):
|
||||||
"""Test that an agent can request a folder hash check."""
|
"""Test that an agent can request a folder hash check."""
|
||||||
fs, folder, file = populated_file_system
|
fs, folder, file = populated_file_system
|
||||||
@@ -62,6 +64,16 @@ def test_folder_checkhash_request(populated_file_system):
|
|||||||
assert folder.health_status == FileSystemItemHealthStatus.CORRUPT
|
assert folder.health_status == FileSystemItemHealthStatus.CORRUPT
|
||||||
|
|
||||||
|
|
||||||
|
def test_folder_warning_triggered(populated_file_system):
|
||||||
|
fs, folder, _ = populated_file_system
|
||||||
|
with warnings.catch_warnings(record=True) as w:
|
||||||
|
warnings.simplefilter("always")
|
||||||
|
fs.apply_request(request=["folder", folder.name, "checkhash"])
|
||||||
|
# Check warning issued
|
||||||
|
assert len(w) == 1
|
||||||
|
assert "not implemented" in str(w[-1].message)
|
||||||
|
|
||||||
|
|
||||||
def test_folder_repair_request(populated_file_system):
|
def test_folder_repair_request(populated_file_system):
|
||||||
"""Test that an agent can request a folder repair."""
|
"""Test that an agent can request a folder repair."""
|
||||||
fs, folder, file = populated_file_system
|
fs, folder, file = populated_file_system
|
||||||
|
|||||||
Reference in New Issue
Block a user