Remove pending contact state from the database.

This commit is contained in:
akwizgran
2019-05-22 11:25:05 +01:00
parent da5d442c91
commit 01ef367864
25 changed files with 286 additions and 171 deletions

View File

@@ -107,11 +107,27 @@ Until it is completed, a pending contact is returned as JSON:
{
"pendingContactId": "jsTgWcsEQ2g9rnomeK1g/hmO8M1Ix6ZIGWAjgBtlS9U=",
"alias": "ztatsaajzeegraqcizbbfftofdekclatyht",
"state": "adding_contact",
"timestamp": 1557838312175
}
```
It is possible to get a list of all pending contacts:
`GET /v1/contacts/add/pending`
This will return a JSON array of pending contacts and their states:
```json
{
"pendingContact": {
"pendingContactId": "jsTgWcsEQ2g9rnomeK1g/hmO8M1Ix6ZIGWAjgBtlS9U=",
"alias": "ztatsaajzeegraqcizbbfftofdekclatyht",
"timestamp": 1557838312175
},
"state": "adding_contact"
}
```
The state can be one of these values:
* `waiting_for_connection`
@@ -119,21 +135,16 @@ The state can be one of these values:
* `adding_contact`
* `failed`
If you want to get informed about state changes,
If you want to be informed about state changes,
you can use the Websocket API (below) to listen for events.
The following events are relevant here:
* `PendingContactAddedEvent`
* `PendingContactStateChangedEvent`
* `PendingContactRemovedEvent`
* `ContactAddedRemotelyEvent` (when the pending contact becomes an actual contact)
It is possible to get a list of all pending contacts:
`GET /v1/contacts/add/pending`
This will return a JSON array of pending contacts formatted as shown above.
To remove a pending contact and abort the process of adding it:
`DELETE /v1/contacts/add/pending`
@@ -302,6 +313,22 @@ it will send a JSON object representing the new contact to connected websocket c
}
```
### A pending contact was added
```json
{
"data": {
"pendingContact": {
"pendingContactId": "jsTgWcsEQ2g9rnomeK1g/hmO8M1Ix6ZIGWAjgBtlS9U=",
"alias": "ztatsaajzeegraqcizbbfftofdekclatyht",
"timestamp": 1557838312175
}
},
"name": "PendingContactAddedEvent",
"type": "event"
}
```
### A pending contact changed its state
```json

View File

@@ -8,6 +8,7 @@ import org.briarproject.bramble.api.contact.ContactManager
import org.briarproject.bramble.api.contact.HandshakeLinkConstants.LINK_REGEX
import org.briarproject.bramble.api.contact.PendingContactId
import org.briarproject.bramble.api.contact.event.ContactAddedRemotelyEvent
import org.briarproject.bramble.api.contact.event.PendingContactAddedEvent
import org.briarproject.bramble.api.contact.event.PendingContactRemovedEvent
import org.briarproject.bramble.api.contact.event.PendingContactStateChangedEvent
import org.briarproject.bramble.api.db.NoSuchContactException
@@ -28,6 +29,7 @@ import javax.inject.Singleton
internal const val EVENT_CONTACT_ADDED_REMOTELY = "ContactAddedRemotelyEvent"
internal const val EVENT_PENDING_CONTACT_STATE_CHANGED = "PendingContactStateChangedEvent"
internal const val EVENT_PENDING_CONTACT_ADDED = "PendingContactAddedEvent"
internal const val EVENT_PENDING_CONTACT_REMOVED = "PendingContactRemovedEvent"
@Immutable
@@ -47,6 +49,9 @@ constructor(
is PendingContactStateChangedEvent -> {
webSocket.sendEvent(EVENT_PENDING_CONTACT_STATE_CHANGED, e.output())
}
is PendingContactAddedEvent -> {
webSocket.sendEvent(EVENT_PENDING_CONTACT_ADDED, e.output())
}
is PendingContactRemovedEvent -> {
webSocket.sendEvent(EVENT_PENDING_CONTACT_REMOVED, e.output())
}
@@ -78,8 +83,8 @@ constructor(
}
override fun listPendingContacts(ctx: Context): Context {
val pendingContacts = contactManager.pendingContacts.map { pendingContact ->
pendingContact.output()
val pendingContacts = contactManager.pendingContacts.map { pair ->
JsonDict("pendingContact" to pair.first.output(), "state" to pair.second.output())
}
return ctx.json(pendingContacts)
}

View File

@@ -3,6 +3,7 @@ package org.briarproject.briar.headless.contact
import org.briarproject.bramble.api.contact.PendingContact
import org.briarproject.bramble.api.contact.PendingContactState
import org.briarproject.bramble.api.contact.PendingContactState.*
import org.briarproject.bramble.api.contact.event.PendingContactAddedEvent
import org.briarproject.bramble.api.contact.event.PendingContactRemovedEvent
import org.briarproject.bramble.api.contact.event.PendingContactStateChangedEvent
import org.briarproject.briar.headless.json.JsonDict
@@ -10,7 +11,6 @@ import org.briarproject.briar.headless.json.JsonDict
internal fun PendingContact.output() = JsonDict(
"pendingContactId" to id.bytes,
"alias" to alias,
"state" to state.output(),
"timestamp" to timestamp
)
@@ -22,6 +22,10 @@ internal fun PendingContactState.output() = when(this) {
else -> throw AssertionError()
}
internal fun PendingContactAddedEvent.output() = JsonDict(
"pendingContact" to pendingContact.output()
)
internal fun PendingContactStateChangedEvent.output() = JsonDict(
"pendingContactId" to id.bytes,
"state" to pendingContactState.output()

View File

@@ -11,7 +11,7 @@ import org.junit.jupiter.api.Test
class ContactControllerIntegrationTest: IntegrationTest() {
@Test
fun `list of contacts need authentication token`() {
fun `returning list of contacts needs authentication token`() {
val response = getWithWrongToken("$url/contacts")
assertEquals(401, response.statusCode)
}
@@ -72,11 +72,10 @@ class ContactControllerIntegrationTest: IntegrationTest() {
assertEquals(200, response.statusCode)
assertEquals(1, response.jsonArray.length())
val jsonObject = response.jsonArray.getJSONObject(0)
assertEquals(alias, jsonObject.getString("alias"))
assertEquals("waiting_for_connection", jsonObject.getString("state"))
assertEquals(alias, jsonObject.getJSONObject("pendingContact").getString("alias"))
// remove pending contact again
val idString = jsonObject.getString("pendingContactId")
val idString = jsonObject.getJSONObject("pendingContact").getString("pendingContactId")
val deleteJson = """{"pendingContactId": "$idString"}"""
response = delete("$url/contacts/add/pending", deleteJson)
assertEquals(200, response.statusCode)
@@ -94,7 +93,7 @@ class ContactControllerIntegrationTest: IntegrationTest() {
}
@Test
fun `adding pending contacts needs authentication token`() {
fun `adding a pending contact needs authentication token`() {
val response = postWithWrongToken("$url/contacts/add/pending")
assertEquals(401, response.statusCode)
}
@@ -106,7 +105,7 @@ class ContactControllerIntegrationTest: IntegrationTest() {
}
@Test
fun `deleting contact need authentication token`() {
fun `deleting a contact needs authentication token`() {
val response = deleteWithWrongToken("$url/contacts/1")
assertEquals(401, response.statusCode)
}

View File

@@ -7,11 +7,14 @@ import io.mockk.Runs
import io.mockk.every
import io.mockk.just
import io.mockk.runs
import org.briarproject.bramble.api.Pair
import org.briarproject.bramble.api.contact.Contact
import org.briarproject.bramble.api.contact.ContactId
import org.briarproject.bramble.api.contact.PendingContactId
import org.briarproject.bramble.api.contact.PendingContactState.FAILED
import org.briarproject.bramble.api.contact.PendingContactState.WAITING_FOR_CONNECTION
import org.briarproject.bramble.api.contact.event.ContactAddedRemotelyEvent
import org.briarproject.bramble.api.contact.event.PendingContactAddedEvent
import org.briarproject.bramble.api.contact.event.PendingContactRemovedEvent
import org.briarproject.bramble.api.contact.event.PendingContactStateChangedEvent
import org.briarproject.bramble.api.db.NoSuchContactException
@@ -124,8 +127,19 @@ internal class ContactControllerTest : ControllerTest() {
@Test
fun testListPendingContacts() {
every { contactManager.pendingContacts } returns listOf(pendingContact)
every { ctx.json(listOf(pendingContact.output())) } returns ctx
every { contactManager.pendingContacts } returns listOf(
Pair(pendingContact, WAITING_FOR_CONNECTION)
)
every {
ctx.json(
listOf(
JsonDict(
"pendingContact" to pendingContact.output(),
"state" to WAITING_FOR_CONNECTION.output()
)
)
)
} returns ctx
controller.listPendingContacts(ctx)
}
@@ -225,6 +239,20 @@ internal class ContactControllerTest : ControllerTest() {
controller.eventOccurred(event)
}
@Test
fun testPendingContactAddedEvent() {
val event = PendingContactAddedEvent(pendingContact)
every {
webSocketController.sendEvent(
EVENT_PENDING_CONTACT_ADDED,
event.output()
)
} just runs
controller.eventOccurred(event)
}
@Test
fun testPendingContactRemovedEvent() {
val event = PendingContactRemovedEvent(pendingContact.id)
@@ -284,13 +312,27 @@ internal class ContactControllerTest : ControllerTest() {
{
"pendingContactId": ${toJson(pendingContact.id.bytes)},
"alias": "${pendingContact.alias}",
"state": "${pendingContact.state.name.toLowerCase()}",
"timestamp": ${pendingContact.timestamp}
}
"""
assertJsonEquals(json, pendingContact.output())
}
@Test
fun testOutputPendingContactAddedEvent() {
val event = PendingContactAddedEvent(pendingContact)
val json = """
{
"pendingContact": {
"pendingContactId": ${toJson(pendingContact.id.bytes)},
"alias": "${pendingContact.alias}",
"timestamp": ${pendingContact.timestamp}
}
}
"""
assertJsonEquals(json, event.output())
}
@Test
fun testOutputPendingContactStateChangedEvent() {
val event = PendingContactStateChangedEvent(pendingContact.id, FAILED)