feat: store assets in database (#3290)

* feat: use database as asset storage

* being only uploading assets if allowed

* tests

* fixes

* cleanup after merge

* renaming

* various fixes

* fix: change to repository event types and removed unused code

* feat: set default features

* error handling

* error handling and naming

* fix tests

* fix tests

* fix merge

* rename
This commit is contained in:
Livio Amstutz
2022-04-06 08:13:40 +02:00
committed by GitHub
parent b949b8fc65
commit 4a0d61d75a
36 changed files with 2016 additions and 967 deletions

View File

@@ -124,10 +124,7 @@ func (c *Commands) ActivateDefaultLabelPolicy(ctx context.Context) (*domain.Obje
return writeModelToObjectDetails(&existingPolicy.LabelPolicyWriteModel.WriteModel), nil
}
func (c *Commands) AddLogoDefaultLabelPolicy(ctx context.Context, storageKey string) (*domain.ObjectDetails, error) {
if storageKey == "" {
return nil, caos_errs.ThrowInvalidArgument(nil, "INSTANCE-3m20c", "Errors.Assets.EmptyKey")
}
func (c *Commands) AddLogoDefaultLabelPolicy(ctx context.Context, upload *AssetUpload) (*domain.ObjectDetails, error) {
existingPolicy, err := c.defaultLabelPolicyWriteModelByID(ctx)
if err != nil {
return nil, err
@@ -136,8 +133,12 @@ func (c *Commands) AddLogoDefaultLabelPolicy(ctx context.Context, storageKey str
if existingPolicy.State == domain.PolicyStateUnspecified || existingPolicy.State == domain.PolicyStateRemoved {
return nil, caos_errs.ThrowNotFound(nil, "INSTANCE-Qw0pd", "Errors.IAM.LabelPolicy.NotFound")
}
asset, err := c.uploadAsset(ctx, upload)
if err != nil {
return nil, caos_errs.ThrowInternal(err, "INSTANCE-3m20c", "Errors.Assets.Object.PutFailed")
}
instanceAgg := InstanceAggregateFromWriteModel(&existingPolicy.LabelPolicyWriteModel.WriteModel)
pushedEvents, err := c.eventstore.Push(ctx, instance.NewLabelPolicyLogoAddedEvent(ctx, instanceAgg, storageKey))
pushedEvents, err := c.eventstore.Push(ctx, instance.NewLabelPolicyLogoAddedEvent(ctx, instanceAgg, asset.Name))
if err != nil {
return nil, err
}
@@ -158,7 +159,7 @@ func (c *Commands) RemoveLogoDefaultLabelPolicy(ctx context.Context) (*domain.Ob
return nil, caos_errs.ThrowNotFound(nil, "INSTANCE-Xc8Kf", "Errors.IAM.LabelPolicy.NotFound")
}
err = c.RemoveAsset(ctx, authz.GetInstance(ctx).InstanceID(), existingPolicy.LogoKey)
err = c.removeAsset(ctx, authz.GetInstance(ctx).InstanceID(), existingPolicy.LogoKey)
if err != nil {
return nil, err
}
@@ -174,10 +175,7 @@ func (c *Commands) RemoveLogoDefaultLabelPolicy(ctx context.Context) (*domain.Ob
return writeModelToObjectDetails(&existingPolicy.LabelPolicyWriteModel.WriteModel), nil
}
func (c *Commands) AddIconDefaultLabelPolicy(ctx context.Context, storageKey string) (*domain.ObjectDetails, error) {
if storageKey == "" {
return nil, caos_errs.ThrowInvalidArgument(nil, "INSTANCE-yxE4f", "Errors.Assets.EmptyKey")
}
func (c *Commands) AddIconDefaultLabelPolicy(ctx context.Context, upload *AssetUpload) (*domain.ObjectDetails, error) {
existingPolicy, err := c.defaultLabelPolicyWriteModelByID(ctx)
if err != nil {
return nil, err
@@ -186,8 +184,12 @@ func (c *Commands) AddIconDefaultLabelPolicy(ctx context.Context, storageKey str
if existingPolicy.State == domain.PolicyStateUnspecified || existingPolicy.State == domain.PolicyStateRemoved {
return nil, caos_errs.ThrowNotFound(nil, "INSTANCE-1yMx0", "Errors.IAM.LabelPolicy.NotFound")
}
asset, err := c.uploadAsset(ctx, upload)
if err != nil {
return nil, caos_errs.ThrowInternal(err, "INSTANCE-yxE4f", "Errors.Assets.Object.PutFailed")
}
instanceAgg := InstanceAggregateFromWriteModel(&existingPolicy.LabelPolicyWriteModel.WriteModel)
pushedEvents, err := c.eventstore.Push(ctx, instance.NewLabelPolicyIconAddedEvent(ctx, instanceAgg, storageKey))
pushedEvents, err := c.eventstore.Push(ctx, instance.NewLabelPolicyIconAddedEvent(ctx, instanceAgg, asset.Name))
if err != nil {
return nil, err
}
@@ -207,7 +209,7 @@ func (c *Commands) RemoveIconDefaultLabelPolicy(ctx context.Context) (*domain.Ob
if existingPolicy.State == domain.PolicyStateUnspecified || existingPolicy.State == domain.PolicyStateRemoved {
return nil, caos_errs.ThrowNotFound(nil, "INSTANCE-4M0qw", "Errors.IAM.LabelPolicy.NotFound")
}
err = c.RemoveAsset(ctx, authz.GetInstance(ctx).InstanceID(), existingPolicy.IconKey)
err = c.removeAsset(ctx, authz.GetInstance(ctx).InstanceID(), existingPolicy.IconKey)
if err != nil {
return nil, err
}
@@ -223,20 +225,21 @@ func (c *Commands) RemoveIconDefaultLabelPolicy(ctx context.Context) (*domain.Ob
return writeModelToObjectDetails(&existingPolicy.LabelPolicyWriteModel.WriteModel), nil
}
func (c *Commands) AddLogoDarkDefaultLabelPolicy(ctx context.Context, storageKey string) (*domain.ObjectDetails, error) {
if storageKey == "" {
return nil, caos_errs.ThrowInvalidArgument(nil, "INSTANCE-4fMs9", "Errors.Assets.EmptyKey")
}
func (c *Commands) AddLogoDarkDefaultLabelPolicy(ctx context.Context, upload *AssetUpload) (*domain.ObjectDetails, error) {
existingPolicy, err := c.defaultLabelPolicyWriteModelByID(ctx)
if err != nil {
return nil, err
}
if existingPolicy.State == domain.PolicyStateUnspecified || existingPolicy.State == domain.PolicyStateRemoved {
return nil, caos_errs.ThrowNotFound(nil, "INSTANCE-ZR9fs", "Errors.IAM.LabelPolicy.NotFound")
return nil, caos_errs.ThrowNotFound(nil, "INSTANCE-ZR9fs", "Errors.Instance.LabelPolicy.NotFound")
}
asset, err := c.uploadAsset(ctx, upload)
if err != nil {
return nil, caos_errs.ThrowInternal(err, "INSTANCE-4fMs9", "Errors.Assets.Object.PutFailed")
}
instanceAgg := InstanceAggregateFromWriteModel(&existingPolicy.LabelPolicyWriteModel.WriteModel)
pushedEvents, err := c.eventstore.Push(ctx, instance.NewLabelPolicyLogoDarkAddedEvent(ctx, instanceAgg, storageKey))
pushedEvents, err := c.eventstore.Push(ctx, instance.NewLabelPolicyLogoDarkAddedEvent(ctx, instanceAgg, asset.Name))
if err != nil {
return nil, err
}
@@ -254,9 +257,9 @@ func (c *Commands) RemoveLogoDarkDefaultLabelPolicy(ctx context.Context) (*domai
}
if existingPolicy.State == domain.PolicyStateUnspecified || existingPolicy.State == domain.PolicyStateRemoved {
return nil, caos_errs.ThrowNotFound(nil, "INSTANCE-3FGds", "Errors.IAM.LabelPolicy.NotFound")
return nil, caos_errs.ThrowNotFound(nil, "INSTANCE-3FGds", "Errors.Instance.LabelPolicy.NotFound")
}
err = c.RemoveAsset(ctx, authz.GetInstance(ctx).InstanceID(), existingPolicy.LogoDarkKey)
err = c.removeAsset(ctx, authz.GetInstance(ctx).InstanceID(), existingPolicy.LogoDarkKey)
if err != nil {
return nil, err
}
@@ -272,20 +275,21 @@ func (c *Commands) RemoveLogoDarkDefaultLabelPolicy(ctx context.Context) (*domai
return writeModelToObjectDetails(&existingPolicy.LabelPolicyWriteModel.WriteModel), nil
}
func (c *Commands) AddIconDarkDefaultLabelPolicy(ctx context.Context, storageKey string) (*domain.ObjectDetails, error) {
if storageKey == "" {
return nil, caos_errs.ThrowInvalidArgument(nil, "INSTANCE-1cxM3", "Errors.Assets.EmptyKey")
}
func (c *Commands) AddIconDarkDefaultLabelPolicy(ctx context.Context, upload *AssetUpload) (*domain.ObjectDetails, error) {
existingPolicy, err := c.defaultLabelPolicyWriteModelByID(ctx)
if err != nil {
return nil, err
}
if existingPolicy.State == domain.PolicyStateUnspecified || existingPolicy.State == domain.PolicyStateRemoved {
return nil, caos_errs.ThrowNotFound(nil, "INSTANCE-vMsf9", "Errors.IAM.LabelPolicy.NotFound")
return nil, caos_errs.ThrowNotFound(nil, "INSTANCE-vMsf9", "Errors.Instance.LabelPolicy.NotFound")
}
asset, err := c.uploadAsset(ctx, upload)
if err != nil {
return nil, caos_errs.ThrowInternal(err, "INSTANCE-1cxM3", "Errors.Assets.Object.PutFailed")
}
instanceAgg := InstanceAggregateFromWriteModel(&existingPolicy.LabelPolicyWriteModel.WriteModel)
pushedEvents, err := c.eventstore.Push(ctx, instance.NewLabelPolicyIconDarkAddedEvent(ctx, instanceAgg, storageKey))
pushedEvents, err := c.eventstore.Push(ctx, instance.NewLabelPolicyIconDarkAddedEvent(ctx, instanceAgg, asset.Name))
if err != nil {
return nil, err
}
@@ -303,9 +307,9 @@ func (c *Commands) RemoveIconDarkDefaultLabelPolicy(ctx context.Context) (*domai
}
if existingPolicy.State == domain.PolicyStateUnspecified || existingPolicy.State == domain.PolicyStateRemoved {
return nil, caos_errs.ThrowNotFound(nil, "INSTANCE-2nc7F", "Errors.IAM.LabelPolicy.NotFound")
return nil, caos_errs.ThrowNotFound(nil, "INSTANCE-2nc7F", "Errors.Instance.LabelPolicy.NotFound")
}
err = c.RemoveAsset(ctx, authz.GetInstance(ctx).InstanceID(), existingPolicy.IconDarkKey)
err = c.removeAsset(ctx, authz.GetInstance(ctx).InstanceID(), existingPolicy.IconDarkKey)
if err != nil {
return nil, err
}
@@ -321,20 +325,21 @@ func (c *Commands) RemoveIconDarkDefaultLabelPolicy(ctx context.Context) (*domai
return writeModelToObjectDetails(&existingPolicy.LabelPolicyWriteModel.WriteModel), nil
}
func (c *Commands) AddFontDefaultLabelPolicy(ctx context.Context, storageKey string) (*domain.ObjectDetails, error) {
if storageKey == "" {
return nil, caos_errs.ThrowInvalidArgument(nil, "INSTANCE-1N8fs", "Errors.Assets.EmptyKey")
}
func (c *Commands) AddFontDefaultLabelPolicy(ctx context.Context, upload *AssetUpload) (*domain.ObjectDetails, error) {
existingPolicy, err := c.defaultLabelPolicyWriteModelByID(ctx)
if err != nil {
return nil, err
}
if existingPolicy.State == domain.PolicyStateUnspecified || existingPolicy.State == domain.PolicyStateRemoved {
return nil, caos_errs.ThrowNotFound(nil, "INSTANCE-1N8fE", "Errors.IAM.LabelPolicy.NotFound")
return nil, caos_errs.ThrowNotFound(nil, "INSTANCE-1N8fE", "Errors.Instance.LabelPolicy.NotFound")
}
asset, err := c.uploadAsset(ctx, upload)
if err != nil {
return nil, caos_errs.ThrowInternal(nil, "INSTANCE-1N8fs", "Errors.Assets.Object.PutFailed")
}
instanceAgg := InstanceAggregateFromWriteModel(&existingPolicy.LabelPolicyWriteModel.WriteModel)
pushedEvents, err := c.eventstore.Push(ctx, instance.NewLabelPolicyFontAddedEvent(ctx, instanceAgg, storageKey))
pushedEvents, err := c.eventstore.Push(ctx, instance.NewLabelPolicyFontAddedEvent(ctx, instanceAgg, asset.Name))
if err != nil {
return nil, err
}
@@ -352,9 +357,9 @@ func (c *Commands) RemoveFontDefaultLabelPolicy(ctx context.Context) (*domain.Ob
}
if existingPolicy.State == domain.PolicyStateUnspecified || existingPolicy.State == domain.PolicyStateRemoved {
return nil, caos_errs.ThrowNotFound(nil, "INSTANCE-Tk0gw", "Errors.IAM.LabelPolicy.NotFound")
return nil, caos_errs.ThrowNotFound(nil, "INSTANCE-Tk0gw", "Errors.Instance.LabelPolicy.NotFound")
}
err = c.RemoveAsset(ctx, authz.GetInstance(ctx).InstanceID(), existingPolicy.FontKey)
err = c.removeAsset(ctx, authz.GetInstance(ctx).InstanceID(), existingPolicy.FontKey)
if err != nil {
return nil, err
}

View File

@@ -1,13 +1,14 @@
package command
import (
"bytes"
"context"
"testing"
"github.com/caos/zitadel/internal/api/authz"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
"github.com/caos/zitadel/internal/api/authz"
"github.com/caos/zitadel/internal/domain"
caos_errs "github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/eventstore"
@@ -452,8 +453,8 @@ func TestCommandSide_AddLogoDefaultLabelPolicy(t *testing.T) {
storage static.Storage
}
type args struct {
ctx context.Context
storageKey string
ctx context.Context
upload *AssetUpload
}
type res struct {
want *domain.ObjectDetails
@@ -465,20 +466,6 @@ func TestCommandSide_AddLogoDefaultLabelPolicy(t *testing.T) {
args args
res res
}{
{
name: "storage key empty, invalid argument error",
fields: fields{
eventstore: eventstoreExpect(
t,
),
},
args: args{
ctx: context.Background(),
},
res: res{
err: caos_errs.IsErrorInvalidArgument,
},
},
{
name: "label policy not existing, not found error",
fields: fields{
@@ -488,13 +475,61 @@ func TestCommandSide_AddLogoDefaultLabelPolicy(t *testing.T) {
),
},
args: args{
ctx: context.Background(),
storageKey: "key",
ctx: context.Background(),
upload: &AssetUpload{
ResourceOwner: "IAM",
ObjectName: "logo",
ContentType: "text/css",
ObjectType: static.ObjectTypeStyling,
File: nil,
Size: 0,
},
},
res: res{
err: caos_errs.IsNotFound,
},
},
{
name: "upload failed, error",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(
eventFromEventPusher(
instance.NewLabelPolicyAddedEvent(context.Background(),
&instance.NewAggregate("INSTANCE").Aggregate,
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
true,
true,
true,
),
),
),
),
storage: mock.NewStorage(t).ExpectPutObjectError(),
},
args: args{
ctx: context.Background(),
upload: &AssetUpload{
ResourceOwner: "IAM",
ObjectName: "logo",
ContentType: "image",
ObjectType: static.ObjectTypeStyling,
File: bytes.NewReader([]byte("test")),
Size: 4,
},
},
res: res{
err: caos_errs.IsInternal,
},
},
{
name: "logo added, ok",
fields: fields{
@@ -523,16 +558,24 @@ func TestCommandSide_AddLogoDefaultLabelPolicy(t *testing.T) {
eventFromEventPusher(
instance.NewLabelPolicyLogoAddedEvent(context.Background(),
&instance.NewAggregate("INSTANCE").Aggregate,
"key",
"logo",
),
),
},
),
),
storage: mock.NewStorage(t).ExpectPutObject(),
},
args: args{
ctx: context.Background(),
storageKey: "key",
ctx: context.Background(),
upload: &AssetUpload{
ResourceOwner: "IAM",
ObjectName: "logo",
ContentType: "image",
ObjectType: static.ObjectTypeStyling,
File: bytes.NewReader([]byte("test")),
Size: 4,
},
},
res: res{
want: &domain.ObjectDetails{
@@ -545,8 +588,9 @@ func TestCommandSide_AddLogoDefaultLabelPolicy(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
r := &Commands{
eventstore: tt.fields.eventstore,
static: tt.fields.storage,
}
got, err := r.AddLogoDefaultLabelPolicy(tt.args.ctx, tt.args.storageKey)
got, err := r.AddLogoDefaultLabelPolicy(tt.args.ctx, tt.args.upload)
if tt.res.err == nil {
assert.NoError(t, err)
}
@@ -593,7 +637,6 @@ func TestCommandSide_RemoveLogoDefaultLabelPolicy(t *testing.T) {
err: caos_errs.IsNotFound,
},
},
{
name: "asset remove error, internal error",
fields: fields{
@@ -708,10 +751,11 @@ func TestCommandSide_RemoveLogoDefaultLabelPolicy(t *testing.T) {
func TestCommandSide_AddIconDefaultLabelPolicy(t *testing.T) {
type fields struct {
eventstore *eventstore.Eventstore
storage static.Storage
}
type args struct {
ctx context.Context
storageKey string
ctx context.Context
upload *AssetUpload
}
type res struct {
want *domain.ObjectDetails
@@ -723,20 +767,6 @@ func TestCommandSide_AddIconDefaultLabelPolicy(t *testing.T) {
args args
res res
}{
{
name: "storage key empty, invalid argument error",
fields: fields{
eventstore: eventstoreExpect(
t,
),
},
args: args{
ctx: context.Background(),
},
res: res{
err: caos_errs.IsErrorInvalidArgument,
},
},
{
name: "label policy not existing, not found error",
fields: fields{
@@ -746,13 +776,61 @@ func TestCommandSide_AddIconDefaultLabelPolicy(t *testing.T) {
),
},
args: args{
ctx: context.Background(),
storageKey: "key",
ctx: context.Background(),
upload: &AssetUpload{
ResourceOwner: "IAM",
ObjectName: "icon",
ContentType: "image",
ObjectType: static.ObjectTypeStyling,
File: bytes.NewReader([]byte("test")),
Size: 4,
},
},
res: res{
err: caos_errs.IsNotFound,
},
},
{
name: "upload failed, error",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(
eventFromEventPusher(
instance.NewLabelPolicyAddedEvent(context.Background(),
&instance.NewAggregate("INSTANCE").Aggregate,
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
true,
true,
true,
),
),
),
),
storage: mock.NewStorage(t).ExpectPutObjectError(),
},
args: args{
ctx: context.Background(),
upload: &AssetUpload{
ResourceOwner: "IAM",
ObjectName: "icon",
ContentType: "image",
ObjectType: static.ObjectTypeStyling,
File: bytes.NewReader([]byte("test")),
Size: 4,
},
},
res: res{
err: caos_errs.IsInternal,
},
},
{
name: "icon added, ok",
fields: fields{
@@ -781,16 +859,24 @@ func TestCommandSide_AddIconDefaultLabelPolicy(t *testing.T) {
eventFromEventPusher(
instance.NewLabelPolicyIconAddedEvent(context.Background(),
&instance.NewAggregate("INSTANCE").Aggregate,
"key",
"icon",
),
),
},
),
),
storage: mock.NewStorage(t).ExpectPutObject(),
},
args: args{
ctx: context.Background(),
storageKey: "key",
ctx: context.Background(),
upload: &AssetUpload{
ResourceOwner: "IAM",
ObjectName: "icon",
ContentType: "image",
ObjectType: static.ObjectTypeStyling,
File: bytes.NewReader([]byte("test")),
Size: 4,
},
},
res: res{
want: &domain.ObjectDetails{
@@ -803,8 +889,9 @@ func TestCommandSide_AddIconDefaultLabelPolicy(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
r := &Commands{
eventstore: tt.fields.eventstore,
static: tt.fields.storage,
}
got, err := r.AddIconDefaultLabelPolicy(tt.args.ctx, tt.args.storageKey)
got, err := r.AddIconDefaultLabelPolicy(tt.args.ctx, tt.args.upload)
if tt.res.err == nil {
assert.NoError(t, err)
}
@@ -926,11 +1013,12 @@ func TestCommandSide_RemoveIconDefaultLabelPolicy(t *testing.T) {
func TestCommandSide_AddLogoDarkDefaultLabelPolicy(t *testing.T) {
type fields struct {
eventstore *eventstore.Eventstore
storage static.Storage
}
type args struct {
ctx context.Context
instanceID string
storageKey string
upload *AssetUpload
}
type res struct {
want *domain.ObjectDetails
@@ -942,21 +1030,6 @@ func TestCommandSide_AddLogoDarkDefaultLabelPolicy(t *testing.T) {
args args
res res
}{
{
name: "storage key empty, invalid argument error",
fields: fields{
eventstore: eventstoreExpect(
t,
),
},
args: args{
ctx: context.Background(),
instanceID: "INSTANCE",
},
res: res{
err: caos_errs.IsErrorInvalidArgument,
},
},
{
name: "label policy not existing, not found error",
fields: fields{
@@ -968,12 +1041,61 @@ func TestCommandSide_AddLogoDarkDefaultLabelPolicy(t *testing.T) {
args: args{
ctx: context.Background(),
instanceID: "INSTANCE",
storageKey: "key",
upload: &AssetUpload{
ResourceOwner: "IAM",
ObjectName: "logo",
ContentType: "image",
ObjectType: static.ObjectTypeStyling,
File: bytes.NewReader([]byte("test")),
Size: 4,
},
},
res: res{
err: caos_errs.IsNotFound,
},
},
{
name: "upload failed, error",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(
eventFromEventPusher(
instance.NewLabelPolicyAddedEvent(context.Background(),
&instance.NewAggregate("INSTANCE").Aggregate,
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
true,
true,
true,
),
),
),
),
storage: mock.NewStorage(t).ExpectPutObjectError(),
},
args: args{
ctx: context.Background(),
instanceID: "INSTANCE",
upload: &AssetUpload{
ResourceOwner: "IAM",
ObjectName: "logo",
ContentType: "image",
ObjectType: static.ObjectTypeStyling,
File: bytes.NewReader([]byte("test")),
Size: 4,
},
},
res: res{
err: caos_errs.IsInternal,
},
},
{
name: "logo dark added, ok",
fields: fields{
@@ -1002,16 +1124,24 @@ func TestCommandSide_AddLogoDarkDefaultLabelPolicy(t *testing.T) {
eventFromEventPusher(
instance.NewLabelPolicyLogoDarkAddedEvent(context.Background(),
&instance.NewAggregate("INSTANCE").Aggregate,
"key",
"logo",
),
),
},
),
),
storage: mock.NewStorage(t).ExpectPutObject(),
},
args: args{
ctx: context.Background(),
storageKey: "key",
ctx: context.Background(),
upload: &AssetUpload{
ResourceOwner: "IAM",
ObjectName: "logo",
ContentType: "image",
ObjectType: static.ObjectTypeStyling,
File: bytes.NewReader([]byte("test")),
Size: 4,
},
},
res: res{
want: &domain.ObjectDetails{
@@ -1024,8 +1154,9 @@ func TestCommandSide_AddLogoDarkDefaultLabelPolicy(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
r := &Commands{
eventstore: tt.fields.eventstore,
static: tt.fields.storage,
}
got, err := r.AddLogoDarkDefaultLabelPolicy(tt.args.ctx, tt.args.storageKey)
got, err := r.AddLogoDarkDefaultLabelPolicy(tt.args.ctx, tt.args.upload)
if tt.res.err == nil {
assert.NoError(t, err)
}
@@ -1186,10 +1317,11 @@ func TestCommandSide_RemoveLogoDarkDefaultLabelPolicy(t *testing.T) {
func TestCommandSide_AddIconDarkDefaultLabelPolicy(t *testing.T) {
type fields struct {
eventstore *eventstore.Eventstore
storage static.Storage
}
type args struct {
ctx context.Context
storageKey string
ctx context.Context
upload *AssetUpload
}
type res struct {
want *domain.ObjectDetails
@@ -1201,20 +1333,6 @@ func TestCommandSide_AddIconDarkDefaultLabelPolicy(t *testing.T) {
args args
res res
}{
{
name: "storage key empty, invalid argument error",
fields: fields{
eventstore: eventstoreExpect(
t,
),
},
args: args{
ctx: context.Background(),
},
res: res{
err: caos_errs.IsErrorInvalidArgument,
},
},
{
name: "label policy not existing, not found error",
fields: fields{
@@ -1224,13 +1342,61 @@ func TestCommandSide_AddIconDarkDefaultLabelPolicy(t *testing.T) {
),
},
args: args{
ctx: context.Background(),
storageKey: "key",
ctx: context.Background(),
upload: &AssetUpload{
ResourceOwner: "IAM",
ObjectName: "icon",
ContentType: "image",
ObjectType: static.ObjectTypeStyling,
File: bytes.NewReader([]byte("test")),
Size: 4,
},
},
res: res{
err: caos_errs.IsNotFound,
},
},
{
name: "upload failed, error",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(
eventFromEventPusher(
instance.NewLabelPolicyAddedEvent(context.Background(),
&instance.NewAggregate("INSTANCE").Aggregate,
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
true,
true,
true,
),
),
),
),
storage: mock.NewStorage(t).ExpectPutObjectError(),
},
args: args{
ctx: context.Background(),
upload: &AssetUpload{
ResourceOwner: "IAM",
ObjectName: "icon",
ContentType: "image",
ObjectType: static.ObjectTypeStyling,
File: bytes.NewReader([]byte("test")),
Size: 4,
},
},
res: res{
err: caos_errs.IsInternal,
},
},
{
name: "icon dark added, ok",
fields: fields{
@@ -1259,16 +1425,24 @@ func TestCommandSide_AddIconDarkDefaultLabelPolicy(t *testing.T) {
eventFromEventPusher(
instance.NewLabelPolicyIconDarkAddedEvent(context.Background(),
&instance.NewAggregate("INSTANCE").Aggregate,
"key",
"icon",
),
),
},
),
),
storage: mock.NewStorage(t).ExpectPutObject(),
},
args: args{
ctx: context.Background(),
storageKey: "key",
ctx: context.Background(),
upload: &AssetUpload{
ResourceOwner: "IAM",
ObjectName: "icon",
ContentType: "image",
ObjectType: static.ObjectTypeStyling,
File: bytes.NewReader([]byte("test")),
Size: 4,
},
},
res: res{
want: &domain.ObjectDetails{
@@ -1281,8 +1455,9 @@ func TestCommandSide_AddIconDarkDefaultLabelPolicy(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
r := &Commands{
eventstore: tt.fields.eventstore,
static: tt.fields.storage,
}
got, err := r.AddIconDarkDefaultLabelPolicy(tt.args.ctx, tt.args.storageKey)
got, err := r.AddIconDarkDefaultLabelPolicy(tt.args.ctx, tt.args.upload)
if tt.res.err == nil {
assert.NoError(t, err)
}
@@ -1443,10 +1618,11 @@ func TestCommandSide_RemoveIconDarkDefaultLabelPolicy(t *testing.T) {
func TestCommandSide_AddFontDefaultLabelPolicy(t *testing.T) {
type fields struct {
eventstore *eventstore.Eventstore
storage static.Storage
}
type args struct {
ctx context.Context
storageKey string
ctx context.Context
upload *AssetUpload
}
type res struct {
want *domain.ObjectDetails
@@ -1458,20 +1634,6 @@ func TestCommandSide_AddFontDefaultLabelPolicy(t *testing.T) {
args args
res res
}{
{
name: "storage key empty, invalid argument error",
fields: fields{
eventstore: eventstoreExpect(
t,
),
},
args: args{
ctx: context.Background(),
},
res: res{
err: caos_errs.IsErrorInvalidArgument,
},
},
{
name: "label policy not existing, not found error",
fields: fields{
@@ -1481,13 +1643,61 @@ func TestCommandSide_AddFontDefaultLabelPolicy(t *testing.T) {
),
},
args: args{
ctx: context.Background(),
storageKey: "key",
ctx: context.Background(),
upload: &AssetUpload{
ResourceOwner: "IAM",
ObjectName: "font",
ContentType: "ttf",
ObjectType: static.ObjectTypeStyling,
File: bytes.NewReader([]byte("test")),
Size: 4,
},
},
res: res{
err: caos_errs.IsNotFound,
},
},
{
name: "upload failed, error",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(
eventFromEventPusher(
instance.NewLabelPolicyAddedEvent(context.Background(),
&instance.NewAggregate("INSTANCE").Aggregate,
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
true,
true,
true,
),
),
),
),
storage: mock.NewStorage(t).ExpectPutObjectError(),
},
args: args{
ctx: context.Background(),
upload: &AssetUpload{
ResourceOwner: "IAM",
ObjectName: "font",
ContentType: "ttf",
ObjectType: static.ObjectTypeStyling,
File: bytes.NewReader([]byte("test")),
Size: 4,
},
},
res: res{
err: caos_errs.IsInternal,
},
},
{
name: "font added, ok",
fields: fields{
@@ -1516,16 +1726,24 @@ func TestCommandSide_AddFontDefaultLabelPolicy(t *testing.T) {
eventFromEventPusher(
instance.NewLabelPolicyFontAddedEvent(context.Background(),
&instance.NewAggregate("INSTANCE").Aggregate,
"key",
"font",
),
),
},
),
),
storage: mock.NewStorage(t).ExpectPutObject(),
},
args: args{
ctx: context.Background(),
storageKey: "key",
ctx: context.Background(),
upload: &AssetUpload{
ResourceOwner: "IAM",
ObjectName: "font",
ContentType: "ttf",
ObjectType: static.ObjectTypeStyling,
File: bytes.NewReader([]byte("test")),
Size: 4,
},
},
res: res{
want: &domain.ObjectDetails{
@@ -1538,8 +1756,9 @@ func TestCommandSide_AddFontDefaultLabelPolicy(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
r := &Commands{
eventstore: tt.fields.eventstore,
static: tt.fields.storage,
}
got, err := r.AddFontDefaultLabelPolicy(tt.args.ctx, tt.args.storageKey)
got, err := r.AddFontDefaultLabelPolicy(tt.args.ctx, tt.args.upload)
if tt.res.err == nil {
assert.NoError(t, err)
}

View File

@@ -6,6 +6,7 @@ import (
"github.com/caos/zitadel/internal/domain"
caos_errs "github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/repository/org"
"github.com/caos/zitadel/internal/static"
)
func (c *Commands) AddLabelPolicy(ctx context.Context, resourceOwner string, policy *domain.LabelPolicy) (*domain.LabelPolicy, error) {
@@ -150,13 +151,10 @@ func (c *Commands) ActivateLabelPolicy(ctx context.Context, orgID string) (*doma
return writeModelToObjectDetails(&existingPolicy.LabelPolicyWriteModel.WriteModel), nil
}
func (c *Commands) AddLogoLabelPolicy(ctx context.Context, orgID, storageKey string) (*domain.ObjectDetails, error) {
func (c *Commands) AddLogoLabelPolicy(ctx context.Context, orgID string, upload *AssetUpload) (*domain.ObjectDetails, error) {
if orgID == "" {
return nil, caos_errs.ThrowInvalidArgument(nil, "Org-KKd4X", "Errors.ResourceOwnerMissing")
}
if storageKey == "" {
return nil, caos_errs.ThrowInvalidArgument(nil, "IAM-4N3nf", "Errors.Assets.EmptyKey")
}
existingPolicy, err := c.orgLabelPolicyWriteModelByID(ctx, orgID)
if err != nil {
return nil, err
@@ -165,8 +163,12 @@ func (c *Commands) AddLogoLabelPolicy(ctx context.Context, orgID, storageKey str
if existingPolicy.State == domain.PolicyStateUnspecified || existingPolicy.State == domain.PolicyStateRemoved {
return nil, caos_errs.ThrowNotFound(nil, "ORG-23BMs", "Errors.Org.LabelPolicy.NotFound")
}
asset, err := c.uploadAsset(ctx, upload)
if err != nil {
return nil, caos_errs.ThrowInternal(err, "IAM-4N3nf", "Errors.Assets.Object.PutFailed")
}
orgAgg := OrgAggregateFromWriteModel(&existingPolicy.LabelPolicyWriteModel.WriteModel)
pushedEvents, err := c.eventstore.Push(ctx, org.NewLabelPolicyLogoAddedEvent(ctx, orgAgg, storageKey))
pushedEvents, err := c.eventstore.Push(ctx, org.NewLabelPolicyLogoAddedEvent(ctx, orgAgg, asset.Name))
if err != nil {
return nil, err
}
@@ -189,7 +191,7 @@ func (c *Commands) RemoveLogoLabelPolicy(ctx context.Context, orgID string) (*do
if existingPolicy.State == domain.PolicyStateUnspecified || existingPolicy.State == domain.PolicyStateRemoved {
return nil, caos_errs.ThrowNotFound(nil, "ORG-4MVsf", "Errors.Org.LabelPolicy.NotFound")
}
err = c.RemoveAsset(ctx, orgID, existingPolicy.LogoKey)
err = c.removeAsset(ctx, orgID, existingPolicy.LogoKey)
if err != nil {
return nil, err
}
@@ -205,13 +207,10 @@ func (c *Commands) RemoveLogoLabelPolicy(ctx context.Context, orgID string) (*do
return writeModelToObjectDetails(&existingPolicy.LabelPolicyWriteModel.WriteModel), nil
}
func (c *Commands) AddIconLabelPolicy(ctx context.Context, orgID, storageKey string) (*domain.ObjectDetails, error) {
func (c *Commands) AddIconLabelPolicy(ctx context.Context, orgID string, upload *AssetUpload) (*domain.ObjectDetails, error) {
if orgID == "" {
return nil, caos_errs.ThrowInvalidArgument(nil, "Org-hMDs3", "Errors.ResourceOwnerMissing")
}
if storageKey == "" {
return nil, caos_errs.ThrowInvalidArgument(nil, "IAM-4BS7f", "Errors.Assets.EmptyKey")
}
existingPolicy, err := c.orgLabelPolicyWriteModelByID(ctx, orgID)
if err != nil {
return nil, err
@@ -220,8 +219,12 @@ func (c *Commands) AddIconLabelPolicy(ctx context.Context, orgID, storageKey str
if existingPolicy.State == domain.PolicyStateUnspecified || existingPolicy.State == domain.PolicyStateRemoved {
return nil, caos_errs.ThrowNotFound(nil, "ORG-4nq2f", "Errors.Org.LabelPolicy.NotFound")
}
asset, err := c.uploadAsset(ctx, upload)
if err != nil {
return nil, caos_errs.ThrowInternal(err, "IAM-4BS7f", "Errors.Assets.Object.PutFailed")
}
orgAgg := OrgAggregateFromWriteModel(&existingPolicy.LabelPolicyWriteModel.WriteModel)
pushedEvents, err := c.eventstore.Push(ctx, org.NewLabelPolicyIconAddedEvent(ctx, orgAgg, storageKey))
pushedEvents, err := c.eventstore.Push(ctx, org.NewLabelPolicyIconAddedEvent(ctx, orgAgg, asset.Name))
if err != nil {
return nil, err
}
@@ -245,7 +248,7 @@ func (c *Commands) RemoveIconLabelPolicy(ctx context.Context, orgID string) (*do
return nil, caos_errs.ThrowNotFound(nil, "ORG-1nd9f", "Errors.Org.LabelPolicy.NotFound")
}
err = c.RemoveAsset(ctx, orgID, existingPolicy.IconKey)
err = c.removeAsset(ctx, orgID, existingPolicy.IconKey)
if err != nil {
return nil, err
}
@@ -261,13 +264,10 @@ func (c *Commands) RemoveIconLabelPolicy(ctx context.Context, orgID string) (*do
return writeModelToObjectDetails(&existingPolicy.LabelPolicyWriteModel.WriteModel), nil
}
func (c *Commands) AddLogoDarkLabelPolicy(ctx context.Context, orgID, storageKey string) (*domain.ObjectDetails, error) {
func (c *Commands) AddLogoDarkLabelPolicy(ctx context.Context, orgID string, upload *AssetUpload) (*domain.ObjectDetails, error) {
if orgID == "" {
return nil, caos_errs.ThrowInvalidArgument(nil, "Org-67Ms2", "Errors.ResourceOwnerMissing")
}
if storageKey == "" {
return nil, caos_errs.ThrowInvalidArgument(nil, "IAM-3S7fN", "Errors.Assets.EmptyKey")
}
existingPolicy, err := c.orgLabelPolicyWriteModelByID(ctx, orgID)
if err != nil {
return nil, err
@@ -276,8 +276,12 @@ func (c *Commands) AddLogoDarkLabelPolicy(ctx context.Context, orgID, storageKey
if existingPolicy.State == domain.PolicyStateUnspecified || existingPolicy.State == domain.PolicyStateRemoved {
return nil, caos_errs.ThrowNotFound(nil, "ORG-QSqcd", "Errors.Org.LabelPolicy.NotFound")
}
asset, err := c.uploadAsset(ctx, upload)
if err != nil {
return nil, caos_errs.ThrowInternal(err, "IAM-3S7fN", "Errors.Assets.Object.PutFailed")
}
orgAgg := OrgAggregateFromWriteModel(&existingPolicy.LabelPolicyWriteModel.WriteModel)
pushedEvents, err := c.eventstore.Push(ctx, org.NewLabelPolicyLogoDarkAddedEvent(ctx, orgAgg, storageKey))
pushedEvents, err := c.eventstore.Push(ctx, org.NewLabelPolicyLogoDarkAddedEvent(ctx, orgAgg, asset.Name))
if err != nil {
return nil, err
}
@@ -300,7 +304,7 @@ func (c *Commands) RemoveLogoDarkLabelPolicy(ctx context.Context, orgID string)
if existingPolicy.State == domain.PolicyStateUnspecified || existingPolicy.State == domain.PolicyStateRemoved {
return nil, caos_errs.ThrowNotFound(nil, "ORG-0peQw", "Errors.Org.LabelPolicy.NotFound")
}
err = c.RemoveAsset(ctx, orgID, existingPolicy.LogoDarkKey)
err = c.removeAsset(ctx, orgID, existingPolicy.LogoDarkKey)
if err != nil {
return nil, err
}
@@ -316,13 +320,10 @@ func (c *Commands) RemoveLogoDarkLabelPolicy(ctx context.Context, orgID string)
return writeModelToObjectDetails(&existingPolicy.LabelPolicyWriteModel.WriteModel), nil
}
func (c *Commands) AddIconDarkLabelPolicy(ctx context.Context, orgID, storageKey string) (*domain.ObjectDetails, error) {
func (c *Commands) AddIconDarkLabelPolicy(ctx context.Context, orgID string, upload *AssetUpload) (*domain.ObjectDetails, error) {
if orgID == "" {
return nil, caos_errs.ThrowInvalidArgument(nil, "Org-tzBfs", "Errors.ResourceOwnerMissing")
}
if storageKey == "" {
return nil, caos_errs.ThrowInvalidArgument(nil, "IAM-4B7cs", "Errors.Assets.EmptyKey")
}
existingPolicy, err := c.orgLabelPolicyWriteModelByID(ctx, orgID)
if err != nil {
return nil, err
@@ -331,8 +332,12 @@ func (c *Commands) AddIconDarkLabelPolicy(ctx context.Context, orgID, storageKey
if existingPolicy.State == domain.PolicyStateUnspecified || existingPolicy.State == domain.PolicyStateRemoved {
return nil, caos_errs.ThrowNotFound(nil, "ORG-4Nf8s", "Errors.Org.LabelPolicy.NotFound")
}
asset, err := c.uploadAsset(ctx, upload)
if err != nil {
return nil, caos_errs.ThrowInternal(err, "IAM-4B7cs", "Errors.Assets.Object.PutFailed")
}
orgAgg := OrgAggregateFromWriteModel(&existingPolicy.LabelPolicyWriteModel.WriteModel)
pushedEvents, err := c.eventstore.Push(ctx, org.NewLabelPolicyIconDarkAddedEvent(ctx, orgAgg, storageKey))
pushedEvents, err := c.eventstore.Push(ctx, org.NewLabelPolicyIconDarkAddedEvent(ctx, orgAgg, asset.Name))
if err != nil {
return nil, err
}
@@ -367,13 +372,10 @@ func (c *Commands) RemoveIconDarkLabelPolicy(ctx context.Context, orgID string)
return writeModelToObjectDetails(&existingPolicy.LabelPolicyWriteModel.WriteModel), nil
}
func (c *Commands) AddFontLabelPolicy(ctx context.Context, orgID, storageKey string) (*domain.ObjectDetails, error) {
func (c *Commands) AddFontLabelPolicy(ctx context.Context, orgID string, upload *AssetUpload) (*domain.ObjectDetails, error) {
if orgID == "" {
return nil, caos_errs.ThrowInvalidArgument(nil, "Org-1Nf9s", "Errors.ResourceOwnerMissing")
}
if storageKey == "" {
return nil, caos_errs.ThrowInvalidArgument(nil, "ORG-2f9fw", "Errors.Assets.EmptyKey")
}
existingPolicy, err := c.orgLabelPolicyWriteModelByID(ctx, orgID)
if err != nil {
return nil, err
@@ -382,8 +384,12 @@ func (c *Commands) AddFontLabelPolicy(ctx context.Context, orgID, storageKey str
if existingPolicy.State == domain.PolicyStateUnspecified || existingPolicy.State == domain.PolicyStateRemoved {
return nil, caos_errs.ThrowNotFound(nil, "ORG-2M9fs", "Errors.Org.LabelPolicy.NotFound")
}
asset, err := c.uploadAsset(ctx, upload)
if err != nil {
return nil, caos_errs.ThrowInternal(err, "ORG-2f9fw", "Errors.Assets.Object.PutFailed")
}
orgAgg := OrgAggregateFromWriteModel(&existingPolicy.LabelPolicyWriteModel.WriteModel)
pushedEvents, err := c.eventstore.Push(ctx, org.NewLabelPolicyFontAddedEvent(ctx, orgAgg, storageKey))
pushedEvents, err := c.eventstore.Push(ctx, org.NewLabelPolicyFontAddedEvent(ctx, orgAgg, asset.Name))
if err != nil {
return nil, err
}
@@ -447,7 +453,7 @@ func (c *Commands) removeLabelPolicy(ctx context.Context, existingPolicy *OrgLab
return nil, caos_errs.ThrowNotFound(nil, "Org-3M9df", "Errors.Org.LabelPolicy.NotFound")
}
err = c.RemoveAssetsFolder(ctx, existingPolicy.AggregateID, domain.LabelPolicyPrefix+"/", true)
err = c.removeAssetsFolder(ctx, existingPolicy.AggregateID, static.ObjectTypeStyling)
if err != nil {
return nil, err
}
@@ -463,7 +469,7 @@ func (c *Commands) removeLabelPolicyIfExists(ctx context.Context, orgID string)
if existingPolicy.State != domain.PolicyStateActive {
return nil, nil
}
err = c.RemoveAssetsFolder(ctx, orgID, domain.LabelPolicyPrefix+"/", true)
err = c.removeAssetsFolder(ctx, orgID, static.ObjectTypeStyling)
if err != nil {
return nil, err
}
@@ -472,7 +478,7 @@ func (c *Commands) removeLabelPolicyIfExists(ctx context.Context, orgID string)
}
func (c *Commands) removeLabelPolicyAssets(ctx context.Context, existingPolicy *OrgLabelPolicyWriteModel) (*org.LabelPolicyAssetsRemovedEvent, error) {
err := c.RemoveAssetsFolder(ctx, existingPolicy.AggregateID, domain.LabelPolicyPrefix+"/", true)
err := c.removeAssetsFolder(ctx, existingPolicy.AggregateID, static.ObjectTypeStyling)
if err != nil {
return nil, err
}

View File

@@ -1,6 +1,7 @@
package command
import (
"bytes"
"context"
"testing"
@@ -782,9 +783,9 @@ func TestCommandSide_AddLogoLabelPolicy(t *testing.T) {
storage static.Storage
}
type args struct {
ctx context.Context
orgID string
storageKey string
ctx context.Context
orgID string
upload *AssetUpload
}
type res struct {
want *domain.ObjectDetails
@@ -803,24 +804,17 @@ func TestCommandSide_AddLogoLabelPolicy(t *testing.T) {
t,
),
},
args: args{
ctx: context.Background(),
storageKey: "key",
},
res: res{
err: caos_errs.IsErrorInvalidArgument,
},
},
{
name: "storage key empty, invalid argument error",
fields: fields{
eventstore: eventstoreExpect(
t,
),
},
args: args{
ctx: context.Background(),
orgID: "org1",
orgID: "",
upload: &AssetUpload{
ResourceOwner: "org1",
ObjectName: "logo",
ContentType: "image",
ObjectType: static.ObjectTypeStyling,
File: bytes.NewReader([]byte("test")),
Size: 4,
},
},
res: res{
err: caos_errs.IsErrorInvalidArgument,
@@ -835,14 +829,63 @@ func TestCommandSide_AddLogoLabelPolicy(t *testing.T) {
),
},
args: args{
ctx: context.Background(),
orgID: "org1",
storageKey: "key",
ctx: context.Background(),
orgID: "org1",
upload: &AssetUpload{
ResourceOwner: "org1",
ObjectName: "logo",
ContentType: "image",
ObjectType: static.ObjectTypeStyling,
File: bytes.NewReader([]byte("test")),
Size: 4,
},
},
res: res{
err: caos_errs.IsNotFound,
},
},
{
name: "upload failed, error",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(
eventFromEventPusher(
org.NewLabelPolicyAddedEvent(context.Background(),
&org.NewAggregate("org1", "org1").Aggregate,
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
true,
true,
true,
),
),
),
),
storage: mock.NewStorage(t).ExpectPutObjectError(),
},
args: args{
ctx: context.Background(),
orgID: "org1",
upload: &AssetUpload{
ResourceOwner: "org1",
ObjectName: "logo",
ContentType: "image",
ObjectType: static.ObjectTypeStyling,
File: bytes.NewReader([]byte("test")),
Size: 4,
},
},
res: res{
err: caos_errs.IsInternal,
},
},
{
name: "logo added, ok",
fields: fields{
@@ -871,17 +914,25 @@ func TestCommandSide_AddLogoLabelPolicy(t *testing.T) {
eventFromEventPusher(
org.NewLabelPolicyLogoAddedEvent(context.Background(),
&org.NewAggregate("org1", "org1").Aggregate,
"key",
"logo",
),
),
},
),
),
storage: mock.NewStorage(t).ExpectPutObject(),
},
args: args{
ctx: context.Background(),
orgID: "org1",
storageKey: "key",
ctx: context.Background(),
orgID: "org1",
upload: &AssetUpload{
ResourceOwner: "org1",
ObjectName: "logo",
ContentType: "image",
ObjectType: static.ObjectTypeStyling,
File: bytes.NewReader([]byte("test")),
Size: 4,
},
},
res: res{
want: &domain.ObjectDetails{
@@ -896,7 +947,7 @@ func TestCommandSide_AddLogoLabelPolicy(t *testing.T) {
eventstore: tt.fields.eventstore,
static: tt.fields.storage,
}
got, err := r.AddLogoLabelPolicy(tt.args.ctx, tt.args.orgID, tt.args.storageKey)
got, err := r.AddLogoLabelPolicy(tt.args.ctx, tt.args.orgID, tt.args.upload)
if tt.res.err == nil {
assert.NoError(t, err)
}
@@ -1039,11 +1090,12 @@ func TestCommandSide_RemoveLogoLabelPolicy(t *testing.T) {
func TestCommandSide_AddIconLabelPolicy(t *testing.T) {
type fields struct {
eventstore *eventstore.Eventstore
storage static.Storage
}
type args struct {
ctx context.Context
orgID string
storageKey string
ctx context.Context
orgID string
upload *AssetUpload
}
type res struct {
want *domain.ObjectDetails
@@ -1062,24 +1114,17 @@ func TestCommandSide_AddIconLabelPolicy(t *testing.T) {
t,
),
},
args: args{
ctx: context.Background(),
storageKey: "key",
},
res: res{
err: caos_errs.IsErrorInvalidArgument,
},
},
{
name: "storage key empty, invalid argument error",
fields: fields{
eventstore: eventstoreExpect(
t,
),
},
args: args{
ctx: context.Background(),
orgID: "org1",
orgID: "",
upload: &AssetUpload{
ResourceOwner: "org1",
ObjectName: "icon",
ContentType: "image",
ObjectType: static.ObjectTypeStyling,
File: bytes.NewReader([]byte("test")),
Size: 4,
},
},
res: res{
err: caos_errs.IsErrorInvalidArgument,
@@ -1094,14 +1139,63 @@ func TestCommandSide_AddIconLabelPolicy(t *testing.T) {
),
},
args: args{
ctx: context.Background(),
orgID: "org1",
storageKey: "key",
ctx: context.Background(),
orgID: "org1",
upload: &AssetUpload{
ResourceOwner: "org1",
ObjectName: "icon",
ContentType: "image",
ObjectType: static.ObjectTypeStyling,
File: bytes.NewReader([]byte("test")),
Size: 4,
},
},
res: res{
err: caos_errs.IsNotFound,
},
},
{
name: "upload failed, error",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(
eventFromEventPusher(
org.NewLabelPolicyAddedEvent(context.Background(),
&org.NewAggregate("org1", "org1").Aggregate,
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
true,
true,
true,
),
),
),
),
storage: mock.NewStorage(t).ExpectPutObjectError(),
},
args: args{
ctx: context.Background(),
orgID: "org1",
upload: &AssetUpload{
ResourceOwner: "org1",
ObjectName: "icon",
ContentType: "image",
ObjectType: static.ObjectTypeStyling,
File: bytes.NewReader([]byte("test")),
Size: 4,
},
},
res: res{
err: caos_errs.IsInternal,
},
},
{
name: "icon added, ok",
fields: fields{
@@ -1130,17 +1224,25 @@ func TestCommandSide_AddIconLabelPolicy(t *testing.T) {
eventFromEventPusher(
org.NewLabelPolicyIconAddedEvent(context.Background(),
&org.NewAggregate("org1", "org1").Aggregate,
"key",
"icon",
),
),
},
),
),
storage: mock.NewStorage(t).ExpectPutObject(),
},
args: args{
ctx: context.Background(),
orgID: "org1",
storageKey: "key",
ctx: context.Background(),
orgID: "org1",
upload: &AssetUpload{
ResourceOwner: "org1",
ObjectName: "icon",
ContentType: "image",
ObjectType: static.ObjectTypeStyling,
File: bytes.NewReader([]byte("test")),
Size: 4,
},
},
res: res{
want: &domain.ObjectDetails{
@@ -1153,8 +1255,9 @@ func TestCommandSide_AddIconLabelPolicy(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
r := &Commands{
eventstore: tt.fields.eventstore,
static: tt.fields.storage,
}
got, err := r.AddIconLabelPolicy(tt.args.ctx, tt.args.orgID, tt.args.storageKey)
got, err := r.AddIconLabelPolicy(tt.args.ctx, tt.args.orgID, tt.args.upload)
if tt.res.err == nil {
assert.NoError(t, err)
}
@@ -1294,11 +1397,12 @@ func TestCommandSide_RemoveIconLabelPolicy(t *testing.T) {
func TestCommandSide_AddLogoDarkLabelPolicy(t *testing.T) {
type fields struct {
eventstore *eventstore.Eventstore
storage static.Storage
}
type args struct {
ctx context.Context
orgID string
storageKey string
ctx context.Context
orgID string
upload *AssetUpload
}
type res struct {
want *domain.ObjectDetails
@@ -1319,22 +1423,15 @@ func TestCommandSide_AddLogoDarkLabelPolicy(t *testing.T) {
},
args: args{
ctx: context.Background(),
orgID: "org1",
},
res: res{
err: caos_errs.IsErrorInvalidArgument,
},
},
{
name: "storage key empty, invalid argument error",
fields: fields{
eventstore: eventstoreExpect(
t,
),
},
args: args{
ctx: context.Background(),
orgID: "org1",
orgID: "",
upload: &AssetUpload{
ResourceOwner: "org1",
ObjectName: "logo",
ContentType: "image",
ObjectType: static.ObjectTypeStyling,
File: bytes.NewReader([]byte("test")),
Size: 4,
},
},
res: res{
err: caos_errs.IsErrorInvalidArgument,
@@ -1349,14 +1446,63 @@ func TestCommandSide_AddLogoDarkLabelPolicy(t *testing.T) {
),
},
args: args{
ctx: context.Background(),
orgID: "org1",
storageKey: "key",
ctx: context.Background(),
orgID: "org1",
upload: &AssetUpload{
ResourceOwner: "org1",
ObjectName: "logo",
ContentType: "image",
ObjectType: static.ObjectTypeStyling,
File: bytes.NewReader([]byte("test")),
Size: 4,
},
},
res: res{
err: caos_errs.IsNotFound,
},
},
{
name: "upload failed, error",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(
eventFromEventPusher(
org.NewLabelPolicyAddedEvent(context.Background(),
&org.NewAggregate("org1", "org1").Aggregate,
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
true,
true,
true,
),
),
),
),
storage: mock.NewStorage(t).ExpectPutObjectError(),
},
args: args{
ctx: context.Background(),
orgID: "org1",
upload: &AssetUpload{
ResourceOwner: "org1",
ObjectName: "logo",
ContentType: "image",
ObjectType: static.ObjectTypeStyling,
File: bytes.NewReader([]byte("test")),
Size: 4,
},
},
res: res{
err: caos_errs.IsInternal,
},
},
{
name: "logo dark added, ok",
fields: fields{
@@ -1385,17 +1531,25 @@ func TestCommandSide_AddLogoDarkLabelPolicy(t *testing.T) {
eventFromEventPusher(
org.NewLabelPolicyLogoDarkAddedEvent(context.Background(),
&org.NewAggregate("org1", "org1").Aggregate,
"key",
"logo",
),
),
},
),
),
storage: mock.NewStorage(t).ExpectPutObject(),
},
args: args{
ctx: context.Background(),
orgID: "org1",
storageKey: "key",
ctx: context.Background(),
orgID: "org1",
upload: &AssetUpload{
ResourceOwner: "org1",
ObjectName: "logo",
ContentType: "image",
ObjectType: static.ObjectTypeStyling,
File: bytes.NewReader([]byte("test")),
Size: 4,
},
},
res: res{
want: &domain.ObjectDetails{
@@ -1408,8 +1562,9 @@ func TestCommandSide_AddLogoDarkLabelPolicy(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
r := &Commands{
eventstore: tt.fields.eventstore,
static: tt.fields.storage,
}
got, err := r.AddLogoDarkLabelPolicy(tt.args.ctx, tt.args.orgID, tt.args.storageKey)
got, err := r.AddLogoDarkLabelPolicy(tt.args.ctx, tt.args.orgID, tt.args.upload)
if tt.res.err == nil {
assert.NoError(t, err)
}
@@ -1555,9 +1710,9 @@ func TestCommandSide_AddIconDarkLabelPolicy(t *testing.T) {
storage static.Storage
}
type args struct {
ctx context.Context
orgID string
storageKey string
ctx context.Context
orgID string
upload *AssetUpload
}
type res struct {
want *domain.ObjectDetails
@@ -1576,24 +1731,17 @@ func TestCommandSide_AddIconDarkLabelPolicy(t *testing.T) {
t,
),
},
args: args{
ctx: context.Background(),
storageKey: "key",
},
res: res{
err: caos_errs.IsErrorInvalidArgument,
},
},
{
name: "storage key empty, invalid argument error",
fields: fields{
eventstore: eventstoreExpect(
t,
),
},
args: args{
ctx: context.Background(),
orgID: "org1",
orgID: "",
upload: &AssetUpload{
ResourceOwner: "org1",
ObjectName: "icon",
ContentType: "image",
ObjectType: static.ObjectTypeStyling,
File: bytes.NewReader([]byte("test")),
Size: 4,
},
},
res: res{
err: caos_errs.IsErrorInvalidArgument,
@@ -1608,14 +1756,63 @@ func TestCommandSide_AddIconDarkLabelPolicy(t *testing.T) {
),
},
args: args{
ctx: context.Background(),
orgID: "org1",
storageKey: "key",
ctx: context.Background(),
orgID: "org1",
upload: &AssetUpload{
ResourceOwner: "org1",
ObjectName: "icon",
ContentType: "image",
ObjectType: static.ObjectTypeStyling,
File: bytes.NewReader([]byte("test")),
Size: 4,
},
},
res: res{
err: caos_errs.IsNotFound,
},
},
{
name: "upload failed, error",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(
eventFromEventPusher(
org.NewLabelPolicyAddedEvent(context.Background(),
&org.NewAggregate("org1", "org1").Aggregate,
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
true,
true,
true,
),
),
),
),
storage: mock.NewStorage(t).ExpectPutObjectError(),
},
args: args{
ctx: context.Background(),
orgID: "org1",
upload: &AssetUpload{
ResourceOwner: "org1",
ObjectName: "icon",
ContentType: "image",
ObjectType: static.ObjectTypeStyling,
File: bytes.NewReader([]byte("test")),
Size: 4,
},
},
res: res{
err: caos_errs.IsInternal,
},
},
{
name: "icon dark added, ok",
fields: fields{
@@ -1644,17 +1841,25 @@ func TestCommandSide_AddIconDarkLabelPolicy(t *testing.T) {
eventFromEventPusher(
org.NewLabelPolicyIconDarkAddedEvent(context.Background(),
&org.NewAggregate("org1", "org1").Aggregate,
"key",
"icon",
),
),
},
),
),
storage: mock.NewStorage(t).ExpectPutObject(),
},
args: args{
ctx: context.Background(),
orgID: "org1",
storageKey: "key",
ctx: context.Background(),
orgID: "org1",
upload: &AssetUpload{
ResourceOwner: "org1",
ObjectName: "icon",
ContentType: "image",
ObjectType: static.ObjectTypeStyling,
File: bytes.NewReader([]byte("test")),
Size: 4,
},
},
res: res{
want: &domain.ObjectDetails{
@@ -1667,8 +1872,9 @@ func TestCommandSide_AddIconDarkLabelPolicy(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
r := &Commands{
eventstore: tt.fields.eventstore,
static: tt.fields.storage,
}
got, err := r.AddIconDarkLabelPolicy(tt.args.ctx, tt.args.orgID, tt.args.storageKey)
got, err := r.AddIconDarkLabelPolicy(tt.args.ctx, tt.args.orgID, tt.args.upload)
if tt.res.err == nil {
assert.NoError(t, err)
}
@@ -1806,11 +2012,12 @@ func TestCommandSide_RemoveIconDarkLabelPolicy(t *testing.T) {
func TestCommandSide_AddFontLabelPolicy(t *testing.T) {
type fields struct {
eventstore *eventstore.Eventstore
storage static.Storage
}
type args struct {
ctx context.Context
orgID string
storageKey string
ctx context.Context
orgID string
upload *AssetUpload
}
type res struct {
want *domain.ObjectDetails
@@ -1829,24 +2036,17 @@ func TestCommandSide_AddFontLabelPolicy(t *testing.T) {
t,
),
},
args: args{
ctx: context.Background(),
storageKey: "key",
},
res: res{
err: caos_errs.IsErrorInvalidArgument,
},
},
{
name: "storage key empty, invalid argument error",
fields: fields{
eventstore: eventstoreExpect(
t,
),
},
args: args{
ctx: context.Background(),
orgID: "org1",
orgID: "",
upload: &AssetUpload{
ResourceOwner: "org1",
ObjectName: "font",
ContentType: "ttf",
ObjectType: static.ObjectTypeStyling,
File: bytes.NewReader([]byte("test")),
Size: 4,
},
},
res: res{
err: caos_errs.IsErrorInvalidArgument,
@@ -1861,14 +2061,55 @@ func TestCommandSide_AddFontLabelPolicy(t *testing.T) {
),
},
args: args{
ctx: context.Background(),
orgID: "org1",
storageKey: "key",
ctx: context.Background(),
orgID: "org1",
},
res: res{
err: caos_errs.IsNotFound,
},
},
{
name: "upload failed, error",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(
eventFromEventPusher(
org.NewLabelPolicyAddedEvent(context.Background(),
&org.NewAggregate("org1", "org1").Aggregate,
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
"#ffffff",
true,
true,
true,
),
),
),
),
storage: mock.NewStorage(t).ExpectPutObjectError(),
},
args: args{
ctx: context.Background(),
orgID: "org1",
upload: &AssetUpload{
ResourceOwner: "org1",
ObjectName: "font",
ContentType: "ttf",
ObjectType: static.ObjectTypeStyling,
File: bytes.NewReader([]byte("test")),
Size: 4,
},
},
res: res{
err: caos_errs.IsInternal,
},
},
{
name: "font added, ok",
fields: fields{
@@ -1897,17 +2138,25 @@ func TestCommandSide_AddFontLabelPolicy(t *testing.T) {
eventFromEventPusher(
org.NewLabelPolicyFontAddedEvent(context.Background(),
&org.NewAggregate("org1", "org1").Aggregate,
"key",
"font",
),
),
},
),
),
storage: mock.NewStorage(t).ExpectPutObject(),
},
args: args{
ctx: context.Background(),
orgID: "org1",
storageKey: "key",
ctx: context.Background(),
orgID: "org1",
upload: &AssetUpload{
ResourceOwner: "org1",
ObjectName: "font",
ContentType: "ttf",
ObjectType: static.ObjectTypeStyling,
File: bytes.NewReader([]byte("test")),
Size: 4,
},
},
res: res{
want: &domain.ObjectDetails{
@@ -1920,8 +2169,9 @@ func TestCommandSide_AddFontLabelPolicy(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
r := &Commands{
eventstore: tt.fields.eventstore,
static: tt.fields.storage,
}
got, err := r.AddFontLabelPolicy(tt.args.ctx, tt.args.orgID, tt.args.storageKey)
got, err := r.AddFontLabelPolicy(tt.args.ctx, tt.args.orgID, tt.args.upload)
if tt.res.err == nil {
assert.NoError(t, err)
}

View File

@@ -1,27 +1,70 @@
package command
import (
"bytes"
"context"
"io"
"strings"
"github.com/caos/zitadel/internal/domain"
"github.com/superseriousbusiness/exifremove/pkg/exifremove"
"github.com/caos/zitadel/internal/api/authz"
"github.com/caos/zitadel/internal/static"
)
func (c *Commands) UploadAsset(ctx context.Context, bucketName, objectName, contentType string, file io.Reader, size int64) (*domain.AssetInfo, error) {
type AssetUpload struct {
ResourceOwner string
ObjectName string
ContentType string
ObjectType static.ObjectType
File io.Reader
Size int64
}
func (c *Commands) uploadAsset(ctx context.Context, upload *AssetUpload) (*static.Asset, error) {
//TODO: handle location as soon as possible
file, size, err := removeExif(upload.File, upload.Size, upload.ContentType)
if err != nil {
return nil, err
}
return c.static.PutObject(ctx,
bucketName,
objectName,
contentType,
authz.GetInstance(ctx).InstanceID(),
"",
upload.ResourceOwner,
upload.ObjectName,
upload.ContentType,
upload.ObjectType,
file,
size,
true,
)
}
func (c *Commands) RemoveAsset(ctx context.Context, bucketName, storeKey string) error {
return c.static.RemoveObject(ctx, bucketName, storeKey)
func (c *Commands) removeAsset(ctx context.Context, resourceOwner, storeKey string) error {
return c.static.RemoveObject(ctx, authz.GetInstance(ctx).InstanceID(), resourceOwner, storeKey)
}
func (c *Commands) RemoveAssetsFolder(ctx context.Context, bucketName, path string, recursive bool) error {
return c.static.RemoveObjects(ctx, bucketName, path, recursive)
func (c *Commands) removeAssetsFolder(ctx context.Context, resourceOwner string, objectType static.ObjectType) error {
return c.static.RemoveObjects(ctx, authz.GetInstance(ctx).InstanceID(), resourceOwner, objectType)
}
func removeExif(file io.Reader, size int64, contentType string) (io.Reader, int64, error) {
if !isAllowedContentType(contentType) {
return file, size, nil
}
buf := new(bytes.Buffer)
_, err := buf.ReadFrom(file)
if err != nil {
return file, 0, err
}
data, err := exifremove.Remove(buf.Bytes())
if err != nil {
return nil, 0, err
}
return bytes.NewReader(data), int64(len(data)), nil
}
func isAllowedContentType(contentType string) bool {
return strings.HasSuffix(contentType, "png") ||
strings.HasSuffix(contentType, "jpg") ||
strings.HasSuffix(contentType, "jpeg")
}

View File

@@ -8,13 +8,10 @@ import (
"github.com/caos/zitadel/internal/repository/user"
)
func (c *Commands) AddHumanAvatar(ctx context.Context, orgID, userID, storageKey string) (*domain.ObjectDetails, error) {
func (c *Commands) AddHumanAvatar(ctx context.Context, orgID, userID string, upload *AssetUpload) (*domain.ObjectDetails, error) {
if userID == "" {
return nil, caos_errs.ThrowInvalidArgument(nil, "USER-Ba5Ds", "Errors.IDMissing")
}
if storageKey == "" {
return nil, caos_errs.ThrowInvalidArgument(nil, "USER-1Xyud", "Errors.Assets.EmptyKey")
}
existingUser, err := c.userWriteModelByID(ctx, userID, orgID)
if err != nil {
return nil, err
@@ -23,8 +20,12 @@ func (c *Commands) AddHumanAvatar(ctx context.Context, orgID, userID, storageKey
if existingUser.UserState == domain.UserStateUnspecified || existingUser.UserState == domain.UserStateDeleted {
return nil, caos_errs.ThrowNotFound(nil, "USER-vJ3fS", "Errors.Users.NotFound")
}
asset, err := c.uploadAsset(ctx, upload)
if err != nil {
return nil, caos_errs.ThrowInternal(err, "USER-1Xyud", "Errors.Assets.Object.PutFailed")
}
userAgg := UserAggregateFromWriteModel(&existingUser.WriteModel)
pushedEvents, err := c.eventstore.Push(ctx, user.NewHumanAvatarAddedEvent(ctx, userAgg, storageKey))
pushedEvents, err := c.eventstore.Push(ctx, user.NewHumanAvatarAddedEvent(ctx, userAgg, asset.Name))
if err != nil {
return nil, err
}
@@ -46,7 +47,7 @@ func (c *Commands) RemoveHumanAvatar(ctx context.Context, orgID, userID string)
if existingUser.UserState == domain.UserStateUnspecified || existingUser.UserState == domain.UserStateDeleted {
return nil, caos_errs.ThrowNotFound(nil, "USER-35N8f", "Errors.Users.NotFound")
}
err = c.RemoveAsset(ctx, orgID, existingUser.Avatar)
err = c.removeAsset(ctx, orgID, existingUser.Avatar)
if err != nil {
return nil, err
}

View File

@@ -1,6 +1,7 @@
package command
import (
"bytes"
"context"
"testing"
@@ -20,12 +21,13 @@ import (
func TestCommandSide_AddHumanAvatar(t *testing.T) {
type fields struct {
eventstore *eventstore.Eventstore
storage static.Storage
}
type args struct {
ctx context.Context
orgID string
userID string
storageKey string
ctx context.Context
orgID string
userID string
upload *AssetUpload
}
type res struct {
want *domain.ObjectDetails
@@ -44,25 +46,18 @@ func TestCommandSide_AddHumanAvatar(t *testing.T) {
t,
),
},
args: args{
ctx: context.Background(),
storageKey: "key",
},
res: res{
err: caos_errs.IsErrorInvalidArgument,
},
},
{
name: "storage key empty, invalid argument error",
fields: fields{
eventstore: eventstoreExpect(
t,
),
},
args: args{
ctx: context.Background(),
orgID: "org1",
userID: "user1",
orgID: "",
userID: "",
upload: &AssetUpload{
ResourceOwner: "org1",
ObjectName: "avatar",
ContentType: "image",
ObjectType: static.ObjectTypeUserAvatar,
File: bytes.NewReader([]byte("test")),
Size: 4,
},
},
res: res{
err: caos_errs.IsErrorInvalidArgument,
@@ -77,17 +72,65 @@ func TestCommandSide_AddHumanAvatar(t *testing.T) {
),
},
args: args{
ctx: context.Background(),
orgID: "org1",
userID: "user1",
storageKey: "key",
ctx: context.Background(),
orgID: "org1",
userID: "user1",
upload: &AssetUpload{
ResourceOwner: "org1",
ObjectName: "avatar",
ContentType: "image",
ObjectType: static.ObjectTypeUserAvatar,
File: bytes.NewReader([]byte("test")),
Size: 4,
},
},
res: res{
err: caos_errs.IsNotFound,
},
},
{
name: "logo added, ok",
name: "upload failed, error",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(
eventFromEventPusher(
user.NewHumanAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"username",
"firstname",
"lastname",
"nickname",
"displayname",
language.Und,
domain.GenderUnspecified,
"email@test.ch",
true,
),
),
),
),
storage: mock.NewStorage(t).ExpectPutObjectError(),
},
args: args{
ctx: context.Background(),
orgID: "org1",
userID: "user1",
upload: &AssetUpload{
ResourceOwner: "org1",
ObjectName: "avatar",
ContentType: "image",
ObjectType: static.ObjectTypeUserAvatar,
File: bytes.NewReader([]byte("test")),
Size: 4,
},
},
res: res{
err: caos_errs.IsInternal,
},
},
{
name: "avatar added, ok",
fields: fields{
eventstore: eventstoreExpect(
t,
@@ -112,18 +155,26 @@ func TestCommandSide_AddHumanAvatar(t *testing.T) {
eventFromEventPusher(
user.NewHumanAvatarAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"key",
"avatar",
),
),
},
),
),
storage: mock.NewStorage(t).ExpectPutObject(),
},
args: args{
ctx: context.Background(),
orgID: "org1",
userID: "user1",
storageKey: "key",
ctx: context.Background(),
orgID: "org1",
userID: "user1",
upload: &AssetUpload{
ResourceOwner: "org1",
ObjectName: "avatar",
ContentType: "image",
ObjectType: static.ObjectTypeUserAvatar,
File: bytes.NewReader([]byte("test")),
Size: 4,
},
},
res: res{
want: &domain.ObjectDetails{
@@ -136,8 +187,9 @@ func TestCommandSide_AddHumanAvatar(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
r := &Commands{
eventstore: tt.fields.eventstore,
static: tt.fields.storage,
}
got, err := r.AddHumanAvatar(tt.args.ctx, tt.args.orgID, tt.args.userID, tt.args.storageKey)
got, err := r.AddHumanAvatar(tt.args.ctx, tt.args.orgID, tt.args.userID, tt.args.upload)
if tt.res.err == nil {
assert.NoError(t, err)
}

View File

@@ -27,8 +27,32 @@ const (
)
type InstanceSetup struct {
Org OrgSetup
Zitadel ZitadelConfig
Org OrgSetup
Zitadel ZitadelConfig
Features struct {
TierName string
TierDescription string
Retention time.Duration
State domain.FeaturesState
StateDescription string
LoginPolicyFactors bool
LoginPolicyIDP bool
LoginPolicyPasswordless bool
LoginPolicyRegistration bool
LoginPolicyUsernameLogin bool
LoginPolicyPasswordReset bool
PasswordComplexityPolicy bool
LabelPolicyPrivateLabel bool
LabelPolicyWatermark bool
CustomDomain bool
PrivacyPolicy bool
MetadataUser bool
CustomTextMessage bool
CustomTextLogin bool
LockoutPolicy bool
ActionsAllowed domain.ActionsAllowed
MaxActions int
}
PasswordComplexityPolicy struct {
MinLength uint64
HasLowercase bool
@@ -170,6 +194,31 @@ func (command *Command) SetUpInstance(ctx context.Context, setup *InstanceSetup)
projectAgg := project.NewAggregate(setup.Zitadel.projectID, orgID)
validations := []preparation.Validation{
SetDefaultFeatures(
instanceAgg,
setup.Features.TierName,
setup.Features.TierDescription,
setup.Features.State,
setup.Features.StateDescription,
setup.Features.Retention,
setup.Features.LoginPolicyFactors,
setup.Features.LoginPolicyIDP,
setup.Features.LoginPolicyPasswordless,
setup.Features.LoginPolicyRegistration,
setup.Features.LoginPolicyUsernameLogin,
setup.Features.LoginPolicyPasswordReset,
setup.Features.PasswordComplexityPolicy,
setup.Features.LabelPolicyPrivateLabel,
setup.Features.LabelPolicyWatermark,
setup.Features.CustomDomain,
setup.Features.PrivacyPolicy,
setup.Features.MetadataUser,
setup.Features.CustomTextMessage,
setup.Features.CustomTextLogin,
setup.Features.LockoutPolicy,
setup.Features.ActionsAllowed,
setup.Features.MaxActions,
),
AddPasswordComplexityPolicy(
instanceAgg,
setup.PasswordComplexityPolicy.MinLength,

View File

@@ -0,0 +1,95 @@
package command
import (
"context"
"time"
"github.com/caos/zitadel/internal/command"
"github.com/caos/zitadel/internal/command/v2/preparation"
"github.com/caos/zitadel/internal/domain"
"github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/eventstore"
"github.com/caos/zitadel/internal/repository/instance"
)
func SetDefaultFeatures(
a *instance.Aggregate,
tierName,
tierDescription string,
state domain.FeaturesState,
stateDescription string,
retention time.Duration,
loginPolicyFactors,
loginPolicyIDP,
loginPolicyPasswordless,
loginPolicyRegistration,
loginPolicyUsernameLogin,
loginPolicyPasswordReset,
passwordComplexityPolicy,
labelPolicyPrivateLabel,
labelPolicyWatermark,
customDomain,
privacyPolicy,
metadataUser,
customTextMessage,
customTextLogin,
lockoutPolicy bool,
actionsAllowed domain.ActionsAllowed,
maxActions int,
) preparation.Validation {
return func() (preparation.CreateCommands, error) {
if !state.Valid() || state == domain.FeaturesStateUnspecified || state == domain.FeaturesStateRemoved {
return nil, errors.ThrowInvalidArgument(nil, "INSTA-d3r1s", "Errors.Invalid.Argument")
}
return func(ctx context.Context, filter preparation.FilterToQueryReducer) ([]eventstore.Command, error) {
writeModel, err := defaultFeatures(ctx, filter)
if err != nil {
return nil, err
}
event, hasChanged := writeModel.NewSetEvent(ctx, &a.Aggregate,
tierName,
tierDescription,
state,
stateDescription,
retention,
loginPolicyFactors,
loginPolicyIDP,
loginPolicyPasswordless,
loginPolicyRegistration,
loginPolicyUsernameLogin,
loginPolicyPasswordReset,
passwordComplexityPolicy,
labelPolicyPrivateLabel,
labelPolicyWatermark,
customDomain,
privacyPolicy,
metadataUser,
customTextMessage,
customTextLogin,
lockoutPolicy,
actionsAllowed,
maxActions,
)
if !hasChanged {
return nil, errors.ThrowPreconditionFailed(nil, "INSTA-GE4h2", "Errors.Features.NotChanged")
}
return []eventstore.Command{
event,
}, nil
}, nil
}
}
func defaultFeatures(ctx context.Context, filter preparation.FilterToQueryReducer) (*command.InstanceFeaturesWriteModel, error) {
features := command.NewInstanceFeaturesWriteModel(ctx)
events, err := filter(ctx, features.Query())
if err != nil {
return nil, err
}
if len(events) == 0 {
return features, nil
}
features.AppendEvents(events...)
err = features.Reduce()
return features, err
}

View File

@@ -0,0 +1,152 @@
package command
import (
"context"
"testing"
"time"
"github.com/caos/zitadel/internal/domain"
"github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/eventstore"
"github.com/caos/zitadel/internal/repository/features"
"github.com/caos/zitadel/internal/repository/instance"
)
func TestSetDefaultFeatures(t *testing.T) {
type args struct {
a *instance.Aggregate
tierName string
tierDescription string
state domain.FeaturesState
stateDescription string
retention time.Duration
loginPolicyFactors bool
loginPolicyIDP bool
loginPolicyPasswordless bool
loginPolicyRegistration bool
loginPolicyUsernameLogin bool
loginPolicyPasswordReset bool
passwordComplexityPolicy bool
labelPolicyPrivateLabel bool
labelPolicyWatermark bool
customDomain bool
privacyPolicy bool
metadataUser bool
customTextMessage bool
customTextLogin bool
lockoutPolicy bool
actionsAllowed domain.ActionsAllowed
maxActions int
}
tests := []struct {
name string
args args
want Want
}{
{
name: "invalid state",
args: args{
a: instance.NewAggregate("INSTANCE"),
tierName: "",
tierDescription: "",
state: 0,
stateDescription: "",
retention: 0,
loginPolicyFactors: false,
loginPolicyIDP: false,
loginPolicyPasswordless: false,
loginPolicyRegistration: false,
loginPolicyUsernameLogin: false,
loginPolicyPasswordReset: false,
passwordComplexityPolicy: false,
labelPolicyPrivateLabel: false,
labelPolicyWatermark: false,
customDomain: false,
privacyPolicy: false,
metadataUser: false,
customTextMessage: false,
customTextLogin: false,
lockoutPolicy: false,
actionsAllowed: 0,
maxActions: 0,
},
want: Want{
ValidationErr: errors.ThrowInvalidArgument(nil, "INSTA-d3r1s", "Errors.Invalid.Argument"),
},
},
{
name: "correct",
args: args{
a: instance.NewAggregate("INSTANCE"),
tierName: "",
tierDescription: "",
state: domain.FeaturesStateActive,
stateDescription: "",
retention: 0,
loginPolicyFactors: false,
loginPolicyIDP: false,
loginPolicyPasswordless: false,
loginPolicyRegistration: false,
loginPolicyUsernameLogin: false,
loginPolicyPasswordReset: false,
passwordComplexityPolicy: false,
labelPolicyPrivateLabel: false,
labelPolicyWatermark: false,
customDomain: false,
privacyPolicy: false,
metadataUser: false,
customTextMessage: false,
customTextLogin: false,
lockoutPolicy: false,
actionsAllowed: 0,
maxActions: 0,
},
want: Want{
Commands: []eventstore.Command{
func() *instance.FeaturesSetEvent {
event, _ := instance.NewFeaturesSetEvent(context.Background(), &instance.NewAggregate("INSTANCE").Aggregate,
[]features.FeaturesChanges{
features.ChangeState(domain.FeaturesStateActive),
},
)
return event
}(),
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
AssertValidation(t, SetDefaultFeatures(
tt.args.a,
tt.args.tierName,
tt.args.tierDescription,
tt.args.state,
tt.args.stateDescription,
tt.args.retention,
tt.args.loginPolicyFactors,
tt.args.loginPolicyIDP,
tt.args.loginPolicyPasswordless,
tt.args.loginPolicyRegistration,
tt.args.loginPolicyUsernameLogin,
tt.args.loginPolicyPasswordReset,
tt.args.passwordComplexityPolicy,
tt.args.labelPolicyPrivateLabel,
tt.args.labelPolicyWatermark,
tt.args.customDomain,
tt.args.privacyPolicy,
tt.args.metadataUser,
tt.args.customTextMessage,
tt.args.customTextLogin,
tt.args.lockoutPolicy,
tt.args.actionsAllowed,
tt.args.maxActions,
), NewMultiFilter().
Append(func(ctx context.Context, queryFactory *eventstore.SearchQueryBuilder) ([]eventstore.Event, error) {
return nil, nil
}).
Filter(),
tt.want)
})
}
}