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

Fix #3: Handle model difference in Issuer config and Offer credential #17

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
Original file line number Diff line number Diff line change
Expand Up @@ -119,14 +119,17 @@ class MainViewModel : ViewModel() {
}

private suspend fun getCredential() {
val types = IssueService().getTypesFromCredentialOffer(offerCredential)
val format = IssueService().getFormatFromIssuerConfig(issuerConfig, types.lastOrNull() ?:"")
val credential = IssueService().processCredentialRequest(
did,
subJwk,
issuerConfig?.credentialIssuer,
tokenResponse?.tokenResponse?.cNonce,
offerCredential,
issuerConfig?.credentialEndpoint,
tokenResponse?.tokenResponse?.accessToken
tokenResponse?.tokenResponse?.accessToken,
format?:"jwt_vc"
)

withContext(Dispatchers.Main) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ data class AuthorisationServerWellKnownConfiguration(
@SerializedName("response_modes_supported") var responseModesSupported: ArrayList<String> = arrayListOf(),
@SerializedName("grant_types_supported") var grantTypesSupported: ArrayList<String> = arrayListOf(),
@SerializedName("subject_types_supported") var subjectTypesSupported: ArrayList<String> = arrayListOf(),
// @SerializedName("id_token_signing_alg_values_supported") var idTokenSigningAlgValuesSupported: ArrayList<String> = arrayListOf(),
@SerializedName("request_object_signing_alg_values_supported") var requestObjectSigningAlgValuesSupported: ArrayList<String> = arrayListOf(),
@SerializedName("request_parameter_supported") var requestParameterSupported: Boolean? = null,
@SerializedName("request_uri_parameter_supported") var requestUriParameterSupported: Boolean? = null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,21 @@ package com.ewc.eudi_wallet_oidc_android.models
import com.google.gson.annotations.SerializedName

data class CredentialOffer(
@SerializedName("credential_issuer") var credentialIssuer: String? = null,
@SerializedName("credentials") var credentials: ArrayList<Any>? = null,
@SerializedName("grants") var grants: Grants? = null
)

data class CredentialOfferV1(
@SerializedName("credential_issuer") var credentialIssuer: String? = null,
@SerializedName("credentials") var credentials: ArrayList<Credentials>? = null,
@SerializedName("grants") var grants: Grants? = null
)

data class CredentialOfferV2(
@SerializedName("credential_issuer") var credentialIssuer: String? = null,
@SerializedName("credentials") var credentials: ArrayList<String>? = null,
@SerializedName("grants") var grants: Grants? = null
)

data class Credentials(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,34 @@ package com.ewc.eudi_wallet_oidc_android.models
import com.google.gson.annotations.SerializedName

data class IssuerWellKnownConfiguration(

@SerializedName("issuer") var issuer: String? = null,
@SerializedName("credential_issuer") var credentialIssuer: String? = null,
@SerializedName("authorization_server") var authorizationServer: String? = null,
@SerializedName("authorization_servers") var authorizationServers: ArrayList<String>? = null,
@SerializedName("credential_endpoint") var credentialEndpoint: String? = null,
@SerializedName("deferred_credential_endpoint") var deferredCredentialEndpoint: String? = null,
@SerializedName("display") var display: Display? = null,
@SerializedName("credentials_supported") var credentialsSupported: ArrayList<CredentialsSupported> = arrayListOf()

@SerializedName("display") var display: Any? = null,
@SerializedName("credentials_supported") var credentialsSupported: Any? = null
)

data class CredentialsSupported(

@SerializedName("format") var format: String? = null,
@SerializedName("types") var types: ArrayList<String> = arrayListOf(),
@SerializedName("trust_framework") var trustFramework: TrustFramework? = TrustFramework(),
@SerializedName("display") var display: ArrayList<Display> = arrayListOf()

)

data class Display(

@SerializedName("name") var name: String? = null,
@SerializedName("location") var location: String? = null,
@SerializedName("locale") var locale: String? = null,
@SerializedName("cover") var cover: Image? = Image(),
@SerializedName("logo") var logo: Image? = Image(),
@SerializedName("description") var description: String? = null

)

data class Image(

@SerializedName("uri") var uri: String? = null,
@SerializedName("url") var url: String? = null,
@SerializedName("alt_text") var altText: String? = null

)
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ import android.net.Uri
import com.ewc.eudi_wallet_oidc_android.models.AuthorizationDetails
import com.ewc.eudi_wallet_oidc_android.models.ClientMetaData
import com.ewc.eudi_wallet_oidc_android.models.CredentialOffer
import com.ewc.eudi_wallet_oidc_android.models.CredentialOfferV1
import com.ewc.eudi_wallet_oidc_android.models.CredentialOfferV2
import com.ewc.eudi_wallet_oidc_android.models.CredentialRequest
import com.ewc.eudi_wallet_oidc_android.models.ErrorResponse
import com.ewc.eudi_wallet_oidc_android.models.IssuerWellKnownConfiguration
import com.ewc.eudi_wallet_oidc_android.models.Jwt
import com.ewc.eudi_wallet_oidc_android.models.ProofV3
import com.ewc.eudi_wallet_oidc_android.models.TokenResponse
import com.ewc.eudi_wallet_oidc_android.models.VpFormatsSupported
import com.ewc.eudi_wallet_oidc_android.models.WrappedCredentialResponse
import com.ewc.eudi_wallet_oidc_android.models.WrappedTokenResponse
Expand Down Expand Up @@ -84,7 +86,7 @@ class IssueService : IssueServiceInterface {
val authorisationDetails = Gson().toJson(
arrayListOf(
AuthorizationDetails(
types = credentialOffer?.credentials?.get(0)?.types,
types = getTypesFromCredentialOffer(credentialOffer),
locations = arrayListOf(credentialOffer?.credentialIssuer ?: "")
)
)
Expand Down Expand Up @@ -267,7 +269,8 @@ class IssueService : IssueServiceInterface {
nonce: String?,
credentialOffer: CredentialOffer?,
credentialIssuerEndPoint: String?,
accessToken: String?
accessToken: String?,
format:String
): WrappedCredentialResponse? {

// Add claims
Expand Down Expand Up @@ -296,8 +299,8 @@ class IssueService : IssueServiceInterface {

// Construct credential request
val body = CredentialRequest(
types = credentialOffer?.credentials?.get(0)?.types,
format = credentialOffer?.credentials?.get(0)?.format,
types = getTypesFromCredentialOffer(credentialOffer),
format = format,
ProofV3(
proofType = "jwt",
jwt = jwt.serialize()
Expand Down Expand Up @@ -413,5 +416,79 @@ class IssueService : IssueServiceInterface {
}
}

/**
* Get format from IssuerWellKnownConfiguration
*
* @param issuerConfig
* @param type
*/
override fun getFormatFromIssuerConfig(
issuerConfig: IssuerWellKnownConfiguration?,
type: String?
): String? {
var format: String = "jwt_vc"
val credentialOfferJsonString = Gson().toJson(issuerConfig)

val jsonObject = JSONObject(credentialOfferJsonString)

val credentialsSupported: Any = jsonObject.opt("credentials_supported") ?: return null

when (credentialsSupported) {
is JSONObject -> {
val credentialSupported = credentialsSupported.getJSONObject(type ?: "")
format = credentialSupported.getString("format")
}

is JSONArray -> {
for (i in 0 until credentialsSupported.length()) {
val jsonObject: JSONObject = credentialsSupported.getJSONObject(i)

// Get the "types" JSONArray
val typesArray = jsonObject.getJSONArray("types")

// Check if the string is present in the "types" array
for (j in 0 until typesArray.length()) {
if (typesArray.getString(j) == type) {
format = jsonObject.getString("format")
break
}
}
}
}

else -> {
// Neither JSONObject nor JSONArray
println("Child is neither JSONObject nor JSONArray")
}
}

return format
}

/**
* Get types from credential offer
*
* @param credentialOffer
* @return
*/
override fun getTypesFromCredentialOffer(credentialOffer: CredentialOffer?): ArrayList<String> {
var types: ArrayList<String> = ArrayList()
val credentialOfferJsonString = Gson().toJson(credentialOffer)
try {
try {
val credentialOfferV2 =
Gson().fromJson(credentialOfferJsonString, CredentialOfferV2::class.java)
types = credentialOfferV2.credentials ?: ArrayList()
} catch (e: Exception) {
val credentOfferV1 =
Gson().fromJson(credentialOfferJsonString, CredentialOfferV1::class.java)
types = credentOfferV1?.credentials?.get(0)?.types ?: ArrayList()
}
} catch (e: Exception) {

}

return types
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.ewc.eudi_wallet_oidc_android.services.issue

import com.ewc.eudi_wallet_oidc_android.models.CredentialOffer
import com.ewc.eudi_wallet_oidc_android.models.IssuerWellKnownConfiguration
import com.ewc.eudi_wallet_oidc_android.models.WrappedCredentialResponse
import com.ewc.eudi_wallet_oidc_android.models.WrappedTokenResponse
import com.nimbusds.jose.jwk.ECKey
Expand Down Expand Up @@ -83,7 +84,8 @@ interface IssueServiceInterface {
nonce: String?,
credentialOffer: CredentialOffer?,
credentialIssuerEndPoint: String?,
accessToken: String?
accessToken: String?,
format: String
): WrappedCredentialResponse?

/**
Expand All @@ -97,4 +99,25 @@ interface IssueServiceInterface {
acceptanceToken: String?,
deferredCredentialEndPoint: String?
): WrappedCredentialResponse?

/**
* Get format from IssuerWellKnownConfiguration
*
* @param issuerConfig
* @param type
*/
fun getFormatFromIssuerConfig(
issuerConfig: IssuerWellKnownConfiguration?,
type: String?
): String?

/**
* Get types from credential offer
*
* @param credentialOffer
* @return
*/
fun getTypesFromCredentialOffer(
credentialOffer: CredentialOffer?
): ArrayList<String>
}