Added API endpoint for statistics.

This commit is contained in:
Šesták Vít
2018-03-21 10:11:48 +01:00
parent dcc109a729
commit e6e9d4c940
2 changed files with 31 additions and 0 deletions

View File

@@ -92,6 +92,7 @@ object Statistics{
//implicit val groupedDependencyFormats = Json.format[GroupedDependency]
implicit val groupedVulnerableDependencyDetailedIdentifierWrites = Json.writes[GroupedVulnerableDependencyDetailedIdentifier]
implicit val canonizedGroupedVulnerableDependencyDetailedIdentifierWrites = Json.writes[CanonizedGroupedVulnerableDependencyDetailedIdentifier]
}
//noinspection TypeAnnotation
@@ -475,4 +476,33 @@ class Statistics @Inject()(
}
def librariesCountApi(selector: Option[String], operator: Option[String], threshold: Option[Double], strict: Boolean) = ApiAction(Dependencies).async{ implicit req =>
val (lastRefreshTime, resultsFuture) = projectReportsProvider.resultsForVersions(versions)
val vulnLibFilterOrError: Either[GroupedDependency => Boolean, String] = (operator, threshold) match {
case (Some("gte"|">="|"≥"), Some(num)) => Left(_.vulnerabilities.exists(_.cvssScore.exists(_>=num)))
case (Some("gt"|">"), Some(num)) => Left(_.vulnerabilities.exists(_.cvssScore.exists(_>num)))
// Other operators are currently not defined due to unclear semantics when some library has multiple vulnerabilities with various severities
case (None, None) => Left(_ => true)
case _ => Right("Bad combination of operator and number. Supported operators are gt and gte or their variants (>, >=, ≥).")
}
vulnLibFilterOrError match {
case Left(vulnLibFilter) =>
resultsFuture flatMap { allResults =>
select(allResults, selector).fold(Future.successful(NotFound(Json.obj("error" -> "not found")))) { selection =>
val reports = selection.result
if (reports.failedProjects.nonEmpty && strict) {
Future.successful(InternalServerError(Json.obj("error" -> "I don't have all results I need.")))
} else {
Future.successful(Ok(Json.toJson(Map(
"all" -> reports.groupedDependencies.size,
"vulnerable" -> reports.vulnerableDependencies.count(vulnLibFilter)
))))
}
}
}
case Right(error) => Future.successful(BadRequest(Json.obj("error" -> error)))
}
}
}

View File

@@ -4,6 +4,7 @@
# Home page
GET / controllers.Application.homepage()
GET /api/stats/libraries/count.json controllers.Statistics.librariesCountApi(selector: Option[String], operator: Option[String], threshold: Option[Double], strict: Boolean)
GET /api/table controllers.Statistics.table()
GET /api/all-dependencies.json controllers.Statistics.allDependencies(selector: Option[String])
GET /api/all-dependencies-verbose.json controllers.Statistics.allDependenciesVerbose(selector: Option[String])