forked from TrueCloudLab/frostfs-node
Evgenii Stratonikov
0e31c12e63
Drop duplicate entities. Format entities. Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com> Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
99 lines
2.4 KiB
Go
99 lines
2.4 KiB
Go
package container
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs"
|
|
cntClient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/container"
|
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/event/container"
|
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/eacl"
|
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/session"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
func (cp *Processor) processSetEACL(e container.SetEACL) {
|
|
if !cp.alphabetState.IsAlphabet() {
|
|
cp.log.Info(logs.ContainerNonAlphabetModeIgnoreSetEACL)
|
|
return
|
|
}
|
|
|
|
err := cp.checkSetEACL(e)
|
|
if err != nil {
|
|
cp.log.Error(logs.ContainerSetEACLCheckFailed,
|
|
zap.String("error", err.Error()),
|
|
)
|
|
|
|
return
|
|
}
|
|
|
|
cp.approveSetEACL(e)
|
|
}
|
|
|
|
func (cp *Processor) checkSetEACL(e container.SetEACL) error {
|
|
binTable := e.Table()
|
|
|
|
// unmarshal table
|
|
table := eacl.NewTable()
|
|
|
|
err := table.Unmarshal(binTable)
|
|
if err != nil {
|
|
return fmt.Errorf("invalid binary table: %w", err)
|
|
}
|
|
|
|
idCnr, ok := table.CID()
|
|
if !ok {
|
|
return errors.New("missing container ID in eACL table")
|
|
}
|
|
|
|
// receive owner of the related container
|
|
cnr, err := cntClient.Get(cp.cnrClient, idCnr)
|
|
if err != nil {
|
|
return fmt.Errorf("could not receive the container: %w", err)
|
|
}
|
|
|
|
// ACL extensions can be disabled by basic ACL, check it
|
|
if !cnr.Value.BasicACL().Extendable() {
|
|
return errors.New("ACL extension disabled by container basic ACL")
|
|
}
|
|
|
|
err = cp.verifySignature(signatureVerificationData{
|
|
ownerContainer: cnr.Value.Owner(),
|
|
verb: session.VerbContainerSetEACL,
|
|
idContainerSet: true,
|
|
idContainer: idCnr,
|
|
binTokenSession: e.SessionToken(),
|
|
binPublicKey: e.PublicKey(),
|
|
signature: e.Signature(),
|
|
signedData: binTable,
|
|
})
|
|
if err != nil {
|
|
return fmt.Errorf("auth eACL table setting: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (cp *Processor) approveSetEACL(e container.SetEACL) {
|
|
var err error
|
|
|
|
prm := cntClient.PutEACLPrm{}
|
|
|
|
prm.SetTable(e.Table())
|
|
prm.SetKey(e.PublicKey())
|
|
prm.SetSignature(e.Signature())
|
|
prm.SetToken(e.SessionToken())
|
|
|
|
if nr := e.NotaryRequest(); nr != nil {
|
|
// setEACL event was received via Notary service
|
|
err = cp.cnrClient.Morph().NotarySignAndInvokeTX(nr.MainTransaction)
|
|
} else {
|
|
// setEACL event was received via notification service
|
|
err = cp.cnrClient.PutEACL(prm)
|
|
}
|
|
if err != nil {
|
|
cp.log.Error(logs.ContainerCouldNotApproveSetEACL,
|
|
zap.String("error", err.Error()),
|
|
)
|
|
}
|
|
}
|