Skip to content

Commit

Permalink
Merge pull request #967 from hmrc/update
Browse files Browse the repository at this point in the history
Fix vulnerabilities sorting
  • Loading branch information
colin-lamed authored Nov 29, 2024
2 parents a865ee6 + d50dd71 commit 76e7b0c
Show file tree
Hide file tree
Showing 9 changed files with 35 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ class CatalogueController @Inject() (
)
canMarkForDecommissioning <- hasMarkForDecommissioningAuthorisation(repositoryName)
lifecycle <- serviceCommissioningStatusConnector.getLifecycle(serviceName)
isGuest = request.session.get(AuthController.SESSION_USERNAME).exists(_.startsWith("guest-"))
isGuest = request.session.get(AuthController.SESSION_USERNAME).exists(_.startsWith("guest-"))
yield
Ok(serviceInfoPage(
serviceName = serviceName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ class CatalogueErrorHandler @Inject()(
override val ec: ExecutionContext
) extends FrontendErrorHandler:

override def standardErrorTemplate(pageTitle: String, heading: String, message: String)(using request: RequestHeader): Future[Html] =
override def standardErrorTemplate(pageTitle: String, heading: String, message: String)(using RequestHeader): Future[Html] =
Future.successful(error_template(pageTitle, heading, message))

override def notFoundTemplate(using request: RequestHeader): Future[Html] =
override def notFoundTemplate(using RequestHeader): Future[Html] =
Future.successful(error_404_template())

def forbiddenTemplate(using request: RequestHeader): Html =
def forbiddenTemplate(using RequestHeader): Html =
error_403_template()
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,17 @@ import uk.gov.hmrc.cataloguefrontend.connector.RouteConfigurationConnector
import uk.gov.hmrc.cataloguefrontend.model.Environment
import uk.gov.hmrc.http.HeaderCarrier

import scala.concurrent.{ExecutionContext, Future}
import scala.concurrent.Future

@Singleton
class SearchByUrlService @Inject() (
routeConfigurationConnector: RouteConfigurationConnector
)(using ec: ExecutionContext):
):

def searchFrontendPath(
term : Option[String]
, environment: Option[Environment] = Some(Environment.Production)
)(using
)(using
HeaderCarrier
): Future[Seq[Route]] =
if isValidSearchTerm(term)
Expand All @@ -48,7 +48,7 @@ class SearchByUrlService @Inject() (
then
false
else
try {
try
val url = URI(term.get)

Option(url.getPath).getOrElse("").nonEmpty
Expand All @@ -57,9 +57,8 @@ class SearchByUrlService @Inject() (
&& Option(url.getPath).getOrElse("").contains("tax.service.gov.uk")
&& url.getPath.substring(url.getPath.indexOf(".gov.uk") + 7).trim.nonEmpty
)
} catch {
catch
case e: URISyntaxException => false
}

private def takeUrlPath(term: String): String =
val url = URI(term)
Expand All @@ -70,7 +69,7 @@ class SearchByUrlService @Inject() (
else if Option(url.getHost).getOrElse("").trim.isEmpty
&& Option(url.getPath).getOrElse("").contains("tax.service.gov.uk")
then
url.getPath.substring(url.getPath.indexOf(".gov.uk") + 7).trim
url.getPath.substring(url.getPath.indexOf(".gov.uk") + 7).trim
else
url.getPath.trim

Expand Down
29 changes: 11 additions & 18 deletions app/uk/gov/hmrc/cataloguefrontend/vulnerabilities/model.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,43 +17,36 @@
package uk.gov.hmrc.cataloguefrontend.vulnerabilities

import play.api.libs.functional.syntax._
import play.api.libs.json.{Format, Reads, __}
import play.api.libs.json.{Reads, __}
import uk.gov.hmrc.cataloguefrontend.model.{ServiceName, Version, VersionRange}

import java.time.Instant
import scala.collection.Seq

case class VulnerableComponent(
component: String,
version: String
version : Version
):
// Note two edge cases which would otherwise break the dependency explorer links are handled below:
// 1. A vulnerable version may have another `.` after the patch version.
// 2. An artefact may have a trailing `_someVersionNumber`.
def cleansedVersion: String =
version.split("\\.").take(3).mkString(".")

def group: String =
component.stripPrefix("gav://").split(":")(0)

def artefact: String =
component.stripPrefix("gav://").split(":")(1).split("_")(0)

def versionRange: VersionRange =
val v = Version(cleansedVersion)
VersionRange(s"[${v.major}.${v.minor}.${v.patch}]")
VersionRange(s"[${version.major}.${version.minor}.${version.patch}]")

def componentWithoutPrefix: Option[String] =
component.split("://").lift(1)

end VulnerableComponent

object VulnerableComponent {
val format: Format[VulnerableComponent] =
( (__ \ "component").format[String]
~ (__ \ "version" ).format[String]
)(apply, vc => Tuple.fromProductTyped(vc))
}
object VulnerableComponent:
val reads: Reads[VulnerableComponent] =
given Reads[Version] = Version.format
( (__ \ "component").read[String]
~ (__ \ "version" ).read[Version]
)(apply)

case class DistinctVulnerability(
vulnerableComponentName : String,
Expand All @@ -74,7 +67,7 @@ case class DistinctVulnerability(
object DistinctVulnerability {

val reads: Reads[DistinctVulnerability] =
given Format[VulnerableComponent] = VulnerableComponent.format
given Reads[VulnerableComponent] = VulnerableComponent.reads
( (__ \ "vulnerableComponentName" ).read[String]
~ (__ \ "vulnerableComponentVersion").read[String]
~ (__ \ "vulnerableComponents" ).read[Seq[VulnerableComponent]]
Expand All @@ -94,7 +87,7 @@ object DistinctVulnerability {
case class VulnerabilityOccurrence(
service : ServiceName,
serviceVersion : String,
componentPathInSlug: String,
componentPathInSlug: String
)

object VulnerabilityOccurrence {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ <h1 class="page-heading mt-4">Vulnerabilities</h1>
}
</div>

@maybeSummaries.map{ summaries =>
@maybeSummaries.map { summaries =>
@if(summaries.nonEmpty) {
<script @CSPNonce.attr>
let options = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
<p class="fw-bold">Vulnerable components on platform:</p>
<div class="overflow-x-hidden overflow-y-auto" style="height: 140px;">
<ul>
@vuln.distinctVulnerability.vulnerableComponents.sortWith(_.version > _.version).map { vc =>
@vuln.distinctVulnerability.vulnerableComponents.sortBy(_.version).map { vc =>
<li>
@if(vc.component.startsWith("gav")) {
<a href="@DependencyExplorerController.search(flag = SlugInfoFlag.Latest, scopes = Seq(DependencyScope.Compile), group = vc.group, artefact = vc.artefact, versionRange = VersionRange("[0.0.0,)"))">@vc.componentWithoutPrefix.getOrElse(vc.component)</a>
Expand Down Expand Up @@ -143,7 +143,7 @@
</tr>
</thead>
<tbody>
@vuln.occurrences.map { occ =>
@vuln.occurrences.sortBy(o => (o.service, o.serviceVersion)).map { occ =>
<tr>
<td class="col-3"><a href="@appRoutes.CatalogueController.service(occ.service)">@occ.service.asString</a></td>
<td class="col-1">@occ.serviceVersion</td>
Expand Down
14 changes: 6 additions & 8 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
import play.core.PlayVersion
import play.sbt.PlayImport.PlayKeys.playDefaultPort
import play.sbt.PlayImport.PlayKeys
import play.sbt.routes.RoutesKeys
import uk.gov.hmrc.versioning.SbtGitVersioning

lazy val microservice = Project("catalogue-frontend", file("."))
.enablePlugins(PlayScala, SbtDistributablesPlugin)
.disablePlugins(JUnitXmlReportPlugin) //Required to prevent https://github.com/scalatest/scalatest/issues/1427
.settings(
majorVersion := 5,
scalaVersion := "3.3.4",
playDefaultPort := 9017,
PlayKeys.playDefaultPort := 9017,
libraryDependencies ++= compile ++ test,
RoutesKeys.routesImport ++= Seq(
"uk.gov.hmrc.cataloguefrontend.model._",
Expand All @@ -35,20 +33,20 @@ lazy val microservice = Project("catalogue-frontend", file("."))
scalacOptions += "-Wconf:src=routes/.*:s",
scalacOptions += "-Wconf:msg=Flag.*repeatedly:s",
//scalacOptions += "-explain",
javaOptions += "-Xmx2G",
Compile / javaOptions += "-Xmx2G", // without `Compile` it breaks sbt start/runProd (Universal scope)
pipelineStages := Seq(digest)
)

val bootstrapPlayVersion = "9.2.0"
val hmrcMongoVersion = "2.2.0"
val bootstrapPlayVersion = "9.5.0"
val hmrcMongoVersion = "2.3.0"

val compile = Seq(
caffeine,
"uk.gov.hmrc" %% "bootstrap-frontend-play-30" % bootstrapPlayVersion,
"uk.gov.hmrc.mongo" %% "hmrc-mongo-play-30" % hmrcMongoVersion,
"uk.gov.hmrc" %% "internal-auth-client-play-30" % "3.0.0",
"org.typelevel" %% "cats-core" % "2.12.0",
"org.yaml" % "snakeyaml" % "2.2",
"org.yaml" % "snakeyaml" % "2.3",
"org.planet42" %% "laika-core" % "0.19.5",
"org.jsoup" % "jsoup" % "1.17.2"
)
Expand Down
4 changes: 2 additions & 2 deletions project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
resolvers += MavenRepository("HMRC-open-artefacts-maven2", "https://open.artefacts.tax.service.gov.uk/maven2")
resolvers += Resolver.url("HMRC-open-artefacts-ivy2", url("https://open.artefacts.tax.service.gov.uk/ivy2"))(Resolver.ivyStylePatterns)

addSbtPlugin("uk.gov.hmrc" % "sbt-auto-build" % "3.22.0")
addSbtPlugin("uk.gov.hmrc" % "sbt-auto-build" % "3.24.0")
addSbtPlugin("uk.gov.hmrc" % "sbt-distributables" % "2.5.0")
addSbtPlugin("org.playframework" % "sbt-plugin" % "3.0.4")
addSbtPlugin("org.playframework" % "sbt-plugin" % "3.0.5")
addSbtPlugin("com.typesafe.sbt" % "sbt-digest" % "1.1.4")
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@ import org.scalatest.concurrent.{IntegrationPatience, ScalaFutures}
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpecLike
import play.api.Configuration
import uk.gov.hmrc.cataloguefrontend.model.{ServiceName, SlugInfoFlag}
import uk.gov.hmrc.cataloguefrontend.vulnerabilities.CurationStatus.ActionRequired
import uk.gov.hmrc.cataloguefrontend.model.{ServiceName, SlugInfoFlag, Version}
import uk.gov.hmrc.http.HeaderCarrier
import uk.gov.hmrc.http.test.{HttpClientV2Support, WireMockSupport}
import uk.gov.hmrc.play.bootstrap.config.ServicesConfig
Expand Down Expand Up @@ -101,7 +100,7 @@ class VulnerabilitiesConnectorSpec
distinctVulnerability = DistinctVulnerability(
vulnerableComponentName = "deb://ubuntu/xenial:test",
vulnerableComponentVersion = "1.2.5.4-1",
vulnerableComponents = Seq(VulnerableComponent("deb://ubuntu/xenial:test", "1.2.5.4-1")),
vulnerableComponents = Seq(VulnerableComponent("deb://ubuntu/xenial:test", Version("1.2.5.4-1"))),
id = "CVE-123",
score = Some(10.0),
description = "testing",
Expand All @@ -110,7 +109,7 @@ class VulnerabilitiesConnectorSpec
publishedDate = Instant.parse("2019-08-20T10:53:37.00Z"),
firstDetected = Some(Instant.parse("2019-08-20T10:53:37.00Z")),
assessment = Some("Serious"),
curationStatus = Some(ActionRequired),
curationStatus = Some(CurationStatus.ActionRequired),
ticket = Some("ticket1")
),
occurrences = Seq(VulnerabilityOccurrence(
Expand Down

0 comments on commit 76e7b0c

Please sign in to comment.