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

hyperledger / identus-cloud-agent / 10833924030

12 Sep 2024 03:25PM CUT coverage: 48.864% (+0.07%) from 48.793%
10833924030

Pull #1351

CryptoKnightIOG
ATL-7660: Credential Schema as List

Signed-off-by: Bassam Riman <bassam.riman@iohk.io>
Pull Request #1351: feat: Support Array Of Credential Schema

15 of 28 new or added lines in 3 files covered. (53.57%)

222 existing lines in 68 files now uncovered.

7530 of 15410 relevant lines covered (48.86%)

0.49 hits per line

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

72.0
/pollux/core/src/main/scala/org/hyperledger/identus/pollux/core/service/CredentialService.scala
1
package org.hyperledger.identus.pollux.core.service
2

3
import io.circe.{Json, JsonObject}
4
import io.circe.syntax.*
5
import org.hyperledger.identus.castor.core.model.did.{CanonicalPrismDID, PrismDID, VerificationRelationship}
6
import org.hyperledger.identus.mercury.model.DidId
7
import org.hyperledger.identus.mercury.protocol.issuecredential.{
8
  Attribute,
9
  IssueCredential,
10
  OfferCredential,
11
  RequestCredential
12
}
13
import org.hyperledger.identus.pollux.core.model.*
14
import org.hyperledger.identus.pollux.core.model.error.CredentialServiceError
15
import org.hyperledger.identus.pollux.core.model.error.CredentialServiceError.*
16
import org.hyperledger.identus.pollux.vc.jwt.Issuer
17
import org.hyperledger.identus.shared.models.*
18
import zio.{Duration, IO, UIO, URIO, ZIO}
19

20
import java.nio.charset.StandardCharsets
21
import java.util.UUID
22

23
trait CredentialService {
24

25
  def createJWTIssueCredentialRecord(
26
      pairwiseIssuerDID: DidId,
27
      pairwiseHolderDID: Option[DidId],
28
      thid: DidCommID,
29
      maybeSchemaId: Option[String],
30
      claims: io.circe.Json,
31
      validityPeriod: Option[Double] = None,
×
32
      automaticIssuance: Option[Boolean],
33
      issuingDID: CanonicalPrismDID,
34
      goalCode: Option[String],
35
      goal: Option[String],
36
      expirationDuration: Option[Duration],
37
      connectionId: Option[UUID],
38
  ): URIO[WalletAccessContext, IssueCredentialRecord]
39

40
  def createSDJWTIssueCredentialRecord(
41
      pairwiseIssuerDID: DidId,
42
      pairwiseHolderDID: Option[DidId],
43
      thid: DidCommID,
44
      maybeSchemaId: Option[String],
45
      claims: io.circe.Json,
46
      validityPeriod: Option[Double] = None,
×
47
      automaticIssuance: Option[Boolean],
48
      issuingDID: CanonicalPrismDID,
49
      goalCode: Option[String],
50
      goal: Option[String],
51
      expirationDuration: Option[Duration],
52
      connectionId: Option[UUID],
53
  ): URIO[WalletAccessContext, IssueCredentialRecord]
54

55
  def createAnonCredsIssueCredentialRecord(
56
      pairwiseIssuerDID: DidId,
57
      pairwiseHolderDID: Option[DidId],
58
      thid: DidCommID,
59
      credentialDefinitionGUID: UUID,
60
      credentialDefinitionId: String,
61
      claims: io.circe.Json,
62
      validityPeriod: Option[Double] = None,
×
63
      automaticIssuance: Option[Boolean],
64
      goalCode: Option[String],
65
      goal: Option[String],
66
      expirationDuration: Option[Duration],
67
      connectionId: Option[UUID],
68
  ): URIO[WalletAccessContext, IssueCredentialRecord]
69

70
  /** Return a list of records as well as a count of all filtered items */
71
  def getIssueCredentialRecords(
72
      ignoreWithZeroRetries: Boolean,
73
      offset: Option[Int] = None,
1✔
74
      limit: Option[Int] = None
1✔
75
  ): URIO[WalletAccessContext, (Seq[IssueCredentialRecord], Int)]
76

77
  def getIssueCredentialRecordsByStates(
78
      ignoreWithZeroRetries: Boolean,
79
      limit: Int,
80
      states: IssueCredentialRecord.ProtocolState*
81
  ): URIO[WalletAccessContext, Seq[IssueCredentialRecord]]
82

83
  def getIssueCredentialRecordsByStatesForAllWallets(
84
      ignoreWithZeroRetries: Boolean,
85
      limit: Int,
86
      states: IssueCredentialRecord.ProtocolState*
87
  ): UIO[Seq[IssueCredentialRecord]]
88

89
  def findById(
90
      recordId: DidCommID
91
  ): URIO[WalletAccessContext, Option[IssueCredentialRecord]]
92

93
  def getById(
94
      recordId: DidCommID
95
  ): ZIO[WalletAccessContext, RecordNotFound, IssueCredentialRecord]
96

97
  def getIssueCredentialRecordByThreadId(
98
      thid: DidCommID,
99
      ignoreWithZeroRetries: Boolean
100
  ): URIO[WalletAccessContext, Option[IssueCredentialRecord]]
101

102
  def receiveCredentialOffer(
103
      offer: OfferCredential
104
  ): ZIO[WalletAccessContext, InvalidCredentialOffer, IssueCredentialRecord]
105

106
  def acceptCredentialOffer(
107
      recordId: DidCommID,
108
      subjectId: Option[String],
109
      keyId: Option[KeyId]
110
  ): ZIO[WalletAccessContext, RecordNotFound | UnsupportedDidFormat, IssueCredentialRecord]
111

112
  def generateJWTCredentialRequest(
113
      recordId: DidCommID
114
  ): ZIO[WalletAccessContext, RecordNotFound | UnsupportedDidFormat, IssueCredentialRecord]
115

116
  def generateSDJWTCredentialRequest(
117
      recordId: DidCommID
118
  ): ZIO[WalletAccessContext, RecordNotFound | UnsupportedDidFormat, IssueCredentialRecord]
119

120
  def generateAnonCredsCredentialRequest(
121
      recordId: DidCommID
122
  ): ZIO[WalletAccessContext, RecordNotFound, IssueCredentialRecord]
123

124
  def receiveCredentialRequest(
125
      request: RequestCredential
126
  ): ZIO[WalletAccessContext, InvalidCredentialRequest | RecordNotFoundForThreadIdAndStates, IssueCredentialRecord]
127

128
  def acceptCredentialRequest(
129
      recordId: DidCommID
130
  ): ZIO[WalletAccessContext, RecordNotFound, IssueCredentialRecord]
131

132
  def generateJWTCredential(
133
      recordId: DidCommID,
134
      statusListRegistryUrl: String,
135
  ): ZIO[WalletAccessContext, RecordNotFound | CredentialRequestValidationFailed, IssueCredentialRecord]
136

137
  def generateSDJWTCredential(
138
      recordId: DidCommID,
139
      expirationTime: Duration,
140
  ): ZIO[WalletAccessContext, RecordNotFound | ExpirationDateHasPassed | VCJwtHeaderParsingError, IssueCredentialRecord]
141

142
  def generateAnonCredsCredential(
143
      recordId: DidCommID
144
  ): ZIO[WalletAccessContext, RecordNotFound, IssueCredentialRecord]
145

146
  def receiveCredentialIssue(
147
      issueCredential: IssueCredential
148
  ): ZIO[WalletAccessContext, InvalidCredentialIssue | RecordNotFoundForThreadIdAndStates, IssueCredentialRecord]
149

150
  def markOfferSent(
151
      recordId: DidCommID
152
  ): ZIO[WalletAccessContext, InvalidStateForOperation, IssueCredentialRecord]
153

154
  def markRequestSent(
155
      recordId: DidCommID
156
  ): ZIO[WalletAccessContext, InvalidStateForOperation, IssueCredentialRecord]
157

158
  def markCredentialSent(
159
      recordId: DidCommID
160
  ): ZIO[WalletAccessContext, CredentialServiceError, IssueCredentialRecord]
161

162
  def markCredentialOfferInvitationExpired(
163
      recordId: DidCommID
164
  ): ZIO[WalletAccessContext, CredentialServiceError, IssueCredentialRecord]
165

166
  def reportProcessingFailure(
167
      recordId: DidCommID,
168
      failReason: Option[Failure]
169
  ): URIO[WalletAccessContext, Unit]
170

171
  def getJwtIssuer(
172
      jwtIssuerDID: PrismDID,
173
      verificationRelationship: VerificationRelationship,
174
      keyId: Option[KeyId]
175
  ): URIO[WalletAccessContext, Issuer]
176

177
  def getCredentialOfferInvitation(
178
      pairwiseHolderDID: DidId,
179
      invitation: String
180
  ): ZIO[WalletAccessContext, CredentialServiceError, OfferCredential]
181
}
182

