Skip to content

Commit 18f5916

Browse files
committed
Improve Warning Logic Gate and Properly OUI backup logic enabled
1 parent d8d73f6 commit 18f5916

File tree

3 files changed

+61
-38
lines changed

3 files changed

+61
-38
lines changed

src/libinspector/common.py

Lines changed: 45 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,31 @@
2626
"- Metadata of your network traffic (e.g., which IPs/domains your devices communicate with) is shared anonymously with NYU researchers during the labeling stage."
2727
)
2828

29+
def remove_warning():
30+
"""
31+
Remove the warning acceptance state, forcing the user to see the warning again.
32+
"""
33+
config_set("suppress_warning", True)
34+
35+
36+
def reset_prolific_id():
37+
"""
38+
Clear the stored Prolific ID, forcing the user to re-enter it.
39+
"""
40+
config_set("prolific_id", "")
41+
42+
43+
def set_prolific_id(prolific_id: str):
44+
"""
45+
Store the provided Prolific ID in the configuration.
46+
47+
Args:
48+
prolific_id (str): The Prolific ID to store.
49+
"""
50+
if is_prolific_id_valid(prolific_id):
51+
config_set("prolific_id", prolific_id)
52+
53+
2954
def show_warning():
3055
"""
3156
Displays a warning message to the user about network monitoring and ARP spoofing.
@@ -36,28 +61,30 @@ def show_warning():
3661
False if the user has accepted the warning and can proceed.
3762
"""
3863
current_id = config_get("prolific_id", "")
64+
st.subheader("1. Prolific ID Confirmation")
65+
st.info(f"Your currently stored ID is: `{current_id}`")
66+
st.button("Change Prolific ID",
67+
on_click=reset_prolific_id,
68+
help="Clicking this will clear your stored ID and return you to the ID entry form.")
3969

4070
# --- GATE 1: PROLIFIC ID CHECK (Must be valid to proceed to confirmation) ---
4171
if is_prolific_id_valid(current_id):
42-
# --- SHOW CONFIRMATION UI (Only reached if ID is valid but warning is unaccepted) ---
43-
st.subheader("1. Prolific ID Confirmation")
44-
st.info(f"Your currently stored ID is: `{current_id}`")
45-
46-
# Allows the user to change the ID, which forces them back through GATE 1
47-
if st.button("Change Prolific ID", help="Clicking this will clear your stored ID and return you to the ID entry form."):
48-
config_set("prolific_id", "") # Clear the stored ID
49-
st.rerun()
50-
72+
# Check if the warning is NOT suppressed. If it's not suppressed, we show the UI
73+
# and MUST return True (Block execution) until the user clicks the button.
5174
if not config_get("suppress_warning", False):
5275
st.markdown("---")
5376
st.subheader("2. Network Monitoring Warning")
5477
st.markdown(warning_text)
5578

56-
if st.button("OK, I understand and wish to proceed", help="Clicking this confirms that you understand the warning and wish to proceed."):
57-
config_set("suppress_warning", True)
58-
st.rerun()
79+
st.button("OK, I understand and wish to proceed",
80+
on_click=remove_warning,
81+
help="Clicking this confirms that you understand the warning and wish to proceed.")
82+
83+
# Since the warning is displayed and unaccepted, we must block.
84+
return True
5985

60-
return not is_prolific_id_valid(config_get("prolific_id", ""))
86+
# If we reach here, ID is valid AND suppress_warning is True.
87+
return False
6188
else:
6289
# ID is missing or invalid -> BLOCK and show input form
6390
st.subheader("Prolific ID Required")
@@ -69,15 +96,10 @@ def show_warning():
6996
value="",
7097
key="prolific_id_input"
7198
).strip()
72-
73-
submitted = st.form_submit_button("Submit ID")
74-
if submitted:
75-
if is_prolific_id_valid(input_id):
76-
config_set("prolific_id", input_id)
77-
st.success("Prolific ID accepted. Please review the details below.")
78-
st.rerun() # Rerun to jump to the confirmation step (GATE 2)
79-
else:
80-
st.error("Invalid Prolific ID. Must be 1-50 alphanumeric characters.")
99+
st.form_submit_button("Submit ID",
100+
on_click=set_prolific_id,
101+
args=(input_id,),
102+
help="Submit your Prolific ID to proceed.")
81103

