Commit 51209b5e authored by Torsten Grote's avatar Torsten Grote

briar-headless: Add endpoint for removing a contact

parent 822597b4
......@@ -72,9 +72,16 @@ Returns a JSON array of contacts:
The only workaround is to add a contact to the Briar app running on a rooted Android phone
and then move its database (and key files) to the headless peer.
### Removing a contact
`DELETE /v1/contacts/{contactId}`
The `{contactId}` is the `contactId` of the contact (`1` in the example above).
It returns with a status code `200`, if removal was successful.
### Listing all private messages
`GET /messages/{contactId}`
`GET /v1/messages/{contactId}`
The `{contactId}` is the `contactId` of the contact (`1` in the example above).
It returns a JSON array of private messages:
......@@ -100,7 +107,7 @@ Attention: There can messages of other `type`s where the message `text` is `null
### Writing a private message
`POST /messages/{contactId}`
`POST /v1/messages/{contactId}`
The text of the message should be posted as JSON:
......
......@@ -7,9 +7,11 @@ import io.javalin.Context
import io.javalin.Javalin
import io.javalin.JavalinEvent.SERVER_START_FAILED
import io.javalin.JavalinEvent.SERVER_STOPPED
import io.javalin.NotFoundResponse
import io.javalin.apibuilder.ApiBuilder.*
import io.javalin.core.util.ContextUtil
import io.javalin.core.util.Header.AUTHORIZATION
import org.briarproject.bramble.api.contact.ContactId
import org.briarproject.briar.headless.blogs.BlogController
import org.briarproject.briar.headless.contact.ContactController
import org.briarproject.briar.headless.event.WebSocketController
......@@ -63,6 +65,9 @@ constructor(
path("/v1") {
path("/contacts") {
get { ctx -> contactController.list(ctx) }
path("/:contactId") {
delete { ctx -> contactController.delete(ctx) }
}
}
path("/messages/:contactId") {
get { ctx -> messagingController.list(ctx) }
......@@ -112,6 +117,21 @@ constructor(
}
/**
* Returns a [ContactId] from the "contactId" path parameter.
*
* @throws NotFoundResponse when contactId is not a number.
*/
fun Context.getContactIdFromPathParam(): ContactId {
val contactString = pathParam("contactId")
val contactInt = try {
Integer.parseInt(contactString)
} catch (e: NumberFormatException) {
throw NotFoundResponse()
}
return ContactId(contactInt)
}
/**
* Returns a String from the JSON field or throws [BadRequestResponse] if null or empty.
*/
......
......@@ -5,5 +5,6 @@ import io.javalin.Context
interface ContactController {
fun list(ctx: Context): Context
fun delete(ctx: Context): Context
}
package org.briarproject.briar.headless.contact
import io.javalin.Context
import io.javalin.NotFoundResponse
import org.briarproject.bramble.api.contact.ContactManager
import org.briarproject.bramble.api.db.NoSuchContactException
import org.briarproject.briar.headless.getContactIdFromPathParam
import javax.annotation.concurrent.Immutable
import javax.inject.Inject
import javax.inject.Singleton
......@@ -19,4 +22,14 @@ constructor(private val contactManager: ContactManager) : ContactController {
return ctx.json(contacts)
}
override fun delete(ctx: Context): Context {
val contactId = ctx.getContactIdFromPathParam()
try {
contactManager.removeContact(contactId)
} catch (e: NoSuchContactException) {
throw NotFoundResponse()
}
return ctx
}
}
......@@ -26,6 +26,7 @@ import org.briarproject.briar.api.privategroup.invitation.GroupInvitationRequest
import org.briarproject.briar.api.privategroup.invitation.GroupInvitationResponse
import org.briarproject.briar.headless.event.WebSocketController
import org.briarproject.briar.headless.event.output
import org.briarproject.briar.headless.getContactIdFromPathParam
import org.briarproject.briar.headless.getFromJson
import org.briarproject.briar.headless.json.JsonDict
import java.util.concurrent.Executor
......@@ -84,13 +85,7 @@ constructor(
}
private fun getContact(ctx: Context): Contact {
val contactString = ctx.pathParam("contactId")
val contactInt = try {
Integer.parseInt(contactString)
} catch (e: NumberFormatException) {
throw NotFoundResponse()
}
val contactId = ContactId(contactInt)
val contactId = ctx.getContactIdFromPathParam()
return try {
contactManager.getContact(contactId)
} catch (e: NoSuchContactException) {
......
package org.briarproject.briar.headless.contact
import io.javalin.NotFoundResponse
import io.javalin.json.JavalinJson.toJson
import io.mockk.Runs
import io.mockk.every
import io.mockk.just
import org.briarproject.bramble.api.contact.Contact
import org.briarproject.bramble.api.contact.ContactId
import org.briarproject.bramble.api.db.NoSuchContactException
import org.briarproject.bramble.identity.output
import org.briarproject.briar.headless.ControllerTest
import org.junit.jupiter.api.Assertions.assertThrows
import org.junit.jupiter.api.Test
internal class ContactControllerTest : ControllerTest() {
......@@ -25,6 +31,30 @@ internal class ContactControllerTest : ControllerTest() {
controller.list(ctx)
}
@Test
fun testDelete() {
every { ctx.pathParam("contactId") } returns "1"
every { contactManager.removeContact(ContactId(1)) } just Runs
controller.delete(ctx)
}
@Test
fun testDeleteInvalidContactId() {
every { ctx.pathParam("contactId") } returns "foo"
assertThrows(NotFoundResponse::class.java) {
controller.delete(ctx)
}
}
@Test
fun testDeleteNonexistentContactId() {
every { ctx.pathParam("contactId") } returns "1"
every { contactManager.removeContact(ContactId(1)) } throws NoSuchContactException()
assertThrows(NotFoundResponse::class.java) {
controller.delete(ctx)
}
}
@Test
fun testOutputContact() {
val json = """
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment