Commit graph

32 commits

Author SHA1 Message Date
6aab59dcf5
refactor: centralize LiveView access control checks
Extract duplicate access control logic from multiple LiveView files into
a reusable AccessControl helper module.

**Changes:**
- NEW: lib/towerops_web/live/helpers/access_control.ex
- NEW: test/towerops_web/live/helpers/access_control_test.exs
- Refactor device_live/index.ex to use AccessControl.verify_site_access/2
  and verify_device_access/2
- Refactor device_live/form.ex to use AccessControl.verify_device_access/2
- Refactor alert_live/index.ex to use AccessControl.verify_alert_access/2
- Refactor device_live/show.ex to use AccessControl.verify_device_access/2
- Remove unused Repo aliases from refactored files

**Benefits:**
- Reduces code duplication across 7+ locations
- Centralizes security-critical access checks
- Improves testability (helper module has >90% coverage)
- Consistent error handling across all LiveViews

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-04 17:51:05 -06:00
4f936d5549
device edit fix 2026-02-04 16:28:15 -06:00
8382b5df6a
make devices site optional and many test fix 2026-02-04 15:05:42 -06:00
1a054fd598
make sites optional 2026-02-04 13:05:32 -06:00
c93144cc37
snmp v3 support 2026-02-04 12:02:38 -06:00
3583624e0d
fix: prevent nil boolean error in device edit page
Fixed production bug where visiting the edit page for a device with no
SNMP discovery data would crash with "expected boolean on left-side of
'and', got: nil" error.

The mikrotik_device?/1 function was using && operator which returns nil
when device.snmp_device is nil, instead of returning false. The template
conditional on line 455 requires a proper boolean value.

Changed from:
  device.snmp_device && (...)

To:
  not is_nil(device.snmp_device) and (...)

This ensures the function always returns a boolean (true/false) instead
of potentially returning nil.

Added regression test to verify the page renders correctly when a device
has no SNMP discovery data yet.

Fixes: https://app.honeybadger.io/projects/136860/faults/127120431
2026-02-03 15:32:51 -06:00
89a076fb67
feat: migrate equipment features to gettext and fix sudo mode tests
Migrates all equipment-related flash messages to gettext for internationalization:
- DeviceLive.Index: device discovery, reordering, error messages
- DeviceLive.Show: backup messages, permission errors
- DeviceLive.Form: device CRUD operations
- AlertLive.Index: alert acknowledgment messages
- SiteLive.Show: site discovery messages
- SiteLive.Form: site CRUD and SNMP/agent propagation

Fixes sudo mode test suite issues:
- Updates Accounts.sudo_mode?/2 test to check last_sudo_at instead of authenticated_at
- Adds register_and_log_in_user_with_sudo/1 helper to ConnCase
- Fixes UserAuth sudo mode tests to use session-based authentication
- Updates MyData tests to use sudo mode (now required per router config)
- Removes obsolete UserSettingsLive "without sudo mode" test
- Fixes grant_sudo_mode/1 DateTime truncation to seconds

All equipment module tests passing. Ready for Phase 3 (Admin Features).
2026-02-02 12:41:58 -06:00
23af86ba73
add mikrotik device handling 2026-02-01 16:42:39 -06:00
6ca22c5dd0 enhance user auditing 2026-01-30 17:38:07 -06:00
8e739283ad refactoring 2026-01-29 10:03:43 -06:00
58b1aa50c2 security fixes 2026-01-28 16:55:41 -06:00
5fb92dd961
add device/org limit 2026-01-27 14:14:25 -06:00
328d4659a7
show correct agent on edit screen and fix airfiber/ltu 2026-01-27 12:52:43 -06:00
9c5b4096f9
discovery working 2026-01-25 14:48:57 -06:00
6c1f344b5e
fix: resolve all dialyzer unmatched return and pattern match warnings
Fixed dialyzer warnings across multiple files by properly handling return
values from functions that are called for side effects.

