mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 20:57:31 +00:00
feat: specify login UI version on instance and apps (#9071)
# Which Problems Are Solved To be able to migrate or test the new login UI, admins might want to (temporarily) switch individual apps. At a later point admin might want to make sure all applications use the new login UI. # How the Problems Are Solved - Added a feature flag `` on instance level to require all apps to use the new login and provide an optional base url. - if the flag is enabled, all (OIDC) applications will automatically use the v2 login. - if disabled, applications can decide based on their configuration - Added an option on OIDC apps to use the new login UI and an optional base url. - Removed the requirement to use `x-zitadel-login-client` to be redirected to the login V2 and retrieve created authrequest and link them to SSO sessions. - Added a new "IAM_LOGIN_CLIENT" role to allow management of users, sessions, grants and more without `x-zitadel-login-client`. # Additional Changes None # Additional Context closes https://github.com/zitadel/zitadel/issues/8702
This commit is contained in:
@@ -60,6 +60,8 @@ type OIDCApp struct {
|
||||
AllowedOrigins database.TextArray[string]
|
||||
SkipNativeAppSuccessPage bool
|
||||
BackChannelLogoutURI string
|
||||
LoginVersion domain.LoginVersion
|
||||
LoginBaseURI *string
|
||||
}
|
||||
|
||||
type SAMLApp struct {
|
||||
@@ -180,6 +182,10 @@ var (
|
||||
name: projection.AppOIDCConfigColumnAppID,
|
||||
table: appOIDCConfigsTable,
|
||||
}
|
||||
AppOIDCConfigColumnInstanceID = Column{
|
||||
name: projection.AppOIDCConfigColumnInstanceID,
|
||||
table: appOIDCConfigsTable,
|
||||
}
|
||||
AppOIDCConfigColumnVersion = Column{
|
||||
name: projection.AppOIDCConfigColumnVersion,
|
||||
table: appOIDCConfigsTable,
|
||||
@@ -248,6 +254,14 @@ var (
|
||||
name: projection.AppOIDCConfigColumnBackChannelLogoutURI,
|
||||
table: appOIDCConfigsTable,
|
||||
}
|
||||
AppOIDCConfigColumnLoginVersion = Column{
|
||||
name: projection.AppOIDCConfigColumnLoginVersion,
|
||||
table: appOIDCConfigsTable,
|
||||
}
|
||||
AppOIDCConfigColumnLoginBaseURI = Column{
|
||||
name: projection.AppOIDCConfigColumnLoginBaseURI,
|
||||
table: appOIDCConfigsTable,
|
||||
}
|
||||
)
|
||||
|
||||
func (q *Queries) AppByProjectAndAppID(ctx context.Context, shouldTriggerBulk bool, projectID, appID string) (app *App, err error) {
|
||||
@@ -501,6 +515,30 @@ func (q *Queries) SearchClientIDs(ctx context.Context, queries *AppSearchQueries
|
||||
return ids, nil
|
||||
}
|
||||
|
||||
func (q *Queries) OIDCClientLoginVersion(ctx context.Context, clientID string) (loginVersion domain.LoginVersion, err error) {
|
||||
ctx, span := tracing.NewSpan(ctx)
|
||||
defer func() { span.EndWithError(err) }()
|
||||
|
||||
query, scan := prepareLoginVersionByClientID(ctx, q.client)
|
||||
eq := sq.Eq{
|
||||
AppOIDCConfigColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
|
||||
AppOIDCConfigColumnClientID.identifier(): clientID,
|
||||
}
|
||||
stmt, args, err := query.Where(eq).ToSql()
|
||||
if err != nil {
|
||||
return domain.LoginVersionUnspecified, zerrors.ThrowInvalidArgument(err, "QUERY-WEh31", "Errors.Query.InvalidRequest")
|
||||
}
|
||||
|
||||
err = q.client.QueryRowContext(ctx, func(row *sql.Row) error {
|
||||
loginVersion, err = scan(row)
|
||||
return err
|
||||
}, stmt, args...)
|
||||
if err != nil {
|
||||
return domain.LoginVersionUnspecified, zerrors.ThrowInternal(err, "QUERY-W2gsa", "Errors.Internal")
|
||||
}
|
||||
return loginVersion, nil
|
||||
}
|
||||
|
||||
func NewAppNameSearchQuery(method TextComparison, value string) (SearchQuery, error) {
|
||||
return NewTextQuery(AppColumnName, value, method)
|
||||
}
|
||||
@@ -542,6 +580,8 @@ func prepareAppQuery(ctx context.Context, db prepareDatabase, activeOnly bool) (
|
||||
AppOIDCConfigColumnAdditionalOrigins.identifier(),
|
||||
AppOIDCConfigColumnSkipNativeAppSuccessPage.identifier(),
|
||||
AppOIDCConfigColumnBackChannelLogoutURI.identifier(),
|
||||
AppOIDCConfigColumnLoginVersion.identifier(),
|
||||
AppOIDCConfigColumnLoginBaseURI.identifier(),
|
||||
|
||||
AppSAMLConfigColumnAppID.identifier(),
|
||||
AppSAMLConfigColumnEntityID.identifier(),
|
||||
@@ -607,6 +647,8 @@ func scanApp(row *sql.Row) (*App, error) {
|
||||
&oidcConfig.additionalOrigins,
|
||||
&oidcConfig.skipNativeAppSuccessPage,
|
||||
&oidcConfig.backChannelLogoutURI,
|
||||
&oidcConfig.loginVersion,
|
||||
&oidcConfig.loginBaseURI,
|
||||
|
||||
&samlConfig.appID,
|
||||
&samlConfig.entityID,
|
||||
@@ -657,6 +699,8 @@ func prepareOIDCAppQuery() (sq.SelectBuilder, func(*sql.Row) (*App, error)) {
|
||||
AppOIDCConfigColumnAdditionalOrigins.identifier(),
|
||||
AppOIDCConfigColumnSkipNativeAppSuccessPage.identifier(),
|
||||
AppOIDCConfigColumnBackChannelLogoutURI.identifier(),
|
||||
AppOIDCConfigColumnLoginVersion.identifier(),
|
||||
AppOIDCConfigColumnLoginBaseURI.identifier(),
|
||||
).From(appsTable.identifier()).
|
||||
Join(join(AppOIDCConfigColumnAppID, AppColumnID)).
|
||||
PlaceholderFormat(sq.Dollar), func(row *sql.Row) (*App, error) {
|
||||
@@ -694,6 +738,8 @@ func prepareOIDCAppQuery() (sq.SelectBuilder, func(*sql.Row) (*App, error)) {
|
||||
&oidcConfig.additionalOrigins,
|
||||
&oidcConfig.skipNativeAppSuccessPage,
|
||||
&oidcConfig.backChannelLogoutURI,
|
||||
&oidcConfig.loginVersion,
|
||||
&oidcConfig.loginBaseURI,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
@@ -906,6 +952,8 @@ func prepareAppsQuery(ctx context.Context, db prepareDatabase) (sq.SelectBuilder
|
||||
AppOIDCConfigColumnAdditionalOrigins.identifier(),
|
||||
AppOIDCConfigColumnSkipNativeAppSuccessPage.identifier(),
|
||||
AppOIDCConfigColumnBackChannelLogoutURI.identifier(),
|
||||
AppOIDCConfigColumnLoginVersion.identifier(),
|
||||
AppOIDCConfigColumnLoginBaseURI.identifier(),
|
||||
|
||||
AppSAMLConfigColumnAppID.identifier(),
|
||||
AppSAMLConfigColumnEntityID.identifier(),
|
||||
@@ -959,6 +1007,8 @@ func prepareAppsQuery(ctx context.Context, db prepareDatabase) (sq.SelectBuilder
|
||||
&oidcConfig.additionalOrigins,
|
||||
&oidcConfig.skipNativeAppSuccessPage,
|
||||
&oidcConfig.backChannelLogoutURI,
|
||||
&oidcConfig.loginVersion,
|
||||
&oidcConfig.loginBaseURI,
|
||||
|
||||
&samlConfig.appID,
|
||||
&samlConfig.entityID,
|
||||
@@ -1013,6 +1063,21 @@ func prepareClientIDsQuery(ctx context.Context, db prepareDatabase) (sq.SelectBu
|
||||
}
|
||||
}
|
||||
|
||||
func prepareLoginVersionByClientID(ctx context.Context, db prepareDatabase) (sq.SelectBuilder, func(*sql.Row) (domain.LoginVersion, error)) {
|
||||
return sq.Select(
|
||||
AppOIDCConfigColumnLoginVersion.identifier(),
|
||||
).From(appOIDCConfigsTable.identifier()).
|
||||
PlaceholderFormat(sq.Dollar), func(row *sql.Row) (domain.LoginVersion, error) {
|
||||
var loginVersion sql.NullInt16
|
||||
if err := row.Scan(
|
||||
&loginVersion,
|
||||
); err != nil {
|
||||
return domain.LoginVersionUnspecified, zerrors.ThrowInternal(err, "QUERY-KL2io", "Errors.Internal")
|
||||
}
|
||||
return domain.LoginVersion(loginVersion.Int16), nil
|
||||
}
|
||||
}
|
||||
|
||||
type sqlOIDCConfig struct {
|
||||
appID sql.NullString
|
||||
version sql.NullInt32
|
||||
@@ -1032,6 +1097,8 @@ type sqlOIDCConfig struct {
|
||||
grantTypes database.NumberArray[domain.OIDCGrantType]
|
||||
skipNativeAppSuccessPage sql.NullBool
|
||||
backChannelLogoutURI sql.NullString
|
||||
loginVersion sql.NullInt16
|
||||
loginBaseURI sql.NullString
|
||||
}
|
||||
|
||||
func (c sqlOIDCConfig) set(app *App) {
|
||||
@@ -1056,6 +1123,10 @@ func (c sqlOIDCConfig) set(app *App) {
|
||||
GrantTypes: c.grantTypes,
|
||||
SkipNativeAppSuccessPage: c.skipNativeAppSuccessPage.Bool,
|
||||
BackChannelLogoutURI: c.backChannelLogoutURI.String,
|
||||
LoginVersion: domain.LoginVersion(c.loginVersion.Int16),
|
||||
}
|
||||
if c.loginBaseURI.Valid {
|
||||
app.OIDCConfig.LoginBaseURI = &c.loginBaseURI.String
|
||||
}
|
||||
compliance := domain.GetOIDCCompliance(app.OIDCConfig.Version, app.OIDCConfig.AppType, app.OIDCConfig.GrantTypes, app.OIDCConfig.ResponseTypes, app.OIDCConfig.AuthMethodType, app.OIDCConfig.RedirectURIs)
|
||||
app.OIDCConfig.ComplianceProblems = compliance.Problems
|
||||
|
Reference in New Issue
Block a user