mirror of https://github.com/halo-dev/halo
Fix the problem of being able to configure invalid external URL (#6840)
#### What type of PR is this? /kind bug /area core /milestone 2.20.x #### What this PR does / why we need it: This PR makes users not be able to configure a invalid external URL like `https:www/halo.run` even if it is an valid URL format. #### Which issue(s) this PR fixes: Fixes #6837 #### Does this PR introduce a user-facing change? ```release-note 修复可配置无效的外部访问地址的问题 ```pull/6844/head
parent
91a69de849
commit
6d149ae3bb
|
@ -2,6 +2,7 @@ package run.halo.app.infra.properties;
|
||||||
|
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
import jakarta.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
@ -69,9 +70,26 @@ public class HaloProperties implements Validator {
|
||||||
@Override
|
@Override
|
||||||
public void validate(Object target, Errors errors) {
|
public void validate(Object target, Errors errors) {
|
||||||
var props = (HaloProperties) target;
|
var props = (HaloProperties) target;
|
||||||
if (props.isUseAbsolutePermalink() && props.getExternalUrl() == null) {
|
var externalUrl = props.getExternalUrl();
|
||||||
|
if (props.isUseAbsolutePermalink() && externalUrl == null) {
|
||||||
errors.rejectValue("externalUrl", "external-url.required.when-using-absolute-permalink",
|
errors.rejectValue("externalUrl", "external-url.required.when-using-absolute-permalink",
|
||||||
"External URL is required when property `use-absolute-permalink` is set to true.");
|
"External URL is required when property `use-absolute-permalink` is set to true.");
|
||||||
}
|
}
|
||||||
|
// check if the external URL is a http or https URL and is not an opaque URL.
|
||||||
|
if (externalUrl != null && !isValidExternalUrl(externalUrl)) {
|
||||||
|
errors.rejectValue("externalUrl", "external-url.invalid-format",
|
||||||
|
"External URL must be a http or https URL.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isValidExternalUrl(URL externalUrl) {
|
||||||
|
try {
|
||||||
|
var uri = externalUrl.toURI();
|
||||||
|
return !uri.isOpaque()
|
||||||
|
&& uri.getAuthority() != null
|
||||||
|
&& Set.of("http", "https").contains(uri.getScheme());
|
||||||
|
} catch (URISyntaxException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package run.halo.app;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
@ -34,4 +35,10 @@ public class PathPrefixPredicateTest {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void urlTest() {
|
||||||
|
URI uri = URI.create("https:///path");
|
||||||
|
System.out.println(uri);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
package run.halo.app.infra.properties;
|
||||||
|
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
|
import org.springframework.validation.SimpleErrors;
|
||||||
|
|
||||||
|
class HaloPropertiesTest {
|
||||||
|
|
||||||
|
static Stream<Arguments> validateTest() throws MalformedURLException {
|
||||||
|
return Stream.of(
|
||||||
|
Arguments.of(true, new URL("http://localhost:8080"), true),
|
||||||
|
Arguments.of(false, new URL("http://localhost:8080"), true),
|
||||||
|
Arguments.of(true, new URL("https://localhost:8080"), true),
|
||||||
|
Arguments.of(false, new URL("https://localhost:8080"), true),
|
||||||
|
Arguments.of(true, new URL("ftp://localhost:8080"), false),
|
||||||
|
Arguments.of(false, new URL("ftp://localhost:8080"), false),
|
||||||
|
Arguments.of(true, new URL("http:www/halo/run"), false),
|
||||||
|
Arguments.of(false, new URL("http:www/halo.run"), false),
|
||||||
|
Arguments.of(true, new URL("https:www/halo/run"), false),
|
||||||
|
Arguments.of(false, new URL("https:www/halo/run"), false),
|
||||||
|
Arguments.of(true, new URL("https:///path"), false),
|
||||||
|
Arguments.of(false, new URL("https:///path"), false),
|
||||||
|
Arguments.of(true, new URL("http:///path"), false),
|
||||||
|
Arguments.of(false, new URL("http:///path"), false),
|
||||||
|
Arguments.of(true, null, false),
|
||||||
|
Arguments.of(false, null, true)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@MethodSource
|
||||||
|
void validateTest(boolean useAbsolutePermalink, URL externalUrl, boolean valid) {
|
||||||
|
var properties = new HaloProperties();
|
||||||
|
properties.setUseAbsolutePermalink(useAbsolutePermalink);
|
||||||
|
properties.setExternalUrl(externalUrl);
|
||||||
|
var errors = new SimpleErrors(properties);
|
||||||
|
properties.validate(properties, errors);
|
||||||
|
Assertions.assertEquals(valid, !errors.hasErrors());
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue