From 6b5d877831f9c3605147919873c39a8577f9aba4 Mon Sep 17 00:00:00 2001 From: ghostiee-11 <168410465+ghostiee-11@users.noreply.github.com> Date: Mon, 9 Mar 2026 17:07:53 +0530 Subject: [PATCH] fix: redirect smartlink directly to CRE when only one is linked Fixes #486 When a smartlinked standard resolves to exactly one CRE, skip the intermediate standard page and redirect directly to the CRE page. Standards with multiple CRE links retain the existing behavior. --- application/tests/web_main_test.py | 23 +++++++++++++++++++++-- application/web/web_main.py | 7 +++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/application/tests/web_main_test.py b/application/tests/web_main_test.py index 9e219b4ce..286192e20 100644 --- a/application/tests/web_main_test.py +++ b/application/tests/web_main_test.py @@ -569,6 +569,7 @@ def test_smartlink(self) -> None: collection.add_link(dcb, dasvs, ltype=defs.LinkTypes.LinkedTo) collection.add_link(dcd, dcwe, ltype=defs.LinkTypes.LinkedTo) + # Single CRE linked to CWE/456 — should redirect directly to the CRE response = client.get( "/smartlink/standard/CWE/456", headers={"Content-Type": "application/json"}, @@ -577,9 +578,10 @@ def test_smartlink(self) -> None: for head in response.headers: if head[0] == "Location": location = head[1] - self.assertEqual(location, "/node/standard/CWE/sectionid/456") + self.assertEqual(location, "/cre/222-222") self.assertEqual(302, response.status_code) + # Single CRE linked to ASVS/v0.1.2 — should redirect directly to the CRE response = client.get( "/smartlink/standard/ASVS/v0.1.2", headers={"Content-Type": "application/json"}, @@ -588,7 +590,24 @@ def test_smartlink(self) -> None: for head in response.headers: if head[0] == "Location": location = head[1] - self.assertEqual(location, "/node/standard/ASVS/section/v0.1.2") + self.assertEqual(location, "/cre/333-333") + self.assertEqual(302, response.status_code) + + # Multiple CREs linked — should redirect to the node page, not a single CRE + multi_std = defs.Standard(name="MultiCRE", section="s1") + dmulti = collection.add_node(multi_std) + collection.add_link(dcd, dmulti, ltype=defs.LinkTypes.LinkedTo) + collection.add_link(dcb, dmulti, ltype=defs.LinkTypes.LinkedTo) + + response = client.get( + "/smartlink/standard/MultiCRE/s1", + headers={"Content-Type": "application/json"}, + ) + location = "" + for head in response.headers: + if head[0] == "Location": + location = head[1] + self.assertEqual(location, "/node/standard/MultiCRE/section/s1") self.assertEqual(302, response.status_code) # negative test, this cwe does not exist, therefore we redirect to Mitre! diff --git a/application/web/web_main.py b/application/web/web_main.py index 29567470a..2e12965b3 100644 --- a/application/web/web_main.py +++ b/application/web/web_main.py @@ -580,6 +580,13 @@ def smartlink( ) found_section_id = True if nodes and len(nodes[0].links): + if len(nodes[0].links) == 1: + cre_doc = nodes[0].links[0].document + logger.info( + f"found node of type {ntype}, name {name} and section {section}, " + f"single CRE linked, redirecting directly to CRE {cre_doc.id}" + ) + return redirect(f"/cre/{cre_doc.id}") logger.info( f"found node of type {ntype}, name {name} and section {section}, redirecting to opencre" )