diff --git a/mailbox-core/src/main/java/org/briarproject/mailbox/core/server/AuthManager.kt b/mailbox-core/src/main/java/org/briarproject/mailbox/core/server/AuthManager.kt index 455bdff772511e233b603a562bd2ae7674aa0d6f..f72d5aac658c7e6b13ba22d1bd52ce2d6e34a548 100644 --- a/mailbox-core/src/main/java/org/briarproject/mailbox/core/server/AuthManager.kt +++ b/mailbox-core/src/main/java/org/briarproject/mailbox/core/server/AuthManager.kt @@ -5,19 +5,15 @@ import org.briarproject.mailbox.core.contacts.Contact import org.briarproject.mailbox.core.db.Database import org.briarproject.mailbox.core.server.MailboxPrincipal.ContactPrincipal 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 javax.inject.Inject 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 class AuthManager @Inject constructor( private val db: Database, - private val settingsManager: SettingsManager, + private val setupManager: SetupManager, private val randomIdManager: RandomIdManager, ) { @@ -32,8 +28,7 @@ class AuthManager @Inject constructor( if (contact != null) { ContactPrincipal(contact) } else { - val settings = settingsManager.getSettings(txn, SETTINGS_NAMESPACE_OWNER) - if (token == settings[SETTINGS_OWNER_TOKEN]) OwnerPrincipal + if (token == setupManager.getOwnerToken(txn)) OwnerPrincipal else null } } diff --git a/mailbox-core/src/main/java/org/briarproject/mailbox/core/setup/SetupManager.kt b/mailbox-core/src/main/java/org/briarproject/mailbox/core/setup/SetupManager.kt new file mode 100644 index 0000000000000000000000000000000000000000..14002b3a48905b5d5ab2fe992e69f6905cb95d81 --- /dev/null +++ b/mailbox-core/src/main/java/org/briarproject/mailbox/core/setup/SetupManager.kt @@ -0,0 +1,47 @@ +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 + } + +} diff --git a/mailbox-core/src/test/java/org/briarproject/mailbox/core/TestComponent.kt b/mailbox-core/src/test/java/org/briarproject/mailbox/core/TestComponent.kt index c374303c762f7845193081bf282b218a0dca1830..564531b71e307b705f0864f5c9559cc752fc057a 100644 --- a/mailbox-core/src/test/java/org/briarproject/mailbox/core/TestComponent.kt +++ b/mailbox-core/src/test/java/org/briarproject/mailbox/core/TestComponent.kt @@ -5,6 +5,7 @@ import org.briarproject.mailbox.core.db.Database import org.briarproject.mailbox.core.files.FileManager import org.briarproject.mailbox.core.lifecycle.LifecycleManager import org.briarproject.mailbox.core.settings.SettingsManager +import org.briarproject.mailbox.core.setup.SetupManager import org.briarproject.mailbox.core.system.RandomIdManager import javax.inject.Singleton @@ -18,6 +19,7 @@ interface TestComponent { fun injectCoreEagerSingletons(): CoreEagerSingletons fun getLifecycleManager(): LifecycleManager fun getSettingsManager(): SettingsManager + fun getSetupManager(): SetupManager fun getFileManager(): FileManager fun getDatabase(): Database fun getRandomIdManager(): RandomIdManager diff --git a/mailbox-core/src/test/java/org/briarproject/mailbox/core/server/AuthManagerTest.kt b/mailbox-core/src/test/java/org/briarproject/mailbox/core/server/AuthManagerTest.kt index 1a3d6f5b0992b952674f1771900e817c070f5935..6eaf19addf139cab6d53819bfee0fc73ba84265c 100644 --- a/mailbox-core/src/test/java/org/briarproject/mailbox/core/server/AuthManagerTest.kt +++ b/mailbox-core/src/test/java/org/briarproject/mailbox/core/server/AuthManagerTest.kt @@ -7,8 +7,7 @@ import org.briarproject.mailbox.core.TestUtils.getNewRandomContact import org.briarproject.mailbox.core.TestUtils.getNewRandomId import org.briarproject.mailbox.core.db.Database import org.briarproject.mailbox.core.server.MailboxPrincipal.OwnerPrincipal -import org.briarproject.mailbox.core.settings.Settings -import org.briarproject.mailbox.core.settings.SettingsManager +import org.briarproject.mailbox.core.setup.SetupManager import org.briarproject.mailbox.core.system.InvalidIdException import org.briarproject.mailbox.core.system.RandomIdManager import org.briarproject.mailbox.core.system.toHex @@ -21,10 +20,10 @@ import kotlin.test.assertNull class AuthManagerTest { private val db: Database = mockk() - private val settingsManager: SettingsManager = mockk() + private val setupManager: SetupManager = mockk() private val randomIdManager = RandomIdManager() - private val authManager = AuthManager(db, settingsManager, randomIdManager) + private val authManager = AuthManager(db, setupManager, randomIdManager) private val id = getNewRandomId() private val otherId = getNewRandomId() @@ -49,13 +48,9 @@ class AuthManagerTest { @Test fun `getPrincipal() returns authenticated owner`() { - val settings = Settings().apply { - put(SETTINGS_OWNER_TOKEN, id) - } - everyTransactionWithResult(db, true) { txn -> 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)) @@ -63,13 +58,9 @@ class AuthManagerTest { @Test fun `getPrincipal() returns null when unauthenticated`() { - val settings = Settings().apply { - put(SETTINGS_OWNER_TOKEN, otherId) - } - everyTransactionWithResult(db, true) { txn -> 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)) diff --git a/mailbox-core/src/test/java/org/briarproject/mailbox/core/server/IntegrationTest.kt b/mailbox-core/src/test/java/org/briarproject/mailbox/core/server/IntegrationTest.kt index d963bd1161b04bc19120967702551c9beb75076b..140ef2e3aed6b908a02b841ba48587f6911bcf9a 100644 --- a/mailbox-core/src/test/java/org/briarproject/mailbox/core/server/IntegrationTest.kt +++ b/mailbox-core/src/test/java/org/briarproject/mailbox/core/server/IntegrationTest.kt @@ -14,7 +14,6 @@ import org.briarproject.mailbox.core.TestUtils.getNewRandomContact import org.briarproject.mailbox.core.TestUtils.getNewRandomId import org.briarproject.mailbox.core.contacts.Contact 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.BeforeAll import org.junit.jupiter.api.TestInstance @@ -58,10 +57,7 @@ abstract class IntegrationTest(private val installJsonFeature: Boolean = true) { } protected fun addOwnerToken() { - val settingsManager = testComponent.getSettingsManager() - val settings = Settings() - settings[SETTINGS_OWNER_TOKEN] = ownerToken - settingsManager.mergeSettings(settings, SETTINGS_NAMESPACE_OWNER) + testComponent.getSetupManager().setOwnerToken(ownerToken) } protected fun addContact(c: Contact) { diff --git a/mailbox-core/src/test/java/org/briarproject/mailbox/core/setup/SetupManagerTest.kt b/mailbox-core/src/test/java/org/briarproject/mailbox/core/setup/SetupManagerTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..88470f41171f36d77efb80976f96e04e2b938941 --- /dev/null +++ b/mailbox-core/src/test/java/org/briarproject/mailbox/core/setup/SetupManagerTest.kt @@ -0,0 +1,36 @@ +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