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 }