KEYCLOAK-3439, KEYCLOAK-3893, KEYCLOAK-3894 - Support for Unicode

Treatment of Unicode characters varies among databases. This change
adds support for Unicode characters in the following fields:

* Realms: display name, HTML display name
* Users: username, given name, last name, attribute values
* Groups: name, attribute values
* Components: attribute values
* Roles: name
* Descriptions of objects

Unicode support for the rest of the fields depends on database vendor
and is described in the installation guide in more detail.
This commit is contained in:
Hynek Mlnarik 2016-11-28 12:30:08 +01:00
parent 1ae60ef8a7
commit 46d3555798
2 changed files with 104 additions and 0 deletions

View file

@ -22,4 +22,79 @@
<customChange class="org.keycloak.connections.jpa.updater.liquibase.custom.MigrateUserFedToComponent"/>
</changeSet>
<changeSet author="hmlnarik@redhat.com" id="2.4.1-unicode-oracle">
<preConditions onSqlOutput="TEST" onFail="MARK_RAN">
<dbms type="oracle" />
</preConditions>
<modifyDataType tableName="AUTHENTICATION_FLOW" columnName="DESCRIPTION" newDataType="NVARCHAR(255)"/>
<modifyDataType tableName="CLIENT_TEMPLATE" columnName="DESCRIPTION" newDataType="NVARCHAR(255)"/>
<modifyDataType tableName="RESOURCE_SERVER_POLICY" columnName="DESCRIPTION" newDataType="NVARCHAR(255)"/>
<modifyDataType tableName="CLIENT" columnName="DESCRIPTION" newDataType="NVARCHAR(255)"/>
<modifyDataType tableName="CLIENT" columnName="NAME" newDataType="NVARCHAR(255)"/>
<modifyDataType tableName="USER_ENTITY" columnName="FIRST_NAME" newDataType="NVARCHAR(255)"/>
<modifyDataType tableName="USER_ENTITY" columnName="LAST_NAME" newDataType="NVARCHAR(255)"/>
<modifyDataType tableName="USER_ENTITY" columnName="USERNAME" newDataType="NVARCHAR(255)"/>
<modifyDataType tableName="USERNAME_LOGIN_FAILURE" columnName="USERNAME" newDataType="NVARCHAR(255)"/>
<modifyDataType tableName="KEYCLOAK_GROUP" columnName="NAME" newDataType="NVARCHAR(255)"/>
<modifyDataType tableName="USER_ATTRIBUTE" columnName="VALUE" newDataType="NVARCHAR(255)"/>
<modifyDataType tableName="GROUP_ATTRIBUTE" columnName="VALUE" newDataType="NVARCHAR(255)"/>
<modifyDataType tableName="REALM_ATTRIBUTE" columnName="VALUE" newDataType="NVARCHAR(255)"/>
<addColumn tableName="COMPONENT_CONFIG">
<column name="VALUE_NEW" type="NCLOB" />
</addColumn>
<sql>UPDATE COMPONENT_CONFIG SET VALUE_NEW = VALUE, VALUE = NULL</sql>
<dropColumn tableName="COMPONENT_CONFIG" columnName="VALUE"/>
<renameColumn tableName="COMPONENT_CONFIG" oldColumnName="VALUE_NEW" newColumnName="VALUE"/>
<!--
<modifyDataType tableName="COMPONENT_CONFIG" columnName="VALUE" newDataType="NVARCHAR(2000)"/>
-->
<modifyDataType tableName="KEYCLOAK_ROLE" columnName="NAME" newDataType="NVARCHAR(255)"/>
<modifyDataType tableName="KEYCLOAK_ROLE" columnName="DESCRIPTION" newDataType="NVARCHAR(255)"/>
</changeSet>
<changeSet author="hmlnarik@redhat.com" id="2.4.1-unicode-other-dbs">
<preConditions onSqlOutput="TEST" onFail="MARK_RAN">
<not>
<dbms type="oracle" />
</not>
</preConditions>
<modifyDataType tableName="AUTHENTICATION_FLOW" columnName="DESCRIPTION" newDataType="NVARCHAR(255)"/>
<modifyDataType tableName="CLIENT_TEMPLATE" columnName="DESCRIPTION" newDataType="NVARCHAR(255)"/>
<modifyDataType tableName="RESOURCE_SERVER_POLICY" columnName="DESCRIPTION" newDataType="NVARCHAR(255)"/>
<modifyDataType tableName="CLIENT" columnName="DESCRIPTION" newDataType="NVARCHAR(255)"/>
<modifyDataType tableName="CLIENT" columnName="NAME" newDataType="NVARCHAR(255)"/>
<dropUniqueConstraint constraintName="UK_RU8TT6T700S9V50BU18WS5HA6" tableName="USER_ENTITY"/>
<modifyDataType tableName="USER_ENTITY" columnName="FIRST_NAME" newDataType="NVARCHAR(255)"/>
<modifyDataType tableName="USER_ENTITY" columnName="LAST_NAME" newDataType="NVARCHAR(255)"/>
<modifyDataType tableName="USER_ENTITY" columnName="USERNAME" newDataType="NVARCHAR(255)"/>
<addUniqueConstraint columnNames="REALM_ID,USERNAME" constraintName="UK_RU8TT6T700S9V50BU18WS5HA6" tableName="USER_ENTITY"/>
<dropPrimaryKey constraintName="CONSTRAINT_17" tableName="USERNAME_LOGIN_FAILURE"/>
<modifyDataType tableName="USERNAME_LOGIN_FAILURE" columnName="USERNAME" newDataType="NVARCHAR(255)"/>
<addNotNullConstraint tableName="USERNAME_LOGIN_FAILURE" columnName="USERNAME" columnDataType="NVARCHAR(255)"/>
<addPrimaryKey columnNames="REALM_ID, USERNAME" constraintName="CONSTRAINT_17-2" tableName="USERNAME_LOGIN_FAILURE"/>
<modifyDataType tableName="KEYCLOAK_GROUP" columnName="NAME" newDataType="NVARCHAR(255)"/>
<modifyDataType tableName="USER_ATTRIBUTE" columnName="VALUE" newDataType="NVARCHAR(255)"/>
<modifyDataType tableName="GROUP_ATTRIBUTE" columnName="VALUE" newDataType="NVARCHAR(255)"/>
<modifyDataType tableName="REALM_ATTRIBUTE" columnName="VALUE" newDataType="NVARCHAR(255)"/>
<modifyDataType tableName="COMPONENT_CONFIG" columnName="VALUE" newDataType="NVARCHAR(4000)"/>
<dropUniqueConstraint constraintName="UK_J3RWUVD56ONTGSUHOGM184WW2-2" tableName="KEYCLOAK_ROLE"/>
<modifyDataType tableName="KEYCLOAK_ROLE" columnName="NAME" newDataType="NVARCHAR(255)"/>
<addUniqueConstraint columnNames="NAME,CLIENT_REALM_CONSTRAINT" constraintName="UK_J3RWUVD56ONTGSUHOGM184WW2-2" tableName="KEYCLOAK_ROLE"/>
<modifyDataType tableName="KEYCLOAK_ROLE" columnName="DESCRIPTION" newDataType="NVARCHAR(255)"/>
</changeSet>
</databaseChangeLog>

