Skip to content

Commit

Permalink
feat: revocation notification
Browse files Browse the repository at this point in the history
  • Loading branch information
cristianIOHK committed Apr 17, 2024
1 parent a536386 commit 862aef4
Show file tree
Hide file tree
Showing 16 changed files with 85 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ interface Pollux {
* @param credentialData The byte array containing the credential data.
* @return The restored credential.
*/
fun restoreCredential(restorationIdentifier: String, credentialData: ByteArray): Credential
fun restoreCredential(restorationIdentifier: String, credentialData: ByteArray, revoked: Boolean): Credential

/**
* Converts a [Credential] object to a [StorableCredential] object of the specified [CredentialType].
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ interface Credential {
val subject: String?
val claims: Array<Claim>
val properties: Map<String, Any?>
var revoked: Boolean?
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ interface StorableCredential : Credential {
val credentialUpdated: String?
val credentialSchema: String?
val validUntil: String?
val revoked: Boolean?
val availableClaims: Array<String>

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ package io.iohk.atala.prism.walletsdk.pluto
* @property restorationId The restoration ID associated with the credential recovery.
* @property credentialData The credential data as a byte array.
*/
class CredentialRecovery(val restorationId: String, val credentialData: ByteArray)
class CredentialRecovery(val restorationId: String, val credentialData: ByteArray, val revoked: Boolean)
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,11 @@ class PlutoImpl(private val connection: DbConnection) : Pluto {
PrismPlutoDb.Schema.version,
AfterVersion(1) {
it.execute(null, "ALTER TABLE CredentialMetadata DROB COLUMN nonce;", 0)
it.execute(null, "ALTER TABLE CredentialMetadata DROB COLUMN linkSecretBlindingData;", 0)
it.execute(
null,
"ALTER TABLE CredentialMetadata DROB COLUMN linkSecretBlindingData;",
0
)
it.execute(null, "ALTER TABLE CredentialMetadata ADD COLUMN json TEXT;", 0)
}
)
Expand Down Expand Up @@ -926,7 +930,8 @@ class PlutoImpl(private val connection: DbConnection) : Pluto {
it.executeAsList().map { credential ->
CredentialRecovery(
restorationId = credential.recoveryId,
credentialData = credential.credentialData
credentialData = credential.credentialData,
revoked = credential.revoked != 0
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,25 +147,29 @@ class PolluxImpl(
*/
override fun restoreCredential(
restorationIdentifier: String,
credentialData: ByteArray
credentialData: ByteArray,
revoked: Boolean
): Credential {
return when (restorationIdentifier) {
val cred: Credential
when (restorationIdentifier) {
"jwt+credential" -> {
JWTCredential(credentialData.decodeToString())
cred = JWTCredential(credentialData.decodeToString())
}

"anon+credential" -> {
AnonCredential.fromStorableData(credentialData)
cred = AnonCredential.fromStorableData(credentialData)
}

"w3c+credential" -> {
Json.decodeFromString<W3CCredential>(credentialData.decodeToString())
cred = Json.decodeFromString<W3CCredential>(credentialData.decodeToString())
}

else -> {
throw PolluxError.InvalidCredentialError()
}
}
cred.revoked = revoked
return cred
}

/**
Expand Down Expand Up @@ -258,8 +262,10 @@ class PolluxImpl(
val presentationRequest = PresentationRequest(attachmentBase64.base64.base64UrlDecoded)
val cred = anoncreds_wrapper.Credential(credential.id)

val requestedAttributes = presentationRequest.getRequestedAttributes().toListRequestedAttribute()
val requestedPredicate = presentationRequest.getRequestedPredicates().toListRequestedPredicate()
val requestedAttributes =
presentationRequest.getRequestedAttributes().toListRequestedAttribute()
val requestedPredicate =
presentationRequest.getRequestedPredicates().toListRequestedPredicate()

val credentialRequests = CredentialRequests(
credential = cred,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ data class AnonCredential(
return properties.toMap()
}

override var revoked: Boolean? = null

/**
* Converts the current credential object into a storable credential object.
*
Expand Down Expand Up @@ -119,8 +121,7 @@ data class AnonCredential(
override val validUntil: String?
get() = null

override val revoked: Boolean?
get() = null
override var revoked: Boolean? = c.revoked

override val availableClaims: Array<String>
get() = c.claims.map { it.key }.toTypedArray()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ data class JWTCredential(val data: String) : Credential {
return properties.toMap()
}

override var revoked: Boolean? = null

/**
* Converts the current instance of [JWTCredential] to a [StorableCredential].
*
Expand Down Expand Up @@ -105,8 +107,7 @@ data class JWTCredential(val data: String) : Credential {
get() = c.jwtPayload.verifiableCredential.credentialSchema?.type
override val validUntil: String?
get() = null
override val revoked: Boolean?
get() = null
override var revoked: Boolean? = c.revoked
override val availableClaims: Array<String>
get() = c.claims.map { it.key }.toTypedArray()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ data class W3CCredential @JvmOverloads constructor(
return properties.toMap()
}

override var revoked: Boolean? = null

/**
* Converts the current W3CCredential object to a StorableCredential object that can be stored and retrieved from a storage system.
*
Expand All @@ -102,8 +104,7 @@ data class W3CCredential @JvmOverloads constructor(
get() = c.credentialSchema?.type
override val validUntil: String?
get() = null
override val revoked: Boolean?
get() = null
override var revoked: Boolean? = c.revoked
override val availableClaims: Array<String>
get() = claims.map { it.key }.toTypedArray()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import io.iohk.atala.prism.walletsdk.domain.models.CredentialType
import io.iohk.atala.prism.walletsdk.domain.models.DID
import io.iohk.atala.prism.walletsdk.domain.models.DIDPair
import io.iohk.atala.prism.walletsdk.domain.models.Message
import io.iohk.atala.prism.walletsdk.pollux.models.JWTCredential
import io.iohk.atala.prism.walletsdk.prismagent.connectionsmanager.ConnectionsManager
import io.iohk.atala.prism.walletsdk.prismagent.connectionsmanager.DIDCommConnection
import io.iohk.atala.prism.walletsdk.prismagent.mediation.MediationHandler
Expand Down Expand Up @@ -214,7 +213,7 @@ class ConnectionManager(

internal fun processMessages(arrayMessages: Array<Pair<String, Message>>) {
scope.launch {
val messagesIds = mutableListOf<String>()
val messagesIds = mutableListOf<String>()
val messages = mutableListOf<Message>()
arrayMessages.map { pair ->
messagesIds.add(pair.first)
Expand All @@ -233,7 +232,8 @@ class ConnectionManager(
matchingMessages.forEach { message ->
val issueMessage = IssueCredential.fromMessage(message)
if (pollux.extractCredentialFormatFromMessage(issueMessage.attachments) == CredentialType.JWT) {
val attachment = issueMessage.attachments.firstOrNull()?.data as? AttachmentBase64
val attachment =
issueMessage.attachments.firstOrNull()?.data as? AttachmentBase64
attachment?.let {
val credentialId = it.base64.base64UrlDecoded
pluto.revokeCredential(credentialId)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -881,7 +881,7 @@ class PrismAgent {
return pluto.getAllCredentials()
.map { list ->
list.map {
pollux.restoreCredential(it.restorationId, it.credentialData)
pollux.restoreCredential(it.restorationId, it.credentialData, it.revoked)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@file:Suppress("ktlint:standard:import-ordering")

package io.iohk.atala.prism.walletsdk.prismagent.protocols.revocation

import io.iohk.atala.prism.walletsdk.domain.models.DID
Expand Down Expand Up @@ -39,8 +41,8 @@ class RevocationNotification(
fun fromMessage(message: Message): RevocationNotification {
require(
message.piuri == ProtocolType.PrismRevocation.value &&
message.from != null &&
message.to != null
message.from != null &&
message.to != null
) {
throw PrismAgentError.InvalidMessageType(
type = message.piuri,
Expand All @@ -54,4 +56,4 @@ class RevocationNotification(
)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,9 @@ import org.mockito.MockitoAnnotations
import org.mockito.kotlin.any
import java.util.UUID
import kotlinx.coroutines.flow.Flow
import org.mockito.ArgumentCaptor
import org.mockito.Mockito.anyList
import org.mockito.kotlin.anyArray
import org.mockito.kotlin.argumentCaptor
import org.mockito.kotlin.mock
import kotlin.test.assertNotNull
import kotlin.test.BeforeTest
import kotlin.test.Test
Expand Down Expand Up @@ -179,6 +177,32 @@ class ConnectionManagerTest {
)
}
)
val attachments: Array<AttachmentDescriptor> =
arrayOf(
AttachmentDescriptor(
mediaType = "application/json",
format = CredentialType.JWT.type,
data = AttachmentBase64(base64 = "asdfasdfasdfasdfasdfasdfasdfasdfasdf".base64UrlEncoded)
)
)
val listMessages = listOf(
Message(
piuri = ProtocolType.DidcommconnectionRequest.value,
body = ""
),
Message(
piuri = ProtocolType.DidcommIssueCredential.value,
thid = UUID.randomUUID().toString(),
from = DID("did:peer:asdf897a6sdf"),
to = DID("did:peer:f706sg678ha"),
attachments = attachments,
body = """{}"""
)
)
val messageList: Flow<List<Message>> = flow {
emit(listMessages)
}
`when`(plutoMock.getAllMessages()).thenReturn(messageList)

connectionManager.startFetchingMessages()
assertNotNull(connectionManager.fetchingMessagesJob)
Expand Down Expand Up @@ -219,16 +243,16 @@ class ConnectionManagerTest {

val messages = arrayOf(
Pair(
threadId, Message(
threadId,
Message(
piuri = ProtocolType.PrismRevocation.value,
from = DID("did:peer:0978aszdf7890asg"),
to = DID("did:peer:asdf9068asdf"),
body = """{"threadId":"$threadId","comment":null}"""
body = """{"issueCredentialProtocolThreadId":"$threadId","comment":null}"""
)
)
)


connectionManager.processMessages(messages)
val argumentCaptor = argumentCaptor<String>()
verify(plutoMock).revokeCredential(argumentCaptor.capture())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class PolluxMock : Pollux {
TODO("Not yet implemented")
}

override fun restoreCredential(restorationIdentifier: String, credentialData: ByteArray): Credential {
override fun restoreCredential(restorationIdentifier: String, credentialData: ByteArray, revoked: Boolean): Credential {
TODO("Not yet implemented")
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ class CredentialsAdapter(private var data: MutableList<Credential> = mutableList
private val type: TextView = itemView.findViewById(R.id.credential_id)
private val issuanceDate: TextView = itemView.findViewById(R.id.credential_issuance_date)
private val expDate: TextView = itemView.findViewById(R.id.credential_expiration_date)
private val revoked: TextView = itemView.findViewById(R.id.revoked)
private val typeString: String = itemView.context.getString(R.string.credential_type)
private val issuanceString: String = itemView.context.getString(R.string.credential_issuance)
private val expirationString: String = itemView.context.getString(R.string.credential_expiration)
Expand All @@ -70,6 +71,9 @@ class CredentialsAdapter(private var data: MutableList<Credential> = mutableList
when (cred::class) {
JWTCredential::class -> {
val jwt = cred as JWTCredential
if (jwt.revoked != null && jwt.revoked!!) {
revoked.visibility = View.VISIBLE
}
type.text = String.format(typeString, "JWT")
// TODO: Check what else to display
jwt.jwtPayload.nbf?.let {
Expand Down
11 changes: 10 additions & 1 deletion sampleapp/src/main/res/layout/placeholder_credential.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/cardview_dark_background"
android:background="#F1F1F1"
android:orientation="vertical"
android:padding="8dp">

Expand All @@ -30,6 +30,15 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp" />

<TextView
android:id="@+id/revoked"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Revoked"
android:layout_gravity="end"
android:visibility="gone"
/>

</LinearLayout>
</LinearLayout>

0 comments on commit 862aef4

Please sign in to comment.