feat: System api (#3461)

* feat: start system api

* feat: remove auth

* feat: change gitignore

* feat: run system api

* feat: remove clear view form admin api

* feat: search instances

* feat: add instance

* fix: set primary domain

* Update .gitignore

* fix: add instance

* fix: add instance

* fix: handle errors

* fix: handle instance name

* fix: test

Co-authored-by: Livio Amstutz <livio.a@gmail.com>
This commit is contained in:
Fabi
2022-04-21 12:37:39 +02:00
committed by GitHub
parent a7816a43b1
commit 3d5891eb11
40 changed files with 1216 additions and 485 deletions

View File

@@ -28,10 +28,22 @@ const (
consolePostLogoutPath = console.HandlerPrefix + "/signedout"
)
type AddInstance struct {
InstanceName string
CustomDomain string
FirstOrgName string
OwnerEmail string
OwnerUsername string
OwnerFirstName string
OwnerLastName string
}
type InstanceSetup struct {
Org OrgSetup
Zitadel ZitadelConfig
Features struct {
zitadel ZitadelConfig
InstanceName string
CustomDomain string
Org OrgSetup
Features struct {
TierName string
TierDescription string
Retention time.Duration
@@ -120,9 +132,6 @@ type InstanceSetup struct {
}
type ZitadelConfig struct {
IsDevMode bool
BaseURL string
projectID string
mgmtAppID string
adminAppID string
@@ -131,41 +140,41 @@ type ZitadelConfig struct {
}
func (s *InstanceSetup) generateIDs() (err error) {
s.Zitadel.projectID, err = id.SonyFlakeGenerator.Next()
s.zitadel.projectID, err = id.SonyFlakeGenerator.Next()
if err != nil {
return err
}
s.Zitadel.mgmtAppID, err = id.SonyFlakeGenerator.Next()
s.zitadel.mgmtAppID, err = id.SonyFlakeGenerator.Next()
if err != nil {
return err
}
s.Zitadel.adminAppID, err = id.SonyFlakeGenerator.Next()
s.zitadel.adminAppID, err = id.SonyFlakeGenerator.Next()
if err != nil {
return err
}
s.Zitadel.authAppID, err = id.SonyFlakeGenerator.Next()
s.zitadel.authAppID, err = id.SonyFlakeGenerator.Next()
if err != nil {
return err
}
s.Zitadel.consoleAppID, err = id.SonyFlakeGenerator.Next()
s.zitadel.consoleAppID, err = id.SonyFlakeGenerator.Next()
if err != nil {
return err
}
return nil
}
func (c *Commands) SetUpInstance(ctx context.Context, setup *InstanceSetup) (*domain.ObjectDetails, error) {
func (c *Commands) SetUpInstance(ctx context.Context, setup *InstanceSetup, externalSecure bool, baseURL string) (string, *domain.ObjectDetails, error) {
instanceID, err := id.SonyFlakeGenerator.Next()
if err != nil {
return nil, err
return "", nil, err
}
if err = c.eventstore.NewInstance(ctx, instanceID); err != nil {
return nil, err
return "", nil, err
}
ctx = authz.SetCtxData(authz.WithInstanceID(ctx, instanceID), authz.CtxData{OrgID: instanceID, ResourceOwner: instanceID})
@@ -174,16 +183,16 @@ func (c *Commands) SetUpInstance(ctx context.Context, setup *InstanceSetup) (*do
orgID, err := id.SonyFlakeGenerator.Next()
if err != nil {
return nil, err
return "", nil, err
}
userID, err := id.SonyFlakeGenerator.Next()
if err != nil {
return nil, err
return "", nil, err
}
if err = setup.generateIDs(); err != nil {
return nil, err
return "", nil, err
}
setup.Org.Human.PasswordChangeRequired = true
@@ -191,9 +200,11 @@ func (c *Commands) SetUpInstance(ctx context.Context, setup *InstanceSetup) (*do
instanceAgg := instance.NewAggregate(instanceID)
orgAgg := org.NewAggregate(orgID)
userAgg := user.NewAggregate(userID, orgID)
projectAgg := project.NewAggregate(setup.Zitadel.projectID, orgID)
projectAgg := project.NewAggregate(setup.zitadel.projectID, orgID)
validations := []preparation.Validation{
addInstance(instanceAgg, setup.InstanceName),
c.addGeneratedInstanceDomain(instanceAgg, setup.InstanceName),
SetDefaultFeatures(
instanceAgg,
setup.Features.TierName,
@@ -289,20 +300,24 @@ func (c *Commands) SetUpInstance(ctx context.Context, setup *InstanceSetup) (*do
validations = append(validations, SetInstanceCustomTexts(instanceAgg, msg))
}
if setup.CustomDomain != "" {
validations = append(validations, c.addInstanceDomain(instanceAgg, setup.CustomDomain, false))
}
console := &addOIDCApp{
AddApp: AddApp{
Aggregate: *projectAgg,
ID: setup.Zitadel.consoleAppID,
ID: setup.zitadel.consoleAppID,
Name: consoleAppName,
},
Version: domain.OIDCVersionV1,
RedirectUris: []string{setup.Zitadel.BaseURL + consoleRedirectPath},
RedirectUris: []string{baseURL + consoleRedirectPath},
ResponseTypes: []domain.OIDCResponseType{domain.OIDCResponseTypeCode},
GrantTypes: []domain.OIDCGrantType{domain.OIDCGrantTypeAuthorizationCode},
ApplicationType: domain.OIDCApplicationTypeUserAgent,
AuthMethodType: domain.OIDCAuthMethodTypeNone,
PostLogoutRedirectUris: []string{setup.Zitadel.BaseURL + consolePostLogoutPath},
DevMode: setup.Zitadel.IsDevMode,
PostLogoutRedirectUris: []string{baseURL + consolePostLogoutPath},
DevMode: !externalSecure,
AccessTokenType: domain.OIDCTokenTypeBearer,
AccessTokenRoleAssertion: false,
IDTokenRoleAssertion: false,
@@ -323,7 +338,7 @@ func (c *Commands) SetUpInstance(ctx context.Context, setup *InstanceSetup) (*do
&addAPIApp{
AddApp: AddApp{
Aggregate: *projectAgg,
ID: setup.Zitadel.mgmtAppID,
ID: setup.zitadel.mgmtAppID,
Name: mgmtAppName,
},
AuthMethodType: domain.APIAuthMethodTypePrivateKeyJWT,
@@ -335,7 +350,7 @@ func (c *Commands) SetUpInstance(ctx context.Context, setup *InstanceSetup) (*do
&addAPIApp{
AddApp: AddApp{
Aggregate: *projectAgg,
ID: setup.Zitadel.adminAppID,
ID: setup.zitadel.adminAppID,
Name: adminAppName,
},
AuthMethodType: domain.APIAuthMethodTypePrivateKeyJWT,
@@ -347,7 +362,7 @@ func (c *Commands) SetUpInstance(ctx context.Context, setup *InstanceSetup) (*do
&addAPIApp{
AddApp: AddApp{
Aggregate: *projectAgg,
ID: setup.Zitadel.authAppID,
ID: setup.zitadel.authAppID,
Name: authAppName,
},
AuthMethodType: domain.APIAuthMethodTypePrivateKeyJWT,
@@ -356,25 +371,35 @@ func (c *Commands) SetUpInstance(ctx context.Context, setup *InstanceSetup) (*do
),
AddOIDCAppCommand(console, nil),
SetIAMConsoleID(instanceAgg, &console.ClientID, &setup.Zitadel.consoleAppID),
SetIAMConsoleID(instanceAgg, &console.ClientID, &setup.zitadel.consoleAppID),
)
cmds, err := preparation.PrepareCommands(ctx, c.eventstore.Filter, validations...)
if err != nil {
return nil, err
return "", nil, err
}
events, err := c.eventstore.Push(ctx, cmds...)
if err != nil {
return nil, err
return "", nil, err
}
return &domain.ObjectDetails{
return instanceID, &domain.ObjectDetails{
Sequence: events[len(events)-1].Sequence(),
EventDate: events[len(events)-1].CreationDate(),
ResourceOwner: orgID,
}, nil
}
func addInstance(a *instance.Aggregate, instanceName string) preparation.Validation {
return func() (preparation.CreateCommands, error) {
return func(ctx context.Context, filter preparation.FilterToQueryReducer) ([]eventstore.Command, error) {
return []eventstore.Command{
instance.NewInstanceAddedEvent(ctx, &a.Aggregate, instanceName),
}, nil
}, nil
}
}
//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) {

View File

@@ -67,6 +67,11 @@ func (c *Commands) RemoveInstanceDomain(ctx context.Context, instanceDomain stri
}, nil
}
func (c *Commands) addGeneratedInstanceDomain(a *instance.Aggregate, instanceName string) preparation.Validation {
domain := domain.NewGeneratedInstanceDomain(instanceName, c.iamDomain)
return c.addInstanceDomain(a, domain, true)
}
func (c *Commands) addInstanceDomain(a *instance.Aggregate, instanceDomain string, generated bool) preparation.Validation {
return func() (preparation.CreateCommands, error) {
if instanceDomain = strings.TrimSpace(instanceDomain); instanceDomain == "" {
@@ -80,28 +85,32 @@ func (c *Commands) addInstanceDomain(a *instance.Aggregate, instanceDomain strin
if domainWriteModel.State == domain.InstanceDomainStateActive {
return nil, errors.ThrowAlreadyExists(nil, "INST-i2nl", "Errors.Instance.Domain.AlreadyExists")
}
events := []eventstore.Command{
instance.NewDomainAddedEvent(ctx, &a.Aggregate, instanceDomain, generated),
}
appWriteModel, err := c.getOIDCAppWriteModel(ctx, authz.GetInstance(ctx).ProjectID(), authz.GetInstance(ctx).ConsoleApplicationID(), "")
if err != nil {
return nil, err
}
redirectUrls := append(appWriteModel.RedirectUris, instanceDomain+consoleRedirectPath)
logoutUrls := append(appWriteModel.PostLogoutRedirectUris, instanceDomain+consolePostLogoutPath)
consoleChangeEvent, err := project.NewOIDCConfigChangedEvent(
ctx,
ProjectAggregateFromWriteModel(&appWriteModel.WriteModel),
appWriteModel.AppID,
[]project.OIDCConfigChanges{
project.ChangeRedirectURIs(redirectUrls),
project.ChangePostLogoutRedirectURIs(logoutUrls),
},
)
if err != nil {
return nil, err
if appWriteModel.State.Exists() {
redirectUrls := append(appWriteModel.RedirectUris, instanceDomain+consoleRedirectPath)
logoutUrls := append(appWriteModel.PostLogoutRedirectUris, instanceDomain+consolePostLogoutPath)
consoleChangeEvent, err := project.NewOIDCConfigChangedEvent(
ctx,
ProjectAggregateFromWriteModel(&appWriteModel.WriteModel),
appWriteModel.AppID,
[]project.OIDCConfigChanges{
project.ChangeRedirectURIs(redirectUrls),
project.ChangePostLogoutRedirectURIs(logoutUrls),
},
)
if err != nil {
return nil, err
}
events = append(events, consoleChangeEvent)
}
return []eventstore.Command{
instance.NewDomainAddedEvent(ctx, &a.Aggregate, instanceDomain, generated),
consoleChangeEvent,
}, nil
return events, nil
}, nil
}
}

View File

@@ -291,7 +291,7 @@ func (c *Commands) VerifyOIDCClientSecret(ctx context.Context, projectID, appID,
return err
}
if !app.State.Exists() {
return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-D6hba", "Errors.Project.App.NoExisting")
return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-D6hba", "Errors.Project.App.NotExisting")
}
if !app.IsOIDC() {
return caos_errs.ThrowInvalidArgument(nil, "COMMAND-BHgn2", "Errors.Project.App.IsNotOIDC")