mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 16:47:32 +00:00
chore(oidc): graduate webkey to stable (#10122)
# Which Problems Are Solved Stabilize the usage of webkeys. # How the Problems Are Solved - Remove all legacy signing key code from the OIDC API - Remove the webkey feature flag from proto - Remove the webkey feature flag from console - Cleanup documentation # Additional Changes - Resolved some canonical header linter errors in OIDC - Use the constant for `projections.lock` in the saml package. # Additional Context - Closes #10029 - After #10105 - After #10061
This commit is contained in:
@@ -550,7 +550,6 @@ func startAPIs(
|
|||||||
keys.OIDC,
|
keys.OIDC,
|
||||||
keys.OIDCKey,
|
keys.OIDCKey,
|
||||||
eventstore,
|
eventstore,
|
||||||
dbClient,
|
|
||||||
userAgentInterceptor,
|
userAgentInterceptor,
|
||||||
instanceInterceptor.Handler,
|
instanceInterceptor.Handler,
|
||||||
limitingAccessInterceptor,
|
limitingAccessInterceptor,
|
||||||
|
@@ -38,7 +38,6 @@ const FEATURE_KEYS = [
|
|||||||
'oidcTriggerIntrospectionProjections',
|
'oidcTriggerIntrospectionProjections',
|
||||||
'permissionCheckV2',
|
'permissionCheckV2',
|
||||||
'userSchema',
|
'userSchema',
|
||||||
'webKey',
|
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
export type ToggleState = { source: Source; enabled: boolean };
|
export type ToggleState = { source: Source; enabled: boolean };
|
||||||
|
@@ -1641,8 +1641,6 @@
|
|||||||
"ENABLEBACKCHANNELLOGOUT_DESCRIPTION": "Back-Channel Logout имплементира OpenID Connect Back-Channel Logout 1.0 и може да се използва за уведомяване на клиентите за прекратяване на сесията при OpenID доставчика.",
|
"ENABLEBACKCHANNELLOGOUT_DESCRIPTION": "Back-Channel Logout имплементира OpenID Connect Back-Channel Logout 1.0 и може да се използва за уведомяване на клиентите за прекратяване на сесията при OpenID доставчика.",
|
||||||
"PERMISSIONCHECKV2": "Проверка на разрешения V2",
|
"PERMISSIONCHECKV2": "Проверка на разрешения V2",
|
||||||
"PERMISSIONCHECKV2_DESCRIPTION": "Ако флагът е активиран, ще можете да използвате новия API и неговите функции.",
|
"PERMISSIONCHECKV2_DESCRIPTION": "Ако флагът е активиран, ще можете да използвате новия API и неговите функции.",
|
||||||
"WEBKEY": "Уеб ключ",
|
|
||||||
"WEBKEY_DESCRIPTION": "Ако флагът е активиран, ще можете да използвате новия API и неговите функции.",
|
|
||||||
"STATES": {
|
"STATES": {
|
||||||
"INHERITED": "Наследено",
|
"INHERITED": "Наследено",
|
||||||
"ENABLED": "Активирано",
|
"ENABLED": "Активирано",
|
||||||
|
@@ -1642,8 +1642,6 @@
|
|||||||
"ENABLEBACKCHANNELLOGOUT_DESCRIPTION": "Back-Channel Logout implementuje OpenID Connect Back-Channel Logout 1.0 a může být použit k informování klientů o ukončení relace u poskytovatele OpenID.",
|
"ENABLEBACKCHANNELLOGOUT_DESCRIPTION": "Back-Channel Logout implementuje OpenID Connect Back-Channel Logout 1.0 a může být použit k informování klientů o ukončení relace u poskytovatele OpenID.",
|
||||||
"PERMISSIONCHECKV2": "Kontrola oprávnění V2",
|
"PERMISSIONCHECKV2": "Kontrola oprávnění V2",
|
||||||
"PERMISSIONCHECKV2_DESCRIPTION": "Pokud je příznak povolen, budete moci používat nový API a jeho funkce.",
|
"PERMISSIONCHECKV2_DESCRIPTION": "Pokud je příznak povolen, budete moci používat nový API a jeho funkce.",
|
||||||
"WEBKEY": "Webový klíč",
|
|
||||||
"WEBKEY_DESCRIPTION": "Pokud je příznak povolen, budete moci používat nový API a jeho funkce.",
|
|
||||||
"STATES": {
|
"STATES": {
|
||||||
"INHERITED": "Děděno",
|
"INHERITED": "Děděno",
|
||||||
"ENABLED": "Povoleno",
|
"ENABLED": "Povoleno",
|
||||||
|
@@ -1642,8 +1642,6 @@
|
|||||||
"ENABLEBACKCHANNELLOGOUT_DESCRIPTION": "Der Back-Channel-Logout implementiert OpenID Connect Back-Channel Logout 1.0 und kann verwendet werden, um Clients über die Beendigung der Sitzung beim OpenID-Provider zu benachrichtigen.",
|
"ENABLEBACKCHANNELLOGOUT_DESCRIPTION": "Der Back-Channel-Logout implementiert OpenID Connect Back-Channel Logout 1.0 und kann verwendet werden, um Clients über die Beendigung der Sitzung beim OpenID-Provider zu benachrichtigen.",
|
||||||
"PERMISSIONCHECKV2": "Berechtigungsprüfung V2",
|
"PERMISSIONCHECKV2": "Berechtigungsprüfung V2",
|
||||||
"PERMISSIONCHECKV2_DESCRIPTION": "Wenn die Flagge aktiviert ist, können Sie die neue API und ihre Funktionen verwenden.",
|
"PERMISSIONCHECKV2_DESCRIPTION": "Wenn die Flagge aktiviert ist, können Sie die neue API und ihre Funktionen verwenden.",
|
||||||
"WEBKEY": "Web-Schlüssel",
|
|
||||||
"WEBKEY_DESCRIPTION": "Wenn die Flagge aktiviert ist, können Sie die neue API und ihre Funktionen verwenden.",
|
|
||||||
"STATES": {
|
"STATES": {
|
||||||
"INHERITED": "Erben",
|
"INHERITED": "Erben",
|
||||||
"ENABLED": "Aktiviert",
|
"ENABLED": "Aktiviert",
|
||||||
|
@@ -1645,8 +1645,6 @@
|
|||||||
"ENABLEBACKCHANNELLOGOUT_DESCRIPTION": "The Back-Channel Logout implements OpenID Connect Back-Channel Logout 1.0 and can be used to notify clients about session termination at the OpenID Provider.",
|
"ENABLEBACKCHANNELLOGOUT_DESCRIPTION": "The Back-Channel Logout implements OpenID Connect Back-Channel Logout 1.0 and can be used to notify clients about session termination at the OpenID Provider.",
|
||||||
"PERMISSIONCHECKV2": "Permission Check V2",
|
"PERMISSIONCHECKV2": "Permission Check V2",
|
||||||
"PERMISSIONCHECKV2_DESCRIPTION": "If the flag is enabled, you'll be able to use the new API and its features.",
|
"PERMISSIONCHECKV2_DESCRIPTION": "If the flag is enabled, you'll be able to use the new API and its features.",
|
||||||
"WEBKEY": "Web Key",
|
|
||||||
"WEBKEY_DESCRIPTION": "If the flag is enabled, you'll be able to use the new API and its features.",
|
|
||||||
"STATES": {
|
"STATES": {
|
||||||
"INHERITED": "Inherit",
|
"INHERITED": "Inherit",
|
||||||
"ENABLED": "Enabled",
|
"ENABLED": "Enabled",
|
||||||
|
@@ -1643,8 +1643,6 @@
|
|||||||
"ENABLEBACKCHANNELLOGOUT_DESCRIPTION": "El Back-Channel Logout implementa OpenID Connect Back-Channel Logout 1.0 y se puede usar para notificar a los clientes sobre la terminación de la sesión en el proveedor de OpenID.",
|
"ENABLEBACKCHANNELLOGOUT_DESCRIPTION": "El Back-Channel Logout implementa OpenID Connect Back-Channel Logout 1.0 y se puede usar para notificar a los clientes sobre la terminación de la sesión en el proveedor de OpenID.",
|
||||||
"PERMISSIONCHECKV2": "Verificación de permisos V2",
|
"PERMISSIONCHECKV2": "Verificación de permisos V2",
|
||||||
"PERMISSIONCHECKV2_DESCRIPTION": "Si la bandera está habilitada, podrá usar la nueva API y sus funciones.",
|
"PERMISSIONCHECKV2_DESCRIPTION": "Si la bandera está habilitada, podrá usar la nueva API y sus funciones.",
|
||||||
"WEBKEY": "Clave web",
|
|
||||||
"WEBKEY_DESCRIPTION": "Si la bandera está habilitada, podrá usar la nueva API y sus funciones.",
|
|
||||||
"STATES": {
|
"STATES": {
|
||||||
"INHERITED": "Heredado",
|
"INHERITED": "Heredado",
|
||||||
"ENABLED": "Habilitado",
|
"ENABLED": "Habilitado",
|
||||||
|
@@ -1642,8 +1642,6 @@
|
|||||||
"ENABLEBACKCHANNELLOGOUT_DESCRIPTION": "Le Back-Channel Logout implémente OpenID Connect Back-Channel Logout 1.0 et peut être utilisé pour notifier les clients de la fin de session chez le fournisseur OpenID.",
|
"ENABLEBACKCHANNELLOGOUT_DESCRIPTION": "Le Back-Channel Logout implémente OpenID Connect Back-Channel Logout 1.0 et peut être utilisé pour notifier les clients de la fin de session chez le fournisseur OpenID.",
|
||||||
"PERMISSIONCHECKV2": "Vérification des permissions V2",
|
"PERMISSIONCHECKV2": "Vérification des permissions V2",
|
||||||
"PERMISSIONCHECKV2_DESCRIPTION": "Si le drapeau est activé, vous pourrez utiliser la nouvelle API et ses fonctionnalités.",
|
"PERMISSIONCHECKV2_DESCRIPTION": "Si le drapeau est activé, vous pourrez utiliser la nouvelle API et ses fonctionnalités.",
|
||||||
"WEBKEY": "Clé web",
|
|
||||||
"WEBKEY_DESCRIPTION": "Si le drapeau est activé, vous pourrez utiliser la nouvelle API et ses fonctionnalités.",
|
|
||||||
"STATES": {
|
"STATES": {
|
||||||
"INHERITED": "Hérité",
|
"INHERITED": "Hérité",
|
||||||
"ENABLED": "Activé",
|
"ENABLED": "Activé",
|
||||||
|
@@ -1640,8 +1640,6 @@
|
|||||||
"ENABLEBACKCHANNELLOGOUT_DESCRIPTION": "A Back-Channel Logout megvalósítja az OpenID Connect Back-Channel Logout 1.0-t, és használható az ügyfelek értesítésére a munkamenet befejezéséről az OpenID szolgáltatónál.",
|
"ENABLEBACKCHANNELLOGOUT_DESCRIPTION": "A Back-Channel Logout megvalósítja az OpenID Connect Back-Channel Logout 1.0-t, és használható az ügyfelek értesítésére a munkamenet befejezéséről az OpenID szolgáltatónál.",
|
||||||
"PERMISSIONCHECKV2": "Engedély ellenőrzés V2",
|
"PERMISSIONCHECKV2": "Engedély ellenőrzés V2",
|
||||||
"PERMISSIONCHECKV2_DESCRIPTION": "Ha a zászló engedélyezve van, használhatja az új API-t és annak funkcióit.",
|
"PERMISSIONCHECKV2_DESCRIPTION": "Ha a zászló engedélyezve van, használhatja az új API-t és annak funkcióit.",
|
||||||
"WEBKEY": "Webkulcs",
|
|
||||||
"WEBKEY_DESCRIPTION": "Ha a zászló engedélyezve van, használhatja az új API-t és annak funkcióit.",
|
|
||||||
"STATES": {
|
"STATES": {
|
||||||
"INHERITED": "Örököl",
|
"INHERITED": "Örököl",
|
||||||
"ENABLED": "Engedélyezve",
|
"ENABLED": "Engedélyezve",
|
||||||
|
@@ -1513,8 +1513,6 @@
|
|||||||
"ENABLEBACKCHANNELLOGOUT_DESCRIPTION": "The Back-Channel Logout implements OpenID Connect Back-Channel Logout 1.0 and can be used to notify clients about session termination at the OpenID Provider.",
|
"ENABLEBACKCHANNELLOGOUT_DESCRIPTION": "The Back-Channel Logout implements OpenID Connect Back-Channel Logout 1.0 and can be used to notify clients about session termination at the OpenID Provider.",
|
||||||
"PERMISSIONCHECKV2": "Permission Check V2",
|
"PERMISSIONCHECKV2": "Permission Check V2",
|
||||||
"PERMISSIONCHECKV2_DESCRIPTION": "If the flag is enabled, you'll be able to use the new API and its features.",
|
"PERMISSIONCHECKV2_DESCRIPTION": "If the flag is enabled, you'll be able to use the new API and its features.",
|
||||||
"WEBKEY": "Web Key",
|
|
||||||
"WEBKEY_DESCRIPTION": "If the flag is enabled, you'll be able to use the new API and its features.",
|
|
||||||
"STATES": { "INHERITED": "Mewarisi", "ENABLED": "Diaktifkan", "DISABLED": "Dengan disabilitas" },
|
"STATES": { "INHERITED": "Mewarisi", "ENABLED": "Diaktifkan", "DISABLED": "Dengan disabilitas" },
|
||||||
"INHERITED_DESCRIPTION": "Ini menetapkan nilai ke nilai default sistem.",
|
"INHERITED_DESCRIPTION": "Ini menetapkan nilai ke nilai default sistem.",
|
||||||
"INHERITEDINDICATOR_DESCRIPTION": {
|
"INHERITEDINDICATOR_DESCRIPTION": {
|
||||||
|
@@ -1642,8 +1642,6 @@
|
|||||||
"ENABLEBACKCHANNELLOGOUT_DESCRIPTION": "Il Back-Channel Logout implementa OpenID Connect Back-Channel Logout 1.0 e può essere utilizzato per notificare ai client la terminazione della sessione presso il provider OpenID.",
|
"ENABLEBACKCHANNELLOGOUT_DESCRIPTION": "Il Back-Channel Logout implementa OpenID Connect Back-Channel Logout 1.0 e può essere utilizzato per notificare ai client la terminazione della sessione presso il provider OpenID.",
|
||||||
"PERMISSIONCHECKV2": "Controllo permessi V2",
|
"PERMISSIONCHECKV2": "Controllo permessi V2",
|
||||||
"PERMISSIONCHECKV2_DESCRIPTION": "Se il flag è abilitato, potrai utilizzare la nuova API e le sue funzionalità.",
|
"PERMISSIONCHECKV2_DESCRIPTION": "Se il flag è abilitato, potrai utilizzare la nuova API e le sue funzionalità.",
|
||||||
"WEBKEY": "Chiave Web",
|
|
||||||
"WEBKEY_DESCRIPTION": "Se il flag è abilitato, potrai utilizzare la nuova API e le sue funzionalità.",
|
|
||||||
"STATES": {
|
"STATES": {
|
||||||
"INHERITED": "Predefinito",
|
"INHERITED": "Predefinito",
|
||||||
"ENABLED": "Abilitato",
|
"ENABLED": "Abilitato",
|
||||||
|
@@ -1642,8 +1642,6 @@
|
|||||||
"ENABLEBACKCHANNELLOGOUT_DESCRIPTION": "バックチャネルログアウトは OpenID Connect バックチャネルログアウト 1.0 を実装し、OpenID プロバイダーでのセッション終了についてクライアントに通知するために使用できます。",
|
"ENABLEBACKCHANNELLOGOUT_DESCRIPTION": "バックチャネルログアウトは OpenID Connect バックチャネルログアウト 1.0 を実装し、OpenID プロバイダーでのセッション終了についてクライアントに通知するために使用できます。",
|
||||||
"PERMISSIONCHECKV2": "権限チェック V2",
|
"PERMISSIONCHECKV2": "権限チェック V2",
|
||||||
"PERMISSIONCHECKV2_DESCRIPTION": "フラグが有効になっている場合、新しい API とその機能を使用できます。",
|
"PERMISSIONCHECKV2_DESCRIPTION": "フラグが有効になっている場合、新しい API とその機能を使用できます。",
|
||||||
"WEBKEY": "ウェブキー",
|
|
||||||
"WEBKEY_DESCRIPTION": "フラグが有効になっている場合、新しい API とその機能を使用できます。",
|
|
||||||
"STATES": {
|
"STATES": {
|
||||||
"INHERITED": "継承",
|
"INHERITED": "継承",
|
||||||
"ENABLED": "有効",
|
"ENABLED": "有効",
|
||||||
|
@@ -1642,8 +1642,6 @@
|
|||||||
"ENABLEBACKCHANNELLOGOUT_DESCRIPTION": "백채널 로그아웃은 OpenID Connect 백채널 로그아웃 1.0을 구현하며, OpenID 제공자에서 세션 종료에 대해 클라이언트에게 알리는 데 사용할 수 있습니다.",
|
"ENABLEBACKCHANNELLOGOUT_DESCRIPTION": "백채널 로그아웃은 OpenID Connect 백채널 로그아웃 1.0을 구현하며, OpenID 제공자에서 세션 종료에 대해 클라이언트에게 알리는 데 사용할 수 있습니다.",
|
||||||
"PERMISSIONCHECKV2": "권한 확인 V2",
|
"PERMISSIONCHECKV2": "권한 확인 V2",
|
||||||
"PERMISSIONCHECKV2_DESCRIPTION": "플래그가 활성화되면 새로운 API와 그 기능을 사용할 수 있습니다.",
|
"PERMISSIONCHECKV2_DESCRIPTION": "플래그가 활성화되면 새로운 API와 그 기능을 사용할 수 있습니다.",
|
||||||
"WEBKEY": "웹 키",
|
|
||||||
"WEBKEY_DESCRIPTION": "플래그가 활성화되면 새로운 API와 그 기능을 사용할 수 있습니다.",
|
|
||||||
"STATES": {
|
"STATES": {
|
||||||
"INHERITED": "상속",
|
"INHERITED": "상속",
|
||||||
"ENABLED": "활성화됨",
|
"ENABLED": "활성화됨",
|
||||||
|
@@ -1643,8 +1643,6 @@
|
|||||||
"ENABLEBACKCHANNELLOGOUT_DESCRIPTION": "Back-Channel Logout имплементира OpenID Connect Back-Channel Logout 1.0 и може да се користи за известување на клиентите за завршување на сесијата кај OpenID провајдерот.",
|
"ENABLEBACKCHANNELLOGOUT_DESCRIPTION": "Back-Channel Logout имплементира OpenID Connect Back-Channel Logout 1.0 и може да се користи за известување на клиентите за завршување на сесијата кај OpenID провајдерот.",
|
||||||
"PERMISSIONCHECKV2": "Проверка на дозволи V2",
|
"PERMISSIONCHECKV2": "Проверка на дозволи V2",
|
||||||
"PERMISSIONCHECKV2_DESCRIPTION": "Ако знамето е овозможено, ќе можете да ја користите новата API и нејзините функции.",
|
"PERMISSIONCHECKV2_DESCRIPTION": "Ако знамето е овозможено, ќе можете да ја користите новата API и нејзините функции.",
|
||||||
"WEBKEY": "Веб клуч",
|
|
||||||
"WEBKEY_DESCRIPTION": "Ако знамето е овозможено, ќе можете да ја користите новата API и нејзините функции.",
|
|
||||||
"STATES": {
|
"STATES": {
|
||||||
"INHERITED": "Наследи",
|
"INHERITED": "Наследи",
|
||||||
"ENABLED": "Овозможено",
|
"ENABLED": "Овозможено",
|
||||||
|
@@ -1642,8 +1642,6 @@
|
|||||||
"ENABLEBACKCHANNELLOGOUT_DESCRIPTION": "De Back-Channel Logout implementeert OpenID Connect Back-Channel Logout 1.0 en kan worden gebruikt om clients te informeren over het beëindigen van de sessie bij de OpenID-provider.",
|
"ENABLEBACKCHANNELLOGOUT_DESCRIPTION": "De Back-Channel Logout implementeert OpenID Connect Back-Channel Logout 1.0 en kan worden gebruikt om clients te informeren over het beëindigen van de sessie bij de OpenID-provider.",
|
||||||
"PERMISSIONCHECKV2": "Permissiecontrole V2",
|
"PERMISSIONCHECKV2": "Permissiecontrole V2",
|
||||||
"PERMISSIONCHECKV2_DESCRIPTION": "Als de vlag is ingeschakeld, kunt u de nieuwe API en de bijbehorende functies gebruiken.",
|
"PERMISSIONCHECKV2_DESCRIPTION": "Als de vlag is ingeschakeld, kunt u de nieuwe API en de bijbehorende functies gebruiken.",
|
||||||
"WEBKEY": "Websleutel",
|
|
||||||
"WEBKEY_DESCRIPTION": "Als de vlag is ingeschakeld, kunt u de nieuwe API en de bijbehorende functies gebruiken.",
|
|
||||||
"STATES": {
|
"STATES": {
|
||||||
"INHERITED": "Overgenomen",
|
"INHERITED": "Overgenomen",
|
||||||
"ENABLED": "Ingeschakeld",
|
"ENABLED": "Ingeschakeld",
|
||||||
|
@@ -1641,8 +1641,6 @@
|
|||||||
"ENABLEBACKCHANNELLOGOUT_DESCRIPTION": "Back-Channel Logout implementuje OpenID Connect Back-Channel Logout 1.0 i może być używany do powiadamiania klientów o zakończeniu sesji u dostawcy OpenID.",
|
"ENABLEBACKCHANNELLOGOUT_DESCRIPTION": "Back-Channel Logout implementuje OpenID Connect Back-Channel Logout 1.0 i może być używany do powiadamiania klientów o zakończeniu sesji u dostawcy OpenID.",
|
||||||
"PERMISSIONCHECKV2": "Sprawdzanie uprawnień V2",
|
"PERMISSIONCHECKV2": "Sprawdzanie uprawnień V2",
|
||||||
"PERMISSIONCHECKV2_DESCRIPTION": "Jeśli flaga jest włączona, będziesz mógł korzystać z nowego API i jego funkcji.",
|
"PERMISSIONCHECKV2_DESCRIPTION": "Jeśli flaga jest włączona, będziesz mógł korzystać z nowego API i jego funkcji.",
|
||||||
"WEBKEY": "Klucz Web",
|
|
||||||
"WEBKEY_DESCRIPTION": "Jeśli flaga jest włączona, będziesz mógł korzystać z nowego API i jego funkcji.",
|
|
||||||
"STATES": {
|
"STATES": {
|
||||||
"INHERITED": "Dziedziczony",
|
"INHERITED": "Dziedziczony",
|
||||||
"ENABLED": "Włączony",
|
"ENABLED": "Włączony",
|
||||||
|
@@ -1643,8 +1643,6 @@
|
|||||||
"ENABLEBACKCHANNELLOGOUT_DESCRIPTION": "O Logout de Back-Channel implementa o OpenID Connect Back-Channel Logout 1.0 e pode ser usado para notificar os clientes sobre a terminação da sessão no Provedor de OpenID.",
|
"ENABLEBACKCHANNELLOGOUT_DESCRIPTION": "O Logout de Back-Channel implementa o OpenID Connect Back-Channel Logout 1.0 e pode ser usado para notificar os clientes sobre a terminação da sessão no Provedor de OpenID.",
|
||||||
"PERMISSIONCHECKV2": "Verificação de Permissão V2",
|
"PERMISSIONCHECKV2": "Verificação de Permissão V2",
|
||||||
"PERMISSIONCHECKV2_DESCRIPTION": "Se a bandeira estiver ativada, você poderá usar a nova API e seus recursos.",
|
"PERMISSIONCHECKV2_DESCRIPTION": "Se a bandeira estiver ativada, você poderá usar a nova API e seus recursos.",
|
||||||
"WEBKEY": "Chave Web",
|
|
||||||
"WEBKEY_DESCRIPTION": "Se a bandeira estiver ativada, você poderá usar a nova API e seus recursos.",
|
|
||||||
"STATES": {
|
"STATES": {
|
||||||
"INHERITED": "Herdade",
|
"INHERITED": "Herdade",
|
||||||
"ENABLED": "Habilitado",
|
"ENABLED": "Habilitado",
|
||||||
|
@@ -1640,8 +1640,6 @@
|
|||||||
"ENABLEBACKCHANNELLOGOUT_DESCRIPTION": "Logout-ul Back-Channel implementează OpenID Connect Back-Channel Logout 1.0 și poate fi folosit pentru a notifica clienții despre terminarea sesiunii la Producătorul OpenID.",
|
"ENABLEBACKCHANNELLOGOUT_DESCRIPTION": "Logout-ul Back-Channel implementează OpenID Connect Back-Channel Logout 1.0 și poate fi folosit pentru a notifica clienții despre terminarea sesiunii la Producătorul OpenID.",
|
||||||
"PERMISSIONCHECKV2": "Verificare Permisiuni V2",
|
"PERMISSIONCHECKV2": "Verificare Permisiuni V2",
|
||||||
"PERMISSIONCHECKV2_DESCRIPTION": "Dacă steagul este activat, veți putea folosi noua API și funcțiile sale.",
|
"PERMISSIONCHECKV2_DESCRIPTION": "Dacă steagul este activat, veți putea folosi noua API și funcțiile sale.",
|
||||||
"WEBKEY": "Cheie Web",
|
|
||||||
"WEBKEY_DESCRIPTION": "Dacă steagul este activat, veți putea folosi noua API și funcțiile sale.",
|
|
||||||
"STATES": {
|
"STATES": {
|
||||||
"INHERITED": "Moșteniți",
|
"INHERITED": "Moșteniți",
|
||||||
"ENABLED": "Activat",
|
"ENABLED": "Activat",
|
||||||
|
@@ -1695,8 +1695,6 @@
|
|||||||
"ENABLEBACKCHANNELLOGOUT_DESCRIPTION": "Back-Channel Logout реализует OpenID Connect Back-Channel Logout 1.0 и может использоваться для уведомления клиентов о завершении сеанса у поставщика OpenID.",
|
"ENABLEBACKCHANNELLOGOUT_DESCRIPTION": "Back-Channel Logout реализует OpenID Connect Back-Channel Logout 1.0 и может использоваться для уведомления клиентов о завершении сеанса у поставщика OpenID.",
|
||||||
"PERMISSIONCHECKV2": "Проверка Разрешений V2",
|
"PERMISSIONCHECKV2": "Проверка Разрешений V2",
|
||||||
"PERMISSIONCHECKV2_DESCRIPTION": "Если флаг включен, вы сможете использовать новый API и его функции.",
|
"PERMISSIONCHECKV2_DESCRIPTION": "Если флаг включен, вы сможете использовать новый API и его функции.",
|
||||||
"WEBKEY": "Веб-ключ",
|
|
||||||
"WEBKEY_DESCRIPTION": "Если флаг включен, вы сможете использовать новый API и его функции.",
|
|
||||||
"STATES": {
|
"STATES": {
|
||||||
"INHERITED": "Наследовать",
|
"INHERITED": "Наследовать",
|
||||||
"ENABLED": "Включено",
|
"ENABLED": "Включено",
|
||||||
|
@@ -1646,8 +1646,6 @@
|
|||||||
"ENABLEBACKCHANNELLOGOUT_DESCRIPTION": "Back-Channel Logout implementerar OpenID Connect Back-Channel Logout 1.0 och kan användas för att meddela klienter om sessionens avslutning hos OpenID-leverantören.",
|
"ENABLEBACKCHANNELLOGOUT_DESCRIPTION": "Back-Channel Logout implementerar OpenID Connect Back-Channel Logout 1.0 och kan användas för att meddela klienter om sessionens avslutning hos OpenID-leverantören.",
|
||||||
"PERMISSIONCHECKV2": "Behörighetskontroll V2",
|
"PERMISSIONCHECKV2": "Behörighetskontroll V2",
|
||||||
"PERMISSIONCHECKV2_DESCRIPTION": "Om flaggan är aktiverad kan du använda den nya API:n och dess funktioner.",
|
"PERMISSIONCHECKV2_DESCRIPTION": "Om flaggan är aktiverad kan du använda den nya API:n och dess funktioner.",
|
||||||
"WEBKEY": "Webbnyckel",
|
|
||||||
"WEBKEY_DESCRIPTION": "Om flaggan är aktiverad kan du använda den nya API:n och dess funktioner.",
|
|
||||||
"STATES": {
|
"STATES": {
|
||||||
"INHERITED": "Ärv",
|
"INHERITED": "Ärv",
|
||||||
"ENABLED": "Aktiverad",
|
"ENABLED": "Aktiverad",
|
||||||
|
@@ -1642,8 +1642,6 @@
|
|||||||
"ENABLEBACKCHANNELLOGOUT_DESCRIPTION": "Back-Channel 注销实现了 OpenID Connect Back-Channel Logout 1.0,可用于通知客户端在 OpenID 提供商处终止会话。",
|
"ENABLEBACKCHANNELLOGOUT_DESCRIPTION": "Back-Channel 注销实现了 OpenID Connect Back-Channel Logout 1.0,可用于通知客户端在 OpenID 提供商处终止会话。",
|
||||||
"PERMISSIONCHECKV2": "权限检查 V2",
|
"PERMISSIONCHECKV2": "权限检查 V2",
|
||||||
"PERMISSIONCHECKV2_DESCRIPTION": "如果启用该标志,您将能够使用新的 API 及其功能。",
|
"PERMISSIONCHECKV2_DESCRIPTION": "如果启用该标志,您将能够使用新的 API 及其功能。",
|
||||||
"WEBKEY": "Web 密钥",
|
|
||||||
"WEBKEY_DESCRIPTION": "如果启用该标志,您将能够使用新的 API 及其功能。",
|
|
||||||
"STATES": {
|
"STATES": {
|
||||||
"INHERITED": "继承",
|
"INHERITED": "继承",
|
||||||
"ENABLED": "已启用",
|
"ENABLED": "已启用",
|
||||||
|
@@ -20,13 +20,6 @@ JWT access tokens, instead of [introspection](/docs/apis/openidoauth/endpoints#i
|
|||||||
ZITADEL uses public key verification when API calls are made or when the userInfo or introspection
|
ZITADEL uses public key verification when API calls are made or when the userInfo or introspection
|
||||||
endpoints are called with a JWT access token.
|
endpoints are called with a JWT access token.
|
||||||
|
|
||||||
:::info
|
|
||||||
Web keys are an [experimental](/docs/support/software-release-cycles-support#beta) feature. Be sure to enable the `web_key` [feature](/docs/apis/resources/feature_service_v2/feature-service-set-instance-features) before using it.
|
|
||||||
|
|
||||||
The documentation describes the state of the feature in ZITADEL V3.
|
|
||||||
Test the feature and add improvement or bug reports directly to the [github repository](https://github.com/zitadel/zitadel) or let us know your general feedback in the [discord thread](https://discord.com/channels/927474939156643850/1329100936127320175/threads/1332344892629717075)!
|
|
||||||
:::
|
|
||||||
|
|
||||||
### JSON Web Key
|
### JSON Web Key
|
||||||
|
|
||||||
ZITADEL implements the [RFC7517 - JSON Web Key (JWK)](https://www.rfc-editor.org/rfc/rfc7517) format for storage and distribution of public keys.
|
ZITADEL implements the [RFC7517 - JSON Web Key (JWK)](https://www.rfc-editor.org/rfc/rfc7517) format for storage and distribution of public keys.
|
||||||
|
@@ -58,7 +58,6 @@ func instanceFeaturesToCommand(req *feature_pb.SetInstanceFeaturesRequest) (*com
|
|||||||
UserSchema: req.UserSchema,
|
UserSchema: req.UserSchema,
|
||||||
TokenExchange: req.OidcTokenExchange,
|
TokenExchange: req.OidcTokenExchange,
|
||||||
ImprovedPerformance: improvedPerformanceListToDomain(req.ImprovedPerformance),
|
ImprovedPerformance: improvedPerformanceListToDomain(req.ImprovedPerformance),
|
||||||
WebKey: req.WebKey,
|
|
||||||
DebugOIDCParentError: req.DebugOidcParentError,
|
DebugOIDCParentError: req.DebugOidcParentError,
|
||||||
OIDCSingleV1SessionTermination: req.OidcSingleV1SessionTermination,
|
OIDCSingleV1SessionTermination: req.OidcSingleV1SessionTermination,
|
||||||
DisableUserTokenEvent: req.DisableUserTokenEvent,
|
DisableUserTokenEvent: req.DisableUserTokenEvent,
|
||||||
@@ -77,7 +76,6 @@ func instanceFeaturesToPb(f *query.InstanceFeatures) *feature_pb.GetInstanceFeat
|
|||||||
UserSchema: featureSourceToFlagPb(&f.UserSchema),
|
UserSchema: featureSourceToFlagPb(&f.UserSchema),
|
||||||
OidcTokenExchange: featureSourceToFlagPb(&f.TokenExchange),
|
OidcTokenExchange: featureSourceToFlagPb(&f.TokenExchange),
|
||||||
ImprovedPerformance: featureSourceToImprovedPerformanceFlagPb(&f.ImprovedPerformance),
|
ImprovedPerformance: featureSourceToImprovedPerformanceFlagPb(&f.ImprovedPerformance),
|
||||||
WebKey: featureSourceToFlagPb(&f.WebKey),
|
|
||||||
DebugOidcParentError: featureSourceToFlagPb(&f.DebugOIDCParentError),
|
DebugOidcParentError: featureSourceToFlagPb(&f.DebugOIDCParentError),
|
||||||
OidcSingleV1SessionTermination: featureSourceToFlagPb(&f.OIDCSingleV1SessionTermination),
|
OidcSingleV1SessionTermination: featureSourceToFlagPb(&f.OIDCSingleV1SessionTermination),
|
||||||
DisableUserTokenEvent: featureSourceToFlagPb(&f.DisableUserTokenEvent),
|
DisableUserTokenEvent: featureSourceToFlagPb(&f.DisableUserTokenEvent),
|
||||||
|
@@ -153,7 +153,6 @@ func Test_instanceFeaturesToCommand(t *testing.T) {
|
|||||||
UserSchema: gu.Ptr(true),
|
UserSchema: gu.Ptr(true),
|
||||||
OidcTokenExchange: gu.Ptr(true),
|
OidcTokenExchange: gu.Ptr(true),
|
||||||
ImprovedPerformance: nil,
|
ImprovedPerformance: nil,
|
||||||
WebKey: gu.Ptr(true),
|
|
||||||
DebugOidcParentError: gu.Ptr(true),
|
DebugOidcParentError: gu.Ptr(true),
|
||||||
OidcSingleV1SessionTermination: gu.Ptr(true),
|
OidcSingleV1SessionTermination: gu.Ptr(true),
|
||||||
EnableBackChannelLogout: gu.Ptr(true),
|
EnableBackChannelLogout: gu.Ptr(true),
|
||||||
@@ -169,7 +168,6 @@ func Test_instanceFeaturesToCommand(t *testing.T) {
|
|||||||
UserSchema: gu.Ptr(true),
|
UserSchema: gu.Ptr(true),
|
||||||
TokenExchange: gu.Ptr(true),
|
TokenExchange: gu.Ptr(true),
|
||||||
ImprovedPerformance: nil,
|
ImprovedPerformance: nil,
|
||||||
WebKey: gu.Ptr(true),
|
|
||||||
DebugOIDCParentError: gu.Ptr(true),
|
DebugOIDCParentError: gu.Ptr(true),
|
||||||
OIDCSingleV1SessionTermination: gu.Ptr(true),
|
OIDCSingleV1SessionTermination: gu.Ptr(true),
|
||||||
EnableBackChannelLogout: gu.Ptr(true),
|
EnableBackChannelLogout: gu.Ptr(true),
|
||||||
@@ -211,10 +209,6 @@ func Test_instanceFeaturesToPb(t *testing.T) {
|
|||||||
Level: feature.LevelSystem,
|
Level: feature.LevelSystem,
|
||||||
Value: []feature.ImprovedPerformanceType{feature.ImprovedPerformanceTypeOrgByID},
|
Value: []feature.ImprovedPerformanceType{feature.ImprovedPerformanceTypeOrgByID},
|
||||||
},
|
},
|
||||||
WebKey: query.FeatureSource[bool]{
|
|
||||||
Level: feature.LevelInstance,
|
|
||||||
Value: true,
|
|
||||||
},
|
|
||||||
OIDCSingleV1SessionTermination: query.FeatureSource[bool]{
|
OIDCSingleV1SessionTermination: query.FeatureSource[bool]{
|
||||||
Level: feature.LevelInstance,
|
Level: feature.LevelInstance,
|
||||||
Value: true,
|
Value: true,
|
||||||
@@ -265,10 +259,6 @@ func Test_instanceFeaturesToPb(t *testing.T) {
|
|||||||
ExecutionPaths: []feature_pb.ImprovedPerformance{feature_pb.ImprovedPerformance_IMPROVED_PERFORMANCE_ORG_BY_ID},
|
ExecutionPaths: []feature_pb.ImprovedPerformance{feature_pb.ImprovedPerformance_IMPROVED_PERFORMANCE_ORG_BY_ID},
|
||||||
Source: feature_pb.Source_SOURCE_SYSTEM,
|
Source: feature_pb.Source_SOURCE_SYSTEM,
|
||||||
},
|
},
|
||||||
WebKey: &feature_pb.FeatureFlag{
|
|
||||||
Enabled: true,
|
|
||||||
Source: feature_pb.Source_SOURCE_INSTANCE,
|
|
||||||
},
|
|
||||||
DebugOidcParentError: &feature_pb.FeatureFlag{
|
DebugOidcParentError: &feature_pb.FeatureFlag{
|
||||||
Enabled: false,
|
Enabled: false,
|
||||||
Source: feature_pb.Source_SOURCE_UNSPECIFIED,
|
Source: feature_pb.Source_SOURCE_UNSPECIFIED,
|
||||||
|
@@ -38,7 +38,6 @@ func instanceFeaturesToCommand(req *feature_pb.SetInstanceFeaturesRequest) *comm
|
|||||||
UserSchema: req.UserSchema,
|
UserSchema: req.UserSchema,
|
||||||
TokenExchange: req.OidcTokenExchange,
|
TokenExchange: req.OidcTokenExchange,
|
||||||
ImprovedPerformance: improvedPerformanceListToDomain(req.ImprovedPerformance),
|
ImprovedPerformance: improvedPerformanceListToDomain(req.ImprovedPerformance),
|
||||||
WebKey: req.WebKey,
|
|
||||||
DebugOIDCParentError: req.DebugOidcParentError,
|
DebugOIDCParentError: req.DebugOidcParentError,
|
||||||
OIDCSingleV1SessionTermination: req.OidcSingleV1SessionTermination,
|
OIDCSingleV1SessionTermination: req.OidcSingleV1SessionTermination,
|
||||||
}
|
}
|
||||||
@@ -52,7 +51,6 @@ func instanceFeaturesToPb(f *query.InstanceFeatures) *feature_pb.GetInstanceFeat
|
|||||||
UserSchema: featureSourceToFlagPb(&f.UserSchema),
|
UserSchema: featureSourceToFlagPb(&f.UserSchema),
|
||||||
OidcTokenExchange: featureSourceToFlagPb(&f.TokenExchange),
|
OidcTokenExchange: featureSourceToFlagPb(&f.TokenExchange),
|
||||||
ImprovedPerformance: featureSourceToImprovedPerformanceFlagPb(&f.ImprovedPerformance),
|
ImprovedPerformance: featureSourceToImprovedPerformanceFlagPb(&f.ImprovedPerformance),
|
||||||
WebKey: featureSourceToFlagPb(&f.WebKey),
|
|
||||||
DebugOidcParentError: featureSourceToFlagPb(&f.DebugOIDCParentError),
|
DebugOidcParentError: featureSourceToFlagPb(&f.DebugOIDCParentError),
|
||||||
OidcSingleV1SessionTermination: featureSourceToFlagPb(&f.OIDCSingleV1SessionTermination),
|
OidcSingleV1SessionTermination: featureSourceToFlagPb(&f.OIDCSingleV1SessionTermination),
|
||||||
}
|
}
|
||||||
|
@@ -111,7 +111,6 @@ func Test_instanceFeaturesToCommand(t *testing.T) {
|
|||||||
UserSchema: gu.Ptr(true),
|
UserSchema: gu.Ptr(true),
|
||||||
OidcTokenExchange: gu.Ptr(true),
|
OidcTokenExchange: gu.Ptr(true),
|
||||||
ImprovedPerformance: nil,
|
ImprovedPerformance: nil,
|
||||||
WebKey: gu.Ptr(true),
|
|
||||||
OidcSingleV1SessionTermination: gu.Ptr(true),
|
OidcSingleV1SessionTermination: gu.Ptr(true),
|
||||||
}
|
}
|
||||||
want := &command.InstanceFeatures{
|
want := &command.InstanceFeatures{
|
||||||
@@ -120,7 +119,6 @@ func Test_instanceFeaturesToCommand(t *testing.T) {
|
|||||||
UserSchema: gu.Ptr(true),
|
UserSchema: gu.Ptr(true),
|
||||||
TokenExchange: gu.Ptr(true),
|
TokenExchange: gu.Ptr(true),
|
||||||
ImprovedPerformance: nil,
|
ImprovedPerformance: nil,
|
||||||
WebKey: gu.Ptr(true),
|
|
||||||
OIDCSingleV1SessionTermination: gu.Ptr(true),
|
OIDCSingleV1SessionTermination: gu.Ptr(true),
|
||||||
}
|
}
|
||||||
got := instanceFeaturesToCommand(arg)
|
got := instanceFeaturesToCommand(arg)
|
||||||
@@ -154,10 +152,6 @@ func Test_instanceFeaturesToPb(t *testing.T) {
|
|||||||
Level: feature.LevelSystem,
|
Level: feature.LevelSystem,
|
||||||
Value: []feature.ImprovedPerformanceType{feature.ImprovedPerformanceTypeOrgByID},
|
Value: []feature.ImprovedPerformanceType{feature.ImprovedPerformanceTypeOrgByID},
|
||||||
},
|
},
|
||||||
WebKey: query.FeatureSource[bool]{
|
|
||||||
Level: feature.LevelInstance,
|
|
||||||
Value: true,
|
|
||||||
},
|
|
||||||
OIDCSingleV1SessionTermination: query.FeatureSource[bool]{
|
OIDCSingleV1SessionTermination: query.FeatureSource[bool]{
|
||||||
Level: feature.LevelInstance,
|
Level: feature.LevelInstance,
|
||||||
Value: true,
|
Value: true,
|
||||||
@@ -189,10 +183,6 @@ func Test_instanceFeaturesToPb(t *testing.T) {
|
|||||||
ExecutionPaths: []feature_pb.ImprovedPerformance{feature_pb.ImprovedPerformance_IMPROVED_PERFORMANCE_ORG_BY_ID},
|
ExecutionPaths: []feature_pb.ImprovedPerformance{feature_pb.ImprovedPerformance_IMPROVED_PERFORMANCE_ORG_BY_ID},
|
||||||
Source: feature_pb.Source_SOURCE_SYSTEM,
|
Source: feature_pb.Source_SOURCE_SYSTEM,
|
||||||
},
|
},
|
||||||
WebKey: &feature_pb.FeatureFlag{
|
|
||||||
Enabled: true,
|
|
||||||
Source: feature_pb.Source_SOURCE_INSTANCE,
|
|
||||||
},
|
|
||||||
DebugOidcParentError: &feature_pb.FeatureFlag{
|
DebugOidcParentError: &feature_pb.FeatureFlag{
|
||||||
Enabled: false,
|
Enabled: false,
|
||||||
Source: feature_pb.Source_SOURCE_UNSPECIFIED,
|
Source: feature_pb.Source_SOURCE_UNSPECIFIED,
|
||||||
|
@@ -12,11 +12,9 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
"google.golang.org/protobuf/proto"
|
|
||||||
"google.golang.org/protobuf/types/known/timestamppb"
|
"google.golang.org/protobuf/types/known/timestamppb"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/integration"
|
"github.com/zitadel/zitadel/internal/integration"
|
||||||
"github.com/zitadel/zitadel/pkg/grpc/feature/v2"
|
|
||||||
webkey "github.com/zitadel/zitadel/pkg/grpc/webkey/v2beta"
|
webkey "github.com/zitadel/zitadel/pkg/grpc/webkey/v2beta"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -33,34 +31,8 @@ func TestMain(m *testing.M) {
|
|||||||
}())
|
}())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestServer_Feature_Disabled(t *testing.T) {
|
|
||||||
instance, iamCtx, _ := createInstance(t, false)
|
|
||||||
client := instance.Client.WebKeyV2Beta
|
|
||||||
|
|
||||||
t.Run("CreateWebKey", func(t *testing.T) {
|
|
||||||
_, err := client.CreateWebKey(iamCtx, &webkey.CreateWebKeyRequest{})
|
|
||||||
assertFeatureDisabledError(t, err)
|
|
||||||
})
|
|
||||||
t.Run("ActivateWebKey", func(t *testing.T) {
|
|
||||||
_, err := client.ActivateWebKey(iamCtx, &webkey.ActivateWebKeyRequest{
|
|
||||||
Id: "1",
|
|
||||||
})
|
|
||||||
assertFeatureDisabledError(t, err)
|
|
||||||
})
|
|
||||||
t.Run("DeleteWebKey", func(t *testing.T) {
|
|
||||||
_, err := client.DeleteWebKey(iamCtx, &webkey.DeleteWebKeyRequest{
|
|
||||||
Id: "1",
|
|
||||||
})
|
|
||||||
assertFeatureDisabledError(t, err)
|
|
||||||
})
|
|
||||||
t.Run("ListWebKeys", func(t *testing.T) {
|
|
||||||
_, err := client.ListWebKeys(iamCtx, &webkey.ListWebKeysRequest{})
|
|
||||||
assertFeatureDisabledError(t, err)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestServer_ListWebKeys(t *testing.T) {
|
func TestServer_ListWebKeys(t *testing.T) {
|
||||||
instance, iamCtx, creationDate := createInstance(t, true)
|
instance, iamCtx, creationDate := createInstance(t)
|
||||||
// After the feature is first enabled, we can expect 2 generated keys with the default config.
|
// After the feature is first enabled, we can expect 2 generated keys with the default config.
|
||||||
checkWebKeyListState(iamCtx, t, instance, 2, "", &webkey.WebKey_Rsa{
|
checkWebKeyListState(iamCtx, t, instance, 2, "", &webkey.WebKey_Rsa{
|
||||||
Rsa: &webkey.RSA{
|
Rsa: &webkey.RSA{
|
||||||
@@ -71,7 +43,7 @@ func TestServer_ListWebKeys(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestServer_CreateWebKey(t *testing.T) {
|
func TestServer_CreateWebKey(t *testing.T) {
|
||||||
instance, iamCtx, creationDate := createInstance(t, true)
|
instance, iamCtx, creationDate := createInstance(t)
|
||||||
client := instance.Client.WebKeyV2Beta
|
client := instance.Client.WebKeyV2Beta
|
||||||
|
|
||||||
_, err := client.CreateWebKey(iamCtx, &webkey.CreateWebKeyRequest{
|
_, err := client.CreateWebKey(iamCtx, &webkey.CreateWebKeyRequest{
|
||||||
@@ -93,7 +65,7 @@ func TestServer_CreateWebKey(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestServer_ActivateWebKey(t *testing.T) {
|
func TestServer_ActivateWebKey(t *testing.T) {
|
||||||
instance, iamCtx, creationDate := createInstance(t, true)
|
instance, iamCtx, creationDate := createInstance(t)
|
||||||
client := instance.Client.WebKeyV2Beta
|
client := instance.Client.WebKeyV2Beta
|
||||||
|
|
||||||
resp, err := client.CreateWebKey(iamCtx, &webkey.CreateWebKeyRequest{
|
resp, err := client.CreateWebKey(iamCtx, &webkey.CreateWebKeyRequest{
|
||||||
@@ -120,7 +92,7 @@ func TestServer_ActivateWebKey(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestServer_DeleteWebKey(t *testing.T) {
|
func TestServer_DeleteWebKey(t *testing.T) {
|
||||||
instance, iamCtx, creationDate := createInstance(t, true)
|
instance, iamCtx, creationDate := createInstance(t)
|
||||||
client := instance.Client.WebKeyV2Beta
|
client := instance.Client.WebKeyV2Beta
|
||||||
|
|
||||||
keyIDs := make([]string, 2)
|
keyIDs := make([]string, 2)
|
||||||
@@ -197,40 +169,22 @@ func TestServer_DeleteWebKey(t *testing.T) {
|
|||||||
}, creationDate)
|
}, creationDate)
|
||||||
}
|
}
|
||||||
|
|
||||||
func createInstance(t *testing.T, enableFeature bool) (*integration.Instance, context.Context, *timestamppb.Timestamp) {
|
func createInstance(t *testing.T) (*integration.Instance, context.Context, *timestamppb.Timestamp) {
|
||||||
instance := integration.NewInstance(CTX)
|
instance := integration.NewInstance(CTX)
|
||||||
creationDate := timestamppb.Now()
|
creationDate := timestamppb.Now()
|
||||||
iamCTX := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner)
|
iamCTX := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner)
|
||||||
|
|
||||||
if enableFeature {
|
|
||||||
_, err := instance.Client.FeatureV2.SetInstanceFeatures(iamCTX, &feature.SetInstanceFeaturesRequest{
|
|
||||||
WebKey: proto.Bool(true),
|
|
||||||
})
|
|
||||||
require.NoError(t, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
retryDuration, tick := integration.WaitForAndTickWithMaxDuration(iamCTX, time.Minute)
|
retryDuration, tick := integration.WaitForAndTickWithMaxDuration(iamCTX, time.Minute)
|
||||||
assert.EventuallyWithT(t, func(collect *assert.CollectT) {
|
assert.EventuallyWithT(t, func(collect *assert.CollectT) {
|
||||||
resp, err := instance.Client.WebKeyV2Beta.ListWebKeys(iamCTX, &webkey.ListWebKeysRequest{})
|
resp, err := instance.Client.WebKeyV2Beta.ListWebKeys(iamCTX, &webkey.ListWebKeysRequest{})
|
||||||
if enableFeature {
|
assert.NoError(collect, err)
|
||||||
assert.NoError(collect, err)
|
assert.Len(collect, resp.GetWebKeys(), 2)
|
||||||
assert.Len(collect, resp.GetWebKeys(), 2)
|
|
||||||
} else {
|
|
||||||
assert.Error(collect, err)
|
|
||||||
}
|
|
||||||
}, retryDuration, tick)
|
}, retryDuration, tick)
|
||||||
|
|
||||||
return instance, iamCTX, creationDate
|
return instance, iamCTX, creationDate
|
||||||
}
|
}
|
||||||
|
|
||||||
func assertFeatureDisabledError(t *testing.T, err error) {
|
|
||||||
t.Helper()
|
|
||||||
require.Error(t, err)
|
|
||||||
s := status.Convert(err)
|
|
||||||
assert.Equal(t, codes.FailedPrecondition, s.Code())
|
|
||||||
assert.Contains(t, s.Message(), "WEBKEY-Ohx6E")
|
|
||||||
}
|
|
||||||
|
|
||||||
func checkWebKeyListState(ctx context.Context, t *testing.T, instance *integration.Instance, nKeys int, expectActiveKeyID string, config any, creationDate *timestamppb.Timestamp) {
|
func checkWebKeyListState(ctx context.Context, t *testing.T, instance *integration.Instance, nKeys int, expectActiveKeyID string, config any, creationDate *timestamppb.Timestamp) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
|
@@ -5,9 +5,7 @@ import (
|
|||||||
|
|
||||||
"google.golang.org/protobuf/types/known/timestamppb"
|
"google.golang.org/protobuf/types/known/timestamppb"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/api/authz"
|
|
||||||
"github.com/zitadel/zitadel/internal/telemetry/tracing"
|
"github.com/zitadel/zitadel/internal/telemetry/tracing"
|
||||||
"github.com/zitadel/zitadel/internal/zerrors"
|
|
||||||
webkey "github.com/zitadel/zitadel/pkg/grpc/webkey/v2beta"
|
webkey "github.com/zitadel/zitadel/pkg/grpc/webkey/v2beta"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -15,9 +13,6 @@ func (s *Server) CreateWebKey(ctx context.Context, req *webkey.CreateWebKeyReque
|
|||||||
ctx, span := tracing.NewSpan(ctx)
|
ctx, span := tracing.NewSpan(ctx)
|
||||||
defer func() { span.EndWithError(err) }()
|
defer func() { span.EndWithError(err) }()
|
||||||
|
|
||||||
if err = checkWebKeyFeature(ctx); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
webKey, err := s.command.CreateWebKey(ctx, createWebKeyRequestToConfig(req))
|
webKey, err := s.command.CreateWebKey(ctx, createWebKeyRequestToConfig(req))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -33,9 +28,6 @@ func (s *Server) ActivateWebKey(ctx context.Context, req *webkey.ActivateWebKeyR
|
|||||||
ctx, span := tracing.NewSpan(ctx)
|
ctx, span := tracing.NewSpan(ctx)
|
||||||
defer func() { span.EndWithError(err) }()
|
defer func() { span.EndWithError(err) }()
|
||||||
|
|
||||||
if err = checkWebKeyFeature(ctx); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
details, err := s.command.ActivateWebKey(ctx, req.GetId())
|
details, err := s.command.ActivateWebKey(ctx, req.GetId())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -50,9 +42,6 @@ func (s *Server) DeleteWebKey(ctx context.Context, req *webkey.DeleteWebKeyReque
|
|||||||
ctx, span := tracing.NewSpan(ctx)
|
ctx, span := tracing.NewSpan(ctx)
|
||||||
defer func() { span.EndWithError(err) }()
|
defer func() { span.EndWithError(err) }()
|
||||||
|
|
||||||
if err = checkWebKeyFeature(ctx); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
deletedAt, err := s.command.DeleteWebKey(ctx, req.GetId())
|
deletedAt, err := s.command.DeleteWebKey(ctx, req.GetId())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -71,9 +60,6 @@ func (s *Server) ListWebKeys(ctx context.Context, _ *webkey.ListWebKeysRequest)
|
|||||||
ctx, span := tracing.NewSpan(ctx)
|
ctx, span := tracing.NewSpan(ctx)
|
||||||
defer func() { span.EndWithError(err) }()
|
defer func() { span.EndWithError(err) }()
|
||||||
|
|
||||||
if err = checkWebKeyFeature(ctx); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
list, err := s.query.ListWebKeys(ctx)
|
list, err := s.query.ListWebKeys(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -83,10 +69,3 @@ func (s *Server) ListWebKeys(ctx context.Context, _ *webkey.ListWebKeysRequest)
|
|||||||
WebKeys: webKeyDetailsListToPb(list),
|
WebKeys: webKeyDetailsListToPb(list),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkWebKeyFeature(ctx context.Context) error {
|
|
||||||
if !authz.GetFeatures(ctx).WebKey {
|
|
||||||
return zerrors.ThrowPreconditionFailed(nil, "WEBKEY-Ohx6E", "Errors.WebKey.FeatureDisabled")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
@@ -53,7 +53,7 @@ func (s *Server) verifyAccessToken(ctx context.Context, tkn string) (_ *accessTo
|
|||||||
tokenID, subject = split[0], split[1]
|
tokenID, subject = split[0], split[1]
|
||||||
} else {
|
} else {
|
||||||
verifier := op.NewAccessTokenVerifier(op.IssuerFromContext(ctx), s.accessTokenKeySet,
|
verifier := op.NewAccessTokenVerifier(op.IssuerFromContext(ctx), s.accessTokenKeySet,
|
||||||
op.WithSupportedAccessTokenSigningAlgorithms(supportedSigningAlgs(ctx)...),
|
op.WithSupportedAccessTokenSigningAlgorithms(supportedSigningAlgs()...),
|
||||||
)
|
)
|
||||||
claims, err := op.VerifyAccessToken[*oidc.AccessTokenClaims](ctx, tkn, verifier)
|
claims, err := op.VerifyAccessToken[*oidc.AccessTokenClaims](ctx, tkn, verifier)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@@ -140,13 +140,8 @@ func HttpHeadersFromContext(ctx context.Context) (userAgent, acceptLang string)
|
|||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if agents, ok := ctxHeaders[http_utils.UserAgentHeader]; ok {
|
return ctxHeaders.Get(http_utils.UserAgentHeader),
|
||||||
userAgent = agents[0]
|
ctxHeaders.Get(http_utils.AcceptLanguage)
|
||||||
}
|
|
||||||
if langs, ok := ctxHeaders[http_utils.AcceptLanguage]; ok {
|
|
||||||
acceptLang = langs[0]
|
|
||||||
}
|
|
||||||
return userAgent, acceptLang
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func IpFromContext(ctx context.Context) net.IP {
|
func IpFromContext(ctx context.Context) net.IP {
|
||||||
|
@@ -14,12 +14,10 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"github.com/zitadel/oidc/v3/pkg/client"
|
"github.com/zitadel/oidc/v3/pkg/client"
|
||||||
"github.com/zitadel/oidc/v3/pkg/oidc"
|
"github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
"google.golang.org/protobuf/proto"
|
|
||||||
|
|
||||||
http_util "github.com/zitadel/zitadel/internal/api/http"
|
http_util "github.com/zitadel/zitadel/internal/api/http"
|
||||||
"github.com/zitadel/zitadel/internal/crypto"
|
"github.com/zitadel/zitadel/internal/crypto"
|
||||||
"github.com/zitadel/zitadel/internal/integration"
|
"github.com/zitadel/zitadel/internal/integration"
|
||||||
"github.com/zitadel/zitadel/pkg/grpc/feature/v2"
|
|
||||||
oidc_pb "github.com/zitadel/zitadel/pkg/grpc/oidc/v2"
|
oidc_pb "github.com/zitadel/zitadel/pkg/grpc/oidc/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -53,25 +51,16 @@ func TestServer_Keys(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
webKeyFeature bool
|
wantLen int
|
||||||
wantLen int
|
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "legacy only",
|
name: "webkeys",
|
||||||
webKeyFeature: false,
|
wantLen: 2, // 2 from instance creation.
|
||||||
wantLen: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "webkeys with legacy",
|
|
||||||
webKeyFeature: true,
|
|
||||||
wantLen: 3, // 1 legacy + 2 created by enabling feature flag
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
ensureWebKeyFeature(t, instance, tt.webKeyFeature)
|
|
||||||
|
|
||||||
assert.EventuallyWithT(t, func(ttt *assert.CollectT) {
|
assert.EventuallyWithT(t, func(ttt *assert.CollectT) {
|
||||||
resp, err := http.Get(discovery.JwksURI)
|
resp, err := http.Get(discovery.JwksURI)
|
||||||
require.NoError(ttt, err)
|
require.NoError(ttt, err)
|
||||||
@@ -92,30 +81,10 @@ func TestServer_Keys(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cacheControl := resp.Header.Get("cache-control")
|
cacheControl := resp.Header.Get("cache-control")
|
||||||
if tt.webKeyFeature {
|
require.Equal(ttt, "max-age=300, must-revalidate", cacheControl)
|
||||||
require.Equal(ttt, "max-age=300, must-revalidate", cacheControl)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
require.Equal(ttt, "no-store", cacheControl)
|
|
||||||
|
|
||||||
}, time.Minute, time.Second/10)
|
}, time.Minute, time.Second/10)
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ensureWebKeyFeature(t *testing.T, instance *integration.Instance, set bool) {
|
|
||||||
ctxIam := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner)
|
|
||||||
|
|
||||||
_, err := instance.Client.FeatureV2.SetInstanceFeatures(ctxIam, &feature.SetInstanceFeaturesRequest{
|
|
||||||
WebKey: proto.Bool(set),
|
|
||||||
})
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
t.Cleanup(func() {
|
|
||||||
_, err := instance.Client.FeatureV2.SetInstanceFeatures(ctxIam, &feature.SetInstanceFeaturesRequest{
|
|
||||||
WebKey: proto.Bool(false),
|
|
||||||
})
|
|
||||||
require.NoError(t, err)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
@@ -35,21 +35,14 @@ func TestServer_UserInfo(t *testing.T) {
|
|||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
trigger bool
|
trigger bool
|
||||||
webKey bool
|
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "trigger enabled",
|
name: "trigger enabled",
|
||||||
trigger: true,
|
trigger: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
// This is the only functional test we need to cover web keys.
|
|
||||||
// - By creating tokens the signer is tested
|
|
||||||
// - When obtaining the tokens, the RP verifies the ID Token using the key set from the jwks endpoint.
|
|
||||||
// - By calling userinfo with the access token as JWT, the Token Verifier with the public key cache is tested.
|
|
||||||
{
|
{
|
||||||
name: "web keys",
|
name: "trigger disabled",
|
||||||
trigger: false,
|
trigger: false,
|
||||||
webKey: true,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,7 +50,6 @@ func TestServer_UserInfo(t *testing.T) {
|
|||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
_, err := Instance.Client.FeatureV2.SetInstanceFeatures(iamOwnerCTX, &feature.SetInstanceFeaturesRequest{
|
_, err := Instance.Client.FeatureV2.SetInstanceFeatures(iamOwnerCTX, &feature.SetInstanceFeaturesRequest{
|
||||||
OidcTriggerIntrospectionProjections: &tt.trigger,
|
OidcTriggerIntrospectionProjections: &tt.trigger,
|
||||||
WebKey: &tt.webKey,
|
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
testServer_UserInfo(t)
|
testServer_UserInfo(t)
|
||||||
|
@@ -10,18 +10,12 @@ import (
|
|||||||
|
|
||||||
"github.com/go-jose/go-jose/v4"
|
"github.com/go-jose/go-jose/v4"
|
||||||
"github.com/jonboulle/clockwork"
|
"github.com/jonboulle/clockwork"
|
||||||
"github.com/muhlemmer/gu"
|
|
||||||
"github.com/shopspring/decimal"
|
|
||||||
"github.com/zitadel/logging"
|
|
||||||
"github.com/zitadel/oidc/v3/pkg/op"
|
"github.com/zitadel/oidc/v3/pkg/op"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/api/authz"
|
"github.com/zitadel/zitadel/internal/api/authz"
|
||||||
http_util "github.com/zitadel/zitadel/internal/api/http"
|
http_util "github.com/zitadel/zitadel/internal/api/http"
|
||||||
"github.com/zitadel/zitadel/internal/crypto"
|
"github.com/zitadel/zitadel/internal/crypto"
|
||||||
"github.com/zitadel/zitadel/internal/eventstore"
|
|
||||||
"github.com/zitadel/zitadel/internal/query"
|
"github.com/zitadel/zitadel/internal/query"
|
||||||
"github.com/zitadel/zitadel/internal/repository/instance"
|
|
||||||
"github.com/zitadel/zitadel/internal/repository/keypair"
|
|
||||||
"github.com/zitadel/zitadel/internal/telemetry/tracing"
|
"github.com/zitadel/zitadel/internal/telemetry/tracing"
|
||||||
"github.com/zitadel/zitadel/internal/zerrors"
|
"github.com/zitadel/zitadel/internal/zerrors"
|
||||||
)
|
)
|
||||||
@@ -36,11 +30,8 @@ var supportedWebKeyAlgs = []string{
|
|||||||
string(jose.ES512),
|
string(jose.ES512),
|
||||||
}
|
}
|
||||||
|
|
||||||
func supportedSigningAlgs(ctx context.Context) []string {
|
func supportedSigningAlgs() []string {
|
||||||
if authz.GetFeatures(ctx).WebKey {
|
return supportedWebKeyAlgs
|
||||||
return supportedWebKeyAlgs
|
|
||||||
}
|
|
||||||
return []string{string(jose.RS256)}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type cachedPublicKey struct {
|
type cachedPublicKey struct {
|
||||||
@@ -211,15 +202,6 @@ func withKeyExpiryCheck(check bool) keySetOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func jsonWebkey(key query.PublicKey) *jose.JSONWebKey {
|
|
||||||
return &jose.JSONWebKey{
|
|
||||||
KeyID: key.ID(),
|
|
||||||
Algorithm: key.Algorithm(),
|
|
||||||
Use: key.Use().String(),
|
|
||||||
Key: key.Key(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// keySetMap is a mapping of key IDs to public key data.
|
// keySetMap is a mapping of key IDs to public key data.
|
||||||
type keySetMap map[string][]byte
|
type keySetMap map[string][]byte
|
||||||
|
|
||||||
@@ -250,7 +232,6 @@ func (k keySetMap) VerifySignature(ctx context.Context, jws *jose.JSONWebSignatu
|
|||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
locksTable = "projections.locks"
|
|
||||||
signingKey = "signing_key"
|
signingKey = "signing_key"
|
||||||
oidcUser = "OIDC"
|
oidcUser = "OIDC"
|
||||||
|
|
||||||
@@ -279,203 +260,36 @@ func (s *SigningKey) ID() string {
|
|||||||
return s.id
|
return s.id
|
||||||
}
|
}
|
||||||
|
|
||||||
// PublicKey wraps the query.PublicKey to implement the op.Key interface
|
|
||||||
type PublicKey struct {
|
|
||||||
key query.PublicKey
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *PublicKey) Algorithm() jose.SignatureAlgorithm {
|
|
||||||
return jose.SignatureAlgorithm(s.key.Algorithm())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *PublicKey) Use() string {
|
|
||||||
return s.key.Use().String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *PublicKey) Key() interface{} {
|
|
||||||
return s.key.Key()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *PublicKey) ID() string {
|
|
||||||
return s.key.ID()
|
|
||||||
}
|
|
||||||
|
|
||||||
// KeySet implements the op.Storage interface
|
// KeySet implements the op.Storage interface
|
||||||
func (o *OPStorage) KeySet(ctx context.Context) (keys []op.Key, err error) {
|
func (o *OPStorage) KeySet(ctx context.Context) (keys []op.Key, err error) {
|
||||||
ctx, span := tracing.NewSpan(ctx)
|
panic(o.panicErr("KeySet"))
|
||||||
defer func() { span.EndWithError(err) }()
|
|
||||||
err = retry(func() error {
|
|
||||||
publicKeys, err := o.query.ActivePublicKeys(ctx, time.Now())
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
keys = make([]op.Key, len(publicKeys.Keys))
|
|
||||||
for i, key := range publicKeys.Keys {
|
|
||||||
keys[i] = &PublicKey{key}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
return keys, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SignatureAlgorithms implements the op.Storage interface
|
// SignatureAlgorithms implements the op.Storage interface
|
||||||
func (o *OPStorage) SignatureAlgorithms(ctx context.Context) ([]jose.SignatureAlgorithm, error) {
|
func (o *OPStorage) SignatureAlgorithms(ctx context.Context) ([]jose.SignatureAlgorithm, error) {
|
||||||
key, err := o.SigningKey(ctx)
|
panic(o.panicErr("SignatureAlgorithms"))
|
||||||
if err != nil {
|
|
||||||
logging.WithError(err).Warn("unable to fetch signing key")
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return []jose.SignatureAlgorithm{key.SignatureAlgorithm()}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SigningKey implements the op.Storage interface
|
// SigningKey implements the op.Storage interface
|
||||||
func (o *OPStorage) SigningKey(ctx context.Context) (key op.SigningKey, err error) {
|
func (o *OPStorage) SigningKey(ctx context.Context) (key op.SigningKey, err error) {
|
||||||
err = retry(func() error {
|
panic(o.panicErr("SigningKey"))
|
||||||
key, err = o.getSigningKey(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if key == nil {
|
|
||||||
return zerrors.ThrowNotFound(nil, "OIDC-ve4Qu", "Errors.Internal")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
return key, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *OPStorage) getSigningKey(ctx context.Context) (op.SigningKey, error) {
|
|
||||||
keys, err := o.query.ActivePrivateSigningKey(ctx, time.Now().Add(gracefulPeriod))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if len(keys.Keys) > 0 {
|
|
||||||
return PrivateKeyToSigningKey(SelectSigningKey(keys.Keys), o.encAlg)
|
|
||||||
}
|
|
||||||
var position decimal.Decimal
|
|
||||||
if keys.State != nil {
|
|
||||||
position = keys.State.Position
|
|
||||||
}
|
|
||||||
return nil, o.refreshSigningKey(ctx, position)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *OPStorage) refreshSigningKey(ctx context.Context, position decimal.Decimal) error {
|
|
||||||
ok, err := o.ensureIsLatestKey(ctx, position)
|
|
||||||
if err != nil || !ok {
|
|
||||||
return zerrors.ThrowInternal(err, "OIDC-ASfh3", "cannot ensure that projection is up to date")
|
|
||||||
}
|
|
||||||
err = o.lockAndGenerateSigningKeyPair(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return zerrors.ThrowInternal(err, "OIDC-ADh31", "could not create signing key")
|
|
||||||
}
|
|
||||||
return zerrors.ThrowInternal(nil, "OIDC-Df1bh", "")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *OPStorage) ensureIsLatestKey(ctx context.Context, position decimal.Decimal) (bool, error) {
|
|
||||||
maxSequence, err := o.getMaxKeyPosition(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return false, fmt.Errorf("error retrieving new events: %w", err)
|
|
||||||
}
|
|
||||||
return position.GreaterThanOrEqual(maxSequence), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func PrivateKeyToSigningKey(key query.PrivateKey, algorithm crypto.EncryptionAlgorithm) (_ op.SigningKey, err error) {
|
|
||||||
keyData, err := crypto.Decrypt(key.Key(), algorithm)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
privateKey, err := crypto.BytesToPrivateKey(keyData)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &SigningKey{
|
|
||||||
algorithm: jose.SignatureAlgorithm(key.Algorithm()),
|
|
||||||
key: privateKey,
|
|
||||||
id: key.ID(),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *OPStorage) lockAndGenerateSigningKeyPair(ctx context.Context) error {
|
|
||||||
logging.Info("lock and generate signing key pair")
|
|
||||||
|
|
||||||
ctx, cancel := context.WithCancel(ctx)
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
errs := o.locker.Lock(ctx, lockDuration, authz.GetInstance(ctx).InstanceID())
|
|
||||||
err, ok := <-errs
|
|
||||||
if err != nil || !ok {
|
|
||||||
if zerrors.IsErrorAlreadyExists(err) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
logging.OnError(err).Debug("initial lock failed")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return o.command.GenerateSigningKeyPair(setOIDCCtx(ctx), "RS256")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *OPStorage) getMaxKeyPosition(ctx context.Context) (decimal.Decimal, error) {
|
|
||||||
return o.eventstore.LatestPosition(ctx,
|
|
||||||
eventstore.NewSearchQueryBuilder(eventstore.ColumnsMaxPosition).
|
|
||||||
ResourceOwner(authz.GetInstance(ctx).InstanceID()).
|
|
||||||
AwaitOpenTransactions().
|
|
||||||
AddQuery().
|
|
||||||
AggregateTypes(
|
|
||||||
keypair.AggregateType,
|
|
||||||
instance.AggregateType,
|
|
||||||
).
|
|
||||||
EventTypes(
|
|
||||||
keypair.AddedEventType,
|
|
||||||
instance.InstanceRemovedEventType,
|
|
||||||
).
|
|
||||||
Builder(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func SelectSigningKey(keys []query.PrivateKey) query.PrivateKey {
|
|
||||||
return keys[len(keys)-1]
|
|
||||||
}
|
|
||||||
|
|
||||||
func setOIDCCtx(ctx context.Context) context.Context {
|
|
||||||
return authz.SetCtxData(ctx, authz.CtxData{UserID: oidcUser, OrgID: authz.GetInstance(ctx).InstanceID()})
|
|
||||||
}
|
|
||||||
|
|
||||||
func retry(retryable func() error) (err error) {
|
|
||||||
for i := 0; i < retryCount; i++ {
|
|
||||||
err = retryable()
|
|
||||||
if err == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
time.Sleep(retryBackoff)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) Keys(ctx context.Context, r *op.Request[struct{}]) (_ *op.Response, err error) {
|
func (s *Server) Keys(ctx context.Context, r *op.Request[struct{}]) (_ *op.Response, err error) {
|
||||||
ctx, span := tracing.NewSpan(ctx)
|
ctx, span := tracing.NewSpan(ctx)
|
||||||
defer func() { span.EndWithError(err) }()
|
defer func() { span.EndWithError(err) }()
|
||||||
|
|
||||||
if !authz.GetFeatures(ctx).WebKey {
|
|
||||||
return s.LegacyServer.Keys(ctx, r)
|
|
||||||
}
|
|
||||||
|
|
||||||
keyset, err := s.query.GetWebKeySet(ctx)
|
keyset, err := s.query.GetWebKeySet(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return legacy keys, so we do not invalidate all tokens
|
|
||||||
// once the feature flag is enabled.
|
|
||||||
legacyKeys, err := s.query.ActivePublicKeys(ctx, time.Now())
|
|
||||||
logging.OnError(err).Error("oidc server: active public keys (legacy)")
|
|
||||||
appendPublicKeysToWebKeySet(keyset, legacyKeys)
|
|
||||||
|
|
||||||
resp := op.NewResponse(keyset)
|
resp := op.NewResponse(keyset)
|
||||||
if s.jwksCacheControlMaxAge != 0 {
|
if s.jwksCacheControlMaxAge != 0 {
|
||||||
resp.Header.Set(http_util.CacheControl,
|
resp.Header.Set(http_util.CacheControl,
|
||||||
fmt.Sprintf("max-age=%d, must-revalidate", int(s.jwksCacheControlMaxAge/time.Second)),
|
fmt.Sprintf("max-age=%d, must-revalidate", int(s.jwksCacheControlMaxAge/time.Second)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -497,20 +311,10 @@ func appendPublicKeysToWebKeySet(keyset *jose.JSONWebKeySet, pubkeys *query.Publ
|
|||||||
|
|
||||||
func queryKeyFunc(q *query.Queries) func(ctx context.Context, keyID string) (*jose.JSONWebKey, *time.Time, error) {
|
func queryKeyFunc(q *query.Queries) func(ctx context.Context, keyID string) (*jose.JSONWebKey, *time.Time, error) {
|
||||||
return func(ctx context.Context, keyID string) (*jose.JSONWebKey, *time.Time, error) {
|
return func(ctx context.Context, keyID string) (*jose.JSONWebKey, *time.Time, error) {
|
||||||
if authz.GetFeatures(ctx).WebKey {
|
webKey, err := q.GetPublicWebKeyByID(ctx, keyID)
|
||||||
webKey, err := q.GetPublicWebKeyByID(ctx, keyID)
|
|
||||||
if err == nil {
|
|
||||||
return webKey, nil, nil
|
|
||||||
}
|
|
||||||
if !zerrors.IsNotFound(err) {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pubKey, err := q.GetPublicKeyByID(ctx, keyID)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
return jsonWebkey(pubKey), gu.Ptr(pubKey.Expiry()), nil
|
return webKey, nil, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -18,10 +18,8 @@ import (
|
|||||||
"github.com/zitadel/zitadel/internal/cache"
|
"github.com/zitadel/zitadel/internal/cache"
|
||||||
"github.com/zitadel/zitadel/internal/command"
|
"github.com/zitadel/zitadel/internal/command"
|
||||||
"github.com/zitadel/zitadel/internal/crypto"
|
"github.com/zitadel/zitadel/internal/crypto"
|
||||||
"github.com/zitadel/zitadel/internal/database"
|
|
||||||
"github.com/zitadel/zitadel/internal/domain/federatedlogout"
|
"github.com/zitadel/zitadel/internal/domain/federatedlogout"
|
||||||
"github.com/zitadel/zitadel/internal/eventstore"
|
"github.com/zitadel/zitadel/internal/eventstore"
|
||||||
"github.com/zitadel/zitadel/internal/eventstore/handler/crdb"
|
|
||||||
"github.com/zitadel/zitadel/internal/query"
|
"github.com/zitadel/zitadel/internal/query"
|
||||||
"github.com/zitadel/zitadel/internal/telemetry/metrics"
|
"github.com/zitadel/zitadel/internal/telemetry/metrics"
|
||||||
"github.com/zitadel/zitadel/internal/zerrors"
|
"github.com/zitadel/zitadel/internal/zerrors"
|
||||||
@@ -75,7 +73,6 @@ type OPStorage struct {
|
|||||||
defaultRefreshTokenIdleExpiration time.Duration
|
defaultRefreshTokenIdleExpiration time.Duration
|
||||||
defaultRefreshTokenExpiration time.Duration
|
defaultRefreshTokenExpiration time.Duration
|
||||||
encAlg crypto.EncryptionAlgorithm
|
encAlg crypto.EncryptionAlgorithm
|
||||||
locker crdb.Locker
|
|
||||||
assetAPIPrefix func(ctx context.Context) string
|
assetAPIPrefix func(ctx context.Context) string
|
||||||
contextToIssuer func(context.Context) string
|
contextToIssuer func(context.Context) string
|
||||||
federateLogoutCache cache.Cache[federatedlogout.Index, string, *federatedlogout.FederatedLogout]
|
federateLogoutCache cache.Cache[federatedlogout.Index, string, *federatedlogout.FederatedLogout]
|
||||||
@@ -91,14 +88,14 @@ type Provider struct {
|
|||||||
// IDTokenHintVerifier configures a Verifier and supported signing algorithms based on the Web Key feature in the context.
|
// IDTokenHintVerifier configures a Verifier and supported signing algorithms based on the Web Key feature in the context.
|
||||||
func (o *Provider) IDTokenHintVerifier(ctx context.Context) *op.IDTokenHintVerifier {
|
func (o *Provider) IDTokenHintVerifier(ctx context.Context) *op.IDTokenHintVerifier {
|
||||||
return op.NewIDTokenHintVerifier(op.IssuerFromContext(ctx), o.idTokenHintKeySet, op.WithSupportedIDTokenHintSigningAlgorithms(
|
return op.NewIDTokenHintVerifier(op.IssuerFromContext(ctx), o.idTokenHintKeySet, op.WithSupportedIDTokenHintSigningAlgorithms(
|
||||||
supportedSigningAlgs(ctx)...,
|
supportedSigningAlgs()...,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
// AccessTokenVerifier configures a Verifier and supported signing algorithms based on the Web Key feature in the context.
|
// AccessTokenVerifier configures a Verifier and supported signing algorithms based on the Web Key feature in the context.
|
||||||
func (o *Provider) AccessTokenVerifier(ctx context.Context) *op.AccessTokenVerifier {
|
func (o *Provider) AccessTokenVerifier(ctx context.Context) *op.AccessTokenVerifier {
|
||||||
return op.NewAccessTokenVerifier(op.IssuerFromContext(ctx), o.accessTokenKeySet, op.WithSupportedAccessTokenSigningAlgorithms(
|
return op.NewAccessTokenVerifier(op.IssuerFromContext(ctx), o.accessTokenKeySet, op.WithSupportedAccessTokenSigningAlgorithms(
|
||||||
supportedSigningAlgs(ctx)...,
|
supportedSigningAlgs()...,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,7 +110,6 @@ func NewServer(
|
|||||||
encryptionAlg crypto.EncryptionAlgorithm,
|
encryptionAlg crypto.EncryptionAlgorithm,
|
||||||
cryptoKey []byte,
|
cryptoKey []byte,
|
||||||
es *eventstore.Eventstore,
|
es *eventstore.Eventstore,
|
||||||
projections *database.DB,
|
|
||||||
userAgentCookie, instanceHandler func(http.Handler) http.Handler,
|
userAgentCookie, instanceHandler func(http.Handler) http.Handler,
|
||||||
accessHandler *middleware.AccessInterceptor,
|
accessHandler *middleware.AccessInterceptor,
|
||||||
fallbackLogger *slog.Logger,
|
fallbackLogger *slog.Logger,
|
||||||
@@ -124,7 +120,7 @@ func NewServer(
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, zerrors.ThrowInternal(err, "OIDC-EGrqd", "cannot create op config: %w")
|
return nil, zerrors.ThrowInternal(err, "OIDC-EGrqd", "cannot create op config: %w")
|
||||||
}
|
}
|
||||||
storage := newStorage(config, command, query, repo, encryptionAlg, es, projections, ContextToIssuer, federatedLogoutCache)
|
storage := newStorage(config, command, query, repo, encryptionAlg, es, ContextToIssuer, federatedLogoutCache)
|
||||||
keyCache := newPublicKeyCache(ctx, config.PublicKeyCacheMaxAge, queryKeyFunc(query))
|
keyCache := newPublicKeyCache(ctx, config.PublicKeyCacheMaxAge, queryKeyFunc(query))
|
||||||
accessTokenKeySet := newOidcKeySet(keyCache, withKeyExpiryCheck(true))
|
accessTokenKeySet := newOidcKeySet(keyCache, withKeyExpiryCheck(true))
|
||||||
idTokenHintKeySet := newOidcKeySet(keyCache)
|
idTokenHintKeySet := newOidcKeySet(keyCache)
|
||||||
@@ -236,7 +232,6 @@ func newStorage(
|
|||||||
repo repository.Repository,
|
repo repository.Repository,
|
||||||
encAlg crypto.EncryptionAlgorithm,
|
encAlg crypto.EncryptionAlgorithm,
|
||||||
es *eventstore.Eventstore,
|
es *eventstore.Eventstore,
|
||||||
db *database.DB,
|
|
||||||
contextToIssuer func(context.Context) string,
|
contextToIssuer func(context.Context) string,
|
||||||
federateLogoutCache cache.Cache[federatedlogout.Index, string, *federatedlogout.FederatedLogout],
|
federateLogoutCache cache.Cache[federatedlogout.Index, string, *federatedlogout.FederatedLogout],
|
||||||
) *OPStorage {
|
) *OPStorage {
|
||||||
@@ -253,7 +248,6 @@ func newStorage(
|
|||||||
defaultRefreshTokenIdleExpiration: config.DefaultRefreshTokenIdleExpiration,
|
defaultRefreshTokenIdleExpiration: config.DefaultRefreshTokenIdleExpiration,
|
||||||
defaultRefreshTokenExpiration: config.DefaultRefreshTokenExpiration,
|
defaultRefreshTokenExpiration: config.DefaultRefreshTokenExpiration,
|
||||||
encAlg: encAlg,
|
encAlg: encAlg,
|
||||||
locker: crdb.NewLocker(db.DB, locksTable, signingKey),
|
|
||||||
assetAPIPrefix: assets.AssetAPI(),
|
assetAPIPrefix: assets.AssetAPI(),
|
||||||
contextToIssuer: contextToIssuer,
|
contextToIssuer: contextToIssuer,
|
||||||
federateLogoutCache: federateLogoutCache,
|
federateLogoutCache: federateLogoutCache,
|
||||||
|
@@ -188,7 +188,7 @@ func (s *Server) createDiscoveryConfig(ctx context.Context, supportedUILocales o
|
|||||||
},
|
},
|
||||||
GrantTypesSupported: op.GrantTypes(s.Provider()),
|
GrantTypesSupported: op.GrantTypes(s.Provider()),
|
||||||
SubjectTypesSupported: op.SubjectTypes(s.Provider()),
|
SubjectTypesSupported: op.SubjectTypes(s.Provider()),
|
||||||
IDTokenSigningAlgValuesSupported: supportedSigningAlgs(ctx),
|
IDTokenSigningAlgValuesSupported: supportedSigningAlgs(),
|
||||||
RequestObjectSigningAlgValuesSupported: op.RequestObjectSigAlgorithms(s.Provider()),
|
RequestObjectSigningAlgValuesSupported: op.RequestObjectSigAlgorithms(s.Provider()),
|
||||||
TokenEndpointAuthMethodsSupported: op.AuthMethodsTokenEndpoint(s.Provider()),
|
TokenEndpointAuthMethodsSupported: op.AuthMethodsTokenEndpoint(s.Provider()),
|
||||||
TokenEndpointAuthSigningAlgValuesSupported: op.TokenSigAlgorithms(s.Provider()),
|
TokenEndpointAuthSigningAlgValuesSupported: op.TokenSigAlgorithms(s.Provider()),
|
||||||
|
@@ -8,9 +8,6 @@ import (
|
|||||||
"github.com/zitadel/oidc/v3/pkg/oidc"
|
"github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
"github.com/zitadel/oidc/v3/pkg/op"
|
"github.com/zitadel/oidc/v3/pkg/op"
|
||||||
"golang.org/x/text/language"
|
"golang.org/x/text/language"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/api/authz"
|
|
||||||
"github.com/zitadel/zitadel/internal/feature"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestServer_createDiscoveryConfig(t *testing.T) {
|
func TestServer_createDiscoveryConfig(t *testing.T) {
|
||||||
@@ -63,92 +60,6 @@ func TestServer_createDiscoveryConfig(t *testing.T) {
|
|||||||
ctx: op.ContextWithIssuer(context.Background(), "https://issuer.com"),
|
ctx: op.ContextWithIssuer(context.Background(), "https://issuer.com"),
|
||||||
supportedUILocales: []language.Tag{language.English, language.German},
|
supportedUILocales: []language.Tag{language.English, language.German},
|
||||||
},
|
},
|
||||||
&oidc.DiscoveryConfiguration{
|
|
||||||
Issuer: "https://issuer.com",
|
|
||||||
AuthorizationEndpoint: "https://issuer.com/auth",
|
|
||||||
TokenEndpoint: "https://issuer.com/token",
|
|
||||||
IntrospectionEndpoint: "https://issuer.com/introspect",
|
|
||||||
UserinfoEndpoint: "https://issuer.com/userinfo",
|
|
||||||
RevocationEndpoint: "https://issuer.com/revoke",
|
|
||||||
EndSessionEndpoint: "https://issuer.com/logout",
|
|
||||||
DeviceAuthorizationEndpoint: "https://issuer.com/device",
|
|
||||||
CheckSessionIframe: "",
|
|
||||||
JwksURI: "https://issuer.com/keys",
|
|
||||||
RegistrationEndpoint: "",
|
|
||||||
ScopesSupported: []string{oidc.ScopeOpenID, oidc.ScopeProfile, oidc.ScopeEmail, oidc.ScopePhone, oidc.ScopeAddress, oidc.ScopeOfflineAccess},
|
|
||||||
ResponseTypesSupported: []string{string(oidc.ResponseTypeCode), string(oidc.ResponseTypeIDTokenOnly), string(oidc.ResponseTypeIDToken)},
|
|
||||||
ResponseModesSupported: []string{string(oidc.ResponseModeQuery), string(oidc.ResponseModeFragment), string(oidc.ResponseModeFormPost)},
|
|
||||||
GrantTypesSupported: []oidc.GrantType{oidc.GrantTypeCode, oidc.GrantTypeImplicit, oidc.GrantTypeRefreshToken, oidc.GrantTypeBearer},
|
|
||||||
ACRValuesSupported: nil,
|
|
||||||
SubjectTypesSupported: []string{"public"},
|
|
||||||
IDTokenSigningAlgValuesSupported: []string{"RS256"},
|
|
||||||
IDTokenEncryptionAlgValuesSupported: nil,
|
|
||||||
IDTokenEncryptionEncValuesSupported: nil,
|
|
||||||
UserinfoSigningAlgValuesSupported: nil,
|
|
||||||
UserinfoEncryptionAlgValuesSupported: nil,
|
|
||||||
UserinfoEncryptionEncValuesSupported: nil,
|
|
||||||
RequestObjectSigningAlgValuesSupported: []string{"RS256"},
|
|
||||||
RequestObjectEncryptionAlgValuesSupported: nil,
|
|
||||||
RequestObjectEncryptionEncValuesSupported: nil,
|
|
||||||
TokenEndpointAuthMethodsSupported: []oidc.AuthMethod{oidc.AuthMethodNone, oidc.AuthMethodBasic, oidc.AuthMethodPost, oidc.AuthMethodPrivateKeyJWT},
|
|
||||||
TokenEndpointAuthSigningAlgValuesSupported: []string{"RS256"},
|
|
||||||
RevocationEndpointAuthMethodsSupported: []oidc.AuthMethod{oidc.AuthMethodNone, oidc.AuthMethodBasic, oidc.AuthMethodPost, oidc.AuthMethodPrivateKeyJWT},
|
|
||||||
RevocationEndpointAuthSigningAlgValuesSupported: []string{"RS256"},
|
|
||||||
IntrospectionEndpointAuthMethodsSupported: []oidc.AuthMethod{oidc.AuthMethodBasic, oidc.AuthMethodPrivateKeyJWT},
|
|
||||||
IntrospectionEndpointAuthSigningAlgValuesSupported: []string{"RS256"},
|
|
||||||
DisplayValuesSupported: nil,
|
|
||||||
ClaimTypesSupported: nil,
|
|
||||||
ClaimsSupported: []string{"sub", "aud", "exp", "iat", "iss", "auth_time", "nonce", "acr", "amr", "c_hash", "at_hash", "act", "scopes", "client_id", "azp", "preferred_username", "name", "family_name", "given_name", "locale", "email", "email_verified", "phone_number", "phone_number_verified"},
|
|
||||||
ClaimsParameterSupported: false,
|
|
||||||
CodeChallengeMethodsSupported: []oidc.CodeChallengeMethod{"S256"},
|
|
||||||
ServiceDocumentation: "",
|
|
||||||
ClaimsLocalesSupported: nil,
|
|
||||||
UILocalesSupported: []language.Tag{language.English, language.German},
|
|
||||||
RequestParameterSupported: true,
|
|
||||||
RequestURIParameterSupported: false,
|
|
||||||
RequireRequestURIRegistration: false,
|
|
||||||
OPPolicyURI: "",
|
|
||||||
OPTermsOfServiceURI: "",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"web keys feature enabled",
|
|
||||||
fields{
|
|
||||||
LegacyServer: op.NewLegacyServer(
|
|
||||||
func() *op.Provider {
|
|
||||||
//nolint:staticcheck
|
|
||||||
provider, _ := op.NewForwardedOpenIDProvider("path",
|
|
||||||
&op.Config{
|
|
||||||
CodeMethodS256: true,
|
|
||||||
AuthMethodPost: true,
|
|
||||||
AuthMethodPrivateKeyJWT: true,
|
|
||||||
GrantTypeRefreshToken: true,
|
|
||||||
RequestObjectSupported: true,
|
|
||||||
},
|
|
||||||
nil,
|
|
||||||
)
|
|
||||||
return provider
|
|
||||||
}(),
|
|
||||||
op.Endpoints{
|
|
||||||
Authorization: op.NewEndpoint("auth"),
|
|
||||||
Token: op.NewEndpoint("token"),
|
|
||||||
Introspection: op.NewEndpoint("introspect"),
|
|
||||||
Userinfo: op.NewEndpoint("userinfo"),
|
|
||||||
Revocation: op.NewEndpoint("revoke"),
|
|
||||||
EndSession: op.NewEndpoint("logout"),
|
|
||||||
JwksURI: op.NewEndpoint("keys"),
|
|
||||||
DeviceAuthorization: op.NewEndpoint("device"),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
signingKeyAlgorithm: "RS256",
|
|
||||||
},
|
|
||||||
args{
|
|
||||||
ctx: authz.WithFeatures(
|
|
||||||
op.ContextWithIssuer(context.Background(), "https://issuer.com"),
|
|
||||||
feature.Features{WebKey: true},
|
|
||||||
),
|
|
||||||
supportedUILocales: []language.Tag{language.English, language.German},
|
|
||||||
},
|
|
||||||
&oidc.DiscoveryConfiguration{
|
&oidc.DiscoveryConfiguration{
|
||||||
Issuer: "https://issuer.com",
|
Issuer: "https://issuer.com",
|
||||||
AuthorizationEndpoint: "https://issuer.com/auth",
|
AuthorizationEndpoint: "https://issuer.com/auth",
|
||||||
|
@@ -12,7 +12,6 @@ import (
|
|||||||
"github.com/zitadel/oidc/v3/pkg/oidc"
|
"github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
"github.com/zitadel/oidc/v3/pkg/op"
|
"github.com/zitadel/oidc/v3/pkg/op"
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/api/authz"
|
|
||||||
"github.com/zitadel/zitadel/internal/command"
|
"github.com/zitadel/zitadel/internal/command"
|
||||||
"github.com/zitadel/zitadel/internal/domain"
|
"github.com/zitadel/zitadel/internal/domain"
|
||||||
"github.com/zitadel/zitadel/internal/telemetry/tracing"
|
"github.com/zitadel/zitadel/internal/telemetry/tracing"
|
||||||
@@ -64,14 +63,13 @@ func (s *Server) accessTokenResponseFromSession(ctx context.Context, client op.C
|
|||||||
type SignerFunc func(ctx context.Context) (jose.Signer, jose.SignatureAlgorithm, error)
|
type SignerFunc func(ctx context.Context) (jose.Signer, jose.SignatureAlgorithm, error)
|
||||||
|
|
||||||
func (s *Server) getSignerOnce() SignerFunc {
|
func (s *Server) getSignerOnce() SignerFunc {
|
||||||
return GetSignerOnce(s.query.GetActiveSigningWebKey, s.Provider().Storage().SigningKey)
|
return GetSignerOnce(s.query.GetActiveSigningWebKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSignerOnce returns a function which retrieves the instance's signer from the database once.
|
// GetSignerOnce returns a function which retrieves the instance's signer from the database once.
|
||||||
// Repeated calls of the returned function return the same results.
|
// Repeated calls of the returned function return the same results.
|
||||||
func GetSignerOnce(
|
func GetSignerOnce(
|
||||||
getActiveSigningWebKey func(ctx context.Context) (*jose.JSONWebKey, error),
|
getActiveSigningWebKey func(ctx context.Context) (*jose.JSONWebKey, error),
|
||||||
getSigningKey func(ctx context.Context) (op.SigningKey, error),
|
|
||||||
) SignerFunc {
|
) SignerFunc {
|
||||||
var (
|
var (
|
||||||
once sync.Once
|
once sync.Once
|
||||||
@@ -84,23 +82,12 @@ func GetSignerOnce(
|
|||||||
ctx, span := tracing.NewSpan(ctx)
|
ctx, span := tracing.NewSpan(ctx)
|
||||||
defer func() { span.EndWithError(err) }()
|
defer func() { span.EndWithError(err) }()
|
||||||
|
|
||||||
if authz.GetFeatures(ctx).WebKey {
|
var webKey *jose.JSONWebKey
|
||||||
var webKey *jose.JSONWebKey
|
webKey, err = getActiveSigningWebKey(ctx)
|
||||||
webKey, err = getActiveSigningWebKey(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
signer, signAlg, err = signerFromWebKey(webKey)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var signingKey op.SigningKey
|
|
||||||
signingKey, err = getSigningKey(ctx)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
signAlg = signingKey.SignatureAlgorithm()
|
signer, signAlg, err = signerFromWebKey(webKey)
|
||||||
signer, err = op.SignerFromKey(signingKey)
|
|
||||||
})
|
})
|
||||||
return signer, signAlg, err
|
return signer, signAlg, err
|
||||||
}
|
}
|
||||||
|
@@ -14,13 +14,14 @@ import (
|
|||||||
"github.com/zitadel/zitadel/internal/crypto"
|
"github.com/zitadel/zitadel/internal/crypto"
|
||||||
"github.com/zitadel/zitadel/internal/eventstore"
|
"github.com/zitadel/zitadel/internal/eventstore"
|
||||||
"github.com/zitadel/zitadel/internal/query"
|
"github.com/zitadel/zitadel/internal/query"
|
||||||
|
"github.com/zitadel/zitadel/internal/query/projection"
|
||||||
"github.com/zitadel/zitadel/internal/repository/instance"
|
"github.com/zitadel/zitadel/internal/repository/instance"
|
||||||
"github.com/zitadel/zitadel/internal/repository/keypair"
|
"github.com/zitadel/zitadel/internal/repository/keypair"
|
||||||
"github.com/zitadel/zitadel/internal/zerrors"
|
"github.com/zitadel/zitadel/internal/zerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
locksTable = "projections.locks"
|
locksTable = projection.LocksTable
|
||||||
signingKey = "signing_key"
|
signingKey = "signing_key"
|
||||||
samlUser = "SAML"
|
samlUser = "SAML"
|
||||||
|
|
||||||
|
@@ -4,7 +4,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
"slices"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -329,18 +328,10 @@ type openIDKeySet struct {
|
|||||||
// VerifySignature implements the oidc.KeySet interface
|
// VerifySignature implements the oidc.KeySet interface
|
||||||
// providing an implementation for the keys retrieved directly from Queries
|
// providing an implementation for the keys retrieved directly from Queries
|
||||||
func (o *openIDKeySet) VerifySignature(ctx context.Context, jws *jose.JSONWebSignature) (payload []byte, err error) {
|
func (o *openIDKeySet) VerifySignature(ctx context.Context, jws *jose.JSONWebSignature) (payload []byte, err error) {
|
||||||
keySet := new(jose.JSONWebKeySet)
|
keySet, err := o.Queries.GetWebKeySet(ctx)
|
||||||
if authz.GetFeatures(ctx).WebKey {
|
|
||||||
keySet, err = o.Queries.GetWebKeySet(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
legacyKeySet, err := o.Queries.ActivePublicKeys(ctx, time.Now())
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("error fetching keys: %w", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
appendPublicKeysToWebKeySet(keySet, legacyKeySet)
|
|
||||||
keyID, alg := oidc.GetKeyIDAndAlg(jws)
|
keyID, alg := oidc.GetKeyIDAndAlg(jws)
|
||||||
key, err := oidc.FindMatchingKey(keyID, oidc.KeyUseSignature, alg, keySet.Keys...)
|
key, err := oidc.FindMatchingKey(keyID, oidc.KeyUseSignature, alg, keySet.Keys...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -348,19 +339,3 @@ func (o *openIDKeySet) VerifySignature(ctx context.Context, jws *jose.JSONWebSig
|
|||||||
}
|
}
|
||||||
return jws.Verify(&key)
|
return jws.Verify(&key)
|
||||||
}
|
}
|
||||||
|
|
||||||
func appendPublicKeysToWebKeySet(keyset *jose.JSONWebKeySet, pubkeys *query.PublicKeys) {
|
|
||||||
if pubkeys == nil || len(pubkeys.Keys) == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
keyset.Keys = slices.Grow(keyset.Keys, len(pubkeys.Keys))
|
|
||||||
|
|
||||||
for _, key := range pubkeys.Keys {
|
|
||||||
keyset.Keys = append(keyset.Keys, jose.JSONWebKey{
|
|
||||||
Key: key.Key(),
|
|
||||||
KeyID: key.ID(),
|
|
||||||
Algorithm: key.Algorithm(),
|
|
||||||
Use: key.Use().String(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@@ -3,11 +3,8 @@ package command
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/muhlemmer/gu"
|
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/api/authz"
|
"github.com/zitadel/zitadel/internal/api/authz"
|
||||||
"github.com/zitadel/zitadel/internal/command/preparation"
|
"github.com/zitadel/zitadel/internal/command/preparation"
|
||||||
"github.com/zitadel/zitadel/internal/crypto"
|
|
||||||
"github.com/zitadel/zitadel/internal/domain"
|
"github.com/zitadel/zitadel/internal/domain"
|
||||||
"github.com/zitadel/zitadel/internal/eventstore"
|
"github.com/zitadel/zitadel/internal/eventstore"
|
||||||
"github.com/zitadel/zitadel/internal/feature"
|
"github.com/zitadel/zitadel/internal/feature"
|
||||||
@@ -21,7 +18,6 @@ type InstanceFeatures struct {
|
|||||||
UserSchema *bool
|
UserSchema *bool
|
||||||
TokenExchange *bool
|
TokenExchange *bool
|
||||||
ImprovedPerformance []feature.ImprovedPerformanceType
|
ImprovedPerformance []feature.ImprovedPerformanceType
|
||||||
WebKey *bool
|
|
||||||
DebugOIDCParentError *bool
|
DebugOIDCParentError *bool
|
||||||
OIDCSingleV1SessionTermination *bool
|
OIDCSingleV1SessionTermination *bool
|
||||||
DisableUserTokenEvent *bool
|
DisableUserTokenEvent *bool
|
||||||
@@ -38,7 +34,6 @@ func (m *InstanceFeatures) isEmpty() bool {
|
|||||||
m.TokenExchange == nil &&
|
m.TokenExchange == nil &&
|
||||||
// nil check to allow unset improvements
|
// nil check to allow unset improvements
|
||||||
m.ImprovedPerformance == nil &&
|
m.ImprovedPerformance == nil &&
|
||||||
m.WebKey == nil &&
|
|
||||||
m.DebugOIDCParentError == nil &&
|
m.DebugOIDCParentError == nil &&
|
||||||
m.OIDCSingleV1SessionTermination == nil &&
|
m.OIDCSingleV1SessionTermination == nil &&
|
||||||
m.DisableUserTokenEvent == nil &&
|
m.DisableUserTokenEvent == nil &&
|
||||||
@@ -55,9 +50,6 @@ func (c *Commands) SetInstanceFeatures(ctx context.Context, f *InstanceFeatures)
|
|||||||
if err := c.eventstore.FilterToQueryReducer(ctx, wm); err != nil {
|
if err := c.eventstore.FilterToQueryReducer(ctx, wm); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := c.setupWebKeyFeature(ctx, wm, f); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
commands := wm.setCommands(ctx, f)
|
commands := wm.setCommands(ctx, f)
|
||||||
if len(commands) == 0 {
|
if len(commands) == 0 {
|
||||||
return writeModelToObjectDetails(wm.WriteModel), nil
|
return writeModelToObjectDetails(wm.WriteModel), nil
|
||||||
@@ -78,21 +70,6 @@ func prepareSetFeatures(instanceID string, f *InstanceFeatures) preparation.Vali
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// setupWebKeyFeature generates the initial web keys for the instance,
|
|
||||||
// if the feature is enabled in the request and the feature wasn't enabled already in the writeModel.
|
|
||||||
// [Commands.GenerateInitialWebKeys] checks if keys already exist and does nothing if that's the case.
|
|
||||||
// The default config of a RSA key with 2048 and the SHA256 hasher is assumed.
|
|
||||||
// Users can customize this after using the webkey/v3 API.
|
|
||||||
func (c *Commands) setupWebKeyFeature(ctx context.Context, wm *InstanceFeaturesWriteModel, f *InstanceFeatures) error {
|
|
||||||
if !gu.Value(f.WebKey) || gu.Value(wm.WebKey) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return c.GenerateInitialWebKeys(ctx, &crypto.WebKeyRSAConfig{
|
|
||||||
Bits: crypto.RSABits2048,
|
|
||||||
Hasher: crypto.RSAHasherSHA256,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Commands) ResetInstanceFeatures(ctx context.Context) (*domain.ObjectDetails, error) {
|
func (c *Commands) ResetInstanceFeatures(ctx context.Context) (*domain.ObjectDetails, error) {
|
||||||
instanceID := authz.GetInstance(ctx).InstanceID()
|
instanceID := authz.GetInstance(ctx).InstanceID()
|
||||||
wm := NewInstanceFeaturesWriteModel(instanceID)
|
wm := NewInstanceFeaturesWriteModel(instanceID)
|
||||||
|
@@ -71,7 +71,6 @@ func (m *InstanceFeaturesWriteModel) Query() *eventstore.SearchQueryBuilder {
|
|||||||
feature_v2.InstanceUserSchemaEventType,
|
feature_v2.InstanceUserSchemaEventType,
|
||||||
feature_v2.InstanceTokenExchangeEventType,
|
feature_v2.InstanceTokenExchangeEventType,
|
||||||
feature_v2.InstanceImprovedPerformanceEventType,
|
feature_v2.InstanceImprovedPerformanceEventType,
|
||||||
feature_v2.InstanceWebKeyEventType,
|
|
||||||
feature_v2.InstanceDebugOIDCParentErrorEventType,
|
feature_v2.InstanceDebugOIDCParentErrorEventType,
|
||||||
feature_v2.InstanceOIDCSingleV1SessionTerminationEventType,
|
feature_v2.InstanceOIDCSingleV1SessionTerminationEventType,
|
||||||
feature_v2.InstanceDisableUserTokenEvent,
|
feature_v2.InstanceDisableUserTokenEvent,
|
||||||
@@ -106,9 +105,6 @@ func reduceInstanceFeature(features *InstanceFeatures, key feature.Key, value an
|
|||||||
case feature.KeyImprovedPerformance:
|
case feature.KeyImprovedPerformance:
|
||||||
v := value.([]feature.ImprovedPerformanceType)
|
v := value.([]feature.ImprovedPerformanceType)
|
||||||
features.ImprovedPerformance = v
|
features.ImprovedPerformance = v
|
||||||
case feature.KeyWebKey:
|
|
||||||
v := value.(bool)
|
|
||||||
features.WebKey = &v
|
|
||||||
case feature.KeyDebugOIDCParentError:
|
case feature.KeyDebugOIDCParentError:
|
||||||
v := value.(bool)
|
v := value.(bool)
|
||||||
features.DebugOIDCParentError = &v
|
features.DebugOIDCParentError = &v
|
||||||
@@ -140,7 +136,6 @@ func (wm *InstanceFeaturesWriteModel) setCommands(ctx context.Context, f *Instan
|
|||||||
cmds = appendFeatureUpdate(ctx, cmds, aggregate, wm.TokenExchange, f.TokenExchange, feature_v2.InstanceTokenExchangeEventType)
|
cmds = appendFeatureUpdate(ctx, cmds, aggregate, wm.TokenExchange, f.TokenExchange, feature_v2.InstanceTokenExchangeEventType)
|
||||||
cmds = appendFeatureUpdate(ctx, cmds, aggregate, wm.UserSchema, f.UserSchema, feature_v2.InstanceUserSchemaEventType)
|
cmds = appendFeatureUpdate(ctx, cmds, aggregate, wm.UserSchema, f.UserSchema, feature_v2.InstanceUserSchemaEventType)
|
||||||
cmds = appendFeatureSliceUpdate(ctx, cmds, aggregate, wm.ImprovedPerformance, f.ImprovedPerformance, feature_v2.InstanceImprovedPerformanceEventType)
|
cmds = appendFeatureSliceUpdate(ctx, cmds, aggregate, wm.ImprovedPerformance, f.ImprovedPerformance, feature_v2.InstanceImprovedPerformanceEventType)
|
||||||
cmds = appendFeatureUpdate(ctx, cmds, aggregate, wm.WebKey, f.WebKey, feature_v2.InstanceWebKeyEventType)
|
|
||||||
cmds = appendFeatureUpdate(ctx, cmds, aggregate, wm.DebugOIDCParentError, f.DebugOIDCParentError, feature_v2.InstanceDebugOIDCParentErrorEventType)
|
cmds = appendFeatureUpdate(ctx, cmds, aggregate, wm.DebugOIDCParentError, f.DebugOIDCParentError, feature_v2.InstanceDebugOIDCParentErrorEventType)
|
||||||
cmds = appendFeatureUpdate(ctx, cmds, aggregate, wm.OIDCSingleV1SessionTermination, f.OIDCSingleV1SessionTermination, feature_v2.InstanceOIDCSingleV1SessionTerminationEventType)
|
cmds = appendFeatureUpdate(ctx, cmds, aggregate, wm.OIDCSingleV1SessionTermination, f.OIDCSingleV1SessionTermination, feature_v2.InstanceOIDCSingleV1SessionTerminationEventType)
|
||||||
cmds = appendFeatureUpdate(ctx, cmds, aggregate, wm.DisableUserTokenEvent, f.DisableUserTokenEvent, feature_v2.InstanceDisableUserTokenEvent)
|
cmds = appendFeatureUpdate(ctx, cmds, aggregate, wm.DisableUserTokenEvent, f.DisableUserTokenEvent, feature_v2.InstanceDisableUserTokenEvent)
|
||||||
|
@@ -13,31 +13,6 @@ import (
|
|||||||
"github.com/zitadel/zitadel/internal/repository/keypair"
|
"github.com/zitadel/zitadel/internal/repository/keypair"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *Commands) GenerateSigningKeyPair(ctx context.Context, algorithm string) error {
|
|
||||||
privateCrypto, publicCrypto, err := crypto.GenerateEncryptedKeyPair(c.keySize, c.keyAlgorithm)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
keyID, err := c.idGenerator.Next()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
privateKeyExp := time.Now().UTC().Add(c.privateKeyLifetime)
|
|
||||||
publicKeyExp := time.Now().UTC().Add(c.publicKeyLifetime)
|
|
||||||
|
|
||||||
keyPairWriteModel := NewKeyPairWriteModel(keyID, authz.GetInstance(ctx).InstanceID())
|
|
||||||
keyAgg := KeyPairAggregateFromWriteModel(&keyPairWriteModel.WriteModel)
|
|
||||||
_, err = c.eventstore.Push(ctx, keypair.NewAddedEvent(
|
|
||||||
ctx,
|
|
||||||
keyAgg,
|
|
||||||
crypto.KeyUsageSigning,
|
|
||||||
algorithm,
|
|
||||||
privateCrypto, publicCrypto,
|
|
||||||
privateKeyExp, publicKeyExp))
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Commands) GenerateSAMLCACertificate(ctx context.Context, algorithm string) error {
|
func (c *Commands) GenerateSAMLCACertificate(ctx context.Context, algorithm string) error {
|
||||||
now := time.Now().UTC()
|
now := time.Now().UTC()
|
||||||
after := now.Add(c.certificateLifetime)
|
after := now.Add(c.certificateLifetime)
|
||||||
|
@@ -21,14 +21,6 @@ func GenerateKeyPair(bits int) (*rsa.PrivateKey, *rsa.PublicKey, error) {
|
|||||||
return privkey, &privkey.PublicKey, nil
|
return privkey, &privkey.PublicKey, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GenerateEncryptedKeyPair(bits int, alg EncryptionAlgorithm) (*CryptoValue, *CryptoValue, error) {
|
|
||||||
privateKey, publicKey, err := GenerateKeyPair(bits)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
return EncryptKeys(privateKey, publicKey, alg)
|
|
||||||
}
|
|
||||||
|
|
||||||
type CertificateInformations struct {
|
type CertificateInformations struct {
|
||||||
SerialNumber *big.Int
|
SerialNumber *big.Int
|
||||||
Organisation []string
|
Organisation []string
|
||||||
|
@@ -9,7 +9,7 @@ import (
|
|||||||
type Key int
|
type Key int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// Reserved: 3, 6
|
// Reserved: 3, 6, 8
|
||||||
|
|
||||||
KeyUnspecified Key = 0
|
KeyUnspecified Key = 0
|
||||||
KeyLoginDefaultOrg Key = 1
|
KeyLoginDefaultOrg Key = 1
|
||||||
@@ -17,7 +17,6 @@ const (
|
|||||||
KeyUserSchema Key = 4
|
KeyUserSchema Key = 4
|
||||||
KeyTokenExchange Key = 5
|
KeyTokenExchange Key = 5
|
||||||
KeyImprovedPerformance Key = 7
|
KeyImprovedPerformance Key = 7
|
||||||
KeyWebKey Key = 8
|
|
||||||
KeyDebugOIDCParentError Key = 9
|
KeyDebugOIDCParentError Key = 9
|
||||||
KeyOIDCSingleV1SessionTermination Key = 10
|
KeyOIDCSingleV1SessionTermination Key = 10
|
||||||
KeyDisableUserTokenEvent Key = 11
|
KeyDisableUserTokenEvent Key = 11
|
||||||
@@ -46,7 +45,6 @@ type Features struct {
|
|||||||
UserSchema bool `json:"user_schema,omitempty"`
|
UserSchema bool `json:"user_schema,omitempty"`
|
||||||
TokenExchange bool `json:"token_exchange,omitempty"`
|
TokenExchange bool `json:"token_exchange,omitempty"`
|
||||||
ImprovedPerformance []ImprovedPerformanceType `json:"improved_performance,omitempty"`
|
ImprovedPerformance []ImprovedPerformanceType `json:"improved_performance,omitempty"`
|
||||||
WebKey bool `json:"web_key,omitempty"`
|
|
||||||
DebugOIDCParentError bool `json:"debug_oidc_parent_error,omitempty"`
|
DebugOIDCParentError bool `json:"debug_oidc_parent_error,omitempty"`
|
||||||
OIDCSingleV1SessionTermination bool `json:"oidc_single_v1_session_termination,omitempty"`
|
OIDCSingleV1SessionTermination bool `json:"oidc_single_v1_session_termination,omitempty"`
|
||||||
DisableUserTokenEvent bool `json:"disable_user_token_event,omitempty"`
|
DisableUserTokenEvent bool `json:"disable_user_token_event,omitempty"`
|
||||||
|
@@ -12,14 +12,17 @@ const (
|
|||||||
_KeyLowerName_0 = "unspecifiedlogin_default_orgtrigger_introspection_projections"
|
_KeyLowerName_0 = "unspecifiedlogin_default_orgtrigger_introspection_projections"
|
||||||
_KeyName_1 = "user_schematoken_exchange"
|
_KeyName_1 = "user_schematoken_exchange"
|
||||||
_KeyLowerName_1 = "user_schematoken_exchange"
|
_KeyLowerName_1 = "user_schematoken_exchange"
|
||||||
_KeyName_2 = "improved_performanceweb_keydebug_oidc_parent_erroroidc_single_v1_session_terminationdisable_user_token_eventenable_back_channel_logoutlogin_v2permission_check_v2console_use_v2_user_api"
|
_KeyName_2 = "improved_performance"
|
||||||
_KeyLowerName_2 = "improved_performanceweb_keydebug_oidc_parent_erroroidc_single_v1_session_terminationdisable_user_token_eventenable_back_channel_logoutlogin_v2permission_check_v2console_use_v2_user_api"
|
_KeyLowerName_2 = "improved_performance"
|
||||||
|
_KeyName_3 = "debug_oidc_parent_erroroidc_single_v1_session_terminationdisable_user_token_eventenable_back_channel_logoutlogin_v2permission_check_v2console_use_v2_user_api"
|
||||||
|
_KeyLowerName_3 = "debug_oidc_parent_erroroidc_single_v1_session_terminationdisable_user_token_eventenable_back_channel_logoutlogin_v2permission_check_v2console_use_v2_user_api"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
_KeyIndex_0 = [...]uint8{0, 11, 28, 61}
|
_KeyIndex_0 = [...]uint8{0, 11, 28, 61}
|
||||||
_KeyIndex_1 = [...]uint8{0, 11, 25}
|
_KeyIndex_1 = [...]uint8{0, 11, 25}
|
||||||
_KeyIndex_2 = [...]uint8{0, 20, 27, 50, 84, 108, 134, 142, 161, 184}
|
_KeyIndex_2 = [...]uint8{0, 20}
|
||||||
|
_KeyIndex_3 = [...]uint8{0, 23, 57, 81, 107, 115, 134, 157}
|
||||||
)
|
)
|
||||||
|
|
||||||
func (i Key) String() string {
|
func (i Key) String() string {
|
||||||
@@ -29,9 +32,11 @@ func (i Key) String() string {
|
|||||||
case 4 <= i && i <= 5:
|
case 4 <= i && i <= 5:
|
||||||
i -= 4
|
i -= 4
|
||||||
return _KeyName_1[_KeyIndex_1[i]:_KeyIndex_1[i+1]]
|
return _KeyName_1[_KeyIndex_1[i]:_KeyIndex_1[i+1]]
|
||||||
case 7 <= i && i <= 15:
|
case i == 7:
|
||||||
i -= 7
|
return _KeyName_2
|
||||||
return _KeyName_2[_KeyIndex_2[i]:_KeyIndex_2[i+1]]
|
case 9 <= i && i <= 15:
|
||||||
|
i -= 9
|
||||||
|
return _KeyName_3[_KeyIndex_3[i]:_KeyIndex_3[i+1]]
|
||||||
default:
|
default:
|
||||||
return fmt.Sprintf("Key(%d)", i)
|
return fmt.Sprintf("Key(%d)", i)
|
||||||
}
|
}
|
||||||
@@ -47,7 +52,6 @@ func _KeyNoOp() {
|
|||||||
_ = x[KeyUserSchema-(4)]
|
_ = x[KeyUserSchema-(4)]
|
||||||
_ = x[KeyTokenExchange-(5)]
|
_ = x[KeyTokenExchange-(5)]
|
||||||
_ = x[KeyImprovedPerformance-(7)]
|
_ = x[KeyImprovedPerformance-(7)]
|
||||||
_ = x[KeyWebKey-(8)]
|
|
||||||
_ = x[KeyDebugOIDCParentError-(9)]
|
_ = x[KeyDebugOIDCParentError-(9)]
|
||||||
_ = x[KeyOIDCSingleV1SessionTermination-(10)]
|
_ = x[KeyOIDCSingleV1SessionTermination-(10)]
|
||||||
_ = x[KeyDisableUserTokenEvent-(11)]
|
_ = x[KeyDisableUserTokenEvent-(11)]
|
||||||
@@ -57,7 +61,7 @@ func _KeyNoOp() {
|
|||||||
_ = x[KeyConsoleUseV2UserApi-(15)]
|
_ = x[KeyConsoleUseV2UserApi-(15)]
|
||||||
}
|
}
|
||||||
|
|
||||||
var _KeyValues = []Key{KeyUnspecified, KeyLoginDefaultOrg, KeyTriggerIntrospectionProjections, KeyUserSchema, KeyTokenExchange, KeyImprovedPerformance, KeyWebKey, KeyDebugOIDCParentError, KeyOIDCSingleV1SessionTermination, KeyDisableUserTokenEvent, KeyEnableBackChannelLogout, KeyLoginV2, KeyPermissionCheckV2, KeyConsoleUseV2UserApi}
|
var _KeyValues = []Key{KeyUnspecified, KeyLoginDefaultOrg, KeyTriggerIntrospectionProjections, KeyUserSchema, KeyTokenExchange, KeyImprovedPerformance, KeyDebugOIDCParentError, KeyOIDCSingleV1SessionTermination, KeyDisableUserTokenEvent, KeyEnableBackChannelLogout, KeyLoginV2, KeyPermissionCheckV2, KeyConsoleUseV2UserApi}
|
||||||
|
|
||||||
var _KeyNameToValueMap = map[string]Key{
|
var _KeyNameToValueMap = map[string]Key{
|
||||||
_KeyName_0[0:11]: KeyUnspecified,
|
_KeyName_0[0:11]: KeyUnspecified,
|
||||||
@@ -72,22 +76,20 @@ var _KeyNameToValueMap = map[string]Key{
|
|||||||
_KeyLowerName_1[11:25]: KeyTokenExchange,
|
_KeyLowerName_1[11:25]: KeyTokenExchange,
|
||||||
_KeyName_2[0:20]: KeyImprovedPerformance,
|
_KeyName_2[0:20]: KeyImprovedPerformance,
|
||||||
_KeyLowerName_2[0:20]: KeyImprovedPerformance,
|
_KeyLowerName_2[0:20]: KeyImprovedPerformance,
|
||||||
_KeyName_2[20:27]: KeyWebKey,
|
_KeyName_3[0:23]: KeyDebugOIDCParentError,
|
||||||
_KeyLowerName_2[20:27]: KeyWebKey,
|
_KeyLowerName_3[0:23]: KeyDebugOIDCParentError,
|
||||||
_KeyName_2[27:50]: KeyDebugOIDCParentError,
|
_KeyName_3[23:57]: KeyOIDCSingleV1SessionTermination,
|
||||||
_KeyLowerName_2[27:50]: KeyDebugOIDCParentError,
|
_KeyLowerName_3[23:57]: KeyOIDCSingleV1SessionTermination,
|
||||||
_KeyName_2[50:84]: KeyOIDCSingleV1SessionTermination,
|
_KeyName_3[57:81]: KeyDisableUserTokenEvent,
|
||||||
_KeyLowerName_2[50:84]: KeyOIDCSingleV1SessionTermination,
|
_KeyLowerName_3[57:81]: KeyDisableUserTokenEvent,
|
||||||
_KeyName_2[84:108]: KeyDisableUserTokenEvent,
|
_KeyName_3[81:107]: KeyEnableBackChannelLogout,
|
||||||
_KeyLowerName_2[84:108]: KeyDisableUserTokenEvent,
|
_KeyLowerName_3[81:107]: KeyEnableBackChannelLogout,
|
||||||
_KeyName_2[108:134]: KeyEnableBackChannelLogout,
|
_KeyName_3[107:115]: KeyLoginV2,
|
||||||
_KeyLowerName_2[108:134]: KeyEnableBackChannelLogout,
|
_KeyLowerName_3[107:115]: KeyLoginV2,
|
||||||
_KeyName_2[134:142]: KeyLoginV2,
|
_KeyName_3[115:134]: KeyPermissionCheckV2,
|
||||||
_KeyLowerName_2[134:142]: KeyLoginV2,
|
_KeyLowerName_3[115:134]: KeyPermissionCheckV2,
|
||||||
_KeyName_2[142:161]: KeyPermissionCheckV2,
|
_KeyName_3[134:157]: KeyConsoleUseV2UserApi,
|
||||||
_KeyLowerName_2[142:161]: KeyPermissionCheckV2,
|
_KeyLowerName_3[134:157]: KeyConsoleUseV2UserApi,
|
||||||
_KeyName_2[161:184]: KeyConsoleUseV2UserApi,
|
|
||||||
_KeyLowerName_2[161:184]: KeyConsoleUseV2UserApi,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var _KeyNames = []string{
|
var _KeyNames = []string{
|
||||||
@@ -97,14 +99,13 @@ var _KeyNames = []string{
|
|||||||
_KeyName_1[0:11],
|
_KeyName_1[0:11],
|
||||||
_KeyName_1[11:25],
|
_KeyName_1[11:25],
|
||||||
_KeyName_2[0:20],
|
_KeyName_2[0:20],
|
||||||
_KeyName_2[20:27],
|
_KeyName_3[0:23],
|
||||||
_KeyName_2[27:50],
|
_KeyName_3[23:57],
|
||||||
_KeyName_2[50:84],
|
_KeyName_3[57:81],
|
||||||
_KeyName_2[84:108],
|
_KeyName_3[81:107],
|
||||||
_KeyName_2[108:134],
|
_KeyName_3[107:115],
|
||||||
_KeyName_2[134:142],
|
_KeyName_3[115:134],
|
||||||
_KeyName_2[142:161],
|
_KeyName_3[134:157],
|
||||||
_KeyName_2[161:184],
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// KeyString retrieves an enum value from the enum constants string name.
|
// KeyString retrieves an enum value from the enum constants string name.
|
||||||
|
@@ -7,10 +7,8 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/zitadel/logging"
|
|
||||||
"github.com/zitadel/oidc/v3/pkg/crypto"
|
"github.com/zitadel/oidc/v3/pkg/crypto"
|
||||||
"github.com/zitadel/oidc/v3/pkg/oidc"
|
"github.com/zitadel/oidc/v3/pkg/oidc"
|
||||||
"github.com/zitadel/oidc/v3/pkg/op"
|
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/api/authz"
|
"github.com/zitadel/zitadel/internal/api/authz"
|
||||||
http_utils "github.com/zitadel/zitadel/internal/api/http"
|
http_utils "github.com/zitadel/zitadel/internal/api/http"
|
||||||
@@ -149,7 +147,7 @@ func (u *backChannelLogoutNotifier) terminateSession(ctx context.Context, id str
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
getSigner := zoidc.GetSignerOnce(u.queries.GetActiveSigningWebKey, u.signingKey)
|
getSigner := zoidc.GetSignerOnce(u.queries.GetActiveSigningWebKey)
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
wg.Add(len(sessions.sessions))
|
wg.Add(len(sessions.sessions))
|
||||||
@@ -172,20 +170,6 @@ func (u *backChannelLogoutNotifier) terminateSession(ctx context.Context, id str
|
|||||||
return errors.Join(errs...)
|
return errors.Join(errs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *backChannelLogoutNotifier) signingKey(ctx context.Context) (op.SigningKey, error) {
|
|
||||||
keys, err := u.queries.ActivePrivateSigningKey(ctx, time.Now())
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if len(keys.Keys) == 0 {
|
|
||||||
logging.WithFields("instanceID", authz.GetInstance(ctx).InstanceID()).
|
|
||||||
Info("There's no active signing key and automatic rotation is not supported for back channel logout." +
|
|
||||||
"Please enable the webkey management feature on your instance")
|
|
||||||
return nil, zerrors.ThrowPreconditionFailed(nil, "HANDL-DF3nf", "no active signing key")
|
|
||||||
}
|
|
||||||
return zoidc.PrivateKeyToSigningKey(zoidc.SelectSigningKey(keys.Keys), u.keyEncryptionAlg)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *backChannelLogoutNotifier) sendLogoutToken(ctx context.Context, oidcSession *backChannelLogoutOIDCSessions, e eventstore.Event, getSigner zoidc.SignerFunc) error {
|
func (u *backChannelLogoutNotifier) sendLogoutToken(ctx context.Context, oidcSession *backChannelLogoutOIDCSessions, e eventstore.Event, getSigner zoidc.SignerFunc) error {
|
||||||
token, err := u.logoutToken(ctx, oidcSession, getSigner)
|
token, err := u.logoutToken(ctx, oidcSession, getSigner)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@@ -23,6 +23,7 @@ import (
|
|||||||
type MockCommands struct {
|
type MockCommands struct {
|
||||||
ctrl *gomock.Controller
|
ctrl *gomock.Controller
|
||||||
recorder *MockCommandsMockRecorder
|
recorder *MockCommandsMockRecorder
|
||||||
|
isgomock struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MockCommandsMockRecorder is the mock recorder for MockCommands.
|
// MockCommandsMockRecorder is the mock recorder for MockCommands.
|
||||||
@@ -43,197 +44,197 @@ func (m *MockCommands) EXPECT() *MockCommandsMockRecorder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// HumanEmailVerificationCodeSent mocks base method.
|
// HumanEmailVerificationCodeSent mocks base method.
|
||||||
func (m *MockCommands) HumanEmailVerificationCodeSent(arg0 context.Context, arg1, arg2 string) error {
|
func (m *MockCommands) HumanEmailVerificationCodeSent(ctx context.Context, orgID, userID string) error {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "HumanEmailVerificationCodeSent", arg0, arg1, arg2)
|
ret := m.ctrl.Call(m, "HumanEmailVerificationCodeSent", ctx, orgID, userID)
|
||||||
ret0, _ := ret[0].(error)
|
ret0, _ := ret[0].(error)
|
||||||
return ret0
|
return ret0
|
||||||
}
|
}
|
||||||
|
|
||||||
// HumanEmailVerificationCodeSent indicates an expected call of HumanEmailVerificationCodeSent.
|
// HumanEmailVerificationCodeSent indicates an expected call of HumanEmailVerificationCodeSent.
|
||||||
func (mr *MockCommandsMockRecorder) HumanEmailVerificationCodeSent(arg0, arg1, arg2 any) *gomock.Call {
|
func (mr *MockCommandsMockRecorder) HumanEmailVerificationCodeSent(ctx, orgID, userID any) *gomock.Call {
|
||||||
mr.mock.ctrl.T.Helper()
|
mr.mock.ctrl.T.Helper()
|
||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HumanEmailVerificationCodeSent", reflect.TypeOf((*MockCommands)(nil).HumanEmailVerificationCodeSent), arg0, arg1, arg2)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HumanEmailVerificationCodeSent", reflect.TypeOf((*MockCommands)(nil).HumanEmailVerificationCodeSent), ctx, orgID, userID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HumanInitCodeSent mocks base method.
|
// HumanInitCodeSent mocks base method.
|
||||||
func (m *MockCommands) HumanInitCodeSent(arg0 context.Context, arg1, arg2 string) error {
|
func (m *MockCommands) HumanInitCodeSent(ctx context.Context, orgID, userID string) error {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "HumanInitCodeSent", arg0, arg1, arg2)
|
ret := m.ctrl.Call(m, "HumanInitCodeSent", ctx, orgID, userID)
|
||||||
ret0, _ := ret[0].(error)
|
ret0, _ := ret[0].(error)
|
||||||
return ret0
|
return ret0
|
||||||
}
|
}
|
||||||
|
|
||||||
// HumanInitCodeSent indicates an expected call of HumanInitCodeSent.
|
// HumanInitCodeSent indicates an expected call of HumanInitCodeSent.
|
||||||
func (mr *MockCommandsMockRecorder) HumanInitCodeSent(arg0, arg1, arg2 any) *gomock.Call {
|
func (mr *MockCommandsMockRecorder) HumanInitCodeSent(ctx, orgID, userID any) *gomock.Call {
|
||||||
mr.mock.ctrl.T.Helper()
|
mr.mock.ctrl.T.Helper()
|
||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HumanInitCodeSent", reflect.TypeOf((*MockCommands)(nil).HumanInitCodeSent), arg0, arg1, arg2)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HumanInitCodeSent", reflect.TypeOf((*MockCommands)(nil).HumanInitCodeSent), ctx, orgID, userID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HumanOTPEmailCodeSent mocks base method.
|
// HumanOTPEmailCodeSent mocks base method.
|
||||||
func (m *MockCommands) HumanOTPEmailCodeSent(arg0 context.Context, arg1, arg2 string) error {
|
func (m *MockCommands) HumanOTPEmailCodeSent(ctx context.Context, userID, resourceOwner string) error {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "HumanOTPEmailCodeSent", arg0, arg1, arg2)
|
ret := m.ctrl.Call(m, "HumanOTPEmailCodeSent", ctx, userID, resourceOwner)
|
||||||
ret0, _ := ret[0].(error)
|
ret0, _ := ret[0].(error)
|
||||||
return ret0
|
return ret0
|
||||||
}
|
}
|
||||||
|
|
||||||
// HumanOTPEmailCodeSent indicates an expected call of HumanOTPEmailCodeSent.
|
// HumanOTPEmailCodeSent indicates an expected call of HumanOTPEmailCodeSent.
|
||||||
func (mr *MockCommandsMockRecorder) HumanOTPEmailCodeSent(arg0, arg1, arg2 any) *gomock.Call {
|
func (mr *MockCommandsMockRecorder) HumanOTPEmailCodeSent(ctx, userID, resourceOwner any) *gomock.Call {
|
||||||
mr.mock.ctrl.T.Helper()
|
mr.mock.ctrl.T.Helper()
|
||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HumanOTPEmailCodeSent", reflect.TypeOf((*MockCommands)(nil).HumanOTPEmailCodeSent), arg0, arg1, arg2)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HumanOTPEmailCodeSent", reflect.TypeOf((*MockCommands)(nil).HumanOTPEmailCodeSent), ctx, userID, resourceOwner)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HumanOTPSMSCodeSent mocks base method.
|
// HumanOTPSMSCodeSent mocks base method.
|
||||||
func (m *MockCommands) HumanOTPSMSCodeSent(arg0 context.Context, arg1, arg2 string, arg3 *senders.CodeGeneratorInfo) error {
|
func (m *MockCommands) HumanOTPSMSCodeSent(ctx context.Context, userID, resourceOwner string, generatorInfo *senders.CodeGeneratorInfo) error {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "HumanOTPSMSCodeSent", arg0, arg1, arg2, arg3)
|
ret := m.ctrl.Call(m, "HumanOTPSMSCodeSent", ctx, userID, resourceOwner, generatorInfo)
|
||||||
ret0, _ := ret[0].(error)
|
ret0, _ := ret[0].(error)
|
||||||
return ret0
|
return ret0
|
||||||
}
|
}
|
||||||
|
|
||||||
// HumanOTPSMSCodeSent indicates an expected call of HumanOTPSMSCodeSent.
|
// HumanOTPSMSCodeSent indicates an expected call of HumanOTPSMSCodeSent.
|
||||||
func (mr *MockCommandsMockRecorder) HumanOTPSMSCodeSent(arg0, arg1, arg2, arg3 any) *gomock.Call {
|
func (mr *MockCommandsMockRecorder) HumanOTPSMSCodeSent(ctx, userID, resourceOwner, generatorInfo any) *gomock.Call {
|
||||||
mr.mock.ctrl.T.Helper()
|
mr.mock.ctrl.T.Helper()
|
||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HumanOTPSMSCodeSent", reflect.TypeOf((*MockCommands)(nil).HumanOTPSMSCodeSent), arg0, arg1, arg2, arg3)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HumanOTPSMSCodeSent", reflect.TypeOf((*MockCommands)(nil).HumanOTPSMSCodeSent), ctx, userID, resourceOwner, generatorInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HumanPasswordlessInitCodeSent mocks base method.
|
// HumanPasswordlessInitCodeSent mocks base method.
|
||||||
func (m *MockCommands) HumanPasswordlessInitCodeSent(arg0 context.Context, arg1, arg2, arg3 string) error {
|
func (m *MockCommands) HumanPasswordlessInitCodeSent(ctx context.Context, userID, resourceOwner, codeID string) error {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "HumanPasswordlessInitCodeSent", arg0, arg1, arg2, arg3)
|
ret := m.ctrl.Call(m, "HumanPasswordlessInitCodeSent", ctx, userID, resourceOwner, codeID)
|
||||||
ret0, _ := ret[0].(error)
|
ret0, _ := ret[0].(error)
|
||||||
return ret0
|
return ret0
|
||||||
}
|
}
|
||||||
|
|
||||||
// HumanPasswordlessInitCodeSent indicates an expected call of HumanPasswordlessInitCodeSent.
|
// HumanPasswordlessInitCodeSent indicates an expected call of HumanPasswordlessInitCodeSent.
|
||||||
func (mr *MockCommandsMockRecorder) HumanPasswordlessInitCodeSent(arg0, arg1, arg2, arg3 any) *gomock.Call {
|
func (mr *MockCommandsMockRecorder) HumanPasswordlessInitCodeSent(ctx, userID, resourceOwner, codeID any) *gomock.Call {
|
||||||
mr.mock.ctrl.T.Helper()
|
mr.mock.ctrl.T.Helper()
|
||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HumanPasswordlessInitCodeSent", reflect.TypeOf((*MockCommands)(nil).HumanPasswordlessInitCodeSent), arg0, arg1, arg2, arg3)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HumanPasswordlessInitCodeSent", reflect.TypeOf((*MockCommands)(nil).HumanPasswordlessInitCodeSent), ctx, userID, resourceOwner, codeID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HumanPhoneVerificationCodeSent mocks base method.
|
// HumanPhoneVerificationCodeSent mocks base method.
|
||||||
func (m *MockCommands) HumanPhoneVerificationCodeSent(arg0 context.Context, arg1, arg2 string, arg3 *senders.CodeGeneratorInfo) error {
|
func (m *MockCommands) HumanPhoneVerificationCodeSent(ctx context.Context, orgID, userID string, generatorInfo *senders.CodeGeneratorInfo) error {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "HumanPhoneVerificationCodeSent", arg0, arg1, arg2, arg3)
|
ret := m.ctrl.Call(m, "HumanPhoneVerificationCodeSent", ctx, orgID, userID, generatorInfo)
|
||||||
ret0, _ := ret[0].(error)
|
ret0, _ := ret[0].(error)
|
||||||
return ret0
|
return ret0
|
||||||
}
|
}
|
||||||
|
|
||||||
// HumanPhoneVerificationCodeSent indicates an expected call of HumanPhoneVerificationCodeSent.
|
// HumanPhoneVerificationCodeSent indicates an expected call of HumanPhoneVerificationCodeSent.
|
||||||
func (mr *MockCommandsMockRecorder) HumanPhoneVerificationCodeSent(arg0, arg1, arg2, arg3 any) *gomock.Call {
|
func (mr *MockCommandsMockRecorder) HumanPhoneVerificationCodeSent(ctx, orgID, userID, generatorInfo any) *gomock.Call {
|
||||||
mr.mock.ctrl.T.Helper()
|
mr.mock.ctrl.T.Helper()
|
||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HumanPhoneVerificationCodeSent", reflect.TypeOf((*MockCommands)(nil).HumanPhoneVerificationCodeSent), arg0, arg1, arg2, arg3)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HumanPhoneVerificationCodeSent", reflect.TypeOf((*MockCommands)(nil).HumanPhoneVerificationCodeSent), ctx, orgID, userID, generatorInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
// InviteCodeSent mocks base method.
|
// InviteCodeSent mocks base method.
|
||||||
func (m *MockCommands) InviteCodeSent(arg0 context.Context, arg1, arg2 string) error {
|
func (m *MockCommands) InviteCodeSent(ctx context.Context, orgID, userID string) error {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "InviteCodeSent", arg0, arg1, arg2)
|
ret := m.ctrl.Call(m, "InviteCodeSent", ctx, orgID, userID)
|
||||||
ret0, _ := ret[0].(error)
|
ret0, _ := ret[0].(error)
|
||||||
return ret0
|
return ret0
|
||||||
}
|
}
|
||||||
|
|
||||||
// InviteCodeSent indicates an expected call of InviteCodeSent.
|
// InviteCodeSent indicates an expected call of InviteCodeSent.
|
||||||
func (mr *MockCommandsMockRecorder) InviteCodeSent(arg0, arg1, arg2 any) *gomock.Call {
|
func (mr *MockCommandsMockRecorder) InviteCodeSent(ctx, orgID, userID any) *gomock.Call {
|
||||||
mr.mock.ctrl.T.Helper()
|
mr.mock.ctrl.T.Helper()
|
||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InviteCodeSent", reflect.TypeOf((*MockCommands)(nil).InviteCodeSent), arg0, arg1, arg2)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InviteCodeSent", reflect.TypeOf((*MockCommands)(nil).InviteCodeSent), ctx, orgID, userID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MilestonePushed mocks base method.
|
// MilestonePushed mocks base method.
|
||||||
func (m *MockCommands) MilestonePushed(arg0 context.Context, arg1 string, arg2 milestone.Type, arg3 []string) error {
|
func (m *MockCommands) MilestonePushed(ctx context.Context, instanceID string, msType milestone.Type, endpoints []string) error {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "MilestonePushed", arg0, arg1, arg2, arg3)
|
ret := m.ctrl.Call(m, "MilestonePushed", ctx, instanceID, msType, endpoints)
|
||||||
ret0, _ := ret[0].(error)
|
ret0, _ := ret[0].(error)
|
||||||
return ret0
|
return ret0
|
||||||
}
|
}
|
||||||
|
|
||||||
// MilestonePushed indicates an expected call of MilestonePushed.
|
// MilestonePushed indicates an expected call of MilestonePushed.
|
||||||
func (mr *MockCommandsMockRecorder) MilestonePushed(arg0, arg1, arg2, arg3 any) *gomock.Call {
|
func (mr *MockCommandsMockRecorder) MilestonePushed(ctx, instanceID, msType, endpoints any) *gomock.Call {
|
||||||
mr.mock.ctrl.T.Helper()
|
mr.mock.ctrl.T.Helper()
|
||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MilestonePushed", reflect.TypeOf((*MockCommands)(nil).MilestonePushed), arg0, arg1, arg2, arg3)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MilestonePushed", reflect.TypeOf((*MockCommands)(nil).MilestonePushed), ctx, instanceID, msType, endpoints)
|
||||||
}
|
}
|
||||||
|
|
||||||
// OTPEmailSent mocks base method.
|
// OTPEmailSent mocks base method.
|
||||||
func (m *MockCommands) OTPEmailSent(arg0 context.Context, arg1, arg2 string) error {
|
func (m *MockCommands) OTPEmailSent(ctx context.Context, sessionID, resourceOwner string) error {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "OTPEmailSent", arg0, arg1, arg2)
|
ret := m.ctrl.Call(m, "OTPEmailSent", ctx, sessionID, resourceOwner)
|
||||||
ret0, _ := ret[0].(error)
|
ret0, _ := ret[0].(error)
|
||||||
return ret0
|
return ret0
|
||||||
}
|
}
|
||||||
|
|
||||||
// OTPEmailSent indicates an expected call of OTPEmailSent.
|
// OTPEmailSent indicates an expected call of OTPEmailSent.
|
||||||
func (mr *MockCommandsMockRecorder) OTPEmailSent(arg0, arg1, arg2 any) *gomock.Call {
|
func (mr *MockCommandsMockRecorder) OTPEmailSent(ctx, sessionID, resourceOwner any) *gomock.Call {
|
||||||
mr.mock.ctrl.T.Helper()
|
mr.mock.ctrl.T.Helper()
|
||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OTPEmailSent", reflect.TypeOf((*MockCommands)(nil).OTPEmailSent), arg0, arg1, arg2)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OTPEmailSent", reflect.TypeOf((*MockCommands)(nil).OTPEmailSent), ctx, sessionID, resourceOwner)
|
||||||
}
|
}
|
||||||
|
|
||||||
// OTPSMSSent mocks base method.
|
// OTPSMSSent mocks base method.
|
||||||
func (m *MockCommands) OTPSMSSent(arg0 context.Context, arg1, arg2 string, arg3 *senders.CodeGeneratorInfo) error {
|
func (m *MockCommands) OTPSMSSent(ctx context.Context, sessionID, resourceOwner string, generatorInfo *senders.CodeGeneratorInfo) error {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "OTPSMSSent", arg0, arg1, arg2, arg3)
|
ret := m.ctrl.Call(m, "OTPSMSSent", ctx, sessionID, resourceOwner, generatorInfo)
|
||||||
ret0, _ := ret[0].(error)
|
ret0, _ := ret[0].(error)
|
||||||
return ret0
|
return ret0
|
||||||
}
|
}
|
||||||
|
|
||||||
// OTPSMSSent indicates an expected call of OTPSMSSent.
|
// OTPSMSSent indicates an expected call of OTPSMSSent.
|
||||||
func (mr *MockCommandsMockRecorder) OTPSMSSent(arg0, arg1, arg2, arg3 any) *gomock.Call {
|
func (mr *MockCommandsMockRecorder) OTPSMSSent(ctx, sessionID, resourceOwner, generatorInfo any) *gomock.Call {
|
||||||
mr.mock.ctrl.T.Helper()
|
mr.mock.ctrl.T.Helper()
|
||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OTPSMSSent", reflect.TypeOf((*MockCommands)(nil).OTPSMSSent), arg0, arg1, arg2, arg3)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OTPSMSSent", reflect.TypeOf((*MockCommands)(nil).OTPSMSSent), ctx, sessionID, resourceOwner, generatorInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PasswordChangeSent mocks base method.
|
// PasswordChangeSent mocks base method.
|
||||||
func (m *MockCommands) PasswordChangeSent(arg0 context.Context, arg1, arg2 string) error {
|
func (m *MockCommands) PasswordChangeSent(ctx context.Context, orgID, userID string) error {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "PasswordChangeSent", arg0, arg1, arg2)
|
ret := m.ctrl.Call(m, "PasswordChangeSent", ctx, orgID, userID)
|
||||||
ret0, _ := ret[0].(error)
|
ret0, _ := ret[0].(error)
|
||||||
return ret0
|
return ret0
|
||||||
}
|
}
|
||||||
|
|
||||||
// PasswordChangeSent indicates an expected call of PasswordChangeSent.
|
// PasswordChangeSent indicates an expected call of PasswordChangeSent.
|
||||||
func (mr *MockCommandsMockRecorder) PasswordChangeSent(arg0, arg1, arg2 any) *gomock.Call {
|
func (mr *MockCommandsMockRecorder) PasswordChangeSent(ctx, orgID, userID any) *gomock.Call {
|
||||||
mr.mock.ctrl.T.Helper()
|
mr.mock.ctrl.T.Helper()
|
||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PasswordChangeSent", reflect.TypeOf((*MockCommands)(nil).PasswordChangeSent), arg0, arg1, arg2)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PasswordChangeSent", reflect.TypeOf((*MockCommands)(nil).PasswordChangeSent), ctx, orgID, userID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PasswordCodeSent mocks base method.
|
// PasswordCodeSent mocks base method.
|
||||||
func (m *MockCommands) PasswordCodeSent(arg0 context.Context, arg1, arg2 string, arg3 *senders.CodeGeneratorInfo) error {
|
func (m *MockCommands) PasswordCodeSent(ctx context.Context, orgID, userID string, generatorInfo *senders.CodeGeneratorInfo) error {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "PasswordCodeSent", arg0, arg1, arg2, arg3)
|
ret := m.ctrl.Call(m, "PasswordCodeSent", ctx, orgID, userID, generatorInfo)
|
||||||
ret0, _ := ret[0].(error)
|
ret0, _ := ret[0].(error)
|
||||||
return ret0
|
return ret0
|
||||||
}
|
}
|
||||||
|
|
||||||
// PasswordCodeSent indicates an expected call of PasswordCodeSent.
|
// PasswordCodeSent indicates an expected call of PasswordCodeSent.
|
||||||
func (mr *MockCommandsMockRecorder) PasswordCodeSent(arg0, arg1, arg2, arg3 any) *gomock.Call {
|
func (mr *MockCommandsMockRecorder) PasswordCodeSent(ctx, orgID, userID, generatorInfo any) *gomock.Call {
|
||||||
mr.mock.ctrl.T.Helper()
|
mr.mock.ctrl.T.Helper()
|
||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PasswordCodeSent", reflect.TypeOf((*MockCommands)(nil).PasswordCodeSent), arg0, arg1, arg2, arg3)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PasswordCodeSent", reflect.TypeOf((*MockCommands)(nil).PasswordCodeSent), ctx, orgID, userID, generatorInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UsageNotificationSent mocks base method.
|
// UsageNotificationSent mocks base method.
|
||||||
func (m *MockCommands) UsageNotificationSent(arg0 context.Context, arg1 *quota.NotificationDueEvent) error {
|
func (m *MockCommands) UsageNotificationSent(ctx context.Context, dueEvent *quota.NotificationDueEvent) error {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "UsageNotificationSent", arg0, arg1)
|
ret := m.ctrl.Call(m, "UsageNotificationSent", ctx, dueEvent)
|
||||||
ret0, _ := ret[0].(error)
|
ret0, _ := ret[0].(error)
|
||||||
return ret0
|
return ret0
|
||||||
}
|
}
|
||||||
|
|
||||||
// UsageNotificationSent indicates an expected call of UsageNotificationSent.
|
// UsageNotificationSent indicates an expected call of UsageNotificationSent.
|
||||||
func (mr *MockCommandsMockRecorder) UsageNotificationSent(arg0, arg1 any) *gomock.Call {
|
func (mr *MockCommandsMockRecorder) UsageNotificationSent(ctx, dueEvent any) *gomock.Call {
|
||||||
mr.mock.ctrl.T.Helper()
|
mr.mock.ctrl.T.Helper()
|
||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UsageNotificationSent", reflect.TypeOf((*MockCommands)(nil).UsageNotificationSent), arg0, arg1)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UsageNotificationSent", reflect.TypeOf((*MockCommands)(nil).UsageNotificationSent), ctx, dueEvent)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UserDomainClaimedSent mocks base method.
|
// UserDomainClaimedSent mocks base method.
|
||||||
func (m *MockCommands) UserDomainClaimedSent(arg0 context.Context, arg1, arg2 string) error {
|
func (m *MockCommands) UserDomainClaimedSent(ctx context.Context, orgID, userID string) error {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "UserDomainClaimedSent", arg0, arg1, arg2)
|
ret := m.ctrl.Call(m, "UserDomainClaimedSent", ctx, orgID, userID)
|
||||||
ret0, _ := ret[0].(error)
|
ret0, _ := ret[0].(error)
|
||||||
return ret0
|
return ret0
|
||||||
}
|
}
|
||||||
|
|
||||||
// UserDomainClaimedSent indicates an expected call of UserDomainClaimedSent.
|
// UserDomainClaimedSent indicates an expected call of UserDomainClaimedSent.
|
||||||
func (mr *MockCommandsMockRecorder) UserDomainClaimedSent(arg0, arg1, arg2 any) *gomock.Call {
|
func (mr *MockCommandsMockRecorder) UserDomainClaimedSent(ctx, orgID, userID any) *gomock.Call {
|
||||||
mr.mock.ctrl.T.Helper()
|
mr.mock.ctrl.T.Helper()
|
||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UserDomainClaimedSent", reflect.TypeOf((*MockCommands)(nil).UserDomainClaimedSent), arg0, arg1, arg2)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UserDomainClaimedSent", reflect.TypeOf((*MockCommands)(nil).UserDomainClaimedSent), ctx, orgID, userID)
|
||||||
}
|
}
|
||||||
|
@@ -12,7 +12,6 @@ package mock
|
|||||||
import (
|
import (
|
||||||
context "context"
|
context "context"
|
||||||
reflect "reflect"
|
reflect "reflect"
|
||||||
time "time"
|
|
||||||
|
|
||||||
jose "github.com/go-jose/go-jose/v4"
|
jose "github.com/go-jose/go-jose/v4"
|
||||||
authz "github.com/zitadel/zitadel/internal/api/authz"
|
authz "github.com/zitadel/zitadel/internal/api/authz"
|
||||||
@@ -26,6 +25,7 @@ import (
|
|||||||
type MockQueries struct {
|
type MockQueries struct {
|
||||||
ctrl *gomock.Controller
|
ctrl *gomock.Controller
|
||||||
recorder *MockQueriesMockRecorder
|
recorder *MockQueriesMockRecorder
|
||||||
|
isgomock struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MockQueriesMockRecorder is the mock recorder for MockQueries.
|
// MockQueriesMockRecorder is the mock recorder for MockQueries.
|
||||||
@@ -60,240 +60,225 @@ func (mr *MockQueriesMockRecorder) ActiveInstances() *gomock.Call {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ActiveLabelPolicyByOrg mocks base method.
|
// ActiveLabelPolicyByOrg mocks base method.
|
||||||
func (m *MockQueries) ActiveLabelPolicyByOrg(arg0 context.Context, arg1 string, arg2 bool) (*query.LabelPolicy, error) {
|
func (m *MockQueries) ActiveLabelPolicyByOrg(ctx context.Context, orgID string, withOwnerRemoved bool) (*query.LabelPolicy, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "ActiveLabelPolicyByOrg", arg0, arg1, arg2)
|
ret := m.ctrl.Call(m, "ActiveLabelPolicyByOrg", ctx, orgID, withOwnerRemoved)
|
||||||
ret0, _ := ret[0].(*query.LabelPolicy)
|
ret0, _ := ret[0].(*query.LabelPolicy)
|
||||||
ret1, _ := ret[1].(error)
|
ret1, _ := ret[1].(error)
|
||||||
return ret0, ret1
|
return ret0, ret1
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActiveLabelPolicyByOrg indicates an expected call of ActiveLabelPolicyByOrg.
|
// ActiveLabelPolicyByOrg indicates an expected call of ActiveLabelPolicyByOrg.
|
||||||
func (mr *MockQueriesMockRecorder) ActiveLabelPolicyByOrg(arg0, arg1, arg2 any) *gomock.Call {
|
func (mr *MockQueriesMockRecorder) ActiveLabelPolicyByOrg(ctx, orgID, withOwnerRemoved any) *gomock.Call {
|
||||||
mr.mock.ctrl.T.Helper()
|
mr.mock.ctrl.T.Helper()
|
||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ActiveLabelPolicyByOrg", reflect.TypeOf((*MockQueries)(nil).ActiveLabelPolicyByOrg), arg0, arg1, arg2)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ActiveLabelPolicyByOrg", reflect.TypeOf((*MockQueries)(nil).ActiveLabelPolicyByOrg), ctx, orgID, withOwnerRemoved)
|
||||||
}
|
|
||||||
|
|
||||||
// ActivePrivateSigningKey mocks base method.
|
|
||||||
func (m *MockQueries) ActivePrivateSigningKey(arg0 context.Context, arg1 time.Time) (*query.PrivateKeys, error) {
|
|
||||||
m.ctrl.T.Helper()
|
|
||||||
ret := m.ctrl.Call(m, "ActivePrivateSigningKey", arg0, arg1)
|
|
||||||
ret0, _ := ret[0].(*query.PrivateKeys)
|
|
||||||
ret1, _ := ret[1].(error)
|
|
||||||
return ret0, ret1
|
|
||||||
}
|
|
||||||
|
|
||||||
// ActivePrivateSigningKey indicates an expected call of ActivePrivateSigningKey.
|
|
||||||
func (mr *MockQueriesMockRecorder) ActivePrivateSigningKey(arg0, arg1 any) *gomock.Call {
|
|
||||||
mr.mock.ctrl.T.Helper()
|
|
||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ActivePrivateSigningKey", reflect.TypeOf((*MockQueries)(nil).ActivePrivateSigningKey), arg0, arg1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// CustomTextListByTemplate mocks base method.
|
// CustomTextListByTemplate mocks base method.
|
||||||
func (m *MockQueries) CustomTextListByTemplate(arg0 context.Context, arg1, arg2 string, arg3 bool) (*query.CustomTexts, error) {
|
func (m *MockQueries) CustomTextListByTemplate(ctx context.Context, aggregateID, template string, withOwnerRemoved bool) (*query.CustomTexts, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "CustomTextListByTemplate", arg0, arg1, arg2, arg3)
|
ret := m.ctrl.Call(m, "CustomTextListByTemplate", ctx, aggregateID, template, withOwnerRemoved)
|
||||||
ret0, _ := ret[0].(*query.CustomTexts)
|
ret0, _ := ret[0].(*query.CustomTexts)
|
||||||
ret1, _ := ret[1].(error)
|
ret1, _ := ret[1].(error)
|
||||||
return ret0, ret1
|
return ret0, ret1
|
||||||
}
|
}
|
||||||
|
|
||||||
// CustomTextListByTemplate indicates an expected call of CustomTextListByTemplate.
|
// CustomTextListByTemplate indicates an expected call of CustomTextListByTemplate.
|
||||||
func (mr *MockQueriesMockRecorder) CustomTextListByTemplate(arg0, arg1, arg2, arg3 any) *gomock.Call {
|
func (mr *MockQueriesMockRecorder) CustomTextListByTemplate(ctx, aggregateID, template, withOwnerRemoved any) *gomock.Call {
|
||||||
mr.mock.ctrl.T.Helper()
|
mr.mock.ctrl.T.Helper()
|
||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CustomTextListByTemplate", reflect.TypeOf((*MockQueries)(nil).CustomTextListByTemplate), arg0, arg1, arg2, arg3)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CustomTextListByTemplate", reflect.TypeOf((*MockQueries)(nil).CustomTextListByTemplate), ctx, aggregateID, template, withOwnerRemoved)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetActiveSigningWebKey mocks base method.
|
// GetActiveSigningWebKey mocks base method.
|
||||||
func (m *MockQueries) GetActiveSigningWebKey(arg0 context.Context) (*jose.JSONWebKey, error) {
|
func (m *MockQueries) GetActiveSigningWebKey(ctx context.Context) (*jose.JSONWebKey, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "GetActiveSigningWebKey", arg0)
|
ret := m.ctrl.Call(m, "GetActiveSigningWebKey", ctx)
|
||||||
ret0, _ := ret[0].(*jose.JSONWebKey)
|
ret0, _ := ret[0].(*jose.JSONWebKey)
|
||||||
ret1, _ := ret[1].(error)
|
ret1, _ := ret[1].(error)
|
||||||
return ret0, ret1
|
return ret0, ret1
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetActiveSigningWebKey indicates an expected call of GetActiveSigningWebKey.
|
// GetActiveSigningWebKey indicates an expected call of GetActiveSigningWebKey.
|
||||||
func (mr *MockQueriesMockRecorder) GetActiveSigningWebKey(arg0 any) *gomock.Call {
|
func (mr *MockQueriesMockRecorder) GetActiveSigningWebKey(ctx any) *gomock.Call {
|
||||||
mr.mock.ctrl.T.Helper()
|
mr.mock.ctrl.T.Helper()
|
||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetActiveSigningWebKey", reflect.TypeOf((*MockQueries)(nil).GetActiveSigningWebKey), arg0)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetActiveSigningWebKey", reflect.TypeOf((*MockQueries)(nil).GetActiveSigningWebKey), ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetDefaultLanguage mocks base method.
|
// GetDefaultLanguage mocks base method.
|
||||||
func (m *MockQueries) GetDefaultLanguage(arg0 context.Context) language.Tag {
|
func (m *MockQueries) GetDefaultLanguage(ctx context.Context) language.Tag {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "GetDefaultLanguage", arg0)
|
ret := m.ctrl.Call(m, "GetDefaultLanguage", ctx)
|
||||||
ret0, _ := ret[0].(language.Tag)
|
ret0, _ := ret[0].(language.Tag)
|
||||||
return ret0
|
return ret0
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetDefaultLanguage indicates an expected call of GetDefaultLanguage.
|
// GetDefaultLanguage indicates an expected call of GetDefaultLanguage.
|
||||||
func (mr *MockQueriesMockRecorder) GetDefaultLanguage(arg0 any) *gomock.Call {
|
func (mr *MockQueriesMockRecorder) GetDefaultLanguage(ctx any) *gomock.Call {
|
||||||
mr.mock.ctrl.T.Helper()
|
mr.mock.ctrl.T.Helper()
|
||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDefaultLanguage", reflect.TypeOf((*MockQueries)(nil).GetDefaultLanguage), arg0)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetDefaultLanguage", reflect.TypeOf((*MockQueries)(nil).GetDefaultLanguage), ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetInstanceRestrictions mocks base method.
|
// GetInstanceRestrictions mocks base method.
|
||||||
func (m *MockQueries) GetInstanceRestrictions(arg0 context.Context) (query.Restrictions, error) {
|
func (m *MockQueries) GetInstanceRestrictions(ctx context.Context) (query.Restrictions, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "GetInstanceRestrictions", arg0)
|
ret := m.ctrl.Call(m, "GetInstanceRestrictions", ctx)
|
||||||
ret0, _ := ret[0].(query.Restrictions)
|
ret0, _ := ret[0].(query.Restrictions)
|
||||||
ret1, _ := ret[1].(error)
|
ret1, _ := ret[1].(error)
|
||||||
return ret0, ret1
|
return ret0, ret1
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetInstanceRestrictions indicates an expected call of GetInstanceRestrictions.
|
// GetInstanceRestrictions indicates an expected call of GetInstanceRestrictions.
|
||||||
func (mr *MockQueriesMockRecorder) GetInstanceRestrictions(arg0 any) *gomock.Call {
|
func (mr *MockQueriesMockRecorder) GetInstanceRestrictions(ctx any) *gomock.Call {
|
||||||
mr.mock.ctrl.T.Helper()
|
mr.mock.ctrl.T.Helper()
|
||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetInstanceRestrictions", reflect.TypeOf((*MockQueries)(nil).GetInstanceRestrictions), arg0)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetInstanceRestrictions", reflect.TypeOf((*MockQueries)(nil).GetInstanceRestrictions), ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetNotifyUserByID mocks base method.
|
// GetNotifyUserByID mocks base method.
|
||||||
func (m *MockQueries) GetNotifyUserByID(arg0 context.Context, arg1 bool, arg2 string) (*query.NotifyUser, error) {
|
func (m *MockQueries) GetNotifyUserByID(ctx context.Context, shouldTriggered bool, userID string) (*query.NotifyUser, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "GetNotifyUserByID", arg0, arg1, arg2)
|
ret := m.ctrl.Call(m, "GetNotifyUserByID", ctx, shouldTriggered, userID)
|
||||||
ret0, _ := ret[0].(*query.NotifyUser)
|
ret0, _ := ret[0].(*query.NotifyUser)
|
||||||
ret1, _ := ret[1].(error)
|
ret1, _ := ret[1].(error)
|
||||||
return ret0, ret1
|
return ret0, ret1
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetNotifyUserByID indicates an expected call of GetNotifyUserByID.
|
// GetNotifyUserByID indicates an expected call of GetNotifyUserByID.
|
||||||
func (mr *MockQueriesMockRecorder) GetNotifyUserByID(arg0, arg1, arg2 any) *gomock.Call {
|
func (mr *MockQueriesMockRecorder) GetNotifyUserByID(ctx, shouldTriggered, userID any) *gomock.Call {
|
||||||
mr.mock.ctrl.T.Helper()
|
mr.mock.ctrl.T.Helper()
|
||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNotifyUserByID", reflect.TypeOf((*MockQueries)(nil).GetNotifyUserByID), arg0, arg1, arg2)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNotifyUserByID", reflect.TypeOf((*MockQueries)(nil).GetNotifyUserByID), ctx, shouldTriggered, userID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// InstanceByID mocks base method.
|
// InstanceByID mocks base method.
|
||||||
func (m *MockQueries) InstanceByID(arg0 context.Context, arg1 string) (authz.Instance, error) {
|
func (m *MockQueries) InstanceByID(ctx context.Context, id string) (authz.Instance, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "InstanceByID", arg0, arg1)
|
ret := m.ctrl.Call(m, "InstanceByID", ctx, id)
|
||||||
ret0, _ := ret[0].(authz.Instance)
|
ret0, _ := ret[0].(authz.Instance)
|
||||||
ret1, _ := ret[1].(error)
|
ret1, _ := ret[1].(error)
|
||||||
return ret0, ret1
|
return ret0, ret1
|
||||||
}
|
}
|
||||||
|
|
||||||
// InstanceByID indicates an expected call of InstanceByID.
|
// InstanceByID indicates an expected call of InstanceByID.
|
||||||
func (mr *MockQueriesMockRecorder) InstanceByID(arg0, arg1 any) *gomock.Call {
|
func (mr *MockQueriesMockRecorder) InstanceByID(ctx, id any) *gomock.Call {
|
||||||
mr.mock.ctrl.T.Helper()
|
mr.mock.ctrl.T.Helper()
|
||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InstanceByID", reflect.TypeOf((*MockQueries)(nil).InstanceByID), arg0, arg1)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InstanceByID", reflect.TypeOf((*MockQueries)(nil).InstanceByID), ctx, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MailTemplateByOrg mocks base method.
|
// MailTemplateByOrg mocks base method.
|
||||||
func (m *MockQueries) MailTemplateByOrg(arg0 context.Context, arg1 string, arg2 bool) (*query.MailTemplate, error) {
|
func (m *MockQueries) MailTemplateByOrg(ctx context.Context, orgID string, withOwnerRemoved bool) (*query.MailTemplate, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "MailTemplateByOrg", arg0, arg1, arg2)
|
ret := m.ctrl.Call(m, "MailTemplateByOrg", ctx, orgID, withOwnerRemoved)
|
||||||
ret0, _ := ret[0].(*query.MailTemplate)
|
ret0, _ := ret[0].(*query.MailTemplate)
|
||||||
ret1, _ := ret[1].(error)
|
ret1, _ := ret[1].(error)
|
||||||
return ret0, ret1
|
return ret0, ret1
|
||||||
}
|
}
|
||||||
|
|
||||||
// MailTemplateByOrg indicates an expected call of MailTemplateByOrg.
|
// MailTemplateByOrg indicates an expected call of MailTemplateByOrg.
|
||||||
func (mr *MockQueriesMockRecorder) MailTemplateByOrg(arg0, arg1, arg2 any) *gomock.Call {
|
func (mr *MockQueriesMockRecorder) MailTemplateByOrg(ctx, orgID, withOwnerRemoved any) *gomock.Call {
|
||||||
mr.mock.ctrl.T.Helper()
|
mr.mock.ctrl.T.Helper()
|
||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MailTemplateByOrg", reflect.TypeOf((*MockQueries)(nil).MailTemplateByOrg), arg0, arg1, arg2)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MailTemplateByOrg", reflect.TypeOf((*MockQueries)(nil).MailTemplateByOrg), ctx, orgID, withOwnerRemoved)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NotificationPolicyByOrg mocks base method.
|
// NotificationPolicyByOrg mocks base method.
|
||||||
func (m *MockQueries) NotificationPolicyByOrg(arg0 context.Context, arg1 bool, arg2 string, arg3 bool) (*query.NotificationPolicy, error) {
|
func (m *MockQueries) NotificationPolicyByOrg(ctx context.Context, shouldTriggerBulk bool, orgID string, withOwnerRemoved bool) (*query.NotificationPolicy, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "NotificationPolicyByOrg", arg0, arg1, arg2, arg3)
|
ret := m.ctrl.Call(m, "NotificationPolicyByOrg", ctx, shouldTriggerBulk, orgID, withOwnerRemoved)
|
||||||
ret0, _ := ret[0].(*query.NotificationPolicy)
|
ret0, _ := ret[0].(*query.NotificationPolicy)
|
||||||
ret1, _ := ret[1].(error)
|
ret1, _ := ret[1].(error)
|
||||||
return ret0, ret1
|
return ret0, ret1
|
||||||
}
|
}
|
||||||
|
|
||||||
// NotificationPolicyByOrg indicates an expected call of NotificationPolicyByOrg.
|
// NotificationPolicyByOrg indicates an expected call of NotificationPolicyByOrg.
|
||||||
func (mr *MockQueriesMockRecorder) NotificationPolicyByOrg(arg0, arg1, arg2, arg3 any) *gomock.Call {
|
func (mr *MockQueriesMockRecorder) NotificationPolicyByOrg(ctx, shouldTriggerBulk, orgID, withOwnerRemoved any) *gomock.Call {
|
||||||
mr.mock.ctrl.T.Helper()
|
mr.mock.ctrl.T.Helper()
|
||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NotificationPolicyByOrg", reflect.TypeOf((*MockQueries)(nil).NotificationPolicyByOrg), arg0, arg1, arg2, arg3)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NotificationPolicyByOrg", reflect.TypeOf((*MockQueries)(nil).NotificationPolicyByOrg), ctx, shouldTriggerBulk, orgID, withOwnerRemoved)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NotificationProviderByIDAndType mocks base method.
|
// NotificationProviderByIDAndType mocks base method.
|
||||||
func (m *MockQueries) NotificationProviderByIDAndType(arg0 context.Context, arg1 string, arg2 domain.NotificationProviderType) (*query.DebugNotificationProvider, error) {
|
func (m *MockQueries) NotificationProviderByIDAndType(ctx context.Context, aggID string, providerType domain.NotificationProviderType) (*query.DebugNotificationProvider, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "NotificationProviderByIDAndType", arg0, arg1, arg2)
|
ret := m.ctrl.Call(m, "NotificationProviderByIDAndType", ctx, aggID, providerType)
|
||||||
ret0, _ := ret[0].(*query.DebugNotificationProvider)
|
ret0, _ := ret[0].(*query.DebugNotificationProvider)
|
||||||
ret1, _ := ret[1].(error)
|
ret1, _ := ret[1].(error)
|
||||||
return ret0, ret1
|
return ret0, ret1
|
||||||
}
|
}
|
||||||
|
|
||||||
// NotificationProviderByIDAndType indicates an expected call of NotificationProviderByIDAndType.
|
// NotificationProviderByIDAndType indicates an expected call of NotificationProviderByIDAndType.
|
||||||
func (mr *MockQueriesMockRecorder) NotificationProviderByIDAndType(arg0, arg1, arg2 any) *gomock.Call {
|
func (mr *MockQueriesMockRecorder) NotificationProviderByIDAndType(ctx, aggID, providerType any) *gomock.Call {
|
||||||
mr.mock.ctrl.T.Helper()
|
mr.mock.ctrl.T.Helper()
|
||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NotificationProviderByIDAndType", reflect.TypeOf((*MockQueries)(nil).NotificationProviderByIDAndType), arg0, arg1, arg2)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NotificationProviderByIDAndType", reflect.TypeOf((*MockQueries)(nil).NotificationProviderByIDAndType), ctx, aggID, providerType)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SMSProviderConfigActive mocks base method.
|
// SMSProviderConfigActive mocks base method.
|
||||||
func (m *MockQueries) SMSProviderConfigActive(arg0 context.Context, arg1 string) (*query.SMSConfig, error) {
|
func (m *MockQueries) SMSProviderConfigActive(ctx context.Context, resourceOwner string) (*query.SMSConfig, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "SMSProviderConfigActive", arg0, arg1)
|
ret := m.ctrl.Call(m, "SMSProviderConfigActive", ctx, resourceOwner)
|
||||||
ret0, _ := ret[0].(*query.SMSConfig)
|
ret0, _ := ret[0].(*query.SMSConfig)
|
||||||
ret1, _ := ret[1].(error)
|
ret1, _ := ret[1].(error)
|
||||||
return ret0, ret1
|
return ret0, ret1
|
||||||
}
|
}
|
||||||
|
|
||||||
// SMSProviderConfigActive indicates an expected call of SMSProviderConfigActive.
|
// SMSProviderConfigActive indicates an expected call of SMSProviderConfigActive.
|
||||||
func (mr *MockQueriesMockRecorder) SMSProviderConfigActive(arg0, arg1 any) *gomock.Call {
|
func (mr *MockQueriesMockRecorder) SMSProviderConfigActive(ctx, resourceOwner any) *gomock.Call {
|
||||||
mr.mock.ctrl.T.Helper()
|
mr.mock.ctrl.T.Helper()
|
||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SMSProviderConfigActive", reflect.TypeOf((*MockQueries)(nil).SMSProviderConfigActive), arg0, arg1)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SMSProviderConfigActive", reflect.TypeOf((*MockQueries)(nil).SMSProviderConfigActive), ctx, resourceOwner)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SMTPConfigActive mocks base method.
|
// SMTPConfigActive mocks base method.
|
||||||
func (m *MockQueries) SMTPConfigActive(arg0 context.Context, arg1 string) (*query.SMTPConfig, error) {
|
func (m *MockQueries) SMTPConfigActive(ctx context.Context, resourceOwner string) (*query.SMTPConfig, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "SMTPConfigActive", arg0, arg1)
|
ret := m.ctrl.Call(m, "SMTPConfigActive", ctx, resourceOwner)
|
||||||
ret0, _ := ret[0].(*query.SMTPConfig)
|
ret0, _ := ret[0].(*query.SMTPConfig)
|
||||||
ret1, _ := ret[1].(error)
|
ret1, _ := ret[1].(error)
|
||||||
return ret0, ret1
|
return ret0, ret1
|
||||||
}
|
}
|
||||||
|
|
||||||
// SMTPConfigActive indicates an expected call of SMTPConfigActive.
|
// SMTPConfigActive indicates an expected call of SMTPConfigActive.
|
||||||
func (mr *MockQueriesMockRecorder) SMTPConfigActive(arg0, arg1 any) *gomock.Call {
|
func (mr *MockQueriesMockRecorder) SMTPConfigActive(ctx, resourceOwner any) *gomock.Call {
|
||||||
mr.mock.ctrl.T.Helper()
|
mr.mock.ctrl.T.Helper()
|
||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SMTPConfigActive", reflect.TypeOf((*MockQueries)(nil).SMTPConfigActive), arg0, arg1)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SMTPConfigActive", reflect.TypeOf((*MockQueries)(nil).SMTPConfigActive), ctx, resourceOwner)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SearchInstanceDomains mocks base method.
|
// SearchInstanceDomains mocks base method.
|
||||||
func (m *MockQueries) SearchInstanceDomains(arg0 context.Context, arg1 *query.InstanceDomainSearchQueries) (*query.InstanceDomains, error) {
|
func (m *MockQueries) SearchInstanceDomains(ctx context.Context, queries *query.InstanceDomainSearchQueries) (*query.InstanceDomains, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "SearchInstanceDomains", arg0, arg1)
|
ret := m.ctrl.Call(m, "SearchInstanceDomains", ctx, queries)
|
||||||
ret0, _ := ret[0].(*query.InstanceDomains)
|
ret0, _ := ret[0].(*query.InstanceDomains)
|
||||||
ret1, _ := ret[1].(error)
|
ret1, _ := ret[1].(error)
|
||||||
return ret0, ret1
|
return ret0, ret1
|
||||||
}
|
}
|
||||||
|
|
||||||
// SearchInstanceDomains indicates an expected call of SearchInstanceDomains.
|
// SearchInstanceDomains indicates an expected call of SearchInstanceDomains.
|
||||||
func (mr *MockQueriesMockRecorder) SearchInstanceDomains(arg0, arg1 any) *gomock.Call {
|
func (mr *MockQueriesMockRecorder) SearchInstanceDomains(ctx, queries any) *gomock.Call {
|
||||||
mr.mock.ctrl.T.Helper()
|
mr.mock.ctrl.T.Helper()
|
||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SearchInstanceDomains", reflect.TypeOf((*MockQueries)(nil).SearchInstanceDomains), arg0, arg1)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SearchInstanceDomains", reflect.TypeOf((*MockQueries)(nil).SearchInstanceDomains), ctx, queries)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SearchMilestones mocks base method.
|
// SearchMilestones mocks base method.
|
||||||
func (m *MockQueries) SearchMilestones(arg0 context.Context, arg1 []string, arg2 *query.MilestonesSearchQueries) (*query.Milestones, error) {
|
func (m *MockQueries) SearchMilestones(ctx context.Context, instanceIDs []string, queries *query.MilestonesSearchQueries) (*query.Milestones, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "SearchMilestones", arg0, arg1, arg2)
|
ret := m.ctrl.Call(m, "SearchMilestones", ctx, instanceIDs, queries)
|
||||||
ret0, _ := ret[0].(*query.Milestones)
|
ret0, _ := ret[0].(*query.Milestones)
|
||||||
ret1, _ := ret[1].(error)
|
ret1, _ := ret[1].(error)
|
||||||
return ret0, ret1
|
return ret0, ret1
|
||||||
}
|
}
|
||||||
|
|
||||||
// SearchMilestones indicates an expected call of SearchMilestones.
|
// SearchMilestones indicates an expected call of SearchMilestones.
|
||||||
func (mr *MockQueriesMockRecorder) SearchMilestones(arg0, arg1, arg2 any) *gomock.Call {
|
func (mr *MockQueriesMockRecorder) SearchMilestones(ctx, instanceIDs, queries any) *gomock.Call {
|
||||||
mr.mock.ctrl.T.Helper()
|
mr.mock.ctrl.T.Helper()
|
||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SearchMilestones", reflect.TypeOf((*MockQueries)(nil).SearchMilestones), arg0, arg1, arg2)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SearchMilestones", reflect.TypeOf((*MockQueries)(nil).SearchMilestones), ctx, instanceIDs, queries)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SessionByID mocks base method.
|
// SessionByID mocks base method.
|
||||||
func (m *MockQueries) SessionByID(arg0 context.Context, arg1 bool, arg2, arg3 string, arg4 domain.PermissionCheck) (*query.Session, error) {
|
func (m *MockQueries) SessionByID(ctx context.Context, shouldTriggerBulk bool, id, sessionToken string, check domain.PermissionCheck) (*query.Session, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "SessionByID", arg0, arg1, arg2, arg3, arg4)
|
ret := m.ctrl.Call(m, "SessionByID", ctx, shouldTriggerBulk, id, sessionToken, check)
|
||||||
ret0, _ := ret[0].(*query.Session)
|
ret0, _ := ret[0].(*query.Session)
|
||||||
ret1, _ := ret[1].(error)
|
ret1, _ := ret[1].(error)
|
||||||
return ret0, ret1
|
return ret0, ret1
|
||||||
}
|
}
|
||||||
|
|
||||||
// SessionByID indicates an expected call of SessionByID.
|
// SessionByID indicates an expected call of SessionByID.
|
||||||
func (mr *MockQueriesMockRecorder) SessionByID(arg0, arg1, arg2, arg3, arg4 any) *gomock.Call {
|
func (mr *MockQueriesMockRecorder) SessionByID(ctx, shouldTriggerBulk, id, sessionToken, check any) *gomock.Call {
|
||||||
mr.mock.ctrl.T.Helper()
|
mr.mock.ctrl.T.Helper()
|
||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SessionByID", reflect.TypeOf((*MockQueries)(nil).SessionByID), arg0, arg1, arg2, arg3, arg4)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SessionByID", reflect.TypeOf((*MockQueries)(nil).SessionByID), ctx, shouldTriggerBulk, id, sessionToken, check)
|
||||||
}
|
}
|
||||||
|
@@ -22,6 +22,7 @@ import (
|
|||||||
type MockQueue struct {
|
type MockQueue struct {
|
||||||
ctrl *gomock.Controller
|
ctrl *gomock.Controller
|
||||||
recorder *MockQueueMockRecorder
|
recorder *MockQueueMockRecorder
|
||||||
|
isgomock struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MockQueueMockRecorder is the mock recorder for MockQueue.
|
// MockQueueMockRecorder is the mock recorder for MockQueue.
|
||||||
@@ -42,10 +43,10 @@ func (m *MockQueue) EXPECT() *MockQueueMockRecorder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Insert mocks base method.
|
// Insert mocks base method.
|
||||||
func (m *MockQueue) Insert(arg0 context.Context, arg1 river.JobArgs, arg2 ...queue.InsertOpt) error {
|
func (m *MockQueue) Insert(ctx context.Context, args river.JobArgs, opts ...queue.InsertOpt) error {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
varargs := []any{arg0, arg1}
|
varargs := []any{ctx, args}
|
||||||
for _, a := range arg2 {
|
for _, a := range opts {
|
||||||
varargs = append(varargs, a)
|
varargs = append(varargs, a)
|
||||||
}
|
}
|
||||||
ret := m.ctrl.Call(m, "Insert", varargs...)
|
ret := m.ctrl.Call(m, "Insert", varargs...)
|
||||||
@@ -54,8 +55,8 @@ func (m *MockQueue) Insert(arg0 context.Context, arg1 river.JobArgs, arg2 ...que
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Insert indicates an expected call of Insert.
|
// Insert indicates an expected call of Insert.
|
||||||
func (mr *MockQueueMockRecorder) Insert(arg0, arg1 any, arg2 ...any) *gomock.Call {
|
func (mr *MockQueueMockRecorder) Insert(ctx, args any, opts ...any) *gomock.Call {
|
||||||
mr.mock.ctrl.T.Helper()
|
mr.mock.ctrl.T.Helper()
|
||||||
varargs := append([]any{arg0, arg1}, arg2...)
|
varargs := append([]any{ctx, args}, opts...)
|
||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Insert", reflect.TypeOf((*MockQueue)(nil).Insert), varargs...)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Insert", reflect.TypeOf((*MockQueue)(nil).Insert), varargs...)
|
||||||
}
|
}
|
||||||
|
@@ -2,7 +2,6 @@ package handlers
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/go-jose/go-jose/v4"
|
"github.com/go-jose/go-jose/v4"
|
||||||
"golang.org/x/text/language"
|
"golang.org/x/text/language"
|
||||||
@@ -30,7 +29,6 @@ type Queries interface {
|
|||||||
GetInstanceRestrictions(ctx context.Context) (restrictions query.Restrictions, err error)
|
GetInstanceRestrictions(ctx context.Context) (restrictions query.Restrictions, err error)
|
||||||
InstanceByID(ctx context.Context, id string) (instance authz.Instance, err error)
|
InstanceByID(ctx context.Context, id string) (instance authz.Instance, err error)
|
||||||
GetActiveSigningWebKey(ctx context.Context) (*jose.JSONWebKey, error)
|
GetActiveSigningWebKey(ctx context.Context) (*jose.JSONWebKey, error)
|
||||||
ActivePrivateSigningKey(ctx context.Context, t time.Time) (keys *query.PrivateKeys, err error)
|
|
||||||
|
|
||||||
ActiveInstances() []string
|
ActiveInstances() []string
|
||||||
}
|
}
|
||||||
|
@@ -14,7 +14,6 @@ type InstanceFeatures struct {
|
|||||||
UserSchema FeatureSource[bool]
|
UserSchema FeatureSource[bool]
|
||||||
TokenExchange FeatureSource[bool]
|
TokenExchange FeatureSource[bool]
|
||||||
ImprovedPerformance FeatureSource[[]feature.ImprovedPerformanceType]
|
ImprovedPerformance FeatureSource[[]feature.ImprovedPerformanceType]
|
||||||
WebKey FeatureSource[bool]
|
|
||||||
DebugOIDCParentError FeatureSource[bool]
|
DebugOIDCParentError FeatureSource[bool]
|
||||||
OIDCSingleV1SessionTermination FeatureSource[bool]
|
OIDCSingleV1SessionTermination FeatureSource[bool]
|
||||||
DisableUserTokenEvent FeatureSource[bool]
|
DisableUserTokenEvent FeatureSource[bool]
|
||||||
|
@@ -67,7 +67,6 @@ func (m *InstanceFeaturesReadModel) Query() *eventstore.SearchQueryBuilder {
|
|||||||
feature_v2.InstanceUserSchemaEventType,
|
feature_v2.InstanceUserSchemaEventType,
|
||||||
feature_v2.InstanceTokenExchangeEventType,
|
feature_v2.InstanceTokenExchangeEventType,
|
||||||
feature_v2.InstanceImprovedPerformanceEventType,
|
feature_v2.InstanceImprovedPerformanceEventType,
|
||||||
feature_v2.InstanceWebKeyEventType,
|
|
||||||
feature_v2.InstanceDebugOIDCParentErrorEventType,
|
feature_v2.InstanceDebugOIDCParentErrorEventType,
|
||||||
feature_v2.InstanceOIDCSingleV1SessionTerminationEventType,
|
feature_v2.InstanceOIDCSingleV1SessionTerminationEventType,
|
||||||
feature_v2.InstanceDisableUserTokenEvent,
|
feature_v2.InstanceDisableUserTokenEvent,
|
||||||
@@ -121,8 +120,6 @@ func reduceInstanceFeatureSet[T any](features *InstanceFeatures, event *feature_
|
|||||||
features.TokenExchange.set(level, event.Value)
|
features.TokenExchange.set(level, event.Value)
|
||||||
case feature.KeyImprovedPerformance:
|
case feature.KeyImprovedPerformance:
|
||||||
features.ImprovedPerformance.set(level, event.Value)
|
features.ImprovedPerformance.set(level, event.Value)
|
||||||
case feature.KeyWebKey:
|
|
||||||
features.WebKey.set(level, event.Value)
|
|
||||||
case feature.KeyDebugOIDCParentError:
|
case feature.KeyDebugOIDCParentError:
|
||||||
features.DebugOIDCParentError.set(level, event.Value)
|
features.DebugOIDCParentError.set(level, event.Value)
|
||||||
case feature.KeyOIDCSingleV1SessionTermination:
|
case feature.KeyOIDCSingleV1SessionTermination:
|
||||||
|
@@ -1,20 +1,10 @@
|
|||||||
package query
|
package query
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"crypto/rsa"
|
|
||||||
"database/sql"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
sq "github.com/Masterminds/squirrel"
|
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/api/authz"
|
|
||||||
"github.com/zitadel/zitadel/internal/crypto"
|
"github.com/zitadel/zitadel/internal/crypto"
|
||||||
"github.com/zitadel/zitadel/internal/eventstore"
|
|
||||||
"github.com/zitadel/zitadel/internal/query/projection"
|
"github.com/zitadel/zitadel/internal/query/projection"
|
||||||
"github.com/zitadel/zitadel/internal/repository/keypair"
|
|
||||||
"github.com/zitadel/zitadel/internal/telemetry/tracing"
|
|
||||||
"github.com/zitadel/zitadel/internal/zerrors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Key interface {
|
type Key interface {
|
||||||
@@ -36,11 +26,6 @@ type PublicKey interface {
|
|||||||
Key() interface{}
|
Key() interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
type PrivateKeys struct {
|
|
||||||
SearchResponse
|
|
||||||
Keys []PrivateKey
|
|
||||||
}
|
|
||||||
|
|
||||||
type PublicKeys struct {
|
type PublicKeys struct {
|
||||||
SearchResponse
|
SearchResponse
|
||||||
Keys []PublicKey
|
Keys []PublicKey
|
||||||
@@ -72,34 +57,6 @@ func (k *key) Sequence() uint64 {
|
|||||||
return k.sequence
|
return k.sequence
|
||||||
}
|
}
|
||||||
|
|
||||||
type privateKey struct {
|
|
||||||
key
|
|
||||||
expiry time.Time
|
|
||||||
privateKey *crypto.CryptoValue
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *privateKey) Expiry() time.Time {
|
|
||||||
return k.expiry
|
|
||||||
}
|
|
||||||
|
|
||||||
func (k *privateKey) Key() *crypto.CryptoValue {
|
|
||||||
return k.privateKey
|
|
||||||
}
|
|
||||||
|
|
||||||
type rsaPublicKey struct {
|
|
||||||
key
|
|
||||||
expiry time.Time
|
|
||||||
publicKey *rsa.PublicKey
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *rsaPublicKey) Expiry() time.Time {
|
|
||||||
return r.expiry
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *rsaPublicKey) Key() interface{} {
|
|
||||||
return r.publicKey
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
keyTable = table{
|
keyTable = table{
|
||||||
name: projection.KeyProjectionTable,
|
name: projection.KeyProjectionTable,
|
||||||
@@ -157,277 +114,3 @@ var (
|
|||||||
table: keyPrivateTable,
|
table: keyPrivateTable,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
keyPublicTable = table{
|
|
||||||
name: projection.KeyPublicTable,
|
|
||||||
instanceIDCol: projection.KeyPrivateColumnInstanceID,
|
|
||||||
}
|
|
||||||
KeyPublicColID = Column{
|
|
||||||
name: projection.KeyPublicColumnID,
|
|
||||||
table: keyPublicTable,
|
|
||||||
}
|
|
||||||
KeyPublicColExpiry = Column{
|
|
||||||
name: projection.KeyPublicColumnExpiry,
|
|
||||||
table: keyPublicTable,
|
|
||||||
}
|
|
||||||
KeyPublicColKey = Column{
|
|
||||||
name: projection.KeyPublicColumnKey,
|
|
||||||
table: keyPublicTable,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
func (q *Queries) ActivePublicKeys(ctx context.Context, t time.Time) (keys *PublicKeys, err error) {
|
|
||||||
ctx, span := tracing.NewSpan(ctx)
|
|
||||||
defer func() { span.EndWithError(err) }()
|
|
||||||
|
|
||||||
query, scan := preparePublicKeysQuery()
|
|
||||||
if t.IsZero() {
|
|
||||||
t = time.Now()
|
|
||||||
}
|
|
||||||
stmt, args, err := query.Where(
|
|
||||||
sq.And{
|
|
||||||
sq.Eq{KeyColInstanceID.identifier(): authz.GetInstance(ctx).InstanceID()},
|
|
||||||
sq.Gt{KeyPublicColExpiry.identifier(): t},
|
|
||||||
}).ToSql()
|
|
||||||
if err != nil {
|
|
||||||
return nil, zerrors.ThrowInternal(err, "QUERY-SDFfg", "Errors.Query.SQLStatement")
|
|
||||||
}
|
|
||||||
|
|
||||||
err = q.client.QueryContext(ctx, func(rows *sql.Rows) error {
|
|
||||||
keys, err = scan(rows)
|
|
||||||
return err
|
|
||||||
}, stmt, args...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, zerrors.ThrowInternal(err, "QUERY-Sghn4", "Errors.Internal")
|
|
||||||
}
|
|
||||||
|
|
||||||
keys.State, err = q.latestState(ctx, keyTable)
|
|
||||||
if !zerrors.IsNotFound(err) {
|
|
||||||
return keys, err
|
|
||||||
}
|
|
||||||
return keys, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (q *Queries) ActivePrivateSigningKey(ctx context.Context, t time.Time) (keys *PrivateKeys, err error) {
|
|
||||||
ctx, span := tracing.NewSpan(ctx)
|
|
||||||
defer func() { span.EndWithError(err) }()
|
|
||||||
|
|
||||||
stmt, scan := preparePrivateKeysQuery()
|
|
||||||
if t.IsZero() {
|
|
||||||
t = time.Now()
|
|
||||||
}
|
|
||||||
query, args, err := stmt.Where(
|
|
||||||
sq.And{
|
|
||||||
sq.Eq{
|
|
||||||
KeyColUse.identifier(): crypto.KeyUsageSigning,
|
|
||||||
KeyColInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
|
|
||||||
},
|
|
||||||
sq.Gt{KeyPrivateColExpiry.identifier(): t},
|
|
||||||
}).OrderBy(KeyPrivateColExpiry.identifier()).ToSql()
|
|
||||||
if err != nil {
|
|
||||||
return nil, zerrors.ThrowInternal(err, "QUERY-SDff2", "Errors.Query.SQLStatement")
|
|
||||||
}
|
|
||||||
|
|
||||||
err = q.client.QueryContext(ctx, func(rows *sql.Rows) error {
|
|
||||||
keys, err = scan(rows)
|
|
||||||
return err
|
|
||||||
}, query, args...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, zerrors.ThrowInternal(err, "QUERY-WRFG4", "Errors.Internal")
|
|
||||||
}
|
|
||||||
keys.State, err = q.latestState(ctx, keyTable)
|
|
||||||
if !zerrors.IsNotFound(err) {
|
|
||||||
return keys, err
|
|
||||||
}
|
|
||||||
return keys, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func preparePublicKeysQuery() (sq.SelectBuilder, func(*sql.Rows) (*PublicKeys, error)) {
|
|
||||||
return sq.Select(
|
|
||||||
KeyColID.identifier(),
|
|
||||||
KeyColCreationDate.identifier(),
|
|
||||||
KeyColChangeDate.identifier(),
|
|
||||||
KeyColSequence.identifier(),
|
|
||||||
KeyColResourceOwner.identifier(),
|
|
||||||
KeyColAlgorithm.identifier(),
|
|
||||||
KeyColUse.identifier(),
|
|
||||||
KeyPublicColExpiry.identifier(),
|
|
||||||
KeyPublicColKey.identifier(),
|
|
||||||
countColumn.identifier(),
|
|
||||||
).From(keyTable.identifier()).
|
|
||||||
LeftJoin(join(KeyPublicColID, KeyColID)).
|
|
||||||
PlaceholderFormat(sq.Dollar),
|
|
||||||
func(rows *sql.Rows) (*PublicKeys, error) {
|
|
||||||
keys := make([]PublicKey, 0)
|
|
||||||
var count uint64
|
|
||||||
for rows.Next() {
|
|
||||||
k := new(rsaPublicKey)
|
|
||||||
var keyValue []byte
|
|
||||||
err := rows.Scan(
|
|
||||||
&k.id,
|
|
||||||
&k.creationDate,
|
|
||||||
&k.changeDate,
|
|
||||||
&k.sequence,
|
|
||||||
&k.resourceOwner,
|
|
||||||
&k.algorithm,
|
|
||||||
&k.use,
|
|
||||||
&k.expiry,
|
|
||||||
&keyValue,
|
|
||||||
&count,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
k.publicKey, err = crypto.BytesToPublicKey(keyValue)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
keys = append(keys, k)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := rows.Close(); err != nil {
|
|
||||||
return nil, zerrors.ThrowInternal(err, "QUERY-rKd6k", "Errors.Query.CloseRows")
|
|
||||||
}
|
|
||||||
|
|
||||||
return &PublicKeys{
|
|
||||||
Keys: keys,
|
|
||||||
SearchResponse: SearchResponse{
|
|
||||||
Count: count,
|
|
||||||
},
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func preparePrivateKeysQuery() (sq.SelectBuilder, func(*sql.Rows) (*PrivateKeys, error)) {
|
|
||||||
return sq.Select(
|
|
||||||
KeyColID.identifier(),
|
|
||||||
KeyColCreationDate.identifier(),
|
|
||||||
KeyColChangeDate.identifier(),
|
|
||||||
KeyColSequence.identifier(),
|
|
||||||
KeyColResourceOwner.identifier(),
|
|
||||||
KeyColAlgorithm.identifier(),
|
|
||||||
KeyColUse.identifier(),
|
|
||||||
KeyPrivateColExpiry.identifier(),
|
|
||||||
KeyPrivateColKey.identifier(),
|
|
||||||
countColumn.identifier(),
|
|
||||||
).From(keyTable.identifier()).
|
|
||||||
LeftJoin(join(KeyPrivateColID, KeyColID)).
|
|
||||||
PlaceholderFormat(sq.Dollar),
|
|
||||||
func(rows *sql.Rows) (*PrivateKeys, error) {
|
|
||||||
keys := make([]PrivateKey, 0)
|
|
||||||
var count uint64
|
|
||||||
for rows.Next() {
|
|
||||||
k := new(privateKey)
|
|
||||||
err := rows.Scan(
|
|
||||||
&k.id,
|
|
||||||
&k.creationDate,
|
|
||||||
&k.changeDate,
|
|
||||||
&k.sequence,
|
|
||||||
&k.resourceOwner,
|
|
||||||
&k.algorithm,
|
|
||||||
&k.use,
|
|
||||||
&k.expiry,
|
|
||||||
&k.privateKey,
|
|
||||||
&count,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
keys = append(keys, k)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := rows.Close(); err != nil {
|
|
||||||
return nil, zerrors.ThrowInternal(err, "QUERY-rKd6k", "Errors.Query.CloseRows")
|
|
||||||
}
|
|
||||||
|
|
||||||
return &PrivateKeys{
|
|
||||||
Keys: keys,
|
|
||||||
SearchResponse: SearchResponse{
|
|
||||||
Count: count,
|
|
||||||
},
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type PublicKeyReadModel struct {
|
|
||||||
eventstore.ReadModel
|
|
||||||
|
|
||||||
Algorithm string
|
|
||||||
Key *crypto.CryptoValue
|
|
||||||
Expiry time.Time
|
|
||||||
Usage crypto.KeyUsage
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewPublicKeyReadModel(keyID, resourceOwner string) *PublicKeyReadModel {
|
|
||||||
return &PublicKeyReadModel{
|
|
||||||
ReadModel: eventstore.ReadModel{
|
|
||||||
AggregateID: keyID,
|
|
||||||
ResourceOwner: resourceOwner,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (wm *PublicKeyReadModel) AppendEvents(events ...eventstore.Event) {
|
|
||||||
wm.ReadModel.AppendEvents(events...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (wm *PublicKeyReadModel) Reduce() error {
|
|
||||||
for _, event := range wm.Events {
|
|
||||||
switch e := event.(type) {
|
|
||||||
case *keypair.AddedEvent:
|
|
||||||
wm.Algorithm = e.Algorithm
|
|
||||||
wm.Key = e.PublicKey.Key
|
|
||||||
wm.Expiry = e.PublicKey.Expiry
|
|
||||||
wm.Usage = e.Usage
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return wm.ReadModel.Reduce()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (wm *PublicKeyReadModel) Query() *eventstore.SearchQueryBuilder {
|
|
||||||
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent).
|
|
||||||
AwaitOpenTransactions().
|
|
||||||
ResourceOwner(wm.ResourceOwner).
|
|
||||||
AddQuery().
|
|
||||||
AggregateTypes(keypair.AggregateType).
|
|
||||||
AggregateIDs(wm.AggregateID).
|
|
||||||
EventTypes(keypair.AddedEventType).
|
|
||||||
Builder()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (q *Queries) GetPublicKeyByID(ctx context.Context, keyID string) (_ PublicKey, err error) {
|
|
||||||
ctx, span := tracing.NewSpan(ctx)
|
|
||||||
defer func() { span.EndWithError(err) }()
|
|
||||||
|
|
||||||
model := NewPublicKeyReadModel(keyID, authz.GetInstance(ctx).InstanceID())
|
|
||||||
if err := q.eventstore.FilterToQueryReducer(ctx, model); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if model.Algorithm == "" || model.Key == nil {
|
|
||||||
return nil, zerrors.ThrowNotFound(err, "QUERY-Ahf7x", "Errors.Key.NotFound")
|
|
||||||
}
|
|
||||||
keyValue, err := crypto.Decrypt(model.Key, q.keyEncryptionAlgorithm)
|
|
||||||
if err != nil {
|
|
||||||
return nil, zerrors.ThrowInternal(err, "QUERY-Ie4oh", "Errors.Internal")
|
|
||||||
}
|
|
||||||
publicKey, err := crypto.BytesToPublicKey(keyValue)
|
|
||||||
if err != nil {
|
|
||||||
return nil, zerrors.ThrowInternal(err, "QUERY-Kai2Z", "Errors.Internal")
|
|
||||||
}
|
|
||||||
|
|
||||||
return &rsaPublicKey{
|
|
||||||
key: key{
|
|
||||||
id: model.AggregateID,
|
|
||||||
creationDate: model.CreationDate,
|
|
||||||
changeDate: model.ChangeDate,
|
|
||||||
sequence: model.ProcessedSequence,
|
|
||||||
resourceOwner: model.ResourceOwner,
|
|
||||||
algorithm: model.Algorithm,
|
|
||||||
use: model.Usage,
|
|
||||||
},
|
|
||||||
expiry: model.Expiry,
|
|
||||||
publicKey: publicKey,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
@@ -1,453 +0,0 @@
|
|||||||
package query
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"crypto/rsa"
|
|
||||||
"database/sql"
|
|
||||||
"database/sql/driver"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"math/big"
|
|
||||||
"regexp"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
"go.uber.org/mock/gomock"
|
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/api/authz"
|
|
||||||
"github.com/zitadel/zitadel/internal/crypto"
|
|
||||||
"github.com/zitadel/zitadel/internal/eventstore"
|
|
||||||
key_repo "github.com/zitadel/zitadel/internal/repository/keypair"
|
|
||||||
"github.com/zitadel/zitadel/internal/zerrors"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
preparePublicKeysStmt = `SELECT projections.keys4.id,` +
|
|
||||||
` projections.keys4.creation_date,` +
|
|
||||||
` projections.keys4.change_date,` +
|
|
||||||
` projections.keys4.sequence,` +
|
|
||||||
` projections.keys4.resource_owner,` +
|
|
||||||
` projections.keys4.algorithm,` +
|
|
||||||
` projections.keys4.use,` +
|
|
||||||
` projections.keys4_public.expiry,` +
|
|
||||||
` projections.keys4_public.key,` +
|
|
||||||
` COUNT(*) OVER ()` +
|
|
||||||
` FROM projections.keys4` +
|
|
||||||
` LEFT JOIN projections.keys4_public ON projections.keys4.id = projections.keys4_public.id AND projections.keys4.instance_id = projections.keys4_public.instance_id`
|
|
||||||
preparePublicKeysCols = []string{
|
|
||||||
"id",
|
|
||||||
"creation_date",
|
|
||||||
"change_date",
|
|
||||||
"sequence",
|
|
||||||
"resource_owner",
|
|
||||||
"algorithm",
|
|
||||||
"use",
|
|
||||||
"expiry",
|
|
||||||
"key",
|
|
||||||
"count",
|
|
||||||
}
|
|
||||||
|
|
||||||
preparePrivateKeysStmt = `SELECT projections.keys4.id,` +
|
|
||||||
` projections.keys4.creation_date,` +
|
|
||||||
` projections.keys4.change_date,` +
|
|
||||||
` projections.keys4.sequence,` +
|
|
||||||
` projections.keys4.resource_owner,` +
|
|
||||||
` projections.keys4.algorithm,` +
|
|
||||||
` projections.keys4.use,` +
|
|
||||||
` projections.keys4_private.expiry,` +
|
|
||||||
` projections.keys4_private.key,` +
|
|
||||||
` COUNT(*) OVER ()` +
|
|
||||||
` FROM projections.keys4` +
|
|
||||||
` LEFT JOIN projections.keys4_private ON projections.keys4.id = projections.keys4_private.id AND projections.keys4.instance_id = projections.keys4_private.instance_id`
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_KeyPrepares(t *testing.T) {
|
|
||||||
type want struct {
|
|
||||||
sqlExpectations sqlExpectation
|
|
||||||
err checkErr
|
|
||||||
}
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
prepare interface{}
|
|
||||||
want want
|
|
||||||
object interface{}
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "preparePublicKeysQuery no result",
|
|
||||||
prepare: preparePublicKeysQuery,
|
|
||||||
want: want{
|
|
||||||
sqlExpectations: mockQueries(
|
|
||||||
regexp.QuoteMeta(preparePublicKeysStmt),
|
|
||||||
nil,
|
|
||||||
nil,
|
|
||||||
),
|
|
||||||
err: func(err error) (error, bool) {
|
|
||||||
if !zerrors.IsNotFound(err) {
|
|
||||||
return fmt.Errorf("err should be zitadel.NotFoundError got: %w", err), false
|
|
||||||
}
|
|
||||||
return nil, true
|
|
||||||
},
|
|
||||||
},
|
|
||||||
object: &PublicKeys{Keys: []PublicKey{}},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "preparePublicKeysQuery found",
|
|
||||||
prepare: preparePublicKeysQuery,
|
|
||||||
want: want{
|
|
||||||
sqlExpectations: mockQueries(
|
|
||||||
regexp.QuoteMeta(preparePublicKeysStmt),
|
|
||||||
preparePublicKeysCols,
|
|
||||||
[][]driver.Value{
|
|
||||||
{
|
|
||||||
"key-id",
|
|
||||||
testNow,
|
|
||||||
testNow,
|
|
||||||
uint64(20211109),
|
|
||||||
"ro",
|
|
||||||
"RS256",
|
|
||||||
0,
|
|
||||||
testNow,
|
|
||||||
[]byte("-----BEGIN RSA PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsvX9P58JFxEs5C+L+H7W\nduFSWL5EPzber7C2m94klrSV6q0bAcrYQnGwFOlveThsY200hRbadKaKjHD7qIKH\nDEe0IY2PSRht33Jye52AwhkRw+M3xuQH/7R8LydnsNFk2KHpr5X2SBv42e37LjkE\nslKSaMRgJW+v0KZ30piY8QsdFRKKaVg5/Ajt1YToM1YVsdHXJ3vmXFMtypLdxwUD\ndIaLEX6pFUkU75KSuEQ/E2luT61Q3ta9kOWm9+0zvi7OMcbdekJT7mzcVnh93R1c\n13ZhQCLbh9A7si8jKFtaMWevjayrvqQABEcTN9N4Hoxcyg6l4neZtRDk75OMYcqm\nDQIDAQAB\n-----END RSA PUBLIC KEY-----\n"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
),
|
|
||||||
},
|
|
||||||
object: &PublicKeys{
|
|
||||||
SearchResponse: SearchResponse{
|
|
||||||
Count: 1,
|
|
||||||
},
|
|
||||||
Keys: []PublicKey{
|
|
||||||
&rsaPublicKey{
|
|
||||||
key: key{
|
|
||||||
id: "key-id",
|
|
||||||
creationDate: testNow,
|
|
||||||
changeDate: testNow,
|
|
||||||
sequence: 20211109,
|
|
||||||
resourceOwner: "ro",
|
|
||||||
algorithm: "RS256",
|
|
||||||
use: crypto.KeyUsageSigning,
|
|
||||||
},
|
|
||||||
expiry: testNow,
|
|
||||||
publicKey: &rsa.PublicKey{
|
|
||||||
E: 65537,
|
|
||||||
N: fromBase16("b2f5fd3f9f0917112ce42f8bf87ed676e15258be443f36deafb0b69bde2496b495eaad1b01cad84271b014e96f79386c636d348516da74a68a8c70fba882870c47b4218d8f49186ddf72727b9d80c21911c3e337c6e407ffb47c2f2767b0d164d8a1e9af95f6481bf8d9edfb2e3904b2529268c460256fafd0a677d29898f10b1d15128a695839fc08edd584e8335615b1d1d7277be65c532dca92ddc7050374868b117ea9154914ef9292b8443f13696e4fad50ded6bd90e5a6f7ed33be2ece31c6dd7a4253ee6cdc56787ddd1d5cd776614022db87d03bb22f23285b5a3167af8dacabbea40004471337d3781e8c5cca0ea5e27799b510e4ef938c61caa60d"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "preparePublicKeysQuery sql err",
|
|
||||||
prepare: preparePublicKeysQuery,
|
|
||||||
want: want{
|
|
||||||
sqlExpectations: mockQueryErr(
|
|
||||||
regexp.QuoteMeta(preparePublicKeysStmt),
|
|
||||||
sql.ErrConnDone,
|
|
||||||
),
|
|
||||||
err: func(err error) (error, bool) {
|
|
||||||
if !errors.Is(err, sql.ErrConnDone) {
|
|
||||||
return fmt.Errorf("err should be sql.ErrConnDone got: %w", err), false
|
|
||||||
}
|
|
||||||
return nil, true
|
|
||||||
},
|
|
||||||
},
|
|
||||||
object: (*PublicKeys)(nil),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "preparePrivateKeysQuery no result",
|
|
||||||
prepare: preparePrivateKeysQuery,
|
|
||||||
want: want{
|
|
||||||
sqlExpectations: mockQueries(
|
|
||||||
regexp.QuoteMeta(preparePrivateKeysStmt),
|
|
||||||
nil,
|
|
||||||
nil,
|
|
||||||
),
|
|
||||||
err: func(err error) (error, bool) {
|
|
||||||
if !zerrors.IsNotFound(err) {
|
|
||||||
return fmt.Errorf("err should be zitadel.NotFoundError got: %w", err), false
|
|
||||||
}
|
|
||||||
return nil, true
|
|
||||||
},
|
|
||||||
},
|
|
||||||
object: &PrivateKeys{Keys: []PrivateKey{}},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "preparePrivateKeysQuery found",
|
|
||||||
prepare: preparePrivateKeysQuery,
|
|
||||||
want: want{
|
|
||||||
sqlExpectations: mockQueries(
|
|
||||||
regexp.QuoteMeta(preparePrivateKeysStmt),
|
|
||||||
preparePublicKeysCols,
|
|
||||||
[][]driver.Value{
|
|
||||||
{
|
|
||||||
"key-id",
|
|
||||||
testNow,
|
|
||||||
testNow,
|
|
||||||
uint64(20211109),
|
|
||||||
"ro",
|
|
||||||
"RS256",
|
|
||||||
0,
|
|
||||||
testNow,
|
|
||||||
[]byte(`{"Algorithm": "enc", "Crypted": "cHJpdmF0ZUtleQ==", "CryptoType": 0, "KeyID": "id"}`),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
),
|
|
||||||
},
|
|
||||||
object: &PrivateKeys{
|
|
||||||
SearchResponse: SearchResponse{
|
|
||||||
Count: 1,
|
|
||||||
},
|
|
||||||
Keys: []PrivateKey{
|
|
||||||
&privateKey{
|
|
||||||
key: key{
|
|
||||||
id: "key-id",
|
|
||||||
creationDate: testNow,
|
|
||||||
changeDate: testNow,
|
|
||||||
sequence: 20211109,
|
|
||||||
resourceOwner: "ro",
|
|
||||||
algorithm: "RS256",
|
|
||||||
use: crypto.KeyUsageSigning,
|
|
||||||
},
|
|
||||||
expiry: testNow,
|
|
||||||
privateKey: &crypto.CryptoValue{
|
|
||||||
CryptoType: crypto.TypeEncryption,
|
|
||||||
Algorithm: "enc",
|
|
||||||
KeyID: "id",
|
|
||||||
Crypted: []byte("privateKey"),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "preparePrivateKeysQuery sql err",
|
|
||||||
prepare: preparePrivateKeysQuery,
|
|
||||||
want: want{
|
|
||||||
sqlExpectations: mockQueryErr(
|
|
||||||
regexp.QuoteMeta(preparePrivateKeysStmt),
|
|
||||||
sql.ErrConnDone,
|
|
||||||
),
|
|
||||||
err: func(err error) (error, bool) {
|
|
||||||
if !errors.Is(err, sql.ErrConnDone) {
|
|
||||||
return fmt.Errorf("err should be sql.ErrConnDone got: %w", err), false
|
|
||||||
}
|
|
||||||
return nil, true
|
|
||||||
},
|
|
||||||
},
|
|
||||||
object: (*PrivateKeys)(nil),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
assertPrepare(t, tt.prepare, tt.object, tt.want.sqlExpectations, tt.want.err)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func fromBase16(base16 string) *big.Int {
|
|
||||||
i, ok := new(big.Int).SetString(base16, 16)
|
|
||||||
if !ok {
|
|
||||||
panic("bad number: " + base16)
|
|
||||||
}
|
|
||||||
return i
|
|
||||||
}
|
|
||||||
|
|
||||||
const pubKey = `-----BEGIN PUBLIC KEY-----
|
|
||||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs38btwb3c7r0tMaQpGvB
|
|
||||||
mY+mPwMU/LpfuPoC0k2t4RsKp0fv40SMl50CRrHgk395wch8PMPYbl3+8TtYAJuy
|
|
||||||
rFALIj3Ff1UcKIk0hOH5DDsfh7/q2wFuncTmS6bifYo8CfSq2vDGnM7nZnEvxY/M
|
|
||||||
fSydZdcmIqlkUpfQmtzExw9+tSe5Dxq6gn5JtlGgLgZGt69r5iMMrTEGhhVAXzNu
|
|
||||||
MZbmlCoBru+rC8ITlTX/0V1ZcsSbL8tYWhthyu9x6yjo1bH85wiVI4gs0MhU8f2a
|
|
||||||
+kjL/KGZbR14Ua2eo6tonBZLC5DHWM2TkYXgRCDPufjcgmzN0Lm91E4P8KvBcvly
|
|
||||||
6QIDAQAB
|
|
||||||
-----END PUBLIC KEY-----
|
|
||||||
`
|
|
||||||
|
|
||||||
func TestQueries_GetPublicKeyByID(t *testing.T) {
|
|
||||||
now := time.Now()
|
|
||||||
future := now.Add(time.Hour)
|
|
||||||
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
eventstore func(*testing.T) *eventstore.Eventstore
|
|
||||||
encryption func(*testing.T) *crypto.MockEncryptionAlgorithm
|
|
||||||
want *rsaPublicKey
|
|
||||||
wantErr error
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "filter error",
|
|
||||||
eventstore: expectEventstore(
|
|
||||||
expectFilterError(io.ErrClosedPipe),
|
|
||||||
),
|
|
||||||
wantErr: io.ErrClosedPipe,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "not found error",
|
|
||||||
eventstore: expectEventstore(
|
|
||||||
expectFilter(),
|
|
||||||
),
|
|
||||||
wantErr: zerrors.ThrowNotFound(nil, "QUERY-Ahf7x", "Errors.Key.NotFound"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "decrypt error",
|
|
||||||
eventstore: expectEventstore(
|
|
||||||
expectFilter(
|
|
||||||
eventFromEventPusher(key_repo.NewAddedEvent(context.Background(),
|
|
||||||
&eventstore.Aggregate{
|
|
||||||
ID: "keyID",
|
|
||||||
Type: key_repo.AggregateType,
|
|
||||||
ResourceOwner: "instanceID",
|
|
||||||
InstanceID: "instanceID",
|
|
||||||
Version: key_repo.AggregateVersion,
|
|
||||||
},
|
|
||||||
crypto.KeyUsageSigning, "alg",
|
|
||||||
&crypto.CryptoValue{
|
|
||||||
CryptoType: crypto.TypeEncryption,
|
|
||||||
Algorithm: "alg",
|
|
||||||
KeyID: "keyID",
|
|
||||||
Crypted: []byte("private"),
|
|
||||||
},
|
|
||||||
&crypto.CryptoValue{
|
|
||||||
CryptoType: crypto.TypeEncryption,
|
|
||||||
Algorithm: "alg",
|
|
||||||
KeyID: "keyID",
|
|
||||||
Crypted: []byte("public"),
|
|
||||||
},
|
|
||||||
future,
|
|
||||||
future,
|
|
||||||
)),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
encryption: func(t *testing.T) *crypto.MockEncryptionAlgorithm {
|
|
||||||
encryption := crypto.NewMockEncryptionAlgorithm(gomock.NewController(t))
|
|
||||||
expect := encryption.EXPECT()
|
|
||||||
expect.Algorithm().Return("alg")
|
|
||||||
expect.DecryptionKeyIDs().Return([]string{})
|
|
||||||
return encryption
|
|
||||||
},
|
|
||||||
wantErr: zerrors.ThrowInternal(nil, "QUERY-Ie4oh", "Errors.Internal"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "parse error",
|
|
||||||
eventstore: expectEventstore(
|
|
||||||
expectFilter(
|
|
||||||
eventFromEventPusher(key_repo.NewAddedEvent(context.Background(),
|
|
||||||
&eventstore.Aggregate{
|
|
||||||
ID: "keyID",
|
|
||||||
Type: key_repo.AggregateType,
|
|
||||||
ResourceOwner: "instanceID",
|
|
||||||
InstanceID: "instanceID",
|
|
||||||
Version: key_repo.AggregateVersion,
|
|
||||||
},
|
|
||||||
crypto.KeyUsageSigning, "alg",
|
|
||||||
&crypto.CryptoValue{
|
|
||||||
CryptoType: crypto.TypeEncryption,
|
|
||||||
Algorithm: "alg",
|
|
||||||
KeyID: "keyID",
|
|
||||||
Crypted: []byte("private"),
|
|
||||||
},
|
|
||||||
&crypto.CryptoValue{
|
|
||||||
CryptoType: crypto.TypeEncryption,
|
|
||||||
Algorithm: "alg",
|
|
||||||
KeyID: "keyID",
|
|
||||||
Crypted: []byte("public"),
|
|
||||||
},
|
|
||||||
future,
|
|
||||||
future,
|
|
||||||
)),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
encryption: func(t *testing.T) *crypto.MockEncryptionAlgorithm {
|
|
||||||
encryption := crypto.NewMockEncryptionAlgorithm(gomock.NewController(t))
|
|
||||||
expect := encryption.EXPECT()
|
|
||||||
expect.Algorithm().Return("alg")
|
|
||||||
expect.DecryptionKeyIDs().Return([]string{"keyID"})
|
|
||||||
expect.Decrypt([]byte("public"), "keyID").Return([]byte("foo"), nil)
|
|
||||||
return encryption
|
|
||||||
},
|
|
||||||
wantErr: zerrors.ThrowInternal(nil, "QUERY-Kai2Z", "Errors.Internal"),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "success",
|
|
||||||
eventstore: expectEventstore(
|
|
||||||
expectFilter(
|
|
||||||
eventFromEventPusher(key_repo.NewAddedEvent(context.Background(),
|
|
||||||
&eventstore.Aggregate{
|
|
||||||
ID: "keyID",
|
|
||||||
Type: key_repo.AggregateType,
|
|
||||||
ResourceOwner: "instanceID",
|
|
||||||
InstanceID: "instanceID",
|
|
||||||
Version: key_repo.AggregateVersion,
|
|
||||||
},
|
|
||||||
crypto.KeyUsageSigning, "alg",
|
|
||||||
&crypto.CryptoValue{
|
|
||||||
CryptoType: crypto.TypeEncryption,
|
|
||||||
Algorithm: "alg",
|
|
||||||
KeyID: "keyID",
|
|
||||||
Crypted: []byte("private"),
|
|
||||||
},
|
|
||||||
&crypto.CryptoValue{
|
|
||||||
CryptoType: crypto.TypeEncryption,
|
|
||||||
Algorithm: "alg",
|
|
||||||
KeyID: "keyID",
|
|
||||||
Crypted: []byte("public"),
|
|
||||||
},
|
|
||||||
future,
|
|
||||||
future,
|
|
||||||
)),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
encryption: func(t *testing.T) *crypto.MockEncryptionAlgorithm {
|
|
||||||
encryption := crypto.NewMockEncryptionAlgorithm(gomock.NewController(t))
|
|
||||||
expect := encryption.EXPECT()
|
|
||||||
expect.Algorithm().Return("alg")
|
|
||||||
expect.DecryptionKeyIDs().Return([]string{"keyID"})
|
|
||||||
expect.Decrypt([]byte("public"), "keyID").Return([]byte(pubKey), nil)
|
|
||||||
return encryption
|
|
||||||
},
|
|
||||||
want: &rsaPublicKey{
|
|
||||||
key: key{
|
|
||||||
id: "keyID",
|
|
||||||
resourceOwner: "instanceID",
|
|
||||||
algorithm: "alg",
|
|
||||||
use: crypto.KeyUsageSigning,
|
|
||||||
},
|
|
||||||
expiry: future,
|
|
||||||
publicKey: func() *rsa.PublicKey {
|
|
||||||
publicKey, err := crypto.BytesToPublicKey([]byte(pubKey))
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return publicKey
|
|
||||||
}(),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
q := &Queries{
|
|
||||||
eventstore: tt.eventstore(t),
|
|
||||||
}
|
|
||||||
if tt.encryption != nil {
|
|
||||||
q.keyEncryptionAlgorithm = tt.encryption(t)
|
|
||||||
}
|
|
||||||
ctx := authz.NewMockContext("instanceID", "orgID", "loginClient")
|
|
||||||
key, err := q.GetPublicKeyByID(ctx, "keyID")
|
|
||||||
if tt.wantErr != nil {
|
|
||||||
require.ErrorIs(t, err, tt.wantErr)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.NotNil(t, key)
|
|
||||||
|
|
||||||
got := key.(*rsaPublicKey)
|
|
||||||
assert.WithinDuration(t, tt.want.expiry, got.expiry, time.Second)
|
|
||||||
tt.want.expiry = time.Time{}
|
|
||||||
got.expiry = time.Time{}
|
|
||||||
assert.Equal(t, tt.want, got)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
@@ -80,10 +80,6 @@ func (*instanceFeatureProjection) Reducers() []handler.AggregateReducer {
|
|||||||
Event: feature_v2.InstanceImprovedPerformanceEventType,
|
Event: feature_v2.InstanceImprovedPerformanceEventType,
|
||||||
Reduce: reduceInstanceSetFeature[[]feature.ImprovedPerformanceType],
|
Reduce: reduceInstanceSetFeature[[]feature.ImprovedPerformanceType],
|
||||||
},
|
},
|
||||||
{
|
|
||||||
Event: feature_v2.InstanceWebKeyEventType,
|
|
||||||
Reduce: reduceInstanceSetFeature[bool],
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
Event: feature_v2.InstanceDebugOIDCParentErrorEventType,
|
Event: feature_v2.InstanceDebugOIDCParentErrorEventType,
|
||||||
Reduce: reduceInstanceSetFeature[bool],
|
Reduce: reduceInstanceSetFeature[bool],
|
||||||
|
@@ -24,7 +24,6 @@ func init() {
|
|||||||
eventstore.RegisterFilterEventMapper(AggregateType, InstanceUserSchemaEventType, eventstore.GenericEventMapper[SetEvent[bool]])
|
eventstore.RegisterFilterEventMapper(AggregateType, InstanceUserSchemaEventType, eventstore.GenericEventMapper[SetEvent[bool]])
|
||||||
eventstore.RegisterFilterEventMapper(AggregateType, InstanceTokenExchangeEventType, eventstore.GenericEventMapper[SetEvent[bool]])
|
eventstore.RegisterFilterEventMapper(AggregateType, InstanceTokenExchangeEventType, eventstore.GenericEventMapper[SetEvent[bool]])
|
||||||
eventstore.RegisterFilterEventMapper(AggregateType, InstanceImprovedPerformanceEventType, eventstore.GenericEventMapper[SetEvent[[]feature.ImprovedPerformanceType]])
|
eventstore.RegisterFilterEventMapper(AggregateType, InstanceImprovedPerformanceEventType, eventstore.GenericEventMapper[SetEvent[[]feature.ImprovedPerformanceType]])
|
||||||
eventstore.RegisterFilterEventMapper(AggregateType, InstanceWebKeyEventType, eventstore.GenericEventMapper[SetEvent[bool]])
|
|
||||||
eventstore.RegisterFilterEventMapper(AggregateType, InstanceDebugOIDCParentErrorEventType, eventstore.GenericEventMapper[SetEvent[bool]])
|
eventstore.RegisterFilterEventMapper(AggregateType, InstanceDebugOIDCParentErrorEventType, eventstore.GenericEventMapper[SetEvent[bool]])
|
||||||
eventstore.RegisterFilterEventMapper(AggregateType, InstanceOIDCSingleV1SessionTerminationEventType, eventstore.GenericEventMapper[SetEvent[bool]])
|
eventstore.RegisterFilterEventMapper(AggregateType, InstanceOIDCSingleV1SessionTerminationEventType, eventstore.GenericEventMapper[SetEvent[bool]])
|
||||||
eventstore.RegisterFilterEventMapper(AggregateType, InstanceDisableUserTokenEvent, eventstore.GenericEventMapper[SetEvent[bool]])
|
eventstore.RegisterFilterEventMapper(AggregateType, InstanceDisableUserTokenEvent, eventstore.GenericEventMapper[SetEvent[bool]])
|
||||||
|
@@ -29,7 +29,6 @@ var (
|
|||||||
InstanceUserSchemaEventType = setEventTypeFromFeature(feature.LevelInstance, feature.KeyUserSchema)
|
InstanceUserSchemaEventType = setEventTypeFromFeature(feature.LevelInstance, feature.KeyUserSchema)
|
||||||
InstanceTokenExchangeEventType = setEventTypeFromFeature(feature.LevelInstance, feature.KeyTokenExchange)
|
InstanceTokenExchangeEventType = setEventTypeFromFeature(feature.LevelInstance, feature.KeyTokenExchange)
|
||||||
InstanceImprovedPerformanceEventType = setEventTypeFromFeature(feature.LevelInstance, feature.KeyImprovedPerformance)
|
InstanceImprovedPerformanceEventType = setEventTypeFromFeature(feature.LevelInstance, feature.KeyImprovedPerformance)
|
||||||
InstanceWebKeyEventType = setEventTypeFromFeature(feature.LevelInstance, feature.KeyWebKey)
|
|
||||||
InstanceDebugOIDCParentErrorEventType = setEventTypeFromFeature(feature.LevelInstance, feature.KeyDebugOIDCParentError)
|
InstanceDebugOIDCParentErrorEventType = setEventTypeFromFeature(feature.LevelInstance, feature.KeyDebugOIDCParentError)
|
||||||
InstanceOIDCSingleV1SessionTerminationEventType = setEventTypeFromFeature(feature.LevelInstance, feature.KeyOIDCSingleV1SessionTermination)
|
InstanceOIDCSingleV1SessionTerminationEventType = setEventTypeFromFeature(feature.LevelInstance, feature.KeyOIDCSingleV1SessionTermination)
|
||||||
InstanceDisableUserTokenEvent = setEventTypeFromFeature(feature.LevelInstance, feature.KeyDisableUserTokenEvent)
|
InstanceDisableUserTokenEvent = setEventTypeFromFeature(feature.LevelInstance, feature.KeyDisableUserTokenEvent)
|
||||||
|
@@ -11,8 +11,8 @@ import "zitadel/feature/v2/feature.proto";
|
|||||||
option go_package = "github.com/zitadel/zitadel/pkg/grpc/feature/v2;feature";
|
option go_package = "github.com/zitadel/zitadel/pkg/grpc/feature/v2;feature";
|
||||||
|
|
||||||
message SetInstanceFeaturesRequest{
|
message SetInstanceFeaturesRequest{
|
||||||
reserved 3, 6;
|
reserved 3, 6, 8;
|
||||||
reserved "oidc_legacy_introspection", "actions";
|
reserved "oidc_legacy_introspection", "actions", "web_key";
|
||||||
optional bool login_default_org = 1 [
|
optional bool login_default_org = 1 [
|
||||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||||
example: "true";
|
example: "true";
|
||||||
@@ -49,13 +49,6 @@ message SetInstanceFeaturesRequest{
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
optional bool web_key = 8 [
|
|
||||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
||||||
example: "true";
|
|
||||||
description: "Enable the webkey/v3alpha API. The first time this feature is enabled, web keys are generated and activated.";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
optional bool debug_oidc_parent_error = 9 [
|
optional bool debug_oidc_parent_error = 9 [
|
||||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||||
example: "true";
|
example: "true";
|
||||||
@@ -125,8 +118,8 @@ message GetInstanceFeaturesRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message GetInstanceFeaturesResponse {
|
message GetInstanceFeaturesResponse {
|
||||||
reserved 4, 7;
|
reserved 4, 7, 9;
|
||||||
reserved "oidc_legacy_introspection", "actions";
|
reserved "oidc_legacy_introspection", "actions", "web_key";
|
||||||
zitadel.object.v2.Details details = 1;
|
zitadel.object.v2.Details details = 1;
|
||||||
FeatureFlag login_default_org = 2 [
|
FeatureFlag login_default_org = 2 [
|
||||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||||
@@ -163,13 +156,6 @@ message GetInstanceFeaturesResponse {
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
FeatureFlag web_key = 9 [
|
|
||||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
||||||
example: "true";
|
|
||||||
description: "Enable the webkey/v3alpha API. The first time this feature is enabled, web keys are generated and activated.";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
FeatureFlag debug_oidc_parent_error = 10 [
|
FeatureFlag debug_oidc_parent_error = 10 [
|
||||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||||
example: "true";
|
example: "true";
|
||||||
|
@@ -11,8 +11,8 @@ import "zitadel/feature/v2beta/feature.proto";
|
|||||||
option go_package = "github.com/zitadel/zitadel/pkg/grpc/feature/v2beta;feature";
|
option go_package = "github.com/zitadel/zitadel/pkg/grpc/feature/v2beta;feature";
|
||||||
|
|
||||||
message SetInstanceFeaturesRequest{
|
message SetInstanceFeaturesRequest{
|
||||||
reserved 3, 6;
|
reserved 3, 6, 8;
|
||||||
reserved "oidc_legacy_introspection", "actions";
|
reserved "oidc_legacy_introspection", "actions", "web_key";
|
||||||
optional bool login_default_org = 1 [
|
optional bool login_default_org = 1 [
|
||||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||||
example: "true";
|
example: "true";
|
||||||
@@ -49,13 +49,6 @@ message SetInstanceFeaturesRequest{
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
optional bool web_key = 8 [
|
|
||||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
||||||
example: "true";
|
|
||||||
description: "Enable the webkey/v3alpha API. The first time this feature is enabled, web keys are generated and activated.";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
optional bool debug_oidc_parent_error = 9 [
|
optional bool debug_oidc_parent_error = 9 [
|
||||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||||
example: "true";
|
example: "true";
|
||||||
@@ -91,8 +84,8 @@ message GetInstanceFeaturesRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message GetInstanceFeaturesResponse {
|
message GetInstanceFeaturesResponse {
|
||||||
reserved 4, 7;
|
reserved 4, 7, 9;
|
||||||
reserved "oidc_legacy_introspection", "actions";
|
reserved "oidc_legacy_introspection", "actions", "web_key";
|
||||||
zitadel.object.v2beta.Details details = 1;
|
zitadel.object.v2beta.Details details = 1;
|
||||||
FeatureFlag login_default_org = 2 [
|
FeatureFlag login_default_org = 2 [
|
||||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||||
@@ -129,13 +122,6 @@ message GetInstanceFeaturesResponse {
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
FeatureFlag web_key = 9 [
|
|
||||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
|
||||||
example: "true";
|
|
||||||
description: "Enable the webkey/v3alpha API. The first time this feature is enabled, web keys are generated and activated.";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
FeatureFlag debug_oidc_parent_error = 10 [
|
FeatureFlag debug_oidc_parent_error = 10 [
|
||||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||||
example: "true";
|
example: "true";
|
||||||
|
Reference in New Issue
Block a user