Merge pull request #170 from KirillovDenis/feature/89-placement_policy

[#89] Add placement policy
This commit is contained in:
Alex Vanin 2021-07-26 13:43:38 +03:00 committed by GitHub
commit f4cd1e4c38
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 394 additions and 124 deletions

View file

@ -280,6 +280,18 @@ Rules for session token can be set via param `session-rules` (json-string and fi
If `session-rules` is set, but `create-session-token` is not, the session If `session-rules` is set, but `create-session-token` is not, the session
token will not be created. token will not be created.
Rules for mapping of `LocationConstraint` ([aws spec](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html#API_CreateBucket_RequestBody))
to `PlacementPolicy` ([neofs spec](https://github.com/nspcc-dev/neofs-spec/blob/master/01-arch/02-policy.md))
can be set via param `container-policy` (json-string and file path allowed):
```
{
"rep-3": "REP 3",
"complex": "REP 1 IN X CBF 1 SELECT 1 FROM * AS X",
"example-json-policy": "{\"replicas\":[{\"count\":3,\"selector\":\"SelASD0\"}],\"container_backup_factor\":3,\"selectors\":[{\"name\":\"SelASD0\",\"count\":3,\"filter\":\"*\"}],\"filters\":[]}"
}
```
Example of a command to issue a secret with custom rules for multiple gates: Example of a command to issue a secret with custom rules for multiple gates:
``` ```
$ ./neofs-authmate issue-secret --wallet wallet.json \ $ ./neofs-authmate issue-secret --wallet wallet.json \
@ -289,6 +301,7 @@ $ ./neofs-authmate issue-secret --wallet wallet.json \
--gate-public-key 0317585fa8274f7afdf1fc5f2a2e7bece549d5175c4e5182e37924f30229aef967 \ --gate-public-key 0317585fa8274f7afdf1fc5f2a2e7bece549d5175c4e5182e37924f30229aef967 \
--create-session-token \ --create-session-token \
--session-rules '{"verb":"DELETE","wildcard":false,"containerID":{"value":"%CID"}}' --session-rules '{"verb":"DELETE","wildcard":false,"containerID":{"value":"%CID"}}'
--container-policy '{"rep-3": "REP 3"}'
Enter password for wallet.json > Enter password for wallet.json >
{ {

View file

@ -26,7 +26,7 @@ var authorizationFieldRegexp = regexp.MustCompile(`AWS4-HMAC-SHA256 Credential=(
type ( type (
// Center is a user authentication interface. // Center is a user authentication interface.
Center interface { Center interface {
Authenticate(request *http.Request) (*accessbox.GateData, error) Authenticate(request *http.Request) (*accessbox.Box, error)
} }
center struct { center struct {
@ -64,7 +64,7 @@ func New(conns pool.Pool, key *keys.PrivateKey) Center {
} }
} }
func (c *center) Authenticate(r *http.Request) (*accessbox.GateData, error) { func (c *center) Authenticate(r *http.Request) (*accessbox.Box, error) {
queryValues := r.URL.Query() queryValues := r.URL.Query()
if queryValues.Get("X-Amz-Algorithm") == "AWS4-HMAC-SHA256" { if queryValues.Get("X-Amz-Algorithm") == "AWS4-HMAC-SHA256" {
return nil, errors.New("pre-signed form of request is not supported") return nil, errors.New("pre-signed form of request is not supported")
@ -98,7 +98,7 @@ func (c *center) Authenticate(r *http.Request) (*accessbox.GateData, error) {
return nil, fmt.Errorf("could not parse AccessBox address: %s : %w", accessKeyID, err) return nil, fmt.Errorf("could not parse AccessBox address: %s : %w", accessKeyID, err)
} }
tkns, err := c.cli.GetTokens(r.Context(), address) box, err := c.cli.GetBox(r.Context(), address)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -114,7 +114,7 @@ func (c *center) Authenticate(r *http.Request) (*accessbox.GateData, error) {
} }
} }
awsCreds := credentials.NewStaticCredentials(accessKeyID, tkns.AccessKey, "") awsCreds := credentials.NewStaticCredentials(accessKeyID, box.Gate.AccessKey, "")
signer := v4.NewSigner(awsCreds) signer := v4.NewSigner(awsCreds)
signer.DisableURIPathEscaping = true signer.DisableURIPathEscaping = true
@ -128,5 +128,5 @@ func (c *center) Authenticate(r *http.Request) (*accessbox.GateData, error) {
return nil, errors.New("failed to pass authentication procedure") return nil, errors.New("failed to pass authentication procedure")
} }
return tkns, nil return box, nil
} }

View file

@ -1,6 +1,8 @@
package handler package handler
import ( import (
"context"
"encoding/xml"
"fmt" "fmt"
"net/http" "net/http"
"strconv" "strconv"
@ -11,6 +13,7 @@ import (
"github.com/nspcc-dev/neofs-node/pkg/policy" "github.com/nspcc-dev/neofs-node/pkg/policy"
"github.com/nspcc-dev/neofs-s3-gw/api" "github.com/nspcc-dev/neofs-s3-gw/api"
"github.com/nspcc-dev/neofs-s3-gw/api/layer" "github.com/nspcc-dev/neofs-s3-gw/api/layer"
"github.com/nspcc-dev/neofs-s3-gw/creds/accessbox"
"go.uber.org/zap" "go.uber.org/zap"
) )
@ -24,6 +27,11 @@ const (
publicBasicRule = 0x0FFFFFFF publicBasicRule = 0x0FFFFFFF
) )
type createBucketParams struct {
XMLName xml.Name `xml:"http://s3.amazonaws.com/doc/2006-03-01/ CreateBucketConfiguration" json:"-"`
LocationConstraint string
}
func (h *handler) PutObjectHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) PutObjectHandler(w http.ResponseWriter, r *http.Request) {
var ( var (
err error err error
@ -79,7 +87,6 @@ func (h *handler) CreateBucketHandler(w http.ResponseWriter, r *http.Request) {
var ( var (
err error err error
p = layer.CreateBucketParams{} p = layer.CreateBucketParams{}
rid = api.GetRequestID(r.Context())
req = mux.Vars(r) req = mux.Vars(r)
) )
p.Name = req["bucket"] p.Name = req["bucket"]
@ -90,43 +97,41 @@ func (h *handler) CreateBucketHandler(w http.ResponseWriter, r *http.Request) {
} }
if err != nil { if err != nil {
h.log.Error("could not parse basic ACL", h.registerAndSendError(w, r, err, "could not parse basic ACL")
zap.String("request_id", rid),
zap.Error(err))
api.WriteErrorResponse(r.Context(), w, api.Error{
Code: api.GetAPIError(api.ErrBadRequest).Code,
Description: err.Error(),
HTTPStatusCode: http.StatusBadRequest,
}, r.URL)
return return
} }
createParams, err := parseLocationConstraint(r)
if err != nil {
h.registerAndSendError(w, r, err, "could not parse body")
return
}
p.BoxData, err = getBoxData(r.Context())
if err != nil {
h.registerAndSendError(w, r, err, "could not get boxData")
return
}
if createParams.LocationConstraint != "" {
for _, placementPolicy := range p.BoxData.Policies {
if placementPolicy.LocationConstraint == createParams.LocationConstraint {
p.Policy = placementPolicy.Policy
break
}
}
}
if p.Policy == nil {
p.Policy, err = policy.Parse(defaultPolicy) p.Policy, err = policy.Parse(defaultPolicy)
if err != nil { if err != nil {
h.log.Error("could not parse policy", h.registerAndSendError(w, r, err, "could not parse policy")
zap.String("request_id", rid),
zap.Error(err))
api.WriteErrorResponse(r.Context(), w, api.Error{
Code: api.GetAPIError(api.ErrBadRequest).Code,
Description: err.Error(),
HTTPStatusCode: http.StatusBadRequest,
}, r.URL)
return return
} }
}
cid, err := h.obj.CreateBucket(r.Context(), &p) cid, err := h.obj.CreateBucket(r.Context(), &p)
if err != nil { if err != nil {
h.log.Error("could not create bucket", h.registerAndSendError(w, r, err, "could not create bucket")
zap.String("request_id", rid),
zap.Error(err))
api.WriteErrorResponse(r.Context(), w, api.Error{
Code: api.GetAPIError(api.ErrInternalError).Code,
Description: err.Error(),
HTTPStatusCode: http.StatusInternalServerError,
}, r.URL)
return return
} }
@ -136,6 +141,18 @@ func (h *handler) CreateBucketHandler(w http.ResponseWriter, r *http.Request) {
api.WriteSuccessResponseHeadersOnly(w) api.WriteSuccessResponseHeadersOnly(w)
} }
func parseLocationConstraint(r *http.Request) (*createBucketParams, error) {
if r.ContentLength == 0 {
return new(createBucketParams), nil
}
params := new(createBucketParams)
if err := xml.NewDecoder(r.Body).Decode(params); err != nil {
return nil, err
}
return params, nil
}
func parseBasicACL(basicACL string) (uint32, error) { func parseBasicACL(basicACL string) (uint32, error) {
switch basicACL { switch basicACL {
case basicACLPublic: case basicACLPublic:
@ -155,3 +172,17 @@ func parseBasicACL(basicACL string) (uint32, error) {
return uint32(value), nil return uint32(value), nil
} }
} }
func getBoxData(ctx context.Context) (*accessbox.Box, error) {
var boxData *accessbox.Box
data, ok := ctx.Value(api.BoxData).(*accessbox.Box)
if !ok || data == nil {
return nil, fmt.Errorf("couldn't get box data from context")
}
boxData = data
if boxData.Gate == nil {
boxData.Gate = &accessbox.GateData{}
}
return boxData, nil
}

View file

@ -15,7 +15,6 @@ import (
cid "github.com/nspcc-dev/neofs-api-go/pkg/container/id" cid "github.com/nspcc-dev/neofs-api-go/pkg/container/id"
"github.com/nspcc-dev/neofs-api-go/pkg/owner" "github.com/nspcc-dev/neofs-api-go/pkg/owner"
"github.com/nspcc-dev/neofs-s3-gw/api" "github.com/nspcc-dev/neofs-s3-gw/api"
"github.com/nspcc-dev/neofs-s3-gw/creds/accessbox"
"github.com/nspcc-dev/neofs-sdk-go/pkg/pool" "github.com/nspcc-dev/neofs-sdk-go/pkg/pool"
"go.uber.org/zap" "go.uber.org/zap"
) )
@ -119,14 +118,7 @@ func (n *layer) createContainer(ctx context.Context, p *CreateBucketParams) (*ci
container.WithAttribute(container.AttributeName, p.Name), container.WithAttribute(container.AttributeName, p.Name),
container.WithAttribute(container.AttributeTimestamp, strconv.FormatInt(time.Now().Unix(), 10))) container.WithAttribute(container.AttributeTimestamp, strconv.FormatInt(time.Now().Unix(), 10)))
var gateData *accessbox.GateData cnr.SetSessionToken(p.BoxData.Gate.SessionToken)
if data, ok := ctx.Value(api.GateData).(*accessbox.GateData); ok && data != nil {
gateData = data
} else {
return nil, fmt.Errorf("couldn't get gate data from context")
}
cnr.SetSessionToken(gateData.SessionToken)
cnr.SetOwnerID(n.Owner(ctx)) cnr.SetOwnerID(n.Owner(ctx))
cid, err := n.pool.PutContainer(ctx, cnr) cid, err := n.pool.PutContainer(ctx, cnr)
@ -138,7 +130,7 @@ func (n *layer) createContainer(ctx context.Context, p *CreateBucketParams) (*ci
return nil, err return nil, err
} }
if err := n.setContainerEACL(ctx, cid, gateData.GateKey); err != nil { if err := n.setContainerEACL(ctx, cid, p.BoxData.Gate.GateKey); err != nil {
return nil, err return nil, err
} }

View file

@ -73,6 +73,7 @@ type (
Name string Name string
ACL uint32 ACL uint32
Policy *netmap.PlacementPolicy Policy *netmap.PlacementPolicy
BoxData *accessbox.Box
} }
// DeleteBucketParams stores delete bucket request parameters. // DeleteBucketParams stores delete bucket request parameters.
DeleteBucketParams struct { DeleteBucketParams struct {
@ -134,8 +135,8 @@ func NewLayer(log *zap.Logger, conns pool.Pool) Client {
// Owner returns owner id from BearerToken (context) or from client owner. // Owner returns owner id from BearerToken (context) or from client owner.
func (n *layer) Owner(ctx context.Context) *owner.ID { func (n *layer) Owner(ctx context.Context) *owner.ID {
if data, ok := ctx.Value(api.GateData).(*accessbox.GateData); ok && data != nil { if data, ok := ctx.Value(api.BoxData).(*accessbox.Box); ok && data != nil && data.Gate != nil {
return data.BearerToken.Issuer() return data.Gate.BearerToken.Issuer()
} }
return n.pool.OwnerID() return n.pool.OwnerID()
@ -143,8 +144,8 @@ func (n *layer) Owner(ctx context.Context) *owner.ID {
// BearerOpt returns client.WithBearer call option with token from context or with nil token. // BearerOpt returns client.WithBearer call option with token from context or with nil token.
func (n *layer) BearerOpt(ctx context.Context) client.CallOption { func (n *layer) BearerOpt(ctx context.Context) client.CallOption {
if data, ok := ctx.Value(api.GateData).(*accessbox.GateData); ok && data != nil { if data, ok := ctx.Value(api.BoxData).(*accessbox.Box); ok && data != nil && data.Gate != nil {
return client.WithBearer(data.BearerToken) return client.WithBearer(data.Gate.BearerToken)
} }
return client.WithBearer(nil) return client.WithBearer(nil)
@ -152,8 +153,8 @@ func (n *layer) BearerOpt(ctx context.Context) client.CallOption {
// SessionOpt returns client.WithSession call option with token from context or with nil token. // SessionOpt returns client.WithSession call option with token from context or with nil token.
func (n *layer) SessionOpt(ctx context.Context) client.CallOption { func (n *layer) SessionOpt(ctx context.Context) client.CallOption {
if data, ok := ctx.Value(api.GateData).(*accessbox.GateData); ok && data != nil { if data, ok := ctx.Value(api.BoxData).(*accessbox.Box); ok && data != nil && data.Gate != nil {
return client.WithSession(data.SessionToken) return client.WithSession(data.Gate.SessionToken)
} }
return client.WithSession(nil) return client.WithSession(nil)

View file

@ -12,15 +12,15 @@ import (
// KeyWrapper is wrapper for context keys. // KeyWrapper is wrapper for context keys.
type KeyWrapper string type KeyWrapper string
// GateData is an ID used to store GateData in a context. // BoxData is an ID used to store accessbox.Box in a context.
var GateData = KeyWrapper("__context_gate_data_key") var BoxData = KeyWrapper("__context_box_key")
// AttachUserAuth adds user authentication via center to router using log for logging. // AttachUserAuth adds user authentication via center to router using log for logging.
func AttachUserAuth(router *mux.Router, center auth.Center, log *zap.Logger) { func AttachUserAuth(router *mux.Router, center auth.Center, log *zap.Logger) {
router.Use(func(h http.Handler) http.Handler { router.Use(func(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var ctx context.Context var ctx context.Context
tokens, err := center.Authenticate(r) box, err := center.Authenticate(r)
if err != nil { if err != nil {
if err == auth.ErrNoAuthorizationHeader { if err == auth.ErrNoAuthorizationHeader {
log.Debug("couldn't receive bearer token, using neofs-key") log.Debug("couldn't receive bearer token, using neofs-key")
@ -31,7 +31,7 @@ func AttachUserAuth(router *mux.Router, center auth.Center, log *zap.Logger) {
return return
} }
} else { } else {
ctx = context.WithValue(r.Context(), GateData, tokens) ctx = context.WithValue(r.Context(), BoxData, box)
} }
h.ServeHTTP(w, r.WithContext(ctx)) h.ServeHTTP(w, r.WithContext(ctx))

View file

@ -44,6 +44,9 @@ func New(log *zap.Logger, conns pool.Pool) *Agent {
} }
type ( type (
// ContainerPolicies contains mapping of aws LocationConstraint to neofs PlacementPolicy.
ContainerPolicies map[string]string
// IssueSecretOptions contains options for passing to Agent.IssueSecret method. // IssueSecretOptions contains options for passing to Agent.IssueSecret method.
IssueSecretOptions struct { IssueSecretOptions struct {
ContainerID *cid.ID ContainerID *cid.ID
@ -54,6 +57,7 @@ type (
ContextRules []byte ContextRules []byte
SessionTkn bool SessionTkn bool
Lifetime uint64 Lifetime uint64
ContainerPolicies ContainerPolicies
} }
// ObtainSecretOptions contains options for passing to Agent.ObtainSecret method. // ObtainSecretOptions contains options for passing to Agent.ObtainSecret method.
@ -122,6 +126,45 @@ func (a *Agent) getCurrentEpoch(ctx context.Context) (uint64, error) {
} }
} }
func checkPolicy(policyString string) (*netmap.PlacementPolicy, error) {
result, err := policy.Parse(policyString)
if err == nil {
return result, nil
}
result = netmap.NewPlacementPolicy()
if err = result.UnmarshalJSON([]byte(policyString)); err == nil {
return result, nil
}
return nil, fmt.Errorf("can't parse placement policy")
}
func preparePolicy(policy ContainerPolicies) ([]*accessbox.AccessBox_ContainerPolicy, error) {
if policy == nil {
return nil, nil
}
var result []*accessbox.AccessBox_ContainerPolicy
for locationConstraint, placementPolicy := range policy {
parsedPolicy, err := checkPolicy(placementPolicy)
if err != nil {
return nil, err
}
marshaled, err := parsedPolicy.Marshal()
if err != nil {
return nil, fmt.Errorf("can't marshal placement policy: %w", err)
}
result = append(result, &accessbox.AccessBox_ContainerPolicy{
LocationConstraint: locationConstraint,
Policy: marshaled,
})
}
return result, nil
}
// IssueSecret creates an auth token, puts it in the NeoFS network and writes to io.Writer a new secret access key. // IssueSecret creates an auth token, puts it in the NeoFS network and writes to io.Writer a new secret access key.
func (a *Agent) IssueSecret(ctx context.Context, w io.Writer, options *IssueSecretOptions) error { func (a *Agent) IssueSecret(ctx context.Context, w io.Writer, options *IssueSecretOptions) error {
var ( var (
@ -131,6 +174,11 @@ func (a *Agent) IssueSecret(ctx context.Context, w io.Writer, options *IssueSecr
lifetime lifetimeOptions lifetime lifetimeOptions
) )
policies, err := preparePolicy(options.ContainerPolicies)
if err != nil {
return err
}
lifetime.Iat, err = a.getCurrentEpoch(ctx) lifetime.Iat, err = a.getCurrentEpoch(ctx)
if err != nil { if err != nil {
return err return err
@ -157,6 +205,8 @@ func (a *Agent) IssueSecret(ctx context.Context, w io.Writer, options *IssueSecr
return err return err
} }
box.ContainerPolicy = policies
oid, err := ownerIDFromNeoFSKey(options.NeoFSKey.PublicKey()) oid, err := ownerIDFromNeoFSKey(options.NeoFSKey.PublicKey())
if err != nil { if err != nil {
return err return err
@ -203,14 +253,14 @@ func (a *Agent) ObtainSecret(ctx context.Context, w io.Writer, options *ObtainSe
return fmt.Errorf("failed to parse secret address: %w", err) return fmt.Errorf("failed to parse secret address: %w", err)
} }
tkns, err := bearerCreds.GetTokens(ctx, address) box, err := bearerCreds.GetBox(ctx, address)
if err != nil { if err != nil {
return fmt.Errorf("failed to get tokens: %w", err) return fmt.Errorf("failed to get tokens: %w", err)
} }
or := &obtainingResult{ or := &obtainingResult{
BearerToken: tkns.BearerToken, BearerToken: box.Gate.BearerToken,
SecretAccessKey: tkns.AccessKey, SecretAccessKey: box.Gate.AccessKey,
} }
enc := json.NewEncoder(w) enc := json.NewEncoder(w)

View file

@ -3,6 +3,7 @@ package main
import ( import (
"context" "context"
"crypto/ecdsa" "crypto/ecdsa"
"encoding/json"
"fmt" "fmt"
"os" "os"
"os/signal" "os/signal"
@ -45,6 +46,7 @@ var (
logDebugEnabledFlag bool logDebugEnabledFlag bool
sessionTokenFlag bool sessionTokenFlag bool
lifetimeFlag uint64 lifetimeFlag uint64
containerPolicies string
) )
const ( const (
@ -201,6 +203,12 @@ func issueSecret() *cli.Command {
Destination: &lifetimeFlag, Destination: &lifetimeFlag,
Value: defaultLifetime, Value: defaultLifetime,
}, },
&cli.StringFlag{
Name: "container-policy",
Usage: "mapping AWS storage class to NeoFS storage policy as plain json string or path to json file",
Required: false,
Destination: &containerPolicies,
},
}, },
Action: func(c *cli.Context) error { Action: func(c *cli.Context) error {
ctx, log := prepare() ctx, log := prepare()
@ -241,6 +249,11 @@ func issueSecret() *cli.Command {
return cli.Exit(fmt.Sprintf("lifetime must be at least 1, current value: %d", lifetimeFlag), 5) return cli.Exit(fmt.Sprintf("lifetime must be at least 1, current value: %d", lifetimeFlag), 5)
} }
policies, err := parsePolicies(containerPolicies)
if err != nil {
return cli.Exit(fmt.Sprintf("couldn't parse container policy: %s", err.Error()), 6)
}
issueSecretOptions := &authmate.IssueSecretOptions{ issueSecretOptions := &authmate.IssueSecretOptions{
ContainerID: containerID, ContainerID: containerID,
ContainerFriendlyName: containerFriendlyName, ContainerFriendlyName: containerFriendlyName,
@ -248,6 +261,7 @@ func issueSecret() *cli.Command {
GatesPublicKeys: gatesPublicKeys, GatesPublicKeys: gatesPublicKeys,
EACLRules: getJSONRules(eaclRulesFlag), EACLRules: getJSONRules(eaclRulesFlag),
ContextRules: getJSONRules(contextRulesFlag), ContextRules: getJSONRules(contextRulesFlag),
ContainerPolicies: policies,
SessionTkn: sessionTokenFlag, SessionTkn: sessionTokenFlag,
Lifetime: lifetimeFlag, Lifetime: lifetimeFlag,
} }
@ -261,6 +275,23 @@ func issueSecret() *cli.Command {
} }
} }
func parsePolicies(val string) (authmate.ContainerPolicies, error) {
if val == "" {
return nil, nil
}
data, err := os.ReadFile(val)
if err != nil {
data = []byte(val)
}
var policies authmate.ContainerPolicies
if err = json.Unmarshal(data, &policies); err != nil {
return nil, err
}
return policies, nil
}
func getJSONRules(val string) []byte { func getJSONRules(val string) []byte {
if data, err := os.ReadFile(val); err == nil { if data, err := os.ReadFile(val); err == nil {
return data return data

View file

@ -11,6 +11,7 @@ import (
"io" "io"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"github.com/nspcc-dev/neofs-api-go/pkg/netmap"
"github.com/nspcc-dev/neofs-api-go/pkg/session" "github.com/nspcc-dev/neofs-api-go/pkg/session"
"github.com/nspcc-dev/neofs-api-go/pkg/token" "github.com/nspcc-dev/neofs-api-go/pkg/token"
"golang.org/x/crypto/chacha20poly1305" "golang.org/x/crypto/chacha20poly1305"
@ -18,6 +19,18 @@ import (
"google.golang.org/protobuf/proto" "google.golang.org/protobuf/proto"
) )
// Box represents friendly AccessBox.
type Box struct {
Gate *GateData
Policies []*ContainerPolicy
}
// ContainerPolicy represents friendly AccessBox_ContainerPolicy.
type ContainerPolicy struct {
LocationConstraint string
Policy *netmap.PlacementPolicy
}
// GateData represents gate tokens in AccessBox. // GateData represents gate tokens in AccessBox.
type GateData struct { type GateData struct {
AccessKey string AccessKey string
@ -91,6 +104,42 @@ func (x *AccessBox) GetTokens(owner *keys.PrivateKey) (*GateData, error) {
return nil, fmt.Errorf("no gate data for key %x was found", ownerKey) return nil, fmt.Errorf("no gate data for key %x was found", ownerKey)
} }
// GetPlacementPolicy returns ContainerPolicy from AccessBox.
func (x *AccessBox) GetPlacementPolicy() ([]*ContainerPolicy, error) {
var result []*ContainerPolicy
for _, policy := range x.ContainerPolicy {
placementPolicy := netmap.NewPlacementPolicy()
if err := placementPolicy.Unmarshal(policy.Policy); err != nil {
return nil, err
}
result = append(result, &ContainerPolicy{
LocationConstraint: policy.LocationConstraint,
Policy: placementPolicy,
})
}
return result, nil
}
// GetBox parse AccessBox to Box.
func (x *AccessBox) GetBox(owner *keys.PrivateKey) (*Box, error) {
tokens, err := x.GetTokens(owner)
if err != nil {
return nil, err
}
policy, err := x.GetPlacementPolicy()
if err != nil {
return nil, err
}
return &Box{
Gate: tokens,
Policies: policy,
}, nil
}
func (x *AccessBox) addTokens(gatesData []*GateData, ephemeralKey *keys.PrivateKey, secret []byte) error { func (x *AccessBox) addTokens(gatesData []*GateData, ephemeralKey *keys.PrivateKey, secret []byte) error {
for i, gate := range gatesData { for i, gate := range gatesData {
encBearer, err := gate.BearerToken.Marshal() encBearer, err := gate.BearerToken.Marshal()

View file

@ -7,10 +7,11 @@
package accessbox package accessbox
import ( import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect" reflect "reflect"
sync "sync" sync "sync"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
) )
const ( const (
@ -27,12 +28,13 @@ type AccessBox struct {
OwnerPublicKey []byte `protobuf:"bytes,1,opt,name=ownerPublicKey,proto3" json:"ownerPublicKey,omitempty"` OwnerPublicKey []byte `protobuf:"bytes,1,opt,name=ownerPublicKey,proto3" json:"ownerPublicKey,omitempty"`
Gates []*AccessBox_Gate `protobuf:"bytes,2,rep,name=gates,proto3" json:"gates,omitempty"` Gates []*AccessBox_Gate `protobuf:"bytes,2,rep,name=gates,proto3" json:"gates,omitempty"`
ContainerPolicy []*AccessBox_ContainerPolicy `protobuf:"bytes,3,rep,name=containerPolicy,proto3" json:"containerPolicy,omitempty"`
} }
func (x *AccessBox) Reset() { func (x *AccessBox) Reset() {
*x = AccessBox{} *x = AccessBox{}
if protoimpl.UnsafeEnabled { if protoimpl.UnsafeEnabled {
mi := &file_creds_accessbox_accessbox_proto_msgTypes[0] mi := &file_accessbox_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -45,7 +47,7 @@ func (x *AccessBox) String() string {
func (*AccessBox) ProtoMessage() {} func (*AccessBox) ProtoMessage() {}
func (x *AccessBox) ProtoReflect() protoreflect.Message { func (x *AccessBox) ProtoReflect() protoreflect.Message {
mi := &file_creds_accessbox_accessbox_proto_msgTypes[0] mi := &file_accessbox_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -58,7 +60,7 @@ func (x *AccessBox) ProtoReflect() protoreflect.Message {
// Deprecated: Use AccessBox.ProtoReflect.Descriptor instead. // Deprecated: Use AccessBox.ProtoReflect.Descriptor instead.
func (*AccessBox) Descriptor() ([]byte, []int) { func (*AccessBox) Descriptor() ([]byte, []int) {
return file_creds_accessbox_accessbox_proto_rawDescGZIP(), []int{0} return file_accessbox_proto_rawDescGZIP(), []int{0}
} }
func (x *AccessBox) GetOwnerPublicKey() []byte { func (x *AccessBox) GetOwnerPublicKey() []byte {
@ -75,6 +77,13 @@ func (x *AccessBox) GetGates() []*AccessBox_Gate {
return nil return nil
} }
func (x *AccessBox) GetContainerPolicy() []*AccessBox_ContainerPolicy {
if x != nil {
return x.ContainerPolicy
}
return nil
}
type Tokens struct { type Tokens struct {
state protoimpl.MessageState state protoimpl.MessageState
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
@ -88,7 +97,7 @@ type Tokens struct {
func (x *Tokens) Reset() { func (x *Tokens) Reset() {
*x = Tokens{} *x = Tokens{}
if protoimpl.UnsafeEnabled { if protoimpl.UnsafeEnabled {
mi := &file_creds_accessbox_accessbox_proto_msgTypes[1] mi := &file_accessbox_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -101,7 +110,7 @@ func (x *Tokens) String() string {
func (*Tokens) ProtoMessage() {} func (*Tokens) ProtoMessage() {}
func (x *Tokens) ProtoReflect() protoreflect.Message { func (x *Tokens) ProtoReflect() protoreflect.Message {
mi := &file_creds_accessbox_accessbox_proto_msgTypes[1] mi := &file_accessbox_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -114,7 +123,7 @@ func (x *Tokens) ProtoReflect() protoreflect.Message {
// Deprecated: Use Tokens.ProtoReflect.Descriptor instead. // Deprecated: Use Tokens.ProtoReflect.Descriptor instead.
func (*Tokens) Descriptor() ([]byte, []int) { func (*Tokens) Descriptor() ([]byte, []int) {
return file_creds_accessbox_accessbox_proto_rawDescGZIP(), []int{1} return file_accessbox_proto_rawDescGZIP(), []int{1}
} }
func (x *Tokens) GetAccessKey() []byte { func (x *Tokens) GetAccessKey() []byte {
@ -150,7 +159,7 @@ type AccessBox_Gate struct {
func (x *AccessBox_Gate) Reset() { func (x *AccessBox_Gate) Reset() {
*x = AccessBox_Gate{} *x = AccessBox_Gate{}
if protoimpl.UnsafeEnabled { if protoimpl.UnsafeEnabled {
mi := &file_creds_accessbox_accessbox_proto_msgTypes[2] mi := &file_accessbox_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -163,7 +172,7 @@ func (x *AccessBox_Gate) String() string {
func (*AccessBox_Gate) ProtoMessage() {} func (*AccessBox_Gate) ProtoMessage() {}
func (x *AccessBox_Gate) ProtoReflect() protoreflect.Message { func (x *AccessBox_Gate) ProtoReflect() protoreflect.Message {
mi := &file_creds_accessbox_accessbox_proto_msgTypes[2] mi := &file_accessbox_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -176,7 +185,7 @@ func (x *AccessBox_Gate) ProtoReflect() protoreflect.Message {
// Deprecated: Use AccessBox_Gate.ProtoReflect.Descriptor instead. // Deprecated: Use AccessBox_Gate.ProtoReflect.Descriptor instead.
func (*AccessBox_Gate) Descriptor() ([]byte, []int) { func (*AccessBox_Gate) Descriptor() ([]byte, []int) {
return file_creds_accessbox_accessbox_proto_rawDescGZIP(), []int{0, 0} return file_accessbox_proto_rawDescGZIP(), []int{0, 0}
} }
func (x *AccessBox_Gate) GetTokens() []byte { func (x *AccessBox_Gate) GetTokens() []byte {
@ -193,70 +202,137 @@ func (x *AccessBox_Gate) GetGatePublicKey() []byte {
return nil return nil
} }
var File_creds_accessbox_accessbox_proto protoreflect.FileDescriptor type AccessBox_ContainerPolicy struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
var file_creds_accessbox_accessbox_proto_rawDesc = []byte{ LocationConstraint string `protobuf:"bytes,1,opt,name=locationConstraint,proto3" json:"locationConstraint,omitempty"`
0x0a, 0x1f, 0x63, 0x72, 0x65, 0x64, 0x73, 0x2f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x62, 0x6f, Policy []byte `protobuf:"bytes,2,opt,name=policy,proto3" json:"policy,omitempty"`
0x78, 0x2f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x62, 0x6f, 0x78, 0x2e, 0x70, 0x72, 0x6f, 0x74, }
0x6f, 0x12, 0x09, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x62, 0x6f, 0x78, 0x22, 0xaa, 0x01, 0x0a,
func (x *AccessBox_ContainerPolicy) Reset() {
*x = AccessBox_ContainerPolicy{}
if protoimpl.UnsafeEnabled {
mi := &file_accessbox_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *AccessBox_ContainerPolicy) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*AccessBox_ContainerPolicy) ProtoMessage() {}
func (x *AccessBox_ContainerPolicy) ProtoReflect() protoreflect.Message {
mi := &file_accessbox_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use AccessBox_ContainerPolicy.ProtoReflect.Descriptor instead.
func (*AccessBox_ContainerPolicy) Descriptor() ([]byte, []int) {
return file_accessbox_proto_rawDescGZIP(), []int{0, 1}
}
func (x *AccessBox_ContainerPolicy) GetLocationConstraint() string {
if x != nil {
return x.LocationConstraint
}
return ""
}
func (x *AccessBox_ContainerPolicy) GetPolicy() []byte {
if x != nil {
return x.Policy
}
return nil
}
var File_accessbox_proto protoreflect.FileDescriptor
var file_accessbox_proto_rawDesc = []byte{
0x0a, 0x0f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x62, 0x6f, 0x78, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x12, 0x09, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x62, 0x6f, 0x78, 0x22, 0xd5, 0x02, 0x0a,
0x09, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x42, 0x6f, 0x78, 0x12, 0x26, 0x0a, 0x0e, 0x6f, 0x77, 0x09, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x42, 0x6f, 0x78, 0x12, 0x26, 0x0a, 0x0e, 0x6f, 0x77,
0x6e, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x6e, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01,
0x28, 0x0c, 0x52, 0x0e, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x28, 0x0c, 0x52, 0x0e, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b,
0x65, 0x79, 0x12, 0x2f, 0x0a, 0x05, 0x67, 0x61, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x65, 0x79, 0x12, 0x2f, 0x0a, 0x05, 0x67, 0x61, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28,
0x0b, 0x32, 0x19, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x62, 0x6f, 0x78, 0x2e, 0x41, 0x63, 0x0b, 0x32, 0x19, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x62, 0x6f, 0x78, 0x2e, 0x41, 0x63,
0x63, 0x65, 0x73, 0x73, 0x42, 0x6f, 0x78, 0x2e, 0x47, 0x61, 0x74, 0x65, 0x52, 0x05, 0x67, 0x61, 0x63, 0x65, 0x73, 0x73, 0x42, 0x6f, 0x78, 0x2e, 0x47, 0x61, 0x74, 0x65, 0x52, 0x05, 0x67, 0x61,
0x74, 0x65, 0x73, 0x1a, 0x44, 0x0a, 0x04, 0x47, 0x61, 0x74, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x74, 0x65, 0x73, 0x12, 0x4e, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72,
0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x61,
0x63, 0x63, 0x65, 0x73, 0x73, 0x62, 0x6f, 0x78, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x42,
0x6f, 0x78, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x50, 0x6f, 0x6c, 0x69,
0x63, 0x79, 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x50, 0x6f, 0x6c,
0x69, 0x63, 0x79, 0x1a, 0x44, 0x0a, 0x04, 0x47, 0x61, 0x74, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x74,
0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x74, 0x6f, 0x6b, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x74, 0x6f, 0x6b,
0x65, 0x6e, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x67, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x65, 0x6e, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x67, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69,
0x63, 0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x67, 0x61, 0x74, 0x65, 0x63, 0x4b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x67, 0x61, 0x74, 0x65,
0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x22, 0x6c, 0x0a, 0x06, 0x54, 0x6f, 0x6b, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x1a, 0x59, 0x0a, 0x0f, 0x43, 0x6f, 0x6e,
0x65, 0x6e, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4b, 0x65, 0x79, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x2e, 0x0a, 0x12,
0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4b, 0x65, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69,
0x79, 0x12, 0x20, 0x0a, 0x0b, 0x62, 0x65, 0x61, 0x72, 0x65, 0x72, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69,
0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x62, 0x65, 0x61, 0x72, 0x65, 0x72, 0x54, 0x6f, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06,
0x6b, 0x65, 0x6e, 0x12, 0x22, 0x0a, 0x0c, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x70, 0x6f,
0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6c, 0x69, 0x63, 0x79, 0x22, 0x6c, 0x0a, 0x06, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x1c,
0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x42, 0x3b, 0x5a, 0x39, 0x67, 0x69, 0x74, 0x68, 0x75, 0x0a, 0x09, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28,
0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6e, 0x73, 0x70, 0x63, 0x63, 0x2d, 0x64, 0x65, 0x76, 0x2f, 0x0c, 0x52, 0x09, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4b, 0x65, 0x79, 0x12, 0x20, 0x0a, 0x0b,
0x6e, 0x65, 0x6f, 0x66, 0x73, 0x2d, 0x73, 0x33, 0x2d, 0x67, 0x77, 0x2f, 0x63, 0x72, 0x65, 0x64, 0x62, 0x65, 0x61, 0x72, 0x65, 0x72, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28,
0x73, 0x2f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x62, 0x6f, 0x78, 0x3b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x0c, 0x52, 0x0b, 0x62, 0x65, 0x61, 0x72, 0x65, 0x72, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x22,
0x73, 0x62, 0x6f, 0x78, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 0x0a, 0x0c, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03,
0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b,
0x65, 0x6e, 0x42, 0x3b, 0x5a, 0x39, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
0x2f, 0x6e, 0x73, 0x70, 0x63, 0x63, 0x2d, 0x64, 0x65, 0x76, 0x2f, 0x6e, 0x65, 0x6f, 0x66, 0x73,
0x2d, 0x73, 0x33, 0x2d, 0x67, 0x77, 0x2f, 0x63, 0x72, 0x65, 0x64, 0x73, 0x2f, 0x74, 0x6f, 0x6b,
0x65, 0x6e, 0x62, 0x6f, 0x78, 0x3b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x62, 0x6f, 0x78, 0x62,
0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
} }
var ( var (
file_creds_accessbox_accessbox_proto_rawDescOnce sync.Once file_accessbox_proto_rawDescOnce sync.Once
file_creds_accessbox_accessbox_proto_rawDescData = file_creds_accessbox_accessbox_proto_rawDesc file_accessbox_proto_rawDescData = file_accessbox_proto_rawDesc
) )
func file_creds_accessbox_accessbox_proto_rawDescGZIP() []byte { func file_accessbox_proto_rawDescGZIP() []byte {
file_creds_accessbox_accessbox_proto_rawDescOnce.Do(func() { file_accessbox_proto_rawDescOnce.Do(func() {
file_creds_accessbox_accessbox_proto_rawDescData = protoimpl.X.CompressGZIP(file_creds_accessbox_accessbox_proto_rawDescData) file_accessbox_proto_rawDescData = protoimpl.X.CompressGZIP(file_accessbox_proto_rawDescData)
}) })
return file_creds_accessbox_accessbox_proto_rawDescData return file_accessbox_proto_rawDescData
} }
var file_creds_accessbox_accessbox_proto_msgTypes = make([]protoimpl.MessageInfo, 3) var file_accessbox_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
var file_creds_accessbox_accessbox_proto_goTypes = []interface{}{ var file_accessbox_proto_goTypes = []interface{}{
(*AccessBox)(nil), // 0: accessbox.AccessBox (*AccessBox)(nil), // 0: accessbox.AccessBox
(*Tokens)(nil), // 1: accessbox.Tokens (*Tokens)(nil), // 1: accessbox.Tokens
(*AccessBox_Gate)(nil), // 2: accessbox.AccessBox.Gate (*AccessBox_Gate)(nil), // 2: accessbox.AccessBox.Gate
(*AccessBox_ContainerPolicy)(nil), // 3: accessbox.AccessBox.ContainerPolicy
} }
var file_creds_accessbox_accessbox_proto_depIdxs = []int32{ var file_accessbox_proto_depIdxs = []int32{
2, // 0: accessbox.AccessBox.gates:type_name -> accessbox.AccessBox.Gate 2, // 0: accessbox.AccessBox.gates:type_name -> accessbox.AccessBox.Gate
1, // [1:1] is the sub-list for method output_type 3, // 1: accessbox.AccessBox.containerPolicy:type_name -> accessbox.AccessBox.ContainerPolicy
1, // [1:1] is the sub-list for method input_type 2, // [2:2] is the sub-list for method output_type
1, // [1:1] is the sub-list for extension type_name 2, // [2:2] is the sub-list for method input_type
1, // [1:1] is the sub-list for extension extendee 2, // [2:2] is the sub-list for extension type_name
0, // [0:1] is the sub-list for field type_name 2, // [2:2] is the sub-list for extension extendee
0, // [0:2] is the sub-list for field type_name
} }
func init() { file_creds_accessbox_accessbox_proto_init() } func init() { file_accessbox_proto_init() }
func file_creds_accessbox_accessbox_proto_init() { func file_accessbox_proto_init() {
if File_creds_accessbox_accessbox_proto != nil { if File_accessbox_proto != nil {
return return
} }
if !protoimpl.UnsafeEnabled { if !protoimpl.UnsafeEnabled {
file_creds_accessbox_accessbox_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { file_accessbox_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*AccessBox); i { switch v := v.(*AccessBox); i {
case 0: case 0:
return &v.state return &v.state
@ -268,7 +344,7 @@ func file_creds_accessbox_accessbox_proto_init() {
return nil return nil
} }
} }
file_creds_accessbox_accessbox_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { file_accessbox_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Tokens); i { switch v := v.(*Tokens); i {
case 0: case 0:
return &v.state return &v.state
@ -280,7 +356,7 @@ func file_creds_accessbox_accessbox_proto_init() {
return nil return nil
} }
} }
file_creds_accessbox_accessbox_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { file_accessbox_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*AccessBox_Gate); i { switch v := v.(*AccessBox_Gate); i {
case 0: case 0:
return &v.state return &v.state
@ -292,23 +368,35 @@ func file_creds_accessbox_accessbox_proto_init() {
return nil return nil
} }
} }
file_accessbox_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*AccessBox_ContainerPolicy); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
} }
type x struct{} type x struct{}
out := protoimpl.TypeBuilder{ out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{ File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(), GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_creds_accessbox_accessbox_proto_rawDesc, RawDescriptor: file_accessbox_proto_rawDesc,
NumEnums: 0, NumEnums: 0,
NumMessages: 3, NumMessages: 4,
NumExtensions: 0, NumExtensions: 0,
NumServices: 0, NumServices: 0,
}, },
GoTypes: file_creds_accessbox_accessbox_proto_goTypes, GoTypes: file_accessbox_proto_goTypes,
DependencyIndexes: file_creds_accessbox_accessbox_proto_depIdxs, DependencyIndexes: file_accessbox_proto_depIdxs,
MessageInfos: file_creds_accessbox_accessbox_proto_msgTypes, MessageInfos: file_accessbox_proto_msgTypes,
}.Build() }.Build()
File_creds_accessbox_accessbox_proto = out.File File_accessbox_proto = out.File
file_creds_accessbox_accessbox_proto_rawDesc = nil file_accessbox_proto_rawDesc = nil
file_creds_accessbox_accessbox_proto_goTypes = nil file_accessbox_proto_goTypes = nil
file_creds_accessbox_accessbox_proto_depIdxs = nil file_accessbox_proto_depIdxs = nil
} }

View file

@ -12,8 +12,14 @@ message AccessBox {
bytes gatePublicKey = 2 [json_name = "gatePublicKey"]; bytes gatePublicKey = 2 [json_name = "gatePublicKey"];
} }
message ContainerPolicy {
string locationConstraint = 1;
bytes policy = 2;
}
bytes ownerPublicKey = 1 [json_name = "ownerPublicKey"]; bytes ownerPublicKey = 1 [json_name = "ownerPublicKey"];
repeated Gate gates = 2 [json_name = "gates"]; repeated Gate gates = 2 [json_name = "gates"];
repeated ContainerPolicy containerPolicy = 3 [json_name = "containerPolicy"];
} }
message Tokens { message Tokens {

View file

@ -20,7 +20,7 @@ import (
type ( type (
// Credentials is a bearer token get/put interface. // Credentials is a bearer token get/put interface.
Credentials interface { Credentials interface {
GetTokens(context.Context, *object.Address) (*accessbox.GateData, error) GetBox(context.Context, *object.Address) (*accessbox.Box, error)
Put(context.Context, *cid.ID, *owner.ID, *accessbox.AccessBox, ...*keys.PublicKey) (*object.Address, error) Put(context.Context, *cid.ID, *owner.ID, *accessbox.AccessBox, ...*keys.PublicKey) (*object.Address, error)
} }
@ -68,6 +68,15 @@ func (c *cred) GetTokens(ctx context.Context, address *object.Address) (*accessb
return box.GetTokens(c.key) return box.GetTokens(c.key)
} }
func (c *cred) GetBox(ctx context.Context, address *object.Address) (*accessbox.Box, error) {
box, err := c.getAccessBox(ctx, address)
if err != nil {
return nil, err
}
return box.GetBox(c.key)
}
func (c *cred) getAccessBox(ctx context.Context, address *object.Address) (*accessbox.AccessBox, error) { func (c *cred) getAccessBox(ctx context.Context, address *object.Address) (*accessbox.AccessBox, error) {
var ( var (
box accessbox.AccessBox box accessbox.AccessBox