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

hyperledger / identus-cloud-agent / 9002206942

08 May 2024 12:55PM UTC coverage: 47.829% (-1.6%) from 49.381%
9002206942

Pull #909

patlo-iog
Merge branch 'main' into oidc
Pull Request #909: feat(agent): define the OAS for CredentialIssuerEndpoints [WIP]

49 of 598 new or added lines in 31 files covered. (8.19%)

299 existing lines in 65 files now uncovered.

7348 of 15363 relevant lines covered (47.83%)

0.48 hits per line

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

0.0
/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/controller/http/ManagedDID.scala
1
package org.hyperledger.identus.castor.controller.http
2

3
import org.hyperledger.identus.agent.walletapi.model as walletDomain
4
import org.hyperledger.identus.agent.walletapi.model.DIDPublicKeyTemplate
5
import org.hyperledger.identus.agent.walletapi.model.ManagedDIDDetail
6
import org.hyperledger.identus.agent.walletapi.model.PublicationState
7
import org.hyperledger.identus.api.http.Annotation
8
import org.hyperledger.identus.castor.core.model.did as castorDomain
9
import org.hyperledger.identus.castor.core.model.did.EllipticCurve
UNCOV
10
import org.hyperledger.identus.castor.core.model.did.PrismDID
×
11
import org.hyperledger.identus.castor.core.model.did.VerificationRelationship
UNCOV
12
import org.hyperledger.identus.shared.utils.Traverse.*
×
UNCOV
13
import sttp.tapir.Schema
×
UNCOV
14
import sttp.tapir.Schema.annotations.{description, encodedExample}
×
UNCOV
15
import zio.json.{DeriveJsonDecoder, DeriveJsonEncoder, JsonEncoder, JsonDecoder}
×
UNCOV
16

×
UNCOV
17
import scala.language.implicitConversions
×
UNCOV
18

×
UNCOV
19
final case class ManagedDID(
×
20
    @description(ManagedDID.annotations.did.description)
×
21
    @encodedExample(ManagedDID.annotations.did.example)
×
22
    did: String,
23
    @description(ManagedDID.annotations.longFormDid.description)
×
24
    @encodedExample(ManagedDID.annotations.longFormDid.example)
×
25
    longFormDid: Option[String] = None,
×
26
    @description(ManagedDID.annotations.status.description)
×
27
    @encodedExample(ManagedDID.annotations.status.example)
×
28
    status: String // TODO: use enum
29
)
30

31
object ManagedDID {
32
  object annotations {
UNCOV
33
    object did
×
34
        extends Annotation[String](
×
UNCOV
35
          description = "A managed DID",
×
36
          example = "did:prism:4a5b5cf0a513e83b598bbea25cd6196746747f361a73ef77068268bc9bd732ff"
UNCOV
37
        )
×
38

39
    object longFormDid
40
        extends Annotation[String](
×
41
          description =
42
            "A long-form DID. Mandatory when status is not `PUBLISHED` and optional when status is `PUBLISHED`",
UNCOV
43
          example =
×
UNCOV
44
            "did:prism:4a5b5cf0a513e83b598bbea25cd6196746747f361a73ef77068268bc9bd732ff:Cr4BCrsBElsKBmF1dGgtMRAEQk8KCXNlY3AyNTZrMRIg0opTuxu-zt6aRbT1tPniG4eu4CYsQPM3rrLzvzNiNgwaIIFTnyT2N4U7qCQ78qtWC3-p0el6Hvv8qxG5uuEw-WgMElwKB21hc3RlcjAQAUJPCglzZWNwMjU2azESIKhBU0eCOO6Vinz_8vhtFSAhYYqrkEXC8PHGxkuIUev8GiAydFHLXb7c22A1Uj_PR21NZp6BCDQqNq2xd244txRgsQ"
×
45
        )
UNCOV
46

×
UNCOV
47
    object status
×
48
        extends Annotation[String](
×
UNCOV
49
          description =
×
50
            """A status indicating a publication state of a DID in the wallet (e.g. `PUBLICATION_PENDING`, `PUBLISHED`).
×
51
              |Does not represent DID a lifecyle (e.g. `deactivated`, `recovered`, `updated`).""".stripMargin,
×
UNCOV
52
          example = "CREATED"
×
UNCOV
53
        )
×
UNCOV
54
  }
×
UNCOV
55

×
56
  given encoder: JsonEncoder[ManagedDID] = DeriveJsonEncoder.gen[ManagedDID]
×
57
  given decoder: JsonDecoder[ManagedDID] = DeriveJsonDecoder.gen[ManagedDID]
×
58
  given schema: Schema[ManagedDID] = Schema.derived
×
UNCOV
59

×
UNCOV
60
  given Conversion[ManagedDIDDetail, ManagedDID] = { didDetail =>
×
UNCOV
61
    val operation = didDetail.state.createOperation
×
62
    val (longFormDID, status) = didDetail.state.publicationState match {
×
63
      case PublicationState.Created() => Some(PrismDID.buildLongFormFromOperation(operation)) -> "CREATED"
×
64
      case PublicationState.PublicationPending(_) =>
×
65
        Some(PrismDID.buildLongFormFromOperation(operation)) -> "PUBLICATION_PENDING"
×
66
      case PublicationState.Published(_) => None -> "PUBLISHED"
×
67
    }
68
    ManagedDID(
69
      did = didDetail.did.toString,
×
70
      longFormDid = longFormDID.map(_.toString),
×
71
      status = status
72
    )
UNCOV
73
  }
×
UNCOV
74
}
×
75

