KEYCLOAK-16502 Migration of DELETE_ACCOUNT role
This commit is contained in:
parent
6a6dba5d6e
commit
cd9e01af90
12 changed files with 54 additions and 20 deletions
|
@ -1,9 +1,26 @@
|
|||
/*
|
||||
* Copyright 2020 Red Hat, Inc. and/or its affiliates
|
||||
* and other contributors as indicated by the @author tags.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.keycloak.migration.migrators;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import org.keycloak.migration.ModelVersion;
|
||||
import org.keycloak.models.AccountRoles;
|
||||
import org.keycloak.models.Constants;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RequiredActionProviderModel;
|
||||
|
||||
|
@ -26,14 +43,13 @@ public class MigrateTo12_0_0 implements Migration {
|
|||
@Override
|
||||
public void migrate(KeycloakSession session) {
|
||||
session.realms()
|
||||
.getRealms()
|
||||
.stream()
|
||||
.map(realm -> realm.getClientByClientId("account"))
|
||||
.getRealmsStream()
|
||||
.map(realm -> realm.getClientByClientId(Constants.ACCOUNT_MANAGEMENT_CLIENT_ID))
|
||||
.filter(client -> Objects.isNull(client.getRole(AccountRoles.DELETE_ACCOUNT)))
|
||||
.forEach(client -> client.addRole(AccountRoles.DELETE_ACCOUNT)
|
||||
.setDescription("${role_"+AccountRoles.DELETE_ACCOUNT+"}"));
|
||||
|
||||
session.realms().getRealms().stream().filter(realm -> Objects.isNull(realm.getRequiredActionProviderByAlias("delete_account"))).forEach(realm -> realm.addRequiredActionProvider(deleteAccount));
|
||||
session.realms().getRealmsStream().filter(realm -> Objects.isNull(realm.getRequiredActionProviderByAlias("delete_account"))).forEach(realm -> realm.addRequiredActionProvider(deleteAccount));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -84,7 +84,10 @@ public class DefaultRequiredActions {
|
|||
}
|
||||
|
||||
addUpdateLocaleAction(realm);
|
||||
addDeleteAccountAction(realm);
|
||||
}
|
||||
|
||||
public static void addDeleteAccountAction(RealmModel realm) {
|
||||
if (realm.getRequiredActionProviderByAlias("delete_account") == null) {
|
||||
RequiredActionProviderModel deleteAccount = new RequiredActionProviderModel();
|
||||
deleteAccount.setEnabled(false);
|
||||
|
|
|
@ -62,6 +62,7 @@ import java.util.Set;
|
|||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import org.keycloak.models.AccountRoles;
|
||||
|
||||
/**
|
||||
* Set of helper methods, which are useful in various model implementations.
|
||||
|
@ -350,6 +351,13 @@ public final class KeycloakModelUtils {
|
|||
return offlineRole;
|
||||
}
|
||||
|
||||
public static void setupDeleteAccount(ClientModel accountClient) {
|
||||
RoleModel deleteOwnAccount = accountClient.getRole(AccountRoles.DELETE_ACCOUNT);
|
||||
if (deleteOwnAccount == null) {
|
||||
deleteOwnAccount = accountClient.addRole(AccountRoles.DELETE_ACCOUNT);
|
||||
}
|
||||
deleteOwnAccount.setDescription("${role_" + AccountRoles.DELETE_ACCOUNT + "}");
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively find all AuthenticationExecutionModel from specified flow or all it's subflows
|
||||
|
|
|
@ -294,6 +294,7 @@ public class RepresentationToModel {
|
|||
|
||||
newRealm.addRequiredActionProvider(model);
|
||||
}
|
||||
DefaultRequiredActions.addDeleteAccountAction(newRealm);
|
||||
} else {
|
||||
DefaultRequiredActions.addActions(newRealm);
|
||||
}
|
||||
|
|
|
@ -443,8 +443,7 @@ public class RealmManager {
|
|||
manageConsentRole.setDescription("${role_" + AccountRoles.MANAGE_CONSENT + "}");
|
||||
manageConsentRole.addCompositeRole(viewConsentRole);
|
||||
|
||||
RoleModel deleteOwnAccount = accountClient.addRole(AccountRoles.DELETE_ACCOUNT);
|
||||
deleteOwnAccount.setDescription("${role_"+AccountRoles.DELETE_ACCOUNT+"}");
|
||||
KeycloakModelUtils.setupDeleteAccount(accountClient);
|
||||
|
||||
ClientModel accountConsoleClient = realm.getClientByClientId(Constants.ACCOUNT_CONSOLE_CLIENT_ID);
|
||||
if (accountConsoleClient == null) {
|
||||
|
@ -550,6 +549,7 @@ public class RealmManager {
|
|||
setupOfflineTokens(realm, rep);
|
||||
}
|
||||
|
||||
|
||||
if (rep.getClientScopes() == null) {
|
||||
createDefaultClientScopes(realm);
|
||||
}
|
||||
|
@ -583,6 +583,10 @@ public class RealmManager {
|
|||
setupAuthenticationFlows(realm);
|
||||
setupRequiredActions(realm);
|
||||
|
||||
if (!hasRealmRole(rep, AccountRoles.DELETE_ACCOUNT)) {
|
||||
KeycloakModelUtils.setupDeleteAccount(realm.getClientByClientId(Constants.ACCOUNT_MANAGEMENT_CLIENT_ID));
|
||||
}
|
||||
|
||||
// Refresh periodic sync tasks for configured storageProviders
|
||||
UserStorageSyncManager storageSync = new UserStorageSyncManager();
|
||||
realm.getUserStorageProvidersStream()
|
||||
|
|
|
@ -286,16 +286,16 @@ public abstract class AbstractMigrationTest extends AbstractKeycloakTest {
|
|||
}
|
||||
|
||||
protected void testMigrationTo12_0_0() {
|
||||
testAccountConsoleClientHasDeleteUserRole(masterRealm);
|
||||
testAccountConsoleClientHasDeleteUserRole(migrationRealm);
|
||||
testDeleteAccount(masterRealm);
|
||||
testDeleteAccount(migrationRealm);
|
||||
}
|
||||
|
||||
private void testAccountConsoleClientHasDeleteUserRole(RealmResource realm) {
|
||||
private void testDeleteAccount(RealmResource realm) {
|
||||
ClientRepresentation accountClient = realm.clients().findByClientId(ACCOUNT_MANAGEMENT_CLIENT_ID).get(0);
|
||||
|
||||
ClientResource accountResource = realm.clients().get(accountClient.getId());
|
||||
RoleRepresentation deleteUserRole = accountResource.roles().get(AccountRoles.DELETE_ACCOUNT).toRepresentation();
|
||||
assertNotNull(deleteUserRole);
|
||||
|
||||
assertNotNull(accountResource.roles().get(AccountRoles.DELETE_ACCOUNT).toRepresentation());
|
||||
assertNotNull(realm.flows().getRequiredAction("delete_account"));
|
||||
}
|
||||
|
||||
private void testAccountClient(RealmResource realm) {
|
||||
|
|
|
@ -70,6 +70,7 @@ public class JsonFileImport198MigrationTest extends AbstractJsonFileImportMigrat
|
|||
testMigrationTo7_x(false);
|
||||
testMigrationTo8_x();
|
||||
testMigrationTo9_x();
|
||||
testMigrationTo12_x();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -64,6 +64,7 @@ public class JsonFileImport255MigrationTest extends AbstractJsonFileImportMigrat
|
|||
testMigrationTo7_x(true);
|
||||
testMigrationTo8_x();
|
||||
testMigrationTo9_x();
|
||||
testMigrationTo12_x();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -63,6 +63,7 @@ public class JsonFileImport343MigrationTest extends AbstractJsonFileImportMigrat
|
|||
testMigrationTo7_x(true);
|
||||
testMigrationTo8_x();
|
||||
testMigrationTo9_x();
|
||||
testMigrationTo12_x();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -56,6 +56,7 @@ public class JsonFileImport483MigrationTest extends AbstractJsonFileImportMigrat
|
|||
testMigrationTo7_x(true);
|
||||
testMigrationTo8_x();
|
||||
testMigrationTo9_x();
|
||||
testMigrationTo12_x();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ public class JsonFileImport903MigrationTest extends AbstractJsonFileImportMigrat
|
|||
@Test
|
||||
public void migration9_0_3Test() throws Exception {
|
||||
checkRealmsImported();
|
||||
// testMigrationTo10_x();
|
||||
testMigrationTo12_x();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -57,17 +57,11 @@ public class MigrationTest extends AbstractMigrationTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Migration(versionFrom = "12.")
|
||||
public void migration12_xTest() {
|
||||
testMigrationTo12_x();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Migration(versionFrom = "9.")
|
||||
public void migration9_xTest() throws Exception {
|
||||
testMigratedData(false);
|
||||
// testMigrationTo10_x();
|
||||
testMigrationTo12_x();
|
||||
|
||||
// Always test offline-token login during migration test
|
||||
testOfflineTokenLogin();
|
||||
|
@ -82,6 +76,7 @@ public class MigrationTest extends AbstractMigrationTest {
|
|||
testMigrationTo7_x(true);
|
||||
testMigrationTo8_x();
|
||||
testMigrationTo9_x();
|
||||
testMigrationTo12_x();
|
||||
|
||||
// Always test offline-token login during migration test
|
||||
testOfflineTokenLogin();
|
||||
|
@ -97,6 +92,7 @@ public class MigrationTest extends AbstractMigrationTest {
|
|||
testMigrationTo7_x(true);
|
||||
testMigrationTo8_x();
|
||||
testMigrationTo9_x();
|
||||
testMigrationTo12_x();
|
||||
|
||||
// Always test offline-token login during migration test
|
||||
testOfflineTokenLogin();
|
||||
|
@ -113,6 +109,7 @@ public class MigrationTest extends AbstractMigrationTest {
|
|||
testMigrationTo7_x(true);
|
||||
testMigrationTo8_x();
|
||||
testMigrationTo9_x();
|
||||
testMigrationTo12_x();
|
||||
|
||||
// Always test offline-token login during migration test
|
||||
testOfflineTokenLogin();
|
||||
|
@ -130,6 +127,7 @@ public class MigrationTest extends AbstractMigrationTest {
|
|||
testMigrationTo7_x(false);
|
||||
testMigrationTo8_x();
|
||||
testMigrationTo9_x();
|
||||
testMigrationTo12_x();
|
||||
|
||||
// Always test offline-token login during migration test
|
||||
testOfflineTokenLogin();
|
||||
|
|
Loading…
Reference in a new issue