2020-07-10 14:17:51 +00:00
|
|
|
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{
|
2020-07-24 13:54:03 +00:00
|
|
|
cnrStorage: p.ContainerStorage,
|
2020-07-10 14:17:51 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
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,
|
|
|
|
}
|
|
|
|
}
|