76
final case class ManagedDIDPage(
77
    self: String,
78
    kind: String = "ManagedDIDPage",
×
79
    pageOf: String,
80
    next: Option[String] = None,
×
81
    previous: Option[String] = None,
×
82
    contents: Seq[ManagedDID]
83
)
84

85
object ManagedDIDPage {
86
  given encoder: JsonEncoder[ManagedDIDPage] = DeriveJsonEncoder.gen[ManagedDIDPage]
×
87
  given decoder: JsonDecoder[ManagedDIDPage] = DeriveJsonDecoder.gen[ManagedDIDPage]
×
88
  given schema: Schema[ManagedDIDPage] = Schema.derived
×
89
}
UNCOV
90

×
91
final case class CreateManagedDidRequest(
UNCOV
92
    documentTemplate: CreateManagedDidRequestDocumentTemplate
×
93
)
94

95
object CreateManagedDidRequest {
96
  given encoder: JsonEncoder[CreateManagedDidRequest] = DeriveJsonEncoder.gen[CreateManagedDidRequest]
×
97
  given decoder: JsonDecoder[CreateManagedDidRequest] = DeriveJsonDecoder.gen[CreateManagedDidRequest]
×
98
  given schema: Schema[CreateManagedDidRequest] = Schema.derived
×
99
}
100

101
final case class CreateManagedDidRequestDocumentTemplate(
102
    publicKeys: Seq[ManagedDIDKeyTemplate],
UNCOV
103
    services: Seq[Service],
×
104
    contexts: Option[Seq[Context]]
105
)
106

107
object CreateManagedDidRequestDocumentTemplate {
108
  given encoder: JsonEncoder[CreateManagedDidRequestDocumentTemplate] =
109
    DeriveJsonEncoder.gen[CreateManagedDidRequestDocumentTemplate]
×
UNCOV
110
  given decoder: JsonDecoder[CreateManagedDidRequestDocumentTemplate] =
×
111
    DeriveJsonDecoder.gen[CreateManagedDidRequestDocumentTemplate]
×
112
  given schema: Schema[CreateManagedDidRequestDocumentTemplate] = Schema.derived
×
113

114
  extension (template: CreateManagedDidRequestDocumentTemplate) {
115
    def toDomain: Either[String, walletDomain.ManagedDIDTemplate] = {
×
116
      for {
×
117
        services <- template.services.traverse(_.toDomain)
×
118
        publicKeys = template.publicKeys.map[DIDPublicKeyTemplate](k => k)
×
119
      } yield walletDomain.ManagedDIDTemplate(
×
120
        publicKeys = publicKeys,
121
        services = services,
122
        contexts = template.contexts.getOrElse(Nil).map(_.value)
×
123
      )
124
    }
125
  }
126
}
127

