14 Commits
Author SHA1 Message Date
agessaman bf70594b41 fix: close the '*'-only flood_scopes bypass and schedule write race
A flood_scopes of "*" alone leaves scope_keys empty while setting
flood_scope_allow_global, and the loader already logs that as an active
allowlist. The handler gated on scope_keys alone, so that configuration
skipped authorisation entirely and admitted absent, uncorrelated and
TRANSPORT_FLOOD traffic. The gate now fires when either is set, so "*"
means global-only rather than everything.

The scheduled-message duplicate check ran outside the write lock inside
update_ini_values, so two concurrent creates for the same schedule could
both pass and the second silently replace the first instead of getting
the 409. Check and write are now one critical section, and delete is too.
Repaired the delete path's error handling while moving it, so an OSError
during the write is still a 500 rather than escaping.
2026-08-22 01:06:08 -07:00
agessaman 4f6287788b fix(path): never attribute an uncorrelated packet's route (#80)
find_recent_rf_data has four strategies, and the fourth returns the most
recent packet in the cache when the first three fail to correlate. That
fallback exists for SNR/RSSI timing issues, but callers were also taking
its route. So when correlation missed, a message was recorded with some
other transmission's path and hop count — the reporter's four-hop message
stored as a single direct hop via 79, which is the last hop of an
unrelated packet. Rare, because it only fires when correlation fails.

Results are now tagged with how they were matched (exact, pubkey, partial
or fallback) and rf_data_is_correlated() gates the route. The tag rides on
a shallow copy so the cache entry is never marked, and it fails closed: an
untagged dict is treated as uncorrelated.

Guarded in both handlers. The DM path was worse than the channel one — it
falls back to find_recent_rf_data() with no correlation key at all, which
can only ever return a fallback, and then overwrote message.path and
message.routing_info from it. routing_info is what the path command reads,
so a wrong route reached the user directly.

The route is now left unresolved rather than fabricated, which also stops
a bogus edge being written to the mesh graph from path_nodes that belong
to a different packet. SNR and RSSI still use the fallback as before;
mis-correlated signal figures are approximate rather than structurally
wrong, and changing them is a separate call.

Existing tests asserted the returned dict was the cache entry itself.
Identity was incidental, so they now compare contents and additionally
assert the provenance tag.
2026-08-21 22:45:05 -07:00
Felix Moessbauer ee57b35204 style: make test_rf_scope_correlation compliant with ruff 0.15
This restores the style check in CI, which currently fails on all
commits.

Fixes: cb54ca6 ("fix(config): clarify flood scope configuration ...")
2026-05-20 11:41:03 +02:00
agessaman cb54ca6a45 fix(config): clarify flood scope configuration and logging behavior
- Updated `config.ini.example` and `configuration.md` to enhance clarity on the `outgoing_flood_scope_override` and `flood_scopes` settings, detailing their behavior and interactions.
- Improved logging in `CommandManager` to provide better insights into scope resolution and potential issues during message sending.
- Added new methods in `MessageHandler` for improved RF data correlation, ensuring eligibility checks for flood scope matching.
- Enhanced unit tests to cover new behaviors and ensure robust handling of flood scope configurations.
2026-05-17 14:38:47 -07:00
agessaman 74b7de6f72 feat(flood_scope): enhance flood scope handling across services
- Introduced optional regional TC_FLOOD scope configuration for various services, allowing for more granular control over message routing.
- Updated the CommandManager to resolve and apply flood scopes from messages, configuration sections, and explicit parameters, ensuring correct message delivery.
- Enhanced service plugins to utilize the new flood scope functionality, including weather, earthquake, and webhook services.
- Added unit tests to verify the correct resolution and application of flood scopes in different scenarios, ensuring robust functionality.
2026-05-16 12:08:24 -07:00
agessaman 5879838d8b feat(command_manager): Fix flood scope on keyword and RandomLine channel replies
Route process_message keyword/RandomLine sends through send_response so
reply_scope reaches set_flood_scope; add optional command_id to
send_response for transmission tracking.
2026-05-10 19:20:22 -07:00
agessaman 313dfccf75 fix: Align send suppression and security compatibility behavior
Make outbound send suppression consistent by honoring both radio-offline and zombie states across command-manager and scheduler paths. Preserve strict SSRF defaults while adding explicit private-feed URL opt-ins, persist allow_local_smtp from notifications config writes, reconcile zombie alert setting precedence, and replace deprecated UTC timestamp calls with timezone-aware UTC usage.
2026-04-14 12:18:02 -07:00
Stacy Olivasandagessaman c7fa0ba3d2 fix: resolve ruff F401 violations in command_manager and upstream test files
- Add noqa: F401 to PUBLIC_CHANNEL_KEY_HEX import (re-exported for core.py)
- Remove unused `call` import from test_flood_scope_reply.py
- Remove unused `asyncio` import from test_log_data_scope_fields.py
- Remove unused `patch` and `validate_config` imports from
  test_public_channel_guard.py; fix import sort order
