Promote Account Console v3 to default and deprecate v2 (#25852)

Closes #19663

Signed-off-by: Jon Koops <jonkoops@gmail.com>
Co-authored-by: Martin Bartoš <mabartos@redhat.com>
This commit is contained in:
Jon Koops 2024-01-11 19:42:10 +01:00 committed by GitHub
parent 692aeee17d
commit 5eb7363ddd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 18 additions and 13 deletions

View file

@ -48,8 +48,8 @@ public class Profile {
AUTHORIZATION("Authorization Service", Type.DEFAULT), AUTHORIZATION("Authorization Service", Type.DEFAULT),
ACCOUNT_API("Account Management REST API", Type.DEFAULT), ACCOUNT_API("Account Management REST API", Type.DEFAULT),
ACCOUNT2("Account Management Console 2", Type.DEFAULT, Feature.ACCOUNT_API), ACCOUNT2("Account Management Console 2", Type.DEPRECATED, Feature.ACCOUNT_API),
ACCOUNT3("Account Management Console 3", Type.PREVIEW, Feature.ACCOUNT_API), ACCOUNT3("Account Management Console 3", Type.DEFAULT, Feature.ACCOUNT_API),
ADMIN_FINE_GRAINED_AUTHZ("Fine-Grained Admin Permissions", Type.PREVIEW), ADMIN_FINE_GRAINED_AUTHZ("Fine-Grained Admin Permissions", Type.PREVIEW),

View file

@ -71,7 +71,7 @@ public class ProfileTest {
Profile.Feature.TRANSIENT_USERS, Profile.Feature.TRANSIENT_USERS,
Profile.Feature.DPOP, Profile.Feature.DPOP,
Profile.Feature.FIPS, Profile.Feature.FIPS,
Profile.Feature.ACCOUNT3, Profile.Feature.ACCOUNT2,
Profile.Feature.ADMIN_FINE_GRAINED_AUTHZ, Profile.Feature.ADMIN_FINE_GRAINED_AUTHZ,
Profile.Feature.DYNAMIC_SCOPES, Profile.Feature.DYNAMIC_SCOPES,
Profile.Feature.DOCKER, Profile.Feature.DOCKER,
@ -89,7 +89,7 @@ public class ProfileTest {
disabledFeatures.add(Profile.Feature.KERBEROS); disabledFeatures.add(Profile.Feature.KERBEROS);
} }
assertEquals(profile.getDisabledFeatures(), disabledFeatures); assertEquals(profile.getDisabledFeatures(), disabledFeatures);
assertEquals(profile.getPreviewFeatures(), Profile.Feature.ACCOUNT3, Profile.Feature.ADMIN_FINE_GRAINED_AUTHZ, Profile.Feature.MULTI_SITE, Profile.Feature.RECOVERY_CODES, Profile.Feature.SCRIPTS, Profile.Feature.TOKEN_EXCHANGE, Profile.Feature.CLIENT_SECRET_ROTATION, Profile.Feature.UPDATE_EMAIL, Profile.Feature.DPOP); assertEquals(profile.getPreviewFeatures(), Profile.Feature.ADMIN_FINE_GRAINED_AUTHZ, Profile.Feature.MULTI_SITE, Profile.Feature.RECOVERY_CODES, Profile.Feature.SCRIPTS, Profile.Feature.TOKEN_EXCHANGE, Profile.Feature.CLIENT_SECRET_ROTATION, Profile.Feature.UPDATE_EMAIL, Profile.Feature.DPOP);
} }
@Test @Test
@ -100,14 +100,14 @@ public class ProfileTest {
try { try {
Profile.configure(new PropertiesProfileConfigResolver(properties)); Profile.configure(new PropertiesProfileConfigResolver(properties));
} catch (ProfileException e) { } catch (ProfileException e) {
Assert.assertEquals("Feature account2 depends on disabled feature account-api", e.getMessage()); Assert.assertEquals("Feature account3 depends on disabled feature account-api", e.getMessage());
} }
} }
@Test @Test
public void checkSuccessIfFeatureDisabledWithDisabledDependencies() { public void checkSuccessIfFeatureDisabledWithDisabledDependencies() {
Properties properties = new Properties(); Properties properties = new Properties();
properties.setProperty("keycloak.profile.feature.account2", "disabled"); properties.setProperty("keycloak.profile.feature.account3", "disabled");
properties.setProperty("keycloak.profile.feature.account_api", "disabled"); properties.setProperty("keycloak.profile.feature.account_api", "disabled");
Profile.configure(new PropertiesProfileConfigResolver(properties)); Profile.configure(new PropertiesProfileConfigResolver(properties));
Assert.assertFalse(Profile.isFeatureEnabled(Profile.Feature.ACCOUNT2)); Assert.assertFalse(Profile.isFeatureEnabled(Profile.Feature.ACCOUNT2));

View file

@ -6,7 +6,7 @@
<link rel="icon" type="image/svg+xml" href="./favicon.svg" /> <link rel="icon" type="image/svg+xml" href="./favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Web site to manage keycloak" /> <meta name="description" content="Web site to manage keycloak" />
<title>Keycloak account console</title> <title>Account Management</title>
<style> <style>
body { body {
margin: 0; margin: 0;

View file

@ -89,10 +89,10 @@
<value xml:space="preserve"><![CDATA[<link rel="icon" type="${properties.favIconType!"image/svg+xml"}" href="${resourceUrl}${properties.favIcon!"/favicon.svg"}" />]]></value> <value xml:space="preserve"><![CDATA[<link rel="icon" type="${properties.favIconType!"image/svg+xml"}" href="${resourceUrl}${properties.favIcon!"/favicon.svg"}" />]]></value>
</replacement> </replacement>
<replacement> <replacement>
<token><![CDATA[<title>Keycloak account console</title>]]></token> <token><![CDATA[<title>Account Management</title>]]></token>
<value xml:space="preserve"> <value xml:space="preserve">
<![CDATA[ <![CDATA[
<title>${properties.title!"Keycloak account console"}</title> <title>${properties.title!"Account Management"}</title>
<script type="importmap"> <script type="importmap">
{ {
"imports": { "imports": {

View file

@ -23,6 +23,7 @@ const ReferrerLink = () => {
return searchParams.has("referrer_uri") ? ( return searchParams.has("referrer_uri") ? (
<Button <Button
data-testid="referrer-link"
component="a" component="a"
href={searchParams.get("referrer_uri")!.replace("_hash_", "#")} href={searchParams.get("referrer_uri")!.replace("_hash_", "#")}
variant="link" variant="link"

View file

@ -10,7 +10,7 @@ export default class Masthead extends CommonElements {
#userDrpDwnKebab = "#user-dropdown-kebab"; #userDrpDwnKebab = "#user-dropdown-kebab";
#globalAlerts = "global-alerts"; #globalAlerts = "global-alerts";
#documentationLink = "#link"; #documentationLink = "#link";
#backToAdminConsoleLink = "#landingReferrerLink"; #backToAdminConsoleLink = "referrer-link";
#userDrpdwnItem = ".pf-c-dropdown__menu-item"; #userDrpdwnItem = ".pf-c-dropdown__menu-item";
#getAlertsContainer() { #getAlertsContainer() {
@ -70,7 +70,7 @@ export default class Masthead extends CommonElements {
} }
goToAdminConsole() { goToAdminConsole() {
cy.get(this.#backToAdminConsoleLink).click({ force: true }); cy.findByTestId(this.#backToAdminConsoleLink).click({ force: true });
return this; return this;
} }

View file

@ -28,7 +28,7 @@ import static org.keycloak.quarkus.runtime.cli.command.AbstractStartCommand.OPTI
@LegacyStore @LegacyStore
public class FeaturesDistTest { public class FeaturesDistTest {
private static final String PREVIEW_FEATURES_EXPECTED_LOG = "Preview features enabled: account3:v1, admin-fine-grained-authz:v1, client-secret-rotation:v1, dpop:v1, multi-site:v1, recovery-codes:v1, scripts:v1, token-exchange:v1, update-email:v1"; private static final String PREVIEW_FEATURES_EXPECTED_LOG = "Preview features enabled: admin-fine-grained-authz:v1, client-secret-rotation:v1, dpop:v1, multi-site:v1, recovery-codes:v1, scripts:v1, token-exchange:v1, update-email:v1";
@Test @Test
public void testEnableOnBuild(KeycloakDistribution dist) { public void testEnableOnBuild(KeycloakDistribution dist) {

View file

@ -56,7 +56,7 @@ public class ServerInfoTest extends AbstractKeycloakTest {
assertNotNull(info.getThemes()); assertNotNull(info.getThemes());
assertNotNull(info.getThemes().get("account")); assertNotNull(info.getThemes().get("account"));
Assert.assertNames(info.getThemes().get("account"), "base", "keycloak.v2", "custom-account-provider"); Assert.assertNames(info.getThemes().get("account"), "base", "keycloak.v3", "custom-account-provider");
Assert.assertNames(info.getThemes().get("admin"), "base", "keycloak.v2"); Assert.assertNames(info.getThemes().get("admin"), "base", "keycloak.v2");
Assert.assertNames(info.getThemes().get("email"), "base", "keycloak"); Assert.assertNames(info.getThemes().get("email"), "base", "keycloak");
Assert.assertNames(info.getThemes().get("login"), "address", "base", "environment-agnostic", "keycloak"); Assert.assertNames(info.getThemes().get("login"), "address", "base", "environment-agnostic", "keycloak");

View file

@ -34,6 +34,7 @@ import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.RequiredActionProviderSimpleRepresentation; import org.keycloak.representations.idm.RequiredActionProviderSimpleRepresentation;
import org.keycloak.testsuite.AbstractAuthTest; import org.keycloak.testsuite.AbstractAuthTest;
import org.keycloak.testsuite.arquillian.annotation.EnableFeature; import org.keycloak.testsuite.arquillian.annotation.EnableFeature;
import org.keycloak.testsuite.arquillian.annotation.DisableFeature;
import org.keycloak.testsuite.page.AbstractPatternFlyAlert; import org.keycloak.testsuite.page.AbstractPatternFlyAlert;
import org.keycloak.testsuite.ui.account2.page.SigningInPage; import org.keycloak.testsuite.ui.account2.page.SigningInPage;
import org.keycloak.testsuite.ui.account2.page.utils.SigningInPageUtils; import org.keycloak.testsuite.ui.account2.page.utils.SigningInPageUtils;
@ -56,6 +57,9 @@ import static org.keycloak.models.AuthenticationExecutionModel.Requirement.REQUI
import static org.keycloak.testsuite.util.BrowserDriverUtil.isDriverFirefox; import static org.keycloak.testsuite.util.BrowserDriverUtil.isDriverFirefox;
import static org.keycloak.testsuite.util.WaitUtils.waitForPageToLoad; import static org.keycloak.testsuite.util.WaitUtils.waitForPageToLoad;
// Enable ACCOUNT3 feature once https://github.com/keycloak/keycloak/issues/26080 is resolved
@EnableFeature(value = Profile.Feature.ACCOUNT2, skipRestart = true)
@DisableFeature(value = Profile.Feature.ACCOUNT3, skipRestart = true)
public abstract class AbstractWebAuthnAccountTest extends AbstractAuthTest implements UseVirtualAuthenticators { public abstract class AbstractWebAuthnAccountTest extends AbstractAuthTest implements UseVirtualAuthenticators {
@Page @Page