frostfs-s3-gw/pkg/policy-engine/converter.go
Denis Kirillov 0ba6989197 [#680] Move policy engine converter to s3-gw
Signed-off-by: Denis Kirillov <d.kirillov@yadro.com>
2025-04-14 12:11:54 +00:00

118 lines
3.1 KiB
Go

package policyengine
import (
"fmt"
s3common "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/pkg/policy-engine/common"
v2 "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/pkg/policy-engine/v2/iam"
v1 "git.frostfs.info/TrueCloudLab/policy-engine/iam"
"git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain"
)
type Converter struct {
versionFetcher VersionFetcher
}
type Config struct {
VersionFetcher VersionFetcher
}
type VersionFetcher interface {
ConverterVersion() ConverterVersion
}
type ConverterVersion string
const (
V1 ConverterVersion = "v1"
V2 ConverterVersion = "v2"
)
func NewConverter(cfg Config) *Converter {
return &Converter{
versionFetcher: cfg.VersionFetcher,
}
}
func (c *Converter) ToS3Chain(p s3common.Policy, resolver s3common.S3Resolver) (*chain.Chain, error) {
switch v := c.versionFetcher.ConverterVersion(); v {
case V1:
return v1.ConvertToS3Chain(commonPolicyToV1(p), resolver)
case V2:
return v2.ConvertToS3Chain(p, resolver)
default:
return nil, fmt.Errorf("unknown converter version: %s", v)
}
}
func (c *Converter) ToNativeChain(p s3common.Policy, resolver s3common.NativeResolver) (*chain.Chain, error) {
switch v := c.versionFetcher.ConverterVersion(); v {
case V1:
return v1.ConvertToNativeChain(commonPolicyToV1(p), nativeResolverV1Wrapper{resolver: resolver})
case V2:
return v2.ConvertToNativeChain(p, resolver)
default:
return nil, fmt.Errorf("unknown converter version: %s", v)
}
}
func commonPolicyToV1(p s3common.Policy) v1.Policy {
res := v1.Policy{
Version: p.Version,
ID: p.ID,
Statement: make(v1.Statements, len(p.Statement)),
}
for i, statement := range p.Statement {
res.Statement[i] = v1.Statement{
ID: statement.ID,
SID: statement.SID,
Principal: make(map[v1.PrincipalType][]string, len(statement.Principal)),
NotPrincipal: make(map[v1.PrincipalType][]string, len(statement.NotPrincipal)),
Effect: v1.Effect(statement.Effect),
Action: v1.Action(statement.Action),
NotAction: v1.Action(statement.NotAction),
Resource: v1.Resource(statement.Resource),
NotResource: v1.Resource(statement.NotResource),
Conditions: make(map[string]v1.Condition, len(statement.Conditions)),
}
for k, principal := range statement.Principal {
res.Statement[i].Principal[v1.PrincipalType(k)] = principal
}
for k, principal := range statement.NotPrincipal {
res.Statement[i].NotPrincipal[v1.PrincipalType(k)] = principal
}
for k, condition := range statement.Conditions {
res.Statement[i].Conditions[k] = v1.Condition(condition)
}
}
return res
}
type nativeResolverV1Wrapper struct {
resolver s3common.NativeResolver
}
func (w nativeResolverV1Wrapper) GetUserKey(account, name string) (string, error) {
res, err := w.resolver.GetUserKey(account, name)
if err != nil {
return "", err
}
return res, nil
}
func (w nativeResolverV1Wrapper) GetBucketInfo(bucket string) (*v1.BucketInfo, error) {
res, err := w.resolver.GetBucketInfo(bucket)
if err != nil {
return nil, err
}
return &v1.BucketInfo{
Namespace: res.Namespace,
Container: res.Container,
}, nil
}