github.com/hyperledger/aries-framework-go@v0.3.2/pkg/framework/context/context.go (about) 1 /* 2 Copyright SecureKey Technologies Inc. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 // Package context creates a framework Provider context to add optional (non default) framework services and provides 8 // simple accessor methods to those same services. 9 package context 10 11 import ( 12 "fmt" 13 "time" 14 15 jsonld "github.com/piprate/json-gold/ld" 16 17 "github.com/hyperledger/aries-framework-go/pkg/crypto" 18 "github.com/hyperledger/aries-framework-go/pkg/didcomm/common/middleware" 19 "github.com/hyperledger/aries-framework-go/pkg/didcomm/common/service" 20 "github.com/hyperledger/aries-framework-go/pkg/didcomm/dispatcher" 21 "github.com/hyperledger/aries-framework-go/pkg/didcomm/dispatcher/inbound" 22 "github.com/hyperledger/aries-framework-go/pkg/didcomm/packer" 23 "github.com/hyperledger/aries-framework-go/pkg/didcomm/transport" 24 "github.com/hyperledger/aries-framework-go/pkg/framework/aries/api" 25 vdrapi "github.com/hyperledger/aries-framework-go/pkg/framework/aries/api/vdr" 26 "github.com/hyperledger/aries-framework-go/pkg/kms" 27 "github.com/hyperledger/aries-framework-go/pkg/secretlock" 28 "github.com/hyperledger/aries-framework-go/pkg/store/connection" 29 "github.com/hyperledger/aries-framework-go/pkg/store/did" 30 "github.com/hyperledger/aries-framework-go/pkg/store/ld" 31 "github.com/hyperledger/aries-framework-go/pkg/store/verifiable" 32 "github.com/hyperledger/aries-framework-go/spi/storage" 33 ) 34 35 const ( 36 defaultGetDIDsMaxRetries = 3 37 ) 38 39 // Provider supplies the framework configuration to client objects. 40 type Provider struct { 41 services []dispatcher.ProtocolService 42 servicesMsgTypeTargets []dispatcher.MessageTypeTarget 43 msgSvcProvider api.MessageServiceProvider 44 storeProvider storage.Provider 45 protocolStateStoreProvider storage.Provider 46 kms kms.KeyManager 47 secretLock secretlock.Service 48 crypto crypto.Crypto 49 packager transport.Packager 50 primaryPacker packer.Packer 51 packers []packer.Packer 52 serviceEndpoint string 53 routerEndpoint string 54 outboundDispatcher dispatcher.Outbound 55 messenger service.MessengerHandler 56 outboundTransports []transport.OutboundTransport 57 vdr vdrapi.Registry 58 verifiableStore verifiable.Store 59 didConnectionStore did.ConnectionStore 60 contextStore ld.ContextStore 61 remoteProviderStore ld.RemoteProviderStore 62 documentLoader jsonld.DocumentLoader 63 transportReturnRoute string 64 frameworkID string 65 keyType kms.KeyType 66 keyAgreementType kms.KeyType 67 mediaTypeProfiles []string 68 getDIDsMaxRetries uint64 69 getDIDsBackOffDuration time.Duration 70 inboundEnvelopeHandler InboundEnvelopeHandler 71 didRotator *middleware.DIDCommMessageMiddleware 72 connectionRecorder *connection.Recorder 73 } 74 75 // InboundEnvelopeHandler handles inbound envelopes, processing then dispatching to a protocol service based on the 76 // message type. 77 type InboundEnvelopeHandler interface { 78 // HandleInboundEnvelope handles an inbound envelope. 79 HandleInboundEnvelope(envelope *transport.Envelope) error 80 // HandlerFunc provides the transport.InboundMessageHandler of the given InboundEnvelopeHandler. 81 HandlerFunc() transport.InboundMessageHandler 82 } 83 84 type inboundHandler struct { 85 handlers []dispatcher.ProtocolService 86 } 87 88 func (in *inboundHandler) HandleInbound(msg service.DIDCommMsg, ctx service.DIDCommContext) (string, error) { 89 for i := range in.handlers { 90 if in.handlers[i].Accept(msg.Type()) { 91 return in.handlers[i].HandleInbound(msg, ctx) 92 } 93 } 94 95 return "", fmt.Errorf("no inbound handlers for msg type: %s", msg.Type()) 96 } 97 98 // New instantiates a new context provider. 99 func New(opts ...ProviderOption) (*Provider, error) { 100 ctxProvider := Provider{ 101 getDIDsMaxRetries: defaultGetDIDsMaxRetries, 102 getDIDsBackOffDuration: time.Second, 103 } 104 105 for _, opt := range opts { 106 err := opt(&ctxProvider) 107 if err != nil { 108 return nil, fmt.Errorf("option failed: %w", err) 109 } 110 } 111 112 if ctxProvider.storeProvider != nil && ctxProvider.protocolStateStoreProvider != nil { 113 recorder, err := connection.NewRecorder(&ctxProvider) 114 if err != nil { 115 return nil, fmt.Errorf("initialize context connection recorder: %w", err) 116 } 117 118 ctxProvider.connectionRecorder = recorder 119 } 120 121 return &ctxProvider, nil 122 } 123 124 // ConnectionLookup returns a connection.Lookup initialized on this context's stores. 125 func (p *Provider) ConnectionLookup() *connection.Lookup { 126 return p.connectionRecorder.Lookup 127 } 128 129 // OutboundDispatcher returns an outbound dispatcher. 130 func (p *Provider) OutboundDispatcher() dispatcher.Outbound { 131 return p.outboundDispatcher 132 } 133 134 // OutboundTransports returns an outbound transports. 135 func (p *Provider) OutboundTransports() []transport.OutboundTransport { 136 return p.outboundTransports 137 } 138 139 // Service return protocol service. 140 func (p *Provider) Service(id string) (interface{}, error) { 141 for _, v := range p.services { 142 if v.Name() == id { 143 return v, nil 144 } 145 } 146 147 return nil, api.ErrSvcNotFound 148 } 149 150 // AllServices returns a copy of the Provider's list of ProtocolServices. 151 func (p *Provider) AllServices() []dispatcher.ProtocolService { 152 ret := make([]dispatcher.ProtocolService, len(p.services)) 153 154 for i, s := range p.services { 155 ret[i] = s 156 } 157 158 return ret 159 } 160 161 // ServiceMsgTypeTargets returns list of service message types of context protocol services based mapping for 162 // the given targets. 163 func (p *Provider) ServiceMsgTypeTargets() []dispatcher.MessageTypeTarget { 164 return p.servicesMsgTypeTargets 165 } 166 167 // KMS returns a Key Management Service. 168 func (p *Provider) KMS() kms.KeyManager { 169 return p.kms 170 } 171 172 // SecretLock returns a secret lock service. 173 func (p *Provider) SecretLock() secretlock.Service { 174 return p.secretLock 175 } 176 177 // Crypto returns the Crypto service. 178 func (p *Provider) Crypto() crypto.Crypto { 179 return p.crypto 180 } 181 182 // Packager returns a packager service. 183 func (p *Provider) Packager() transport.Packager { 184 return p.packager 185 } 186 187 // Messenger returns a messenger. 188 func (p *Provider) Messenger() service.Messenger { 189 return p.messenger 190 } 191 192 // Packers returns a list of enabled packers. 193 func (p *Provider) Packers() []packer.Packer { 194 return p.packers 195 } 196 197 // PrimaryPacker returns the main inbound/outbound Packer service. 198 func (p *Provider) PrimaryPacker() packer.Packer { 199 return p.primaryPacker 200 } 201 202 // ServiceEndpoint returns an service endpoint. This endpoint is used in Out-Of-Band messages, 203 // DID Exchange Invitations or DID Document service to send messages to the agent. 204 func (p *Provider) ServiceEndpoint() string { 205 return p.serviceEndpoint 206 } 207 208 // RouterEndpoint returns a router transport endpoint. The router gives this 209 // endpoint to the requester agent during route registration. The requester 210 // agent can use as it's service endpoint. The router checks the forward 211 // message to routes the message based on the recipient keys(if registered). 212 func (p *Provider) RouterEndpoint() string { 213 return p.routerEndpoint 214 } 215 216 // MessageServiceProvider returns a provider of message services. 217 func (p *Provider) MessageServiceProvider() api.MessageServiceProvider { 218 return p.msgSvcProvider 219 } 220 221 // InboundMessageHandler return an inbound message handler. 222 func (p *Provider) InboundMessageHandler() transport.InboundMessageHandler { 223 if p.inboundEnvelopeHandler == nil { 224 p.inboundEnvelopeHandler = inbound.NewInboundMessageHandler(p) 225 } 226 227 return p.inboundEnvelopeHandler.HandlerFunc() 228 } 229 230 // DIDRotator returns the didcomm/v2 connection DID rotation service. 231 func (p *Provider) DIDRotator() *middleware.DIDCommMessageMiddleware { 232 return p.didRotator 233 } 234 235 // InboundDIDCommMessageHandler provides a supplier of inbound handlers with all loaded protocol services. 236 func (p *Provider) InboundDIDCommMessageHandler() func() service.InboundHandler { 237 return func() service.InboundHandler { 238 tmp := make([]dispatcher.ProtocolService, len(p.services)) 239 copy(tmp, p.services) 240 241 return &inboundHandler{handlers: tmp} 242 } 243 } 244 245 // StorageProvider return a storage provider. 246 func (p *Provider) StorageProvider() storage.Provider { 247 return p.storeProvider 248 } 249 250 // ProtocolStateStorageProvider return a protocol state storage provider. 251 func (p *Provider) ProtocolStateStorageProvider() storage.Provider { 252 return p.protocolStateStoreProvider 253 } 254 255 // VDRegistry returns a vdr registry. 256 func (p *Provider) VDRegistry() vdrapi.Registry { 257 return p.vdr 258 } 259 260 // TransportReturnRoute returns transport return route. 261 func (p *Provider) TransportReturnRoute() string { 262 return p.transportReturnRoute 263 } 264 265 // AriesFrameworkID returns an inbound transport endpoint. 266 func (p *Provider) AriesFrameworkID() string { 267 return p.frameworkID 268 } 269 270 // VerifiableStore returns a verifiable credential store. 271 func (p *Provider) VerifiableStore() verifiable.Store { 272 return p.verifiableStore 273 } 274 275 // DIDConnectionStore returns a DID connection store. 276 func (p *Provider) DIDConnectionStore() did.ConnectionStore { 277 return p.didConnectionStore 278 } 279 280 // JSONLDContextStore returns a JSON-LD context store. 281 func (p *Provider) JSONLDContextStore() ld.ContextStore { 282 return p.contextStore 283 } 284 285 // JSONLDRemoteProviderStore returns a remote JSON-LD context provider store. 286 func (p *Provider) JSONLDRemoteProviderStore() ld.RemoteProviderStore { 287 return p.remoteProviderStore 288 } 289 290 // JSONLDDocumentLoader returns a JSON-LD document loader. 291 func (p *Provider) JSONLDDocumentLoader() jsonld.DocumentLoader { 292 return p.documentLoader 293 } 294 295 // KeyType returns the default Key type (signing/authentication). 296 func (p *Provider) KeyType() kms.KeyType { 297 return p.keyType 298 } 299 300 // KeyAgreementType returns the default Key type (encryption). 301 func (p *Provider) KeyAgreementType() kms.KeyType { 302 return p.keyAgreementType 303 } 304 305 // MediaTypeProfiles returns the default media types profile. 306 func (p *Provider) MediaTypeProfiles() []string { 307 return p.mediaTypeProfiles 308 } 309 310 // GetDIDsMaxRetries returns get DIDs max retries. 311 func (p *Provider) GetDIDsMaxRetries() uint64 { 312 return p.getDIDsMaxRetries 313 } 314 315 // GetDIDsBackOffDuration returns get DIDs backoff duration. 316 func (p *Provider) GetDIDsBackOffDuration() time.Duration { 317 return p.getDIDsBackOffDuration 318 } 319 320 // InboundMessenger returns inbound messenger. 321 func (p *Provider) InboundMessenger() service.InboundMessenger { 322 return p.messenger 323 } 324 325 // ProviderOption configures the framework. 326 type ProviderOption func(opts *Provider) error 327 328 // WithOutboundTransports injects an outbound transports into the context. 329 func WithOutboundTransports(transports ...transport.OutboundTransport) ProviderOption { 330 return func(opts *Provider) error { 331 opts.outboundTransports = transports 332 return nil 333 } 334 } 335 336 // WithGetDIDsMaxRetries sets max retries. 337 func WithGetDIDsMaxRetries(retries uint64) ProviderOption { 338 return func(opts *Provider) error { 339 opts.getDIDsMaxRetries = retries 340 return nil 341 } 342 } 343 344 // WithGetDIDsBackOffDuration sets backoff duration. 345 func WithGetDIDsBackOffDuration(duration time.Duration) ProviderOption { 346 return func(opts *Provider) error { 347 opts.getDIDsBackOffDuration = duration 348 return nil 349 } 350 } 351 352 // WithDIDRotator injects a DID rotator into the context. 353 func WithDIDRotator(didRotator *middleware.DIDCommMessageMiddleware) ProviderOption { 354 return func(opts *Provider) error { 355 opts.didRotator = didRotator 356 return nil 357 } 358 } 359 360 // WithOutboundDispatcher injects an outbound dispatcher into the context. 361 func WithOutboundDispatcher(outboundDispatcher dispatcher.Outbound) ProviderOption { 362 return func(opts *Provider) error { 363 opts.outboundDispatcher = outboundDispatcher 364 return nil 365 } 366 } 367 368 // WithMessengerHandler injects the messenger into the context. 369 func WithMessengerHandler(mh service.MessengerHandler) ProviderOption { 370 return func(opts *Provider) error { 371 opts.messenger = mh 372 return nil 373 } 374 } 375 376 // WithTransportReturnRoute injects transport return route option to the Aries framework. 377 func WithTransportReturnRoute(transportReturnRoute string) ProviderOption { 378 return func(opts *Provider) error { 379 opts.transportReturnRoute = transportReturnRoute 380 return nil 381 } 382 } 383 384 // WithProtocolServices injects a protocol services into the context. 385 func WithProtocolServices(services ...dispatcher.ProtocolService) ProviderOption { 386 return func(opts *Provider) error { 387 opts.services = services 388 return nil 389 } 390 } 391 392 // WithServiceMsgTypeTargets injects service msg type to target mappings in the context. 393 func WithServiceMsgTypeTargets(msgTypeTargets ...dispatcher.MessageTypeTarget) ProviderOption { 394 return func(opts *Provider) error { 395 opts.servicesMsgTypeTargets = msgTypeTargets 396 return nil 397 } 398 } 399 400 // WithKMS injects a kms service into the context. 401 func WithKMS(k kms.KeyManager) ProviderOption { 402 return func(opts *Provider) error { 403 opts.kms = k 404 return nil 405 } 406 } 407 408 // WithSecretLock injects a secret lock service into the context. 409 func WithSecretLock(s secretlock.Service) ProviderOption { 410 return func(opts *Provider) error { 411 opts.secretLock = s 412 return nil 413 } 414 } 415 416 // WithCrypto injects a Crypto service into the context. 417 func WithCrypto(c crypto.Crypto) ProviderOption { 418 return func(opts *Provider) error { 419 opts.crypto = c 420 return nil 421 } 422 } 423 424 // WithVDRegistry injects a vdr service into the context. 425 func WithVDRegistry(vdr vdrapi.Registry) ProviderOption { 426 return func(opts *Provider) error { 427 opts.vdr = vdr 428 return nil 429 } 430 } 431 432 // WithServiceEndpoint injects an service transport endpoint into the context. 433 func WithServiceEndpoint(endpoint string) ProviderOption { 434 return func(opts *Provider) error { 435 opts.serviceEndpoint = endpoint 436 return nil 437 } 438 } 439 440 // WithRouterEndpoint injects an router transport endpoint into the context. 441 func WithRouterEndpoint(endpoint string) ProviderOption { 442 return func(opts *Provider) error { 443 opts.routerEndpoint = endpoint 444 return nil 445 } 446 } 447 448 // WithStorageProvider injects a storage provider into the context. 449 func WithStorageProvider(s storage.Provider) ProviderOption { 450 return func(opts *Provider) error { 451 opts.storeProvider = s 452 return nil 453 } 454 } 455 456 // WithProtocolStateStorageProvider injects a protocol state storage provider into the context. 457 func WithProtocolStateStorageProvider(s storage.Provider) ProviderOption { 458 return func(opts *Provider) error { 459 opts.protocolStateStoreProvider = s 460 return nil 461 } 462 } 463 464 // WithPackager injects a packager into the context. 465 func WithPackager(p transport.Packager) ProviderOption { 466 return func(opts *Provider) error { 467 opts.packager = p 468 return nil 469 } 470 } 471 472 // WithPacker injects at least one Packer into the context, 473 // with the primary Packer being used for inbound/outbound communication 474 // and the additional packers being available for unpacking inbound messages. 475 func WithPacker(primary packer.Packer, additionalPackers ...packer.Packer) ProviderOption { 476 return func(opts *Provider) error { 477 opts.primaryPacker = primary 478 opts.packers = append(opts.packers, additionalPackers...) 479 480 return nil 481 } 482 } 483 484 // WithAriesFrameworkID injects the framework ID into the context. This is used to tie different framework components. 485 // The client can have multiple framework and with same instance of transport shared across it and this id is used 486 // by the framework to tie the inbound transport and outbound transports (in case of duplex communication). 487 func WithAriesFrameworkID(id string) ProviderOption { 488 return func(opts *Provider) error { 489 opts.frameworkID = id 490 return nil 491 } 492 } 493 494 // WithMessageServiceProvider injects a message service provider into the context. 495 func WithMessageServiceProvider(msv api.MessageServiceProvider) ProviderOption { 496 return func(opts *Provider) error { 497 opts.msgSvcProvider = msv 498 return nil 499 } 500 } 501 502 // WithVerifiableStore injects a verifiable credential store. 503 func WithVerifiableStore(store verifiable.Store) ProviderOption { 504 return func(opts *Provider) error { 505 opts.verifiableStore = store 506 return nil 507 } 508 } 509 510 // WithDIDConnectionStore injects a DID connection store into the context. 511 func WithDIDConnectionStore(store did.ConnectionStore) ProviderOption { 512 return func(opts *Provider) error { 513 opts.didConnectionStore = store 514 return nil 515 } 516 } 517 518 // WithJSONLDContextStore injects a JSON-LD context store into the context. 519 func WithJSONLDContextStore(store ld.ContextStore) ProviderOption { 520 return func(opts *Provider) error { 521 opts.contextStore = store 522 return nil 523 } 524 } 525 526 // WithJSONLDRemoteProviderStore injects a JSON-LD remote provider store into the context. 527 func WithJSONLDRemoteProviderStore(store ld.RemoteProviderStore) ProviderOption { 528 return func(opts *Provider) error { 529 opts.remoteProviderStore = store 530 return nil 531 } 532 } 533 534 // WithJSONLDDocumentLoader injects a JSON-LD document loader into the context. 535 func WithJSONLDDocumentLoader(loader jsonld.DocumentLoader) ProviderOption { 536 return func(opts *Provider) error { 537 opts.documentLoader = loader 538 return nil 539 } 540 } 541 542 // WithKeyType injects a keyType for authentication (signing) into the context. 543 func WithKeyType(keyType kms.KeyType) ProviderOption { 544 return func(opts *Provider) error { 545 switch keyType { 546 case kms.ED25519Type, kms.ECDSAP256TypeIEEEP1363, kms.ECDSAP384TypeIEEEP1363, kms.ECDSAP521TypeIEEEP1363, 547 kms.ECDSAP256TypeDER, kms.ECDSAP384TypeDER, kms.ECDSAP521TypeDER, kms.BLS12381G2Type: 548 opts.keyType = keyType 549 return nil 550 default: 551 return fmt.Errorf("invalid authentication key type: %s", keyType) 552 } 553 } 554 } 555 556 // WithKeyAgreementType injects a keyType for KeyAgreement into the context. 557 func WithKeyAgreementType(keyAgreementType kms.KeyType) ProviderOption { 558 return func(opts *Provider) error { 559 switch keyAgreementType { 560 case kms.X25519ECDHKWType, kms.NISTP256ECDHKWType, kms.NISTP384ECDHKWType, kms.NISTP521ECDHKWType: 561 opts.keyAgreementType = keyAgreementType 562 return nil 563 default: 564 return fmt.Errorf("invalid KeyAgreement key type: %s", keyAgreementType) 565 } 566 } 567 } 568 569 // WithMediaTypeProfiles injects a media type profile into the context. 570 func WithMediaTypeProfiles(mediaTypeProfiles []string) ProviderOption { 571 return func(opts *Provider) error { 572 opts.mediaTypeProfiles = make([]string, len(mediaTypeProfiles)) 573 copy(opts.mediaTypeProfiles, mediaTypeProfiles) 574 575 return nil 576 } 577 } 578 579 // WithInboundEnvelopeHandler injects a handler for inbound message envelopes. 580 func WithInboundEnvelopeHandler(handler InboundEnvelopeHandler) ProviderOption { 581 return func(opts *Provider) error { 582 opts.inboundEnvelopeHandler = handler 583 return nil 584 } 585 }