diff --git a/app/controllers/Statistics.scala b/app/controllers/Statistics.scala index 1f50ffc..e8ce7b0 100644 --- a/app/controllers/Statistics.scala +++ b/app/controllers/Statistics.scala @@ -3,8 +3,9 @@ package controllers import com.github.nscala_time.time.Imports._ import com.google.inject.Inject import com.google.inject.name.Named +import com.ysoft.odc.Confidence.Confidence import com.ysoft.odc.statistics.{LibDepStatistics, TagStatistics} -import com.ysoft.odc.{ArtifactFile, ArtifactItem} +import com.ysoft.odc.{ArtifactFile, ArtifactItem, Hashes} import controllers.DependencyCheckReportsParser.ResultWithSelection import controllers.api.{ApiConfig, ApiController} import models.LibraryTag @@ -21,6 +22,28 @@ final case class ScannedRepository(url: String, branch: String) final case class ScannedProject(name: String, repos: Seq[ScannedRepository], teams: Seq[String], key: String) +final case class GroupedDependencyIdentifier(hashes: Hashes, identifiers: Seq[Identifier]) + +object GroupedDependencyIdentifier{ + def fromGroupedDependency(groupedDependency: GroupedDependency): GroupedDependencyIdentifier = GroupedDependencyIdentifier( + hashes = groupedDependency.hashes, + identifiers = groupedDependency.identifiers.toIndexedSeq.sortBy(_.name) + ) +} + +object Statistics{ + + // TODO: Move this to a better place + + + implicit val hashesWrites = Writes[Hashes](h => JsString(s"${h.sha1}-${h.md5}")) + implicit val confidenceWrites = Writes[Confidence](c => JsString(c.toString)) + implicit val identifierWrites = Json.writes[Identifier] + implicit val groupedDependencyIdentifierWrites = Json.writes[GroupedDependencyIdentifier] + //implicit val groupedDependencyFormats = Json.format[GroupedDependency] + +} + //noinspection TypeAnnotation class Statistics @Inject()( reportsParser: DependencyCheckReportsParser, @@ -41,6 +64,8 @@ class Statistics @Inject()( private val versions = Map[String, Int]() + import Statistics._ + private def notFound()(implicit req: DefaultRequest) = { NotFound(views.html.defaultpages.notFound("GET", req.uri)) } @@ -205,7 +230,6 @@ class Statistics @Inject()( implicit val scannedRepositoryFormat = Json.format[ScannedRepository] implicit val scannedProjectFormats = Json.format[ScannedProject] - def table() = ApiAction(ProjectTable).async{ val RepoFetch = """.*Fetching 'refs/heads/(.*)' from '(.*)'\..*""".r // Bamboo does not seem to have a suitable API, so we are parsing it from logs… val (lastRefreshTime, resultsFuture) = projectReportsProvider.resultsForVersions(versions) @@ -221,6 +245,18 @@ class Statistics @Inject()( } } + def allDependencies(selectorOption: Option[String]) = ApiAction(Dependencies).async { implicit req => + val (lastRefreshTime, resultsFuture) = projectReportsProvider.resultsForVersions(versions) + resultsFuture flatMap { allResults => + select(allResults, selectorOption).fold(Future.successful(NotFound(Json.obj("error" -> "not found")))){ selection => + Future.successful(Ok(Json.toJson( + selection.result.groupedDependencies.map(gd => GroupedDependencyIdentifier.fromGroupedDependency(gd)).sortBy(gdi => (gdi.identifiers.map(_.name).mkString(", "), gdi.hashes.sha1, gdi.hashes.md5)) + ))) + } + } + } + + def vulnerableLibraries(selectorOption: Option[String]) = ReadAction.async { implicit req => val (lastRefreshTime, resultsFuture) = projectReportsProvider.resultsForVersions(versions) diff --git a/app/controllers/api/ApiResources.scala b/app/controllers/api/ApiResources.scala index 3cbc762..860234c 100644 --- a/app/controllers/api/ApiResources.scala +++ b/app/controllers/api/ApiResources.scala @@ -2,10 +2,11 @@ package controllers.api trait ApiResources { val ProjectTable = ApiResource("project-table") + val Dependencies = ApiResource("dependencies") } object ApiResources extends ApiResources{ - val All = Set(ProjectTable) + val All = Set(ProjectTable, Dependencies) private val AllByName = All.map(res => res.name -> res).toMap def byName(name: String): Option[ApiResource] = AllByName.get(name) } \ No newline at end of file diff --git a/conf/routes b/conf/routes index 3608379..153908f 100644 --- a/conf/routes +++ b/conf/routes @@ -5,6 +5,7 @@ # Home page GET / controllers.Application.homepage() GET /api/table controllers.Statistics.table() +GET /api/all-dependencies.json controllers.Statistics.allDependencies(selector: Option[String]) GET /status controllers.Application.index(versions: Map[String, Int] = Map()) GET /versions controllers.Application.index(versions: Map[String, Int]) GET /dependencies controllers.Application.dependencies(classified: Option[Boolean] = None, requiredTags: Seq[Int] ?= Seq(), noTag: Boolean ?= false)