UNCOV
128
class Context(val value: String) extends AnyVal
×
129

130
object Context {
131
  given Conversion[Context, String] = _.value
132
  given Conversion[String, Context] = Context(_)
×
133

134
  given encoder: JsonEncoder[Context] = JsonEncoder[String].contramap(_.value)
×
135
  given decoder: JsonDecoder[Context] = JsonDecoder[String].map(Context(_))
×
136
  given schema: Schema[Context] = Schema
137
    .string[Context]
×
138
    .description("The JSON-LD context describing the JSON document")
×
139
    .encodedExample("https://didcomm.org/messaging/contexts/v2")
×
140
}
UNCOV
141

×
UNCOV
142
enum Purpose {
×
143
  case authentication extends Purpose
UNCOV
144
  case assertionMethod extends Purpose
×
145
  case keyAgreement extends Purpose
UNCOV
146
  case capabilityInvocation extends Purpose
×
147
  case capabilityDelegation extends Purpose
148
}
149

150
object Purpose {
151
  given Conversion[Purpose, VerificationRelationship] = {
152
    case Purpose.authentication       => VerificationRelationship.Authentication
×
153
    case Purpose.assertionMethod      => VerificationRelationship.AssertionMethod
×
154
    case Purpose.keyAgreement         => VerificationRelationship.KeyAgreement
×
155
    case Purpose.capabilityInvocation => VerificationRelationship.CapabilityInvocation
×
156
    case Purpose.capabilityDelegation => VerificationRelationship.CapabilityDelegation
×
157
  }
158

159
  given Conversion[VerificationRelationship, Purpose] = {
160
    case VerificationRelationship.Authentication       => Purpose.authentication
×
161
    case VerificationRelationship.AssertionMethod      => Purpose.assertionMethod
×
162
    case VerificationRelationship.KeyAgreement         => Purpose.keyAgreement
×
163
    case VerificationRelationship.CapabilityInvocation => Purpose.capabilityInvocation
×
164
    case VerificationRelationship.CapabilityDelegation => Purpose.capabilityDelegation
×
UNCOV
165
  }
×
166

167
  given encoder: JsonEncoder[Purpose] = JsonEncoder[String].contramap(_.toString)
×
168
  given decoder: JsonDecoder[Purpose] =
169
    JsonDecoder[String].mapOrFail(s => Purpose.values.find(_.toString == s).toRight(s"Unknown purpose: $s"))
×
170
  given schema: Schema[Purpose] = Schema.derivedEnumeration.defaultStringBased
×
171
}
172

173
enum Curve {
174
  case secp256k1 extends Curve
175
  case Ed25519 extends Curve
176
  case X25519 extends Curve
177
}
178

179
object Curve {
180
  given Conversion[Curve, EllipticCurve] = {
181
    case Curve.secp256k1 => EllipticCurve.SECP256K1
×
182
    case Curve.Ed25519   => EllipticCurve.ED25519
×
183
    case Curve.X25519    => EllipticCurve.X25519
×
184
  }
185

186
  given Conversion[EllipticCurve, Curve] = {
187
    case EllipticCurve.SECP256K1 => Curve.secp256k1
×
188
    case EllipticCurve.ED25519   => Curve.Ed25519
×
189
    case EllipticCurve.X25519    => Curve.X25519
×
190
  }
191

192
  given encoder: JsonEncoder[Curve] = JsonEncoder[String].contramap(_.toString)
×
193
  given decoder: JsonDecoder[Curve] =
194
    JsonDecoder[String].mapOrFail(s => Curve.values.find(_.toString == s).toRight(s"Unknown curve: $s"))
×
195
  given schema: Schema[Curve] = Schema.derivedEnumeration.defaultStringBased
×
196
}
197

