[#713] Add check access control for system caches

Signed-off-by: Denis Kirillov <denis@nspcc.ru>
This commit is contained in:
Denis Kirillov 2022-10-06 11:46:53 +03:00 committed by Alex Vanin
parent cb55d36063
commit 90eb4f0188
8 changed files with 94 additions and 59 deletions

View file

@ -8,7 +8,6 @@ import (
"github.com/nspcc-dev/neofs-s3-gw/api/data" "github.com/nspcc-dev/neofs-s3-gw/api/data"
"github.com/nspcc-dev/neofs-s3-gw/api/errors" "github.com/nspcc-dev/neofs-s3-gw/api/errors"
"github.com/nspcc-dev/neofs-s3-gw/api/layer" "github.com/nspcc-dev/neofs-s3-gw/api/layer"
"go.uber.org/zap"
) )
func (h *handler) PutBucketVersioningHandler(w http.ResponseWriter, r *http.Request) { func (h *handler) PutBucketVersioningHandler(w http.ResponseWriter, r *http.Request) {
@ -68,11 +67,8 @@ func (h *handler) GetBucketVersioningHandler(w http.ResponseWriter, r *http.Requ
settings, err := h.obj.GetBucketSettings(r.Context(), bktInfo) settings, err := h.obj.GetBucketSettings(r.Context(), bktInfo)
if err != nil { if err != nil {
h.log.Warn("couldn't get version settings object: default version settings will be used", h.logAndSendError(w, "couldn't get version settings", reqInfo, err)
zap.String("request_id", reqInfo.RequestID), return
zap.String("method", reqInfo.API),
zap.String("bucket_name", reqInfo.BucketName),
zap.Error(err))
} }
if err = api.EncodeToResponse(w, formVersioningConfiguration(settings)); err != nil { if err = api.EncodeToResponse(w, formVersioningConfiguration(settings)); err != nil {

View file

@ -142,64 +142,110 @@ func (c *Cache) PutList(owner user.ID, key cache.ObjectsListKey, list []*data.No
} }
} }
func (c *Cache) GetTagging(key string) map[string]string { func (c *Cache) GetTagging(owner user.ID, key string) map[string]string {
if !c.accessCache.Get(owner, key) {
return nil
}
return c.systemCache.GetTagging(key) return c.systemCache.GetTagging(key)
} }
func (c *Cache) PutTagging(key string, tags map[string]string) { func (c *Cache) PutTagging(owner user.ID, key string, tags map[string]string) {
if err := c.systemCache.PutTagging(key, tags); err != nil { if err := c.systemCache.PutTagging(key, tags); err != nil {
c.logger.Error("couldn't cache tags", zap.Error(err)) c.logger.Error("couldn't cache tags", zap.Error(err))
} }
if err := c.accessCache.Put(owner, key); err != nil {
c.logger.Warn("couldn't cache access control operation", zap.Error(err))
}
} }
func (c *Cache) DeleteTagging(key string) { func (c *Cache) DeleteTagging(key string) {
c.systemCache.Delete(key) c.systemCache.Delete(key)
} }
func (c *Cache) GetLockInfo(key string) *data.LockInfo { func (c *Cache) GetLockInfo(owner user.ID, key string) *data.LockInfo {
if !c.accessCache.Get(owner, key) {
return nil
}
return c.systemCache.GetLockInfo(key) return c.systemCache.GetLockInfo(key)
} }
func (c *Cache) PutLockInfo(key string, lockInfo *data.LockInfo) { func (c *Cache) PutLockInfo(owner user.ID, key string, lockInfo *data.LockInfo) {
if err := c.systemCache.PutLockInfo(key, lockInfo); err != nil { if err := c.systemCache.PutLockInfo(key, lockInfo); err != nil {
c.logger.Error("couldn't cache lock info", zap.Error(err)) c.logger.Error("couldn't cache lock info", zap.Error(err))
} }
if err := c.accessCache.Put(owner, key); err != nil {
c.logger.Warn("couldn't cache access control operation", zap.Error(err))
}
} }
func (c *Cache) GetSettings(bktInfo *data.BucketInfo) *data.BucketSettings { func (c *Cache) GetSettings(owner user.ID, bktInfo *data.BucketInfo) *data.BucketSettings {
key := bktInfo.Name + bktInfo.SettingsObjectName() key := bktInfo.Name + bktInfo.SettingsObjectName()
if !c.accessCache.Get(owner, key) {
return nil
}
return c.systemCache.GetSettings(key) return c.systemCache.GetSettings(key)
} }
func (c *Cache) PutSettings(bktInfo *data.BucketInfo, settings *data.BucketSettings) { func (c *Cache) PutSettings(owner user.ID, bktInfo *data.BucketInfo, settings *data.BucketSettings) {
key := bktInfo.Name + bktInfo.SettingsObjectName() key := bktInfo.Name + bktInfo.SettingsObjectName()
if err := c.systemCache.PutSettings(key, settings); err != nil { if err := c.systemCache.PutSettings(key, settings); err != nil {
c.logger.Warn("couldn't cache bucket settings", zap.String("bucket", bktInfo.Name), zap.Error(err)) c.logger.Warn("couldn't cache bucket settings", zap.String("bucket", bktInfo.Name), zap.Error(err))
} }
if err := c.accessCache.Put(owner, key); err != nil {
c.logger.Warn("couldn't cache access control operation", zap.Error(err))
}
} }
func (c *Cache) GetCORS(bkt *data.BucketInfo) *data.CORSConfiguration { func (c *Cache) GetCORS(owner user.ID, bkt *data.BucketInfo) *data.CORSConfiguration {
return c.systemCache.GetCORS(bkt.Name + bkt.CORSObjectName()) key := bkt.Name + bkt.CORSObjectName()
if !c.accessCache.Get(owner, key) {
return nil
} }
func (c *Cache) PutCORS(bkt *data.BucketInfo, settings *data.CORSConfiguration) { return c.systemCache.GetCORS(key)
if err := c.systemCache.PutCORS(bkt.Name+bkt.CORSObjectName(), settings); err != nil { }
func (c *Cache) PutCORS(owner user.ID, bkt *data.BucketInfo, cors *data.CORSConfiguration) {
key := bkt.Name + bkt.CORSObjectName()
if err := c.systemCache.PutCORS(key, cors); err != nil {
c.logger.Warn("couldn't cache cors", zap.String("bucket", bkt.Name), zap.Error(err)) c.logger.Warn("couldn't cache cors", zap.String("bucket", bkt.Name), zap.Error(err))
} }
if err := c.accessCache.Put(owner, key); err != nil {
c.logger.Warn("couldn't cache access control operation", zap.Error(err))
}
} }
func (c *Cache) DeleteCORS(bktInfo *data.BucketInfo) { func (c *Cache) DeleteCORS(bktInfo *data.BucketInfo) {
c.systemCache.Delete(bktInfo.Name + bktInfo.CORSObjectName()) c.systemCache.Delete(bktInfo.Name + bktInfo.CORSObjectName())
} }
func (c *Cache) GetNotificationConfiguration(bktInfo *data.BucketInfo) *data.NotificationConfiguration { func (c *Cache) GetNotificationConfiguration(owner user.ID, bktInfo *data.BucketInfo) *data.NotificationConfiguration {
key := bktInfo.Name + bktInfo.NotificationConfigurationObjectName() key := bktInfo.Name + bktInfo.NotificationConfigurationObjectName()
if !c.accessCache.Get(owner, key) {
return nil
}
return c.systemCache.GetNotificationConfiguration(key) return c.systemCache.GetNotificationConfiguration(key)
} }
func (c *Cache) PutNotificationConfiguration(bktInfo *data.BucketInfo, configuration *data.NotificationConfiguration) { func (c *Cache) PutNotificationConfiguration(owner user.ID, bktInfo *data.BucketInfo, configuration *data.NotificationConfiguration) {
key := bktInfo.Name + bktInfo.NotificationConfigurationObjectName() key := bktInfo.Name + bktInfo.NotificationConfigurationObjectName()
if err := c.systemCache.PutNotificationConfiguration(key, configuration); err != nil { if err := c.systemCache.PutNotificationConfiguration(key, configuration); err != nil {
c.logger.Warn("couldn't cache notification configuration", zap.String("bucket", bktInfo.Name), zap.Error(err)) c.logger.Warn("couldn't cache notification configuration", zap.String("bucket", bktInfo.Name), zap.Error(err))
} }
if err := c.accessCache.Put(owner, key); err != nil {
c.logger.Warn("couldn't cache access control operation", zap.Error(err))
}
} }

View file

@ -9,13 +9,11 @@ import (
) )
func (n *layer) GetObjectTaggingAndLock(ctx context.Context, objVersion *ObjectVersion, nodeVersion *data.NodeVersion) (map[string]string, *data.LockInfo, error) { func (n *layer) GetObjectTaggingAndLock(ctx context.Context, objVersion *ObjectVersion, nodeVersion *data.NodeVersion) (map[string]string, *data.LockInfo, error) {
var ( var err error
err error owner := n.Owner(ctx)
tags map[string]string
)
tags = n.cache.GetTagging(objectTaggingCacheKey(objVersion)) tags := n.cache.GetTagging(owner, objectTaggingCacheKey(objVersion))
lockInfo := n.cache.GetLockInfo(lockObjectKey(objVersion)) lockInfo := n.cache.GetLockInfo(owner, lockObjectKey(objVersion))
if tags != nil && lockInfo != nil { if tags != nil && lockInfo != nil {
return tags, lockInfo, nil return tags, lockInfo, nil
@ -36,8 +34,8 @@ func (n *layer) GetObjectTaggingAndLock(ctx context.Context, objVersion *ObjectV
return nil, nil, err return nil, nil, err
} }
n.cache.PutTagging(objectTaggingCacheKey(objVersion), tags) n.cache.PutTagging(owner, objectTaggingCacheKey(objVersion), tags)
n.cache.PutLockInfo(lockObjectKey(objVersion), lockInfo) n.cache.PutLockInfo(owner, lockObjectKey(objVersion), lockInfo)
return tags, lockInfo, nil return tags, lockInfo, nil
} }

View file

@ -107,7 +107,6 @@ func (n *layer) containerList(ctx context.Context) ([]*data.BucketInfo, error) {
} }
func (n *layer) createContainer(ctx context.Context, p *CreateBucketParams) (*data.BucketInfo, error) { func (n *layer) createContainer(ctx context.Context, p *CreateBucketParams) (*data.BucketInfo, error) {
var err error
ownerID := n.Owner(ctx) ownerID := n.Owner(ctx)
if p.LocationConstraint == "" { if p.LocationConstraint == "" {
p.LocationConstraint = api.DefaultLocationConstraint // s3tests_boto3.functional.test_s3:test_bucket_get_location p.LocationConstraint = api.DefaultLocationConstraint // s3tests_boto3.functional.test_s3:test_bucket_get_location

View file

@ -64,7 +64,7 @@ func (n *layer) PutBucketCORS(ctx context.Context, p *PutCORSParams) error {
} }
} }
n.cache.PutCORS(p.BktInfo, cors) n.cache.PutCORS(n.Owner(ctx), p.BktInfo, cors)
return nil return nil
} }

