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

OID4VP #37

Merged
merged 7 commits into from
Oct 22, 2024
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
5 changes: 5 additions & 0 deletions .idea/inspectionProfiles/Project_Default.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

210 changes: 103 additions & 107 deletions MobileSdk/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,140 +1,136 @@
plugins {
id("com.android.library")
id("org.jetbrains.kotlin.android")
`maven-publish`
id("signing")
id("com.gradleup.nmcp")
id("com.android.library")
id("org.jetbrains.kotlin.android")
`maven-publish`
id("signing")
id("com.gradleup.nmcp")
}

publishing {
repositories {
maven {
name = "GitHubPackages"
url = uri("https://maven.pkg.github.com/spruceid/mobile-sdk-kt")
credentials {
username = System.getenv("GITHUB_ACTOR")
password = System.getenv("GITHUB_TOKEN")
}
}
}
publications {
create<MavenPublication>("debug") {
groupId = "com.spruceid.mobile.sdk"
artifactId = "mobilesdk"
version = System.getenv("VERSION")

afterEvaluate { from(components["release"]) }
}
// Creates a Maven publication called "release".
create<MavenPublication>("release") {
groupId = "com.spruceid.mobile.sdk"
artifactId = "mobilesdk"
version = System.getenv("VERSION")

afterEvaluate { from(components["release"]) }

pom {
packaging = "aar"
name.set("mobilesdk")
description.set("Android SpruceID Mobile SDK")
url.set("https://github.com/spruceid/mobile-sdk-kt")
licenses {
license {
name.set("MIT License")
url.set("https://opensource.org/license/mit/")
}
license {
name.set("Apache License, Version 2.0")
url.set("http://www.apache.org/licenses/LICENSE-2.0.txt")
}
}
developers {
developer {
name.set("Spruce Systems, Inc.")
email.set("[email protected]")
}
repositories {
maven {
name = "GitHubPackages"
url = uri("https://maven.pkg.github.com/spruceid/mobile-sdk-kt")
credentials {
username = System.getenv("GITHUB_ACTOR")
password = System.getenv("GITHUB_TOKEN")
}
}
scm {
url.set(pom.url.get())
connection.set("scm:git:${url.get()}.git")
developerConnection.set("scm:git:${url.get()}.git")
}
publications {
// Creates a Maven publication called "release".
create<MavenPublication>("release") {
groupId = "com.spruceid.mobile.sdk"
artifactId = "mobilesdk"
version = System.getenv("VERSION")

afterEvaluate { from(components["release"]) }

pom {
packaging = "aar"
name.set("mobilesdk")
description.set("Android SpruceID Mobile SDK")
url.set("https://github.com/spruceid/mobile-sdk-kt")
licenses {
license {
name.set("MIT License")
url.set("https://opensource.org/license/mit/")
}
license {
name.set("Apache License, Version 2.0")
url.set("http://www.apache.org/licenses/LICENSE-2.0.txt")
}
}
developers {
developer {
name.set("Spruce Systems, Inc.")
email.set("[email protected]")
}
}
scm {
url.set(pom.url.get())
connection.set("scm:git:${url.get()}.git")
developerConnection.set("scm:git:${url.get()}.git")
}
}
}
}
}
}
}

signing {
useGpgCmd()
sign(publishing.publications["release"])
useGpgCmd()
sign(publishing.publications["release"])
}

nmcp {
afterEvaluate {
publish("release") {
username = System.getenv("MAVEN_USERNAME")
password = System.getenv("MAVEN_PASSWORD")
publicationType = "AUTOMATIC"
afterEvaluate {
publish("release") {
username = System.getenv("MAVEN_USERNAME")
password = System.getenv("MAVEN_PASSWORD")
publicationType = "AUTOMATIC"
}
}
}
}

android {
namespace = "com.spruceid.mobile.sdk"
compileSdk = 35

defaultConfig {
minSdk = 26
defaultConfig {
minSdk = 26

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles("consumer-rules.pro")
}
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles("consumer-rules.pro")
}

buildTypes {
release {
isMinifyEnabled = false
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
}

compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}

kotlinOptions { jvmTarget = "1.8" }
kotlinOptions { jvmTarget = "1.8" }

buildFeatures {
compose = true
viewBinding = true
}
buildFeatures {
compose = true
viewBinding = true
}

composeOptions { kotlinCompilerExtensionVersion = "1.5.11" }
composeOptions { kotlinCompilerExtensionVersion = "1.5.11" }

publishing {
singleVariant("release") {
withSourcesJar()
withJavadocJar()
publishing {
singleVariant("release") {
withSourcesJar()
withJavadocJar()
}
}
}
}

dependencies {
api("com.spruceid.mobile.sdk.rs:mobilesdkrs:0.1.0")
//noinspection GradleCompatible
implementation("com.android.support:appcompat-v7:28.0.0")
/* Begin UI dependencies */
implementation("androidx.compose.material3:material3:1.2.1")
implementation("androidx.camera:camera-camera2:1.3.2")
implementation("androidx.camera:camera-lifecycle:1.3.2")
implementation("androidx.camera:camera-view:1.3.2")
implementation("com.google.zxing:core:3.5.1")
implementation("com.google.accompanist:accompanist-permissions:0.34.0")
implementation("androidx.camera:camera-mlkit-vision:1.3.0-alpha06")
implementation("com.google.android.gms:play-services-mlkit-text-recognition:19.0.0")
/* End UI dependencies */
implementation("androidx.datastore:datastore-preferences:1.1.1")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("com.android.support.test:runner:1.0.2")
androidTestImplementation("com.android.support.test.espresso:espresso-core:3.0.2")
api("com.spruceid.mobile.sdk.rs:mobilesdkrs:0.2.1")
//noinspection GradleCompatible
implementation("com.android.support:appcompat-v7:28.0.0")
/* Begin UI dependencies */
implementation("androidx.compose.material3:material3:1.2.1")
implementation("androidx.camera:camera-camera2:1.3.2")
implementation("androidx.camera:camera-lifecycle:1.3.2")
implementation("androidx.camera:camera-view:1.3.2")
implementation("com.google.zxing:core:3.5.1")
implementation("com.google.accompanist:accompanist-permissions:0.34.0")
implementation("androidx.camera:camera-mlkit-vision:1.3.0-alpha06")
implementation("com.google.android.gms:play-services-mlkit-text-recognition:19.0.0")
/* End UI dependencies */
implementation("androidx.datastore:datastore-preferences:1.1.1")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("com.android.support.test:runner:1.0.2")
androidTestImplementation("com.android.support.test.espresso:espresso-core:3.0.2")
}
25 changes: 25 additions & 0 deletions MobileSdk/src/main/java/com/spruceid/mobile/sdk/Credential.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.spruceid.mobile.sdk
import com.spruceid.mobile.sdk.rs.JsonVc
import com.spruceid.mobile.sdk.rs.JwtVc
import com.spruceid.mobile.sdk.rs.Mdoc
import com.spruceid.mobile.sdk.rs.Vcdm2SdJwt
import org.json.JSONException
import org.json.JSONObject
import org.json.JSONTokener
Expand Down Expand Up @@ -97,6 +98,30 @@ fun JsonVc.credentialClaimsFiltered(claimNames: List<String>): JSONObject {
return new
}

/**
* Access the VCDM 2.0 SD-JWT credential.
*/
fun Vcdm2SdJwt.credentialClaims(): JSONObject {
try {
return JSONObject(this.revealedClaimsAsJsonString())
} catch (e: Error) {
print("failed to decode SD-JWT data from UTF-8-encoded JSON")
return JSONObject()
}
}

/**
* Access the specified claims from the VCDM 2.0 SD-JWT credential.
*/
fun Vcdm2SdJwt.credentialClaimsFiltered(claimNames: List<String>): JSONObject {
val old = this.credentialClaims()
val new = JSONObject()
for (name in claimNames) {
new.put(name, keyPathFinder(old, name.split(".").toMutableList()))
}
return new
}

private fun keyPathFinder(json: Any, path: MutableList<String>): Any {
try {
val firstKey = path.first()
Expand Down
34 changes: 31 additions & 3 deletions MobileSdk/src/main/java/com/spruceid/mobile/sdk/CredentialPack.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.spruceid.mobile.sdk.rs.JsonVc
import com.spruceid.mobile.sdk.rs.JwtVc
import com.spruceid.mobile.sdk.rs.Mdoc
import com.spruceid.mobile.sdk.rs.ParsedCredential
import com.spruceid.mobile.sdk.rs.Vcdm2SdJwt
import org.json.JSONObject

/**
Expand Down Expand Up @@ -44,6 +45,14 @@ class CredentialPack {
return credentials
}

/**
* Add a SD-JWT to the CredentialPack.
*/
fun addSdJwt(sdJwt: Vcdm2SdJwt): List<ParsedCredential> {
credentials.add(ParsedCredential.newSdJwt(sdJwt))
return credentials
}

/**
* Find claims from all credentials in this CredentialPack.
*/
Expand All @@ -54,13 +63,32 @@ class CredentialPack {
val mdoc = credential.asMsoMdoc()
val jwtVc = credential.asJwtVc()
val jsonVc = credential.asJsonVc()
val sdJwt = credential.asSdJwt()

if (mdoc != null) {
claims = mdoc.jsonEncodedDetailsFiltered(claimNames)
claims = if (claimNames.isNotEmpty()) {
mdoc.jsonEncodedDetailsFiltered(claimNames)
} else {
mdoc.jsonEncodedDetailsAll()
}
} else if (jwtVc != null) {
claims = jwtVc.credentialClaimsFiltered(claimNames)
claims = if (claimNames.isNotEmpty()) {
jwtVc.credentialClaimsFiltered(claimNames)
} else {
jwtVc.credentialClaims()
}
} else if (jsonVc != null) {
claims = jsonVc.credentialClaimsFiltered(claimNames)
claims = if (claimNames.isNotEmpty()) {
jsonVc.credentialClaimsFiltered(claimNames)
} else {
jsonVc.credentialClaims()
}
} else if (sdJwt != null) {
claims = if (claimNames.isNotEmpty()) {
sdJwt.credentialClaimsFiltered(claimNames)
} else {
sdJwt.credentialClaims()
}
} else {
var type: String
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import androidx.compose.foundation.layout.IntrinsicSize
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
Expand Down Expand Up @@ -162,7 +164,9 @@ fun CardDetailsView(
credentialPack: CredentialPack,
rendering: CardRenderingDetailsView
) {
Column {
Column(
Modifier.verticalScroll(rememberScrollState())
) {
rendering.fields.forEach {
val values = credentialPack.findCredentialClaims(it.keys)

Expand Down
Loading
Loading