mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-12 11:27:33 +00:00
feat: handle instance from context (#3382)
* commander * commander * selber! * move to packages * fix(errors): implement Is interface * test: command * test: commands * add init steps * setup tenant * add default step yaml * possibility to set password * merge v2 into v2-commander * fix: rename iam command side to instance * fix: rename iam command side to instance * fix: rename iam command side to instance * fix: rename iam command side to instance * fix: search query builder can filter events in memory * fix: filters for add member * fix(setup): add `ExternalSecure` to config * chore: name iam to instance * fix: matching * remove unsued func * base url * base url * test(command): filter funcs * test: commands * fix: rename orgiampolicy to domain policy * start from init * commands * config * fix indexes and add constraints * fixes * fix: merge conflicts * fix: protos * fix: md files * setup * add deprecated org iam policy again * typo * fix search query * fix filter * Apply suggestions from code review * remove custom org from org setup * add todos for verification * change apps creation * simplify package structure * fix error * move preparation helper for tests * fix unique constraints * fix config mapping in setup * fix error handling in encryption_keys.go * fix projection config * fix query from old views to projection * fix setup of mgmt api * set iam project and fix instance projection * fix tokens view * fix steps.yaml and defaults.yaml * fix projections * change instance context to interface * instance interceptors and additional events in setup * cleanup * tests for interceptors * fix label policy * add todo * single api endpoint in environment.json Co-authored-by: adlerhurst <silvan.reusser@gmail.com> Co-authored-by: fabi <fabienne.gerschwiler@gmail.com>
This commit is contained in:
@@ -61,6 +61,19 @@ type InstanceSetup struct {
|
||||
PrivacyLink string
|
||||
HelpLink string
|
||||
}
|
||||
LabelPolicy struct {
|
||||
PrimaryColor string
|
||||
BackgroundColor string
|
||||
WarnColor string
|
||||
FontColor string
|
||||
PrimaryColorDark string
|
||||
BackgroundColorDark string
|
||||
WarnColorDark string
|
||||
FontColorDark string
|
||||
HideLoginNameSuffix bool
|
||||
ErrorMsgPopup bool
|
||||
DisableWatermark bool
|
||||
}
|
||||
LockoutPolicy struct {
|
||||
MaxAttempts uint64
|
||||
ShouldShowLockoutFailure bool
|
||||
@@ -134,7 +147,7 @@ func (command *Command) SetUpInstance(ctx context.Context, setup *InstanceSetup)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
ctx = authz.SetCtxData(authz.WithInstance(ctx, authz.Instance{ID: "system"}), authz.CtxData{OrgID: domain.IAMID, ResourceOwner: domain.IAMID})
|
||||
ctx = authz.SetCtxData(authz.WithInstanceID(ctx, "system"), authz.CtxData{OrgID: domain.IAMID, ResourceOwner: domain.IAMID})
|
||||
|
||||
orgID, err := id.SonyFlakeGenerator.Next()
|
||||
if err != nil {
|
||||
@@ -196,6 +209,22 @@ func (command *Command) SetUpInstance(ctx context.Context, setup *InstanceSetup)
|
||||
AddPrivacyPolicy(instanceAgg, setup.PrivacyPolicy.TOSLink, setup.PrivacyPolicy.PrivacyLink, setup.PrivacyPolicy.HelpLink),
|
||||
AddDefaultLockoutPolicy(instanceAgg, setup.LockoutPolicy.MaxAttempts, setup.LockoutPolicy.ShouldShowLockoutFailure),
|
||||
|
||||
AddDefaultLabelPolicy(
|
||||
instanceAgg,
|
||||
setup.LabelPolicy.PrimaryColor,
|
||||
setup.LabelPolicy.BackgroundColor,
|
||||
setup.LabelPolicy.WarnColor,
|
||||
setup.LabelPolicy.FontColor,
|
||||
setup.LabelPolicy.PrimaryColorDark,
|
||||
setup.LabelPolicy.BackgroundColorDark,
|
||||
setup.LabelPolicy.WarnColorDark,
|
||||
setup.LabelPolicy.FontColorDark,
|
||||
setup.LabelPolicy.HideLoginNameSuffix,
|
||||
setup.LabelPolicy.ErrorMsgPopup,
|
||||
setup.LabelPolicy.DisableWatermark,
|
||||
),
|
||||
ActivateDefaultLabelPolicy(instanceAgg),
|
||||
|
||||
AddEmailTemplate(instanceAgg, setup.EmailTemplate),
|
||||
}
|
||||
|
||||
@@ -207,9 +236,9 @@ func (command *Command) SetUpInstance(ctx context.Context, setup *InstanceSetup)
|
||||
AddOrg(orgAgg, setup.Org.Name, command.iamDomain),
|
||||
AddHumanCommand(userAgg, &setup.Org.Human, command.userPasswordAlg),
|
||||
AddOrgMember(orgAgg, userID, domain.RoleOrgOwner),
|
||||
AddInstanceMember(instanceAgg, userID, domain.RoleIAMOwner),
|
||||
|
||||
AddProject(projectAgg, zitadelProjectName, userID, false, false, false, domain.PrivateLabelingSettingUnspecified),
|
||||
|
||||
SetIAMProject(instanceAgg, projectAgg.ID),
|
||||
|
||||
AddAPIApp(
|
||||
@@ -260,6 +289,7 @@ func (command *Command) SetUpInstance(ctx context.Context, setup *InstanceSetup)
|
||||
0,
|
||||
nil,
|
||||
),
|
||||
SetIAMConsoleID(instanceAgg, setup.Zitadel.consoleClientID),
|
||||
)
|
||||
|
||||
cmds, err := preparation.PrepareCommands(ctx, command.es.Filter, validations...)
|
||||
@@ -278,7 +308,7 @@ func (command *Command) SetUpInstance(ctx context.Context, setup *InstanceSetup)
|
||||
}, nil
|
||||
}
|
||||
|
||||
//SetIAMProject defines the commands to set the id of the IAM project onto the instance
|
||||
//SetIAMProject defines the command to set the id of the IAM project onto the instance
|
||||
func SetIAMProject(a *instance.Aggregate, projectID string) preparation.Validation {
|
||||
return func() (preparation.CreateCommands, error) {
|
||||
return func(ctx context.Context, filter preparation.FilterToQueryReducer) ([]eventstore.Command, error) {
|
||||
@@ -288,3 +318,14 @@ func SetIAMProject(a *instance.Aggregate, projectID string) preparation.Validati
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
//SetIAMConsoleID defines the command to set the clientID of the Console App onto the instance
|
||||
func SetIAMConsoleID(a *instance.Aggregate, clientID string) preparation.Validation {
|
||||
return func() (preparation.CreateCommands, error) {
|
||||
return func(ctx context.Context, filter preparation.FilterToQueryReducer) ([]eventstore.Command, error) {
|
||||
return []eventstore.Command{
|
||||
instance.NewIAMConsoleSetEvent(ctx, &a.Aggregate, clientID),
|
||||
}, nil
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
@@ -43,3 +43,16 @@ func AddDefaultLabelPolicy(
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func ActivateDefaultLabelPolicy(
|
||||
a *instance.Aggregate,
|
||||
) preparation.Validation {
|
||||
return func() (preparation.CreateCommands, error) {
|
||||
return func(ctx context.Context, filter preparation.FilterToQueryReducer) ([]eventstore.Command, error) {
|
||||
//TODO: check if already exists
|
||||
return []eventstore.Command{
|
||||
instance.NewLabelPolicyActivatedEvent(ctx, &a.Aggregate),
|
||||
}, nil
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
64
internal/command/v2/instance_member.go
Normal file
64
internal/command/v2/instance_member.go
Normal file
@@ -0,0 +1,64 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/zitadel/internal/command/v2/preparation"
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
"github.com/caos/zitadel/internal/repository/instance"
|
||||
)
|
||||
|
||||
func AddInstanceMember(a *instance.Aggregate, userID string, roles ...string) preparation.Validation {
|
||||
return func() (preparation.CreateCommands, error) {
|
||||
if userID == "" {
|
||||
return nil, errors.ThrowInvalidArgument(nil, "INSTA-SDSfs", "Errors.Invalid.Argument")
|
||||
}
|
||||
// TODO: check roles
|
||||
return func(ctx context.Context, filter preparation.FilterToQueryReducer) ([]eventstore.Command, error) {
|
||||
if exists, err := ExistsUser(ctx, filter, userID, ""); err != nil || !exists {
|
||||
return nil, errors.ThrowNotFound(err, "INSTA-GSXOn", "Errors.User.NotFound")
|
||||
}
|
||||
if isMember, err := IsInstanceMember(ctx, filter, a.ID, userID); err != nil || isMember {
|
||||
return nil, errors.ThrowAlreadyExists(err, "INSTA-pFDwe", "Errors.Instance.Member.AlreadyExists")
|
||||
}
|
||||
return []eventstore.Command{instance.NewMemberAddedEvent(ctx, &a.Aggregate, userID, roles...)}, nil
|
||||
},
|
||||
nil
|
||||
}
|
||||
}
|
||||
|
||||
func IsInstanceMember(ctx context.Context, filter preparation.FilterToQueryReducer, instanceID, userID string) (isMember bool, err error) {
|
||||
events, err := filter(ctx, eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent).
|
||||
OrderAsc().
|
||||
AddQuery().
|
||||
AggregateIDs(instanceID).
|
||||
AggregateTypes(instance.AggregateType).
|
||||
EventTypes(
|
||||
instance.MemberAddedEventType,
|
||||
instance.MemberRemovedEventType,
|
||||
instance.MemberCascadeRemovedEventType,
|
||||
).Builder())
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
for _, event := range events {
|
||||
switch e := event.(type) {
|
||||
case *instance.MemberAddedEvent:
|
||||
if e.UserID == userID {
|
||||
isMember = true
|
||||
}
|
||||
case *instance.MemberRemovedEvent:
|
||||
if e.UserID == userID {
|
||||
isMember = false
|
||||
}
|
||||
case *instance.MemberCascadeRemovedEvent:
|
||||
if e.UserID == userID {
|
||||
isMember = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return isMember, nil
|
||||
}
|
Reference in New Issue
Block a user