mirror of https://github.com/halo-dev/halo
refactor: add validation for initializing super admin username (#3744)
#### What type of PR is this? /kind improvement /area core #### What this PR does / why we need it: 对初始超级管理员用户名增加合法性校验 #### Which issue(s) this PR fixes: Fixes #3482 #### Does this PR introduce a user-facing change? ```release-note 对初始超级管理员用户名增加合法性校验 ```pull/3819/head
parent
11a5807682
commit
f076fc5740
|
@ -0,0 +1,33 @@
|
|||
package run.halo.app.infra;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
import lombok.experimental.UtilityClass;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
@UtilityClass
|
||||
public class ValidationUtils {
|
||||
public static final Pattern NAME_PATTERN =
|
||||
Pattern.compile("^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$");
|
||||
|
||||
public static final String NAME_VALIDATION_MESSAGE = """
|
||||
Super administrator username must be a valid subdomain name, the name must:
|
||||
1. contain no more than 63 characters
|
||||
2. contain only lowercase alphanumeric characters, '-' or '.'
|
||||
3. start with an alphanumeric character
|
||||
4. end with an alphanumeric character
|
||||
""";
|
||||
|
||||
/**
|
||||
* Validates the name.
|
||||
*
|
||||
* @param name name for validation
|
||||
* @return true if the name is valid
|
||||
*/
|
||||
public static boolean validateName(String name) {
|
||||
if (StringUtils.isBlank(name)) {
|
||||
return false;
|
||||
}
|
||||
boolean matches = NAME_PATTERN.matcher(name).matches();
|
||||
return matches && name.length() <= 63;
|
||||
}
|
||||
}
|
|
@ -70,5 +70,7 @@ public class HaloProperties implements Validator {
|
|||
errors.rejectValue("externalUrl", "external-url.required.when-using-absolute-permalink",
|
||||
"External URL is required when property `use-absolute-permalink` is set to true.");
|
||||
}
|
||||
SecurityProperties.Initializer.validateUsername(props.getSecurity().getInitializer(),
|
||||
errors);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,8 +3,11 @@ package run.halo.app.infra.properties;
|
|||
import static org.springframework.security.web.server.header.ReferrerPolicyServerHttpHeadersWriter.ReferrerPolicy.STRICT_ORIGIN_WHEN_CROSS_ORIGIN;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.security.web.server.header.ReferrerPolicyServerHttpHeadersWriter.ReferrerPolicy;
|
||||
import org.springframework.security.web.server.header.XFrameOptionsServerHttpHeadersWriter.Mode;
|
||||
import org.springframework.validation.Errors;
|
||||
import run.halo.app.infra.ValidationUtils;
|
||||
|
||||
@Data
|
||||
public class SecurityProperties {
|
||||
|
@ -39,6 +42,14 @@ public class SecurityProperties {
|
|||
|
||||
private String superAdminPassword;
|
||||
|
||||
static void validateUsername(@NonNull Initializer initializer, @NonNull Errors errors) {
|
||||
if (initializer.isDisabled() || ValidationUtils.validateName(
|
||||
initializer.getSuperAdminUsername())) {
|
||||
return;
|
||||
}
|
||||
errors.rejectValue("security.initializer.superAdminUsername",
|
||||
"initializer.superAdminUsername.invalid",
|
||||
ValidationUtils.NAME_VALIDATION_MESSAGE);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
package run.halo.app.infra;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Tests for {@link ValidationUtils}.
|
||||
*
|
||||
* @author guqing
|
||||
* @since 2.5.0
|
||||
*/
|
||||
class ValidationUtilsTest {
|
||||
|
||||
@Nested
|
||||
class NameValidationTest {
|
||||
@Test
|
||||
void nullName() {
|
||||
assertThat(ValidationUtils.validateName(null)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void emptyUsername() {
|
||||
assertThat(ValidationUtils.validateName("")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void startWithIllegalCharacter() {
|
||||
assertThat(ValidationUtils.validateName("-abc")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void endWithIllegalCharacter() {
|
||||
assertThat(ValidationUtils.validateName("abc-")).isFalse();
|
||||
assertThat(ValidationUtils.validateName("abcD")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void middleWithIllegalCharacter() {
|
||||
assertThat(ValidationUtils.validateName("ab?c")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void moreThan63Characters() {
|
||||
assertThat(ValidationUtils.validateName(StringUtils.repeat('a', 64))).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void correctUsername() {
|
||||
assertThat(ValidationUtils.validateName("abc")).isTrue();
|
||||
assertThat(ValidationUtils.validateName("ab-c")).isTrue();
|
||||
assertThat(ValidationUtils.validateName("1st")).isTrue();
|
||||
assertThat(ValidationUtils.validateName("ast1")).isTrue();
|
||||
assertThat(ValidationUtils.validateName("ast-1")).isTrue();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -59,5 +59,4 @@ class SuperAdminInitializerTest {
|
|||
return false;
|
||||
}));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue