Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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 ...
```

= 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 ...
```
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@
import java.net.IDN;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.keycloak.Config;

import static java.util.regex.Pattern.CASE_INSENSITIVE;

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_INSIDE_QUOTES_ATOM = "(?:[a-z0-9!#$%&'*.(),<>\\[\\]:; @+/=?^_`{|}~\u0080-\uFFFF-]|\\\\\\\\|\\\\\\\")";
/**
Expand All @@ -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);

public static final String MAX_EMAIL_LOCAL_PART_LENGTH = "max-email-local-part-length";


public static boolean isValidEmail(String value) {
if ( value == null || value.length() == 0 ) {
Expand Down Expand Up @@ -56,7 +57,8 @@ public static boolean isValidEmail(String value) {
}

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;
}
Matcher matcher = LOCAL_PART_PATTERN.matcher( localPart );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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_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) {
KeycloakSession session = c.getSession();
Expand Down Expand Up @@ -441,6 +442,12 @@ public List<ProviderConfigProperty> getConfigMetadata() {
.helpText("Array of regular expressions to identify fields that should be treated read-only so administrators can't change them.")
.add()

.property()
.name(MAX_EMAIL_LOCAL_PART_LENGTH)
.type(ProviderConfigProperty.STRING_TYPE)
.helpText("To set user profile max email local part length")
.add()

.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ public void testEmailValidation() {
Assert.assertFalse(Validation.isEmailValid("abc@foo."));
Assert.assertFalse(Validation.isEmailValid("abc@foo..bar"));
Assert.assertTrue(Validation.isEmailValid("diegø@foo.com"));
Assert.assertTrue(Validation.isEmailValid("qwertyuiopasdfghjklz@foo.com"));
Assert.assertFalse(Validation.isEmailValid("qwertyuiopasdfghjklzxcvbnmqwertyuiopasdfghjklzxcvbnmqwertyqwertyu@foo.com"));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ spi-truststore-file-password=secret
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-admin-read-only-attributes=deniedSomeAdmin
spi-user-profile-declarative-user-profile-max-email-local-part-length=100

#password-blacklists path
spi-password-policy-password-blacklist-blacklists-path=${kc.home.dir:}/dependency/password-blacklists
Expand Down