fix: label policy (#1828)

* fix: font color

* fix: assets from iam when policy is default

* fix: remove multiple files

* fix mock storage

* doc: add asset api

* build assets docs

* fix operator test

* docs

* fix remove assets from org label policy and not default

* fix remove label policy assets and feature downgrade correctly

* fix storage mock

* Update docs/docs/apis/apis.md

Co-authored-by: fabi <fabienne.gerschwiler@gmail.com>
Co-authored-by: Fabi <38692350+fgerschwiler@users.noreply.github.com>
This commit is contained in:
Livio Amstutz
2021-06-08 09:48:44 +02:00
committed by GitHub
parent 0ed722395e
commit 81974b977d
34 changed files with 641 additions and 162 deletions

View File

@@ -174,6 +174,12 @@ func (m *Styling) writeFile(policy *iam_model.LabelPolicyView) (io.Reader, int64
cssContent += fmt.Sprintf("--zitadel-color-warn-%v: %s;", i, color)
}
}
if policy.FontColor != "" {
palette := m.generateColorPaletteRGBA255(policy.FontColor)
for i, color := range palette {
cssContent += fmt.Sprintf("--zitadel-color-text-%v: %s;", i, color)
}
}
var fontname string
if policy.FontURL != "" {
split := strings.Split(policy.FontURL, "/")
@@ -206,7 +212,7 @@ func (m *Styling) writeFile(policy *iam_model.LabelPolicyView) (io.Reader, int64
if policy.FontColorDark != "" {
palette := m.generateColorPaletteRGBA255(policy.FontColorDark)
for i, color := range palette {
cssContent += fmt.Sprintf("--zitadel-color-font-%v: %s;", i, color)
cssContent += fmt.Sprintf("--zitadel-color-text-%v: %s;", i, color)
}
}
cssContent += fmt.Sprint("}")

View File

@@ -123,7 +123,7 @@ func UploadHandleFunc(s AssetsService, uploader Uploader) func(http.ResponseWrit
contentType := handler.Header.Get("content-type")
size := handler.Size
if !uploader.ContentTypeAllowed(contentType) {
s.ErrorHandler()(w, r, caos_errs.ThrowInvalidArgument(nil, "UPLOAD-Dbvfs", "invalid content-type"))
s.ErrorHandler()(w, r, caos_errs.ThrowInvalidArgumentf(nil, "UPLOAD-Dbvfs", "invalid content-type: %s", contentType))
return
}
if size > uploader.MaxFileSize() {

View File

@@ -13,6 +13,7 @@ import (
var (
directory = flag.String("directory", "./", "working directory: asset.yaml must be in this directory, files will be generated into parent directory")
assets = flag.String("assets", "../../../../docs/docs/apis/assets/assets.md", "path where the assets.md will be generated")
)
func main() {
@@ -22,7 +23,9 @@ func main() {
logging.Log("ASSETS-Gn31f").OnError(err).Fatal("cannot open authz file")
router, err := os.OpenFile(*directory+"../router.go", os.O_TRUNC|os.O_WRONLY|os.O_CREATE, 0755)
logging.Log("ASSETS-ABen3").OnError(err).Fatal("cannot open router file")
GenerateAssetHandler(configFile, authz, router)
docs, err := os.OpenFile(*assets, os.O_TRUNC|os.O_WRONLY|os.O_CREATE, 0755)
logging.Log("ASSETS-Dfvsd").OnError(err).Fatal("cannot open docs file")
GenerateAssetHandler(configFile, authz, router, docs)
}
type Method struct {
@@ -94,7 +97,7 @@ type Service struct {
Methods map[string]Method
}
func GenerateAssetHandler(configFilePath string, output io.Writer, output2 io.Writer) {
func GenerateAssetHandler(configFilePath string, authz, router, docs io.Writer) {
conf := new(struct {
Services Services
})
@@ -104,6 +107,8 @@ func GenerateAssetHandler(configFilePath string, output io.Writer, output2 io.Wr
logging.Log("ASSETS-BGbbg").OnError(err).Fatal("cannot parse authz template")
tmplRouter, err := template.New("").Parse(routerTmpl)
logging.Log("ASSETS-gh4rq").OnError(err).Fatal("cannot parse router template")
tmplDocs, err := template.New("").Parse(docsTmpl)
logging.Log("ASSETS-FGdgs").OnError(err).Fatal("cannot parse docs template")
data := &struct {
GoPkgName string
Name string
@@ -115,10 +120,12 @@ func GenerateAssetHandler(configFilePath string, output io.Writer, output2 io.Wr
Prefix: "/assets/v1",
Services: conf.Services,
}
err = tmplAuthz.Execute(output, data)
err = tmplAuthz.Execute(authz, data)
logging.Log("ASSETS-BHngj").OnError(err).Fatal("cannot generate authz")
err = tmplRouter.Execute(output2, data)
err = tmplRouter.Execute(router, data)
logging.Log("ASSETS-Bfd41").OnError(err).Fatal("cannot generate router")
err = tmplDocs.Execute(docs, data)
logging.Log("ASSETS-Bfd41").OnError(err).Fatal("cannot generate docs")
}
const authzTmpl = `package {{.GoPkgName}}
@@ -198,3 +205,30 @@ func RegisterRoutes(router *mux.Router, s {{.Name}}) {
{{ end }}
}
`
const docsTmpl = `---
title: zitadel/admin.proto
---
## {{.Name}}
{{ range $service := .Services}}
{{ range $methodName, $method := .Methods}}
{{ range $handler := .Handlers}}
### {{$handler.Name}}{{$methodName}}()
> {{$handler.Name}}{{$methodName}}()
{{$handler.Method}}: {{$service.Prefix}}{{$method.Path}}{{$handler.PathSuffix}}
{{ if $method.HasDarkMode }}
### {{$handler.Name}}{{$methodName}}()
> {{$handler.Name}}{{$methodName}}Dark()
{{$handler.Method}}: {{$service.Prefix}}{{$method.Path}}/dark{{$handler.PathSuffix}}
{{ end }}
{{ end }}
{{ end }}
{{ end }}
`

View File

@@ -136,10 +136,7 @@ func (l *labelPolicyLogoDownloader) ObjectName(ctx context.Context, path string)
}
func (l *labelPolicyLogoDownloader) BucketName(ctx context.Context, id string) string {
if l.defaultPolicy {
return domain.IAMID
}
return authz.GetCtxData(ctx).OrgID
return getLabelPolicyBucketName(ctx, l.defaultPolicy, l.preview, l.org)
}
func (h *Handler) UploadDefaultLabelPolicyIcon() Uploader {
@@ -267,10 +264,7 @@ func (l *labelPolicyIconDownloader) ObjectName(ctx context.Context, path string)
}
func (l *labelPolicyIconDownloader) BucketName(ctx context.Context, id string) string {
if l.defaultPolicy {
return domain.IAMID
}
return authz.GetCtxData(ctx).OrgID
return getLabelPolicyBucketName(ctx, l.defaultPolicy, l.preview, l.org)
}
func (h *Handler) UploadDefaultLabelPolicyFont() Uploader {
@@ -357,10 +351,7 @@ func (l *labelPolicyFontDownloader) ObjectName(ctx context.Context, path string)
}
func (l *labelPolicyFontDownloader) BucketName(ctx context.Context, id string) string {
if l.defaultPolicy {
return domain.IAMID
}
return authz.GetCtxData(ctx).OrgID
return getLabelPolicyBucketName(ctx, l.defaultPolicy, l.preview, l.org)
}
func getLabelPolicy(ctx context.Context, defaultPolicy, preview bool, orgRepo repository.OrgRepository) (*model.LabelPolicyView, error) {
@@ -375,3 +366,17 @@ func getLabelPolicy(ctx context.Context, defaultPolicy, preview bool, orgRepo re
}
return orgRepo.GetLabelPolicy(ctx)
}
func getLabelPolicyBucketName(ctx context.Context, defaultPolicy, preview bool, org repository.OrgRepository) string {
if defaultPolicy {
return domain.IAMID
}
policy, err := getLabelPolicy(ctx, defaultPolicy, preview, org)
if err != nil {
return ""
}
if policy.Default {
return domain.IAMID
}
return authz.GetCtxData(ctx).OrgID
}

View File

@@ -86,7 +86,7 @@ func (s *Server) ResetLabelPolicyToDefault(ctx context.Context, req *mgmt_pb.Res
}
func (s *Server) RemoveCustomLabelPolicyLogo(ctx context.Context, req *mgmt_pb.RemoveCustomLabelPolicyLogoRequest) (*mgmt_pb.RemoveCustomLabelPolicyLogoResponse, error) {
policy, err := s.command.RemoveLogoDefaultLabelPolicy(ctx)
policy, err := s.command.RemoveLogoLabelPolicy(ctx, authz.GetCtxData(ctx).OrgID)
if err != nil {
return nil, err
}
@@ -100,7 +100,7 @@ func (s *Server) RemoveCustomLabelPolicyLogo(ctx context.Context, req *mgmt_pb.R
}
func (s *Server) RemoveCustomLabelPolicyLogoDark(ctx context.Context, req *mgmt_pb.RemoveCustomLabelPolicyLogoDarkRequest) (*mgmt_pb.RemoveCustomLabelPolicyLogoDarkResponse, error) {
policy, err := s.command.RemoveLogoDarkDefaultLabelPolicy(ctx)
policy, err := s.command.RemoveLogoDarkLabelPolicy(ctx, authz.GetCtxData(ctx).OrgID)
if err != nil {
return nil, err
}
@@ -114,7 +114,7 @@ func (s *Server) RemoveCustomLabelPolicyLogoDark(ctx context.Context, req *mgmt_
}
func (s *Server) RemoveCustomLabelPolicyIcon(ctx context.Context, req *mgmt_pb.RemoveCustomLabelPolicyIconRequest) (*mgmt_pb.RemoveCustomLabelPolicyIconResponse, error) {
policy, err := s.command.RemoveIconDefaultLabelPolicy(ctx)
policy, err := s.command.RemoveIconLabelPolicy(ctx, authz.GetCtxData(ctx).OrgID)
if err != nil {
return nil, err
}
@@ -128,7 +128,7 @@ func (s *Server) RemoveCustomLabelPolicyIcon(ctx context.Context, req *mgmt_pb.R
}
func (s *Server) RemoveCustomLabelPolicyIconDark(ctx context.Context, req *mgmt_pb.RemoveCustomLabelPolicyIconDarkRequest) (*mgmt_pb.RemoveCustomLabelPolicyIconDarkResponse, error) {
policy, err := s.command.RemoveIconDarkDefaultLabelPolicy(ctx)
policy, err := s.command.RemoveIconDarkLabelPolicy(ctx, authz.GetCtxData(ctx).OrgID)
if err != nil {
return nil, err
}
@@ -142,7 +142,7 @@ func (s *Server) RemoveCustomLabelPolicyIconDark(ctx context.Context, req *mgmt_
}
func (s *Server) RemoveCustomLabelPolicyFont(ctx context.Context, req *mgmt_pb.RemoveCustomLabelPolicyFontRequest) (*mgmt_pb.RemoveCustomLabelPolicyFontResponse, error) {
policy, err := s.command.RemoveFontDefaultLabelPolicy(ctx)
policy, err := s.command.RemoveFontLabelPolicy(ctx, authz.GetCtxData(ctx).OrgID)
if err != nil {
return nil, err
}

View File

@@ -98,6 +98,8 @@ func (m *LabelPolicy) processLabelPolicy(event *models.Event) (err error) {
return err
}
err = policy.AppendEvent(event)
case model.LabelPolicyRemoved:
return m.view.DeleteLabelPolicy(event.AggregateID, event)
default:
return m.view.ProcessedLabelPolicySequence(event)
}

View File

@@ -279,12 +279,15 @@ func (c *Commands) setAllowedLabelPolicy(ctx context.Context, orgID string, feat
}
events = append(events, assetsEvent)
}
changedEvent, hasChanged := existingPolicy.NewChangedEvent(ctx, OrgAggregateFromWriteModel(&existingPolicy.WriteModel),
changedEvent, hasChangedEvent := existingPolicy.NewChangedEvent(ctx, OrgAggregateFromWriteModel(&existingPolicy.WriteModel),
policy.PrimaryColor, policy.BackgroundColor, policy.WarnColor, policy.FontColor,
policy.PrimaryColorDark, policy.BackgroundColorDark, policy.WarnColorDark, policy.FontColorDark,
policy.HideLoginNameSuffix, policy.ErrorMsgPopup, policy.HideLoginNameSuffix)
if hasChanged {
if hasChangedEvent {
events = append(events, changedEvent)
}
if len(events) > 0 {
events = append(events, org.NewLabelPolicyActivatedEvent(ctx, OrgAggregateFromWriteModel(&existingPolicy.WriteModel)))
}
return events, nil
}

View File

@@ -958,7 +958,7 @@ func TestCommandSide_SetOrgFeatures(t *testing.T) {
),
),
iamDomain: "iam-domain",
static: mock.NewMockStorage(gomock.NewController(t)).ExpectRemoveObjectNoError(),
static: mock.NewMockStorage(gomock.NewController(t)).ExpectRemoveObjectsNoError(),
},
args: args{
ctx: context.Background(),

View File

@@ -324,10 +324,6 @@ func (c *Commands) RemoveIconDarkLabelPolicy(ctx context.Context, orgID string)
if existingPolicy.State == domain.PolicyStateUnspecified || existingPolicy.State == domain.PolicyStateRemoved {
return nil, caos_errs.ThrowNotFound(nil, "ORG-3NFos", "Errors.Org.LabelPolicy.NotFound")
}
err = c.RemoveAsset(ctx, orgID, existingPolicy.IconDarkKey)
if err != nil {
return nil, err
}
orgAgg := OrgAggregateFromWriteModel(&existingPolicy.LabelPolicyWriteModel.WriteModel)
pushedEvents, err := c.eventstore.PushEvents(ctx, org.NewLabelPolicyIconDarkRemovedEvent(ctx, orgAgg, existingPolicy.IconDarkKey))
if err != nil {
@@ -379,10 +375,6 @@ func (c *Commands) RemoveFontLabelPolicy(ctx context.Context, orgID string) (*do
if existingPolicy.State == domain.PolicyStateUnspecified || existingPolicy.State == domain.PolicyStateRemoved {
return nil, caos_errs.ThrowNotFound(nil, "ORG-4n9SD", "Errors.Org.LabelPolicy.NotFound")
}
err = c.RemoveAsset(ctx, orgID, existingPolicy.FontKey)
if err != nil {
return nil, err
}
orgAgg := OrgAggregateFromWriteModel(&existingPolicy.LabelPolicyWriteModel.WriteModel)
pushedEvents, err := c.eventstore.PushEvents(ctx, org.NewLabelPolicyFontRemovedEvent(ctx, orgAgg, existingPolicy.FontKey))
if err != nil {
@@ -423,7 +415,8 @@ func (c *Commands) removeLabelPolicy(ctx context.Context, existingPolicy *OrgLab
if existingPolicy.State == domain.PolicyStateUnspecified || existingPolicy.State == domain.PolicyStateRemoved {
return nil, caos_errs.ThrowNotFound(nil, "Org-3M9df", "Errors.Org.LabelPolicy.NotFound")
}
err = c.RemoveAsset(ctx, existingPolicy.AggregateID, domain.LabelPolicyPrefix)
err = c.RemoveAssetsFolder(ctx, existingPolicy.AggregateID, domain.LabelPolicyPrefix+"/", true)
if err != nil {
return nil, err
}
@@ -439,7 +432,7 @@ func (c *Commands) removeLabelPolicyIfExists(ctx context.Context, orgID string)
if existingPolicy.State != domain.PolicyStateActive {
return nil, nil
}
err = c.RemoveAsset(ctx, orgID, domain.LabelPolicyPrefix)
err = c.RemoveAssetsFolder(ctx, orgID, domain.LabelPolicyPrefix+"/", true)
if err != nil {
return nil, err
}
@@ -448,7 +441,7 @@ func (c *Commands) removeLabelPolicyIfExists(ctx context.Context, orgID string)
}
func (c *Commands) removeLabelPolicyAssets(ctx context.Context, existingPolicy *OrgLabelPolicyWriteModel) (*org.LabelPolicyAssetsRemovedEvent, error) {
err := c.RemoveAsset(ctx, existingPolicy.AggregateID, domain.LabelPolicyPrefix)
err := c.RemoveAssetsFolder(ctx, existingPolicy.AggregateID, domain.LabelPolicyPrefix+"/", true)
if err != nil {
return nil, err
}

View File

@@ -575,7 +575,7 @@ func TestCommandSide_RemoveLabelPolicy(t *testing.T) {
},
),
),
static: mock.NewMockStorage(gomock.NewController(t)).ExpectRemoveObjectNoError(),
static: mock.NewMockStorage(gomock.NewController(t)).ExpectRemoveObjectsNoError(),
},
args: args{
ctx: context.Background(),
@@ -1559,7 +1559,6 @@ func TestCommandSide_RemoveIconDarkLabelPolicy(t *testing.T) {
{
name: "icon dark added, ok",
fields: fields{
storage: mock.NewMockStorage(gomock.NewController(t)).ExpectRemoveObjectNoError(),
eventstore: eventstoreExpect(
t,
expectFilter(
@@ -1813,7 +1812,6 @@ func TestCommandSide_RemoveFontLabelPolicy(t *testing.T) {
{
name: "font added, ok",
fields: fields{
storage: mock.NewMockStorage(gomock.NewController(t)).ExpectRemoveObjectNoError(),
eventstore: eventstoreExpect(
t,
expectFilter(

View File

@@ -25,3 +25,7 @@ func (c *Commands) UploadAsset(ctx context.Context, bucketName, objectName, cont
func (c *Commands) RemoveAsset(ctx context.Context, bucketName, storeKey string) error {
return c.static.RemoveObject(ctx, bucketName, storeKey)
}
func (c *Commands) RemoveAssetsFolder(ctx context.Context, bucketName, path string, recursive bool) error {
return c.static.RemoveObjects(ctx, bucketName, path, recursive)
}

View File

@@ -4,6 +4,7 @@ import (
"context"
"github.com/caos/logging"
"github.com/caos/zitadel/internal/domain"
"github.com/caos/zitadel/internal/eventstore/v1"
es_models "github.com/caos/zitadel/internal/eventstore/v1/models"
@@ -100,6 +101,8 @@ func (m *LabelPolicy) processLabelPolicy(event *es_models.Event) (err error) {
return err
}
err = policy.AppendEvent(event)
case model.LabelPolicyRemoved:
return m.view.DeleteLabelPolicy(event.AggregateID, event)
case iam_es_model.LabelPolicyActivated, model.LabelPolicyActivated:
policy, err = m.view.LabelPolicyByAggregateIDAndState(event.AggregateID, int32(domain.LabelPolicyStatePreview))
if err != nil {
@@ -135,15 +138,21 @@ func (p *LabelPolicy) CleanUpBucket(policy *iam_model.LabelPolicyView) {
return
}
for _, object := range objects {
if !deleteableObject(object, policy) {
if !deletableObject(object, policy) {
continue
}
p.static.RemoveObject(ctx, policy.AggregateID, object.Key)
err = p.static.RemoveObject(ctx, policy.AggregateID, object.Key)
logging.LogWithFields("SPOOL-ASd3g", "aggregate", policy.AggregateID, "key", object.Key).OnError(err).Warn("could not delete asset")
}
}
func deleteableObject(object *domain.AssetInfo, policy *iam_model.LabelPolicyView) bool {
if object.Key == policy.LogoURL || object.Key == policy.LogoDarkURL || object.Key == policy.IconURL || object.Key == policy.IconDarkURL || object.Key == policy.FontURL {
func deletableObject(object *domain.AssetInfo, policy *iam_model.LabelPolicyView) bool {
if object.Key == policy.LogoURL ||
object.Key == policy.LogoDarkURL ||
object.Key == policy.IconURL ||
object.Key == policy.IconDarkURL ||
object.Key == policy.FontURL ||
object.Key == domain.LabelPolicyPrefix+"/css/" {
return false
}
return true

View File

@@ -6,39 +6,40 @@ package mock
import (
context "context"
domain "github.com/caos/zitadel/internal/domain"
static "github.com/caos/zitadel/internal/static"
gomock "github.com/golang/mock/gomock"
io "io"
url "net/url"
reflect "reflect"
time "time"
domain "github.com/caos/zitadel/internal/domain"
static "github.com/caos/zitadel/internal/static"
gomock "github.com/golang/mock/gomock"
)
// MockStorage is a mock of Storage interface
// MockStorage is a mock of Storage interface.
type MockStorage struct {
ctrl *gomock.Controller
recorder *MockStorageMockRecorder
}
// MockStorageMockRecorder is the mock recorder for MockStorage
// MockStorageMockRecorder is the mock recorder for MockStorage.
type MockStorageMockRecorder struct {
mock *MockStorage
}
// NewMockStorage creates a new mock instance
// NewMockStorage creates a new mock instance.
func NewMockStorage(ctrl *gomock.Controller) *MockStorage {
mock := &MockStorage{ctrl: ctrl}
mock.recorder = &MockStorageMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockStorage) EXPECT() *MockStorageMockRecorder {
return m.recorder
}
// CreateBucket mocks base method
// CreateBucket mocks base method.
func (m *MockStorage) CreateBucket(ctx context.Context, name, location string) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "CreateBucket", ctx, name, location)
@@ -46,72 +47,13 @@ func (m *MockStorage) CreateBucket(ctx context.Context, name, location string) e
return ret0
}
// CreateBucket indicates an expected call of CreateBucket
// CreateBucket indicates an expected call of CreateBucket.
func (mr *MockStorageMockRecorder) CreateBucket(ctx, name, location interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateBucket", reflect.TypeOf((*MockStorage)(nil).CreateBucket), ctx, name, location)
}
// RemoveBucket mocks base method
func (m *MockStorage) RemoveBucket(ctx context.Context, name string) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "RemoveBucket", ctx, name)
ret0, _ := ret[0].(error)
return ret0
}
// RemoveBucket indicates an expected call of RemoveBucket
func (mr *MockStorageMockRecorder) RemoveBucket(ctx, name interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveBucket", reflect.TypeOf((*MockStorage)(nil).RemoveBucket), ctx, name)
}
// ListBuckets mocks base method
func (m *MockStorage) ListBuckets(ctx context.Context) ([]*domain.BucketInfo, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ListBuckets", ctx)
ret0, _ := ret[0].([]*domain.BucketInfo)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// ListBuckets indicates an expected call of ListBuckets
func (mr *MockStorageMockRecorder) ListBuckets(ctx interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListBuckets", reflect.TypeOf((*MockStorage)(nil).ListBuckets), ctx)
}
// PutObject mocks base method
func (m *MockStorage) PutObject(ctx context.Context, bucketName, objectName, contentType string, object io.Reader, objectSize int64, createBucketIfNotExisting bool) (*domain.AssetInfo, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "PutObject", ctx, bucketName, objectName, contentType, object, objectSize, createBucketIfNotExisting)
ret0, _ := ret[0].(*domain.AssetInfo)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// PutObject indicates an expected call of PutObject
func (mr *MockStorageMockRecorder) PutObject(ctx, bucketName, objectName, contentType, object, objectSize, createBucketIfNotExisting interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutObject", reflect.TypeOf((*MockStorage)(nil).PutObject), ctx, bucketName, objectName, contentType, object, objectSize, createBucketIfNotExisting)
}
// GetObjectInfo mocks base method
func (m *MockStorage) GetObjectInfo(ctx context.Context, bucketName, objectName string) (*domain.AssetInfo, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetObjectInfo", ctx, bucketName, objectName)
ret0, _ := ret[0].(*domain.AssetInfo)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetObjectInfo indicates an expected call of GetObjectInfo
func (mr *MockStorageMockRecorder) GetObjectInfo(ctx, bucketName, objectName interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetObjectInfo", reflect.TypeOf((*MockStorage)(nil).GetObjectInfo), ctx, bucketName, objectName)
}
// GetObject mocks base method
// GetObject mocks base method.
func (m *MockStorage) GetObject(ctx context.Context, bucketName, objectName string) (io.Reader, func() (*domain.AssetInfo, error), error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetObject", ctx, bucketName, objectName)
@@ -121,28 +63,28 @@ func (m *MockStorage) GetObject(ctx context.Context, bucketName, objectName stri
return ret0, ret1, ret2
}
// GetObject indicates an expected call of GetObject
// GetObject indicates an expected call of GetObject.
func (mr *MockStorageMockRecorder) GetObject(ctx, bucketName, objectName interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetObject", reflect.TypeOf((*MockStorage)(nil).GetObject), ctx, bucketName, objectName)
}
// ListObjectInfos mocks base method
func (m *MockStorage) ListObjectInfos(ctx context.Context, bucketName, prefix string, recursive bool) ([]*domain.AssetInfo, error) {
// GetObjectInfo mocks base method.
func (m *MockStorage) GetObjectInfo(ctx context.Context, bucketName, objectName string) (*domain.AssetInfo, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ListObjectInfos", ctx, bucketName, prefix, recursive)
ret0, _ := ret[0].([]*domain.AssetInfo)
ret := m.ctrl.Call(m, "GetObjectInfo", ctx, bucketName, objectName)
ret0, _ := ret[0].(*domain.AssetInfo)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// ListObjectInfos indicates an expected call of ListObjectInfos
func (mr *MockStorageMockRecorder) ListObjectInfos(ctx, bucketName, prefix, recursive interface{}) *gomock.Call {
// GetObjectInfo indicates an expected call of GetObjectInfo.
func (mr *MockStorageMockRecorder) GetObjectInfo(ctx, bucketName, objectName interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListObjectInfos", reflect.TypeOf((*MockStorage)(nil).ListObjectInfos), ctx, bucketName, prefix, recursive)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetObjectInfo", reflect.TypeOf((*MockStorage)(nil).GetObjectInfo), ctx, bucketName, objectName)
}
// GetObjectPresignedURL mocks base method
// GetObjectPresignedURL mocks base method.
func (m *MockStorage) GetObjectPresignedURL(ctx context.Context, bucketName, objectName string, expiration time.Duration) (*url.URL, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetObjectPresignedURL", ctx, bucketName, objectName, expiration)
@@ -151,13 +93,72 @@ func (m *MockStorage) GetObjectPresignedURL(ctx context.Context, bucketName, obj
return ret0, ret1
}
// GetObjectPresignedURL indicates an expected call of GetObjectPresignedURL
// GetObjectPresignedURL indicates an expected call of GetObjectPresignedURL.
func (mr *MockStorageMockRecorder) GetObjectPresignedURL(ctx, bucketName, objectName, expiration interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetObjectPresignedURL", reflect.TypeOf((*MockStorage)(nil).GetObjectPresignedURL), ctx, bucketName, objectName, expiration)
}
// RemoveObject mocks base method
// ListBuckets mocks base method.
func (m *MockStorage) ListBuckets(ctx context.Context) ([]*domain.BucketInfo, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ListBuckets", ctx)
ret0, _ := ret[0].([]*domain.BucketInfo)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// ListBuckets indicates an expected call of ListBuckets.
func (mr *MockStorageMockRecorder) ListBuckets(ctx interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListBuckets", reflect.TypeOf((*MockStorage)(nil).ListBuckets), ctx)
}
// ListObjectInfos mocks base method.
func (m *MockStorage) ListObjectInfos(ctx context.Context, bucketName, prefix string, recursive bool) ([]*domain.AssetInfo, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ListObjectInfos", ctx, bucketName, prefix, recursive)
ret0, _ := ret[0].([]*domain.AssetInfo)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// ListObjectInfos indicates an expected call of ListObjectInfos.
func (mr *MockStorageMockRecorder) ListObjectInfos(ctx, bucketName, prefix, recursive interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListObjectInfos", reflect.TypeOf((*MockStorage)(nil).ListObjectInfos), ctx, bucketName, prefix, recursive)
}
// PutObject mocks base method.
func (m *MockStorage) PutObject(ctx context.Context, bucketName, objectName, contentType string, object io.Reader, objectSize int64, createBucketIfNotExisting bool) (*domain.AssetInfo, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "PutObject", ctx, bucketName, objectName, contentType, object, objectSize, createBucketIfNotExisting)
ret0, _ := ret[0].(*domain.AssetInfo)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// PutObject indicates an expected call of PutObject.
func (mr *MockStorageMockRecorder) PutObject(ctx, bucketName, objectName, contentType, object, objectSize, createBucketIfNotExisting interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PutObject", reflect.TypeOf((*MockStorage)(nil).PutObject), ctx, bucketName, objectName, contentType, object, objectSize, createBucketIfNotExisting)
}
// RemoveBucket mocks base method.
func (m *MockStorage) RemoveBucket(ctx context.Context, name string) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "RemoveBucket", ctx, name)
ret0, _ := ret[0].(error)
return ret0
}
// RemoveBucket indicates an expected call of RemoveBucket.
func (mr *MockStorageMockRecorder) RemoveBucket(ctx, name interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveBucket", reflect.TypeOf((*MockStorage)(nil).RemoveBucket), ctx, name)
}
// RemoveObject mocks base method.
func (m *MockStorage) RemoveObject(ctx context.Context, bucketName, objectName string) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "RemoveObject", ctx, bucketName, objectName)
@@ -165,36 +166,50 @@ func (m *MockStorage) RemoveObject(ctx context.Context, bucketName, objectName s
return ret0
}
// RemoveObject indicates an expected call of RemoveObject
// RemoveObject indicates an expected call of RemoveObject.
func (mr *MockStorageMockRecorder) RemoveObject(ctx, bucketName, objectName interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveObject", reflect.TypeOf((*MockStorage)(nil).RemoveObject), ctx, bucketName, objectName)
}
// MockConfig is a mock of Config interface
// RemoveObjects mocks base method.
func (m *MockStorage) RemoveObjects(ctx context.Context, bucketName, path string, recursive bool) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "RemoveObjects", ctx, bucketName, path, recursive)
ret0, _ := ret[0].(error)
return ret0
}
// RemoveObjects indicates an expected call of RemoveObjects.
func (mr *MockStorageMockRecorder) RemoveObjects(ctx, bucketName, path, recursive interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveObjects", reflect.TypeOf((*MockStorage)(nil).RemoveObjects), ctx, bucketName, path, recursive)
}
// MockConfig is a mock of Config interface.
type MockConfig struct {
ctrl *gomock.Controller
recorder *MockConfigMockRecorder
}
// MockConfigMockRecorder is the mock recorder for MockConfig
// MockConfigMockRecorder is the mock recorder for MockConfig.
type MockConfigMockRecorder struct {
mock *MockConfig
}
// NewMockConfig creates a new mock instance
// NewMockConfig creates a new mock instance.
func NewMockConfig(ctrl *gomock.Controller) *MockConfig {
mock := &MockConfig{ctrl: ctrl}
mock.recorder = &MockConfigMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockConfig) EXPECT() *MockConfigMockRecorder {
return m.recorder
}
// NewStorage mocks base method
// NewStorage mocks base method.
func (m *MockConfig) NewStorage() (static.Storage, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "NewStorage")
@@ -203,7 +218,7 @@ func (m *MockConfig) NewStorage() (static.Storage, error) {
return ret0, ret1
}
// NewStorage indicates an expected call of NewStorage
// NewStorage indicates an expected call of NewStorage.
func (mr *MockConfigMockRecorder) NewStorage() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewStorage", reflect.TypeOf((*MockConfig)(nil).NewStorage))

View File

@@ -33,6 +33,13 @@ func (m *MockStorage) ExpectRemoveObjectNoError() *MockStorage {
return m
}
func (m *MockStorage) ExpectRemoveObjectsNoError() *MockStorage {
m.EXPECT().
RemoveObjects(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).
Return(nil)
return m
}
func (m *MockStorage) ExpectRemoveObjectError() *MockStorage {
m.EXPECT().
RemoveObject(gomock.Any(), gomock.Any(), gomock.Any()).

View File

@@ -15,6 +15,7 @@ type Config struct {
SSL bool
Location string
BucketPrefix string
MultiDelete bool
}
func (c *Config) NewStorage() (static.Storage, error) {
@@ -30,5 +31,6 @@ func (c *Config) NewStorage() (static.Storage, error) {
Client: minioClient,
Location: c.Location,
BucketPrefix: c.BucketPrefix,
MultiDelete: c.MultiDelete,
}, nil
}

View File

@@ -10,6 +10,7 @@ import (
"github.com/caos/logging"
"github.com/minio/minio-go/v7"
"golang.org/x/sync/errgroup"
"github.com/caos/zitadel/internal/domain"
caos_errs "github.com/caos/zitadel/internal/errors"
@@ -19,6 +20,7 @@ type Minio struct {
Client *minio.Client
Location string
BucketPrefix string
MultiDelete bool
}
func (m *Minio) CreateBucket(ctx context.Context, name, location string) error {
@@ -128,15 +130,11 @@ func (m *Minio) GetObjectPresignedURL(ctx context.Context, bucketName, objectNam
func (m *Minio) ListObjectInfos(ctx context.Context, bucketName, prefix string, recursive bool) ([]*domain.AssetInfo, error) {
bucketName = m.prefixBucketName(bucketName)
ctx, cancel := context.WithCancel(ctx)
defer cancel()
objectCh := m.Client.ListObjects(ctx, bucketName, minio.ListObjectsOptions{
Prefix: prefix,
Recursive: recursive,
})
assetInfos := make([]*domain.AssetInfo, 0)
for object := range objectCh {
objects, cancel := m.listObjects(ctx, bucketName, prefix, recursive)
defer cancel()
for object := range objects {
if object.Err != nil {
logging.LogWithFields("MINIO-wC8sd", "bucket-name", bucketName, "prefix", prefix).WithError(object.Err).Debug("unable to get object")
return nil, caos_errs.ThrowInternal(object.Err, "MINIO-1m09S", "Errors.Assets.Object.ListFailed")
@@ -155,6 +153,47 @@ func (m *Minio) RemoveObject(ctx context.Context, bucketName, objectName string)
return nil
}
func (m *Minio) RemoveObjects(ctx context.Context, bucketName, path string, recursive bool) error {
bucketName = m.prefixBucketName(bucketName)
objectsCh := make(chan minio.ObjectInfo)
g := new(errgroup.Group)
g.Go(func() error {
defer close(objectsCh)
objects, cancel := m.listObjects(ctx, bucketName, path, recursive)
for object := range objects {
if object.Err != nil {
cancel()
return caos_errs.ThrowInternal(object.Err, "MINIO-WQF32", "Errors.Assets.Object.ListFailed")
}
objectsCh <- object
}
return nil
})
if m.MultiDelete {
for objError := range m.Client.RemoveObjects(ctx, bucketName, objectsCh, minio.RemoveObjectsOptions{GovernanceBypass: true}) {
return caos_errs.ThrowInternal(objError.Err, "MINIO-Sfdgr", "Errors.Assets.Object.RemoveFailed")
}
return g.Wait()
}
for objectInfo := range objectsCh {
if err := m.Client.RemoveObject(ctx, bucketName, objectInfo.Key, minio.RemoveObjectOptions{GovernanceBypass: true}); err != nil {
return caos_errs.ThrowInternal(err, "MINIO-GVgew", "Errors.Assets.Object.RemoveFailed")
}
}
return g.Wait()
}
func (m *Minio) listObjects(ctx context.Context, bucketName, prefix string, recursive bool) (<-chan minio.ObjectInfo, context.CancelFunc) {
ctxCancel, cancel := context.WithCancel(ctx)
return m.Client.ListObjects(ctxCancel, bucketName, minio.ListObjectsOptions{
Prefix: prefix,
Recursive: recursive,
}), cancel
}
func (m *Minio) objectToAssetInfo(bucketName string, object minio.ObjectInfo) *domain.AssetInfo {
return &domain.AssetInfo{
Bucket: bucketName,

View File

@@ -19,6 +19,7 @@ type Storage interface {
ListObjectInfos(ctx context.Context, bucketName, prefix string, recursive bool) ([]*domain.AssetInfo, error)
GetObjectPresignedURL(ctx context.Context, bucketName, objectName string, expiration time.Duration) (*url.URL, error)
RemoveObject(ctx context.Context, bucketName, objectName string) error
RemoveObjects(ctx context.Context, bucketName, path string, recursive bool) error
}
type Config interface {
NewStorage() (Storage, error)

View File

@@ -3,6 +3,7 @@
--zitadel-color-background: var(--zitadel-color-background-500);
--zitadel-color-secondary: var(--zitadel-color-secondary-500);
--zitadel-color-warn: var(--zitadel-color-warn-500);
--zitadel-color-text: var(--zitadel-color-text-500);
--zitadel-color-primary-50: #eaedfa;
--zitadel-color-primary-100: #ccd2f2;
@@ -42,7 +43,18 @@
--zitadel-font-family: 'Lato';
--zitadel-color-background-500: var(--zitadel-color-grey-50);
--zitadel-color-background-50: rgb(255, 255, 255);
--zitadel-color-background-100: rgb(255, 255, 255);
--zitadel-color-background-200: rgb(255, 255, 255);
--zitadel-color-background-300: rgb(255, 255, 255);
--zitadel-color-background-400: rgb(255, 255, 255);
--zitadel-color-background-500: rgb(250, 250, 250);
--zitadel-color-background-600: rgb(222, 222, 222);
--zitadel-color-background-700: rgb(195, 195, 194);
--zitadel-color-background-800: rgb(168, 168, 168);
--zitadel-color-background-900: rgb(142, 142, 142);
--zitadel-color-background-contrast: rgb(0, 0, 0);
--zitadel-color-footer-line: #e3e8ee;
--zitadel-color-input-background: #fafafa50;
@@ -50,7 +62,17 @@
--zitadel-color-input-border-hover: #1a1b1b;
--zitadel-color-input-placeholder: var(--zitadel-color-grey-600);
--zitadel-color-text: rgba(0, 0, 0, 0.87);
--zitadel-color-font-50: rgb(0, 0, 0);
--zitadel-color-font-100: rgb(0, 0, 0);
--zitadel-color-font-200: rgb(0, 0, 0);
--zitadel-color-font-300: rgb(0, 0, 0);
--zitadel-color-font-400: rgb(0, 0, 0);
--zitadel-color-font-500: rgb(0, 0, 0);
--zitadel-color-font-600: rgb(0, 0, 0);
--zitadel-color-font-700: rgb(0, 0, 0);
--zitadel-color-font-800: rgb(0, 0, 0);
--zitadel-color-font-900: rgb(0, 0, 0);
--zitadel-color-font-contrast: rgb(255, 255, 255);
--zitadel-color-label: var(--zitadel-color-grey-600);
@@ -69,7 +91,6 @@
--zitadel-color-raised-button-background: var(--zitadel-color-white);
--zitadel-color-white: #ffffff;
--zitadel-color-black: #000000;
--zitadel-color-grey-50: #fafafa;
--zitadel-color-grey-100: #f5f5f5;
@@ -128,7 +149,18 @@
--zitadel-font-family: 'Lato';
--zitadel-color-background-500: var(--zitadel-color-grey-900);
--zitadel-color-background-50: rgb(60, 60, 60);
--zitadel-color-background-100: rgb(55, 55, 55);
--zitadel-color-background-200: rgb(49, 49, 49);
--zitadel-color-background-300: rgb(44, 44, 44);
--zitadel-color-background-400: rgb(36, 36, 36);
--zitadel-color-background-500: rgb(33, 33, 33);
--zitadel-color-background-600: rgb(30, 30, 30);
--zitadel-color-background-700: rgb(28, 28, 28);
--zitadel-color-background-800: rgb(25, 25, 25);
--zitadel-color-background-900: rgb(23, 23, 23);
--zitadel-color-background-contrast: rgb(255, 255, 255);
--zitadel-color-footer-line: #303131;
--zitadel-color-input-background: rgba(0, 0, 0, 0.2);
@@ -136,7 +168,17 @@
--zitadel-color-input-border-hover: #aeafb1;
--zitadel-color-input-placeholder: var(--zitadel-color-grey-600);
--zitadel-color-text: var(--zitadel-color-white);
--zitadel-color-text-50: rgb(255, 255, 255);
--zitadel-color-text-100: rgb(255, 255, 255);
--zitadel-color-text-200: rgb(255, 255, 255);
--zitadel-color-text-300: rgb(255, 255, 255);
--zitadel-color-text-400: rgb(255, 255, 255);
--zitadel-color-text-500: rgb(255, 255, 255);
--zitadel-color-text-600: rgb(221, 222, 223);
--zitadel-color-text-700: rgb(194, 195, 195);
--zitadel-color-text-800: rgb(167, 168, 169);
--zitadel-color-text-900: rgb(141, 142, 143);
--zitadel-color-text-contrast: rgb(0, 0, 0);
--zitadel-color-label: var(--zitadel-color-grey-600);
--zitadel-color-account-selector-hover: rgba(255, 255, 255, 0.02);
@@ -162,4 +204,4 @@
--zitadel-color-google-text: #8b8d8d;
--zitadel-color-google-background: #ffffff;
}
}

View File

@@ -4,6 +4,7 @@
--zitadel-color-background: var(--zitadel-color-background-500);
--zitadel-color-secondary: var(--zitadel-color-secondary-500);
--zitadel-color-warn: var(--zitadel-color-warn-500);
--zitadel-color-text: var(--zitadel-color-text-500);
--zitadel-color-primary-50: #eaedfa;
--zitadel-color-primary-100: #ccd2f2;
--zitadel-color-primary-200: #aab4ea;
@@ -38,13 +39,33 @@
--zitadel-color-warn-800: #c62828;
--zitadel-color-warn-900: #b71c1c;
--zitadel-font-family: "Lato";
--zitadel-color-background-500: var(--zitadel-color-grey-50);
--zitadel-color-background-50: rgb(255, 255, 255);
--zitadel-color-background-100: rgb(255, 255, 255);
--zitadel-color-background-200: rgb(255, 255, 255);
--zitadel-color-background-300: rgb(255, 255, 255);
--zitadel-color-background-400: rgb(255, 255, 255);
--zitadel-color-background-500: rgb(250, 250, 250);
--zitadel-color-background-600: rgb(222, 222, 222);
--zitadel-color-background-700: rgb(195, 195, 194);
--zitadel-color-background-800: rgb(168, 168, 168);
--zitadel-color-background-900: rgb(142, 142, 142);
--zitadel-color-background-contrast: rgb(0, 0, 0);
--zitadel-color-footer-line: #e3e8ee;
--zitadel-color-input-background: #fafafa50;
--zitadel-color-input-border: #00000040;
--zitadel-color-input-border-hover: #1a1b1b;
--zitadel-color-input-placeholder: var(--zitadel-color-grey-600);
--zitadel-color-text: rgba(0, 0, 0, 0.87);
--zitadel-color-font-50: rgb(0, 0, 0);
--zitadel-color-font-100: rgb(0, 0, 0);
--zitadel-color-font-200: rgb(0, 0, 0);
--zitadel-color-font-300: rgb(0, 0, 0);
--zitadel-color-font-400: rgb(0, 0, 0);
--zitadel-color-font-500: rgb(0, 0, 0);
--zitadel-color-font-600: rgb(0, 0, 0);
--zitadel-color-font-700: rgb(0, 0, 0);
--zitadel-color-font-800: rgb(0, 0, 0);
--zitadel-color-font-900: rgb(0, 0, 0);
--zitadel-color-font-contrast: rgb(255, 255, 255);
--zitadel-color-label: var(--zitadel-color-grey-600);
--zitadel-color-account-selector-hover: rgba(0, 0, 0, 0.02);
--zitadel-color-account-selector-active: rgba(0, 0, 0, 0.05);
@@ -56,7 +77,6 @@
--zitadel-color-button-selected-background: var(--zitadel-color-grey-900);
--zitadel-color-button-disabled-selected-background: var(--zitadel-color-grey-800);
--zitadel-color-raised-button-background: var(--zitadel-color-white);
--zitadel-color-white: #ffffff;
--zitadel-color-black: #000000;
--zitadel-color-grey-50: #fafafa;
--zitadel-color-grey-100: #f5f5f5;
@@ -108,13 +128,33 @@
--zitadel-color-warn-800: #c62828;
--zitadel-color-warn-900: #b71c1c;
--zitadel-font-family: "Lato";
--zitadel-color-background-500: var(--zitadel-color-grey-900);
--zitadel-color-background-50: rgb(60, 60, 60);
--zitadel-color-background-100: rgb(55, 55, 55);
--zitadel-color-background-200: rgb(49, 49, 49);
--zitadel-color-background-300: rgb(44, 44, 44);
--zitadel-color-background-400: rgb(36, 36, 36);
--zitadel-color-background-500: rgb(33, 33, 33);
--zitadel-color-background-600: rgb(30, 30, 30);
--zitadel-color-background-700: rgb(28, 28, 28);
--zitadel-color-background-800: rgb(25, 25, 25);
--zitadel-color-background-900: rgb(23, 23, 23);
--zitadel-color-background-contrast: rgb(255, 255, 255);
--zitadel-color-footer-line: #303131;
--zitadel-color-input-background: rgba(0, 0, 0, 0.2);
--zitadel-color-input-border: #403e3e;
--zitadel-color-input-border-hover: #aeafb1;
--zitadel-color-input-placeholder: var(--zitadel-color-grey-600);
--zitadel-color-text: var(--zitadel-color-white);
--zitadel-color-text-50: rgb(255, 255, 255);
--zitadel-color-text-100: rgb(255, 255, 255);
--zitadel-color-text-200: rgb(255, 255, 255);
--zitadel-color-text-300: rgb(255, 255, 255);
--zitadel-color-text-400: rgb(255, 255, 255);
--zitadel-color-text-500: rgb(255, 255, 255);
--zitadel-color-text-600: rgb(221, 222, 223);
--zitadel-color-text-700: rgb(194, 195, 195);
--zitadel-color-text-800: rgb(167, 168, 169);
--zitadel-color-text-900: rgb(141, 142, 143);
--zitadel-color-text-contrast: rgb(0, 0, 0);
--zitadel-color-label: var(--zitadel-color-grey-600);
--zitadel-color-account-selector-hover: rgba(255, 255, 255, 0.02);
--zitadel-color-account-selector-active: rgba(255, 255, 255, 0.05);

File diff suppressed because one or more lines are too long