frostfs-s3-gw/neofs/layer/gateway-neofs.go
2020-07-13 14:25:26 +03:00

82 lines
2.3 KiB
Go

package layer
import (
"context"
"crypto/ecdsa"
"math"
"time"
minio "github.com/minio/minio/legacy"
"github.com/minio/minio/neofs/pool"
"github.com/minio/minio/pkg/auth"
"github.com/nspcc-dev/neofs-api-go/chain"
"github.com/nspcc-dev/neofs-api-go/refs"
"github.com/nspcc-dev/neofs-api-go/service"
crypto "github.com/nspcc-dev/neofs-crypto"
"github.com/pkg/errors"
"go.uber.org/zap"
)
type (
// neofsObjects implements gateway for MinIO and S3
// compatible object storage server.
neofsObject struct {
minio.GatewayUnsupported // placeholder for unimplemented functions
cli pool.Client
log *zap.Logger
key *ecdsa.PrivateKey
owner refs.OwnerID
token *service.Token
// Concurrency must be resolved by creating one lock per object, but
// it may be unnecessary in neofs, because objects are immutable. So
// there are no any mutexes and locks right now but it might be
// useful during parallel execution from one client (different clients
// have different `neofsObject` instances).
// todo: add fast expired cache to store list of containers or
// even short objects during sequential reading
}
)
// NewGatewayLayer creates instance of neofsObject. It checks credentials
// and establishes gRPC connection with node.
func NewLayer(cli pool.Client, log *zap.Logger, cred auth.Credentials) (minio.ObjectLayer, error) {
// check if wif is correct
key, err := crypto.WIFDecode(cred.SecretKey)
if err != nil {
return nil, errors.New("can't decode secret key, it must be WIF")
}
// check if wif corresponds wallet address
if cred.AccessKey != chain.KeysToAddress(&key.PublicKey) {
return nil, errors.New("wif and wallet are not corresponded")
}
// format public key into owner
owner, err := refs.NewOwnerID(&key.PublicKey)
if err != nil {
return nil, errors.New("can't create owner id from key")
}
// setup gRPC connection
// todo: think about getting timeout parameters from cli args
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
token, err := generateToken(ctx, tokenParams{
cli: cli,
key: key,
until: math.MaxInt64,
})
if err != nil {
return nil, errors.Wrap(err, "can't establish neofs session with remote host")
}
return &neofsObject{
cli: cli,
key: key,
log: log,
owner: owner,
token: token,
}, nil
}