From 51d07db71020a1478f899afd744d4f6f0a42461d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophile=20Choutri?= Date: Fri, 27 Dec 2024 15:17:06 +0100 Subject: [PATCH] Adapt advisories listing for search Search results will also show qualified package names associated with an advisory --- assets/css/2-components/11-advisory-list-item.css | 13 +++++++++---- src/advisories/Advisories/Model/Affected/Query.hs | 9 +++++++++ src/advisories/Advisories/Model/Affected/Types.hs | 2 ++ src/web/FloraWeb/Components/AdvisoryListItem.hs | 14 ++++++++++---- src/web/FloraWeb/Pages/Templates/Packages.hs | 12 +++++++----- src/web/FloraWeb/Pages/Templates/Screens/Search.hs | 4 ++-- 6 files changed, 39 insertions(+), 15 deletions(-) diff --git a/assets/css/2-components/11-advisory-list-item.css b/assets/css/2-components/11-advisory-list-item.css index 128f9565..70095f2d 100644 --- a/assets/css/2-components/11-advisory-list-item.css +++ b/assets/css/2-components/11-advisory-list-item.css @@ -9,22 +9,27 @@ display: inline; } -.package-advisory-list-item__hsec_id { +.package-advisory-list-item__package { + font-weight: bolder; order: 1; } -.package-advisory-list-item__published { +.package-advisory-list-item__hsec-id { order: 2; +} + +.package-advisory-list-item__published { + order: 3; display: none; } .package-advisory-list-item__attributes { - order: 3; + order: 4; } .package-advisory-list-item__summary { font-weight: bolder; - order: 4; + order: 5; } .advisory-list-item__severity-pill { diff --git a/src/advisories/Advisories/Model/Affected/Query.hs b/src/advisories/Advisories/Model/Affected/Query.hs index 88df575c..d92d1378 100644 --- a/src/advisories/Advisories/Model/Affected/Query.hs +++ b/src/advisories/Advisories/Model/Affected/Query.hs @@ -49,6 +49,8 @@ getAdvisoryPreviewsByPackageId packageId = Select [sql| SELECT s0.hsec_id + , p3.namespace + , p3.name , s0.summary , CASE WHEN a2.fixed_version IS NULL @@ -78,6 +80,8 @@ searchAdvisoriesQuery = [sql| WITH results AS ( SELECT s0.hsec_id + , p3.namespace + , p3.name , s0.summary , CASE WHEN a2.fixed_version IS NULL @@ -92,12 +96,15 @@ WITH results AS ( INNER JOIN affected_version_ranges AS a2 ON a1.affected_package_id = a2.affected_package_id INNER JOIN packages AS p3 ON a1.package_id = p3.package_id WHERE ? <% s0.summary + GROUP BY s0.hsec_id, p3.namespace, p3.name, s0.summary, fixed, s0.published, a1.cvss, rating ORDER BY rating desc, s0.summary asc OFFSET ? LIMIT ? ) SELECT r0.hsec_id + , r0.namespace + , r0.name , r0.summary , r0.fixed , r0.published @@ -122,6 +129,8 @@ countAdvisorySearchResultsQuery = [sql| WITH results AS ( SELECT s0.hsec_id + , p3.namespace + , p3.name , s0.summary , CASE WHEN a2.fixed_version IS NULL diff --git a/src/advisories/Advisories/Model/Affected/Types.hs b/src/advisories/Advisories/Model/Affected/Types.hs index d8dbfffe..e061151f 100644 --- a/src/advisories/Advisories/Model/Affected/Types.hs +++ b/src/advisories/Advisories/Model/Affected/Types.hs @@ -78,6 +78,8 @@ data AffectedVersionRangeDAO = AffectedVersionRangeDAO data PackageAdvisoryPreview = PackageAdvisoryPreview { hsecId :: HsecId + , namespace :: Namespace + , packageName :: PackageName , summary :: Text , fixed :: Bool , published :: UTCTime diff --git a/src/web/FloraWeb/Components/AdvisoryListItem.hs b/src/web/FloraWeb/Components/AdvisoryListItem.hs index f96f828f..2d8cc973 100644 --- a/src/web/FloraWeb/Components/AdvisoryListItem.hs +++ b/src/web/FloraWeb/Components/AdvisoryListItem.hs @@ -2,6 +2,7 @@ module FloraWeb.Components.AdvisoryListItem ( advisoryListRow ) where +import Control.Monad (when) import Data.Text.Display import Data.Time qualified as Time import Lucid @@ -9,15 +10,16 @@ import Security.CVSS (Rating (..), cvssScore) import Advisories.HsecId.Orphans () import Advisories.Model.Affected.Types -import Control.Monad (when) import Distribution.Orphans.Version () import FloraWeb.Components.Pill +import FloraWeb.Links qualified as Links import FloraWeb.Pages.Templates.Types advisoryListRow - :: PackageAdvisoryPreview + :: Bool + -> PackageAdvisoryPreview -> FloraHTML -advisoryListRow preview = do +advisoryListRow specifyPackage preview = do let href = "https://haskell.github.io/security-advisories/advisory/" <> display preview.hsecId <> ".html" let (rating, score) = cvssScore preview.cvss let severity = case rating of @@ -27,11 +29,15 @@ advisoryListRow preview = do High -> ratingHigh score Critical -> ratingCritical score div_ [class_ "package-advisory-list-item"] $ do - div_ [class_ "package-advisory-list-item__hsec-id md:order-1"] $ do + div_ [class_ "package-advisory-list-item__hsec-id"] $ do a_ [href_ href] (toHtml $ display preview.hsecId) span_ [class_ "package-advisory-list-item__inline-published"] $ toHtml $ Time.formatTime Time.defaultTimeLocale "%_d %b %Y" preview.published + when specifyPackage $ + div_ [class_ "package-advisory-list-item__package"] $ do + let qualifiedName = toHtml $ display preview.namespace <> "/" <> display preview.packageName + a_ [class_ "", href_ $ Links.packageResource preview.namespace preview.packageName] qualifiedName div_ [class_ "package-advisory-list-item__summary"] (toHtml preview.summary) div_ [class_ "package-advisory-list-item__published"] $ toHtml $ diff --git a/src/web/FloraWeb/Pages/Templates/Packages.hs b/src/web/FloraWeb/Pages/Templates/Packages.hs index 89af92c1..b80036e8 100644 --- a/src/web/FloraWeb/Pages/Templates/Packages.hs +++ b/src/web/FloraWeb/Pages/Templates/Packages.hs @@ -24,7 +24,7 @@ module FloraWeb.Pages.Templates.Packages , showDependencies , showDependents , showPackageSecurityPage - , advisoriesListing + , packageAdvisoriesListing ) where import Control.Monad (when) @@ -567,17 +567,19 @@ showPackageSecurityPage showPackageSecurityPage namespace packageName advisoryPreviews = do div_ [class_ "container"] $ do presentationHeaderForAdvisories namespace packageName - advisoriesListing advisoryPreviews + packageAdvisoriesListing False advisoryPreviews -advisoriesListing :: Vector PackageAdvisoryPreview -> FloraHTML -advisoriesListing advisoryPreviews = +packageAdvisoriesListing :: Bool -> Vector PackageAdvisoryPreview -> FloraHTML +packageAdvisoriesListing specifyPackage advisoryPreviews = if Vector.null advisoryPreviews then p_ [] "No advisories found." else div_ [class_ "advisory-list"] $ do div_ [class_ "advisory-list__head"] $ do div_ [class_ "advisory-list__header"] "ID" + when specifyPackage $ + div_ [class_ "advisory-list__header"] "Package" div_ [class_ "advisory-list__header"] "Summary" div_ [class_ "advisory-list__header"] "Published" div_ [class_ "advisory-list__header"] "Attributes" div_ [class_ "advisory-list__body"] $ - Vector.forM_ advisoryPreviews (\preview -> advisoryListRow preview) + Vector.forM_ advisoryPreviews (\preview -> advisoryListRow specifyPackage preview) diff --git a/src/web/FloraWeb/Pages/Templates/Screens/Search.hs b/src/web/FloraWeb/Pages/Templates/Screens/Search.hs index 04095bdc..70da2979 100644 --- a/src/web/FloraWeb/Pages/Templates/Screens/Search.hs +++ b/src/web/FloraWeb/Pages/Templates/Screens/Search.hs @@ -13,7 +13,7 @@ import Flora.Search (SearchAction (..)) import FloraWeb.Components.PackageListHeader (presentationHeader) import FloraWeb.Components.PaginationNav (paginationNav) import FloraWeb.Pages.Templates -import FloraWeb.Pages.Templates.Packages (advisoriesListing, packageListing, packageWithExecutableListing) +import FloraWeb.Pages.Templates.Packages (packageAdvisoriesListing, packageListing, packageWithExecutableListing) showAllPackages :: Word -> Positive Word -> Vector PackageInfo -> FloraHTML showAllPackages count currentPage packagesInfo = do @@ -75,6 +75,6 @@ showAdvisorySearchResults showAdvisorySearchResults searchTerm count currentPage results = do div_ [class_ "container"] $ do presentationHeader searchTerm "" count - advisoriesListing results + packageAdvisoriesListing True results when (count > 30) $ paginationNav count currentPage (SearchInAdvisories searchTerm)