Changes:
- lib/towerops/agents.ex: Explicitly match broadcast and if-expression returns
- lib/towerops/devices.ex: Match worker start function returns in if-expressions
- lib/towerops/workers/agent_latency_evaluator.ex: Match broadcast return
- lib/towerops/workers/device_monitor_worker.ex: Match perform_check and handle_status_change returns, handle schedule_next_check errors
- lib/towerops/workers/device_poller_worker.ex: Match all PubSub broadcast returns, handle schedule_next_poll errors, remove unreachable pattern
- lib/towerops/workers/stale_agent_worker.ex: Match process_stale_agents and broadcast returns
- lib/towerops_web/channels/agent_channel.ex: Match PubSub.subscribe return, improve get_addr pattern matching, remove unreachable format_ip clause
- lib/towerops_web/live/device_live/form.ex: Match enqueue_discovery return, replace compile-time @dev_env with runtime check

Pattern applied:
- PubSub broadcasts: `_ = Phoenix.PubSub.broadcast(...)`
- If-expressions with side effects: `_ = if condition do ... end`
- Critical operations: Added error logging with case statements

All 3625 tests passing. No dialyzer warnings remaining in lib/towerops or lib/towerops_web.

🤖 Generated with Claude Code

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-24 17:34:37 -06:00
d0946c3cd0
refactor: simplify job architecture from Oban coordinators to direct workers
Removes unnecessary two-layer architecture (Oban Coordinator → GenServer)
in favor of direct Oban workers that perform the actual work.

Changes:
- Replace DevicePollerCoordinator + PollerWorker with DevicePollerWorker
- Replace DeviceMonitorCoordinator + DeviceMonitor with DeviceMonitorWorker
- Simplify Monitoring.Supervisor (removed Registries, DynamicSupervisors)
- Remove all Exq dependencies (workers, supervisor, mix deps)
- Convert DiscoveryWorker from Exq to Oban pattern
- Update Devices context to auto-start/stop monitoring and polling
- Update all LiveView callers to use new Oban enqueue pattern
- Fix all tests to use Oban.Job struct instead of raw IDs

Benefits:
- Simpler codebase (~850 lines removed)
- Better reliability (Oban handles retries, failures)
- Lower memory (no persistent GenServers)
- Better observability (work visible in Oban dashboard)
- Cluster-wide coordination via PostgreSQL
- Extensive PubSub usage for real-time events

Files deleted:
- lib/towerops/workers/device_monitor_coordinator.ex
- lib/towerops/workers/device_poller_coordinator.ex
- lib/towerops/snmp/poller_worker.ex
- lib/towerops/monitoring/device_monitor.ex
- lib/towerops/workers/monitor_worker.ex
- lib/towerops/workers/poll_worker.ex
- lib/towerops/exq_supervisor.ex
- All related test files

Files created:
- lib/towerops/workers/device_poller_worker.ex
- lib/towerops/workers/device_monitor_worker.ex

All 3,686 tests passing.
2026-01-24 16:36:57 -06:00
f084e09ea1
add multiple cloud agents 2026-01-23 18:04:01 -06:00
518b49318c
routeros fix 2026-01-23 13:16:02 -06:00
a4335a047a
allow nonroutable for me 2026-01-23 13:10:12 -06:00
a0ba9285dd
bring in snmpkit 2026-01-23 12:52:17 -06:00
d401e0b036
mikrotik improvements 2026-01-22 13:05:28 -06:00
0a4482f974
feat: add 5 new vendor modules and fix dialyzer issues
Vendor modules added:
- Aviat (WTM microwave radios)
- Aruba (wireless controllers and APs)
- CiscoWLC (Cisco wireless LAN controllers)
- Teltonika (RUTOS LTE routers)
- Sub10 (mmWave backhaul radios)

Dialyzer fixes:
- Fix unknown type Devices.t/0 in alert.ex and device.ex
- Fix unmatched_return warnings across multiple files
- Add :exq to PLT for Exq function detection
- Remove dead code in base.ex, dynamic.ex, vendor.ex
- Fix Device.t() type spec to allow nil name field