View file

@ -53,13 +53,14 @@ func (n *layer) PutBucketNotificationConfiguration(ctx context.Context, p *PutBu
} }
} }
n.cache.PutNotificationConfiguration(p.BktInfo, p.Configuration) n.cache.PutNotificationConfiguration(n.Owner(ctx), p.BktInfo, p.Configuration)
return nil return nil
} }
func (n *layer) GetBucketNotificationConfiguration(ctx context.Context, bktInfo *data.BucketInfo) (*data.NotificationConfiguration, error) { func (n *layer) GetBucketNotificationConfiguration(ctx context.Context, bktInfo *data.BucketInfo) (*data.NotificationConfiguration, error) {
if conf := n.cache.GetNotificationConfiguration(bktInfo); conf != nil { owner := n.Owner(ctx)
if conf := n.cache.GetNotificationConfiguration(owner, bktInfo); conf != nil {
return conf, nil return conf, nil
} }
@ -82,7 +83,7 @@ func (n *layer) GetBucketNotificationConfiguration(ctx context.Context, bktInfo
} }
} }
n.cache.PutNotificationConfiguration(bktInfo, conf) n.cache.PutNotificationConfiguration(owner, bktInfo, conf)
return conf, nil return conf, nil
} }

View file

@ -100,7 +100,7 @@ func (n *layer) PutLockInfo(ctx context.Context, p *PutLockInfoParams) (err erro
return fmt.Errorf("couldn't put lock into tree: %w", err) return fmt.Errorf("couldn't put lock into tree: %w", err)
} }
n.cache.PutLockInfo(lockObjectKey(p.ObjVersion), lockInfo) n.cache.PutLockInfo(n.Owner(ctx), lockObjectKey(p.ObjVersion), lockInfo)
return nil return nil
} }
@ -124,7 +124,8 @@ func (n *layer) putLockObject(ctx context.Context, bktInfo *data.BucketInfo, obj
} }
func (n *layer) GetLockInfo(ctx context.Context, objVersion *ObjectVersion) (*data.LockInfo, error) { func (n *layer) GetLockInfo(ctx context.Context, objVersion *ObjectVersion) (*data.LockInfo, error) {
if lockInfo := n.cache.GetLockInfo(lockObjectKey(objVersion)); lockInfo != nil { owner := n.Owner(ctx)
if lockInfo := n.cache.GetLockInfo(owner, lockObjectKey(objVersion)); lockInfo != nil {
return lockInfo, nil return lockInfo, nil
} }
@ -141,13 +142,14 @@ func (n *layer) GetLockInfo(ctx context.Context, objVersion *ObjectVersion) (*da
lockInfo = &data.LockInfo{} lockInfo = &data.LockInfo{}
} }
n.cache.PutLockInfo(lockObjectKey(objVersion), lockInfo) n.cache.PutLockInfo(owner, lockObjectKey(objVersion), lockInfo)
return lockInfo, nil return lockInfo, nil
} }
func (n *layer) getCORS(ctx context.Context, bkt *data.BucketInfo) (*data.CORSConfiguration, error) { func (n *layer) getCORS(ctx context.Context, bkt *data.BucketInfo) (*data.CORSConfiguration, error) {
if cors := n.cache.GetCORS(bkt); cors != nil { owner := n.Owner(ctx)
if cors := n.cache.GetCORS(owner, bkt); cors != nil {
return cors, nil return cors, nil
} }
@ -172,7 +174,7 @@ func (n *layer) getCORS(ctx context.Context, bkt *data.BucketInfo) (*data.CORSCo
return nil, fmt.Errorf("unmarshal cors: %w", err) return nil, fmt.Errorf("unmarshal cors: %w", err)
} }
n.cache.PutCORS(bkt, cors) n.cache.PutCORS(owner, bkt, cors)
return cors, nil return cors, nil
} }
@ -183,7 +185,8 @@ func lockObjectKey(objVersion *ObjectVersion) string {
} }
func (n *layer) GetBucketSettings(ctx context.Context, bktInfo *data.BucketInfo) (*data.BucketSettings, error) { func (n *layer) GetBucketSettings(ctx context.Context, bktInfo *data.BucketInfo) (*data.BucketSettings, error) {
if settings := n.cache.GetSettings(bktInfo); settings != nil { owner := n.Owner(ctx)
if settings := n.cache.GetSettings(owner, bktInfo); settings != nil {
return settings, nil return settings, nil
} }
@ -195,7 +198,7 @@ func (n *layer) GetBucketSettings(ctx context.Context, bktInfo *data.BucketInfo)
settings = &data.BucketSettings{Versioning: data.VersioningUnversioned} settings = &data.BucketSettings{Versioning: data.VersioningUnversioned}
} }
n.cache.PutSettings(bktInfo, settings) n.cache.PutSettings(owner, bktInfo, settings)
return settings, nil return settings, nil
} }
@ -205,7 +208,7 @@ func (n *layer) PutBucketSettings(ctx context.Context, p *PutSettingsParams) err
return fmt.Errorf("failed to get settings node: %w", err) return fmt.Errorf("failed to get settings node: %w", err)
} }
n.cache.PutSettings(p.BktInfo, p.Settings) n.cache.PutSettings(n.Owner(ctx), p.BktInfo, p.Settings)
return nil return nil
} }

