KEYCLOAK-2101 - Ensure consistent order for properties in json configuration export.
We now explicitly order the AuthenticatorFlows, AuthenticatorConfig, as well as RequiredActions to ensure a consistent order for the configuration export to make it easier to diff / version keycloak configuration files. Previously the order of the json properties of an configuration export were non deterministic. The configuration file could look partially different after a export, import, export sequence even if no changes were made.
This commit is contained in:
parent
67fca8f1f3
commit
c81d0c0898
1 changed files with 35 additions and 10 deletions
|
@ -44,13 +44,7 @@ import org.keycloak.representations.idm.UserRepresentation;
|
||||||
import org.keycloak.representations.idm.UserSessionRepresentation;
|
import org.keycloak.representations.idm.UserSessionRepresentation;
|
||||||
import org.keycloak.common.util.Time;
|
import org.keycloak.common.util.Time;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||||
|
@ -292,19 +286,50 @@ public class ModelToRepresentation {
|
||||||
public static void exportAuthenticationFlows(RealmModel realm, RealmRepresentation rep) {
|
public static void exportAuthenticationFlows(RealmModel realm, RealmRepresentation rep) {
|
||||||
rep.setAuthenticationFlows(new LinkedList<AuthenticationFlowRepresentation>());
|
rep.setAuthenticationFlows(new LinkedList<AuthenticationFlowRepresentation>());
|
||||||
rep.setAuthenticatorConfig(new LinkedList<AuthenticatorConfigRepresentation>());
|
rep.setAuthenticatorConfig(new LinkedList<AuthenticatorConfigRepresentation>());
|
||||||
for (AuthenticationFlowModel model : realm.getAuthenticationFlows()) {
|
|
||||||
|
List<AuthenticationFlowModel> authenticationFlows = new ArrayList<>(realm.getAuthenticationFlows());
|
||||||
|
//ensure consistent ordering of authenticationFlows.
|
||||||
|
Collections.sort(authenticationFlows, new Comparator<AuthenticationFlowModel>() {
|
||||||
|
@Override
|
||||||
|
public int compare(AuthenticationFlowModel left, AuthenticationFlowModel right) {
|
||||||
|
return left.getAlias().compareTo(right.getAlias());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
for (AuthenticationFlowModel model : authenticationFlows) {
|
||||||
AuthenticationFlowRepresentation flowRep = toRepresentation(realm, model);
|
AuthenticationFlowRepresentation flowRep = toRepresentation(realm, model);
|
||||||
rep.getAuthenticationFlows().add(flowRep);
|
rep.getAuthenticationFlows().add(flowRep);
|
||||||
}
|
}
|
||||||
for (AuthenticatorConfigModel model : realm.getAuthenticatorConfigs()) {
|
|
||||||
|
List<AuthenticatorConfigModel> authenticatorConfigs = new ArrayList<>(realm.getAuthenticatorConfigs());
|
||||||
|
//ensure consistent ordering of authenticatorConfigs.
|
||||||
|
Collections.sort(authenticatorConfigs, new Comparator<AuthenticatorConfigModel>() {
|
||||||
|
@Override
|
||||||
|
public int compare(AuthenticatorConfigModel left, AuthenticatorConfigModel right) {
|
||||||
|
return left.getAlias().compareTo(right.getAlias());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
for (AuthenticatorConfigModel model : authenticatorConfigs) {
|
||||||
rep.getAuthenticatorConfig().add(toRepresentation(model));
|
rep.getAuthenticatorConfig().add(toRepresentation(model));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void exportRequiredActions(RealmModel realm, RealmRepresentation rep) {
|
public static void exportRequiredActions(RealmModel realm, RealmRepresentation rep) {
|
||||||
|
|
||||||
rep.setRequiredActions(new LinkedList<RequiredActionProviderRepresentation>());
|
rep.setRequiredActions(new LinkedList<RequiredActionProviderRepresentation>());
|
||||||
for (RequiredActionProviderModel model : realm.getRequiredActionProviders()) {
|
|
||||||
|
List<RequiredActionProviderModel> requiredActionProviders = realm.getRequiredActionProviders();
|
||||||
|
//ensure consistent ordering of requiredActionProviders.
|
||||||
|
Collections.sort(requiredActionProviders, new Comparator<RequiredActionProviderModel>() {
|
||||||
|
@Override
|
||||||
|
public int compare(RequiredActionProviderModel left, RequiredActionProviderModel right) {
|
||||||
|
return left.getAlias().compareTo(right.getAlias());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
for (RequiredActionProviderModel model : requiredActionProviders) {
|
||||||
RequiredActionProviderRepresentation action = toRepresentation(model);
|
RequiredActionProviderRepresentation action = toRepresentation(model);
|
||||||
rep.getRequiredActions().add(action);
|
rep.getRequiredActions().add(action);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue