Skip to content

Commit

Permalink
Merge pull request #97 from niscy-eudiw/main
Browse files Browse the repository at this point in the history
Wallet core update to 0.6.0, resolved all breaking changes and vci au…
  • Loading branch information
stzouvaras authored May 22, 2024
2 parents ca070c7 + 57fba9a commit 3b21f1b
Show file tree
Hide file tree
Showing 11 changed files with 219 additions and 82 deletions.
22 changes: 22 additions & 0 deletions assembly-logic/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,28 @@
android:scheme="${openid4vpScheme}" />

</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />

<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />

<data
android:host="${openid4vciHost}"
android:scheme="${openid4vciScheme}" />

</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />

<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />

<data
android:host="${openId4VciAuthorizationHost}"
android:scheme="${openId4VciAuthorizationScheme}" />

</intent-filter>
</activity>

</application>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,11 @@ class AndroidLibraryConventionPlugin : Plugin<Project> {
val openId4VpScheme = "eudi-openid4vp"
val openid4VpHost = "*"

val openId4VciScheme = "eudi-openid4ci"
val openid4VciHost = "authorize"
val openid4VciPath = ""
val openId4VciScheme = "eudi-openid4vci"
val openid4VciHost = "*"

val openId4VciAuthorizationScheme = "eudi-issuance"
val openId4VciAuthorizationHost = "authorization"

val storedVersion = getProperty<String>(
"VERSION_NAME",
Expand All @@ -74,6 +76,11 @@ class AndroidLibraryConventionPlugin : Plugin<Project> {

addConfigField("DEEPLINK", "$walletScheme://")
addConfigField("OPENID4VP_SCHEME", openId4VpScheme)
addConfigField("OPENID4VCI_SCHEME", openId4VciScheme)
addConfigField(
"ISSUE_AUTHORIZATION_DEEPLINK",
"$openId4VciAuthorizationScheme://$openId4VciAuthorizationHost"
)

// Manifest placeholders for Wallet deepLink
manifestPlaceholders["deepLinkScheme"] = walletScheme
Expand All @@ -83,10 +90,15 @@ class AndroidLibraryConventionPlugin : Plugin<Project> {
manifestPlaceholders["openid4vpScheme"] = openId4VpScheme
manifestPlaceholders["openid4vpHost"] = openid4VpHost

// Manifest placeholders used by the Core's VCI
manifestPlaceholders["openid4vciAuthorizeHost"] = openid4VciHost
manifestPlaceholders["openid4vciAuthorizePath"] = openid4VciPath
manifestPlaceholders["openid4vciAuthorizeScheme"] = openId4VciScheme
// Manifest placeholders used for OpenId4VCI
manifestPlaceholders["openid4vciHost"] = openid4VciHost
manifestPlaceholders["openid4vciScheme"] = openId4VciScheme

// Manifest placeholders used for OpenId4VCI Authorization
manifestPlaceholders["openId4VciAuthorizationScheme"] =
openId4VciAuthorizationScheme
manifestPlaceholders["openId4VciAuthorizationHost"] =
openId4VciAuthorizationHost
}
configureFlavors(this, storedVersion)
configureGradleManagedDevices(this)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import eu.europa.ec.uilogic.serializer.UiSerializable
import eu.europa.ec.uilogic.serializer.UiSerializableParser
import eu.europa.ec.uilogic.serializer.adapter.SerializableTypeAdapter

enum class QrScanFlow{
enum class QrScanFlow {
PRESENTATION,
ISSUANCE,
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,10 @@ internal class WalletCoreConfigImpl(
withScheme(BuildConfig.OPENID4VP_SCHEME)
}
.openId4VciConfig {
withIssuerUrl(issuerUrl = VCI_ISSUER_URL)
withClientId(clientId = VCI_CLIENT_ID)
issuerUrl(issuerUrl = VCI_ISSUER_URL)
clientId(clientId = VCI_CLIENT_ID)
authFlowRedirectionURI(BuildConfig.ISSUE_AUTHORIZATION_DEEPLINK)
useStrongBoxIfSupported(true)
}
.trustedReaderCertificates(R.raw.eudi_pid_issuer_ut)
.build()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,10 @@ internal class WalletCoreConfigImpl(
withScheme(BuildConfig.OPENID4VP_SCHEME)
}
.openId4VciConfig {
withIssuerUrl(issuerUrl = VCI_ISSUER_URL)
withClientId(clientId = VCI_CLIENT_ID)
issuerUrl(issuerUrl = VCI_ISSUER_URL)
clientId(clientId = VCI_CLIENT_ID)
authFlowRedirectionURI(BuildConfig.ISSUE_AUTHORIZATION_DEEPLINK)
useStrongBoxIfSupported(true)
}
.trustedReaderCertificates(R.raw.eudi_pid_issuer_ut)
.build()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@ import eu.europa.ec.corelogic.model.toDocumentType
import eu.europa.ec.eudi.wallet.EudiWallet
import eu.europa.ec.eudi.wallet.document.DeleteDocumentResult
import eu.europa.ec.eudi.wallet.document.Document
import eu.europa.ec.eudi.wallet.document.issue.IssueDocumentResult
import eu.europa.ec.eudi.wallet.document.sample.LoadSampleResult
import eu.europa.ec.eudi.wallet.issue.openid4vci.IssueEvent
import eu.europa.ec.eudi.wallet.issue.openid4vci.OpenId4VciManager
import eu.europa.ec.resourceslogic.R
import eu.europa.ec.resourceslogic.provider.ResourceProvider
import kotlinx.coroutines.channels.ProducerScope
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.channels.trySendBlocking
import kotlinx.coroutines.flow.Flow
Expand All @@ -43,20 +45,26 @@ enum class IssuanceMethod {

sealed class IssueDocumentPartialState {
data class Success(val documentId: String) : IssueDocumentPartialState()

data class Failure(val errorMessage: String) : IssueDocumentPartialState()
data class UserAuthRequired(
val crypto: BiometricCrypto,
val resultHandler: DeviceAuthenticationResult
) : IssueDocumentPartialState()
}

sealed class OpenId4VCIIssueDocumentPartialState {
data class Success(val documentId: String) : OpenId4VCIIssueDocumentPartialState()
data class Failure(val errorMessage: String) : OpenId4VCIIssueDocumentPartialState()
sealed class IssueDocumentsPartialState {
data class Success(val documentIds: List<String>) : IssueDocumentsPartialState()
data class PartialSuccess(
val documentIds: List<String>,
val nonIssuedDocuments: Map<String, String>
) : IssueDocumentsPartialState()

data class Failure(val errorMessage: String) : IssueDocumentsPartialState()
data class UserAuthRequired(
val crypto: BiometricCrypto,
val resultHandler: DeviceAuthenticationResult
) : OpenId4VCIIssueDocumentPartialState()
) : IssueDocumentsPartialState()
}

sealed class AddSampleDataPartialState {
Expand Down Expand Up @@ -171,24 +179,30 @@ class WalletCoreDocumentsControllerImpl(
IssuanceMethod.OPENID4VCI -> {
issueDocumentWithOpenId4VCI(documentType = documentType).collect { response ->
when (response) {
is OpenId4VCIIssueDocumentPartialState.Failure -> emit(
is IssueDocumentsPartialState.Failure -> emit(
IssueDocumentPartialState.Failure(
errorMessage = response.errorMessage
)
)

is OpenId4VCIIssueDocumentPartialState.Success -> emit(
is IssueDocumentsPartialState.Success -> emit(
IssueDocumentPartialState.Success(
documentId = response.documentId
response.documentIds.first()
)
)

is OpenId4VCIIssueDocumentPartialState.UserAuthRequired -> emit(
is IssueDocumentsPartialState.UserAuthRequired -> emit(
IssueDocumentPartialState.UserAuthRequired(
crypto = response.crypto,
resultHandler = response.resultHandler
)
)

is IssueDocumentsPartialState.PartialSuccess -> {
IssueDocumentPartialState.Success(
response.documentIds.first()
)
}
}
}
}
Expand Down Expand Up @@ -276,46 +290,94 @@ class WalletCoreDocumentsControllerImpl(
)
}

private fun issueDocumentWithOpenId4VCI(documentType: String): Flow<OpenId4VCIIssueDocumentPartialState> =
private fun issueDocumentWithOpenId4VCI(documentType: String): Flow<IssueDocumentsPartialState> =
callbackFlow {
eudiWallet.issueDocument(

eudiWallet.issueDocumentByDocType(
docType = documentType,
callback = { result ->
when (result) {
is IssueDocumentResult.Failure -> {
val errorMessage = result.error.localizedMessage ?: genericErrorMessage
trySendBlocking(
OpenId4VCIIssueDocumentPartialState.Failure(
errorMessage = errorMessage
)
onEvent = issuanceCallback()
)

awaitClose()

}.safeAsync {
IssueDocumentsPartialState.Failure(
errorMessage = it.localizedMessage ?: genericErrorMessage
)
}

private fun ProducerScope<IssueDocumentsPartialState>.issuanceCallback(): OpenId4VciManager.OnIssueEvent {

var totalDocumentsToBeIssued = 0
val nonIssuedDocuments: MutableMap<String, String> = mutableMapOf()
val issuedDocuments: MutableMap<String, String> = mutableMapOf()

val listener = OpenId4VciManager.OnIssueEvent { event ->
when (event) {
is IssueEvent.DocumentFailed -> {
nonIssuedDocuments[event.docType] = event.name
}

is IssueEvent.DocumentRequiresUserAuth -> {
trySendBlocking(
IssueDocumentsPartialState.UserAuthRequired(
BiometricCrypto(event.cryptoObject),
DeviceAuthenticationResult(
onAuthenticationSuccess = { event.resume() },
onAuthenticationError = { event.cancel() },
onAuthenticationFailure = { event.cancel() },
)
}
)
)
}

is IssueDocumentResult.Success -> {
val documentId = result.documentId
trySendBlocking(OpenId4VCIIssueDocumentPartialState.Success(documentId = documentId))
}
is IssueEvent.Failure -> {
val errorMessage = event.cause.localizedMessage ?: genericErrorMessage
trySendBlocking(
IssueDocumentsPartialState.Failure(
errorMessage = errorMessage
)
)
}

is IssueDocumentResult.UserAuthRequired -> {
trySendBlocking(
OpenId4VCIIssueDocumentPartialState.UserAuthRequired(
BiometricCrypto(result.cryptoObject),
DeviceAuthenticationResult(
onAuthenticationSuccess = { result.resume() },
onAuthenticationError = { result.cancel() },
onAuthenticationFailure = { result.cancel() },
)
)
is IssueEvent.Finished -> {

if (event.issuedDocuments.isEmpty()) {
trySendBlocking(
IssueDocumentsPartialState.Failure(
errorMessage = genericErrorMessage
)
}
)
return@OnIssueEvent
}

if (event.issuedDocuments.size == totalDocumentsToBeIssued) {
trySendBlocking(
IssueDocumentsPartialState.Success(
documentIds = event.issuedDocuments
)
)
return@OnIssueEvent
}

trySendBlocking(
IssueDocumentsPartialState.PartialSuccess(
documentIds = event.issuedDocuments,
nonIssuedDocuments = nonIssuedDocuments
)
)
}
)

awaitClose()
}.safeAsync {
OpenId4VCIIssueDocumentPartialState.Failure(
errorMessage = it.localizedMessage ?: genericErrorMessage
)
is IssueEvent.DocumentIssued -> {
issuedDocuments[event.documentId] = event.docType
}

is IssueEvent.Started -> {
totalDocumentsToBeIssued = event.total
}
}
}

return listener
}
}
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ gson = "2.10.1"
logcat = "0.1"
googlePhoneNumber = "8.13.36"
zxing = "3.5.2"
eudiWalletCore = "0.5.6-SNAPSHOT"
eudiWalletCore = "0.6.0-SNAPSHOT"
cborTree = "0.01.02"
cameraCore = "1.3.3"
owaspDependencyCheck = "9.0.9"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,15 +109,16 @@ class DocumentDetailsInteractorImpl(
}

if (shouldDeleteAllDocuments) {
walletCoreDocumentsController.deleteAllDocuments(mainPidDocumentId = documentId).map {
when (it) {
is DeleteAllDocumentsPartialState.Failure -> DocumentDetailsInteractorDeleteDocumentPartialState.Failure(
errorMessage = it.errorMessage
)

is DeleteAllDocumentsPartialState.Success -> DocumentDetailsInteractorDeleteDocumentPartialState.AllDocumentsDeleted
walletCoreDocumentsController.deleteAllDocuments(mainPidDocumentId = documentId)
.map {
when (it) {
is DeleteAllDocumentsPartialState.Failure -> DocumentDetailsInteractorDeleteDocumentPartialState.Failure(
errorMessage = it.errorMessage
)

is DeleteAllDocumentsPartialState.Success -> DocumentDetailsInteractorDeleteDocumentPartialState.AllDocumentsDeleted
}
}
}
} else {
walletCoreDocumentsController.deleteDocument(documentId = documentId).map {
when (it) {
Expand Down
1 change: 1 addition & 0 deletions ui-logic/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ dependencies {
implementation(project(LibraryModule.ResourcesLogic.path))
implementation(project(LibraryModule.BusinessLogic.path))
implementation(project(LibraryModule.AnalyticsLogic.path))
implementation(project(LibraryModule.CoreLogic.path))

implementation(libs.zxing)
implementation(libs.gson)
Expand Down
Loading

0 comments on commit 3b21f1b

Please sign in to comment.