diff --git a/app/web/services/scan_service.py b/app/web/services/scan_service.py index c87f273..ba518c6 100644 --- a/app/web/services/scan_service.py +++ b/app/web/services/scan_service.py @@ -16,7 +16,7 @@ from sqlalchemy.orm import Session, joinedload from web.models import ( Scan, ScanSite, ScanIP, ScanPort, ScanService as ScanServiceModel, - ScanCertificate, ScanTLSVersion, Site, ScanSiteAssociation + ScanCertificate, ScanTLSVersion, Site, ScanSiteAssociation, SiteIP ) from web.utils.pagination import paginate, PaginatedResult from web.utils.validators import validate_scan_status @@ -630,17 +630,47 @@ class ScanService: def _site_to_dict(self, site: ScanSite) -> Dict[str, Any]: """Convert ScanSite to dictionary.""" + # Look up the master Site ID from ScanSiteAssociation + master_site_id = None + assoc = ( + self.db.query(ScanSiteAssociation) + .filter( + ScanSiteAssociation.scan_id == site.scan_id, + ) + .join(Site) + .filter(Site.name == site.site_name) + .first() + ) + if assoc: + master_site_id = assoc.site_id + return { 'id': site.id, 'name': site.site_name, - 'ips': [self._ip_to_dict(ip) for ip in site.ips] + 'site_id': master_site_id, # The actual Site ID for config updates + 'ips': [self._ip_to_dict(ip, master_site_id) for ip in site.ips] } - def _ip_to_dict(self, ip: ScanIP) -> Dict[str, Any]: + def _ip_to_dict(self, ip: ScanIP, site_id: Optional[int] = None) -> Dict[str, Any]: """Convert ScanIP to dictionary.""" + # Look up the SiteIP ID for this IP address in the master Site + site_ip_id = None + if site_id: + site_ip = ( + self.db.query(SiteIP) + .filter( + SiteIP.site_id == site_id, + SiteIP.ip_address == ip.ip_address + ) + .first() + ) + if site_ip: + site_ip_id = site_ip.id + return { 'id': ip.id, 'address': ip.ip_address, + 'site_ip_id': site_ip_id, # The actual SiteIP ID for config updates 'ping_expected': ip.ping_expected, 'ping_actual': ip.ping_actual, 'ports': [self._port_to_dict(port) for port in ip.ports] diff --git a/app/web/templates/scan_detail.html b/app/web/templates/scan_detail.html index 2e038c4..2d83a75 100644 --- a/app/web/templates/scan_detail.html +++ b/app/web/templates/scan_detail.html @@ -586,6 +586,19 @@ const screenshotPath = service && service.screenshot_path ? service.screenshot_path : null; const certificate = service && service.certificates && service.certificates.length > 0 ? service.certificates[0] : null; + // Build status cell with optional "Mark Expected" button + let statusCell; + if (port.expected) { + statusCell = 'Expected'; + } else { + // Show "Unexpected" badge with "Mark Expected" button if site_id and site_ip_id are available + const canMarkExpected = site.site_id && ip.site_ip_id; + statusCell = `Unexpected`; + if (canMarkExpected) { + statusCell += ` `; + } + } + const row = document.createElement('tr'); row.classList.add('scan-row'); // Fix white row bug row.innerHTML = ` @@ -595,7 +608,7 @@