Tests: 1437 tests, 0 failures
Dialyzer: 0 errors
Credo: no issues
2026-01-22 09:34:50 -06:00
77d4b25da7
test cleanup 2026-01-19 13:29:38 -06:00
9c2f08317f
feat: remove organization slug from sites and devices URLs
- Created new on_mount hook :load_default_organization that automatically loads user's first organization
- Moved sites and devices routes to root path (/ sites, /devices) instead of /orgs/:org_slug
- Updated all navigation links and route references throughout the app
- Dashboard, alerts, and agents still use org-specific routes (/orgs/:org_slug)
- Users can still switch organizations via org selector for other pages
2026-01-18 13:06:23 -06:00
b6ef989809
feat: redirect to device page after triggering rediscovery
When clicking 'Rediscover Device', navigate to the device details page
where the user can see live updates as discovery progresses.

The device show page already subscribes to PubSub discovery events and
will automatically refresh when discovery completes, showing updated
manufacturer, model, sensors, and interfaces.
2026-01-17 18:20:24 -06:00
b1fedcda45
updates 2026-01-17 17:49:53 -06:00
073f9bf27d
feat: use Exq for SNMP discovery background jobs
- Create DiscoveryWorker for handling SNMP device discovery
- Replace Task.start with Exq.enqueue for discovery operations
- Enqueue jobs to 'discovery' queue with device_id parameter
- Add enqueue_discovery/1 helper that falls back to Task.start in test
- Discovery jobs now persistent and retryable via Exq
- Triggered on: new device creation, device update, manual rediscover button
2026-01-17 16:39:40 -06:00
f27e1622a3
feat: stay on add device page after creation for batch adding
- After creating a device, stay on /devices/new instead of navigating to device show page
- Display success flash message with creation confirmation
- Reset form to defaults (preserving selected site) for adding next device
- Allows users to quickly add multiple devices in a row without navigation
- Add tests for staying on page and adding multiple devices sequentially
- All 91 device-related tests passing with no Credo warnings
2026-01-17 16:16:10 -06:00
d87461ba14
feat: add monitoring mode tab selector (SNMP & ICMP vs ICMP Only)
- Add tab selector in Monitoring Configuration section for choosing monitoring mode
- SNMP & ICMP mode: enables ICMP pings + SNMP discovery (default)
- ICMP Only mode: enables only ICMP ping monitoring, hides SNMP fields
- Monitoring mode controls snmp_enabled field automatically on save
- Test SNMP Connection button shows informational message when agent is configured
  (agents handle SNMP testing during their polling cycle)
- Update all tests to use tab selector instead of setting snmp_enabled directly
- All 818 tests passing with no Credo warnings
2026-01-17 16:10:59 -06:00
f0f5aca491
Allow empty SNMP community string for device inheritance
Implemented hierarchical SNMP community string inheritance following TDD:

Schema changes:
- Updated Device.changeset to remove required validation for snmp_community
- Community string is now optional when SNMP is enabled
- Allows inheritance from site or organization level

Inheritance hierarchy:
- Device-level community (highest priority)
- Site-level community
- Organization-level community
- nil (no community set at any level)

Form updates:
- extract_snmp_config now resolves inherited community for SNMP testing
- validate_test_snmp_input provides clearer error message about inheritance
- SNMP test uses effective community from hierarchy

Tests:
- Added tests for creating devices with nil/empty community string
- Added comprehensive SNMP configuration inheritance tests
- Tests verify hierarchy: device > site > org > default
- All 28 device tests passing

All 808 tests passing (2 pre-existing alert notifier failures unrelated to this change)
No Credo warnings
2026-01-17 15:54:06 -06:00
541ab7e7d6
more renames 2026-01-17 15:13:56 -06:00
a810e75fc4
rename equipment to device 2026-01-17 14:48:46 -06:00
Renamed from lib/towerops_web/live/equipment_live/form.ex (Browse further)