diff --git a/apemanager/chain.go b/apemanager/chain.go new file mode 100644 index 0000000..0a4cec4 --- /dev/null +++ b/apemanager/chain.go @@ -0,0 +1,52 @@ +package apemanager + +import ( + "errors" + "fmt" + + apemanager_v2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/apemanager" +) + +var ( + ErrInvalidChainRepresentation = errors.New("invalid chain representation") +) + +// ChainID is Chain's identifier. +type ChainID []byte + +// Chain is an SDK representation for v2's Chain. +// +// Note that Chain (as well as v2's Chain) and all related entities +// are NOT operated by Access-Policy-Engine (APE). The client is responsible +// to convert these types to policy-engine entities. +type Chain struct { + // Raw is the encoded chain kind. + // It assumes that Raw's bytes are the result of encoding provided by + // policy-engine package. + Raw []byte +} + +// ToV2 converts Chain to v2. +func (c *Chain) ToV2() *apemanager_v2.Chain { + v2ct := new(apemanager_v2.Chain) + + if c.Raw != nil { + v2Raw := new(apemanager_v2.ChainRaw) + v2Raw.SetRaw(c.Raw) + v2ct.SetKind(v2Raw) + } + + return v2ct +} + +// ReadFromV2 fills Chain from v2. +func (c *Chain) ReadFromV2(v2ct *apemanager_v2.Chain) error { + switch v := v2ct.GetKind().(type) { + default: + return fmt.Errorf("unsupported chain kind: %T", v) + case *apemanager_v2.ChainRaw: + raw := v.GetRaw() + c.Raw = raw + } + return nil +} diff --git a/apemanager/chain_target.go b/apemanager/chain_target.go new file mode 100644 index 0000000..70cf9dc --- /dev/null +++ b/apemanager/chain_target.go @@ -0,0 +1,53 @@ +package apemanager + +import ( + apemanager_v2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/apemanager" +) + +// TargetType is an SDK representation for v2's TargetType. +type TargetType apemanager_v2.TargetType + +const ( + TargetTypeUndefined TargetType = iota + TargetTypeNamespace + TargetTypeContainer + TargetTypeUser + TargetTypeGroup +) + +// ToV2 converts TargetType to v2. +func (targetType TargetType) ToV2() apemanager_v2.TargetType { + return apemanager_v2.TargetType(targetType) +} + +// FromV2 reads TargetType to v2. +func (targetType *TargetType) FromV2(v2targetType apemanager_v2.TargetType) { + *targetType = TargetType(v2targetType) +} + +// ChainTarget is an SDK representation for v2's ChainTarget. +// +// Note that ChainTarget (as well as v2's ChainTarget) and all related entities +// are NOT operated by Access-Policy-Engine (APE). The client is responsible +// to convert these types to policy-engine entities. +type ChainTarget struct { + TargetType TargetType + + Name string +} + +// ToV2 converts ChainTarget to v2. +func (ct *ChainTarget) ToV2() *apemanager_v2.ChainTarget { + v2ct := new(apemanager_v2.ChainTarget) + + v2ct.SetTargetType(ct.TargetType.ToV2()) + v2ct.SetName(ct.Name) + + return v2ct +} + +// FromV2 reads ChainTarget frpm v2. +func (ct *ChainTarget) FromV2(v2ct *apemanager_v2.ChainTarget) { + ct.TargetType.FromV2(v2ct.GetTargetType()) + ct.Name = v2ct.GetName() +} diff --git a/apemanager/chain_target_test.go b/apemanager/chain_target_test.go new file mode 100644 index 0000000..a5e5fb7 --- /dev/null +++ b/apemanager/chain_target_test.go @@ -0,0 +1,65 @@ +package apemanager_test + +import ( + "testing" + + "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/apemanager" + "github.com/stretchr/testify/require" + + apemanager_v2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/apemanager" +) + +var ( + m = map[apemanager.TargetType]apemanager_v2.TargetType{ + apemanager.TargetTypeUndefined: apemanager_v2.TargetTypeUndefined, + apemanager.TargetTypeNamespace: apemanager_v2.TargetTypeNamespace, + apemanager.TargetTypeContainer: apemanager_v2.TargetTypeContainer, + apemanager.TargetTypeUser: apemanager_v2.TargetTypeUser, + apemanager.TargetTypeGroup: apemanager_v2.TargetTypeGroup, + } +) + +func TestTargetType(t *testing.T) { + for typesdk, typev2 := range m { + t.Run("from sdk to v2 "+typev2.String(), func(t *testing.T) { + v2 := typesdk.ToV2() + require.Equal(t, v2, typev2) + }) + + t.Run("from v2 to sdk "+typev2.String(), func(t *testing.T) { + var typ apemanager.TargetType + typ.FromV2(typev2) + require.Equal(t, typesdk, typ) + }) + } +} + +func TestChainTarget(t *testing.T) { + var ( + typ = apemanager.TargetTypeNamespace + name = "namespaceXXYYZZ" + ) + + t.Run("from sdk to v2", func(t *testing.T) { + ct := apemanager.ChainTarget{ + TargetType: typ, + Name: name, + } + + v2 := ct.ToV2() + require.Equal(t, m[typ], v2.GetTargetType()) + require.Equal(t, name, v2.GetName()) + }) + + t.Run("from v2 to sdk", func(t *testing.T) { + v2 := &apemanager_v2.ChainTarget{} + v2.SetTargetType(m[typ]) + v2.SetName(name) + + var ct apemanager.ChainTarget + ct.FromV2(v2) + + require.Equal(t, typ, ct.TargetType) + require.Equal(t, name, ct.Name) + }) +} diff --git a/apemanager/chain_test.go b/apemanager/chain_test.go new file mode 100644 index 0000000..fbe1818 --- /dev/null +++ b/apemanager/chain_test.go @@ -0,0 +1,43 @@ +package apemanager_test + +import ( + "testing" + + "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/apemanager" + "github.com/stretchr/testify/require" + + apemanager_v2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/apemanager" +) + +const ( + encoded = `{"ID":"","Rules":[{"Status":"Allow","Actions":{"Inverted":false,"Names":["GetObject"]},"Resources":{"Inverted":false,"Names":["native:object/*"]},"Any":false,"Condition":[{"Op":"StringEquals","Object":"Resource","Key":"Department","Value":"HR"}]}],"MatchType":"DenyPriority"}` +) + +func TestChainData(t *testing.T) { + t.Run("raw chain", func(t *testing.T) { + var c apemanager.Chain + + b := []byte(encoded) + c.Raw = b + + v2, ok := c.ToV2().GetKind().(*apemanager_v2.ChainRaw) + require.True(t, ok) + require.Equal(t, b, v2.Raw) + }) +} + +func TestChainMessageV2(t *testing.T) { + b := []byte(encoded) + + v2Raw := &apemanager_v2.ChainRaw{} + v2Raw.SetRaw(b) + + v2 := &apemanager_v2.Chain{} + v2.SetKind(v2Raw) + + var c apemanager.Chain + c.ReadFromV2(v2) + + require.NotNil(t, c.Raw) + require.Equal(t, b, c.Raw) +}