183
object CredentialService {
184
  def convertJsonClaimsToAttributes(
1✔
185
      claims: io.circe.Json
186
  ): UIO[Seq[Attribute]] = {
187
    for {
1✔
UNCOV
188
      fields <- ZIO.succeed(claims.asObject.map(_.toMap).getOrElse(Map.empty).toList)
×
189
      res <- ZIO.foreach(fields) {
1✔
190
        case (k, v) if v.isString =>
1✔
191
          ZIO.succeed(Attribute(name = k, value = v.asString.get))
1✔
192
        case (k, v) =>
1✔
193
          ZIO.succeed {
194
            val jsonValue = v.noSpaces
1✔
195
            Attribute(
196
              name = k,
197
              value = java.util.Base64.getUrlEncoder.encodeToString(jsonValue.getBytes(StandardCharsets.UTF_8)),
1✔
198
              media_type = Some("application/json"),
199
            )
200
          }
201
      }
202
    } yield res
203
  }
204

205
  def convertAttributesToJsonClaims(
1✔
206
      attributes: Seq[Attribute]
207
  ): IO[CredentialServiceError, JsonObject] = {
208
    for {
1✔
209
      claims <- ZIO.foldLeft(attributes)(JsonObject()) { case (jsonObject, attr) =>
1✔
210
        attr.media_type match
211
          case None =>
1✔
212
            ZIO.succeed(jsonObject.add(attr.name, attr.value.asJson))
1✔
213

214
          case Some("application/json") =>
215
            val jsonBytes = java.util.Base64.getUrlDecoder.decode(attr.value.getBytes(StandardCharsets.UTF_8))
1✔
216
            io.circe.parser.parse(new String(jsonBytes, StandardCharsets.UTF_8)) match
1✔
217
              case Right(value) => ZIO.succeed(jsonObject.add(attr.name, value))
1✔
218
              case Left(error)  => ZIO.fail(VCClaimsValueParsingError(error.message))
×
219

220
          case Some(media_type) =>
×
221
            ZIO.fail(UnsupportedVCClaimsMediaType(media_type))
×
222
      }
223
    } yield claims
224
  }
225
}
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