View file

@ -12,14 +12,10 @@ import (
) )
func (n *layer) GetObjectTagging(ctx context.Context, p *ObjectVersion) (string, map[string]string, error) { func (n *layer) GetObjectTagging(ctx context.Context, p *ObjectVersion) (string, map[string]string, error) {
var ( owner := n.Owner(ctx)
err error
tags map[string]string
)
if len(p.VersionID) != 0 && p.VersionID != data.UnversionedObjectVersionID { if len(p.VersionID) != 0 && p.VersionID != data.UnversionedObjectVersionID {
tags = n.cache.GetTagging(objectTaggingCacheKey(p)) if tags := n.cache.GetTagging(owner, objectTaggingCacheKey(p)); tags != nil {
if tags != nil {
return p.VersionID, tags, nil return p.VersionID, tags, nil
} }
} }
@ -30,12 +26,11 @@ func (n *layer) GetObjectTagging(ctx context.Context, p *ObjectVersion) (string,
} }
p.VersionID = version.OID.EncodeToString() p.VersionID = version.OID.EncodeToString()
tags = n.cache.GetTagging(objectTaggingCacheKey(p)) if tags := n.cache.GetTagging(owner, objectTaggingCacheKey(p)); tags != nil {
if tags != nil {
return p.VersionID, tags, nil return p.VersionID, tags, nil
} }
tags, err = n.treeService.GetObjectTagging(ctx, p.BktInfo, version) tags, err := n.treeService.GetObjectTagging(ctx, p.BktInfo, version)
if err != nil { if err != nil {
if errorsStd.Is(err, ErrNodeNotFound) { if errorsStd.Is(err, ErrNodeNotFound) {
return "", nil, errors.GetAPIError(errors.ErrNoSuchKey) return "", nil, errors.GetAPIError(errors.ErrNoSuchKey)
@ -43,7 +38,7 @@ func (n *layer) GetObjectTagging(ctx context.Context, p *ObjectVersion) (string,
return "", nil, err return "", nil, err
} }
n.cache.PutTagging(objectTaggingCacheKey(p), tags) n.cache.PutTagging(owner, objectTaggingCacheKey(p), tags)
return p.VersionID, tags, nil return p.VersionID, tags, nil
} }
@ -63,7 +58,7 @@ func (n *layer) PutObjectTagging(ctx context.Context, p *ObjectVersion, tagSet m
return nil, err return nil, err
} }
n.cache.PutTagging(objectTaggingCacheKey(p), tagSet) n.cache.PutTagging(n.Owner(ctx), objectTaggingCacheKey(p), tagSet)
return version, nil return version, nil
} }
@ -90,21 +85,18 @@ func (n *layer) DeleteObjectTagging(ctx context.Context, p *ObjectVersion) (*dat
} }
func (n *layer) GetBucketTagging(ctx context.Context, bktInfo *data.BucketInfo) (map[string]string, error) { func (n *layer) GetBucketTagging(ctx context.Context, bktInfo *data.BucketInfo) (map[string]string, error) {
var ( owner := n.Owner(ctx)
err error
tags map[string]string
)
tags = n.cache.GetTagging(bucketTaggingCacheKey(bktInfo.CID)) if tags := n.cache.GetTagging(owner, bucketTaggingCacheKey(bktInfo.CID)); tags != nil {
if tags != nil {
return tags, nil return tags, nil
} }
if tags, err = n.treeService.GetBucketTagging(ctx, bktInfo); err != nil && !errorsStd.Is(err, ErrNodeNotFound) { tags, err := n.treeService.GetBucketTagging(ctx, bktInfo)
if err != nil && !errorsStd.Is(err, ErrNodeNotFound) {
return nil, err return nil, err
} }
n.cache.PutTagging(bucketTaggingCacheKey(bktInfo.CID), tags) n.cache.PutTagging(owner, bucketTaggingCacheKey(bktInfo.CID), tags)
return tags, nil return tags, nil
} }
@ -114,7 +106,7 @@ func (n *layer) PutBucketTagging(ctx context.Context, bktInfo *data.BucketInfo,
return err return err
} }
n.cache.PutTagging(bucketTaggingCacheKey(bktInfo.CID), tagSet) n.cache.PutTagging(n.Owner(ctx), bucketTaggingCacheKey(bktInfo.CID), tagSet)
return nil return nil
} }