mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-12 04:57:33 +00:00
feat(6222): remove @ and project from OIDC client ID (#8178)
# Which Problems Are Solved The client ID for OIDC applications has an `@` in it, which is not allowed in some 3rd-party systems (such as AWS). # How the Problems Are Solved Per @fforootd and @hifabienne in #6222, remove the project suffix and the `@` from the client ID and just use the generated ID. # Additional Changes N/A # Additional Context - Closes #6222 --------- Co-authored-by: Stefan Benz <46600784+stebenz@users.noreply.github.com> Co-authored-by: Livio Spring <livio.a@gmail.com>
This commit is contained in:
@@ -63,7 +63,7 @@ func projectAddedEvents(ctx context.Context, instanceID, orgID, id, owner string
|
||||
events = append(events, apiAppEvents(ctx, orgID, id, "auth-id", "Auth-API")...)
|
||||
|
||||
consoleAppID := "console-id"
|
||||
consoleClientID := "clientID@zitadel"
|
||||
consoleClientID := "clientID"
|
||||
events = append(events, oidcAppEvents(ctx, orgID, id, consoleAppID, "Console", consoleClientID, externalSecure)...)
|
||||
events = append(events,
|
||||
instance.NewIAMConsoleSetEvent(ctx,
|
||||
@@ -90,7 +90,7 @@ func apiAppEvents(ctx context.Context, orgID, projectID, id, name string) []even
|
||||
project.NewAPIConfigAddedEvent(ctx,
|
||||
&project.NewAggregate(projectID, orgID).Aggregate,
|
||||
id,
|
||||
"clientID@zitadel",
|
||||
"clientID",
|
||||
"",
|
||||
domain.APIAuthMethodTypePrivateKeyJWT,
|
||||
),
|
||||
|
@@ -35,7 +35,7 @@ func (c *Commands) AddAPIAppCommand(app *addAPIApp) preparation.Validation {
|
||||
return nil, zerrors.ThrowNotFound(err, "PROJE-Sf2gb", "Errors.Project.NotFound")
|
||||
}
|
||||
|
||||
app.ClientID, err = domain.NewClientID(c.idGenerator, project.Name)
|
||||
app.ClientID, err = c.idGenerator.Next()
|
||||
if err != nil {
|
||||
return nil, zerrors.ThrowInternal(err, "V2-f0pgP", "Errors.Internal")
|
||||
}
|
||||
@@ -78,19 +78,19 @@ func (c *Commands) AddAPIApplicationWithID(ctx context.Context, apiApp *domain.A
|
||||
if existingAPI.State != domain.AppStateUnspecified {
|
||||
return nil, zerrors.ThrowPreconditionFailed(nil, "PROJECT-mabu12", "Errors.Project.App.AlreadyExisting")
|
||||
}
|
||||
project, err := c.getProjectByID(ctx, apiApp.AggregateID, resourceOwner)
|
||||
_, err = c.getProjectByID(ctx, apiApp.AggregateID, resourceOwner)
|
||||
if err != nil {
|
||||
return nil, zerrors.ThrowPreconditionFailed(err, "PROJECT-9fnsa", "Errors.Project.NotFound")
|
||||
}
|
||||
|
||||
return c.addAPIApplicationWithID(ctx, apiApp, resourceOwner, project, appID)
|
||||
return c.addAPIApplicationWithID(ctx, apiApp, resourceOwner, appID)
|
||||
}
|
||||
|
||||
func (c *Commands) AddAPIApplication(ctx context.Context, apiApp *domain.APIApp, resourceOwner string) (_ *domain.APIApp, err error) {
|
||||
if apiApp == nil || apiApp.AggregateID == "" {
|
||||
return nil, zerrors.ThrowInvalidArgument(nil, "PROJECT-5m9E", "Errors.Project.App.Invalid")
|
||||
}
|
||||
project, err := c.getProjectByID(ctx, apiApp.AggregateID, resourceOwner)
|
||||
_, err = c.getProjectByID(ctx, apiApp.AggregateID, resourceOwner)
|
||||
if err != nil {
|
||||
return nil, zerrors.ThrowPreconditionFailed(err, "PROJECT-9fnsf", "Errors.Project.NotFound")
|
||||
}
|
||||
@@ -104,10 +104,10 @@ func (c *Commands) AddAPIApplication(ctx context.Context, apiApp *domain.APIApp,
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return c.addAPIApplicationWithID(ctx, apiApp, resourceOwner, project, appID)
|
||||
return c.addAPIApplicationWithID(ctx, apiApp, resourceOwner, appID)
|
||||
}
|
||||
|
||||
func (c *Commands) addAPIApplicationWithID(ctx context.Context, apiApp *domain.APIApp, resourceOwner string, project *domain.Project, appID string) (_ *domain.APIApp, err error) {
|
||||
func (c *Commands) addAPIApplicationWithID(ctx context.Context, apiApp *domain.APIApp, resourceOwner string, appID string) (_ *domain.APIApp, err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
@@ -121,7 +121,7 @@ func (c *Commands) addAPIApplicationWithID(ctx context.Context, apiApp *domain.A
|
||||
}
|
||||
|
||||
var plain string
|
||||
err = domain.SetNewClientID(apiApp, c.idGenerator, project)
|
||||
err = domain.SetNewClientID(apiApp, c.idGenerator)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@@ -117,7 +117,7 @@ func TestAddAPIConfig(t *testing.T) {
|
||||
),
|
||||
project.NewAPIConfigAddedEvent(ctx, &agg.Aggregate,
|
||||
"appID",
|
||||
"clientID@project",
|
||||
"clientID",
|
||||
"",
|
||||
domain.APIAuthMethodTypePrivateKeyJWT,
|
||||
),
|
||||
@@ -252,7 +252,7 @@ func TestCommandSide_AddAPIApplication(t *testing.T) {
|
||||
project.NewAPIConfigAddedEvent(context.Background(),
|
||||
&project.NewAggregate("project1", "org1").Aggregate,
|
||||
"app1",
|
||||
"client1@project",
|
||||
"client1",
|
||||
"secret",
|
||||
domain.APIAuthMethodTypeBasic),
|
||||
),
|
||||
@@ -278,7 +278,61 @@ func TestCommandSide_AddAPIApplication(t *testing.T) {
|
||||
},
|
||||
AppID: "app1",
|
||||
AppName: "app",
|
||||
ClientID: "client1@project",
|
||||
ClientID: "client1",
|
||||
ClientSecretString: "secret",
|
||||
AuthMethodType: domain.APIAuthMethodTypeBasic,
|
||||
State: domain.AppStateActive,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "create api app basic old ID format, ok",
|
||||
fields: fields{
|
||||
eventstore: expectEventstore(
|
||||
expectFilter(
|
||||
eventFromEventPusher(
|
||||
project.NewProjectAddedEvent(context.Background(),
|
||||
&project.NewAggregate("project1", "org1").Aggregate,
|
||||
"project", true, true, true,
|
||||
domain.PrivateLabelingSettingUnspecified),
|
||||
),
|
||||
),
|
||||
expectPush(
|
||||
project.NewApplicationAddedEvent(context.Background(),
|
||||
&project.NewAggregate("project1", "org1").Aggregate,
|
||||
"app1",
|
||||
"app",
|
||||
),
|
||||
project.NewAPIConfigAddedEvent(context.Background(),
|
||||
&project.NewAggregate("project1", "org1").Aggregate,
|
||||
"app1",
|
||||
"client1@project1",
|
||||
"secret",
|
||||
domain.APIAuthMethodTypeBasic),
|
||||
),
|
||||
),
|
||||
idGenerator: id_mock.NewIDGeneratorExpectIDs(t, "app1", "client1@project1"),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
apiApp: &domain.APIApp{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: "project1",
|
||||
},
|
||||
AppName: "app",
|
||||
AuthMethodType: domain.APIAuthMethodTypeBasic,
|
||||
},
|
||||
resourceOwner: "org1",
|
||||
},
|
||||
res: res{
|
||||
want: &domain.APIApp{
|
||||
ObjectRoot: models.ObjectRoot{
|
||||
AggregateID: "project1",
|
||||
ResourceOwner: "org1",
|
||||
},
|
||||
AppID: "app1",
|
||||
AppName: "app",
|
||||
ClientID: "client1@project1",
|
||||
ClientSecretString: "secret",
|
||||
AuthMethodType: domain.APIAuthMethodTypeBasic,
|
||||
State: domain.AppStateActive,
|
||||
@@ -306,7 +360,7 @@ func TestCommandSide_AddAPIApplication(t *testing.T) {
|
||||
project.NewAPIConfigAddedEvent(context.Background(),
|
||||
&project.NewAggregate("project1", "org1").Aggregate,
|
||||
"app1",
|
||||
"client1@project",
|
||||
"client1",
|
||||
"",
|
||||
domain.APIAuthMethodTypePrivateKeyJWT),
|
||||
),
|
||||
@@ -332,7 +386,7 @@ func TestCommandSide_AddAPIApplication(t *testing.T) {
|
||||
},
|
||||
AppID: "app1",
|
||||
AppName: "app",
|
||||
ClientID: "client1@project",
|
||||
ClientID: "client1",
|
||||
AuthMethodType: domain.APIAuthMethodTypePrivateKeyJWT,
|
||||
State: domain.AppStateActive,
|
||||
},
|
||||
|
@@ -68,7 +68,7 @@ func (c *Commands) AddOIDCAppCommand(app *addOIDCApp) preparation.Validation {
|
||||
return nil, zerrors.ThrowNotFound(err, "PROJE-6swVG", "Errors.Project.NotFound")
|
||||
}
|
||||
|
||||
app.ClientID, err = domain.NewClientID(c.idGenerator, project.Name)
|
||||
app.ClientID, err = c.idGenerator.Next()
|
||||
if err != nil {
|
||||
return nil, zerrors.ThrowInternal(err, "V2-VMSQ1", "Errors.Internal")
|
||||
}
|
||||
@@ -126,19 +126,19 @@ func (c *Commands) AddOIDCApplicationWithID(ctx context.Context, oidcApp *domain
|
||||
return nil, zerrors.ThrowPreconditionFailed(nil, "PROJECT-lxowmp", "Errors.Project.App.AlreadyExisting")
|
||||
}
|
||||
|
||||
project, err := c.getProjectByID(ctx, oidcApp.AggregateID, resourceOwner)
|
||||
_, err = c.getProjectByID(ctx, oidcApp.AggregateID, resourceOwner)
|
||||
if err != nil {
|
||||
return nil, zerrors.ThrowPreconditionFailed(err, "PROJECT-3m9s2", "Errors.Project.NotFound")
|
||||
}
|
||||
|
||||
return c.addOIDCApplicationWithID(ctx, oidcApp, resourceOwner, project, appID)
|
||||
return c.addOIDCApplicationWithID(ctx, oidcApp, resourceOwner, appID)
|
||||
}
|
||||
|
||||
func (c *Commands) AddOIDCApplication(ctx context.Context, oidcApp *domain.OIDCApp, resourceOwner string) (_ *domain.OIDCApp, err error) {
|
||||
if oidcApp == nil || oidcApp.AggregateID == "" {
|
||||
return nil, zerrors.ThrowInvalidArgument(nil, "PROJECT-34Fm0", "Errors.Project.App.Invalid")
|
||||
}
|
||||
project, err := c.getProjectByID(ctx, oidcApp.AggregateID, resourceOwner)
|
||||
_, err = c.getProjectByID(ctx, oidcApp.AggregateID, resourceOwner)
|
||||
if err != nil {
|
||||
return nil, zerrors.ThrowPreconditionFailed(err, "PROJECT-3m9ss", "Errors.Project.NotFound")
|
||||
}
|
||||
@@ -152,10 +152,10 @@ func (c *Commands) AddOIDCApplication(ctx context.Context, oidcApp *domain.OIDCA
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return c.addOIDCApplicationWithID(ctx, oidcApp, resourceOwner, project, appID)
|
||||
return c.addOIDCApplicationWithID(ctx, oidcApp, resourceOwner, appID)
|
||||
}
|
||||
|
||||
func (c *Commands) addOIDCApplicationWithID(ctx context.Context, oidcApp *domain.OIDCApp, resourceOwner string, project *domain.Project, appID string) (_ *domain.OIDCApp, err error) {
|
||||
func (c *Commands) addOIDCApplicationWithID(ctx context.Context, oidcApp *domain.OIDCApp, resourceOwner string, appID string) (_ *domain.OIDCApp, err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
@@ -169,7 +169,7 @@ func (c *Commands) addOIDCApplicationWithID(ctx context.Context, oidcApp *domain
|
||||
}
|
||||
|
||||
var plain string
|
||||
err = domain.SetNewClientID(oidcApp, c.idGenerator, project)
|
||||
err = domain.SetNewClientID(oidcApp, c.idGenerator)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@@ -158,7 +158,7 @@ func TestAddOIDCApp(t *testing.T) {
|
||||
project.NewOIDCConfigAddedEvent(ctx, &agg.Aggregate,
|
||||
domain.OIDCVersionV1,
|
||||
"id",
|
||||
"clientID@project",
|
||||
"clientID",
|
||||
"",
|
||||
[]string{"https://test.ch"},
|
||||
[]domain.OIDCResponseType{domain.OIDCResponseTypeCode},
|
||||
@@ -214,6 +214,71 @@ func TestAddOIDCApp(t *testing.T) {
|
||||
}).
|
||||
Filter(),
|
||||
},
|
||||
want: Want{
|
||||
Commands: []eventstore.Command{
|
||||
project.NewApplicationAddedEvent(ctx, &agg.Aggregate,
|
||||
"id",
|
||||
"name",
|
||||
),
|
||||
project.NewOIDCConfigAddedEvent(ctx, &agg.Aggregate,
|
||||
domain.OIDCVersionV1,
|
||||
"id",
|
||||
"clientID",
|
||||
"",
|
||||
nil,
|
||||
[]domain.OIDCResponseType{domain.OIDCResponseTypeCode},
|
||||
[]domain.OIDCGrantType{domain.OIDCGrantTypeAuthorizationCode},
|
||||
domain.OIDCApplicationTypeWeb,
|
||||
domain.OIDCAuthMethodTypeNone,
|
||||
nil,
|
||||
false,
|
||||
domain.OIDCTokenTypeBearer,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
0,
|
||||
nil,
|
||||
false,
|
||||
),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "correct with old ID format",
|
||||
fields: fields{
|
||||
idGenerator: id_mock.NewIDGeneratorExpectIDs(t, "clientID@project"),
|
||||
},
|
||||
args: args{
|
||||
app: &addOIDCApp{
|
||||
AddApp: AddApp{
|
||||
Aggregate: *agg,
|
||||
ID: "id",
|
||||
Name: "name",
|
||||
},
|
||||
GrantTypes: []domain.OIDCGrantType{domain.OIDCGrantTypeAuthorizationCode},
|
||||
ResponseTypes: []domain.OIDCResponseType{domain.OIDCResponseTypeCode},
|
||||
Version: domain.OIDCVersionV1,
|
||||
|
||||
ApplicationType: domain.OIDCApplicationTypeWeb,
|
||||
AuthMethodType: domain.OIDCAuthMethodTypeNone,
|
||||
AccessTokenType: domain.OIDCTokenTypeBearer,
|
||||
},
|
||||
filter: NewMultiFilter().
|
||||
Append(func(ctx context.Context, queryFactory *eventstore.SearchQueryBuilder) ([]eventstore.Event, error) {
|
||||
return []eventstore.Event{
|
||||
project.NewProjectAddedEvent(
|
||||
ctx,
|
||||
&agg.Aggregate,
|
||||
"project",
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
domain.PrivateLabelingSettingUnspecified,
|
||||
),
|
||||
}, nil
|
||||
}).
|
||||
Filter(),
|
||||
},
|
||||
want: Want{
|
||||
Commands: []eventstore.Command{
|
||||
project.NewApplicationAddedEvent(ctx, &agg.Aggregate,
|
||||
@@ -288,7 +353,7 @@ func TestAddOIDCApp(t *testing.T) {
|
||||
project.NewOIDCConfigAddedEvent(ctx, &agg.Aggregate,
|
||||
domain.OIDCVersionV1,
|
||||
"id",
|
||||
"clientID@project",
|
||||
"clientID",
|
||||
"secret",
|
||||
nil,
|
||||
[]domain.OIDCResponseType{domain.OIDCResponseTypeCode},
|
||||
@@ -434,7 +499,7 @@ func TestCommandSide_AddOIDCApplication(t *testing.T) {
|
||||
&project.NewAggregate("project1", "org1").Aggregate,
|
||||
domain.OIDCVersionV1,
|
||||
"app1",
|
||||
"client1@project",
|
||||
"client1",
|
||||
"secret",
|
||||
[]string{"https://test.ch"},
|
||||
[]domain.OIDCResponseType{domain.OIDCResponseTypeCode},
|
||||
@@ -488,7 +553,7 @@ func TestCommandSide_AddOIDCApplication(t *testing.T) {
|
||||
},
|
||||
AppID: "app1",
|
||||
AppName: "app",
|
||||
ClientID: "client1@project",
|
||||
ClientID: "client1",
|
||||
ClientSecretString: "secret",
|
||||
AuthMethodType: domain.OIDCAuthMethodTypePost,
|
||||
OIDCVersion: domain.OIDCVersionV1,
|
||||
@@ -532,7 +597,7 @@ func TestCommandSide_AddOIDCApplication(t *testing.T) {
|
||||
&project.NewAggregate("project1", "org1").Aggregate,
|
||||
domain.OIDCVersionV1,
|
||||
"app1",
|
||||
"client1@project",
|
||||
"client1",
|
||||
"secret",
|
||||
[]string{"https://test.ch"},
|
||||
[]domain.OIDCResponseType{domain.OIDCResponseTypeCode},
|
||||
@@ -586,7 +651,7 @@ func TestCommandSide_AddOIDCApplication(t *testing.T) {
|
||||
},
|
||||
AppID: "app1",
|
||||
AppName: "app",
|
||||
ClientID: "client1@project",
|
||||
ClientID: "client1",
|
||||
ClientSecretString: "secret",
|
||||
AuthMethodType: domain.OIDCAuthMethodTypePost,
|
||||
OIDCVersion: domain.OIDCVersionV1,
|
||||
|
Reference in New Issue
Block a user