github.com/storacha/go-ucanto@v0.7.2/server/options.go (about) 1 package server 2 3 import ( 4 "context" 5 6 "github.com/storacha/go-ucanto/core/delegation" 7 "github.com/storacha/go-ucanto/core/invocation" 8 "github.com/storacha/go-ucanto/core/ipld" 9 "github.com/storacha/go-ucanto/core/result" 10 "github.com/storacha/go-ucanto/core/result/failure" 11 "github.com/storacha/go-ucanto/server/transaction" 12 "github.com/storacha/go-ucanto/transport" 13 "github.com/storacha/go-ucanto/ucan" 14 "github.com/storacha/go-ucanto/validator" 15 ) 16 17 // Option is an option configuring a ucanto server. 18 type Option func(cfg *srvConfig) error 19 20 type srvConfig struct { 21 codec transport.InboundCodec 22 service Service 23 validateAuthorization validator.RevocationCheckerFunc[any] 24 canIssue validator.CanIssueFunc[any] 25 resolveProof validator.ProofResolverFunc 26 parsePrincipal validator.PrincipalParserFunc 27 resolveDIDKey validator.PrincipalResolverFunc 28 validateTimeBounds validator.TimeBoundsValidatorFunc 29 authorityProofs []delegation.Delegation 30 altAudiences []ucan.Principal 31 catch ErrorHandlerFunc 32 logReceipt ReceiptLoggerFunc 33 } 34 35 func WithServiceMethod[O ipld.Builder, X failure.IPLDBuilderFailure](can string, handleFunc ServiceMethod[O, X]) Option { 36 return func(cfg *srvConfig) error { 37 cfg.service[can] = func(ctx context.Context, input invocation.Invocation, invCtx InvocationContext) (transaction.Transaction[ipld.Builder, failure.IPLDBuilderFailure], error) { 38 tx, err := handleFunc(ctx, input, invCtx) 39 if err != nil { 40 return nil, err 41 } 42 out := result.MapResultR0( 43 tx.Out(), 44 func(o O) ipld.Builder { return o }, 45 func(x X) failure.IPLDBuilderFailure { return x }, 46 ) 47 return transaction.NewTransaction(out, transaction.WithEffects(tx.Fx())), nil 48 } 49 return nil 50 } 51 } 52 53 // WithInboundCodec configures the codec used to decode requests and encode 54 // responses. 55 func WithInboundCodec(codec transport.InboundCodec) Option { 56 return func(cfg *srvConfig) error { 57 cfg.codec = codec 58 return nil 59 } 60 } 61 62 // WithRevocationChecker configures the function used to check UCANs for 63 // revocation. 64 func WithRevocationChecker(fn validator.RevocationCheckerFunc[any]) Option { 65 return func(cfg *srvConfig) error { 66 cfg.validateAuthorization = fn 67 return nil 68 } 69 } 70 71 // WithErrorHandler configures a function to be called when errors occur during 72 // execution of a handler. 73 func WithErrorHandler(fn ErrorHandlerFunc) Option { 74 return func(cfg *srvConfig) error { 75 cfg.catch = fn 76 return nil 77 } 78 } 79 80 // WithReceiptLogger configures a function to be called when a receipt is 81 // issued. 82 func WithReceiptLogger(fn ReceiptLoggerFunc) Option { 83 return func(cfg *srvConfig) error { 84 cfg.logReceipt = fn 85 return nil 86 } 87 } 88 89 // WithCanIssue configures a function that determines whether a given capability 90 // can be issued by a given DID or whether it needs to be delegated to the 91 // issuer. 92 func WithCanIssue(fn validator.CanIssueFunc[any]) Option { 93 return func(cfg *srvConfig) error { 94 cfg.canIssue = fn 95 return nil 96 } 97 } 98 99 // WithProofResolver configures a function that finds delegations corresponding 100 // to a given link. If a resolver is not provided the validator may not be able 101 // to explore corresponding path within a proof chain. 102 func WithProofResolver(fn validator.ProofResolverFunc) Option { 103 return func(cfg *srvConfig) error { 104 cfg.resolveProof = fn 105 return nil 106 } 107 } 108 109 // WithPrincipalParser configures a function that provides verifier instances 110 // that can validate UCANs issued by a given principal. 111 func WithPrincipalParser(fn validator.PrincipalParserFunc) Option { 112 return func(cfg *srvConfig) error { 113 cfg.parsePrincipal = fn 114 return nil 115 } 116 } 117 118 // WithPrincipalResolver configures a function that resolves the key of a 119 // principal that is identified by DID different from did:key method. 120 func WithPrincipalResolver(fn validator.PrincipalResolverFunc) Option { 121 return func(cfg *srvConfig) error { 122 cfg.resolveDIDKey = fn 123 return nil 124 } 125 } 126 127 // WithTimeBoundsValidator configures a function that validates the time bounds of a delegation. 128 func WithTimeBoundsValidator(fn validator.TimeBoundsValidatorFunc) Option { 129 return func(cfg *srvConfig) error { 130 cfg.validateTimeBounds = fn 131 return nil 132 } 133 } 134 135 // WithAuthorityProofs allows to provide a list of proofs that designate other 136 // principals (beyond the service authority) whose attestations will be recognized as valid. 137 func WithAuthorityProofs(proofs ...delegation.Delegation) Option { 138 return func(cfg *srvConfig) error { 139 cfg.authorityProofs = proofs 140 return nil 141 } 142 } 143 144 // WithAlternativeAudiences configures a set of alternative audiences that will be assumed by the service. 145 // Invocations targeted to the service itself or any of the alternative audiences will be accepted. 146 func WithAlternativeAudiences(audiences ...ucan.Principal) Option { 147 return func(cfg *srvConfig) error { 148 cfg.altAudiences = audiences 149 return nil 150 } 151 }