Skip to content
Snippets Groups Projects
Verified Commit 6560b32e authored by Torsten Grote's avatar Torsten Grote
Browse files

API endpoint for listing readable folders with available files

parent 1662d9ab
No related branches found
No related tags found
1 merge request!28Implement file management API
......@@ -8,6 +8,7 @@ import io.ktor.response.respond
import io.ktor.response.respondFile
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.briarproject.mailbox.core.db.Database
import org.briarproject.mailbox.core.server.AuthException
import org.briarproject.mailbox.core.server.AuthManager
import org.briarproject.mailbox.core.server.MailboxPrincipal
......@@ -16,6 +17,7 @@ import org.briarproject.mailbox.core.system.RandomIdManager
import javax.inject.Inject
class FileManager @Inject constructor(
private val db: Database,
private val authManager: AuthManager,
private val fileProvider: FileProvider,
private val randomIdManager: RandomIdManager,
......@@ -118,12 +120,23 @@ class FileManager @Inject constructor(
val principal: MailboxPrincipal? = call.principal()
authManager.assertIsOwner(principal)
// TODO implement
call.respond(HttpStatusCode.OK, "get: Not yet implemented")
val folderListResponse = withContext(Dispatchers.IO) {
val list = ArrayList<FolderResponse>()
val contacts = db.transactionWithResult(true) { txn -> db.getContacts(txn) }
contacts.forEach { c ->
val id = c.outboxId
val folder = fileProvider.getFolder(id)
if (folder.listFiles()?.isNotEmpty() == true) {
list.add(FolderResponse(id))
}
}
FolderListResponse(list)
}
call.respond(folderListResponse)
}
}
data class FileListResponse(val files: ArrayList<FileResponse>)
data class FileListResponse(val files: List<FileResponse>)
data class FileResponse(val name: String, val time: Long)
data class FolderListResponse(val folders: List<FolderResponse>)
data class FolderResponse(val id: String)
......@@ -221,4 +221,68 @@ class FileManagerIntegrationTest : IntegrationTest() {
}
assertEquals(HttpStatusCode.NotFound.value, response.status.value)
}
@Test
fun `list folders rejects contacts`(): Unit = runBlocking {
val response: HttpResponse = httpClient.get("$baseUrl/folders") {
authenticateWithToken(contact1.token)
}
assertEquals(HttpStatusCode.Unauthorized.value, response.status.value)
}
@Test
fun `list folders allows owner, returns empty result`(): Unit = runBlocking {
val response: HttpResponse = httpClient.get("$baseUrl/folders") {
authenticateWithToken(ownerToken)
}
assertEquals(HttpStatusCode.OK.value, response.status.value)
assertEquals("""{"folders":[]}""", response.readText())
}
@Test
fun `list folders returns more than a single folder`(): Unit = runBlocking {
// contact1 uploads a file
val response1: HttpResponse = httpClient.post("$baseUrl/files/${contact1.outboxId}") {
authenticateWithToken(contact1.token)
body = bytes
}
assertEquals(HttpStatusCode.OK.value, response1.status.value)
// contact2 uploads a file
val response2: HttpResponse = httpClient.post("$baseUrl/files/${contact2.outboxId}") {
authenticateWithToken(contact2.token)
body = bytes
}
assertEquals(HttpStatusCode.OK.value, response2.status.value)
// owner now sees both contacts' outboxes in folders list
val folderListResponse: FolderListResponse = httpClient.get("$baseUrl/folders") {
authenticateWithToken(ownerToken)
}
val folderList =
listOf(FolderResponse(contact1.outboxId), FolderResponse(contact2.outboxId))
assertEquals(FolderListResponse(folderList), folderListResponse)
// get the file IDs to be able to delete them to not interfere with other tests
val fileListResponse1: FileListResponse =
httpClient.get("$baseUrl/files/${contact1.outboxId}") {
authenticateWithToken(ownerToken)
}
val id1 = fileListResponse1.files[0].name
val deleteResponse1: HttpResponse =
httpClient.delete("$baseUrl/files/${contact1.outboxId}/$id1") {
authenticateWithToken(ownerToken)
}
assertEquals(HttpStatusCode.OK.value, deleteResponse1.status.value)
val fileListResponse2: FileListResponse =
httpClient.get("$baseUrl/files/${contact2.outboxId}") {
authenticateWithToken(ownerToken)
}
val id2 = fileListResponse2.files[0].name
val deleteResponse2: HttpResponse =
httpClient.delete("$baseUrl/files/${contact2.outboxId}/$id2") {
authenticateWithToken(ownerToken)
}
assertEquals(HttpStatusCode.OK.value, deleteResponse2.status.value)
}
}
......@@ -13,6 +13,7 @@ import io.mockk.mockk
import io.mockk.mockkStatic
import kotlinx.coroutines.runBlocking
import org.briarproject.mailbox.core.TestUtils.getNewRandomId
import org.briarproject.mailbox.core.db.Database
import org.briarproject.mailbox.core.server.AuthManager
import org.briarproject.mailbox.core.server.MailboxPrincipal
import org.briarproject.mailbox.core.system.RandomIdManager
......@@ -27,11 +28,12 @@ import kotlin.test.assertTrue
class FileManagerTest {
private val db: Database = mockk()
private val authManager: AuthManager = mockk()
private val fileProvider: FileProvider = mockk()
private val randomIdManager = RandomIdManager()
private val fileManager = FileManager(authManager, fileProvider, randomIdManager)
private val fileManager = FileManager(db, authManager, fileProvider, randomIdManager)
private val call: ApplicationCall = mockk()
private val id = getNewRandomId()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment