Skip to content

Commit

Permalink
Merge branch 'main' into feat/atl-7271-add-schemaId-to-oidc-session
Browse files Browse the repository at this point in the history
  • Loading branch information
yshyn-iohk committed Jun 21, 2024
2 parents 618b6cc + 1712062 commit 2356bfb
Show file tree
Hide file tree
Showing 46 changed files with 1,436 additions and 1,321 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import org.hyperledger.identus.iam.authentication.apikey.ApiKeyAuthenticator
import org.hyperledger.identus.iam.entity.http.EntityServerEndpoints
import org.hyperledger.identus.iam.wallet.http.WalletManagementServerEndpoints
import org.hyperledger.identus.issue.controller.IssueServerEndpoints
import org.hyperledger.identus.mercury.{DidOps, HttpClient}
import org.hyperledger.identus.mercury.{DidAgent, DidOps, HttpClient}
import org.hyperledger.identus.oid4vci.CredentialIssuerServerEndpoints
import org.hyperledger.identus.pollux.core.service.{CredentialService, PresentationService}
import org.hyperledger.identus.pollux.credentialdefinition.CredentialDefinitionRegistryServerEndpoints
Expand Down Expand Up @@ -68,7 +68,7 @@ object CloudAgentApp {

private val presentProofExchangeJob: RIO[
AppConfig & DidOps & DIDResolver & JwtDidResolver & HttpClient & PresentationService & CredentialService &
DIDNonSecretStorage & DIDService & ManagedDIDService & WalletManagementService,
DIDNonSecretStorage & DIDService & ManagedDIDService,
Unit
] =
for {
Expand Down Expand Up @@ -213,8 +213,8 @@ object AgentInitialization {
_ <- walletService
.createWallet(defaultWallet, seed)
.orDieAsUnmanagedFailure
_ <- entityService.create(defaultEntity).mapError(e => Exception(e.message))
_ <- apiKeyAuth.add(defaultEntity.id, config.authApiKey).mapError(e => Exception(e.message))
_ <- entityService.create(defaultEntity).orDieAsUnmanagedFailure
_ <- apiKeyAuth.add(defaultEntity.id, config.authApiKey)
_ <- config.webhookUrl.fold(ZIO.unit) { url =>
val customHeaders = config.webhookApiKey.fold(Map.empty)(apiKey => Map("Authorization" -> s"Bearer $apiKey"))
walletService
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ sealed trait BackgroundJobError

object BackgroundJobError {
final case class InvalidState(cause: String) extends BackgroundJobError

final case class ErrorSendingMessage(cause: String) extends BackgroundJobError
case object NotImplemented extends BackgroundJobError
final case class ErrorResponseReceivedFromPeerAgent(response: HttpResponse) extends BackgroundJobError {
override def toString: String = s"DIDComm sending error: [${response.status}] - ${response.bodyAsString}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package org.hyperledger.identus.agent.server.jobs

import org.hyperledger.identus.agent.walletapi.model.{ManagedDIDState, PublicationState}
import org.hyperledger.identus.agent.walletapi.model.error.DIDSecretStorageError.{KeyNotFoundError, WalletNotFoundError}
import org.hyperledger.identus.agent.walletapi.model.error.GetManagedDIDError
import org.hyperledger.identus.agent.walletapi.service.ManagedDIDService
import org.hyperledger.identus.agent.walletapi.storage.DIDNonSecretStorage
import org.hyperledger.identus.castor.core.model.did.{
Expand All @@ -10,22 +11,22 @@ import org.hyperledger.identus.castor.core.model.did.{
PrismDID,
VerificationRelationship
}
import org.hyperledger.identus.castor.core.model.error.DIDResolutionError
import org.hyperledger.identus.castor.core.service.DIDService
import org.hyperledger.identus.mercury.{AgentPeerService, DidAgent}
import org.hyperledger.identus.mercury.model.DidId
import org.hyperledger.identus.pollux.core.model.error.PresentationError
import org.hyperledger.identus.pollux.sdjwt.SDJWT.*
import org.hyperledger.identus.pollux.vc.jwt.{DIDResolutionFailed, DIDResolutionSucceeded, ES256KSigner, *}
import org.hyperledger.identus.pollux.vc.jwt.{DidResolver as JwtDidResolver, Issuer as JwtIssuer}
import org.hyperledger.identus.shared.crypto.{
Ed25519KeyPair,
Ed25519PublicKey,
KmpEd25519KeyOps,
Secp256k1KeyPair,
X25519KeyPair
import org.hyperledger.identus.pollux.vc.jwt.{
DIDResolutionFailed,
DIDResolutionSucceeded,
DidResolver as JwtDidResolver,
ES256KSigner,
Issuer as JwtIssuer,
*
}
import org.hyperledger.identus.shared.models.KeyId
import org.hyperledger.identus.shared.models.WalletAccessContext
import org.hyperledger.identus.shared.crypto.*
import org.hyperledger.identus.shared.models.{KeyId, WalletAccessContext}
import zio.{ZIO, ZLayer}

import java.util.Base64
Expand All @@ -35,16 +36,20 @@ trait BackgroundJobsHelper {
def getLongForm(
did: PrismDID,
allowUnpublishedIssuingDID: Boolean = false
): ZIO[ManagedDIDService & WalletAccessContext, RuntimeException, LongFormPrismDID] = {
): ZIO[ManagedDIDService & WalletAccessContext, BackgroundJobError | GetManagedDIDError, LongFormPrismDID] = {
for {
managedDIDService <- ZIO.service[ManagedDIDService]
didState <- managedDIDService
.getManagedDIDState(did.asCanonical)
.mapError(e => RuntimeException(s"Error occurred while getting did from wallet: ${e.toString}"))
.someOrFail(RuntimeException(s"Issuer DID does not exist in the wallet: $did"))
.someOrFail(BackgroundJobError.InvalidState(s"Issuer DID does not exist in the wallet: $did"))
.flatMap {
case s @ ManagedDIDState(_, _, PublicationState.Published(_)) => ZIO.succeed(s)
case s => ZIO.cond(allowUnpublishedIssuingDID, s, RuntimeException(s"Issuer DID must be published: $did"))
case s =>
ZIO.cond(
allowUnpublishedIssuingDID,
s,
BackgroundJobError.InvalidState(s"Issuer DID must be published: $did")
)
}
longFormPrismDID = PrismDID.buildLongFormFromOperation(didState.createOperation)
} yield longFormPrismDID
Expand All @@ -53,39 +58,45 @@ trait BackgroundJobsHelper {
def createJwtIssuer(
jwtIssuerDID: PrismDID,
verificationRelationship: VerificationRelationship
): ZIO[DIDService & ManagedDIDService & WalletAccessContext, RuntimeException, JwtIssuer] = {
): ZIO[
DIDService & ManagedDIDService & WalletAccessContext,
BackgroundJobError | GetManagedDIDError | DIDResolutionError,
JwtIssuer
] = {
for {
managedDIDService <- ZIO.service[ManagedDIDService]
didService <- ZIO.service[DIDService]
// Automatically infer keyId to use by resolving DID and choose the corresponding VerificationRelationship
issuingKeyId <- didService
.resolveDID(jwtIssuerDID)
.mapError(e => RuntimeException(s"Error occured while resolving Issuing DID during VC creation: ${e.toString}"))
.someOrFail(RuntimeException(s"Issuing DID resolution result is not found"))
.someOrFail(BackgroundJobError.InvalidState(s"Issuing DID resolution result is not found"))
.map { case (_, didData) =>
didData.publicKeys
.find(pk => pk.purpose == verificationRelationship && pk.publicKeyData.crv == EllipticCurve.SECP256K1)
.map(_.id)
}
.someOrFail(
RuntimeException(s"Issuing DID doesn't have a key in ${verificationRelationship.name} to use: $jwtIssuerDID")
BackgroundJobError.InvalidState(
s"Issuing DID doesn't have a key in ${verificationRelationship.name} to use: $jwtIssuerDID"
)
)
jwtIssuer <- managedDIDService
.findDIDKeyPair(jwtIssuerDID.asCanonical, issuingKeyId)
.flatMap {
case None =>
ZIO.fail(
RuntimeException(s"Issuer key-pair does not exist in the wallet: ${jwtIssuerDID.toString}#$issuingKeyId")
BackgroundJobError
.InvalidState(s"Issuer key-pair does not exist in the wallet: ${jwtIssuerDID.toString}#$issuingKeyId")
)
case Some(Ed25519KeyPair(publicKey, privateKey)) =>
ZIO.fail(
RuntimeException(
BackgroundJobError.InvalidState(
s"Issuer key-pair '$issuingKeyId' is of the type Ed25519. It's not supported by this feature in this version"
)
)
case Some(X25519KeyPair(publicKey, privateKey)) =>
ZIO.fail(
RuntimeException(
BackgroundJobError.InvalidState(
s"Issuer key-pair '$issuingKeyId' is of the type X25519. It's not supported by this feature in this version"
)
)
Expand Down Expand Up @@ -127,14 +138,22 @@ trait BackgroundJobsHelper {
proverDid: PrismDID,
verificationRelationship: VerificationRelationship,
keyId: KeyId
): ZIO[DIDService & ManagedDIDService & WalletAccessContext, RuntimeException, Ed25519KeyPair] = {
): ZIO[
DIDService & ManagedDIDService & WalletAccessContext,
DIDResolutionError | BackgroundJobError,
Ed25519KeyPair
] = {
for {
managedDIDService <- ZIO.service[ManagedDIDService]
didService <- ZIO.service[DIDService]
issuingKeyId <- didService
.resolveDID(proverDid)
.mapError(e => RuntimeException(s"Error occured while resolving Issuing DID during VC creation: ${e.toString}"))
.someOrFail(RuntimeException(s"Issuing DID resolution result is not found"))
.mapError(e =>
BackgroundJobError.InvalidState(
s"Error occured while resolving Issuing DID during VC creation: ${e.toString}"
)
)
.someOrFail(BackgroundJobError.InvalidState(s"Issuing DID resolution result is not found"))
.map { case (_, didData) =>
didData.publicKeys
.find(pk =>
Expand All @@ -144,13 +163,17 @@ trait BackgroundJobsHelper {
.map(_.id)
}
.someOrFail(
RuntimeException(s"Issuing DID doesn't have a key in ${verificationRelationship.name} to use: $proverDid")
BackgroundJobError.InvalidState(
s"Issuing DID doesn't have a key in ${verificationRelationship.name} to use: $proverDid"
)
)
ed25519keyPair <- managedDIDService
.findDIDKeyPair(proverDid.asCanonical, issuingKeyId)
.map(_.collect { case keyPair: Ed25519KeyPair => keyPair })
.someOrFail(
RuntimeException(s"Issuer key-pair does not exist in the wallet: ${proverDid.toString}#$issuingKeyId")
BackgroundJobError.InvalidState(
s"Issuer key-pair does not exist in the wallet: ${proverDid.toString}#$issuingKeyId"
)
)
} yield ed25519keyPair
}
Expand All @@ -162,28 +185,21 @@ trait BackgroundJobsHelper {
publicKeyBase64 <- didResolutionResult match {
case failed: DIDResolutionFailed =>
ZIO.fail(
PresentationError.UnexpectedError(
s"DIDResolutionFailed for $did: ${failed.error.toString}"
)
PresentationError.DIDResolutionFailed(did, failed.error.toString)
)
case succeeded: DIDResolutionSucceeded =>
succeeded.didDocument.verificationMethod
.find(vm => succeeded.didDocument.assertionMethod.contains(vm.id))
.flatMap(_.publicKeyJwk.flatMap(_.x))
.toRight(
PresentationError.UnexpectedError(
s"Did Document is missing the required publicKey: $did"
)
)
.toRight(PresentationError.DIDDocumentMissing(did))
.fold(ZIO.fail(_), ZIO.succeed(_))
}
ed25519PublicKey <- ZIO
.fromTry {
val decodedKey = Base64.getUrlDecoder.decode(publicKeyBase64)
KmpEd25519KeyOps.publicKeyFromEncoded(decodedKey)
}
.mapError(t => PresentationError.UnexpectedError(t.getMessage))
.mapError(t => PresentationError.PublicKeyDecodingError(t.getMessage))
} yield ed25519PublicKey
}

}
Loading

0 comments on commit 2356bfb

Please sign in to comment.