frostfs-node/pkg/network/transport/object/grpc/preprocessor.go
Stanislav Bogatyrev b7b5079934 Add Inner Ring code
2020-07-24 17:07:37 +03:00

160 lines
3.8 KiB
Go

package object
import (
"context"
"crypto/ecdsa"
"github.com/nspcc-dev/neofs-api-go/service"
"go.uber.org/zap"
)
type (
// requestPreProcessor is an interface of Object service request installer.
requestPreProcessor interface {
// Performs preliminary request validation and preparation.
preProcess(context.Context, serviceRequest) error
}
// complexPreProcessor is an implementation of requestPreProcessor interface.
complexPreProcessor struct {
// Sequence of requestPreProcessor instances.
list []requestPreProcessor
}
signingPreProcessor struct {
preProc requestPreProcessor
key *ecdsa.PrivateKey
log *zap.Logger
}
)
const pmEmptyServiceRequest = "empty service request"
var (
_ requestPreProcessor = (*signingPreProcessor)(nil)
_ requestPreProcessor = (*complexPreProcessor)(nil)
)
// requestPreProcessor method implementation.
//
// Passes request through internal requestPreProcessor.
// If internal requestPreProcessor returns non-nil error, this error returns.
// Returns result of signRequest function.
func (s *signingPreProcessor) preProcess(ctx context.Context, req serviceRequest) (err error) {
if err = s.preProc.preProcess(ctx, req); err != nil {
return
} else if err = signRequest(s.key, req); err != nil {
s.log.Error("could not re-sign request",
zap.Error(err),
)
err = errReSigning
}
return
}
// requestPreProcessor method implementation.
//
// Panics with pmEmptyServiceRequest on nil request argument.
//
// Passes request through the sequence of requestPreProcessor instances.
// Any non-nil error returned by some instance returns.
//
// Warn: adding instance to list itself provoke endless recursion.
func (s *complexPreProcessor) preProcess(ctx context.Context, req serviceRequest) error {
if req == nil {
panic(pmEmptyServiceRequest)
}
for i := range s.list {
if err := s.list[i].preProcess(ctx, req); err != nil {
return err
}
}
return nil
}
// Creates requestPreProcessor based on Params.
//
// Uses complexPreProcessor instance as a result implementation.
//
// Adds to next preprocessors to list:
// * verifyPreProcessor;
// * ttlPreProcessor;
// * epochPreProcessor, if CheckEpochSync flag is set in params.
// * aclPreProcessor, if CheckAcl flag is set in params.
func newPreProcessor(p *Params) requestPreProcessor {
preProcList := make([]requestPreProcessor, 0)
if p.CheckACL {
preProcList = append(preProcList, &aclPreProcessor{
log: p.Logger,
aclInfoReceiver: p.aclInfoReceiver,
reqActionCalc: p.requestActionCalculator,
localStore: p.LocalStore,
extACLSource: p.ExtendedACLSource,
bearerVerifier: &complexBearerVerifier{
items: []bearerTokenVerifier{
&bearerActualityVerifier{
epochRecv: p.EpochReceiver,
},
new(bearerSignatureVerifier),
&bearerOwnershipVerifier{
cnrStorage: p.ContainerStorage,
},
},
},
})
}
preProcList = append(preProcList,
&verifyPreProcessor{
fVerify: requestVerifyFunc,
},
&ttlPreProcessor{
staticCond: []service.TTLCondition{
validTTLCondition,
},
condPreps: []ttlConditionPreparer{
&coreTTLCondPreparer{
curAffChecker: &corePlacementUtil{
prevNetMap: false,
localAddrStore: p.AddressStore,
placementBuilder: p.Placer,
log: p.Logger,
},
prevAffChecker: &corePlacementUtil{
prevNetMap: true,
localAddrStore: p.AddressStore,
placementBuilder: p.Placer,
log: p.Logger,
},
},
},
fProc: processTTLConditions,
},
&tokenPreProcessor{
staticVerifier: newComplexTokenVerifier(
&tokenEpochsVerifier{
epochRecv: p.EpochReceiver,
},
),
},
new(decTTLPreProcessor),
)
return &signingPreProcessor{
preProc: &complexPreProcessor{list: preProcList},
key: p.Key,
}
}