Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: pairing authorization #46

Merged
merged 1 commit into from
Sep 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion app/src/main/java/tech/relaycorp/letro/awala/AwalaManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import tech.relaycorp.awaladroid.GatewayBindingException
import tech.relaycorp.awaladroid.GatewayClient
import tech.relaycorp.awaladroid.endpoint.FirstPartyEndpoint
import tech.relaycorp.awaladroid.endpoint.InvalidThirdPartyEndpoint
import tech.relaycorp.awaladroid.endpoint.PrivateThirdPartyEndpoint
import tech.relaycorp.awaladroid.endpoint.PublicThirdPartyEndpoint
import tech.relaycorp.awaladroid.endpoint.ThirdPartyEndpoint
import tech.relaycorp.awaladroid.messaging.OutgoingMessage
Expand All @@ -43,6 +44,7 @@ interface AwalaManager {
thirdPartyPublicKey: ByteArray,
)
suspend fun getFirstPartyPublicKey(): String
suspend fun importPrivateThirdPartyAuth(auth: ByteArray): String
}

@OptIn(ExperimentalCoroutinesApi::class)
Expand Down Expand Up @@ -72,9 +74,9 @@ class AwalaManagerImpl @Inject constructor(
private var thirdPartyServerEndpoint: ThirdPartyEndpoint? = null

init {
Log.i(TAG, "initializing")
awalaSetupJob = awalaScope.launch {
withContext(awalaThreadContext) {
Log.i(TAG, "Setting up Awala")
Awala.setUp(context)
checkIfAwalaAppInstalled()
isAwalaSetUp.compareAndSet(false, true)
Expand Down Expand Up @@ -142,6 +144,10 @@ class AwalaManagerImpl @Inject constructor(
}
}

override suspend fun importPrivateThirdPartyAuth(auth: ByteArray): String {
return PrivateThirdPartyEndpoint.import(auth).nodeId
}

private suspend fun loadFirstPartyEndpoint(): FirstPartyEndpoint {
return withContext(awalaThreadContext) {
val firstPartyEndpointNodeId = awalaRepository.getServerFirstPartyEndpointNodeId()
Expand Down Expand Up @@ -203,6 +209,7 @@ class AwalaManagerImpl @Inject constructor(
return withContext(awalaThreadContext) {
try {
GatewayClient.bind()
Log.i(TAG, "GatewayClient binded")
configureAwala()
} catch (exp: GatewayBindingException) {
[email protected] = false
Expand All @@ -216,6 +223,7 @@ class AwalaManagerImpl @Inject constructor(
private suspend fun registerFirstPartyEndpointIfNeeded(): FirstPartyEndpoint? {
return withContext(awalaThreadContext) {
if (awalaRepository.getServerFirstPartyEndpointNodeId() != null) {
Log.i(TAG, "First party endpoint is already registred ${awalaRepository.getServerFirstPartyEndpointNodeId()}")
startReceivingMessages()
return@withContext null
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,7 @@ interface ContactsDao {

@Delete
suspend fun deleteContact(contact: Contact)

@Query("SELECT * FROM $TABLE_NAME_CONTACTS WHERE contactEndpointId = :contactEndpointId")
suspend fun getContactsByContactEndpointId(contactEndpointId: String): List<Contact>
}
3 changes: 3 additions & 0 deletions app/src/main/java/tech/relaycorp/letro/di/AwalaModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import tech.relaycorp.letro.awala.processor.AwalaMessageProcessor
import tech.relaycorp.letro.awala.processor.AwalaMessageProcessorImpl
import tech.relaycorp.letro.awala.processor.UnknownMessageProcessor
import tech.relaycorp.letro.onboarding.registration.processor.RegistrationMessageProcessor
import tech.relaycorp.letro.pairing.processor.ContactPairingAuthorizationProcessor
import tech.relaycorp.letro.pairing.processor.ContactPairingMatchProcessor
import javax.inject.Singleton

Expand All @@ -25,11 +26,13 @@ object AwalaModule {
fun provideMessageProcessor(
registrationMessageProcessor: RegistrationMessageProcessor,
contactPairingMatchProcessor: ContactPairingMatchProcessor,
contactPairingAuthorizationProcessor: ContactPairingAuthorizationProcessor,
unknownMessageProcessor: UnknownMessageProcessor,
): AwalaMessageProcessor {
val processors = mapOf(
MessageType.AccountCreationCompleted to registrationMessageProcessor,
MessageType.ContactPairingMatch to contactPairingMatchProcessor,
MessageType.ContactPairingAuthorization to contactPairingAuthorizationProcessor,
MessageType.Unknown to unknownMessageProcessor,
)
return AwalaMessageProcessorImpl(processors)
Expand Down
15 changes: 15 additions & 0 deletions app/src/main/java/tech/relaycorp/letro/di/ContactsModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,12 @@ import dagger.hilt.components.SingletonComponent
import tech.relaycorp.letro.contacts.storage.ContactsDao
import tech.relaycorp.letro.contacts.storage.ContactsRepository
import tech.relaycorp.letro.contacts.storage.ContactsRepositoryImpl
import tech.relaycorp.letro.pairing.parser.ContactPairingAuthorizationParser
import tech.relaycorp.letro.pairing.parser.ContactPairingAuthorizationParserImpl
import tech.relaycorp.letro.pairing.parser.ContactPairingMatchParser
import tech.relaycorp.letro.pairing.parser.ContactPairingMatchParserImpl
import tech.relaycorp.letro.pairing.processor.ContactPairingAuthorizationProcessor
import tech.relaycorp.letro.pairing.processor.ContactPairingAuthorizationProcessorImpl
import tech.relaycorp.letro.pairing.processor.ContactPairingMatchProcessor
import tech.relaycorp.letro.pairing.processor.ContactPairingMatchProcessorImpl
import tech.relaycorp.letro.storage.LetroDatabase
Expand Down Expand Up @@ -43,5 +47,16 @@ object ContactsModule {
fun bindContactPairingMatchProcessor(
impl: ContactPairingMatchProcessorImpl,
): ContactPairingMatchProcessor

@Binds
fun bindContactPairingAuthParser(
impl: ContactPairingAuthorizationParserImpl,
): ContactPairingAuthorizationParser

@Binds
@Singleton
fun bindContactPairingAuthProcessor(
impl: ContactPairingAuthorizationProcessorImpl,
): ContactPairingAuthorizationProcessor
}
}
2 changes: 1 addition & 1 deletion app/src/main/java/tech/relaycorp/letro/home/LetroTabs.kt
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ fun LetroTabs(
)
ScrollableTabRow(
selectedTabIndex = uiState.currentTab,
containerColor = MaterialTheme.colorScheme.primary,
containerColor = LetroColor.SurfaceContainerHigh,
contentColor = LetroColor.OnSurfaceContainerHigh,
edgePadding = 9.dp,
indicator = {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package tech.relaycorp.letro.pairing.dto

import tech.relaycorp.letro.awala.message.AwalaIncomingMessage
import tech.relaycorp.letro.awala.message.MessageType

data class ContactPairingAuthorizationResponse(
val authData: ByteArray,
)

data class ContactPairingAuthorizationIncomingMessage(
override val content: ContactPairingAuthorizationResponse,
) : AwalaIncomingMessage<ContactPairingAuthorizationResponse> {
override val type: MessageType
get() = MessageType.ContactPairingAuthorization
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package tech.relaycorp.letro.pairing.parser

import tech.relaycorp.letro.awala.parser.AwalaMessageParser
import tech.relaycorp.letro.pairing.dto.ContactPairingAuthorizationIncomingMessage
import tech.relaycorp.letro.pairing.dto.ContactPairingAuthorizationResponse
import javax.inject.Inject

interface ContactPairingAuthorizationParser : AwalaMessageParser

class ContactPairingAuthorizationParserImpl @Inject constructor() : ContactPairingAuthorizationParser {

override fun parse(content: ByteArray): ContactPairingAuthorizationIncomingMessage {
return ContactPairingAuthorizationIncomingMessage(
content = ContactPairingAuthorizationResponse(
authData = content,
),
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package tech.relaycorp.letro.pairing.processor

import tech.relaycorp.awaladroid.messaging.IncomingMessage
import tech.relaycorp.letro.awala.AwalaManager
import tech.relaycorp.letro.awala.processor.AwalaMessageProcessor
import tech.relaycorp.letro.contacts.model.ContactPairingStatus
import tech.relaycorp.letro.contacts.storage.ContactsDao
import tech.relaycorp.letro.pairing.dto.ContactPairingAuthorizationIncomingMessage
import tech.relaycorp.letro.pairing.parser.ContactPairingAuthorizationParser
import javax.inject.Inject

interface ContactPairingAuthorizationProcessor : AwalaMessageProcessor

class ContactPairingAuthorizationProcessorImpl @Inject constructor(
private val parser: ContactPairingAuthorizationParser,
private val contactsDao: ContactsDao,
) : ContactPairingAuthorizationProcessor {

override suspend fun process(message: IncomingMessage, awalaManager: AwalaManager) {
val response = (parser.parse(message.content) as ContactPairingAuthorizationIncomingMessage).content
val nodeId = awalaManager.importPrivateThirdPartyAuth(response.authData)

contactsDao.getContactsByContactEndpointId(
contactEndpointId = nodeId,
).forEach { contactToUpdate ->
contactsDao.update(
contactToUpdate.copy(
status = ContactPairingStatus.COMPLETED,
),
)
}
}
}
Loading