[#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
|
return info, ErrUnknownContainer
|
||||||
}
|
}
|
||||||
|
|
||||||
// find request role
|
// find request role and key
|
||||||
role := b.sender.Classify(req, cid, cnr)
|
role, key := b.sender.Classify(req, cid, cnr)
|
||||||
if role == acl.RoleUnknown {
|
if role == acl.RoleUnknown {
|
||||||
return info, ErrUnknownRole
|
return info, ErrUnknownRole
|
||||||
}
|
}
|
||||||
|
@ -400,12 +400,11 @@ func (b Service) findRequestInfo(
|
||||||
info.requestRole = role
|
info.requestRole = role
|
||||||
info.operation = verb
|
info.operation = verb
|
||||||
info.owner = owner.NewIDFromV2(cnr.GetOwnerID())
|
info.owner = owner.NewIDFromV2(cnr.GetOwnerID())
|
||||||
|
|
||||||
info.cid = cid
|
info.cid = cid
|
||||||
|
|
||||||
// it is assumed that at the moment the key will be valid,
|
// it is assumed that at the moment the key will be valid,
|
||||||
// otherwise the request would not pass validation
|
// otherwise the request would not pass validation
|
||||||
info.senderKey = req.vheader.GetBodySignature().GetKey()
|
info.senderKey = key
|
||||||
|
|
||||||
return info, nil
|
return info, nil
|
||||||
}
|
}
|
|
@ -42,46 +42,46 @@ func NewSenderClassifier(ir InnerRingFetcher, nm core.Source) SenderClassifier {
|
||||||
func (c SenderClassifier) Classify(
|
func (c SenderClassifier) Classify(
|
||||||
req metaWithToken,
|
req metaWithToken,
|
||||||
cid *container.ID,
|
cid *container.ID,
|
||||||
cnr *container.Container) acl.Role {
|
cnr *container.Container) (acl.Role, []byte) {
|
||||||
|
|
||||||
if cid == nil {
|
if cid == nil {
|
||||||
// log there
|
// log there
|
||||||
return acl.RoleUnknown
|
return acl.RoleUnknown, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
ownerID, ownerKey, err := requestOwner(req)
|
ownerID, ownerKey, err := requestOwner(req)
|
||||||
if err != nil || ownerID == nil || ownerKey == nil {
|
if err != nil || ownerID == nil || ownerKey == nil {
|
||||||
// log there
|
// log there
|
||||||
return acl.RoleUnknown
|
return acl.RoleUnknown, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ownerKeyInBytes := crypto.MarshalPublicKey(ownerKey)
|
||||||
|
|
||||||
// todo: get owner from neofs.id if present
|
// todo: get owner from neofs.id if present
|
||||||
|
|
||||||
// if request owner is the same as container owner, return RoleUser
|
// if request owner is the same as container owner, return RoleUser
|
||||||
if bytes.Equal(cnr.GetOwnerID().GetValue(), ownerID.ToV2().GetValue()) {
|
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)
|
isInnerRingNode, err := c.isInnerRingKey(ownerKeyInBytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// log there
|
// log there
|
||||||
return acl.RoleUnknown
|
return acl.RoleUnknown, nil
|
||||||
} else if isInnerRingNode {
|
} else if isInnerRingNode {
|
||||||
return acl.RoleSystem
|
return acl.RoleSystem, ownerKeyInBytes
|
||||||
}
|
}
|
||||||
|
|
||||||
isContainerNode, err := c.isContainerKey(ownerKeyInBytes, cid.ToV2().GetValue(), cnr)
|
isContainerNode, err := c.isContainerKey(ownerKeyInBytes, cid.ToV2().GetValue(), cnr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// log there
|
// log there
|
||||||
return acl.RoleUnknown
|
return acl.RoleUnknown, nil
|
||||||
} else if isContainerNode {
|
} else if isContainerNode {
|
||||||
return acl.RoleSystem
|
return acl.RoleSystem, ownerKeyInBytes
|
||||||
}
|
}
|
||||||
|
|
||||||
// if none of above, return RoleOthers
|
// if none of above, return RoleOthers
|
||||||
return acl.RoleOthers
|
return acl.RoleOthers, ownerKeyInBytes
|
||||||
}
|
}
|
||||||
|
|
||||||
func requestOwner(req metaWithToken) (*owner.ID, *ecdsa.PublicKey, error) {
|
func requestOwner(req metaWithToken) (*owner.ID, *ecdsa.PublicKey, error) {
|
||||||
|
|
Loading…
Reference in a new issue