mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-12 07:57:32 +00:00
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:
@@ -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("}")
|
||||
|
@@ -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() {
|
||||
|
@@ -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 }}
|
||||
`
|
||||
|
@@ -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
|
||||
}
|
||||
|
@@ -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
|
||||
}
|
||||
|
@@ -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)
|
||||
}
|
||||
|
@@ -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
|
||||
}
|
||||
|
@@ -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(),
|
||||
|
@@ -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
|
||||
}
|
||||
|
@@ -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(
|
||||
|
@@ -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)
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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))
|
||||
|
@@ -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()).
|
||||
|
@@ -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
|
||||
}
|
||||
|
@@ -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,
|
||||
|
@@ -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)
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
@@ -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
Reference in New Issue
Block a user