mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 19:07:30 +00:00
feat: initial admin PAT has IAM_LOGIN_CLIENT (#10143)
# Which Problems Are Solved We provide a seamless way to initialize Zitadel and the login together. # How the Problems Are Solved Additionally to the `IAM_OWNER` role, a set up admin user also gets the `IAM_LOGIN_CLIENT` role if it is a machine user with a PAT. # Additional Changes - Simplifies the load balancing example, as the intermediate configuration step is not needed anymore. # Additional Context - Depends on #10116 - Contributes to https://github.com/zitadel/zitadel-charts/issues/332 - Contributes to https://github.com/zitadel/zitadel/issues/10016 --------- Co-authored-by: Stefan Benz <46600784+stebenz@users.noreply.github.com>
This commit is contained in:
@@ -217,33 +217,33 @@ func (s *InstanceSetup) generateIDs(idGenerator id.Generator) (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *Commands) SetUpInstance(ctx context.Context, setup *InstanceSetup) (string, string, *MachineKey, *domain.ObjectDetails, error) {
|
||||
func (c *Commands) SetUpInstance(ctx context.Context, setup *InstanceSetup) (string, string, *MachineKey, string, *domain.ObjectDetails, error) {
|
||||
if err := setup.generateIDs(c.idGenerator); err != nil {
|
||||
return "", "", nil, nil, err
|
||||
return "", "", nil, "", nil, err
|
||||
}
|
||||
ctx = contextWithInstanceSetupInfo(ctx, setup.zitadel.instanceID, setup.zitadel.projectID, setup.zitadel.consoleAppID, c.externalDomain, setup.DefaultLanguage)
|
||||
|
||||
validations, pat, machineKey, err := setUpInstance(ctx, c, setup)
|
||||
validations, pat, machineKey, loginClientPat, err := setUpInstance(ctx, c, setup)
|
||||
if err != nil {
|
||||
return "", "", nil, nil, err
|
||||
return "", "", nil, "", nil, err
|
||||
}
|
||||
|
||||
//nolint:staticcheck
|
||||
cmds, err := preparation.PrepareCommands(ctx, c.eventstore.Filter, validations...)
|
||||
if err != nil {
|
||||
return "", "", nil, nil, err
|
||||
return "", "", nil, "", nil, err
|
||||
}
|
||||
|
||||
_, err = c.eventstore.Push(ctx, cmds...)
|
||||
if err != nil {
|
||||
return "", "", nil, nil, err
|
||||
return "", "", nil, "", nil, err
|
||||
}
|
||||
|
||||
// RolePermissions need to be pushed in separate transaction.
|
||||
// https://github.com/zitadel/zitadel/issues/9293
|
||||
details, err := c.SynchronizeRolePermission(ctx, setup.zitadel.instanceID, setup.RolePermissionMappings)
|
||||
if err != nil {
|
||||
return "", "", nil, nil, err
|
||||
return "", "", nil, "", nil, err
|
||||
}
|
||||
details.ResourceOwner = setup.zitadel.orgID
|
||||
|
||||
@@ -251,8 +251,12 @@ func (c *Commands) SetUpInstance(ctx context.Context, setup *InstanceSetup) (str
|
||||
if pat != nil {
|
||||
token = pat.Token
|
||||
}
|
||||
var loginClientToken string
|
||||
if loginClientPat != nil {
|
||||
loginClientToken = loginClientPat.Token
|
||||
}
|
||||
|
||||
return setup.zitadel.instanceID, token, machineKey, details, nil
|
||||
return setup.zitadel.instanceID, token, machineKey, loginClientToken, details, nil
|
||||
}
|
||||
|
||||
func contextWithInstanceSetupInfo(ctx context.Context, instanceID, projectID, consoleAppID, externalDomain string, defaultLanguage language.Tag) context.Context {
|
||||
@@ -274,38 +278,38 @@ func contextWithInstanceSetupInfo(ctx context.Context, instanceID, projectID, co
|
||||
)
|
||||
}
|
||||
|
||||
func setUpInstance(ctx context.Context, c *Commands, setup *InstanceSetup) (validations []preparation.Validation, pat *PersonalAccessToken, machineKey *MachineKey, err error) {
|
||||
func setUpInstance(ctx context.Context, c *Commands, setup *InstanceSetup) (validations []preparation.Validation, pat *PersonalAccessToken, machineKey *MachineKey, loginClientPat *PersonalAccessToken, err error) {
|
||||
instanceAgg := instance.NewAggregate(setup.zitadel.instanceID)
|
||||
|
||||
validations = setupInstanceElements(instanceAgg, setup)
|
||||
|
||||
// default organization on setup'd instance
|
||||
pat, machineKey, err = setupDefaultOrg(ctx, c, &validations, instanceAgg, setup.Org.Name, setup.Org.Machine, setup.Org.Human, setup.zitadel)
|
||||
pat, machineKey, loginClientPat, err = setupDefaultOrg(ctx, c, &validations, instanceAgg, setup.Org.Name, setup.Org.Machine, setup.Org.Human, setup.Org.LoginClient, setup.zitadel)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
return nil, nil, nil, nil, err
|
||||
}
|
||||
|
||||
// domains
|
||||
if err := setupGeneratedDomain(ctx, c, &validations, instanceAgg, setup.InstanceName); err != nil {
|
||||
return nil, nil, nil, err
|
||||
return nil, nil, nil, nil, err
|
||||
}
|
||||
setupCustomDomain(c, &validations, instanceAgg, setup.CustomDomain)
|
||||
|
||||
// optional setting if set
|
||||
setupMessageTexts(&validations, setup.MessageTexts, instanceAgg)
|
||||
if err := setupQuotas(c, &validations, setup.Quotas, setup.zitadel.instanceID); err != nil {
|
||||
return nil, nil, nil, err
|
||||
return nil, nil, nil, nil, err
|
||||
}
|
||||
setupSMTPSettings(c, &validations, setup.SMTPConfiguration, instanceAgg)
|
||||
if err := setupWebKeys(c, &validations, setup.zitadel.instanceID, setup); err != nil {
|
||||
return nil, nil, nil, err
|
||||
return nil, nil, nil, nil, err
|
||||
}
|
||||
setupOIDCSettings(c, &validations, setup.OIDCSettings, instanceAgg)
|
||||
setupFeatures(&validations, setup.Features, setup.zitadel.instanceID)
|
||||
setupLimits(c, &validations, limits.NewAggregate(setup.zitadel.limitsID, setup.zitadel.instanceID), setup.Limits)
|
||||
setupRestrictions(c, &validations, restrictions.NewAggregate(setup.zitadel.restrictionsID, setup.zitadel.instanceID, setup.zitadel.instanceID), setup.Restrictions)
|
||||
setupInstanceCreatedMilestone(&validations, setup.zitadel.instanceID)
|
||||
return validations, pat, machineKey, nil
|
||||
return validations, pat, machineKey, loginClientPat, nil
|
||||
}
|
||||
|
||||
func setupInstanceElements(instanceAgg *instance.Aggregate, setup *InstanceSetup) []preparation.Validation {
|
||||
@@ -572,8 +576,9 @@ func setupDefaultOrg(ctx context.Context,
|
||||
name string,
|
||||
machine *AddMachine,
|
||||
human *AddHuman,
|
||||
loginClient *AddLoginClient,
|
||||
ids ZitadelConfig,
|
||||
) (pat *PersonalAccessToken, machineKey *MachineKey, err error) {
|
||||
) (pat *PersonalAccessToken, machineKey *MachineKey, loginClientPat *PersonalAccessToken, err error) {
|
||||
orgAgg := org.NewAggregate(ids.orgID)
|
||||
|
||||
*validations = append(
|
||||
@@ -582,12 +587,12 @@ func setupDefaultOrg(ctx context.Context,
|
||||
commands.prepareSetDefaultOrg(instanceAgg, ids.orgID),
|
||||
)
|
||||
|
||||
projectOwner, pat, machineKey, err := setupAdmins(commands, validations, instanceAgg, orgAgg, machine, human)
|
||||
projectOwner, pat, machineKey, loginClientPat, err := setupAdmins(commands, validations, instanceAgg, orgAgg, machine, human, loginClient)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
setupMinimalInterfaces(commands, validations, instanceAgg, orgAgg, projectOwner, ids)
|
||||
return pat, machineKey, nil
|
||||
return pat, machineKey, loginClientPat, nil
|
||||
}
|
||||
|
||||
func setupAdmins(commands *Commands,
|
||||
@@ -596,21 +601,22 @@ func setupAdmins(commands *Commands,
|
||||
orgAgg *org.Aggregate,
|
||||
machine *AddMachine,
|
||||
human *AddHuman,
|
||||
) (owner string, pat *PersonalAccessToken, machineKey *MachineKey, err error) {
|
||||
loginClient *AddLoginClient,
|
||||
) (owner string, pat *PersonalAccessToken, machineKey *MachineKey, loginClientPat *PersonalAccessToken, err error) {
|
||||
if human == nil && machine == nil {
|
||||
return "", nil, nil, zerrors.ThrowInvalidArgument(nil, "INSTANCE-z1yi2q2ot7", "Error.Instance.NoAdmin")
|
||||
return "", nil, nil, nil, zerrors.ThrowInvalidArgument(nil, "INSTANCE-z1yi2q2ot7", "Error.Instance.NoAdmin")
|
||||
}
|
||||
|
||||
if machine != nil && machine.Machine != nil && !machine.Machine.IsZero() {
|
||||
machineUserID, err := commands.idGenerator.Next()
|
||||
if err != nil {
|
||||
return "", nil, nil, err
|
||||
return "", nil, nil, nil, err
|
||||
}
|
||||
owner = machineUserID
|
||||
|
||||
pat, machineKey, err = setupMachineAdmin(commands, validations, machine, orgAgg.ID, machineUserID)
|
||||
if err != nil {
|
||||
return "", nil, nil, err
|
||||
return "", nil, nil, nil, err
|
||||
}
|
||||
|
||||
setupAdminMembers(commands, validations, instanceAgg, orgAgg, machineUserID)
|
||||
@@ -618,7 +624,7 @@ func setupAdmins(commands *Commands,
|
||||
if human != nil {
|
||||
humanUserID, err := commands.idGenerator.Next()
|
||||
if err != nil {
|
||||
return "", nil, nil, err
|
||||
return "", nil, nil, nil, err
|
||||
}
|
||||
owner = humanUserID
|
||||
human.ID = humanUserID
|
||||
@@ -629,7 +635,18 @@ func setupAdmins(commands *Commands,
|
||||
|
||||
setupAdminMembers(commands, validations, instanceAgg, orgAgg, humanUserID)
|
||||
}
|
||||
return owner, pat, machineKey, nil
|
||||
if loginClient != nil {
|
||||
loginClientUserID, err := commands.idGenerator.Next()
|
||||
if err != nil {
|
||||
return "", nil, nil, nil, err
|
||||
}
|
||||
|
||||
loginClientPat, err = setupLoginClient(commands, validations, instanceAgg, loginClient, orgAgg.ID, loginClientUserID)
|
||||
if err != nil {
|
||||
return "", nil, nil, nil, err
|
||||
}
|
||||
}
|
||||
return owner, pat, machineKey, loginClientPat, nil
|
||||
}
|
||||
|
||||
func setupMachineAdmin(commands *Commands, validations *[]preparation.Validation, machine *AddMachine, orgID, userID string) (pat *PersonalAccessToken, machineKey *MachineKey, err error) {
|
||||
@@ -655,6 +672,22 @@ func setupMachineAdmin(commands *Commands, validations *[]preparation.Validation
|
||||
return pat, machineKey, nil
|
||||
}
|
||||
|
||||
func setupLoginClient(commands *Commands, validations *[]preparation.Validation, instanceAgg *instance.Aggregate, loginClient *AddLoginClient, orgID, userID string) (pat *PersonalAccessToken, err error) {
|
||||
*validations = append(*validations,
|
||||
AddMachineCommand(user.NewAggregate(userID, orgID), loginClient.Machine),
|
||||
commands.AddInstanceMemberCommand(instanceAgg, userID, domain.RoleIAMLoginClient),
|
||||
)
|
||||
if loginClient.Pat != nil {
|
||||
pat = NewPersonalAccessToken(orgID, userID, loginClient.Pat.ExpirationDate, loginClient.Pat.Scopes, domain.UserTypeMachine)
|
||||
pat.TokenID, err = commands.idGenerator.Next()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
*validations = append(*validations, prepareAddPersonalAccessToken(pat, commands.keyAlgorithm))
|
||||
}
|
||||
return pat, nil
|
||||
}
|
||||
|
||||
func setupAdminMembers(commands *Commands, validations *[]preparation.Validation, instanceAgg *instance.Aggregate, orgAgg *org.Aggregate, userID string) {
|
||||
*validations = append(*validations,
|
||||
commands.AddOrgMemberCommand(orgAgg, userID, domain.RoleOrgOwner),
|
||||
|
Reference in New Issue
Block a user