Skip to content

Commit d22328e

Browse files
authored
šŸž Election deletion fails to remove ACL records and ballot-box datastore directories (#224)
Parent issue: sequentech/meta#10283
1 parent 5f0da0c commit d22328e

File tree

2 files changed

+49
-1
lines changed

2 files changed

+49
-1
lines changed

ā€Žapp/controllers/ElectionsApi.scalaā€Ž

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1513,6 +1513,10 @@ object ElectionsApi
15131513
.flatMap { election =>
15141514
val configJson = Json.parse(election.configuration)
15151515
val config = configJson.validate[ElectionConfig].get
1516+
1517+
// If this is a virtual election, also delete datastores for subelections
1518+
val virtualSubelections = config.virtualSubelections.getOrElse(Array[Long]())
1519+
15161520
val url = eoUrl(config.director, "public_api/delete")
15171521
WS.url(url).post(
15181522
Json.obj(
@@ -1524,9 +1528,20 @@ object ElectionsApi
15241528
} else {
15251529
BadRequest(error(s"EO returned status ${resp.status} with body ${resp.body}", ErrorCodes.EO_ERROR))
15261530
}
1531+
}.map { _ =>
1532+
// Delete the parent election from database
1533+
DAL.elections.delete(id)
1534+
1535+
// Delete datastore for parent election
1536+
Datastore.deleteDatastore(id)
1537+
1538+
// Delete datastores for all virtual subelections
1539+
virtualSubelections.foreach { subElectionId =>
1540+
Logger.info(s"Deleting datastore for virtual subelection $subElectionId of parent election $id")
1541+
Datastore.deleteDatastore(subElectionId)
1542+
}
15271543
}
15281544
}.map { _ =>
1529-
DAL.elections.delete(id)
15301545
Ok(response("ok"))
15311546
}.recover {
15321547
case e: NoSuchElementException =>

ā€Žapp/utils/Datastore.scalaā€Ž

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,39 @@ object Datastore {
191191
}
192192
}
193193

194+
/** Recursively deletes a directory and all its contents */
195+
private def deleteDirectoryRecursively(directory: File): Unit = {
196+
if (directory.isDirectory) {
197+
val files = directory.listFiles()
198+
if (files != null) {
199+
files.foreach { file =>
200+
if (file.isDirectory) {
201+
deleteDirectoryRecursively(file)
202+
} else {
203+
file.delete()
204+
}
205+
}
206+
}
207+
}
208+
directory.delete()
209+
}
210+
211+
/** deletes all datastore directories for an election (both private and public) */
212+
def deleteDatastore(electionId: Long) = {
213+
val privatePath = getDirPath(electionId, public = false).toFile
214+
val publicPath = getDirPath(electionId, public = true).toFile
215+
216+
if (privatePath.exists()) {
217+
Logger.info(s"Deleting private datastore directory for election $electionId: ${privatePath.getAbsolutePath}")
218+
deleteDirectoryRecursively(privatePath)
219+
}
220+
221+
if (publicPath.exists()) {
222+
Logger.info(s"Deleting public datastore directory for election $electionId: ${publicPath.getAbsolutePath}")
223+
deleteDirectoryRecursively(publicPath)
224+
}
225+
}
226+
194227

195228
// UNUSED remove
196229

0 commit comments

Comments
Ā (0)