Fix for Keycloak 22.0.1 unable to create user with long email address (#23109)
Closes #22825
This commit is contained in:
parent
2f207a78d7
commit
62927433dc
5 changed files with 21 additions and 3 deletions
|
@ -10,4 +10,10 @@ The old LinkedIn way based on OAuth seems to be completely removed from the link
|
||||||
|
|
||||||
```
|
```
|
||||||
kc.[sh|bat] start --features linkedin-oauth ...
|
kc.[sh|bat] start --features linkedin-oauth ...
|
||||||
|
```
|
||||||
|
|
||||||
|
= A new parameter --spi-user-profile-declarative-user-profile-max-email-local-part-length is added to set max email local part length taking backwards compatibility into consideration. The default value is 64.
|
||||||
|
|
||||||
|
```
|
||||||
|
kc.[sh|bat] start --spi-user-profile-declarative-user-profile-max-email-local-part-length=100 ...
|
||||||
```
|
```
|
|
@ -3,12 +3,11 @@ package org.keycloak.utils;
|
||||||
import java.net.IDN;
|
import java.net.IDN;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
import org.keycloak.Config;
|
||||||
|
|
||||||
import static java.util.regex.Pattern.CASE_INSENSITIVE;
|
import static java.util.regex.Pattern.CASE_INSENSITIVE;
|
||||||
|
|
||||||
public class EmailValidationUtil {
|
public class EmailValidationUtil {
|
||||||
private static final int MAX_LOCAL_PART_LENGTH = 64;
|
|
||||||
|
|
||||||
private static final String LOCAL_PART_ATOM = "[a-z0-9!#$%&'*+/=?^_`{|}~\u0080-\uFFFF-]";
|
private static final String LOCAL_PART_ATOM = "[a-z0-9!#$%&'*+/=?^_`{|}~\u0080-\uFFFF-]";
|
||||||
private static final String LOCAL_PART_INSIDE_QUOTES_ATOM = "(?:[a-z0-9!#$%&'*.(),<>\\[\\]:; @+/=?^_`{|}~\u0080-\uFFFF-]|\\\\\\\\|\\\\\\\")";
|
private static final String LOCAL_PART_INSIDE_QUOTES_ATOM = "(?:[a-z0-9!#$%&'*.(),<>\\[\\]:; @+/=?^_`{|}~\u0080-\uFFFF-]|\\\\\\\\|\\\\\\\")";
|
||||||
/**
|
/**
|
||||||
|
@ -29,6 +28,8 @@ public class EmailValidationUtil {
|
||||||
*/
|
*/
|
||||||
private static final Pattern EMAIL_DOMAIN_PATTERN = Pattern.compile(DOMAIN + "|\\[" + IP_DOMAIN + "\\]|" + "\\[IPv6:" + IP_V6_DOMAIN + "\\]", CASE_INSENSITIVE);
|
private static final Pattern EMAIL_DOMAIN_PATTERN = Pattern.compile(DOMAIN + "|\\[" + IP_DOMAIN + "\\]|" + "\\[IPv6:" + IP_V6_DOMAIN + "\\]", CASE_INSENSITIVE);
|
||||||
|
|
||||||
|
public static final String MAX_EMAIL_LOCAL_PART_LENGTH = "max-email-local-part-length";
|
||||||
|
|
||||||
|
|
||||||
public static boolean isValidEmail(String value) {
|
public static boolean isValidEmail(String value) {
|
||||||
if ( value == null || value.length() == 0 ) {
|
if ( value == null || value.length() == 0 ) {
|
||||||
|
@ -56,7 +57,8 @@ public class EmailValidationUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isValidEmailLocalPart(String localPart) {
|
private static boolean isValidEmailLocalPart(String localPart) {
|
||||||
if ( localPart.length() > MAX_LOCAL_PART_LENGTH ) {
|
|
||||||
|
if ( localPart.length() > Config.scope("user-profile-declarative-user-profile").getInt(MAX_EMAIL_LOCAL_PART_LENGTH,64) ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Matcher matcher = LOCAL_PART_PATTERN.matcher( localPart );
|
Matcher matcher = LOCAL_PART_PATTERN.matcher( localPart );
|
||||||
|
|
|
@ -71,6 +71,7 @@ public abstract class AbstractUserProfileProvider<U extends UserProfileProvider>
|
||||||
|
|
||||||
public static final String CONFIG_ADMIN_READ_ONLY_ATTRIBUTES = "admin-read-only-attributes";
|
public static final String CONFIG_ADMIN_READ_ONLY_ATTRIBUTES = "admin-read-only-attributes";
|
||||||
public static final String CONFIG_READ_ONLY_ATTRIBUTES = "read-only-attributes";
|
public static final String CONFIG_READ_ONLY_ATTRIBUTES = "read-only-attributes";
|
||||||
|
public static final String MAX_EMAIL_LOCAL_PART_LENGTH = "max-email-local-part-length";
|
||||||
|
|
||||||
private static boolean editUsernameCondition(AttributeContext c) {
|
private static boolean editUsernameCondition(AttributeContext c) {
|
||||||
KeycloakSession session = c.getSession();
|
KeycloakSession session = c.getSession();
|
||||||
|
@ -441,6 +442,12 @@ public abstract class AbstractUserProfileProvider<U extends UserProfileProvider>
|
||||||
.helpText("Array of regular expressions to identify fields that should be treated read-only so administrators can't change them.")
|
.helpText("Array of regular expressions to identify fields that should be treated read-only so administrators can't change them.")
|
||||||
.add()
|
.add()
|
||||||
|
|
||||||
|
.property()
|
||||||
|
.name(MAX_EMAIL_LOCAL_PART_LENGTH)
|
||||||
|
.type(ProviderConfigProperty.STRING_TYPE)
|
||||||
|
.helpText("To set user profile max email local part length")
|
||||||
|
.add()
|
||||||
|
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,8 @@ public class ValidationTest {
|
||||||
Assert.assertFalse(Validation.isEmailValid("abc@foo."));
|
Assert.assertFalse(Validation.isEmailValid("abc@foo."));
|
||||||
Assert.assertFalse(Validation.isEmailValid("abc@foo..bar"));
|
Assert.assertFalse(Validation.isEmailValid("abc@foo..bar"));
|
||||||
Assert.assertTrue(Validation.isEmailValid("diegø@foo.com"));
|
Assert.assertTrue(Validation.isEmailValid("diegø@foo.com"));
|
||||||
|
Assert.assertTrue(Validation.isEmailValid("qwertyuiopasdfghjklz@foo.com"));
|
||||||
|
Assert.assertFalse(Validation.isEmailValid("qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyqwertyu@foo.com"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -32,6 +32,7 @@ spi-truststore-file-password=secret
|
||||||
spi-user-profile-provider=declarative-user-profile
|
spi-user-profile-provider=declarative-user-profile
|
||||||
spi-user-profile-declarative-user-profile-read-only-attributes=deniedFoo,deniedBar*,deniedSome/thing,deniedsome*thing
|
spi-user-profile-declarative-user-profile-read-only-attributes=deniedFoo,deniedBar*,deniedSome/thing,deniedsome*thing
|
||||||
spi-user-profile-declarative-user-profile-admin-read-only-attributes=deniedSomeAdmin
|
spi-user-profile-declarative-user-profile-admin-read-only-attributes=deniedSomeAdmin
|
||||||
|
spi-user-profile-declarative-user-profile-max-email-local-part-length=100
|
||||||
|
|
||||||
#password-blacklists path
|
#password-blacklists path
|
||||||
spi-password-policy-password-blacklist-blacklists-path=${kc.home.dir:}/dependency/password-blacklists
|
spi-password-policy-password-blacklist-blacklists-path=${kc.home.dir:}/dependency/password-blacklists
|
||||||
|
|
Loading…
Reference in a new issue