[#73] Use request owner public key in eACL check

Classifier fetches public key of the request owner
and owner itself. Extended ACL check should rely on
this public key, because it might be extracted from
session token.

Signed-off-by: Alex Vanin <alexey@nspcc.ru>
This commit is contained in:
Alex Vanin 2020-10-05 17:13:23 +03:00 committed by Alex Vanin
parent a9e801cb22
commit cd34145969
2 changed files with 14 additions and 15 deletions

View file

@ -386,8 +386,8 @@ func (b Service) findRequestInfo(
return info, ErrUnknownContainer
}
// find request role
role := b.sender.Classify(req, cid, cnr)
// find request role and key
role, key := b.sender.Classify(req, cid, cnr)
if role == acl.RoleUnknown {
return info, ErrUnknownRole
}
@ -400,12 +400,11 @@ func (b Service) findRequestInfo(
info.requestRole = role
info.operation = verb
info.owner = owner.NewIDFromV2(cnr.GetOwnerID())
info.cid = cid
// it is assumed that at the moment the key will be valid,
// otherwise the request would not pass validation
info.senderKey = req.vheader.GetBodySignature().GetKey()
info.senderKey = key
return info, nil
}

View file

@ -42,46 +42,46 @@ func NewSenderClassifier(ir InnerRingFetcher, nm core.Source) SenderClassifier {
func (c SenderClassifier) Classify(
req metaWithToken,
cid *container.ID,
cnr *container.Container) acl.Role {
cnr *container.Container) (acl.Role, []byte) {
if cid == nil {
// log there
return acl.RoleUnknown
return acl.RoleUnknown, nil
}
ownerID, ownerKey, err := requestOwner(req)
if err != nil || ownerID == nil || ownerKey == nil {
// log there
return acl.RoleUnknown
return acl.RoleUnknown, nil
}
ownerKeyInBytes := crypto.MarshalPublicKey(ownerKey)
// todo: get owner from neofs.id if present
// if request owner is the same as container owner, return RoleUser
if bytes.Equal(cnr.GetOwnerID().GetValue(), ownerID.ToV2().GetValue()) {
return acl.RoleUser
return acl.RoleUser, ownerKeyInBytes
}
ownerKeyInBytes := crypto.MarshalPublicKey(ownerKey)
isInnerRingNode, err := c.isInnerRingKey(ownerKeyInBytes)
if err != nil {
// log there
return acl.RoleUnknown
return acl.RoleUnknown, nil
} else if isInnerRingNode {
return acl.RoleSystem
return acl.RoleSystem, ownerKeyInBytes
}
isContainerNode, err := c.isContainerKey(ownerKeyInBytes, cid.ToV2().GetValue(), cnr)
if err != nil {
// log there
return acl.RoleUnknown
return acl.RoleUnknown, nil
} else if isContainerNode {
return acl.RoleSystem
return acl.RoleSystem, ownerKeyInBytes
}
// if none of above, return RoleOthers
return acl.RoleOthers
return acl.RoleOthers, ownerKeyInBytes
}
func requestOwner(req metaWithToken) (*owner.ID, *ecdsa.PublicKey, error) {