View file

@ -31,6 +31,7 @@ import javax.ws.rs.core.Response;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import static org.junit.Assert.*;
@ -210,6 +211,34 @@ public class ComponentsTest extends AbstractAdminTest {
assertEquals(ComponentRepresentation.SECRET_VALUE, returned3.getConfig().getFirst("secret"));
}
@Test
public void testLongValueInComponentConfigAscii() throws Exception {
ComponentRepresentation rep = createComponentRepresentation("mycomponent");
String value = StringUtils.repeat("0123456789", 400); // 4000 8-bit characters
rep.getConfig().addFirst("required", "foo");
rep.getConfig().addFirst("val1", value);
String id = createComponent(rep);
ComponentRepresentation returned = components.component(id).toRepresentation();
assertEquals(value, returned.getConfig().getFirst("val1"));
}
@Test
public void testLongValueInComponentConfigExtLatin() throws Exception {
ComponentRepresentation rep = createComponentRepresentation("mycomponent");
String value = StringUtils.repeat("ěščřžýíŮÍÁ", 400); // 4000 Unicode extended-Latin characters
rep.getConfig().addFirst("required", "foo");
rep.getConfig().addFirst("val1", value);
String id = createComponent(rep);
ComponentRepresentation returned = components.component(id).toRepresentation();
assertEquals(value, returned.getConfig().getFirst("val1"));
}
private String createComponent(ComponentRepresentation rep) {
ComponentsResource components = realm.components();
Response response = components.add(rep);