Merge branch 'dev' into feature/2706-Terminal_Sim_Component
This commit is contained in:
@@ -53,3 +53,30 @@ The number of time steps required to occur in order for the node to cycle from `
|
||||
Optional. Default value is ``3``.
|
||||
|
||||
The number of time steps required to occur in order for the node to cycle from ``ON`` to ``SHUTTING_DOWN`` and then finally ``OFF``.
|
||||
|
||||
``users``
|
||||
---------
|
||||
|
||||
The list of pre-existing users that are additional to the default admin user (``username=admin``, ``password=admin``).
|
||||
Additional users are configured as an array nd must contain a ``username``, ``password``, and can contain an optional
|
||||
boolean ``is_admin``.
|
||||
|
||||
Example of adding two additional users to a node:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
simulation:
|
||||
network:
|
||||
nodes:
|
||||
- hostname: client_1
|
||||
type: computer
|
||||
ip_address: 192.168.10.11
|
||||
subnet_mask: 255.255.255.0
|
||||
default_gateway: 192.168.10.1
|
||||
users:
|
||||
- username: jane.doe
|
||||
password: '1234'
|
||||
is_admin: true
|
||||
- username: john.doe
|
||||
password: password_1
|
||||
is_admin: false
|
||||
|
||||
@@ -97,8 +97,8 @@ Node Behaviours/Functions
|
||||
- **receive_frame()**: Handles the processing of incoming network frames.
|
||||
- **apply_timestep()**: Advances the state of the node according to the simulation timestep.
|
||||
- **power_on()**: Initiates the node, enabling all connected Network Interfaces and starting all Services and
|
||||
Applications, taking into account the `start_up_duration`.
|
||||
- **power_off()**: Stops the node's operations, adhering to the `shut_down_duration`.
|
||||
Applications, taking into account the ``start_up_duration``.
|
||||
- **power_off()**: Stops the node's operations, adhering to the ``shut_down_duration``.
|
||||
- **ping()**: Sends ICMP echo requests to a specified IP address to test connectivity.
|
||||
- **has_enabled_network_interface()**: Checks if the node has any network interfaces enabled, facilitating network
|
||||
communication.
|
||||
@@ -109,3 +109,205 @@ Node Behaviours/Functions
|
||||
The Node class handles installation of system software, network connectivity, frame processing, system logging, and
|
||||
power states. It establishes baseline functionality while allowing subclassing to model specific node types like hosts,
|
||||
routers, firewalls etc. The flexible architecture enables composing complex network topologies.
|
||||
|
||||
User, UserManager, and UserSessionManager
|
||||
=========================================
|
||||
|
||||
The ``base.py`` module also includes essential classes for managing users and their sessions within the PrimAITE
|
||||
simulation. These are the ``User``, ``UserManager``, and ``UserSessionManager`` classes. The base ``Node`` class comes
|
||||
with ``UserManager``, and ``UserSessionManager`` classes pre-installed.
|
||||
|
||||
User Class
|
||||
----------
|
||||
|
||||
The ``User`` class represents a user in the system. It includes attributes such as ``username``, ``password``,
|
||||
``disabled``, and ``is_admin`` to define the user's credentials and status.
|
||||
|
||||
Example Usage
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
Creating a user:
|
||||
.. code-block:: python
|
||||
|
||||
user = User(username="john_doe", password="12345")
|
||||
|
||||
UserManager Class
|
||||
-----------------
|
||||
|
||||
The ``UserManager`` class handles user management tasks such as creating users, authenticating them, changing passwords,
|
||||
and enabling or disabling user accounts. It maintains a dictionary of users and provides methods to manage them
|
||||
effectively.
|
||||
|
||||
Example Usage
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
Creating a ``UserManager`` instance and adding a user:
|
||||
.. code-block:: python
|
||||
|
||||
user_manager = UserManager()
|
||||
user_manager.add_user(username="john_doe", password="12345")
|
||||
|
||||
Authenticating a user:
|
||||
.. code-block:: python
|
||||
|
||||
user = user_manager.authenticate_user(username="john_doe", password="12345")
|
||||
|
||||
UserSessionManager Class
|
||||
------------------------
|
||||
|
||||
The ``UserSessionManager`` class manages user sessions, including local and remote sessions. It handles session creation,
|
||||
timeouts, and provides methods for logging users in and out.
|
||||
|
||||
Example Usage
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
Creating a ``UserSessionManager`` instance and logging a user in locally:
|
||||
.. code-block:: python
|
||||
|
||||
session_manager = UserSessionManager()
|
||||
session_id = session_manager.local_login(username="john_doe", password="12345")
|
||||
|
||||
Logging a user out:
|
||||
.. code-block:: python
|
||||
|
||||
session_manager.local_logout()
|
||||
|
||||
Practical Examples
|
||||
------------------
|
||||
|
||||
Below are unit tests which act as practical examples illustrating how to use the ``User``, ``UserManager``, and
|
||||
``UserSessionManager`` classes within the context of a client-server network simulation.
|
||||
|
||||
Setting up a Client-Server Network
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from typing import Tuple
|
||||
from uuid import uuid4
|
||||
|
||||
import pytest
|
||||
|
||||
from primaite.simulator.network.container import Network
|
||||
from primaite.simulator.network.hardware.nodes.host.computer import Computer
|
||||
from primaite.simulator.network.hardware.nodes.host.server import Server
|
||||
|
||||
@pytest.fixture(scope="function")
|
||||
def client_server_network() -> Tuple[Computer, Server, Network]:
|
||||
network = Network()
|
||||
|
||||
client = Computer(
|
||||
hostname="client",
|
||||
ip_address="192.168.1.2",
|
||||
subnet_mask="255.255.255.0",
|
||||
default_gateway="192.168.1.1",
|
||||
start_up_duration=0,
|
||||
)
|
||||
client.power_on()
|
||||
|
||||
server = Server(
|
||||
hostname="server",
|
||||
ip_address="192.168.1.3",
|
||||
subnet_mask="255.255.255.0",
|
||||
default_gateway="192.168.1.1",
|
||||
start_up_duration=0,
|
||||
)
|
||||
server.power_on()
|
||||
|
||||
network.connect(client.network_interface[1], server.network_interface[1])
|
||||
|
||||
return client, server, network
|
||||
|
||||
Local Login Success
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def test_local_login_success(client_server_network):
|
||||
client, server, network = client_server_network
|
||||
|
||||
assert not client.user_session_manager.local_user_logged_in
|
||||
|
||||
client.user_session_manager.local_login(username="admin", password="admin")
|
||||
|
||||
assert client.user_session_manager.local_user_logged_in
|
||||
|
||||
Local Login Failure
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def test_local_login_failure(client_server_network):
|
||||
client, server, network = client_server_network
|
||||
|
||||
assert not client.user_session_manager.local_user_logged_in
|
||||
|
||||
client.user_session_manager.local_login(username="jane.doe", password="12345")
|
||||
|
||||
assert not client.user_session_manager.local_user_logged_in
|
||||
|
||||
Adding a New User and Successful Local Login
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def test_new_user_local_login_success(client_server_network):
|
||||
client, server, network = client_server_network
|
||||
|
||||
assert not client.user_session_manager.local_user_logged_in
|
||||
|
||||
client.user_manager.add_user(username="jane.doe", password="12345")
|
||||
|
||||
client.user_session_manager.local_login(username="jane.doe", password="12345")
|
||||
|
||||
assert client.user_session_manager.local_user_logged_in
|
||||
|
||||
Clearing Previous Login on New Local Login
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def test_new_local_login_clears_previous_login(client_server_network):
|
||||
client, server, network = client_server_network
|
||||
|
||||
assert not client.user_session_manager.local_user_logged_in
|
||||
|
||||
current_session_id = client.user_session_manager.local_login(username="admin", password="admin")
|
||||
|
||||
assert client.user_session_manager.local_user_logged_in
|
||||
|
||||
assert client.user_session_manager.local_session.user.username == "admin"
|
||||
|
||||
client.user_manager.add_user(username="jane.doe", password="12345")
|
||||
|
||||
new_session_id = client.user_session_manager.local_login(username="jane.doe", password="12345")
|
||||
|
||||
assert client.user_session_manager.local_user_logged_in
|
||||
|
||||
assert client.user_session_manager.local_session.user.username == "jane.doe"
|
||||
|
||||
assert new_session_id != current_session_id
|
||||
|
||||
Persistent Login for the Same User
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def test_new_local_login_attempt_same_uses_persists(client_server_network):
|
||||
client, server, network = client_server_network
|
||||
|
||||
assert not client.user_session_manager.local_user_logged_in
|
||||
|
||||
current_session_id = client.user_session_manager.local_login(username="admin", password="admin")
|
||||
|
||||
assert client.user_session_manager.local_user_logged_in
|
||||
|
||||
assert client.user_session_manager.local_session.user.username == "admin"
|
||||
|
||||
new_session_id = client.user_session_manager.local_login(username="admin", password="admin")
|
||||
|
||||
assert client.user_session_manager.local_user_logged_in
|
||||
|
||||
assert client.user_session_manager.local_session.user.username == "admin"
|
||||
|
||||
assert new_session_id == current_session_id
|
||||
|
||||
Reference in New Issue
Block a user