-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
1c13447
commit b0acf75
Showing
21 changed files
with
518 additions
and
48 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
6 changes: 6 additions & 0 deletions
6
app/src/main/java/com/forcetower/uefs/core/model/edge/AssertionData.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package com.forcetower.uefs.core.model.edge | ||
|
||
data class AssertionData( | ||
val flowId: String, | ||
val challenge: String | ||
) |
6 changes: 6 additions & 0 deletions
6
app/src/main/java/com/forcetower/uefs/core/model/edge/CompleteAssertionData.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package com.forcetower.uefs.core.model.edge | ||
|
||
data class CompleteAssertionData( | ||
val flowId: String, | ||
val credential: String | ||
) |
13 changes: 13 additions & 0 deletions
13
app/src/main/java/com/forcetower/uefs/core/model/edge/PasskeyAssert.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package com.forcetower.uefs.core.model.edge | ||
|
||
data class SimplifiedPublicKey( | ||
val challenge: String, | ||
val timeout: Int, | ||
val rpId: String, | ||
val userVerification: String, | ||
val extensions: Map<String, Any?>? | ||
) | ||
|
||
data class PasskeyAssert( | ||
val publicKey: SimplifiedPublicKey | ||
) |
29 changes: 29 additions & 0 deletions
29
app/src/main/java/com/forcetower/uefs/core/model/edge/PasskeyRegister.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package com.forcetower.uefs.core.model.edge | ||
|
||
data class Rp(val name: String, val id: String) | ||
data class User(val name: String, val displayName: String, val id: String) | ||
data class PublicKeyCredParam(val alg: Int, val type: String) | ||
data class ExcludedCredential(val type: String, val id: String) | ||
data class AuthenticatorSelection( | ||
val authenticatorAttachment: String?, | ||
val requireResidentKey: Boolean?, | ||
val residentKey: String?, | ||
val userVerification: String? | ||
) | ||
data class Extensions(val credProps: Boolean) | ||
|
||
data class PublicKey( | ||
val rp: Rp, | ||
val user: User, | ||
val challenge: String, | ||
val pubKeyCredParams: List<PublicKeyCredParam>, | ||
val timeout: Int, | ||
val excludeCredentials: List<ExcludedCredential>, | ||
val authenticatorSelection: AuthenticatorSelection, | ||
val attestation: String, | ||
val extensions: Extensions | ||
) | ||
|
||
data class PasskeyRegister( | ||
val publicKey: PublicKey | ||
) |
6 changes: 6 additions & 0 deletions
6
app/src/main/java/com/forcetower/uefs/core/model/edge/RegisterPasskeyCredential.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package com.forcetower.uefs.core.model.edge | ||
|
||
data class RegisterPasskeyCredential( | ||
val flowId: String, | ||
val credential: String | ||
) |
6 changes: 6 additions & 0 deletions
6
app/src/main/java/com/forcetower/uefs/core/model/edge/RegisterPasskeyStart.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package com.forcetower.uefs.core.model.edge | ||
|
||
data class RegisterPasskeyStart( | ||
val flowId: String, | ||
val create: String | ||
) |
25 changes: 25 additions & 0 deletions
25
app/src/main/java/com/forcetower/uefs/core/storage/network/EdgeService.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package com.forcetower.uefs.core.storage.network | ||
|
||
import com.forcetower.uefs.core.model.edge.AssertionData | ||
import com.forcetower.uefs.core.model.edge.CompleteAssertionData | ||
import com.forcetower.uefs.core.model.edge.RegisterPasskeyCredential | ||
import com.forcetower.uefs.core.model.edge.RegisterPasskeyStart | ||
import com.forcetower.uefs.core.model.unes.AccessToken | ||
import retrofit2.http.Body | ||
import retrofit2.http.GET | ||
import retrofit2.http.Headers | ||
import retrofit2.http.POST | ||
|
||
interface EdgeService { | ||
@GET("auth/login/passkey/assertion/start") | ||
suspend fun startAssertion(): AssertionData | ||
|
||
@POST("auth/login/passkey/assertion/finish") | ||
suspend fun completeAssertion(@Body data: CompleteAssertionData): AccessToken | ||
|
||
@GET("passkeys/register/start") | ||
suspend fun registerPasskeyStart(): RegisterPasskeyStart | ||
|
||
@POST("passkeys/register/finish") | ||
suspend fun registerPasskeyFinish(@Body data: RegisterPasskeyCredential) | ||
} |
32 changes: 32 additions & 0 deletions
32
app/src/main/java/com/forcetower/uefs/core/storage/repository/cloud/EdgeAuthRepository.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package com.forcetower.uefs.core.storage.repository.cloud | ||
|
||
import com.forcetower.uefs.core.model.edge.AssertionData | ||
import com.forcetower.uefs.core.model.edge.CompleteAssertionData | ||
import com.forcetower.uefs.core.model.edge.RegisterPasskeyCredential | ||
import com.forcetower.uefs.core.model.edge.RegisterPasskeyStart | ||
import com.forcetower.uefs.core.storage.network.EdgeService | ||
import timber.log.Timber | ||
import javax.inject.Inject | ||
import javax.inject.Singleton | ||
|
||
@Singleton | ||
class EdgeAuthRepository @Inject constructor( | ||
private val service: EdgeService | ||
) { | ||
suspend fun startAssertion(): AssertionData { | ||
return service.startAssertion() | ||
} | ||
|
||
suspend fun completeAssertion(flowId: String, response: String) { | ||
val token = service.completeAssertion(CompleteAssertionData(flowId, response)) | ||
Timber.d("Token $token") | ||
} | ||
|
||
suspend fun registerStart(): RegisterPasskeyStart { | ||
return service.registerPasskeyStart() | ||
} | ||
|
||
suspend fun registerFinish(flowId: String, credential: String) { | ||
return service.registerPasskeyFinish(RegisterPasskeyCredential(flowId, credential)) | ||
} | ||
} |
16 changes: 16 additions & 0 deletions
16
app/src/main/java/com/forcetower/uefs/domain/usecase/CompleteAssertionUseCase.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package com.forcetower.uefs.domain.usecase | ||
|
||
import com.forcetower.uefs.core.storage.repository.cloud.EdgeAuthRepository | ||
import dagger.Reusable | ||
import timber.log.Timber | ||
import javax.inject.Inject | ||
|
||
@Reusable | ||
class CompleteAssertionUseCase @Inject constructor( | ||
private val auth: EdgeAuthRepository | ||
) { | ||
suspend operator fun invoke(flowId: String, response: String) { | ||
Timber.d("Credential: $response") | ||
auth.completeAssertion(flowId, response) | ||
} | ||
} |
26 changes: 26 additions & 0 deletions
26
app/src/main/java/com/forcetower/uefs/domain/usecase/RegisterPasskeyUseCase.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package com.forcetower.uefs.domain.usecase | ||
|
||
import com.forcetower.uefs.core.model.edge.PasskeyRegister | ||
import com.forcetower.uefs.core.model.edge.RegisterPasskeyStart | ||
import com.forcetower.uefs.core.storage.repository.cloud.EdgeAuthRepository | ||
import com.google.gson.Gson | ||
import dagger.Reusable | ||
import timber.log.Timber | ||
import javax.inject.Inject | ||
|
||
@Reusable | ||
class RegisterPasskeyUseCase @Inject constructor( | ||
private val edge: EdgeAuthRepository, | ||
private val gson: Gson | ||
) { | ||
suspend fun start(): RegisterPasskeyStart { | ||
val data = edge.registerStart() | ||
Timber.d("Original data: ${data.create}") | ||
val register = gson.fromJson(data.create, PasskeyRegister::class.java) | ||
return data.copy(create = gson.toJson(register.publicKey)) | ||
} | ||
|
||
suspend fun finish(flowId: String, credential: String) { | ||
return edge.registerFinish(flowId, credential) | ||
} | ||
} |
20 changes: 20 additions & 0 deletions
20
app/src/main/java/com/forcetower/uefs/domain/usecase/StartAssertionUseCase.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package com.forcetower.uefs.domain.usecase | ||
|
||
import com.forcetower.uefs.core.model.edge.AssertionData | ||
import com.forcetower.uefs.core.model.edge.PasskeyAssert | ||
import com.forcetower.uefs.core.storage.repository.cloud.EdgeAuthRepository | ||
import com.google.gson.Gson | ||
import dagger.Reusable | ||
import javax.inject.Inject | ||
|
||
@Reusable | ||
class StartAssertionUseCase @Inject constructor( | ||
private val auth: EdgeAuthRepository, | ||
private val gson: Gson | ||
) { | ||
suspend operator fun invoke(): AssertionData { | ||
val data = auth.startAssertion() | ||
val parsed = gson.fromJson(data.challenge, PasskeyAssert::class.java) | ||
return data.copy(challenge = gson.toJson(parsed.publicKey)) | ||
} | ||
} |
74 changes: 74 additions & 0 deletions
74
app/src/main/java/com/forcetower/uefs/feature/login/LoginFormViewModel.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
package com.forcetower.uefs.feature.login | ||
|
||
import androidx.lifecycle.LiveData | ||
import androidx.lifecycle.ViewModel | ||
import androidx.lifecycle.viewModelScope | ||
import com.forcetower.uefs.core.model.edge.RegisterPasskeyStart | ||
import com.forcetower.uefs.domain.usecase.CompleteAssertionUseCase | ||
import com.forcetower.uefs.domain.usecase.RegisterPasskeyUseCase | ||
import com.forcetower.uefs.domain.usecase.StartAssertionUseCase | ||
import com.forcetower.uefs.feature.shared.SingleLiveEvent | ||
import dagger.hilt.android.lifecycle.HiltViewModel | ||
import kotlinx.coroutines.launch | ||
import timber.log.Timber | ||
import javax.inject.Inject | ||
|
||
@HiltViewModel | ||
class LoginFormViewModel @Inject constructor( | ||
private val getLoginChallenge: StartAssertionUseCase, | ||
private val completeAssertion: CompleteAssertionUseCase, | ||
private val registerPasskey: RegisterPasskeyUseCase | ||
) : ViewModel() { | ||
private val _data = SingleLiveEvent<String>() | ||
val challenge: LiveData<String> = _data | ||
|
||
private val _register = SingleLiveEvent<RegisterPasskeyStart>() | ||
val register: LiveData<RegisterPasskeyStart> = _register | ||
|
||
private var flowId = "" | ||
|
||
fun startRegister() { | ||
viewModelScope.launch { | ||
runCatching { | ||
val data = registerPasskey.start() | ||
_register.value = data | ||
}.onFailure { | ||
Timber.e(it, "Failed to request challenge") | ||
} | ||
} | ||
} | ||
|
||
fun finishRegister(flowId: String, credential: String) { | ||
viewModelScope.launch { | ||
runCatching { | ||
registerPasskey.finish(flowId, credential) | ||
}.onFailure { | ||
Timber.e(it, "Failed to register") | ||
} | ||
} | ||
} | ||
|
||
fun startAssertion() { | ||
viewModelScope.launch { | ||
runCatching { | ||
val data = getLoginChallenge() | ||
flowId = data.flowId | ||
val challenge = data.challenge | ||
_data.value = challenge | ||
}.onFailure { | ||
Timber.e(it, "Failed to request assertion") | ||
} | ||
} | ||
} | ||
|
||
fun completeAssertion(responseJson: String) { | ||
if (flowId.isBlank()) return | ||
viewModelScope.launch { | ||
runCatching { | ||
completeAssertion(flowId, responseJson) | ||
}.onFailure { | ||
Timber.e(it, "Failed to authenticate user") | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.