Skip to content

Commit 636197d

Browse files
committed
feature(tools): generate individual advisories page
1 parent 197cf70 commit 636197d

File tree

1 file changed

+38
-17
lines changed
  • code/hsec-tools/src/Security/Advisories/Generate

1 file changed

+38
-17
lines changed

code/hsec-tools/src/Security/Advisories/Generate/HTML.hs

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ where
1111
import Control.Monad (forM_)
1212
import Control.Monad.Extra (mapMaybeM)
1313
import Data.Either.Extra (eitherToMaybe)
14+
import Data.Functor ((<&>))
1415
import Data.List (isPrefixOf, isSuffixOf, sortOn)
1516
import Data.List.Extra (groupSort)
1617
import qualified Data.Map.Strict as Map
@@ -19,18 +20,16 @@ import Data.Text (Text)
1920
import qualified Data.Text as T
2021
import qualified Data.Text.IO as T
2122
import Lucid
22-
import Security.Advisories (AttributeOverridePolicy (NoOverrides), OutOfBandAttributes(..), parseAdvisory, emptyOutOfBandAttributes)
23-
import Data.Functor((<&>))
24-
import Security.Advisories.Git
23+
import Security.Advisories (AttributeOverridePolicy (NoOverrides), OutOfBandAttributes (..), emptyOutOfBandAttributes, parseAdvisory)
2524
import qualified Security.Advisories as Advisories
25+
import Security.Advisories.Git
2626
import System.Directory (createDirectoryIfMissing)
2727
import System.Directory.Extra (listFilesRecursive)
2828
import System.FilePath (takeFileName, (</>))
2929

3030
{-
3131
TODO
32-
* Generate advisories page
33-
* Select head menu
32+
\* Select head menu
3433
-}
3534

3635
-- * Actions
@@ -39,23 +38,36 @@ renderAdvisoriesIndex :: FilePath -> FilePath -> IO ()
3938
renderAdvisoriesIndex src dst = do
4039
let isAdvisory p =
4140
let fileName = takeFileName p
42-
in isPrefixOf "HSEC-" fileName && isSuffixOf ".md" fileName
41+
in isPrefixOf "HSEC-" fileName && isSuffixOf ".md" fileName
4342
readAdvisory path = do
4443
oob <-
4544
getAdvisoryGitInfo path <&> \case
4645
Left _ -> emptyOutOfBandAttributes
47-
Right gitInfo -> emptyOutOfBandAttributes
48-
{ oobPublished = Just (firstAppearanceCommitDate gitInfo)
49-
, oobModified = Just (lastModificationCommitDate gitInfo)
50-
}
46+
Right gitInfo ->
47+
emptyOutOfBandAttributes
48+
{ oobPublished = Just (firstAppearanceCommitDate gitInfo),
49+
oobModified = Just (lastModificationCommitDate gitInfo)
50+
}
5151
fileContent <- T.readFile path
5252
return $ eitherToMaybe $ parseAdvisory NoOverrides oob fileContent
5353
advisoriesFileName <- filter isAdvisory <$> listFilesRecursive src
54-
advisories <- map toAdvisoryR <$> mapMaybeM readAdvisory advisoriesFileName
54+
advisories <- mapMaybeM readAdvisory advisoriesFileName
55+
let renderToFile' path content = do
56+
putStrLn $ "Rendering " <> path
57+
renderToFile path content
5558

5659
createDirectoryIfMissing False dst
57-
renderToFile (dst </> "by-dates.html") $ listByDates advisories
58-
renderToFile (dst </> "by-packages.html") $ listByPackages advisories
60+
let indexAdvisories = map toAdvisoryR advisories
61+
renderToFile' (dst </> "by-dates.html") $ listByDates indexAdvisories
62+
renderToFile' (dst </> "by-packages.html") $ listByPackages indexAdvisories
63+
64+
let advisoriesDir = dst </> "advisory"
65+
createDirectoryIfMissing False advisoriesDir
66+
forM_ advisories $ \advisory ->
67+
renderToFile' (advisoriesDir </> T.unpack (advisoryHtmlFilename advisory.advisoryId)) $
68+
inPage $
69+
div_ [class_ "pure-u-1"] $
70+
toHtmlRaw advisory.advisoryHtml
5971
return ()
6072

6173
-- * Rendering types
@@ -95,7 +107,7 @@ listByDates advisories =
95107
(cycle [[], [class_ "pure-table-odd"]])
96108
forM_ sortedAdvisories $ \(advisory, trClasses) ->
97109
tr_ trClasses $ do
98-
td_ [class_ "advisory-id"] $ a_ [href_ "#"] $ toHtml advisory.advisoryId
110+
td_ [class_ "advisory-id"] $ a_ [href_ $ advisoryLink advisory.advisoryId] $ toHtml advisory.advisoryId
99111
td_ [class_ "advisory-packages"] $ toHtml $ T.intercalate "," $ (.packageName) <$> advisory.advisoryAffected
100112
td_ [class_ "advisory-summary"] $ toHtml advisory.advisorySummary
101113

@@ -130,7 +142,7 @@ listByPackages advisories =
130142
(cycle [[], [class_ "pure-table-odd"]])
131143
forM_ sortedAdvisories $ \((advisory, package), trClasses) ->
132144
tr_ trClasses $ do
133-
td_ [class_ "advisory-id"] $ a_ [href_ "#"] $ toHtml advisory.advisoryId
145+
td_ [class_ "advisory-id"] $ a_ [href_ $ advisoryLink advisory.advisoryId] $ toHtml advisory.advisoryId
134146
td_ [class_ "advisory-introduced"] $ toHtml package.introduced
135147
td_ [class_ "advisory-fixed"] $ maybe (return ()) toHtml package.fixed
136148
td_ [class_ "advisory-summary"] $ toHtml advisory.advisorySummary
@@ -158,6 +170,9 @@ inPage content =
158170
"a:visited {",
159171
" text-decoration: none;",
160172
" color: darkblue;",
173+
"}",
174+
"pre {",
175+
" background: lightgrey;",
161176
"}"
162177
]
163178
body_ $ do
@@ -166,11 +181,17 @@ inPage content =
166181
span_ [class_ "pure-menu-heading pure-menu-link"] "Advisories list"
167182
ul_ [class_ "pure-menu-list"] $ do
168183
li_ [class_ "pure-menu-item"] $
169-
a_ [href_ "#", class_ "pure-menu-link"] "by date"
184+
a_ [href_ "/by-dates.html", class_ "pure-menu-link"] "by date"
170185
li_ [class_ "pure-menu-item"] $
171-
a_ [href_ "#", class_ "pure-menu-link"] "by package"
186+
a_ [href_ "/by-packages.html", class_ "pure-menu-link"] "by package"
172187
div_ [class_ "content"] content
173188

189+
advisoryHtmlFilename :: Text -> Text
190+
advisoryHtmlFilename advisoryId' = advisoryId' <> ".html"
191+
192+
advisoryLink :: Text -> Text
193+
advisoryLink advisoryId' = "/advisory/" <> advisoryHtmlFilename advisoryId'
194+
174195
toAdvisoryR :: Advisories.Advisory -> AdvisoryR
175196
toAdvisoryR x =
176197
AdvisoryR

0 commit comments

Comments
 (0)