[#405] English Check

Signed-off-by: Elizaveta Chichindaeva <elizaveta@nspcc.ru>
remotes/KirillovDenis/bugfix/681-fix_acl_parsing
Elizaveta Chichindaeva 2022-04-13 19:56:58 +03:00 committed by Alex Vanin
parent a0a04a73bd
commit bf38007692
42 changed files with 205 additions and 205 deletions

View File

@ -252,7 +252,7 @@ func hmacSHA256(key []byte, data []byte) []byte {
return hash.Sum(nil)
}
// MultipartFormValue get value by key from multipart form.
// MultipartFormValue gets value by key from multipart form.
func MultipartFormValue(r *http.Request, key string) string {
if r.MultipartForm == nil {
return ""

View File

@ -9,7 +9,7 @@ import (
)
type (
// AccessBoxCache stores access box by its address.
// AccessBoxCache stores an access box by its address.
AccessBoxCache struct {
cache gcache.Cache
}
@ -24,11 +24,11 @@ type (
const (
// DefaultAccessBoxCacheSize is a default maximum number of entries in cache.
DefaultAccessBoxCacheSize = 100
// DefaultAccessBoxCacheLifetime is a default lifetime of entries in cache.
// DefaultAccessBoxCacheLifetime is a default lifetime of entries in cache.
DefaultAccessBoxCacheLifetime = 10 * time.Minute
)
// DefaultAccessBoxConfig return new default cache expiration values.
// DefaultAccessBoxConfig returns new default cache expiration values.
func DefaultAccessBoxConfig() *Config {
return &Config{Size: DefaultAccessBoxCacheSize, Lifetime: DefaultAccessBoxCacheLifetime}
}
@ -40,7 +40,7 @@ func NewAccessBoxCache(config *Config) *AccessBoxCache {
return &AccessBoxCache{cache: gc}
}
// Get returns cached object.
// Get returns a cached object.
func (o *AccessBoxCache) Get(address *address.Address) *accessbox.Box {
entry, err := o.cache.Get(address.String())
if err != nil {

View File

@ -7,7 +7,7 @@ import (
"github.com/nspcc-dev/neofs-s3-gw/api/data"
)
// BucketCache contains cache with objects and lifetime of cache entries.
// BucketCache contains cache with objects and the lifetime of cache entries.
type BucketCache struct {
cache gcache.Cache
}
@ -15,11 +15,11 @@ type BucketCache struct {
const (
// DefaultBucketCacheSize is a default maximum number of entries in cache.
DefaultBucketCacheSize = 1e3
// DefaultBucketCacheLifetime is a default lifetime of entries in cache.
// DefaultBucketCacheLifetime is a default lifetime of entries in cache.
DefaultBucketCacheLifetime = time.Minute
)
// DefaultBucketConfig return new default cache expiration values.
// DefaultBucketConfig returns new default cache expiration values.
func DefaultBucketConfig() *Config {
return &Config{Size: DefaultBucketCacheSize, Lifetime: DefaultBucketCacheLifetime}
}
@ -30,7 +30,7 @@ func NewBucketCache(config *Config) *BucketCache {
return &BucketCache{cache: gc}
}
// Get returns cached object.
// Get returns a cached object.
func (o *BucketCache) Get(key string) *data.BucketInfo {
entry, err := o.cache.Get(key)
if err != nil {

10
api/cache/names.go vendored
View File

@ -7,8 +7,8 @@ import (
"github.com/nspcc-dev/neofs-sdk-go/object/address"
)
// ObjectsNameCache provides for lru cache for objects.
// This cache contains mapping nice name to object addresses.
// ObjectsNameCache provides lru cache for objects.
// This cache contains mapping nice names to object addresses.
// Key is bucketName+objectName.
type ObjectsNameCache struct {
cache gcache.Cache
@ -17,11 +17,11 @@ type ObjectsNameCache struct {
const (
// DefaultObjectsNameCacheSize is a default maximum number of entries in cache.
DefaultObjectsNameCacheSize = 1e4
// DefaultObjectsNameCacheLifetime is a default lifetime of entries in cache.
// DefaultObjectsNameCacheLifetime is a default lifetime of entries in cache.
DefaultObjectsNameCacheLifetime = time.Minute
)
// DefaultObjectsNameConfig return new default cache expiration values.
// DefaultObjectsNameConfig returns new default cache expiration values.
func DefaultObjectsNameConfig() *Config {
return &Config{Size: DefaultObjectsNameCacheSize, Lifetime: DefaultObjectsNameCacheLifetime}
}
@ -32,7 +32,7 @@ func NewObjectsNameCache(config *Config) *ObjectsNameCache {
return &ObjectsNameCache{cache: gc}
}
// Get returns cached object.
// Get returns a cached object.
func (o *ObjectsNameCache) Get(key string) *address.Address {
entry, err := o.cache.Get(key)
if err != nil {

View File

@ -16,11 +16,11 @@ type ObjectsCache struct {
const (
// DefaultObjectsCacheLifetime is a default lifetime of entries in objects' cache.
DefaultObjectsCacheLifetime = time.Minute * 5
// DefaultObjectsCacheSize is a default maximum number of entries in objects' in cache.
// DefaultObjectsCacheSize is a default maximum number of entries in objects' cache.
DefaultObjectsCacheSize = 1e6
)
// DefaultObjectsConfig return new default cache expiration values.
// DefaultObjectsConfig returns new default cache expiration values.
func DefaultObjectsConfig() *Config {
return &Config{Size: DefaultObjectsCacheSize, Lifetime: DefaultObjectsCacheLifetime}
}
@ -31,7 +31,7 @@ func New(config *Config) *ObjectsCache {
return &ObjectsCache{cache: gc}
}
// Get returns cached object.
// Get returns a cached object.
func (o *ObjectsCache) Get(address *address.Address) *object.Object {
entry, err := o.cache.Get(address.String())
if err != nil {

View File

@ -11,16 +11,16 @@ import (
)
/*
This is an implementation of a cache which keeps unsorted lists of objects' IDs (all versions)
This is an implementation of cache which keeps unsorted lists of objects' IDs (all versions)
for a specified bucket and a prefix.
The cache contains gcache whose entries have a key: ObjectsListKey struct and a value: list of ids.
After putting a record it lives for a while (default value is 60 seconds).
After putting a record, it lives for a while (default value is 60 seconds).
When we receive a request from the user we try to find the suitable and non-expired cache entry, go through the list
When we receive a request from a user, we try to find the suitable and non-expired cache entry, go through the list
and get ObjectInfos from common object cache or with a request to NeoFS.
When we put an object into a container we invalidate entries with prefixes that are prefixes of the object's name.
When we put an object into a container, we invalidate entries with prefixes that are prefixes of the object's name.
*/
type (
@ -43,18 +43,18 @@ const (
DefaultObjectsListCacheSize = 1e5
)
// DefaultObjectsListConfig return new default cache expiration values.
// DefaultObjectsListConfig returns new default cache expiration values.
func DefaultObjectsListConfig() *Config {
return &Config{Size: DefaultObjectsListCacheSize, Lifetime: DefaultObjectsListCacheLifetime}
}
// NewObjectsListCache is a constructor which creates an object of ListObjectsCache with given lifetime of entries.
// NewObjectsListCache is a constructor which creates an object of ListObjectsCache with the given lifetime of entries.
func NewObjectsListCache(config *Config) *ObjectsListCache {
gc := gcache.New(config.Size).LRU().Expiration(config.Lifetime).Build()
return &ObjectsListCache{cache: gc}
}
// Get return list of ObjectInfo.
// Get returns a list of ObjectInfo.
func (l *ObjectsListCache) Get(key ObjectsListKey) []oid.ID {
entry, err := l.cache.Get(key)
if err != nil {
@ -93,7 +93,7 @@ func (l *ObjectsListCache) CleanCacheEntriesContainingObject(objectName string,
}
}
// CreateObjectsListCacheKey returns ObjectsListKey with given CID and prefix.
// CreateObjectsListCacheKey returns ObjectsListKey with the given CID and prefix.
func CreateObjectsListCacheKey(cid *cid.ID, prefix string) ObjectsListKey {
p := ObjectsListKey{
cid: cid.String(),

6
api/cache/system.go vendored
View File

@ -17,11 +17,11 @@ type SystemCache struct {
const (
// DefaultSystemCacheSize is a default maximum number of entries in cache.
DefaultSystemCacheSize = 1e4
// DefaultSystemCacheLifetime is a default lifetime of entries in cache.
// DefaultSystemCacheLifetime is a default lifetime of entries in cache.
DefaultSystemCacheLifetime = 5 * time.Minute
)
// DefaultSystemConfig return new default cache expiration values.
// DefaultSystemConfig returns new default cache expiration values.
func DefaultSystemConfig() *Config {
return &Config{Size: DefaultSystemCacheSize, Lifetime: DefaultSystemCacheLifetime}
}
@ -32,7 +32,7 @@ func NewSystemCache(config *Config) *SystemCache {
return &SystemCache{cache: gc}
}
// GetObject returns cached object.
// GetObject returns a cached object.
func (o *SystemCache) GetObject(key string) *data.ObjectInfo {
entry, err := o.cache.Get(key)
if err != nil {

View File

@ -68,10 +68,10 @@ type (
}
)
// SettingsObjectName is system name for bucket settings file.
// SettingsObjectName is a system name for a bucket settings file.
func (b *BucketInfo) SettingsObjectName() string { return bktSettingsObject }
// CORSObjectName returns system name for bucket CORS configuration file.
// CORSObjectName returns a system name for a bucket CORS configuration file.
func (b *BucketInfo) CORSObjectName() string { return bktCORSConfigurationObject }
func (b *BucketInfo) NotificationConfigurationObjectName() string {
@ -82,7 +82,7 @@ func (b *BucketInfo) NotificationConfigurationObjectName() string {
func (o *ObjectInfo) Version() string { return o.ID.String() }
// NullableVersion returns object version from ObjectInfo.
// Return "null" if "S3-Versions-unversioned" header present.
// Return "null" if "S3-Versions-unversioned" header is present.
func (o *ObjectInfo) NullableVersion() string {
if _, ok := o.Headers["S3-Versions-unversioned"]; ok {
return "null"
@ -102,11 +102,11 @@ func (o *ObjectInfo) Address() *address.Address {
return addr
}
// TagsObject returns name of system object for tags.
// TagsObject returns the name of a system object for tags.
func (o *ObjectInfo) TagsObject() string { return ".tagset." + o.Name + "." + o.Version() }
// LegalHoldObject returns name of system object for lock object.
// LegalHoldObject returns the name of a system object for a lock object.
func (o *ObjectInfo) LegalHoldObject() string { return ".lock." + o.Name + "." + o.Version() }
// RetentionObject returns name of system object for retention lock object.
// RetentionObject returns the name of a system object for a retention lock object.
func (o *ObjectInfo) RetentionObject() string { return ".retention." + o.Name + "." + o.Version() }

View File

@ -28,7 +28,7 @@ type (
Value string `xml:"Value" json:"Value"`
}
// TopicConfiguration and LambdaFunctionConfiguration -- we don't support these configurations
// TopicConfiguration and LambdaFunctionConfiguration -- we don't support these configurations,
// but we need them to detect in notification configurations in requests.
TopicConfiguration struct{}
LambdaFunctionConfiguration struct{}

View File

@ -6,7 +6,7 @@ import (
)
type (
// ErrorCode type of error status.
// ErrorCode type of an error status.
ErrorCode int
errorCodeMap map[ErrorCode]Error
@ -20,7 +20,7 @@ type (
}
)
// Error codes, non exhaustive list - http://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html
// Error codes, non exhaustive list -- http://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html
const (
_ ErrorCode = iota
ErrAccessDenied
@ -273,7 +273,7 @@ const (
)
// error code to Error structure, these fields carry respective
// descriptions for all the error responses.
// descriptions for all error responses.
var errorCodes = errorCodeMap{
ErrInvalidCopyDest: {
ErrCode: ErrInvalidCopyDest,
@ -768,7 +768,7 @@ var errorCodes = errorCodeMap{
HTTPStatusCode: http.StatusBadRequest,
},
// FIXME: Actual XML error response also contains the header which missed in list of signed header parameters.
// FIXME: Actual XML error response also contains the header which is missed in the list of signed header parameters.
ErrUnsignedHeaders: {
ErrCode: ErrUnsignedHeaders,
Code: "AccessDenied",
@ -1663,7 +1663,7 @@ var errorCodes = errorCodeMap{
// Add your error structure here.
}
// IsS3Error check if the provided error is a specific s3 error.
// IsS3Error checks if the provided error is a specific s3 error.
func IsS3Error(err error, code ErrorCode) bool {
e, ok := err.(Error)
return ok && e.ErrCode == code
@ -1688,7 +1688,7 @@ func (e Error) Error() string {
return fmt.Sprintf("%s: %d => %s", e.Code, e.HTTPStatusCode, e.Description)
}
// GetAPIError provides API Error for input API error code.
// GetAPIError provides API Error for an input API error code.
func GetAPIError(code ErrorCode) Error {
if apiErr, ok := errorCodes[code]; ok {
return apiErr
@ -1696,12 +1696,12 @@ func GetAPIError(code ErrorCode) Error {
return errorCodes.toAPIErr(ErrInternalError)
}
// GetAPIErrorWithError provides API Error with additional error message for input API error code.
// GetAPIErrorWithError provides API Error with additional error message for an input API error code.
func GetAPIErrorWithError(code ErrorCode, err error) Error {
return errorCodes.toAPIErrWithErr(code, err)
}
// ObjectError - error that linked to specific object.
// ObjectError -- error that is linked to a specific object.
type ObjectError struct {
Err error
Object string
@ -1712,7 +1712,7 @@ func (e ObjectError) Error() string {
return fmt.Sprintf("%s (%s:%s)", e.Err, e.Object, e.Version)
}
// ObjectVersion get "object:version" string.
// ObjectVersion gets "object:version" string.
func (e ObjectError) ObjectVersion() string {
return e.Object + ":" + e.Version
}

View File

@ -357,7 +357,7 @@ func checkOwner(info *data.BucketInfo, owner string) error {
return nil
}
// maybe need to convert owner to appropriate format
// may need to convert owner to appropriate format
if info.Owner.String() != owner {
return errors.GetAPIError(errors.ErrAccessDenied)
}

View File

@ -16,14 +16,14 @@ type (
cfg *Config
}
// Config contains data which handler need to keep.
// Config contains data which handler needs to keep.
Config struct {
DefaultPolicy *netmap.PlacementPolicy
DefaultMaxAge int
}
)
// DefaultPolicy is a default policy of placing container in NeoFS if it's not set at the request.
// DefaultPolicy is a default policy of placing containers in NeoFS if it's not set at the request.
const DefaultPolicy = "REP 3"
var _ api.Handler = (*handler)(nil)

View File

@ -20,7 +20,7 @@ type copyObjectArgs struct {
const replaceMetadataDirective = "REPLACE"
// path2BucketObject returns bucket and object.
// path2BucketObject returns a bucket and an object.
func path2BucketObject(path string) (bucket, prefix string) {
path = strings.TrimPrefix(path, api.SlashSeparator)
m := strings.Index(path, api.SlashSeparator)

View File

@ -11,7 +11,7 @@ import (
)
const (
// DefaultMaxAge -- default value of Access-Control-Max-Age if this value is not set in a rule.
// DefaultMaxAge is a default value of Access-Control-Max-Age if this value is not set in a rule.
DefaultMaxAge = 600
wildcard = "*"
)

View File

@ -15,7 +15,7 @@ import (
"go.uber.org/zap/zapcore"
)
// DeleteObjectsRequest - xml carrying the object key names which needs to be deleted.
// DeleteObjectsRequest -- xml carrying the object key names which should be deleted.
type DeleteObjectsRequest struct {
// Element to enable quiet mode for the request
Quiet bool
@ -23,13 +23,13 @@ type DeleteObjectsRequest struct {
Objects []ObjectIdentifier `xml:"Object"`
}
// ObjectIdentifier carries key name for the object to delete.
// ObjectIdentifier carries the key name for the object to delete.
type ObjectIdentifier struct {
ObjectName string `xml:"Key"`
VersionID string `xml:"VersionId,omitempty"`
}
// DeletedObject carries key name for the object to delete.
// DeletedObject carries the key name for the object to delete.
type DeletedObject struct {
ObjectIdentifier
DeleteMarker bool `xml:"DeleteMarker,omitempty"`
@ -144,7 +144,7 @@ func (h *handler) DeleteObjectHandler(w http.ResponseWriter, r *http.Request) {
func (h *handler) DeleteMultipleObjectsHandler(w http.ResponseWriter, r *http.Request) {
reqInfo := api.GetReqInfo(r.Context())
// Content-Md5 is requied should be set
// Content-Md5 is required and should be set
// http://docs.aws.amazon.com/AmazonS3/latest/API/multiobjectdeleteapi.html
if _, ok := r.Header[api.ContentMD5]; !ok {
h.logAndSendError(w, "missing Content-MD5", reqInfo, errors.GetAPIError(errors.ErrMissingContentMD5))

View File

@ -480,7 +480,7 @@ func TestObjectLegalHold(t *testing.T) {
hc.Handler().GetObjectLegalHoldHandler(w, r)
assertLegalHold(t, w, legalHoldOn)
// to make sure put hold is idempotent operation
// to make sure put hold is an idempotent operation
w, r = prepareTestRequest(t, bktName, objName, &data.LegalHold{Status: legalHoldOn})
hc.Handler().PutObjectLegalHoldHandler(w, r)
require.Equal(t, http.StatusOK, w.Code)
@ -493,7 +493,7 @@ func TestObjectLegalHold(t *testing.T) {
hc.Handler().GetObjectLegalHoldHandler(w, r)
assertLegalHold(t, w, legalHoldOff)
// to make sure put hold is idempotent operation
// to make sure put hold is an idempotent operation
w, r = prepareTestRequest(t, bktName, objName, &data.LegalHold{Status: legalHoldOff})
hc.Handler().PutObjectLegalHoldHandler(w, r)
require.Equal(t, http.StatusOK, w.Code)

View File

@ -2,7 +2,7 @@ package handler
import "encoding/xml"
// ListBucketsResponse - format for list buckets response.
// ListBucketsResponse -- format for list buckets response.
type ListBucketsResponse struct {
XMLName xml.Name `xml:"http://s3.amazonaws.com/doc/2006-03-01/ ListAllMyBucketsResult" json:"-"`
@ -85,7 +85,7 @@ func NewGrantee(t GranteeType) *Grantee {
}
}
// Owner - bucket owner/principal.
// Owner -- bucket owner/principal.
type Owner struct {
ID string
DisplayName string
@ -106,7 +106,7 @@ type Object struct {
// Owner of the object.
Owner *Owner `xml:"Owner,omitempty"`
// The class of storage used to store the object.
// Class of storage used to store the object.
StorageClass string `xml:"StorageClass,omitempty"`
}
@ -134,7 +134,7 @@ type DeleteMarkerEntry struct {
// StringMap is a map[string]string.
type StringMap map[string]string
// LocationResponse - format for location response.
// LocationResponse -- format for location response.
type LocationResponse struct {
XMLName xml.Name `xml:"http://s3.amazonaws.com/doc/2006-03-01/ LocationConstraint" json:"-"`
Location string `xml:",chardata"`
@ -182,13 +182,13 @@ type PostResponse struct {
ETag string `xml:"Etag"`
}
// Tag is AWS key-value tag.
// Tag is an AWS key-value tag.
type Tag struct {
Key string
Value string
}
// MarshalXML - StringMap marshals into XML.
// MarshalXML -- StringMap marshals into XML.
func (s StringMap) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
tokens := []xml.Token{start}

View File

@ -28,7 +28,7 @@ func shouldEscape(c byte) bool {
return true
}
// s3URLEncode is based on url.QueryEscape() code,
// s3URLEncode is based on url.QueryEscape() code
// while considering some S3 exceptions.
func s3URLEncode(s string, mode encoding) string {
spaceCount, hexCount := 0, 0

View File

@ -270,8 +270,8 @@ func DefaultCachesConfigs() *CachesConfig {
}
}
// NewLayer creates instance of layer. It checks credentials
// and establishes gRPC connection with node.
// NewLayer creates an instance of a layer. It checks credentials
// and establishes gRPC connection with the node.
func NewLayer(log *zap.Logger, neoFS neofs.NeoFS, config *Config) Client {
return &layer{
neoFS: neoFS,
@ -307,7 +307,7 @@ func (n *layer) IsNotificationEnabled() bool {
return n.ncontroller != nil
}
// IsAuthenticatedRequest check if access box exists in current request.
// IsAuthenticatedRequest checks if access box exists in the current request.
func IsAuthenticatedRequest(ctx context.Context) bool {
_, ok := ctx.Value(api.BoxData).(*accessbox.Box)
return ok
@ -364,12 +364,12 @@ func (n *layer) GetBucketACL(ctx context.Context, bktInfo *data.BucketInfo) (*Bu
}, nil
}
// PutBucketACL put bucket acl by name.
// PutBucketACL puts bucket acl by name.
func (n *layer) PutBucketACL(ctx context.Context, param *PutBucketACLParams) error {
return n.setContainerEACLTable(ctx, param.BktInfo.CID, param.EACL)
}
// ListBuckets returns all user containers. Name of the bucket is a container
// ListBuckets returns all user containers. The name of the bucket is a container
// id. Timestamp is omitted since it is not saved in neofs container.
func (n *layer) ListBuckets(ctx context.Context) ([]*data.BucketInfo, error) {
return n.containerList(ctx)
@ -532,7 +532,7 @@ func (n *layer) CopyObject(ctx context.Context, p *CopyObjectParams) (*data.Obje
})
}
// DeleteObject removes all objects with passed nice name.
// DeleteObject removes all objects with the passed nice name.
func (n *layer) deleteObject(ctx context.Context, bkt *data.BucketInfo, settings *data.BucketSettings, obj *VersionedObject) *VersionedObject {
var (
err error

View File

@ -255,7 +255,7 @@ func (n *layer) CompleteMultipartUpload(ctx context.Context, p *CompleteMultipar
zap.String("uploadID", p.Info.UploadID),
zap.String("uploadKey", p.Info.Key),
)
// we return InternalError because if we are here it means we've checked InitPart before in handler and
// we return InternalError because if we are here it means we've checked InitPart in handler before and
// received successful result, it's strange we didn't get the InitPart again
return nil, errors.GetAPIError(errors.ErrInternalError)
}
@ -284,7 +284,7 @@ func (n *layer) CompleteMultipartUpload(ctx context.Context, p *CompleteMultipar
initMetadata[api.ContentType] = objects[0].ContentType
}
/* We will keep "S3-Upload-Id" attribute in completed object to determine is it "common" object or completed object.
/* We will keep "S3-Upload-Id" attribute in a completed object to determine if it is a "common" object or a completed object.
We will need to differ these objects if something goes wrong during completing multipart upload.
I.e. we had completed the object but didn't put tagging/acl for some reason */
delete(initMetadata, UploadPartNumberAttributeName)

View File

@ -57,7 +57,7 @@ type PrmObjectSelect struct {
// Container to select the objects from.
Container cid.ID
// Key-value object attribute which should exactly be
// Key-value object attribute which should be
// presented in selected objects. Optional, empty key means any.
ExactAttribute [2]string
@ -141,53 +141,53 @@ var ErrAccessDenied = errors.New("access denied")
// NeoFS represents virtual connection to NeoFS network.
type NeoFS interface {
// CreateContainer creates and saves parameterized container in NeoFS.
// It sets 'Timestamp' attribute to current time.
// Returns ID of the saved container.
// It sets 'Timestamp' attribute to the current time.
// It returns the ID of the saved container.
//
// Returns exactly one non-nil value. Returns any error encountered which
// prevented the container to be created.
// It returns exactly one non-nil value. It returns any error encountered which
// prevented the container from being created.
CreateContainer(context.Context, PrmContainerCreate) (*cid.ID, error)
// Container reads container from NeoFS by ID.
// Container reads a container from NeoFS by ID.
//
// Returns exactly one non-nil value. Returns any error encountered which
// prevented the container to be read.
// It returns exactly one non-nil value. It returns any error encountered which
// prevented the container from being read.
Container(context.Context, cid.ID) (*container.Container, error)
// UserContainers reads list of the containers owned by specified user.
// UserContainers reads a list of the containers owned by the specified user.
//
// Returns exactly one non-nil value. Returns any error encountered which
// prevented the containers to be listed.
// It returns exactly one non-nil value. It returns any error encountered which
// prevented the containers from being listed.
UserContainers(context.Context, owner.ID) ([]cid.ID, error)
// SetContainerEACL saves eACL table of the container in NeoFS.
// SetContainerEACL saves the eACL table of the container in NeoFS.
//
// Returns any error encountered which prevented the eACL to be saved.
// It returns any error encountered which prevented the eACL from being saved.
SetContainerEACL(context.Context, eacl.Table) error
// ContainerEACL reads container eACL from NeoFS by container ID.
// ContainerEACL reads the container eACL from NeoFS by the container ID.
//
// Returns exactly one non-nil value. Returns any error encountered which
// prevented the eACL to be read.
// It returns exactly one non-nil value. It returns any error encountered which
// prevented the eACL from being read.
ContainerEACL(context.Context, cid.ID) (*eacl.Table, error)
// DeleteContainer marks the container to be removed from NeoFS by ID.
// Request is sent within session if the session token is specified.
// Successful return does not guarantee the actual removal.
// Successful return does not guarantee actual removal.
//
// Returns any error encountered which prevented the removal request to be sent.
// It returns any error encountered which prevented the removal request from being sent.
DeleteContainer(context.Context, cid.ID, *session.Token) error
// SelectObjects perform object selection from the NeoFS container according
// to specified parameters. Selects user objects only.
// SelectObjects performs object selection from the NeoFS container according
// to the specified parameters. It selects user's objects only.
//
// Returns ErrAccessDenied on selection access violation.
// It returns ErrAccessDenied on selection access violation.
//
// Returns exactly one non-nil value. Returns any error encountered which
// prevented the objects to be selected.
// It returns exactly one non-nil value. It returns any error encountered which
// prevented the objects from being selected.
SelectObjects(context.Context, PrmObjectSelect) ([]oid.ID, error)
// ReadObject reads part of the object from the NeoFS container by identifier.
// ReadObject reads a part of the object from the NeoFS container by identifier.
// Exact part is returned according to the parameters:
// * with header only: empty payload (both in-mem and reader parts are nil);
// * with payload only: header is nil (zero range means full payload);
@ -197,37 +197,37 @@ type NeoFS interface {
//
// Payload reader should be closed if it is no longer needed.
//
// Returns ErrAccessDenied on read access violation.
// It returns ErrAccessDenied on read access violation.
//
// Returns exactly one non-nil value. Returns any error encountered which
// prevented the object header to be read.
// It returns exactly one non-nil value. It returns any error encountered which
// prevented the object header from being read.
ReadObject(context.Context, PrmObjectRead) (*ObjectPart, error)
// CreateObject creates and saves parameterized object in the NeoFS container.
// It sets 'Timestamp' attribute to current time.
// Returns ID of the saved object.
// CreateObject creates and saves a parameterized object in the NeoFS container.
// It sets 'Timestamp' attribute to the current time.
// It returns the ID of the saved object.
//
// Creation time should be written into object (UTC).
// Creation time should be written into the object (UTC).
//
// Returns ErrAccessDenied on write access violation.
// It returns ErrAccessDenied on write access violation.
//
// Returns exactly one non-nil value. Returns any error encountered which
// prevented the container to be created.
// It returns exactly one non-nil value. It returns any error encountered which
// prevented the container from being created.
CreateObject(context.Context, PrmObjectCreate) (*oid.ID, error)
// DeleteObject marks the object to be removed from the NeoFS container by identifier.
// Successful return does not guarantee the actual removal.
// Successful return does not guarantee actual removal.
//
// Returns ErrAccessDenied on remove access violation.
// It returns ErrAccessDenied on remove access violation.
//
// Returns any error encountered which prevented the removal request to be sent.
// It returns any error encountered which prevented the removal request from being sent.
DeleteObject(context.Context, PrmObjectDelete) error
// TimeToEpoch compute current epoch and epoch that corresponds provided time.
// TimeToEpoch computes current epoch and the epoch that corresponds to the provided time.
// Note:
// * time must be in the future
// * time will be ceil rounded to match epoch
//
// Returns any error encountered which prevented computing epochs.
// It returns any error encountered which prevented computing epochs.
TimeToEpoch(context.Context, time.Time) (uint64, uint64, error)
}

View File

@ -210,7 +210,7 @@ func (n *layer) SendNotifications(ctx context.Context, p *SendNotificationParams
return n.ncontroller.SendNotifications(topics, p)
}
// checkBucketConfiguration checks notification configuration and generates ID for configurations with empty ids.
// checkBucketConfiguration checks notification configuration and generates an ID for configurations with empty ids.
func (n *layer) checkBucketConfiguration(conf *data.NotificationConfiguration, r *api.ReqInfo) (completed bool, err error) {
if conf == nil {
return
@ -248,7 +248,7 @@ func filterSubjects(conf *data.NotificationConfiguration, eventType, objName str
for _, t := range conf.QueueConfigurations {
event := false
for _, e := range t.Events {
// the second condition is comparison with events ending with *:
// the second condition is comparison with the events ending with *:
// s3:ObjectCreated:*, s3:ObjectRemoved:* etc without the last char
if eventType == e || strings.HasPrefix(eventType, e[:len(e)-1]) {
event = true

View File

@ -40,7 +40,7 @@ type (
IsLatest bool
}
// ListObjectVersionsInfo stores info and list of objects' versions.
// ListObjectVersionsInfo stores info and list of objects versions.
ListObjectVersionsInfo struct {
CommonPrefixes []string
IsTruncated bool
@ -138,7 +138,7 @@ func filenameFromObject(o *object.Object) string {
return name
}
// NameFromString splits name into base file name and directory path.
// NameFromString splits name into a base file name and a directory path.
func NameFromString(name string) (string, string) {
ind := strings.LastIndex(name, PathSeparator)
return name[ind+1:], name[:ind+1]

View File

@ -8,7 +8,7 @@ import (
)
type (
// MaxClients provides HTTP handler wrapper with client limit.
// MaxClients provides HTTP handler wrapper with the client limit.
MaxClients interface {
Handle(http.HandlerFunc) http.HandlerFunc
}
@ -22,7 +22,7 @@ type (
const defaultRequestDeadline = time.Second * 30
// NewMaxClientsMiddleware returns MaxClients interface with handler wrapper based on
// provided count and timeout limits.
// the provided count and the timeout limits.
func NewMaxClientsMiddleware(count int, timeout time.Duration) MaxClients {
if timeout <= 0 {
timeout = defaultRequestDeadline

View File

@ -13,7 +13,7 @@ import (
type (
// HTTPAPIStats holds statistics information about
// a given API in the requests.
// the API given in the requests.
HTTPAPIStats struct {
apiStats map[string]int
sync.RWMutex
@ -64,7 +64,7 @@ var (
)
// Collects HTTP metrics for NeoFS S3 Gate in Prometheus specific format
// and sends to given channel.
// and sends to the given channel.
func collectHTTPMetrics(ch chan<- prometheus.Metric) {
for api, value := range httpStatsMetric.currentS3Requests.Load() {
ch <- prometheus.MustNewConstMetric(
@ -122,7 +122,7 @@ func APIStats(api string, f http.HandlerFunc) http.HandlerFunc {
f.ServeHTTP(statsWriter, r)
// Time duration in secs since the call started.
// We don't need to do nanosecond precision in this
// We don't need to do nanosecond precision here
// simply for the fact that it is not human readable.
durationSecs := time.Since(statsWriter.startTime).Seconds()
@ -201,7 +201,7 @@ func (st *HTTPStats) updateStats(api string, w http.ResponseWriter, r *http.Requ
}
}
// WriteHeader - writes http status code.
// WriteHeader -- writes http status code.
func (w *responseWrapper) WriteHeader(code int) {
w.Do(func() {
w.statusCode = code
@ -209,7 +209,7 @@ func (w *responseWrapper) WriteHeader(code int) {
})
}
// Flush - Calls the underlying Flush.
// Flush -- calls the underlying Flush.
func (w *responseWrapper) Flush() {
if f, ok := w.ResponseWriter.(http.Flusher); ok {
f.Flush()

View File

@ -13,7 +13,7 @@ import (
)
type (
// KeyVal - appended to ReqInfo.Tags.
// KeyVal -- appended to ReqInfo.Tags.
KeyVal struct {
Key string
Val string
@ -27,7 +27,7 @@ type (
UserAgent string // User Agent
DeploymentID string // random generated s3-deployment-id
RequestID string // x-amz-request-id
API string // API name - GetObject PutObject NewMultipartUpload etc.
API string // API name -- GetObject PutObject NewMultipartUpload etc.
BucketName string // Bucket name
ObjectName string // Object name
URL *url.URL // Request url
@ -64,15 +64,15 @@ var (
)
// GetSourceIP retrieves the IP from the X-Forwarded-For, X-Real-IP and RFC7239
// Forwarded headers (in that order), falls back to r.RemoteAddr when all
// Forwarded headers (in that order), falls back to r.RemoteAddr when everything
// else fails.
func GetSourceIP(r *http.Request) string {
var addr string
if fwd := r.Header.Get(xForwardedFor); fwd != "" {
// Only grab the first (client) address. Note that '192.168.0.1,
// Only grabs the first (client) address. Note that '192.168.0.1,
// 10.1.1.1' is a valid key for X-Forwarded-For where addresses after
// the first may represent forwarding proxies earlier in the chain.
// the first one may represent forwarding proxies earlier in the chain.
s := strings.Index(fwd, ", ")
if s == -1 {
s = len(fwd)
@ -141,7 +141,7 @@ func NewReqInfo(w http.ResponseWriter, r *http.Request, req ObjectRequest) *ReqI
}
}
// AppendTags - appends key/val to ReqInfo.tags.
// AppendTags -- appends key/val to ReqInfo.tags.
func (r *ReqInfo) AppendTags(key string, val string) *ReqInfo {
if r == nil {
return nil
@ -152,14 +152,14 @@ func (r *ReqInfo) AppendTags(key string, val string) *ReqInfo {
return r
}
// SetTags - sets key/val to ReqInfo.tags.
// SetTags -- sets key/val to ReqInfo.tags.
func (r *ReqInfo) SetTags(key string, val string) *ReqInfo {
if r == nil {
return nil
}
r.Lock()
defer r.Unlock()
// Search of tag key already exists in tags
// Search for a tag key already existing in tags
var updated bool
for _, tag := range r.tags {
if tag.Key == key {
@ -175,7 +175,7 @@ func (r *ReqInfo) SetTags(key string, val string) *ReqInfo {
return r
}
// GetTags - returns the user defined tags.
// GetTags -- returns the user defined tags.
func (r *ReqInfo) GetTags() []KeyVal {
if r == nil {
return nil

View File

@ -18,8 +18,8 @@ const (
type NeoFS interface {
// SystemDNS reads system DNS network parameters of the NeoFS.
//
// Returns exactly on non-zero value. Returns any error encountered
// which prevented the parameter to be read.
// It returns exactly on non-zero value. It returns any error encountered
// which prevented the parameter from being read.
SystemDNS(context.Context) (string, error)
}

View File

@ -13,7 +13,7 @@ import (
)
type (
// ErrorResponse - error response format.
// ErrorResponse -- error response format.
ErrorResponse struct {
XMLName xml.Name `xml:"Error" json:"-"`
Code string
@ -24,7 +24,7 @@ type (
RequestID string `xml:"RequestId" json:"RequestId"`
HostID string `xml:"HostId" json:"HostId"`
// Region where the bucket is located. This header is returned
// The region where the bucket is located. This header is returned
// only in HEAD bucket and ListObjects response.
Region string `xml:"Region,omitempty" json:"Region,omitempty"`
@ -126,7 +126,7 @@ func WriteErrorResponse(w http.ResponseWriter, reqInfo *ReqInfo, err error) {
}
}
// Generate error response.
// Generates error response.
errorResponse := getAPIErrorResponse(reqInfo, err)
encodedErrorResponse := EncodeResponse(errorResponse)
WriteResponse(w, code, encodedErrorResponse, MimeXML)
@ -152,7 +152,7 @@ func setCommonHeaders(w http.ResponseWriter) {
}
// removeSensitiveHeaders removes confidential encryption
// information - e.g. the SSE-C key - from the HTTP headers.
// information -- e.g. the SSE-C key -- from the HTTP headers.
// It has the same semantics as RemoveSensitiveEntries.
func removeSensitiveHeaders(h http.Header) {
h.Del(hdrSSECustomerKey)
@ -212,7 +212,7 @@ func WriteSuccessResponseHeadersOnly(w http.ResponseWriter) {
WriteResponse(w, http.StatusOK, nil, MimeNone)
}
// Error - Returns S3 error string.
// Error -- Returns S3 error string.
func (e ErrorResponse) Error() string {
if e.Message == "" {
msg, ok := s3ErrorResponseMap[e.Code]
@ -225,7 +225,7 @@ func (e ErrorResponse) Error() string {
}
// getErrorResponse gets in standard error and resource value and
// provides a encodable populated response values.
// provides an encodable populated response values.
func getAPIErrorResponse(info *ReqInfo, err error) ErrorResponse {
code := "InternalError"
desc := err.Error()

View File

@ -83,7 +83,7 @@ type (
ListMultipartUploadsHandler(http.ResponseWriter, *http.Request)
}
// mimeType represents various MIME type used API responses.
// mimeType represents various MIME types used in API responses.
mimeType string
logResponseWriter struct {
@ -95,7 +95,7 @@ type (
)
const (
// SlashSeparator - slash separator.
// SlashSeparator -- slash separator.
SlashSeparator = "/"
// MimeNone means no response type.
@ -172,7 +172,7 @@ func logErrorResponse(l *zap.Logger) mux.MiddlewareFunc {
}
}
// GetRequestID returns request ID from response writer or context.
// GetRequestID returns the request ID from the response writer or the context.
func GetRequestID(v interface{}) string {
switch t := v.(type) {
case context.Context:
@ -244,11 +244,11 @@ func Attach(r *mux.Router, domains []string, m MaxClients, h Handler, center aut
bucket.Methods(http.MethodGet).HandlerFunc(
m.Handle(metrics.APIStats("listmultipartuploads", h.ListMultipartUploadsHandler))).Queries("uploads", "").
Name("ListMultipartUploads")
// GetObjectACL - this is a dummy call.
// GetObjectACL -- this is a dummy call.
bucket.Methods(http.MethodGet).Path("/{object:.+}").HandlerFunc(
m.Handle(metrics.APIStats("getobjectacl", h.GetObjectACLHandler))).Queries("acl", "").
Name("GetObjectACL")
// PutObjectACL - this is a dummy call.
// PutObjectACL -- this is a dummy call.
bucket.Methods(http.MethodPut).Path("/{object:.+}").HandlerFunc(
m.Handle(metrics.APIStats("putobjectacl", h.PutObjectACLHandler))).Queries("acl", "").
Name("PutObjectACL")
@ -336,27 +336,27 @@ func Attach(r *mux.Router, domains []string, m MaxClients, h Handler, center aut
bucket.Methods(http.MethodPut).HandlerFunc(
m.Handle(metrics.APIStats("putbucketacl", h.PutBucketACLHandler))).Queries("acl", "").
Name("PutBucketACL")
// GetBucketWebsiteHandler - this is a dummy call.
// GetBucketWebsiteHandler -- this is a dummy call.
bucket.Methods(http.MethodGet).HandlerFunc(
m.Handle(metrics.APIStats("getbucketwebsite", h.GetBucketWebsiteHandler))).Queries("website", "").
Name("GetBucketWebsite")
// GetBucketAccelerateHandler - this is a dummy call.
// GetBucketAccelerateHandler -- this is a dummy call.
bucket.Methods(http.MethodGet).HandlerFunc(
m.Handle(metrics.APIStats("getbucketaccelerate", h.GetBucketAccelerateHandler))).Queries("accelerate", "").
Name("GetBucketAccelerate")
// GetBucketRequestPaymentHandler - this is a dummy call.
// GetBucketRequestPaymentHandler -- this is a dummy call.
bucket.Methods(http.MethodGet).HandlerFunc(
m.Handle(metrics.APIStats("getbucketrequestpayment", h.GetBucketRequestPaymentHandler))).Queries("requestPayment", "").
Name("GetBucketRequestPayment")
// GetBucketLoggingHandler - this is a dummy call.
// GetBucketLoggingHandler -- this is a dummy call.
bucket.Methods(http.MethodGet).HandlerFunc(
m.Handle(metrics.APIStats("getbucketlogging", h.GetBucketLoggingHandler))).Queries("logging", "").
Name("GetBucketLogging")
// GetBucketLifecycleHandler - this is a dummy call.
// GetBucketLifecycleHandler -- this is a dummy call.
bucket.Methods(http.MethodGet).HandlerFunc(
m.Handle(metrics.APIStats("getbucketlifecycle", h.GetBucketLifecycleHandler))).Queries("lifecycle", "").
Name("GetBucketLifecycle")
// GetBucketReplicationHandler - this is a dummy call.
// GetBucketReplicationHandler -- this is a dummy call.
bucket.Methods(http.MethodGet).HandlerFunc(
m.Handle(metrics.APIStats("getbucketreplication", h.GetBucketReplicationHandler))).Queries("replication", "").
Name("GetBucketReplication")
@ -480,7 +480,7 @@ func Attach(r *mux.Router, domains []string, m MaxClients, h Handler, center aut
m.Handle(metrics.APIStats("listbuckets", h.ListBucketsHandler))).
Name("ListBuckets")
// If none of the routes match add default error handler routes
// If none of the routes match, add default error handler routes
api.NotFoundHandler = metrics.APIStats("notfound", errorResponseHandler)
api.MethodNotAllowedHandler = metrics.APIStats("methodnotallowed", errorResponseHandler)
}

View File

@ -54,26 +54,26 @@ type NeoFS interface {
tokens.NeoFS
// ContainerExists checks container presence in NeoFS by identifier.
// Returns nil iff container exists.
// Returns nil if container exists.
ContainerExists(context.Context, cid.ID) error
// CreateContainer creates and saves parameterized container in NeoFS.
// It sets 'Timestamp' attribute to current time.
// Returns ID of the saved container.
// It sets 'Timestamp' attribute to the current time.
// It returns the ID of the saved container.
//
// The container must be private with GET access of OTHERS group.
// The container must be private with GET access for OTHERS group.
// Creation time should also be stamped.
//
// Returns exactly one non-nil value. Returns any error encountered which
// prevented the container to be created.
// It returns exactly one non-nil value. It returns any error encountered which
// prevented the container from being created.
CreateContainer(context.Context, PrmContainerCreate) (*cid.ID, error)
// TimeToEpoch compute current epoch and epoch that corresponds provided time.
// TimeToEpoch computes the current epoch and the epoch that corresponds to the provided time.
// Note:
// * time must be in the future
// * time will be ceil rounded to match epoch
//
// Returns any error encountered which prevented computing epochs.
// It returns any error encountered which prevented computing epochs.
TimeToEpoch(context.Context, time.Time) (uint64, uint64, error)
}
@ -119,7 +119,7 @@ type (
}
)
// lifetimeOptions holds NeoFS epochs, iat -- epoch, which a token was issued at, exp -- epoch, when the token expires.
// lifetimeOptions holds NeoFS epochs, iat -- epoch which the token was issued at, exp -- epoch when the token expires.
type lifetimeOptions struct {
Iat uint64
Exp uint64
@ -141,7 +141,7 @@ type (
func (a *Agent) checkContainer(ctx context.Context, opts ContainerOptions, idOwner *owner.ID) (*cid.ID, error) {
if opts.ID != nil {
// check that container exists
// check that the container exists
return opts.ID, a.neoFS.ContainerExists(ctx, *opts.ID)
}

View File

@ -345,7 +345,7 @@ func getJSONRules(val string) ([]byte, error) {
}
// getSessionRules reads json session rules.
// Returns true if rules must be skipped.
// It returns true if rules must be skipped.
func getSessionRules(r string) ([]byte, bool, error) {
if r == "none" {
return nil, true, nil

View File

@ -194,11 +194,11 @@ func newApp(ctx context.Context, l *zap.Logger, v *viper.Viper) *App {
}
}
// Wait waits for application to finish.
// Wait waits for an application to finish.
//
// Pre-logs a message about the launch of the application mentioning its
// version (version.Version) and name (neofs-s3-gw). At the end writes to the
// log about the stop.
// version (version.Version) and its name (neofs-s3-gw). At the end, it writes
// about the stop to the log.
func (a *App) Wait() {
a.log.Info("application started",
zap.String("name", "neofs-s3-gw"),

View File

@ -99,7 +99,7 @@ const ( // Settings.
cmdVersion = "version"
cmdConfig = "config"
// envPrefix is environment variables prefix used for configuration.
// envPrefix is an environment variables prefix used for configuration.
envPrefix = "S3_GW"
)

View File

@ -11,7 +11,7 @@ import (
"go.uber.org/zap/zapcore"
)
// newLogger constructs a zap.Logger instance for current application.
// newLogger constructs a zap.Logger instance for the current application.
// Panics on failure.
//
// Logger is built from zap's production logging configuration with:

View File

@ -40,22 +40,22 @@ type GateData struct {
GateKey *keys.PublicKey
}
// NewGateData returns GateData from provided bearer token and public gate key.
// NewGateData returns GateData from the provided bearer token and the public gate key.
func NewGateData(gateKey *keys.PublicKey, bearerTkn *token.BearerToken) *GateData {
return &GateData{GateKey: gateKey, BearerToken: bearerTkn}
}
// SessionTokenForPut return the first suitable container session context for PUT operation.
// SessionTokenForPut returns the first suitable container session context for PUT operation.
func (g *GateData) SessionTokenForPut() *session.Token {
return g.containerSessionToken(apisession.ContainerVerbPut)
}
// SessionTokenForDelete return the first suitable container session context for DELETE operation.
// SessionTokenForDelete returns the first suitable container session context for DELETE operation.
func (g *GateData) SessionTokenForDelete() *session.Token {
return g.containerSessionToken(apisession.ContainerVerbDelete)
}
// SessionTokenForSetEACL return the first suitable container session context for SetEACL operation.
// SessionTokenForSetEACL returns the first suitable container session context for SetEACL operation.
func (g *GateData) SessionTokenForSetEACL() *session.Token {
return g.containerSessionToken(apisession.ContainerVerbSetEACL)
}
@ -78,7 +78,7 @@ func isAppropriateContainerContext(ctx *session.ContainerContext, verb apisessio
verb == apisession.ContainerVerbSetEACL && ctx.IsForSetEACL()
}
// Secrets represents AccessKey and key to encrypt gate tokens.
// Secrets represents AccessKey and the key to encrypt gate tokens.
type Secrets struct {
AccessKey string
EphemeralKey *keys.PrivateKey
@ -94,7 +94,7 @@ func (x *AccessBox) Unmarshal(data []byte) error {
return proto.Unmarshal(data, x)
}
// PackTokens adds a bearer and session tokens to BearerTokens and SessionToken lists respectively.
// PackTokens adds bearer and session tokens to BearerTokens and SessionToken lists respectively.
// Session token can be nil.
func PackTokens(gatesData []*GateData) (*AccessBox, *Secrets, error) {
box := &AccessBox{}
@ -156,7 +156,7 @@ func (x *AccessBox) GetPlacementPolicy() ([]*ContainerPolicy, error) {
return result, nil
}
// GetBox parse AccessBox to Box.
// GetBox parses AccessBox to Box.
func (x *AccessBox) GetBox(owner *keys.PrivateKey) (*Box, error) {
tokens, err := x.GetTokens(owner)
if err != nil {

View File

@ -51,18 +51,18 @@ type PrmObjectCreate struct {
// NeoFS represents virtual connection to NeoFS network.
type NeoFS interface {
// CreateObject creates and saves a parameterized object in the specified
// NeoFS container from a specific user. It sets 'Timestamp' attribute to current time.
// Returns ID of the saved object.
// NeoFS container from a specific user. It sets 'Timestamp' attribute to the current time.
// It returns the ID of the saved object.
//
// Returns exactly one non-nil value. Returns any error encountered which
// prevented the object to be created.
// It returns exactly one non-nil value. It returns any error encountered which
// prevented the object from being created.
CreateObject(context.Context, PrmObjectCreate) (*oid.ID, error)
// ReadObjectPayload reads payload of the object from NeoFS network by address
// into memory.
//
// Returns exactly one non-nil value. Returns any error encountered which
// prevented the object payload to be read.
// It returns exactly one non-nil value. It returns any error encountered which
// prevented the object payload from being read.
ReadObjectPayload(context.Context, address.Address) ([]byte, error)
}
@ -75,7 +75,7 @@ var (
var _ = New
// New creates new Credentials instance using given cli and key.
// New creates a new Credentials instance using the given cli and key.
func New(neoFS NeoFS, key *keys.PrivateKey, config *cache.Config) Credentials {
return &cred{neoFS: neoFS, key: key, cache: cache.NewAccessBoxCache(config)}
}

View File

@ -2,18 +2,18 @@
Authmate is a tool to create gateway AWS credentials. AWS users
are authenticated with access key IDs and secrets, while NeoFS users are
authenticated with key pairs. To complicate things further we have S3 gateway
that usually acts on behalf of some user, but user doesn't necessarily want to
authenticated with key pairs. To complicate things further, we have S3 gateway
that usually acts on behalf of some user, but the user doesn't necessarily want to
give their keys to the gateway.
To solve this, we use NeoFS bearer tokens that are signed by the owner (NeoFS
"user") and that can implement any kind of policy for NeoFS requests allowed
using this token. However, tokens can't be used as AWS credentials directly, thus
they're stored on NeoFS as regular objects, and access key ID is just an
address of this object while secret is generated randomly.
to use this token. However, tokens can't be used as AWS credentials directly. Thus,
they're stored on NeoFS as regular objects, and an access key ID is just an
address of this object while a secret is generated randomly.
Tokens are not stored on NeoFS in plaintext, they're encrypted with a set of
gateway keys. So in order for a gateway to be able to successfully extract bearer
gateway keys. So, in order for a gateway to be able to successfully extract bearer
token, the object needs to be stored in a container available for the gateway
to read, and it needs to be encrypted with this gateway's key (among others
potentially).
@ -67,10 +67,10 @@ Confirm passphrase >
}
}
wallet successfully created, file location is wallet.json
wallet is successfully created, the file location is wallet.json
```
To get public key from the wallet:
To get the public key from the wallet:
```shell
$ ./bin/neo-go wallet dump-keys -w wallet.json
@ -80,23 +80,23 @@ NhLQpDnerpviUWDF77j5qyjFgavCmasJ4p (simple signature contract):
## Issuance of a secret
To issue a secret means to create a Bearer and, optionally, Session tokens and
To issue a secret means to create Bearer and, optionally, Session tokens and
put them as an object into a container on the NeoFS network.
### CLI parameters
**Required parameters:**
* `--wallet` - a path to a wallet `.json` file. You can provide a passphrase to decrypt
* `--wallet` is a path to a wallet `.json` file. You can provide a passphrase to decrypt
a wallet via environment variable `AUTHMATE_WALLET_PASSPHRASE`, or you will be asked to enter a passphrase
interactively. You can also specify an account address to use from a wallet using the `--address` parameter.
* `--peer` - address of a NeoFS peer to connect to
* `--gate-public-key` -- public `secp256r1` 33-byte short key of a gate (use flags repeatedly for multiple gates). The tokens are encrypted
* `--peer` is an address of a NeoFS peer to connect to
* `--gate-public-key` is a public `secp256r1` 33-byte short key of a gate (use flags repeatedly for multiple gates). The tokens are encrypted
by a set of gateway keys, so you need to pass them as well.
You can issue a secret using the parameters above only. The tool will
1. create a new container
1. without a friendly name
2. with ACL `0x3c8c8cce` - all operations are forbidden for `OTHERS` and `BEARER` user groups, except for `GET`
2. with ACL `0x3c8c8cce` -- all operations are forbidden for `OTHERS` and `BEARER` user groups, except for `GET`
3. with policy `REP 2 IN X CBF 3 SELECT 2 FROM * AS X`
2. put bearer and session tokens with default rules (details in [Bearer tokens](#Bearer tokens) and
[Session tokens](#Session tokens))
@ -135,9 +135,9 @@ the secret. Format of `access_key_id`: `%cid0%oid`, where 0(zero) is a delimiter
### Bearer tokens
Creation of the bearer tokens is mandatory.
Creation of bearer tokens is mandatory.
Rules for bearer token can be set via parameter `--bearer-rules` (json-string and file path allowed):
Rules for a bearer token can be set via parameter `--bearer-rules` (json-string and file path allowed):
```shell
$ neofs-authmate issue-secret --wallet wallet.json \
--peer 192.168.130.71:8080 \
@ -186,7 +186,7 @@ If bearer rules are not set, a token will be auto-generated with a value:
### Session tokens
With session token, there are 3 options:
With a session token, there are 3 options:
1. append `--session-tokens` parameter with your custom rules in json format (as a string or file path). E.g.:
```shell
$ neofs-authmate issue-secret --wallet wallet.json \

View File

@ -4,7 +4,7 @@
### Credentials
To configure basic settings that the AWS CLI uses to interact with the Gateway, follow steps below:
To configure basic settings that the AWS CLI uses to interact with the Gateway, follow the steps below:
1. issue a secret with neofs-authmate tool (see [NeoFS Authmate] (#neofs-authmate))
2. execute the command

View File

@ -30,7 +30,7 @@ Reference:
## ACL
For now there are some limitations:
* [Bucket policy](https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucket-policies.html) support only one `Principal` (type `AWS`) per `Statement`. To refer all users use `"AWS": "*"`
* [Bucket policy](https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucket-policies.html) supports only one `Principal` (type `AWS`) per `Statement`. To refer all users use `"AWS": "*"`
* AWS conditions and wildcard are not supported in [resources](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-arn-format.html)
* Only `CanonicalUser` (with hex encoded public key) and `All Users Group` are supported in [ACL](https://docs.aws.amazon.com/AmazonS3/latest/userguide/acl-overview.html)

View File

@ -35,7 +35,7 @@ a gateway spread requests equally among them (using weight 1 for every node):
$ neofs-s3-gw -p 192.168.130.72:8080 -p 192.168.130.71:8080
```
If you want some specific load distribution proportions, use weights and priorities, they
can only be specified via environment variables or configuration file.
can only be specified via environment variables or a configuration file.
### Wallet
@ -49,8 +49,8 @@ Gateway listens on `0.0.0.0:8080` by default, and you can change that with the `
It can also provide TLS interface for its users, just specify paths to the key and
certificate files via `--tls.key_file` and `--tls.cert_file` parameters. Note
that using these options makes gateway TLS-only, if you need to serve both TLS
and plain text you either have to run two gateway instances or use some
that using these options makes gateway TLS-only. If you need to serve both TLS
and plain text, you either have to run two gateway instances or use some
external redirecting solution.
Example to bind to `192.168.130.130:443` and serve TLS there (keys and nodes are
@ -100,7 +100,7 @@ default. To enable them, use `--pprof` and `--metrics` flags or
## YAML file and environment variables
Example of YAML configuration file: [.yaml-example](/config/config.yaml)
Example of a YAML configuration file: [.yaml-example](/config/config.yaml)
Examples of environment variables: [.env-example](/config/config.env).
A path to a configuration file can be specified with `--config` parameter:
@ -109,7 +109,7 @@ A path to a configuration file can be specified with `--config` parameter:
$ neofs-s3-gw --config your-config.yaml
```
Parameters of the following groups can be configured via `.yaml` file or environment variables only:
Parameters of the following groups can be configured via a `.yaml` file or environment variables only:
1. logging -- logging level
2. caching -- lifetime and size for each cache
3. notifications

View File

@ -1,6 +1,6 @@
# S3 compatibility test results
To update this file using tests result run:
To update this file using tests result, run:
```sh
./updateTestsResult.sh ceph_tests_result.txt
```

View File

@ -11,7 +11,7 @@ import (
"github.com/spf13/viper"
)
// GetPassword gets passphrase for wallet.
// GetPassword gets the passphrase for a wallet.
func GetPassword(v *viper.Viper, variable string) *string {
var password *string
if v.IsSet(variable) {
@ -21,7 +21,7 @@ func GetPassword(v *viper.Viper, variable string) *string {
return password
}
// GetKeyFromPath reads wallet and gets private key.
// GetKeyFromPath reads a wallet and gets the private key.
func GetKeyFromPath(walletPath, addrStr string, password *string) (*keys.PrivateKey, error) {
if len(walletPath) == 0 {
return nil, fmt.Errorf("wallet path must not be empty")