• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

input-output-hk / atala-prism-building-blocks / 7972371817

20 Feb 2024 10:56AM UTC coverage: 31.112% (-0.2%) from 31.337%
7972371817

Pull #900

FabioPinheiro
build: make docker image only for the server
Pull Request #900: build: make docker image only for the server

4015 of 12905 relevant lines covered (31.11%)

0.31 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

53.97
/castor/lib/core/src/main/scala/io/iohk/atala/castor/core/model/did/PrismDID.scala
1
package io.iohk.atala.castor.core.model.did
2

3
import io.iohk.atala.castor.core.model.ProtoModelHelper
4
import io.iohk.atala.prism.crypto.{Sha256, Sha256Digest}
5
import io.iohk.atala.prism.protos.node_models
6
import io.iohk.atala.prism.protos.node_models.AtalaOperation.Operation
7
import io.iohk.atala.shared.models.Base64UrlString
8
import io.iohk.atala.shared.models.HexString
9
import scala.util.Try
10
import scala.util.matching.Regex
11

12
/** Represents a [Did] used in PRISM with prism-specific method and keys as [PrismDid]
13
  */
14
sealed trait PrismDID {
1✔
15
  override def toString: String = did.toString
16

1✔
17
  final def did: DID = DID(PrismDID.PRISM_METHOD, suffix)
18

1✔
19
  final def asCanonical: CanonicalPrismDID = CanonicalPrismDID(stateHash)
20

21
  def stateHash: HexString
22

23
  def suffix: DIDMethodSpecificId
24

25
}
26

27
object PrismDID extends ProtoModelHelper {
1✔
28
  val PRISM_METHOD: DIDMethod = DIDMethod.fromStringUnsafe("prism")
1✔
29
  val CANONICAL_SUFFIX_REGEX: Regex = "^([0-9a-f]{64}$)".r
1✔
30
  val LONG_FORM_SUFFIX_REGEX: Regex = "^([0-9a-f]{64}):([A-Za-z0-9_-]+$)".r
31

1✔
32
  def buildCanonical(stateHash: Array[Byte]): Either[String, CanonicalPrismDID] =
×
33
    Try(Sha256Digest.fromBytes(stateHash)).toEither.left
×
34
      .map(_.getMessage)
1✔
35
      .map(_ => CanonicalPrismDID(HexString.fromByteArray(stateHash)))
36

1✔
37
  def buildCanonicalFromSuffix(suffix: String): Either[String, CanonicalPrismDID] =
38
    HexString
×
39
      .fromString(suffix)
×
40
      .toEither
×
41
      .left
×
42
      .map(e => s"unable to parse suffix as hex string: ${e.getMessage}")
1✔
43
      .flatMap(suffix => buildCanonical(suffix.toByteArray))
44

1✔
45
  def buildLongFormFromOperation(createOperation: PrismDIDOperation.Create): LongFormPrismDID =
1✔
46
    buildLongFormFromAtalaOperation(
1✔
47
      createOperation.toAtalaOperation
1✔
48
    ).toOption.get // This cannot fail because we know the operation is a CreateDid
49

1✔
50
  def buildLongFormFromAtalaOperation(atalaOperation: node_models.AtalaOperation): Either[String, LongFormPrismDID] =
51
    atalaOperation.operation match {
1✔
52
      case _: Operation.CreateDid => Right(LongFormPrismDID(atalaOperation))
1✔
53
      case operation =>
1✔
54
        Left(s"Provided initial state of long form Prism DID is ${operation.value}, CreateDid Atala operation expected")
55
    }
56

1✔
57
  def fromString(s: String): Either[String, PrismDID] = {
58
    DID
×
59
      .fromString(s)
×
60
      .flatMap { did =>
×
61
        if (did.method == PRISM_METHOD) Right(did)
×
62
        else Left(s"Expected DID to have method $PRISM_METHOD, but got \"${did.method.toString}\" instead")
63
      }
1✔
64
      .flatMap { did =>
1✔
65
        val canonicalMatchGroups = CANONICAL_SUFFIX_REGEX.findAllMatchIn(did.methodSpecificId.toString).toList
1✔
66
        val longFormMatchGroups = LONG_FORM_SUFFIX_REGEX.findAllMatchIn(did.methodSpecificId.toString).toList
67

68
        (canonicalMatchGroups, longFormMatchGroups) match {
1✔
69
          case (Nil, longFormPattern :: Nil) =>
1✔
70
            for {
71
              stateHash <- HexString
×
72
                .fromString(longFormPattern.group(1))
×
73
                .toEither
×
74
                .left
×
75
                .map(_ => "Invalid long form Prism DID state hash")
1✔
76
              atalaOperation <- Base64UrlString
×
77
                .fromString(longFormPattern.group(2))
×
78
                .flatMap { encodedStateBase64 =>
×
79
                  Try(node_models.AtalaOperation.parseFrom(encodedStateBase64.toByteArray))
80
                }
×
81
                .toEither
×
82
                .left
×
83
                .map(_ => "Invalid long form Prism DID encoded state")
×
84
              longFormDID <- buildLongFormFromAtalaOperation(atalaOperation)
×
85
              _ <- Either.cond(
86
                stateHash == longFormDID.stateHash,
87
                (),
88
                "Canonical suffix does not match the computed state"
89
              )
90
            } yield longFormDID
1✔
91
          case (canonicalPattern :: Nil, Nil) =>
92
            HexString
×
93
              .fromString(canonicalPattern.group(1))
×
94
              .toEither
×
95
              .left
×
96
              .map(_ => "Invalid canonical form Prism DID")
1✔
97
              .map(stateHash => CanonicalPrismDID(stateHash))
×
98
          case _ => Left("Provided DID is not a valid PRISM DID")
99
        }
100
      }
101
  }
102
}
103

104
final case class CanonicalPrismDID private[did] (stateHash: HexString) extends PrismDID {
1✔
105
  override val suffix: DIDMethodSpecificId = DIDMethodSpecificId.fromStringUnsafe(stateHash.toString)
106
}
107

108
final case class LongFormPrismDID private[did] (atalaOperation: node_models.AtalaOperation) extends PrismDID {
109

110
  override val stateHash: HexString = {
1✔
111
    val encodedState = atalaOperation.toByteArray
1✔
112
    HexString.fromByteArray(Sha256.compute(encodedState).getValue)
113
  }
114

115
  override val suffix: DIDMethodSpecificId = {
1✔
116
    val encodedState = Base64UrlString.fromByteArray(atalaOperation.toByteArray).toStringNoPadding
1✔
117
    DIDMethodSpecificId.fromStringUnsafe(s"${stateHash.toString}:${encodedState}")
118
  }
119

1✔
120
  def createOperation: Either[String, PrismDIDOperation.Create] = {
121
    import ProtoModelHelper.*
122
    atalaOperation.operation match {
1✔
123
      case Operation.CreateDid(op) => op.toDomain
×
124
      case operation =>
×
125
        Left(s"Provided initial state of long form Prism DID is ${operation.value}, CreateDid Atala operation expected")
126
    }
127
  }
128

129
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc