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

hyperledger / identus-cloud-agent / 8998019047

08 May 2024 07:31AM UTC coverage: 47.171% (-0.7%) from 47.829%
8998019047

Pull #1021

patlo-iog
chore: pr cleanup
Pull Request #1021: feat: oidc4vc credential configuration and metadata endpoints [WIP]

2 of 253 new or added lines in 12 files covered. (0.79%)

186 existing lines in 51 files now uncovered.

7388 of 15662 relevant lines covered (47.17%)

0.47 hits per line

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

34.45
/cloud-agent/service/server/src/main/scala/org/hyperledger/identus/agent/server/CloudAgentApp.scala
1
package org.hyperledger.identus.agent.server
2

3
import org.hyperledger.identus.agent.notification.WebhookPublisher
4
import org.hyperledger.identus.agent.server.config.AppConfig
5
import org.hyperledger.identus.agent.server.http.{ZHttp4sBlazeServer, ZHttpEndpoints}
6
import org.hyperledger.identus.agent.server.jobs.*
7
import org.hyperledger.identus.agent.walletapi.model.{Entity, Wallet, WalletSeed}
8
import org.hyperledger.identus.agent.walletapi.service.{EntityService, ManagedDIDService, WalletManagementService}
9
import org.hyperledger.identus.agent.walletapi.storage.DIDNonSecretStorage
10
import org.hyperledger.identus.castor.controller.{DIDRegistrarServerEndpoints, DIDServerEndpoints}
11
import org.hyperledger.identus.castor.core.service.DIDService
12
import org.hyperledger.identus.connect.controller.ConnectionServerEndpoints
13
import org.hyperledger.identus.connect.core.service.ConnectionService
14
import org.hyperledger.identus.credential.status.controller.CredentialStatusServiceEndpoints
15
import org.hyperledger.identus.event.controller.EventServerEndpoints
16
import org.hyperledger.identus.event.notification.EventNotificationConfig
17
import org.hyperledger.identus.iam.authentication.apikey.ApiKeyAuthenticator
18
import org.hyperledger.identus.iam.entity.http.EntityServerEndpoints
19
import org.hyperledger.identus.iam.wallet.http.WalletManagementServerEndpoints
20
import org.hyperledger.identus.issue.controller.IssueServerEndpoints
21
import org.hyperledger.identus.mercury.{DidOps, HttpClient}
22
import org.hyperledger.identus.oidc4vc.CredentialIssuerServerEndpoints
23
import org.hyperledger.identus.pollux.core.service.{CredentialService, PresentationService}
24
import org.hyperledger.identus.pollux.credentialdefinition.CredentialDefinitionRegistryServerEndpoints
25
import org.hyperledger.identus.pollux.credentialschema.{
26
  SchemaRegistryServerEndpoints,
27
  VerificationPolicyServerEndpoints
28
}
29
import org.hyperledger.identus.pollux.vc.jwt.DidResolver as JwtDidResolver
30
import org.hyperledger.identus.presentproof.controller.PresentProofServerEndpoints
31
import org.hyperledger.identus.resolvers.DIDResolver
32
import org.hyperledger.identus.shared.models.WalletAdministrationContext
33
import org.hyperledger.identus.shared.models.{HexString, WalletAccessContext, WalletId}
34
import org.hyperledger.identus.shared.utils.DurationOps.toMetricsSeconds
35
import org.hyperledger.identus.system.controller.SystemServerEndpoints
36
import org.hyperledger.identus.verification.controller.VcVerificationServerEndpoints
37
import zio.*
38
import zio.metrics.*
39

40
object CloudAgentApp {
41

42
  def run = for {
×
43
    _ <- AgentInitialization.run
×
44
    _ <- issueCredentialDidCommExchangesJob.debug.fork
×
45
    _ <- presentProofExchangeJob.debug.fork
×
46
    _ <- connectDidCommExchangesJob.debug.fork
×
47
    _ <- syncDIDPublicationStateFromDltJob.debug.fork
×
48
    _ <- syncRevocationStatusListsJob.debug.fork
×
49
    _ <- AgentHttpServer.run.fork
×
50
    fiber <- DidCommHttpServer.run.fork
×
51
    _ <- WebhookPublisher.layer.build.map(_.get[WebhookPublisher]).flatMap(_.run.debug.fork)
×
52
    _ <- fiber.join *> ZIO.log(s"Server End")
×
53
    _ <- ZIO.never
×
54
  } yield ()
×
55

56
  private val issueCredentialDidCommExchangesJob: RIO[
57
    AppConfig & DidOps & DIDResolver & JwtDidResolver & HttpClient & CredentialService & DIDNonSecretStorage &
58
      DIDService & ManagedDIDService & PresentationService & WalletManagementService,
59
    Unit
60
  ] =
61
    for {
×
62
      config <- ZIO.service[AppConfig]
×
63
      _ <- (IssueBackgroundJobs.issueCredentialDidCommExchanges @@ Metric
×
64
        .gauge("issuance_flow_did_com_exchange_job_ms_gauge")
×
65
        .trackDurationWith(_.toMetricsSeconds))
×
66
        .repeat(Schedule.spaced(config.pollux.issueBgJobRecurrenceDelay))
×
67
        .unit
68
    } yield ()
×
69

70
  private val presentProofExchangeJob: RIO[
71
    AppConfig & DidOps & DIDResolver & JwtDidResolver & HttpClient & PresentationService & CredentialService &
72
      DIDNonSecretStorage & DIDService & ManagedDIDService & WalletManagementService,
73
    Unit
74
  ] =
75
    for {
×
76
      config <- ZIO.service[AppConfig]
×
77
      _ <- (PresentBackgroundJobs.presentProofExchanges @@ Metric
×
78
        .gauge("present_proof_flow_did_com_exchange_job_ms_gauge")
×
79
        .trackDurationWith(_.toMetricsSeconds))
×
80
        .repeat(Schedule.spaced(config.pollux.presentationBgJobRecurrenceDelay))
×
81
        .unit
82
    } yield ()
×
83

84
  private val connectDidCommExchangesJob: RIO[
85
    AppConfig & DidOps & DIDResolver & HttpClient & ConnectionService & ManagedDIDService & DIDNonSecretStorage &
86
      WalletManagementService,
87
    Unit
88
  ] =
89
    for {
×
90
      config <- ZIO.service[AppConfig]
×
91
      _ <- (ConnectBackgroundJobs.didCommExchanges @@ Metric
×
92
        .gauge("connection_flow_did_com_exchange_job_ms_gauge")
×
93
        .trackDurationWith(_.toMetricsSeconds))
×
94
        .repeat(Schedule.spaced(config.connect.connectBgJobRecurrenceDelay))
×
95
        .unit
96
    } yield ()
×
97

98
  private val syncRevocationStatusListsJob = {
99
    for {
×
100
      config <- ZIO.service[AppConfig]
×
101
      _ <- (StatusListJobs.syncRevocationStatuses @@ Metric
×
102
        .gauge("revocation_status_list_sync_job_ms_gauge")
×
103
        .trackDurationWith(_.toMetricsSeconds))
×
104
        .repeat(Schedule.spaced(config.pollux.syncRevocationStatusesBgJobRecurrenceDelay))
×
105
    } yield ()
×
106
  }
107

108
  private val syncDIDPublicationStateFromDltJob: URIO[ManagedDIDService & WalletManagementService, Unit] =
109
    ZIO
×
110
      .serviceWithZIO[WalletManagementService](_.listWallets().map(_._1))
×
111
      .flatMap { wallets =>
112
        ZIO.foreach(wallets) { wallet =>
×
113
          DIDStateSyncBackgroundJobs.syncDIDPublicationStateFromDlt
×
114
            .provideSomeLayer(ZLayer.succeed(WalletAccessContext(wallet.id)))
×
115
        }
116
      }
117
      .catchAll(e => ZIO.logError(s"error while syncing DID publication state: $e"))
×
118
      .repeat(Schedule.spaced(10.seconds))
×
119
      .unit
120
      .provideSomeLayer(ZLayer.succeed(WalletAdministrationContext.Admin()))
×
121

122
}
123

124
object AgentHttpServer {
125
  val agentRESTServiceEndpoints = for {
×
126
    allCredentialDefinitionRegistryEndpoints <- CredentialDefinitionRegistryServerEndpoints.all
×
127
    allSchemaRegistryEndpoints <- SchemaRegistryServerEndpoints.all
×
128
    allVerificationPolicyEndpoints <- VerificationPolicyServerEndpoints.all
×
129
    allConnectionEndpoints <- ConnectionServerEndpoints.all
×
130
    allIssueEndpoints <- IssueServerEndpoints.all
×
131
    allStatusListEndpoints <- CredentialStatusServiceEndpoints.all
×
132
    allDIDEndpoints <- DIDServerEndpoints.all
×
133
    allDIDRegistrarEndpoints <- DIDRegistrarServerEndpoints.all
×
134
    allPresentProofEndpoints <- PresentProofServerEndpoints.all
×
135
    allVcVerificationEndpoints <- VcVerificationServerEndpoints.all
×
136
    allSystemEndpoints <- SystemServerEndpoints.all
×
137
    allEntityEndpoints <- EntityServerEndpoints.all
×
138
    allWalletManagementEndpoints <- WalletManagementServerEndpoints.all
×
139
    allEventEndpoints <- EventServerEndpoints.all
×
140
    allOIDCEndpoints <- CredentialIssuerServerEndpoints.all
×
141
  } yield allCredentialDefinitionRegistryEndpoints ++
×
142
    allSchemaRegistryEndpoints ++
143
    allVerificationPolicyEndpoints ++
144
    allConnectionEndpoints ++
145
    allDIDEndpoints ++
146
    allDIDRegistrarEndpoints ++
147
    allIssueEndpoints ++
148
    allStatusListEndpoints ++
149
    allPresentProofEndpoints ++
150
    allVcVerificationEndpoints ++
151
    allSystemEndpoints ++
152
    allEntityEndpoints ++
153
    allWalletManagementEndpoints ++
154
    allEventEndpoints ++
155
    allOIDCEndpoints
156
  def run =
×
157
    for {
×
158
      allEndpoints <- agentRESTServiceEndpoints
×
159
      allEndpointsWithDocumentation = ZHttpEndpoints.withDocumentations[Task](allEndpoints)
×
160
      server <- ZHttp4sBlazeServer.make
×
161
      appConfig <- ZIO.service[AppConfig]
×
162
      _ <- server.start(allEndpointsWithDocumentation, port = appConfig.agent.httpEndpoint.http.port).debug
×
163
    } yield ()
×
164
}
165