198
@description("A key-pair template to add to DID document.")
×
199
final case class ManagedDIDKeyTemplate(
200
    @description(ManagedDIDKeyTemplate.annotations.id.description)
×
201
    @encodedExample(ManagedDIDKeyTemplate.annotations.id.example)
×
202
    id: String,
203
    @description(ManagedDIDKeyTemplate.annotations.purpose.description)
×
204
    @encodedExample(ManagedDIDKeyTemplate.annotations.purpose.example)
×
205
    purpose: Purpose,
206
    // @description(ManagedDIDKeyTemplate.annotations.curve.description)
207
    // @encodedExample(ManagedDIDKeyTemplate.annotations.curve.example)
208
    // curve: Option[Curve]
209
) {
210
  // TODO: this curve option is hidden for now, to be added back after integration test with node
211
  def curve: Option[Curve] = None
×
212
}
213

214
object ManagedDIDKeyTemplate {
215
  object annotations {
216
    object id
217
        extends Annotation[String](
218
          description = "Identifier of a verification material in the DID Document",
219
          example = "key-1"
220
        )
221

222
    object purpose
223
        extends Annotation[Purpose](
×
224
          description = "Purpose of the verification material in the DID Document",
225
          example = VerificationRelationship.Authentication
×
226
        )
227

228
    object curve
229
        extends Annotation[Option[Curve]](
×
230
          description =
231
            "The curve name of the verification material in the DID Document. Defaults to `secp256k1` if not specified.",
232
          example = Some(Curve.Ed25519)
233
        )
234
  }
235

236
  given encoder: JsonEncoder[ManagedDIDKeyTemplate] = DeriveJsonEncoder.gen[ManagedDIDKeyTemplate]
×
237
  given decoder: JsonDecoder[ManagedDIDKeyTemplate] = DeriveJsonDecoder.gen[ManagedDIDKeyTemplate]
×
238
  given schema: Schema[ManagedDIDKeyTemplate] = Schema.derived
×
239

240
  given Conversion[ManagedDIDKeyTemplate, walletDomain.DIDPublicKeyTemplate] = publicKeyTemplate =>
241
    walletDomain.DIDPublicKeyTemplate(
242
      id = publicKeyTemplate.id,
243
      purpose = publicKeyTemplate.purpose,
×
244
      curve = publicKeyTemplate.curve.getOrElse(Curve.secp256k1)
×
245
    )
246
}
247

248
final case class CreateManagedDIDResponse(
249
    @description(CreateManagedDIDResponse.annotations.longFormDid.description)
×
250
    @encodedExample(CreateManagedDIDResponse.annotations.longFormDid.example)
×
251
    longFormDid: String
252
)
253

254
object CreateManagedDIDResponse {
255
  object annotations {
256
    object longFormDid
257
        extends Annotation[String](
×
258
          description = "A long-form DID for the created DID",
259
          example =
260
            "did:prism:4a5b5cf0a513e83b598bbea25cd6196746747f361a73ef77068268bc9bd732ff:Cr4BCrsBElsKBmF1dGgtMRAEQk8KCXNlY3AyNTZrMRIg0opTuxu-zt6aRbT1tPniG4eu4CYsQPM3rrLzvzNiNgwaIIFTnyT2N4U7qCQ78qtWC3-p0el6Hvv8qxG5uuEw-WgMElwKB21hc3RlcjAQAUJPCglzZWNwMjU2azESIKhBU0eCOO6Vinz_8vhtFSAhYYqrkEXC8PHGxkuIUev8GiAydFHLXb7c22A1Uj_PR21NZp6BCDQqNq2xd244txRgsQ"
261
        )
262
  }
263

264
  given encoder: JsonEncoder[CreateManagedDIDResponse] = DeriveJsonEncoder.gen[CreateManagedDIDResponse]
×
265
  given decoder: JsonDecoder[CreateManagedDIDResponse] = DeriveJsonDecoder.gen[CreateManagedDIDResponse]
×
266
  given schema: Schema[CreateManagedDIDResponse] = Schema.derived
×
267
}
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