2026-04-14 10:01:51 -07:00
Stacy Olivasandagessaman 68fb1ef080 fix: stub is_radio_zombie in flood scope test mock
The send_channel_message test was leaving bot.is_radio_zombie as an
unset MagicMock attribute, which evaluates truthy and triggers the
zombie-state early return before flood scope logic runs.

Add bot.is_radio_zombie = False to the mock setup so the function
reaches the set_flood_scope call as intended.
2026-04-14 10:01:51 -07:00
agessaman 2ac1722014 Refactor flood scope configuration and enhance message handling
- Updated `config.ini.example` to clarify the usage of `outgoing_flood_scope_override` and `flood_scopes`, providing examples for better understanding.
- Modified `configuration.md` to reflect changes in flood scope handling, emphasizing the distinction between `outgoing_flood_scope_override` and `flood_scopes`.
- Refactored `CommandManager` to utilize the new `outgoing_flood_scope_override` for sending messages, ensuring consistent scope handling.
- Enhanced `MessageHandler` to prioritize library-provided scope fields for improved accuracy in flood scope matching.
- Added tests to validate the handling of flood scope fields from library payloads, ensuring robustness in message processing.
2026-04-10 16:29:52 -07:00
Adam Gessaman 4f820ffbd4 Enhance flood scope handling and channel fetching logic
- Updated `config.ini.example` to clarify flood scope configuration, introducing the auto-hashtag format for region names and adding support for multi-scope replies.
- Refactored `ChannelManager` to improve handling of empty channels, adjusting timeout logic and increasing request delay to prevent overwhelming devices.
- Enhanced `CommandManager` to load flood scope keys for HMAC matching and normalize scope names for consistency.
- Implemented scope matching in `MessageHandler` to ensure replies respect configured flood scopes, improving message routing accuracy.
- Updated `MeshMessage` model to include a `reply_scope` attribute for tracking matched flood scopes.
2026-04-08 21:14:04 -07:00
Stacy Olivas ae57e651ea test: expanded test suite for v0.9.0 modules
Command tests:
- tests/commands/: test_base_command, test_cmd_command, test_dice_command,
  test_hello_command, test_help_command, test_magic8_command,
  test_ping_command, test_roll_command
- tests/test_bridge_bot_responses, test_channel_manager_logic,
  test_checkin_service, test_command_manager, test_command_prefix,
  test_config_merge, test_config_validation, test_db_manager,
  test_plugin_loader, test_profanity_filter, test_security_utils,
  test_service_plugin_loader, test_utils

Integration and unit:
- tests/integration/: test_path_graph_integration, test_path_resolution
- tests/regression/: test_keyword_escapes
- tests/unit/: test_mesh_graph, test_mesh_graph_edges,
  test_mesh_graph_multihop, test_mesh_graph_optimizations,
  test_mesh_graph_scoring, test_mesh_graph_validation,
  test_path_command_graph, test_path_command_graph_selection,
  test_path_command_multibyte

Helpers: tests/conftest.py, tests/helpers.py
2026-03-17 18:07:18 -07:00
agessaman 217d2a4089 Refactor database connection handling across multiple modules
- Replaced direct SQLite connection calls with a context manager in various modules to ensure proper resource management and prevent file descriptor leaks.
- Introduced a new `connection` method in `DBManager` to standardize connection handling.
- Updated all relevant database interactions in modules such as `feed_manager`, `scheduler`, `commands`, and others to utilize the new connection method.
- Improved code readability and maintainability by consolidating connection logic.
2026-03-01 14:12:22 -08:00
agessaman d699ea1cf1 Update configuration handling and validation for bot sections
- Enhanced .gitignore to allow test files in the tests/ directory and committed pytest.ini for test discovery.
- Added checks for missing sections in configuration files, specifically for Admin_ACL and Banned_Users, to prevent errors during bot startup.
- Updated generate_website.py and command_manager.py to handle cases where required sections are absent, returning empty lists instead of raising exceptions.
- Introduced optional dependencies for testing in pyproject.toml, ensuring a smoother development experience.
- Improved localization handling in core.py to default to English when the Localization section is missing, enhancing user experience.
2026-02-12 19:23:35 -08:00