166
object AgentInitialization {
167

168
  private val defaultWalletId = WalletId.default
1✔
169
  private val defaultWallet = Wallet("default", defaultWalletId)
1✔
170
  private val defaultEntity = Entity.Default
171

172
  def run: RIO[AppConfig & WalletManagementService & EntityService & ApiKeyAuthenticator, Unit] =
1✔
173
    for {
1✔
174
      _ <- validateAppConfig
175
      _ <- initializeDefaultWallet
1✔
176
        .provideSomeLayer(ZLayer.succeed(WalletAdministrationContext.Admin()))
1✔
177
    } yield ()
1✔
178

179
  private val validateAppConfig =
180
    ZIO.serviceWithZIO[AppConfig](conf =>
1✔
181
      ZIO
1✔
182
        .fromEither(conf.validate)
1✔
183
        .mapError(msg => RuntimeException(s"Application configuration is invalid. $msg"))
1✔
184
    )
185

186
  private val initializeDefaultWallet =
187
    for {
1✔
188
      _ <- ZIO.logInfo("Initializing default wallet.")
1✔
189
      config <- ZIO.serviceWith[AppConfig](_.agent.defaultWallet)
1✔
190
      walletService <- ZIO.service[WalletManagementService]
1✔
191
      isDefaultWalletEnabled = config.enabled
192
      isDefaultWalletExist <- walletService
1✔
193
        .getWallet(defaultWalletId)
1✔
194
        .map(_.isDefined)
1✔
195
        .mapError(_.toThrowable)
×
196
      _ <- ZIO.logInfo(s"Default wallet not enabled.").when(!isDefaultWalletEnabled)
1✔
197
      _ <- ZIO.logInfo(s"Default wallet already exist.").when(isDefaultWalletExist)
1✔
198
      _ <- createDefaultWallet.when(isDefaultWalletEnabled && !isDefaultWalletExist)
1✔
199
    } yield ()
1✔
200

201
  private val createDefaultWallet =
202
    for {
1✔
203
      walletService <- ZIO.service[WalletManagementService]
1✔
204
      entityService <- ZIO.service[EntityService]
1✔
205
      apiKeyAuth <- ZIO.service[ApiKeyAuthenticator]
1✔
206
      config <- ZIO.serviceWith[AppConfig](_.agent.defaultWallet)
1✔
207
      seed <- config.seed.fold(ZIO.none) { seedHex =>
1✔
208
        ZIO
1✔
209
          .fromTry(HexString.fromString(seedHex))
1✔
210
          .map(bytes => WalletSeed.fromByteArray(bytes.toByteArray).left.map(Exception(_)))
1✔
211
          .absolve
212
          .asSome
213
      }
214
      _ <- ZIO.logInfo(s"Default wallet seed is not provided. New seed will be generated.").when(seed.isEmpty)
1✔
215
      _ <- walletService
1✔
216
        .createWallet(defaultWallet, seed)
1✔
217
        .mapError(_.toThrowable)
×
218
      _ <- entityService.create(defaultEntity).mapError(e => Exception(e.message))
1✔
UNCOV
219
      _ <- apiKeyAuth.add(defaultEntity.id, config.authApiKey).mapError(e => Exception(e.message))
×
220
      _ <- config.webhookUrl.fold(ZIO.unit) { url =>
1✔
221
        val customHeaders = config.webhookApiKey.fold(Map.empty)(apiKey => Map("Authorization" -> s"Bearer $apiKey"))
1✔
222
        walletService
1✔
223
          .createWalletNotification(EventNotificationConfig(defaultWalletId, url, customHeaders))
1✔
224
          .mapError(_.toThrowable)
×
225
          .provide(ZLayer.succeed(WalletAccessContext(defaultWalletId)))
1✔
226
      }
227
    } yield ()
1✔
228

229
}
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