From 49230f3d77bfa280ed42f27902147475a4ad496d Mon Sep 17 00:00:00 2001 From: Tiago Lopes Date: Tue, 5 Jun 2018 00:51:37 +0100 Subject: [PATCH] Fixed bug in client js. Added search functionality for generic collection routes (Home, Dependencies and Licenses). --- build.gradle | 2 +- .../database/entities/ReportPk.kt | 2 +- .../uiController/ReportFilterController.kt | 75 ----------- .../controller}/ReportController.kt | 9 +- .../controller/ReportFilterController.kt | 127 ++++++++++++++++++ .../service}/ReportFilterService.kt | 42 +++--- .../service}/ReportService.kt | 6 +- .../resources/static/javascript/clientJs.js | 12 +- .../resources/templates/dependencies.mustache | 12 ++ .../templates/dependency-list.mustache | 32 ++--- .../templates/generic-licenses.mustache | 8 ++ src/main/resources/templates/home.mustache | 29 ++-- .../resources/templates/license-list.mustache | 19 +-- .../resources/templates/licenses.mustache | 10 +- .../resources/templates/projects.mustache | 9 ++ 15 files changed, 243 insertions(+), 151 deletions(-) delete mode 100644 src/main/kotlin/com/github/ptosda/projectvalidationmanager/uiController/ReportFilterController.kt rename src/main/kotlin/com/github/ptosda/projectvalidationmanager/{uiController => webapp/controller}/ReportController.kt (96%) create mode 100644 src/main/kotlin/com/github/ptosda/projectvalidationmanager/webapp/controller/ReportFilterController.kt rename src/main/kotlin/com/github/ptosda/projectvalidationmanager/{uiController => webapp/service}/ReportFilterService.kt (76%) rename src/main/kotlin/com/github/ptosda/projectvalidationmanager/{uiController => webapp/service}/ReportService.kt (83%) create mode 100644 src/main/resources/templates/dependencies.mustache create mode 100644 src/main/resources/templates/generic-licenses.mustache create mode 100644 src/main/resources/templates/projects.mustache diff --git a/build.gradle b/build.gradle index 917bbab..e205ff2 100644 --- a/build.gradle +++ b/build.gradle @@ -47,7 +47,7 @@ repositories { } configurations { - all*.exclude module : 'spring-boot-starter-logging' + all*.exclude module : 'slf4j-simple' } dependencies { diff --git a/src/main/kotlin/com/github/ptosda/projectvalidationmanager/database/entities/ReportPk.kt b/src/main/kotlin/com/github/ptosda/projectvalidationmanager/database/entities/ReportPk.kt index 90d4a96..97e3875 100644 --- a/src/main/kotlin/com/github/ptosda/projectvalidationmanager/database/entities/ReportPk.kt +++ b/src/main/kotlin/com/github/ptosda/projectvalidationmanager/database/entities/ReportPk.kt @@ -7,7 +7,7 @@ import javax.persistence.ManyToOne @Embeddable class ReportPk( - val timestamp: String, + val timestamp: String, // TODO Edit to a human readable DateTime @ManyToOne @JoinColumn(name = "name") diff --git a/src/main/kotlin/com/github/ptosda/projectvalidationmanager/uiController/ReportFilterController.kt b/src/main/kotlin/com/github/ptosda/projectvalidationmanager/uiController/ReportFilterController.kt deleted file mode 100644 index 677d169..0000000 --- a/src/main/kotlin/com/github/ptosda/projectvalidationmanager/uiController/ReportFilterController.kt +++ /dev/null @@ -1,75 +0,0 @@ -package com.github.ptosda.projectvalidationmanager.uiController - -import com.github.ptosda.projectvalidationmanager.database.entities.Project -import com.github.ptosda.projectvalidationmanager.database.repositories.ProjectRepository -import org.springframework.stereotype.Controller -import org.springframework.web.bind.annotation.GetMapping -import org.springframework.web.bind.annotation.PathVariable -import org.springframework.web.bind.annotation.RequestMapping - -@Controller -@RequestMapping("/") -class ReportFilterController(val reportFilterService: ReportFilterService, - val projectRepo: ProjectRepository) { - - /** - * HashMap with all project filter types and corresponding functions - */ - val projectFilterFunctions = hashMapOf HashMap>( - "detail" to { project -> reportFilterService.getProjectDetailView(project) }, - "licenses" to { project -> reportFilterService.getProjectLicensesView(project) }, - "vulnerabilities" to { project -> reportFilterService.getProjectVulnerabilitiesView(project) } - ) - - /** - * HashMap with all report filter types and corresponding functions - */ - val buildFilterFunctions = hashMapOf HashMap>( - "detail" to { projectId, buildId -> reportFilterService.getBuildDetailView(projectId, buildId) }, - "licenses" to { projectId, buildId -> reportFilterService.getBuildLicensesView(projectId, buildId) }, - "vulnerabilities" to { projectId, buildId -> reportFilterService.getBuildVulnerabilitiesView(projectId, buildId) } - ) - - /** - * Gets the view for either of three elements of a Project. These are its detail, licenses or vulnerabilities - * @param projectId the if of the project to filter - * @param filterType the type of filtering to be done (detail, licenses or vulnerabilities) - */ - @GetMapping("projs/{project-id}/filter/{filter-type}") - fun filterProject(@PathVariable("project-id") projectId: String, - @PathVariable("filter-type") filterType: String, - model: HashMap) : String - { - - val projectInfo = projectRepo.findById(projectId) - - if(!projectInfo.isPresent) { - throw Exception("Project doesn't exist") - } - - val project = projectInfo.get() - - - model.putAll(projectFilterFunctions[filterType]!!.invoke(project)) - - return model["view_name"].toString() - } - - /** - * Gets the view for either three elements of a Report. These are its detail, licenses or vulnerabilities - * @param projectId the if of the project that the report belongs - * @param buildId the if of the report to filter - * @param filterType the type of filtering to be done (detail, licenses or vulnerabilities) - */ - @GetMapping("projs/{project-id}/report/{report-id}/filter/{filter-type}") - fun filterBuild(@PathVariable("project-id") projectId: String, - @PathVariable("report-id") buildId: String, - @PathVariable("filter-type") filterType: String, - model: HashMap) : String - { - - model.putAll(buildFilterFunctions[filterType]!!.invoke(projectId, buildId)) - - return model["view_name"].toString() - } -} \ No newline at end of file diff --git a/src/main/kotlin/com/github/ptosda/projectvalidationmanager/uiController/ReportController.kt b/src/main/kotlin/com/github/ptosda/projectvalidationmanager/webapp/controller/ReportController.kt similarity index 96% rename from src/main/kotlin/com/github/ptosda/projectvalidationmanager/uiController/ReportController.kt rename to src/main/kotlin/com/github/ptosda/projectvalidationmanager/webapp/controller/ReportController.kt index 1035281..d07afbf 100644 --- a/src/main/kotlin/com/github/ptosda/projectvalidationmanager/uiController/ReportController.kt +++ b/src/main/kotlin/com/github/ptosda/projectvalidationmanager/webapp/controller/ReportController.kt @@ -1,7 +1,8 @@ -package com.github.ptosda.projectvalidationmanager.uiController +package com.github.ptosda.projectvalidationmanager.webapp.controller import com.github.ptosda.projectvalidationmanager.database.entities.* import com.github.ptosda.projectvalidationmanager.database.repositories.* +import com.github.ptosda.projectvalidationmanager.webapp.service.ReportService import org.springframework.stereotype.Controller import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PathVariable @@ -9,7 +10,7 @@ import org.springframework.web.bind.annotation.RequestMapping import kotlin.collections.set /** - * Controller for the UI + * Controller for the WebApp */ @Controller @RequestMapping("/") @@ -36,7 +37,6 @@ class ReportController(val reportService: ReportService, /** * Gets the view for the collection of dependencies - * TODO need to show generic dependencies when any is clicked and not specific */ @GetMapping("deps") fun getDependencies(model: HashMap) : String @@ -56,6 +56,7 @@ class ReportController(val reportService: ReportService, * Gets the view of a dependency * @param dependencyId the id of the dependency to show * @param dependencyVersion the version of the dependency to show + * TODO differentiate projects and detail of dependency */ @GetMapping("deps/{dep-id}/version/{dep-version}") fun getDependencyGeneric(@PathVariable("dep-id") dependencyId : String, @@ -134,7 +135,7 @@ class ReportController(val reportService: ReportService, model["report_id"] = reportId model["report_tag"] = report.tag - model.putAll(reportService.getBuildDependencies(report)) + model.putAll(reportService.getReportDependencies(report)) return "report" } diff --git a/src/main/kotlin/com/github/ptosda/projectvalidationmanager/webapp/controller/ReportFilterController.kt b/src/main/kotlin/com/github/ptosda/projectvalidationmanager/webapp/controller/ReportFilterController.kt new file mode 100644 index 0000000..79fda84 --- /dev/null +++ b/src/main/kotlin/com/github/ptosda/projectvalidationmanager/webapp/controller/ReportFilterController.kt @@ -0,0 +1,127 @@ +package com.github.ptosda.projectvalidationmanager.webapp.controller + +import com.github.ptosda.projectvalidationmanager.database.entities.Project +import com.github.ptosda.projectvalidationmanager.database.repositories.DependencyRepository +import com.github.ptosda.projectvalidationmanager.database.repositories.LicenseRepository +import com.github.ptosda.projectvalidationmanager.database.repositories.ProjectRepository +import com.github.ptosda.projectvalidationmanager.webapp.service.ReportFilterService +import org.springframework.stereotype.Controller +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.PathVariable +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RequestParam + +@Controller +@RequestMapping("/") +class ReportFilterController(val reportFilterService: ReportFilterService, + val projectRepo: ProjectRepository, + val dependencyRepo: DependencyRepository, + val licenseRepo: LicenseRepository) +{ + + /** + * HashMap with all project filter types and corresponding functions + */ + val projectFilterFunctions = hashMapOf HashMap>( + "detail" to { project -> reportFilterService.getProjectDetailView(project) }, + "licenses" to { project -> reportFilterService.getProjectLicensesView(project) }, + "vulnerabilities" to { project -> reportFilterService.getProjectVulnerabilitiesView(project) } + ) + + /** + * HashMap with all report filter types and corresponding functions + */ + val buildFilterFunctions = hashMapOf HashMap>( + "detail" to { projectId, buildId -> reportFilterService.getReportDetailView(projectId, buildId) }, + "licenses" to { projectId, buildId -> reportFilterService.getReportLicensesView(projectId, buildId) }, + "vulnerabilities" to { projectId, buildId -> reportFilterService.getReportVulnerabilitiesView(projectId, buildId) } + ) + + /** + * HashMap with all report search functions + */ + val searchFilterFunctions = hashMapOf HashMap>( + "projs" to { searchText -> + hashMapOf( "projects" to projectRepo.findAll().filter { it.name.startsWith(searchText, true) }, + "view_name" to "projects" + ) + }, + "dependencies" to { searchText -> + hashMapOf("dependencies" to dependencyRepo.findAll() + .groupBy { it.pk.id + it.pk.mainVersion } + .values + .map { it.last() } + .sortedBy{ it.pk.id } + .filter { it.pk.id.startsWith(searchText, true) }, + "view_name" to "dependencies" + ) + }, + "licenses" to { searchText -> + hashMapOf( "licenses" to licenseRepo.findAll().filter { it.spdxId.trimStart('(').startsWith(searchText, true) }, + "view_name" to "generic-licenses" + ) + } + ) + + /** + * Gets the view for either of three elements of a Project. These are its detail, licenses or vulnerabilities + * @param projectId the if of the project to filter + * @param filterType the type of filtering to be done (detail, licenses or vulnerabilities) + * @param model hash map to store all view related information + */ + @GetMapping("projs/{project-id}/filter/{filter-type}") + fun filterProject(@PathVariable("project-id") projectId: String, + @PathVariable("filter-type") filterType: String, + model: HashMap) : String + { + + val projectInfo = projectRepo.findById(projectId) + + if(!projectInfo.isPresent) { + throw Exception("Project doesn't exist") + } + + val project = projectInfo.get() + + + model.putAll(projectFilterFunctions[filterType]!!.invoke(project)) + + return model["view_name"].toString() + } + + /** + * Gets the view for any of the three possible elements of a Report. These are its detail, licenses or vulnerabilities + * @param projectId the if of the project that the report belongs + * @param buildId the if of the report to filter + * @param filterType the type of filtering to be done (detail, licenses or vulnerabilities) + * @param model hash map to store all view related information + */ + @GetMapping("projs/{project-id}/report/{report-id}/filter/{filter-type}") + fun filterBuild(@PathVariable("project-id") projectId: String, + @PathVariable("report-id") buildId: String, + @PathVariable("filter-type") filterType: String, + model: HashMap) : String + { + + model.putAll(buildFilterFunctions[filterType]!!.invoke(projectId, buildId)) + + return model["view_name"].toString() + } + + /** + * Gets the view for a search request + * @param searchType the type of search to be done + * @param searchValue the value used in the search + * @param model hash map to store all view related information + */ + @GetMapping("search/{search-type}") + fun search(@PathVariable("search-type") searchType: String, + @RequestParam("value") searchValue: String, + model: HashMap) : String + { + + model.putAll(searchFilterFunctions[searchType]!!.invoke(searchValue)) + + return model["view_name"].toString() + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/github/ptosda/projectvalidationmanager/uiController/ReportFilterService.kt b/src/main/kotlin/com/github/ptosda/projectvalidationmanager/webapp/service/ReportFilterService.kt similarity index 76% rename from src/main/kotlin/com/github/ptosda/projectvalidationmanager/uiController/ReportFilterService.kt rename to src/main/kotlin/com/github/ptosda/projectvalidationmanager/webapp/service/ReportFilterService.kt index ae4bb66..5095b28 100644 --- a/src/main/kotlin/com/github/ptosda/projectvalidationmanager/uiController/ReportFilterService.kt +++ b/src/main/kotlin/com/github/ptosda/projectvalidationmanager/webapp/service/ReportFilterService.kt @@ -1,4 +1,4 @@ -package com.github.ptosda.projectvalidationmanager.uiController +package com.github.ptosda.projectvalidationmanager.webapp.service import com.github.ptosda.projectvalidationmanager.database.entities.* import com.github.ptosda.projectvalidationmanager.database.repositories.ReportRepository @@ -30,23 +30,23 @@ class ReportFilterService(private val reportService: ReportService, * @param projectId the id of the project * @param reportId the id of the report to filter */ - fun getBuildDetailView(projectId: String, reportId: String) : HashMap { + fun getReportDetailView(projectId: String, reportId: String) : HashMap { val model = hashMapOf() - val buildInfo = reportRepo.findById(ReportPk(reportId, Project(projectId, null, null))) + val reportInfo = reportRepo.findById(ReportPk(reportId, Project(projectId, null, null))) - if(!buildInfo.isPresent) { + if(!reportInfo.isPresent) { throw Exception("Report was not found") } - val build = buildInfo.get() + val report = reportInfo.get() model["project_id"] = projectId model["report_id"] = reportId - model["report_tag"] = build.tag + model["report_tag"] = report.tag - model.putAll(reportService.getBuildDependencies(build)) + model.putAll(reportService.getReportDependencies(report)) model["view_name"] = "report-detail" @@ -80,9 +80,9 @@ class ReportFilterService(private val reportService: ReportService, val model = hashMapOf() val licenses = ArrayList() - val build = getProjectLatestBuild(project) + val report = getProjectLatestBuild(project) - build.dependency?.forEach { + report.dependency?.forEach { licenses.addAll(it.license) } @@ -97,20 +97,20 @@ class ReportFilterService(private val reportService: ReportService, * @param projectId the id of the project * @param reportId the id of the report to filter */ - fun getBuildLicensesView(projectId: String, reportId: String) : HashMap { + fun getReportLicensesView(projectId: String, reportId: String) : HashMap { val model = hashMapOf() - val buildInfo = reportRepo.findById(ReportPk(reportId, Project(projectId, null, null))) + val reportInfo = reportRepo.findById(ReportPk(reportId, Project(projectId, null, null))) - if(!buildInfo.isPresent) { + if(!reportInfo.isPresent) { throw Exception("Report was not found") } - val build = buildInfo.get() + val report = reportInfo.get() val licenses = ArrayList() - build.dependency!!.forEach { + report.dependency!!.forEach { licenses.addAll(it.license) } @@ -129,9 +129,9 @@ class ReportFilterService(private val reportService: ReportService, val model = hashMapOf() val vulnerabilities = ArrayList() - val build = getProjectLatestBuild(project) + val report = getProjectLatestBuild(project) - build.dependency?.forEach { + report.dependency?.forEach { vulnerabilities.addAll(it.vulnerabilities) } @@ -146,20 +146,20 @@ class ReportFilterService(private val reportService: ReportService, * @param projectId the id of the project * @param reportId the id of the report to filter */ - fun getBuildVulnerabilitiesView(projectId: String, reportId: String) : HashMap { + fun getReportVulnerabilitiesView(projectId: String, reportId: String) : HashMap { val model = hashMapOf() - val buildInfo = reportRepo.findById(ReportPk(reportId, Project(projectId, null, null))) + val reportInfo = reportRepo.findById(ReportPk(reportId, Project(projectId, null, null))) - if(!buildInfo.isPresent) { + if(!reportInfo.isPresent) { throw Exception("Report was not found") } - val build = buildInfo.get() + val report = reportInfo.get() val vulnerabilities = ArrayList() - build.dependency!!.forEach { + report.dependency!!.forEach { vulnerabilities.addAll(it.vulnerabilities) } diff --git a/src/main/kotlin/com/github/ptosda/projectvalidationmanager/uiController/ReportService.kt b/src/main/kotlin/com/github/ptosda/projectvalidationmanager/webapp/service/ReportService.kt similarity index 83% rename from src/main/kotlin/com/github/ptosda/projectvalidationmanager/uiController/ReportService.kt rename to src/main/kotlin/com/github/ptosda/projectvalidationmanager/webapp/service/ReportService.kt index 857a911..539c188 100644 --- a/src/main/kotlin/com/github/ptosda/projectvalidationmanager/uiController/ReportService.kt +++ b/src/main/kotlin/com/github/ptosda/projectvalidationmanager/webapp/service/ReportService.kt @@ -1,15 +1,16 @@ -package com.github.ptosda.projectvalidationmanager.uiController +package com.github.ptosda.projectvalidationmanager.webapp.service import com.github.ptosda.projectvalidationmanager.database.entities.* import org.springframework.stereotype.Service @Service class ReportService { + /** * Gets an HashMap with both vulnerable and not vulnerable dependencies * @param report the report to search for dependencies */ - fun getBuildDependencies(report: Report): Map> { + fun getReportDependencies(report: Report): Map> { val vulnerable = arrayListOf() val notVulnerable = arrayListOf() @@ -25,4 +26,5 @@ class ReportService { return hashMapOf("vulnerable_dependencies" to vulnerable, "dependencies" to notVulnerable) } + } \ No newline at end of file diff --git a/src/main/resources/static/javascript/clientJs.js b/src/main/resources/static/javascript/clientJs.js index fcb5d54..dc5528e 100644 --- a/src/main/resources/static/javascript/clientJs.js +++ b/src/main/resources/static/javascript/clientJs.js @@ -21,6 +21,15 @@ function httpRequest(method, path, data, cb) { xhr.send(data); } +function search(searchElemId, searchRelUrl, searchOutputElemId) { + var searchValue = document.getElementById(searchElemId).value + var outputElement = document.getElementById(searchOutputElemId) + + httpRequest('GET', `/${searchRelUrl}?value=${searchValue}`, null, function(err, data) { + outputElement.innerHTML = data + }) +} + window.onload = function() { var informationToShow = document.getElementById('show-information') @@ -29,8 +38,7 @@ window.onload = function() { .forEach(function (elem) { elem.addEventListener('click', function () { var filter = elem.firstElementChild.getAttribute('name') - - httpRequest('GET', 'http://localhost:8080/' + filter, null, function(err, data) { + httpRequest('GET', `/${filter}`, null, function(err, data) { informationToShow.innerHTML = data }) }) diff --git a/src/main/resources/templates/dependencies.mustache b/src/main/resources/templates/dependencies.mustache new file mode 100644 index 0000000..e7d8ad1 --- /dev/null +++ b/src/main/resources/templates/dependencies.mustache @@ -0,0 +1,12 @@ + \ No newline at end of file diff --git a/src/main/resources/templates/dependency-list.mustache b/src/main/resources/templates/dependency-list.mustache index 5d56938..d5fff36 100644 --- a/src/main/resources/templates/dependency-list.mustache +++ b/src/main/resources/templates/dependency-list.mustache @@ -1,27 +1,23 @@ {{> header}} -

- Dependencies -

+

+ Dependencies +

-
+
-
- - + +

+ +
+ {{> dependencies}} +
-
+ {{> footer}} \ No newline at end of file diff --git a/src/main/resources/templates/generic-licenses.mustache b/src/main/resources/templates/generic-licenses.mustache new file mode 100644 index 0000000..b1bf483 --- /dev/null +++ b/src/main/resources/templates/generic-licenses.mustache @@ -0,0 +1,8 @@ + \ No newline at end of file diff --git a/src/main/resources/templates/home.mustache b/src/main/resources/templates/home.mustache index 676e000..92d6aab 100644 --- a/src/main/resources/templates/home.mustache +++ b/src/main/resources/templates/home.mustache @@ -1,26 +1,23 @@ {{> header}} -

- Projects -

+

+ Projects +

-
+
-
+
+

+ +
+ +

-
-
- {{#projects}} - - Name: {{name}} - - -
- {{/projects}} +
+ {{> projects}}
-
-
+
{{> footer}} \ No newline at end of file diff --git a/src/main/resources/templates/license-list.mustache b/src/main/resources/templates/license-list.mustache index ebca823..6187601 100644 --- a/src/main/resources/templates/license-list.mustache +++ b/src/main/resources/templates/license-list.mustache @@ -5,15 +5,18 @@ Licenses +
+
- +

+ +
+ +

+ +
+ {{> generic-licenses}} +
{{> footer}} \ No newline at end of file diff --git a/src/main/resources/templates/licenses.mustache b/src/main/resources/templates/licenses.mustache index ad08cae..38913a2 100644 --- a/src/main/resources/templates/licenses.mustache +++ b/src/main/resources/templates/licenses.mustache @@ -3,9 +3,13 @@ License Name: {{pk.license.spdxId}}
- Dependency: {{pk.dependency.pk.id}} -
- Source: {{source}} + {{#pk.dependency.pk.id}} + Dependency: {{pk.dependency.pk.id}} +
+ {{/pk.dependency.pk.id}} + {{#source}} + Source: {{source}} + {{/source}}

{{/licenses}} diff --git a/src/main/resources/templates/projects.mustache b/src/main/resources/templates/projects.mustache new file mode 100644 index 0000000..279d572 --- /dev/null +++ b/src/main/resources/templates/projects.mustache @@ -0,0 +1,9 @@ + \ No newline at end of file