Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main'
Browse files Browse the repository at this point in the history
  • Loading branch information
ruibaby committed Jul 6, 2024
2 parents 5bd610a + 0f01006 commit a9725df
Show file tree
Hide file tree
Showing 13 changed files with 90 additions and 32 deletions.
1 change: 1 addition & 0 deletions .github/workflows/halo.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ jobs:
push: false
context: .
- name: E2E Testing
continue-on-error: true
run: |
sudo curl -L https://github.com/docker/compose/releases/download/v2.23.0/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose
sudo chmod u+x /usr/local/bin/docker-compose
Expand Down
10 changes: 10 additions & 0 deletions api/src/main/java/run/halo/app/plugin/BasePlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.pf4j.Plugin;
import org.pf4j.PluginWrapper;

/**
* This class will be extended by all plugins and serve as the common class between a plugin and
Expand All @@ -26,6 +27,15 @@ public BasePlugin(PluginContext pluginContext) {
this.context = pluginContext;
}

@Deprecated(since = "2.7.0", forRemoval = true)
public BasePlugin(PluginWrapper wrapper) {
super(wrapper);
log.warn("Deprecated constructor 'BasePlugin(PluginWrapper wrapper)' called, please use "
+ "'BasePlugin(PluginContext pluginContext)' instead for plugin '{}',This "
+ "constructor will be removed in 2.19.0",
wrapper.getPluginId());
}

public BasePlugin() {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.MessageSource;
import org.springframework.core.annotation.MergedAnnotations;
import org.springframework.dao.ConcurrencyFailureException;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.ProblemDetail;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.web.ErrorResponse;
Expand All @@ -33,6 +36,9 @@ public enum Exceptions {
public static final String REQUEST_NOT_PERMITTED_TYPE =
"https://halo.run/probs/request-not-permitted";

public static final String CONFLICT_TYPE =
"https://halo.run/probs/conflict";

/**
* Non-ErrorResponse exception to type map.
*/
Expand All @@ -47,22 +53,11 @@ public static ErrorResponse createErrorResponse(Throwable t, @Nullable HttpStatu
if (t instanceof ErrorResponse er) {
errorResponse = er;
} else {
var responseStatusAnno =
MergedAnnotations.from(t.getClass(), TYPE_HIERARCHY).get(ResponseStatus.class);
if (status == null) {
status = responseStatusAnno.getValue("code", HttpStatus.class)
.orElse(HttpStatus.INTERNAL_SERVER_ERROR);
}
var type = EXCEPTION_TYPE_MAP.getOrDefault(t.getClass(), DEFAULT_TYPE);
var detail = responseStatusAnno.getValue("reason", String.class)
.orElseGet(t::getMessage);
var builder = ErrorResponse.builder(t, status, detail)
.type(URI.create(type));
if (status.is5xxServerError()) {
builder.detailMessageCode("problemDetail.internalServerError")
.titleMessageCode("problemDetail.title.internalServerError");
var er = handleConflictException(t);
if (er == null) {
er = handleException(t, status);
}
errorResponse = builder.build();
errorResponse = er;
}
var problemDetail = errorResponse.updateAndGetBody(messageSource, getLocale(exchange));
problemDetail.setInstance(exchange.getRequest().getURI());
Expand All @@ -71,6 +66,39 @@ public static ErrorResponse createErrorResponse(Throwable t, @Nullable HttpStatu
return errorResponse;
}

@NonNull
private static ErrorResponse handleException(Throwable t, @Nullable HttpStatusCode status) {
var responseStatusAnno = MergedAnnotations.from(t.getClass(), TYPE_HIERARCHY)
.get(ResponseStatus.class);
if (status == null) {
status = responseStatusAnno.getValue("code", HttpStatus.class)
.orElse(HttpStatus.INTERNAL_SERVER_ERROR);
}
var type = EXCEPTION_TYPE_MAP.getOrDefault(t.getClass(), DEFAULT_TYPE);
var detail = responseStatusAnno.getValue("reason", String.class)
.orElseGet(t::getMessage);
var builder = ErrorResponse.builder(t, status, detail)
.type(URI.create(type));
if (status.is5xxServerError()) {
builder.detailMessageCode("problemDetail.internalServerError")
.titleMessageCode("problemDetail.title.internalServerError");
}
return builder.build();
}

@Nullable
private static ErrorResponse handleConflictException(Throwable t) {
if (t instanceof ConcurrencyFailureException) {
return ErrorResponse.builder(t, ProblemDetail.forStatus(HttpStatus.CONFLICT))
.type(URI.create(CONFLICT_TYPE))
.titleMessageCode("problemDetail.title.conflict")
.detailMessageCode("problemDetail.conflict")
.build();
}
return null;
}


public static Locale getLocale(ServerWebExchange exchange) {
var locale = exchange.getLocaleContext().getLocale();
return locale == null ? Locale.getDefault() : locale;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,7 @@ private Mono<Device> updateExistingDevice(ServerWebExchange exchange) {
var userAgent =
exchange.getRequest().getHeaders().getFirst(HttpHeaders.USER_AGENT);
var deviceUa = existingDevice.getSpec().getUserAgent();
var ipAddr = existingDevice.getSpec().getIpAddress();
var clientIp = getClientIp(exchange.getRequest());
if (!StringUtils.equals(deviceUa, userAgent)
|| !StringUtils.equals(clientIp, ipAddr)) {
if (!StringUtils.equals(deviceUa, userAgent)) {
// User agent changed, create a new device
return Mono.empty();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ problemDetail.title.run.halo.app.infra.exception.PluginDependencyException$Wrong
problemDetail.title.run.halo.app.infra.exception.PluginDependentsNotDisabledException=Dependents Not Disabled
problemDetail.title.run.halo.app.infra.exception.PluginDependenciesNotEnabledException=Dependencies Not Enabled
problemDetail.title.internalServerError=Internal Server Error
problemDetail.title.conflict=Conflict

# Detail definitions
problemDetail.org.springframework.web.server.UnsupportedMediaTypeStatusException=Content type {0} is not supported. Supported media types: {1}.
Expand Down Expand Up @@ -72,6 +73,7 @@ problemDetail.directoryTraversal=Directory traversal detected. Base path is {0},
problemDetail.plugin.version.unsatisfied.requires=Plugin requires a minimum system version of {0}, but the current version is {1}.
problemDetail.plugin.missingManifest=Missing plugin manifest file "plugin.yaml" or manifest file does not conform to the specification.
problemDetail.internalServerError=Something went wrong, please try again later.
problemDetail.conflict=Conflict detected, please check the data and retry.
problemDetail.migration.backup.notFound=The backup file does not exist or has been deleted.

title.visibility.identification.private=(Private)
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ problemDetail.title.run.halo.app.infra.exception.PluginDependencyException$Wrong
problemDetail.title.run.halo.app.infra.exception.PluginDependentsNotDisabledException=子插件未禁用
problemDetail.title.run.halo.app.infra.exception.PluginDependenciesNotEnabledException=依赖未启用
problemDetail.title.internalServerError=服务器内部错误
problemDetail.title.conflict=冲突

problemDetail.org.springframework.security.authentication.BadCredentialsException=用户名或密码错误。
problemDetail.run.halo.app.infra.exception.AttachmentAlreadyExistsException=文件 {0} 已存在,建议更名后重试。
Expand Down Expand Up @@ -44,6 +45,7 @@ problemDetail.theme.version.unsatisfied.requires=主题要求一个最小的系
problemDetail.theme.install.missingManifest=缺少 theme.yaml 配置文件或配置文件不符合规范。
problemDetail.theme.install.alreadyExists=主题 {0} 已存在。
problemDetail.internalServerError=服务器内部发生错误,请稍候再试。
problemDetail.conflict=检测到冲突,请检查数据后重试。
problemDetail.migration.backup.notFound=备份文件不存在或已删除。

title.visibility.identification.private=(私有)
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.dao.ConcurrencyFailureException;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ProblemDetail;
import org.springframework.http.ResponseEntity;
import org.springframework.test.web.reactive.server.WebTestClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
Expand Down Expand Up @@ -117,6 +119,21 @@ void shouldGetErrorIfThrowingGeneralException() {
});
}

@Test
void shouldGetConflictError() {
webClient.put().uri("/response-entity/conflict-error")
.header("X-XSRF-TOKEN", "fake-token")
.cookie("XSRF-TOKEN", "fake-token")
.exchange()
.expectStatus().isEqualTo(HttpStatus.CONFLICT)
.expectBody(ProblemDetail.class)
.value(problemDetail -> {
assertEquals("Conflict", problemDetail.getTitle());
assertEquals("Conflict detected.",
problemDetail.getDetail());
});
}

@TestConfiguration
static class TestConfig {

Expand Down Expand Up @@ -156,6 +173,10 @@ ResponseEntity<String> throwGeneralException() {
throw new GeneralException("Something went wrong");
}

@PutMapping("/conflict-error")
ResponseEntity<String> throwConflictException() {
throw new ConcurrencyFailureException("Conflict detected");
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion application/src/test/resources/application.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ spring:
mode: always
platform: h2
messages:
basename: config.i18n.messages
basename: config.i18n.messages

halo:
work-dir: ${user.home}/halo-next-test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,7 @@ problemDetail.internalServerError=Something went wrong, please try again later.

problemDetail.run.halo.app.infra.exception.handlers.I18nExceptionTest$ErrorResponseException=Message argument is {0}.
error.somethingWentWrong=Something went wrong, argument is {0}.
problemDetail.title.internalServerError=Internal Server Error
problemDetail.title.internalServerError=Internal Server Error

problemDetail.title.conflict=Conflict
problemDetail.conflict=Conflict detected.
3 changes: 0 additions & 3 deletions ui/console-src/modules/contents/pages/SinglePageEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -431,9 +431,6 @@ async function handleUploadImage(file: File, options?: AxiosRequestConfig) {
if (!currentUserHasPermission(["uc:attachments:manage"])) {
return;
}
if (!isUpdateMode.value) {
await handleSave();
}
const { data } = await ucApiClient.storage.attachment.createAttachmentForPost(
{
Expand Down
4 changes: 0 additions & 4 deletions ui/console-src/modules/contents/posts/PostEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -456,10 +456,6 @@ async function handleUploadImage(file: File, options?: AxiosRequestConfig) {
return;
}
if (!isUpdateMode.value) {
await handleSave();
}
const { data } = await ucApiClient.storage.attachment.createAttachmentForPost(
{
file,
Expand Down
6 changes: 5 additions & 1 deletion ui/packages/editor/src/extensions/text/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import ColorBubbleItem from "@/extensions/color/ColorBubbleItem.vue";
import HighlightBubbleItem from "@/extensions/highlight/HighlightBubbleItem.vue";
import LinkBubbleButton from "@/extensions/link/LinkBubbleButton.vue";
import { RangeSelection } from "@/extensions/range-selection";
import { i18n } from "@/locales";
import type { EditorState } from "@/tiptap/pm";
import { isActive, isTextSelection } from "@/tiptap/vue-3";
Expand Down Expand Up @@ -56,7 +57,10 @@ const Text = TiptapText.extend<ExtensionOptions>({
return false;
}

if (!isTextSelection(selection)) {
if (
!isTextSelection(selection) &&
!(selection instanceof RangeSelection)
) {
return false;
}

Expand Down
3 changes: 0 additions & 3 deletions ui/uc-src/modules/contents/posts/PostEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -422,9 +422,6 @@ async function handleUploadImage(file: File, options?: AxiosRequestConfig) {
if (!currentUserHasPermission(["uc:attachments:manage"])) {
return;
}
if (!isUpdateMode.value) {
await handleCreate();
}
const { data } = await ucApiClient.storage.attachment.createAttachmentForPost(
{
Expand Down

0 comments on commit a9725df

Please sign in to comment.