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  }