Skip to content

Commit

Permalink
#4442 - Option to allow spaces in usernames
Browse files Browse the repository at this point in the history
- Added option
- Added test
- Added documentation
  • Loading branch information
reckart committed Jan 22, 2024
1 parent d74e081 commit acdcd1c
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -488,8 +488,8 @@ public List<ValidationError> validateUsername(String aName)
}

// Do not allow space
if (containsAnyCharacterMatching(aName, Character::isWhitespace)) {
errors.add(new ValidationError("Username cannot contain a space character") //
if (containsAnyCharacterMatching(aName, this::isWhitespaceIllegalInUsername)) {
errors.add(new ValidationError("Username cannot contain whitespace") //
.addKey(MSG_USERNAME_ERROR_ILLEGAL_SPACE));
return errors;
}
Expand Down Expand Up @@ -552,6 +552,15 @@ public List<ValidationError> validateUsername(String aName)
return errors;
}

private boolean isWhitespaceIllegalInUsername(char ch)
{
if (securityProperties.isSpaceAllowedInUsername() && ch == ' ') {
return false;
}

return Character.isWhitespace((int) ch);
}

@Override
public boolean isValidUsername(String aName)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,6 @@ public interface SecurityProperties
Pattern getUsernamePattern();

Pattern getPasswordPattern();

boolean isSpaceAllowedInUsername();
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public class SecurityPropertiesImpl
private String defaultAdminUsername;
private String defaultAdminPassword;
private boolean defaultAdminRemoteAccess = false;
private boolean spaceAllowedInUsername = false;

public static final int HARD_MINIMUM_PASSWORD_LENGTH = 0;
public static final int DEFAULT_MINIMUM_PASSWORD_LENGTH = 8;
Expand Down Expand Up @@ -152,4 +153,15 @@ public void setPasswordPattern(Pattern aPasswordPattern)
{
passwordPattern = aPasswordPattern;
}

@Override
public boolean isSpaceAllowedInUsername()
{
return spaceAllowedInUsername;
}

public void setSpaceAllowedInUsername(boolean aSpaceInUsernameAllowed)
{
spaceAllowedInUsername = aSpaceInUsernameAllowed;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ NOTE: In addition to the restrictions imposed here, {product-name} may impose ad
| `.*`
| `(?=.\*[a-z])(?=.*[A-Z])(?=.\*[0-9])(?=.*\p{Punct}).*`

| `security.space-allowed-in-username`
| Whether simple space characters are permitted in usernames. Enable this option only when necessary to restore access to existing accounts in certain scenarios such as when using external authentication. Usernames with spaces may lead to problems e.g. when exporting/importing projects or documents or when constructing certain URLs.
| `false`
| `true`
|===


Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@
import de.tudarmstadt.ukp.clarin.webanno.security.config.SecurityPropertiesImpl;
import de.tudarmstadt.ukp.clarin.webanno.security.model.User;

@DataJpaTest(showSql = false)
@DataJpaTest(showSql = false, //
properties = { //
"spring.main.banner-mode=off" })
@EnableAutoConfiguration
@ImportAutoConfiguration( //
exclude = { LiquibaseAutoConfiguration.class }, //
Expand All @@ -70,6 +72,7 @@ void setup()
securityProperties.setMaximumUsernameLength(DEFAULT_MAXIMUM_USERNAME_LENGTH);
securityProperties.setMinimumPasswordLength(DEFAULT_MINIMUM_PASSWORD_LENGTH);
securityProperties.setMaximumPasswordLength(DEFAULT_MINIMUM_PASSWORD_LENGTH);
securityProperties.setSpaceAllowedInUsername(false);
}

@Test
Expand Down Expand Up @@ -121,6 +124,18 @@ void thatUsernamePatternIsRespected()
assertThat(userDao.isValidUsername("ay")).isFalse();
}

@Test
void thatAllowingSpaceInUsernameWorks()
{
securityProperties.setMinimumUsernameLength(0);

securityProperties.setSpaceAllowedInUsername(false);
assertThat(userDao.isValidUsername("a z")).isFalse();

securityProperties.setSpaceAllowedInUsername(true);
assertThat(userDao.isValidUsername("a z")).isTrue();
}

@Test
void thatInvalidDefaultUserNameIsRejected()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ password.error.pattern-mismatch=Password invalid. It must match the pattern ${pa
password.error.control-characters=Password cannot contain any control characters

username.error.blank=Username cannot be empty or blank
username.error.illegal-space=Username cannot contain a space character
username.error.illegal-space=Username cannot contain whitespace
username.error.illegal-characters=Username cannot contain any of these characters: ${chars}
username.error.control-characters=Username cannot contain any control characters
username.error.reserved=Username is reserved
Expand Down

0 comments on commit acdcd1c

Please sign in to comment.