82104
return True # BLOCK: ID check still needs resolution.
83105

@@ -157,6 +179,7 @@ def plot_traffic_volume(df: pd.DataFrame, now: int, chart_title: str):
157179
df_reindexed = df_reindexed.sort_values(by='seconds_ago', ascending=False)
158180
st.bar_chart(df_reindexed.set_index('seconds_ago')['Bits'], width='content')
159181

182+
160183
def get_device_metadata(mac_address: str) -> dict:
161184
"""
162185
Retrieve the DHCP hostname and OUI vendor for a device from the database.

src/libinspector/device_list_page.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,25 +43,24 @@ def worker_thread():
4343
for device_dict in device_list:
4444
meta_data = common.get_device_metadata(device_dict['mac_address'])
4545
remote_hostnames = common.get_remote_hostnames(device_dict['mac_address'])
46+
custom_name_key = f"device_custom_name_{device_dict['mac_address']}"
4647
try:
4748
# Note I am passing the metadata as a string because functions with cache cannot take dicts
4849
# as a dict is mutable, and the cache would not work as expected.
4950
api_output = call_predict_api(json.dumps(meta_data), remote_hostnames, device_dict['mac_address'])
5051
common.config_set(f'device_details@{device_dict["mac_address"]}', api_output)
5152
if "Vendor" in api_output:
52-
# Update name based on API
53-
custom_name_key = f"device_custom_name_{device_dict['mac_address']}"
5453
custom_name = api_output["Vendor"]
5554
if api_output["Vendor"] != "":
5655
common.config_set(custom_name_key, custom_name)
57-
else:
58-
# If API is down, just try using OUI vendor
59-
common.config_set(custom_name_key, meta_data.get('oui_vendor', 'Unknown Device, likely a Mobile Phone'))
6056
except Exception as e:
6157
logger.info("[Device ID API] Exception when calling API: %s", str(e))
62-
continue
63-
64-
58+
finally:
59+
# If API is down, just try using OUI vendor if no custom name is set in config.json
60+
if common.config_get(custom_name_key, default='') == '':
61+
common.config_set(custom_name_key,
62+
meta_data.get('oui_vendor', 'Unknown Device, likely a Mobile Phone'))
63+
6564
@functools.cache
6665
def call_predict_api(meta_data_string: str, remote_hostnames: str,
6766
mac_address: str, url="https://dev-id-1.tailcedbd.ts.net/predict") -> dict:

src/libinspector/page_manager.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,7 @@ def _show_page_func_wrapper():
2828
st.query_params['pid'] = pid
2929

3030
initialize_page()
31-
3231
st.markdown(f"## {icon} {title}")
33-
3432
show_page_func()
3533

3634
return st.Page(
@@ -52,7 +50,7 @@ def initialize_page():
5250
menu_items={}
5351
)
5452

55-
# If true, block further execution
53+
initialize_config()
5654
if common.show_warning():
5755
st.stop()
5856

@@ -67,15 +65,18 @@ def initialize_page():
6765
start_inspector_once()
6866

6967

68+
@functools.lru_cache(maxsize=1)
69+
def initialize_config():
70+
"""Initialize certain Config variables when starting IoT Inspector."""
71+
common.config_set("suppress_warning", False)
72+
common.config_set("labeling_in_progress", False)
73+
common.config_set("api_message", "")
74+
75+
7076
@functools.lru_cache(maxsize=1)
7177
def start_inspector_once():
7278
"""Initialize the Inspector core only once."""
7379
with st.spinner("Starting Inspector Core Library..."):
74-
# Just in case someone closes labeling window without finishing
75-
# Same with the general warning
76-
common.config_set("suppress_warning", False)
77-
common.config_set("labeling_in_progress", False)
78-
common.config_set("api_message", "")
7980
libinspector.core.start_threads()
8081
api_thread = threading.Thread(
8182
name="Device API Thread",

0 commit comments

Comments
 (0)