From 95787bcb8071308df940652e54d6ee1ea88ff394 Mon Sep 17 00:00:00 2001 From: Yurii Shynbuiev Date: Thu, 26 Sep 2024 22:02:23 +0700 Subject: [PATCH] feat: allow prism did resolver to handle plain json Signed-off-by: Yurii Shynbuiev --- .../service/uriResolvers/DidUrlResolver.scala | 22 ++++++----- .../shared/http/GenericUriResolver.scala | 39 +++++++++++-------- 2 files changed, 35 insertions(+), 26 deletions(-) diff --git a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/uriResolvers/DidUrlResolver.scala b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/uriResolvers/DidUrlResolver.scala index 29b4024d3d..8d77c04c74 100644 --- a/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/uriResolvers/DidUrlResolver.scala +++ b/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/uriResolvers/DidUrlResolver.scala @@ -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 { diff --git a/shared/core/src/main/scala/org/hyperledger/identus/shared/http/GenericUriResolver.scala b/shared/core/src/main/scala/org/hyperledger/identus/shared/http/GenericUriResolver.scala index f25f6b37f3..25be250c52 100644 --- a/shared/core/src/main/scala/org/hyperledger/identus/shared/http/GenericUriResolver.scala +++ b/shared/core/src/main/scala/org/hyperledger/identus/shared/http/GenericUriResolver.scala @@ -8,6 +8,7 @@ import zio.* import zio.json.* import scala.util +import scala.util.Try trait UriResolver { @@ -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 + } }