Skip to content

Commit

Permalink
fix(pollux): fix JWTPayload serlization & Update Error Handling (#97)
Browse files Browse the repository at this point in the history
Signed-off-by: Ahmed Moussa <ahmed.moussa@iohk.io>
  • Loading branch information
hamada147 authored Aug 30, 2023
1 parent caf569e commit 9eb3927
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ abstract interface Error {
* This object may include an error code, an error message, and possibly an array of underlying errors. If the error
* received does not conform to the [Error] interface, it will be classified as an [UnknownPrismError].
*/
abstract class UnknownPrismError : Error, Throwable() {
abstract class UnknownPrismError @JvmOverloads constructor(message: String? = null, cause: Throwable? = null) : Error, Throwable(message, cause) {

override val code: Int?
get() = null
Expand All @@ -36,7 +36,7 @@ abstract class UnknownPrismError : Error, Throwable() {
* This object may include an error code and an error message. If the error received conforms to the [KnownPrismError],
* it will be classified as a known error.
*/
abstract class KnownPrismError : Error, Throwable() {
abstract class KnownPrismError @JvmOverloads constructor(message: String? = null, cause: Throwable? = null) : Error, Throwable(message, cause) {
override val code: Int?
get() = null
override val message: String?
Expand All @@ -54,12 +54,14 @@ abstract class KnownPrismError : Error, Throwable() {
* This object may include an error code, an error message, and possibly an array of underlying errors.
* If the error received does not conform to the [KnownPrismError], it will be classified as an [UnknownPrismError].
*/
abstract class UnknownError : UnknownPrismError() {
abstract class UnknownError @JvmOverloads constructor(message: String? = null, cause: Throwable? = null) : UnknownPrismError(message, cause) {

class SomethingWentWrongError(
message: String? = null,
cause: Throwable? = null,
private val customMessage: String? = null,
private val customUnderlyingErrors: Array<Error> = emptyArray()
) : UnknownError() {
) : UnknownError(message, cause) {
override val code: Int? = -1
override val message: String?
get() {
Expand All @@ -76,7 +78,7 @@ abstract class UnknownError : UnknownPrismError() {
* This object may include an error code and an error message. If the error received conforms to the [KnownPrismError],
* it will be classified as a known error.
*/
sealed class CommonError : KnownPrismError() {
sealed class CommonError @JvmOverloads constructor(message: String? = null, cause: Throwable? = null) : KnownPrismError(message, cause) {
class InvalidURLError(val url: String) : CommonError() {
override val code: Int
get() = -2
Expand All @@ -101,7 +103,7 @@ sealed class CommonError : KnownPrismError() {
* This object may include an error code and an error message. If the error received conforms to the [KnownPrismError],
* it will be classified as a known error.
*/
sealed class ApolloError : KnownPrismError() {
sealed class ApolloError @JvmOverloads constructor(message: String? = null, cause: Throwable? = null) : KnownPrismError(message, cause) {
class InvalidMnemonicWord(private val invalidWords: Array<String>? = null) : ApolloError() {
override val code: Int
get() = 11
Expand Down Expand Up @@ -147,7 +149,7 @@ sealed class ApolloError : KnownPrismError() {
* This object may include an error code and an error message. If the error received conforms to the [KnownPrismError],
* it will be classified as a known error.
*/
sealed class CastorError : KnownPrismError() {
sealed class CastorError @JvmOverloads constructor(message: String? = null, cause: Throwable? = null) : KnownPrismError(message, cause) {
class KeyCurveNotSupported(val curve: String) : CastorError() {
override val code: Int
get() = 21
Expand Down Expand Up @@ -234,7 +236,7 @@ sealed class CastorError : KnownPrismError() {
* This object may include an error code and an error message. If the error received conforms to the [KnownPrismError],
* it will be classified as a known error.
*/
sealed class MercuryError : KnownPrismError() {
sealed class MercuryError @JvmOverloads constructor(message: String? = null, cause: Throwable? = null) : KnownPrismError(message, cause) {

class NoDIDReceiverSetError : MercuryError() {
override val code: Int
Expand Down Expand Up @@ -307,7 +309,7 @@ sealed class MercuryError : KnownPrismError() {
* This object may include an error code and an error message. If the error received conforms to the [KnownPrismError],
* it will be classified as a known error.
*/
sealed class PlutoError : KnownPrismError() {
sealed class PlutoError @JvmOverloads constructor(message: String? = null, cause: Throwable? = null) : KnownPrismError(message, cause) {
class MissingDataPersistence(val type: String, private val affecting: String) :
PlutoError() {
override val code: Int
Expand Down Expand Up @@ -383,7 +385,7 @@ sealed class PlutoError : KnownPrismError() {
* This object may include an error code and an error message. If the error received conforms to the [KnownPrismError],
* it will be classified as a known error.
*/
sealed class PolluxError : KnownPrismError() {
sealed class PolluxError @JvmOverloads constructor(message: String? = null, cause: Throwable? = null) : KnownPrismError(message, cause) {
class InvalidPrismDID : PolluxError() {
override val code: Int
get() = 53
Expand All @@ -392,7 +394,7 @@ sealed class PolluxError : KnownPrismError() {
get() = "To create a JWT presentation a Prism DID is required"
}

class InvalidCredentialError : PolluxError() {
class InvalidCredentialError @JvmOverloads constructor(message: String? = null, cause: Throwable? = null) : PolluxError(message, cause) {
override val code: Int
get() = 51

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package io.iohk.atala.prism.walletsdk.domain.models

import io.iohk.atala.prism.walletsdk.domain.VC
import kotlinx.serialization.EncodeDefault
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.JsonArray
Expand All @@ -15,14 +16,17 @@ import kotlinx.serialization.json.jsonPrimitive
*
*Note: This data class conforms to the JSON Web Token (JWT) format. For more information, see https://jwt.io/introduction/.
*/
@OptIn(ExperimentalSerializationApi::class)
@Serializable
data class JWTPayload @JvmOverloads constructor(
data class JWTPayload
@JvmOverloads constructor(
val iss: String,
val sub: String?,
@SerialName(VC)
val verifiableCredential: JWTVerifiableCredential,
val nbf: Long?,
val exp: Long?,
@EncodeDefault
val exp: Long? = null,
@EncodeDefault
val jti: String? = null,
@EncodeDefault
Expand Down Expand Up @@ -75,6 +79,39 @@ data class JWTPayload @JvmOverloads constructor(
return result
}
}

override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false

other as JWTPayload

if (iss != other.iss) return false
if (sub != other.sub) return false
if (verifiableCredential != other.verifiableCredential) return false
if (nbf != other.nbf) return false
if (exp != other.exp) return false
if (jti != other.jti) return false
if (aud != null) {
if (other.aud == null) return false
if (!aud.contentEquals(other.aud)) return false
} else if (other.aud != null) return false
if (originalJWTString != other.originalJWTString) return false

return true
}

override fun hashCode(): Int {
var result = iss.hashCode()
result = 31 * result + (sub?.hashCode() ?: 0)
result = 31 * result + verifiableCredential.hashCode()
result = 31 * result + (nbf?.hashCode() ?: 0)
result = 31 * result + (exp?.hashCode() ?: 0)
result = 31 * result + (jti?.hashCode() ?: 0)
result = 31 * result + (aud?.contentHashCode() ?: 0)
result = 31 * result + (originalJWTString?.hashCode() ?: 0)
return result
}
}

inline fun <reified T> JsonObject.getCredentialField(name: String, isOptional: Boolean = false): T {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,9 @@ data class JWTCredential(val data: String) : Credential {
val credentialString = jwtParts[1]
val base64Data = Base64.getUrlDecoder().decode(credentialString)
val jsonString = base64Data.toString(Charsets.UTF_8)
val dataValue = jsonString.toByteArray(Charsets.UTF_8)

val json = Json { ignoreUnknownKeys = true }
this.jwtPayload = json.decodeFromString(dataValue.decodeToString())
this.jwtPayload = json.decodeFromString(jsonString)
}

override val id: String
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class PolluxImpl(val castor: Castor) : Pollux {
try {
Json.decodeFromString<W3CCredential>(data)
} catch (e: Exception) {
throw PolluxError.InvalidCredentialError()
throw PolluxError.InvalidCredentialError(cause = e.cause)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -532,7 +532,7 @@ class PrismAgent {
val jwtString = pollux.createRequestCredentialJWT(did, privateKey, offerJsonObject)
val attachmentDescriptor =
AttachmentDescriptor(
mediaType = "prism/jwt",
mediaType = JWT_MEDIA_TYPE,
data = AttachmentBase64(jwtString.base64UrlEncoded)
)
return RequestCredential(
Expand Down

0 comments on commit 9eb3927

Please sign in to comment.