package services import com.google.inject.Inject import com.mohiva.play.silhouette.api.LoginInfo import com.ysoft.odc.SetDiff import controllers.{ProjectsWithReports, ReportInfo} import models._ import play.api.db.slick.{HasDatabaseConfigProvider, DatabaseConfigProvider} import scala.collection.immutable.Iterable import scala.concurrent.{Future, ExecutionContext} class VulnerabilityNotificationService @Inject() (protected val dbConfigProvider: DatabaseConfigProvider)(implicit executionContext: ExecutionContext) extends HasDatabaseConfigProvider[models.profile.type]{ import dbConfig.driver.api._ import models.tables import models.tables.vulnerabilitySubscriptions def watchedProjectsByUser(identity: LoginInfo) = db.run(vulnerabilitySubscriptions.filter(_.user === identity).result) def subscribe(user: LoginInfo, project: String) = db.run(vulnerabilitySubscriptions += VulnerabilitySubscription(user = user, project = project)) def unsubscribe(user: LoginInfo, project: String) = db.run(vulnerabilitySubscriptions.filter(vs => vs.user === user && vs.project === project).delete) def getRecipientsForProjects(projects: Set[ReportInfo]) = { val bareProjects = projects.map(_.bare) val expandedProjects = projects ++ bareProjects val relevantFullIds = expandedProjects.map(_.fullId) db.run(vulnerabilitySubscriptions.filter(_.project inSet relevantFullIds).map(_.user()).result) } class ExportPlatform[T, U] private[VulnerabilityNotificationService] (ept: ExportPlatformTables[T, U]) { def changeProjects(ticketId: Int, diff: SetDiff[String], projects: ProjectsWithReports) = db.run( DBIO.seq( ept.projects.filter(_.exportedVulnerabilityId === ticketId).delete, ept.projects ++= diff.newSet.map(fullId => ExportedVulnerabilityProject(ticketId, fullId)).toSet ).transactionally ) def projectsForTickets(ticketsIds: Set[Int]): Future[Map[Int, Set[String]]] = db.run( ept.projects.filter(_.exportedVulnerabilityId inSet ticketsIds).result ).map{_.groupBy(_.exportedVulnerabilityId).mapValues(_.map(_.projectFullId).toSet).map(identity).withDefaultValue(Set())} def ticketsForVulnerabilities(vulnerabilities: Traversable[String]) = db.run( ept.tickets.filter(_.vulnerabilityName inSet vulnerabilities).result ).map(_.map{ rec => rec._2.vulnerabilityName -> rec }.toMap) def ticketForVulnerability(vulnerabilityName: String) = db.run( ept.tickets.filter(_.vulnerabilityName === vulnerabilityName).map(_.base).result ).map(_.headOption) def addTicket(vulnerabilityTicket: ExportedVulnerability[T], projects: Set[ReportInfo]): Future[Any] = db.run( ( ept.tickets.map(_.base).returning(ept.tickets.map(_.id)) += vulnerabilityTicket ).flatMap( id => ept.projects ++= projects.map(ri => ExportedVulnerabilityProject(id, ri.fullId)).toSet ).transactionally ) } val issueTrackerExport = new ExportPlatform(tables.issueTrackerExportTables) val mailExport = new ExportPlatform(tables.mailExportTables) }