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

Generate and store single-use auth token for setup

parent d1b868a6
Branches
Tags
1 merge request!30Store single-use auth token and implement setup API endpoint
...@@ -5,19 +5,15 @@ import org.briarproject.mailbox.core.contacts.Contact ...@@ -5,19 +5,15 @@ import org.briarproject.mailbox.core.contacts.Contact
import org.briarproject.mailbox.core.db.Database import org.briarproject.mailbox.core.db.Database
import org.briarproject.mailbox.core.server.MailboxPrincipal.ContactPrincipal import org.briarproject.mailbox.core.server.MailboxPrincipal.ContactPrincipal
import org.briarproject.mailbox.core.server.MailboxPrincipal.OwnerPrincipal import org.briarproject.mailbox.core.server.MailboxPrincipal.OwnerPrincipal
import org.briarproject.mailbox.core.settings.SettingsManager import org.briarproject.mailbox.core.setup.SetupManager
import org.briarproject.mailbox.core.system.RandomIdManager import org.briarproject.mailbox.core.system.RandomIdManager
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
// We might want to move this somewhere else later
internal const val SETTINGS_NAMESPACE_OWNER = "owner"
internal const val SETTINGS_OWNER_TOKEN = "ownerToken"
@Singleton @Singleton
class AuthManager @Inject constructor( class AuthManager @Inject constructor(
private val db: Database, private val db: Database,
private val settingsManager: SettingsManager, private val setupManager: SetupManager,
private val randomIdManager: RandomIdManager, private val randomIdManager: RandomIdManager,
) { ) {
...@@ -32,8 +28,7 @@ class AuthManager @Inject constructor( ...@@ -32,8 +28,7 @@ class AuthManager @Inject constructor(
if (contact != null) { if (contact != null) {
ContactPrincipal(contact) ContactPrincipal(contact)
} else { } else {
val settings = settingsManager.getSettings(txn, SETTINGS_NAMESPACE_OWNER) if (token == setupManager.getOwnerToken(txn)) OwnerPrincipal
if (token == settings[SETTINGS_OWNER_TOKEN]) OwnerPrincipal
else null else null
} }
} }
......
package org.briarproject.mailbox.core.setup
import org.briarproject.mailbox.core.db.DbException
import org.briarproject.mailbox.core.db.Transaction
import org.briarproject.mailbox.core.settings.Settings
import org.briarproject.mailbox.core.settings.SettingsManager
import org.briarproject.mailbox.core.system.RandomIdManager
import javax.inject.Inject
private const val SETTINGS_NAMESPACE_OWNER = "owner"
private const val SETTINGS_SETUP_TOKEN = "setupToken"
private const val SETTINGS_OWNER_TOKEN = "ownerToken"
class SetupManager @Inject constructor(
private val randomIdManager: RandomIdManager,
private val settingsManager: SettingsManager,
) {
/**
* Stores a new single-use setup token and wipes the owner auth token, if one existed.
*/
fun restartSetup() {
val settings = Settings()
settings[SETTINGS_SETUP_TOKEN] = randomIdManager.getNewRandomId()
settings[SETTINGS_OWNER_TOKEN] = "" // we can't remove or null or, so we need to empty it
settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE_OWNER)
}
/**
* Visible for testing, consider private.
*/
@Throws(DbException::class)
internal fun setOwnerToken(token: String) {
val settings = Settings()
settings[SETTINGS_OWNER_TOKEN] = token
settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE_OWNER)
}
@Throws(DbException::class)
fun getOwnerToken(txn: Transaction): String? {
val settings = settingsManager.getSettings(txn, SETTINGS_NAMESPACE_OWNER)
val ownerToken = settings[SETTINGS_OWNER_TOKEN]
return if (ownerToken.isNullOrEmpty()) null
else ownerToken
}
}
...@@ -5,6 +5,7 @@ import org.briarproject.mailbox.core.db.Database ...@@ -5,6 +5,7 @@ import org.briarproject.mailbox.core.db.Database
import org.briarproject.mailbox.core.files.FileManager import org.briarproject.mailbox.core.files.FileManager
import org.briarproject.mailbox.core.lifecycle.LifecycleManager import org.briarproject.mailbox.core.lifecycle.LifecycleManager
import org.briarproject.mailbox.core.settings.SettingsManager import org.briarproject.mailbox.core.settings.SettingsManager
import org.briarproject.mailbox.core.setup.SetupManager
import org.briarproject.mailbox.core.system.RandomIdManager import org.briarproject.mailbox.core.system.RandomIdManager
import javax.inject.Singleton import javax.inject.Singleton
...@@ -18,6 +19,7 @@ interface TestComponent { ...@@ -18,6 +19,7 @@ interface TestComponent {
fun injectCoreEagerSingletons(): CoreEagerSingletons fun injectCoreEagerSingletons(): CoreEagerSingletons
fun getLifecycleManager(): LifecycleManager fun getLifecycleManager(): LifecycleManager
fun getSettingsManager(): SettingsManager fun getSettingsManager(): SettingsManager
fun getSetupManager(): SetupManager
fun getFileManager(): FileManager fun getFileManager(): FileManager
fun getDatabase(): Database fun getDatabase(): Database
fun getRandomIdManager(): RandomIdManager fun getRandomIdManager(): RandomIdManager
......
...@@ -7,8 +7,7 @@ import org.briarproject.mailbox.core.TestUtils.getNewRandomContact ...@@ -7,8 +7,7 @@ import org.briarproject.mailbox.core.TestUtils.getNewRandomContact
import org.briarproject.mailbox.core.TestUtils.getNewRandomId import org.briarproject.mailbox.core.TestUtils.getNewRandomId
import org.briarproject.mailbox.core.db.Database import org.briarproject.mailbox.core.db.Database
import org.briarproject.mailbox.core.server.MailboxPrincipal.OwnerPrincipal import org.briarproject.mailbox.core.server.MailboxPrincipal.OwnerPrincipal
import org.briarproject.mailbox.core.settings.Settings import org.briarproject.mailbox.core.setup.SetupManager
import org.briarproject.mailbox.core.settings.SettingsManager
import org.briarproject.mailbox.core.system.InvalidIdException import org.briarproject.mailbox.core.system.InvalidIdException
import org.briarproject.mailbox.core.system.RandomIdManager import org.briarproject.mailbox.core.system.RandomIdManager
import org.briarproject.mailbox.core.system.toHex import org.briarproject.mailbox.core.system.toHex
...@@ -21,10 +20,10 @@ import kotlin.test.assertNull ...@@ -21,10 +20,10 @@ import kotlin.test.assertNull
class AuthManagerTest { class AuthManagerTest {
private val db: Database = mockk() private val db: Database = mockk()
private val settingsManager: SettingsManager = mockk() private val setupManager: SetupManager = mockk()
private val randomIdManager = RandomIdManager() private val randomIdManager = RandomIdManager()
private val authManager = AuthManager(db, settingsManager, randomIdManager) private val authManager = AuthManager(db, setupManager, randomIdManager)
private val id = getNewRandomId() private val id = getNewRandomId()
private val otherId = getNewRandomId() private val otherId = getNewRandomId()
...@@ -49,13 +48,9 @@ class AuthManagerTest { ...@@ -49,13 +48,9 @@ class AuthManagerTest {
@Test @Test
fun `getPrincipal() returns authenticated owner`() { fun `getPrincipal() returns authenticated owner`() {
val settings = Settings().apply {
put(SETTINGS_OWNER_TOKEN, id)
}
everyTransactionWithResult(db, true) { txn -> everyTransactionWithResult(db, true) { txn ->
every { db.getContactWithToken(txn, id) } returns null every { db.getContactWithToken(txn, id) } returns null
every { settingsManager.getSettings(txn, SETTINGS_NAMESPACE_OWNER) } returns settings every { setupManager.getOwnerToken(txn) } returns id
} }
assertEquals(OwnerPrincipal, authManager.getPrincipal(id)) assertEquals(OwnerPrincipal, authManager.getPrincipal(id))
...@@ -63,13 +58,9 @@ class AuthManagerTest { ...@@ -63,13 +58,9 @@ class AuthManagerTest {
@Test @Test
fun `getPrincipal() returns null when unauthenticated`() { fun `getPrincipal() returns null when unauthenticated`() {
val settings = Settings().apply {
put(SETTINGS_OWNER_TOKEN, otherId)
}
everyTransactionWithResult(db, true) { txn -> everyTransactionWithResult(db, true) { txn ->
every { db.getContactWithToken(txn, id) } returns null every { db.getContactWithToken(txn, id) } returns null
every { settingsManager.getSettings(txn, SETTINGS_NAMESPACE_OWNER) } returns settings every { setupManager.getOwnerToken(txn) } returns otherId
} }
assertNull(authManager.getPrincipal(id)) assertNull(authManager.getPrincipal(id))
......
...@@ -14,7 +14,6 @@ import org.briarproject.mailbox.core.TestUtils.getNewRandomContact ...@@ -14,7 +14,6 @@ import org.briarproject.mailbox.core.TestUtils.getNewRandomContact
import org.briarproject.mailbox.core.TestUtils.getNewRandomId import org.briarproject.mailbox.core.TestUtils.getNewRandomId
import org.briarproject.mailbox.core.contacts.Contact import org.briarproject.mailbox.core.contacts.Contact
import org.briarproject.mailbox.core.server.WebServerManager.Companion.PORT import org.briarproject.mailbox.core.server.WebServerManager.Companion.PORT
import org.briarproject.mailbox.core.settings.Settings
import org.junit.jupiter.api.AfterAll import org.junit.jupiter.api.AfterAll
import org.junit.jupiter.api.BeforeAll import org.junit.jupiter.api.BeforeAll
import org.junit.jupiter.api.TestInstance import org.junit.jupiter.api.TestInstance
...@@ -58,10 +57,7 @@ abstract class IntegrationTest(private val installJsonFeature: Boolean = true) { ...@@ -58,10 +57,7 @@ abstract class IntegrationTest(private val installJsonFeature: Boolean = true) {
} }
protected fun addOwnerToken() { protected fun addOwnerToken() {
val settingsManager = testComponent.getSettingsManager() testComponent.getSetupManager().setOwnerToken(ownerToken)
val settings = Settings()
settings[SETTINGS_OWNER_TOKEN] = ownerToken
settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE_OWNER)
} }
protected fun addContact(c: Contact) { protected fun addContact(c: Contact) {
......
package org.briarproject.mailbox.core.setup
import org.briarproject.mailbox.core.server.IntegrationTest
import org.junit.jupiter.api.Test
import kotlin.test.assertEquals
import kotlin.test.assertNull
class SetupManagerTest : IntegrationTest() {
private val db by lazy { testComponent.getDatabase() }
private val setupManager by lazy { testComponent.getSetupManager() }
@Test
fun `restarting setup wipes owner token`() {
// initially, there's no owner token
val initialOwnerToken = db.transactionWithResult(true) { txn ->
setupManager.getOwnerToken(txn)
}
assertNull(initialOwnerToken)
// setting an owner token stores it in DB
setupManager.setOwnerToken(ownerToken)
val firstOwnerToken = db.transactionWithResult(true) { txn ->
setupManager.getOwnerToken(txn)
}
assertEquals(ownerToken, firstOwnerToken)
// restarting setup wipes owner token
setupManager.restartSetup()
val wipedOwnerToken = db.transactionWithResult(true) { txn ->
setupManager.getOwnerToken(txn)
}
assertNull(wipedOwnerToken)
}
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment