[#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:
parent
a9e801cb22
commit
cd34145969
2 changed files with 14 additions and 15 deletions
|
@ -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
|
||||
}
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue