Skip to content

Commit d50dd71

Browse files
committed
Fix vulnerabilities sorting
1 parent a865ee6 commit d50dd71

File tree

9 files changed

+35
-46
lines changed

9 files changed

+35
-46
lines changed

app/uk/gov/hmrc/cataloguefrontend/CatalogueController.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ class CatalogueController @Inject() (
219219
)
220220
canMarkForDecommissioning <- hasMarkForDecommissioningAuthorisation(repositoryName)
221221
lifecycle <- serviceCommissioningStatusConnector.getLifecycle(serviceName)
222-
isGuest = request.session.get(AuthController.SESSION_USERNAME).exists(_.startsWith("guest-"))
222+
isGuest = request.session.get(AuthController.SESSION_USERNAME).exists(_.startsWith("guest-"))
223223
yield
224224
Ok(serviceInfoPage(
225225
serviceName = serviceName,

app/uk/gov/hmrc/cataloguefrontend/service/CatalogueErrorHandler.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,11 @@ class CatalogueErrorHandler @Inject()(
3232
override val ec: ExecutionContext
3333
) extends FrontendErrorHandler:
3434

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

38-
override def notFoundTemplate(using request: RequestHeader): Future[Html] =
38+
override def notFoundTemplate(using RequestHeader): Future[Html] =
3939
Future.successful(error_404_template())
4040

41-
def forbiddenTemplate(using request: RequestHeader): Html =
41+
def forbiddenTemplate(using RequestHeader): Html =
4242
error_403_template()

app/uk/gov/hmrc/cataloguefrontend/service/SearchByUrlService.scala

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,17 @@ import uk.gov.hmrc.cataloguefrontend.connector.RouteConfigurationConnector
2424
import uk.gov.hmrc.cataloguefrontend.model.Environment
2525
import uk.gov.hmrc.http.HeaderCarrier
2626

27-
import scala.concurrent.{ExecutionContext, Future}
27+
import scala.concurrent.Future
2828

2929
@Singleton
3030
class SearchByUrlService @Inject() (
3131
routeConfigurationConnector: RouteConfigurationConnector
32-
)(using ec: ExecutionContext):
32+
):
3333

3434
def searchFrontendPath(
3535
term : Option[String]
3636
, environment: Option[Environment] = Some(Environment.Production)
37-
)(using
37+
)(using
3838
HeaderCarrier
3939
): Future[Seq[Route]] =
4040
if isValidSearchTerm(term)
@@ -48,7 +48,7 @@ class SearchByUrlService @Inject() (
4848
then
4949
false
5050
else
51-
try {
51+
try
5252
val url = URI(term.get)
5353

5454
Option(url.getPath).getOrElse("").nonEmpty
@@ -57,9 +57,8 @@ class SearchByUrlService @Inject() (
5757
&& Option(url.getPath).getOrElse("").contains("tax.service.gov.uk")
5858
&& url.getPath.substring(url.getPath.indexOf(".gov.uk") + 7).trim.nonEmpty
5959
)
60-
} catch {
60+
catch
6161
case e: URISyntaxException => false
62-
}
6362

6463
private def takeUrlPath(term: String): String =
6564
val url = URI(term)
@@ -70,7 +69,7 @@ class SearchByUrlService @Inject() (
7069
else if Option(url.getHost).getOrElse("").trim.isEmpty
7170
&& Option(url.getPath).getOrElse("").contains("tax.service.gov.uk")
7271
then
73-
url.getPath.substring(url.getPath.indexOf(".gov.uk") + 7).trim
72+
url.getPath.substring(url.getPath.indexOf(".gov.uk") + 7).trim
7473
else
7574
url.getPath.trim
7675

app/uk/gov/hmrc/cataloguefrontend/vulnerabilities/model.scala

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,43 +17,36 @@
1717
package uk.gov.hmrc.cataloguefrontend.vulnerabilities
1818

1919
import play.api.libs.functional.syntax._
20-
import play.api.libs.json.{Format, Reads, __}
20+
import play.api.libs.json.{Reads, __}
2121
import uk.gov.hmrc.cataloguefrontend.model.{ServiceName, Version, VersionRange}
2222

2323
import java.time.Instant
2424
import scala.collection.Seq
2525

2626
case class VulnerableComponent(
2727
component: String,
28-
version: String
28+
version : Version
2929
):
30-
// Note two edge cases which would otherwise break the dependency explorer links are handled below:
31-
// 1. A vulnerable version may have another `.` after the patch version.
32-
// 2. An artefact may have a trailing `_someVersionNumber`.
33-
def cleansedVersion: String =
34-
version.split("\\.").take(3).mkString(".")
35-
3630
def group: String =
3731
component.stripPrefix("gav://").split(":")(0)
3832

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

4236
def versionRange: VersionRange =
43-
val v = Version(cleansedVersion)
44-
VersionRange(s"[${v.major}.${v.minor}.${v.patch}]")
37+
VersionRange(s"[${version.major}.${version.minor}.${version.patch}]")
4538

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

4942
end VulnerableComponent
5043

51-
object VulnerableComponent {
52-
val format: Format[VulnerableComponent] =
53-
( (__ \ "component").format[String]
54-
~ (__ \ "version" ).format[String]
55-
)(apply, vc => Tuple.fromProductTyped(vc))
56-
}
44+
object VulnerableComponent:
45+
val reads: Reads[VulnerableComponent] =
46+
given Reads[Version] = Version.format
47+
( (__ \ "component").read[String]
48+
~ (__ \ "version" ).read[Version]
49+
)(apply)
5750

5851
case class DistinctVulnerability(
5952
vulnerableComponentName : String,
@@ -74,7 +67,7 @@ case class DistinctVulnerability(
7467
object DistinctVulnerability {
7568

7669
val reads: Reads[DistinctVulnerability] =
77-
given Format[VulnerableComponent] = VulnerableComponent.format
70+
given Reads[VulnerableComponent] = VulnerableComponent.reads
7871
( (__ \ "vulnerableComponentName" ).read[String]
7972
~ (__ \ "vulnerableComponentVersion").read[String]
8073
~ (__ \ "vulnerableComponents" ).read[Seq[VulnerableComponent]]
@@ -94,7 +87,7 @@ object DistinctVulnerability {
9487
case class VulnerabilityOccurrence(
9588
service : ServiceName,
9689
serviceVersion : String,
97-
componentPathInSlug: String,
90+
componentPathInSlug: String
9891
)
9992

10093
object VulnerabilityOccurrence {

app/uk/gov/hmrc/cataloguefrontend/vulnerabilities/view/VulnerabilitiesListPage.scala.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ <h1 class="page-heading mt-4">Vulnerabilities</h1>
128128
}
129129
</div>
130130

131-
@maybeSummaries.map{ summaries =>
131+
@maybeSummaries.map { summaries =>
132132
@if(summaries.nonEmpty) {
133133
<script @CSPNonce.attr>
134134
let options = {

app/uk/gov/hmrc/cataloguefrontend/vulnerabilities/view/VulnerabilityDetails.scala.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@
6767
<p class="fw-bold">Vulnerable components on platform:</p>
6868
<div class="overflow-x-hidden overflow-y-auto" style="height: 140px;">
6969
<ul>
70-
@vuln.distinctVulnerability.vulnerableComponents.sortWith(_.version > _.version).map { vc =>
70+
@vuln.distinctVulnerability.vulnerableComponents.sortBy(_.version).map { vc =>
7171
<li>
7272
@if(vc.component.startsWith("gav")) {
7373
<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>
@@ -143,7 +143,7 @@
143143
</tr>
144144
</thead>
145145
<tbody>
146-
@vuln.occurrences.map { occ =>
146+
@vuln.occurrences.sortBy(o => (o.service, o.serviceVersion)).map { occ =>
147147
<tr>
148148
<td class="col-3"><a href="@appRoutes.CatalogueController.service(occ.service)">@occ.service.asString</a></td>
149149
<td class="col-1">@occ.serviceVersion</td>

build.sbt

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
1-
import play.core.PlayVersion
2-
import play.sbt.PlayImport.PlayKeys.playDefaultPort
1+
import play.sbt.PlayImport.PlayKeys
32
import play.sbt.routes.RoutesKeys
4-
import uk.gov.hmrc.versioning.SbtGitVersioning
53

64
lazy val microservice = Project("catalogue-frontend", file("."))
75
.enablePlugins(PlayScala, SbtDistributablesPlugin)
86
.disablePlugins(JUnitXmlReportPlugin) //Required to prevent https://github.com/scalatest/scalatest/issues/1427
97
.settings(
108
majorVersion := 5,
119
scalaVersion := "3.3.4",
12-
playDefaultPort := 9017,
10+
PlayKeys.playDefaultPort := 9017,
1311
libraryDependencies ++= compile ++ test,
1412
RoutesKeys.routesImport ++= Seq(
1513
"uk.gov.hmrc.cataloguefrontend.model._",
@@ -35,20 +33,20 @@ lazy val microservice = Project("catalogue-frontend", file("."))
3533
scalacOptions += "-Wconf:src=routes/.*:s",
3634
scalacOptions += "-Wconf:msg=Flag.*repeatedly:s",
3735
//scalacOptions += "-explain",
38-
javaOptions += "-Xmx2G",
36+
Compile / javaOptions += "-Xmx2G", // without `Compile` it breaks sbt start/runProd (Universal scope)
3937
pipelineStages := Seq(digest)
4038
)
4139

42-
val bootstrapPlayVersion = "9.2.0"
43-
val hmrcMongoVersion = "2.2.0"
40+
val bootstrapPlayVersion = "9.5.0"
41+
val hmrcMongoVersion = "2.3.0"
4442

4543
val compile = Seq(
4644
caffeine,
4745
"uk.gov.hmrc" %% "bootstrap-frontend-play-30" % bootstrapPlayVersion,
4846
"uk.gov.hmrc.mongo" %% "hmrc-mongo-play-30" % hmrcMongoVersion,
4947
"uk.gov.hmrc" %% "internal-auth-client-play-30" % "3.0.0",
5048
"org.typelevel" %% "cats-core" % "2.12.0",
51-
"org.yaml" % "snakeyaml" % "2.2",
49+
"org.yaml" % "snakeyaml" % "2.3",
5250
"org.planet42" %% "laika-core" % "0.19.5",
5351
"org.jsoup" % "jsoup" % "1.17.2"
5452
)

project/plugins.sbt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
resolvers += MavenRepository("HMRC-open-artefacts-maven2", "https://open.artefacts.tax.service.gov.uk/maven2")
22
resolvers += Resolver.url("HMRC-open-artefacts-ivy2", url("https://open.artefacts.tax.service.gov.uk/ivy2"))(Resolver.ivyStylePatterns)
33

4-
addSbtPlugin("uk.gov.hmrc" % "sbt-auto-build" % "3.22.0")
4+
addSbtPlugin("uk.gov.hmrc" % "sbt-auto-build" % "3.24.0")
55
addSbtPlugin("uk.gov.hmrc" % "sbt-distributables" % "2.5.0")
6-
addSbtPlugin("org.playframework" % "sbt-plugin" % "3.0.4")
6+
addSbtPlugin("org.playframework" % "sbt-plugin" % "3.0.5")
77
addSbtPlugin("com.typesafe.sbt" % "sbt-digest" % "1.1.4")

test/uk/gov/hmrc/cataloguefrontend/vulnerabilities/VulnerabilitiesConnectorSpec.scala

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@ import org.scalatest.concurrent.{IntegrationPatience, ScalaFutures}
2121
import org.scalatest.matchers.should.Matchers
2222
import org.scalatest.wordspec.AnyWordSpecLike
2323
import play.api.Configuration
24-
import uk.gov.hmrc.cataloguefrontend.model.{ServiceName, SlugInfoFlag}
25-
import uk.gov.hmrc.cataloguefrontend.vulnerabilities.CurationStatus.ActionRequired
24+
import uk.gov.hmrc.cataloguefrontend.model.{ServiceName, SlugInfoFlag, Version}
2625
import uk.gov.hmrc.http.HeaderCarrier
2726
import uk.gov.hmrc.http.test.{HttpClientV2Support, WireMockSupport}
2827
import uk.gov.hmrc.play.bootstrap.config.ServicesConfig
@@ -101,7 +100,7 @@ class VulnerabilitiesConnectorSpec
101100
distinctVulnerability = DistinctVulnerability(
102101
vulnerableComponentName = "deb://ubuntu/xenial:test",
103102
vulnerableComponentVersion = "1.2.5.4-1",
104-
vulnerableComponents = Seq(VulnerableComponent("deb://ubuntu/xenial:test", "1.2.5.4-1")),
103+
vulnerableComponents = Seq(VulnerableComponent("deb://ubuntu/xenial:test", Version("1.2.5.4-1"))),
105104
id = "CVE-123",
106105
score = Some(10.0),
107106
description = "testing",
@@ -110,7 +109,7 @@ class VulnerabilitiesConnectorSpec
110109
publishedDate = Instant.parse("2019-08-20T10:53:37.00Z"),
111110
firstDetected = Some(Instant.parse("2019-08-20T10:53:37.00Z")),
112111
assessment = Some("Serious"),
113-
curationStatus = Some(ActionRequired),
112+
curationStatus = Some(CurationStatus.ActionRequired),
114113
ticket = Some("ticket1")
115114
),
116115
occurrences = Seq(VulnerabilityOccurrence(

0 commit comments

Comments
 (0)