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:
Livio Spring
2024-12-19 10:37:46 +01:00
committed by GitHub
parent b5e92a6144
commit 50d2b26a28
89 changed files with 1670 additions and 321 deletions

View File

@@ -4,7 +4,9 @@ import (
"context"
"database/sql"
_ "embed"
"encoding/json"
"errors"
"net/url"
"time"
"github.com/zitadel/zitadel/internal/api/authz"
@@ -39,10 +41,32 @@ type OIDCClient struct {
PublicKeys map[string][]byte `json:"public_keys,omitempty"`
ProjectID string `json:"project_id,omitempty"`
ProjectRoleAssertion bool `json:"project_role_assertion,omitempty"`
LoginVersion domain.LoginVersion `json:"login_version,omitempty"`
LoginBaseURI *URL `json:"login_base_uri,omitempty"`
ProjectRoleKeys []string `json:"project_role_keys,omitempty"`
Settings *OIDCSettings `json:"settings,omitempty"`
}
type URL url.URL
func (c *URL) URL() *url.URL {
return (*url.URL)(c)
}
func (c *URL) UnmarshalJSON(src []byte) error {
var s string
err := json.Unmarshal(src, &s)
if err != nil {
return err
}
u, err := url.Parse(s)
if err != nil {
return err
}
*c = URL(*u)
return nil
}
//go:embed oidc_client_by_id.sql
var oidcClientQuery string
@@ -59,7 +83,13 @@ func (q *Queries) ActiveOIDCClientByID(ctx context.Context, clientID string, get
if err != nil {
return nil, zerrors.ThrowInternal(err, "QUERY-ieR7R", "Errors.Internal")
}
if authz.GetInstance(ctx).ConsoleClientID() == clientID {
instance := authz.GetInstance(ctx)
loginV2 := instance.Features().LoginV2
if loginV2.Required {
client.LoginVersion = domain.LoginVersion2
client.LoginBaseURI = (*URL)(loginV2.BaseURI)
}
if instance.ConsoleClientID() == clientID {
client.RedirectURIs = append(client.RedirectURIs, http_util.DomainContext(ctx).Origin()+path.RedirectPath)
client.PostLogoutRedirectURIs = append(client.PostLogoutRedirectURIs, http_util.DomainContext(ctx).Origin()+path.PostLogoutPath)
}