Skip to content

Commit

Permalink
feat: allow prism did resolver to handle plain json
Browse files Browse the repository at this point in the history
Signed-off-by: Yurii Shynbuiev <[email protected]>
  • Loading branch information
yshyn-iohk committed Sep 26, 2024
1 parent de268fd commit 95787bc
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,22 +56,24 @@ class DidUrlResolver(httpUrlResolver: HttpUrlResolver, didResolver: DidResolver)
.mapError(_ => InvalidURI(baseUrl))
result <- httpUrlResolver.resolve(finalUrl)

envelope <- ZIO
.fromEither(result.fromJson[PrismEnvelopeData])
.mapError(_ => InvalidResponseFromResourceServer(finalUrl))

envelopeAsStr = envelope.toJson

validatedResult <- maybeResourceHash.fold(ZIO.succeed(envelopeAsStr)) { hash =>
val computedHash = Sha256Hash.compute(envelope.resource.getBytes()).hexEncoded
if (computedHash == hash) ZIO.succeed(envelopeAsStr)
else ZIO.fail(InvalidHash(hash, computedHash))
validatedResult <- result.fromJson[PrismEnvelopeData] match {
case Right(env) => validateResourceIntegrity(env, maybeResourceHash)
case Left(err) => ZIO.debug("Error parsing response as PrismEnvelope. Falling back to plain json") *> ZIO.succeed(result)
}

} yield validatedResult

}

private def validateResourceIntegrity(envelope: PrismEnvelopeData, maybeResourceHash: Option[String]): IO[DidUrlResolverError, String] = {
val envelopeAsStr = envelope.toJson
maybeResourceHash.fold(ZIO.succeed(envelopeAsStr)) { hash =>
val computedHash = Sha256Hash.compute(envelope.resource.getBytes()).hexEncoded
if (computedHash == hash) ZIO.succeed(envelopeAsStr)
else ZIO.fail(InvalidHash(hash, computedHash))
}
}

}

object DidUrlResolver {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import zio.*
import zio.json.*

import scala.util
import scala.util.Try

trait UriResolver {

Expand All @@ -20,24 +21,30 @@ class GenericUriResolver(resolvers: Map[String, UriResolver]) extends UriResolve
override def resolve(uri: String): IO[GenericUriResolverError, String] = {
val parsedUri = Uri.parseTry(uri)

ZIO.fromTry(parsedUri).mapError(_ => InvalidUri(uri)).flatMap {
case url: Url =>
url.schemeOption.fold(ZIO.fail(InvalidUri(uri)))(schema =>
resolvers.get(schema).fold(ZIO.fail(UnsupportedUriSchema(schema))) { resolver =>
resolver.resolve(uri).flatMap { res =>
schema match
case "did" =>
val envelope = res.fromJson[PrismEnvelopeData].left.map(_ => DidUriResponseNotEnvelope(url.toString))
ZIO.fromEither(
envelope.map(env => Base64Utils.decodeUrlToString(env.resource))
)
case _ => ZIO.succeed(res)
ZIO.debug(s"Resolving resource from uri: $uri") *>
ZIO.fromTry(parsedUri).mapError(_ => InvalidUri(uri)).flatMap {
case url: Url =>
url.schemeOption.fold(ZIO.fail(InvalidUri(uri)))(schema =>
resolvers.get(schema).fold(ZIO.fail(UnsupportedUriSchema(schema))) { resolver =>
resolver.resolve(uri).flatMap { res =>
schema match
case "did" =>
res.fromJson[PrismEnvelopeData] match
case Right(env) =>
ZIO
.fromTry(Try(Base64Utils.decodeUrlToString(env.resource)))
.mapError(_ => DidUriResponseNotEnvelope(uri))
case Left(err) =>
ZIO.debug(s"Failed to parse response as PrismEnvelope: $err") *>
ZIO.debug("Falling back to returning the response as is") *>
ZIO.succeed(res)
case _ => ZIO.succeed(res)
}
}
}
)
)

case Urn(path) => ZIO.fail(InvalidUri(uri)) // Must be a URL
}
case Urn(path) => ZIO.fail(InvalidUri(uri)) // Must be a URL
}

}

Expand Down

0 comments on commit 95787bc

Please sign in to comment.