forked from TrueCloudLab/frostfs-node
[#2028] node: Do not wrap malformed request errors
After presenting request statuses on the API level, all the errors are unwrapped before sending to the caller side. It led to a losing invalid request's context. Signed-off-by: Pavel Karpy <carpawell@nspcc.ru>
This commit is contained in:
parent
2522d924b9
commit
aadd2ad050
5 changed files with 22 additions and 15 deletions
|
@ -21,7 +21,8 @@ Changelog for NeoFS Node
|
||||||
- `neofs-cli lock object`'s `lifetime` flag handling (#1972)
|
- `neofs-cli lock object`'s `lifetime` flag handling (#1972)
|
||||||
- Do not move write-cache in read-only mode for flushing (#1906)
|
- Do not move write-cache in read-only mode for flushing (#1906)
|
||||||
- Child object collection on CLI side with a bearer token (#2000)
|
- Child object collection on CLI side with a bearer token (#2000)
|
||||||
- Fix concurrent map writes in `Object.Put` service
|
- Fix concurrent map writes in `Object.Put` service (#2037)
|
||||||
|
- Malformed request errors' reasons in the responses (#2028)
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
### Updated
|
### Updated
|
||||||
|
|
|
@ -1,18 +1,24 @@
|
||||||
package v2
|
package v2
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const invalidRequestMessage = "malformed request"
|
||||||
|
|
||||||
|
func malformedRequestError(reason string) error {
|
||||||
|
return fmt.Errorf("%s: %s", invalidRequestMessage, reason)
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// ErrMalformedRequest is returned when request contains
|
errEmptyBody = malformedRequestError("empty body")
|
||||||
// invalid data.
|
errEmptyVerificationHeader = malformedRequestError("empty verification header")
|
||||||
ErrMalformedRequest = errors.New("malformed request")
|
errEmptyBodySig = malformedRequestError("empty at body signature")
|
||||||
// ErrInvalidVerb is returned when session token verb doesn't include necessary operation.
|
errInvalidSessionSig = malformedRequestError("invalid session token signature")
|
||||||
ErrInvalidVerb = errors.New("session token verb is invalid")
|
errInvalidSessionOwner = malformedRequestError("invalid session token owner")
|
||||||
|
errInvalidVerb = malformedRequestError("session token verb is invalid")
|
||||||
)
|
)
|
||||||
|
|
||||||
const accessDeniedACLReasonFmt = "access to operation %s is denied by basic ACL check"
|
const accessDeniedACLReasonFmt = "access to operation %s is denied by basic ACL check"
|
||||||
|
|
|
@ -110,7 +110,7 @@ type MetaWithToken struct {
|
||||||
// according to internal meta information.
|
// according to internal meta information.
|
||||||
func (r MetaWithToken) RequestOwner() (*user.ID, *keys.PublicKey, error) {
|
func (r MetaWithToken) RequestOwner() (*user.ID, *keys.PublicKey, error) {
|
||||||
if r.vheader == nil {
|
if r.vheader == nil {
|
||||||
return nil, nil, fmt.Errorf("%w: nil verification header", ErrMalformedRequest)
|
return nil, nil, errEmptyVerificationHeader
|
||||||
}
|
}
|
||||||
|
|
||||||
// if session token is presented, use it as truth source
|
// if session token is presented, use it as truth source
|
||||||
|
@ -122,7 +122,7 @@ func (r MetaWithToken) RequestOwner() (*user.ID, *keys.PublicKey, error) {
|
||||||
// otherwise get original body signature
|
// otherwise get original body signature
|
||||||
bodySignature := originalBodySignature(r.vheader)
|
bodySignature := originalBodySignature(r.vheader)
|
||||||
if bodySignature == nil {
|
if bodySignature == nil {
|
||||||
return nil, nil, fmt.Errorf("%w: nil at body signature", ErrMalformedRequest)
|
return nil, nil, errEmptyBodySig
|
||||||
}
|
}
|
||||||
|
|
||||||
key, err := unmarshalPublicKey(bodySignature.GetKey())
|
key, err := unmarshalPublicKey(bodySignature.GetKey())
|
||||||
|
|
|
@ -445,7 +445,7 @@ func (b Service) GetRangeHash(
|
||||||
func (p putStreamBasicChecker) Send(request *objectV2.PutRequest) error {
|
func (p putStreamBasicChecker) Send(request *objectV2.PutRequest) error {
|
||||||
body := request.GetBody()
|
body := request.GetBody()
|
||||||
if body == nil {
|
if body == nil {
|
||||||
return ErrMalformedRequest
|
return errEmptyBody
|
||||||
}
|
}
|
||||||
|
|
||||||
part := body.GetObjectPart()
|
part := body.GetObjectPart()
|
||||||
|
@ -574,12 +574,12 @@ func (b Service) findRequestInfo(req MetaWithToken, idCnr cid.ID, op acl.Op) (in
|
||||||
return info, errors.New("can't fetch current epoch")
|
return info, errors.New("can't fetch current epoch")
|
||||||
}
|
}
|
||||||
if req.token.ExpiredAt(currentEpoch) {
|
if req.token.ExpiredAt(currentEpoch) {
|
||||||
return info, fmt.Errorf("%w: token has expired (current epoch: %d)",
|
return info, fmt.Errorf("%s: token has expired (current epoch: %d)",
|
||||||
ErrMalformedRequest, currentEpoch)
|
invalidRequestMessage, currentEpoch)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !assertVerb(*req.token, op) {
|
if !assertVerb(*req.token, op) {
|
||||||
return info, ErrInvalidVerb
|
return info, errInvalidVerb
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -114,7 +114,7 @@ func getObjectIDFromRequestBody(body interface{ GetAddress() *refsV2.Address })
|
||||||
func ownerFromToken(token *sessionSDK.Object) (*user.ID, *keys.PublicKey, error) {
|
func ownerFromToken(token *sessionSDK.Object) (*user.ID, *keys.PublicKey, error) {
|
||||||
// 1. First check signature of session token.
|
// 1. First check signature of session token.
|
||||||
if !token.VerifySignature() {
|
if !token.VerifySignature() {
|
||||||
return nil, nil, fmt.Errorf("%w: invalid session token signature", ErrMalformedRequest)
|
return nil, nil, errInvalidSessionSig
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Then check if session token owner issued the session token
|
// 2. Then check if session token owner issued the session token
|
||||||
|
@ -131,7 +131,7 @@ func ownerFromToken(token *sessionSDK.Object) (*user.ID, *keys.PublicKey, error)
|
||||||
|
|
||||||
if !isOwnerFromKey(tokenIssuer, tokenIssuerKey) {
|
if !isOwnerFromKey(tokenIssuer, tokenIssuerKey) {
|
||||||
// TODO: #767 in this case we can issue all owner keys from neofs.id and check once again
|
// TODO: #767 in this case we can issue all owner keys from neofs.id and check once again
|
||||||
return nil, nil, fmt.Errorf("%w: invalid session token owner", ErrMalformedRequest)
|
return nil, nil, errInvalidSessionOwner
|
||||||
}
|
}
|
||||||
|
|
||||||
return &tokenIssuer, tokenIssuerKey, nil
|
return &tokenIssuer, tokenIssuerKey, nil
|
||||||
|
|
Loading…
Reference in a new issue