refactor: rename api group for custom api (#2419)

#### What type of PR is this?
/kind improvement
/kind api-change
/area core
/milestone 2.0

#### What this PR does / why we need it:
- 修改管理后台使用的自定义 API 的 group 为 `api.console.halo.run`
- 面向三方应用的自定义 API 的 group 为 `api.halo.run`
- 插件的自定义 API 的 group 为 `api.plugin.halo.run`

#### Which issue(s) this PR fixes:

Fixes #2418

#### Special notes for your reviewer:
/cc @halo-dev/sig-halo 
#### Does this PR introduce a user-facing change?

```release-note
None
```
pull/2429/head
guqing 2022-09-20 00:24:35 +08:00 committed by GitHub
parent 9fdc9c1bb7
commit a39cf2645e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 55 additions and 54 deletions

View File

@ -2,7 +2,7 @@
系统自定义 API 是一组特殊的 API因为自定义模型 API 无法满足要求,需要开发者自己实现。
但是系统自定义 API 有一个统一的前缀:`/apis/api.halo.run/v1alpha1/`,剩余的部分可随意定义。
但是系统自定义 API 有一个统一的前缀:`/apis/api.console.halo.run/v1alpha1/`,剩余的部分可随意定义。
## 如何在系统中创建一个系统自定义 API
@ -39,7 +39,7 @@ public class UserEndpoint implements CustomEndpoint {
return SpringdocRouteBuilder.route()
.GET("/users/-", this::me, builder -> builder.operationId("GetCurrentUserDetail")
.description("Get current user detail")
.tag("api.halo.run/v1alpha1/User")
.tag("api.console.halo.run/v1alpha1/User")
.response(responseBuilder().implementation(User.class)))
// 这里可添加其他自定义 API
.build();

View File

@ -43,7 +43,7 @@ public class SwaggerConfig {
.group("extension-api")
.displayName("Extension APIs")
.pathsToMatch("/apis/**")
.pathsToExclude("/apis/api.halo.run/**", "/apis/plugin.api.halo.run/**")
.pathsToExclude("/apis/api.console.halo.run/**", "/apis/api.plugin.halo.run/**")
.build();
}
@ -52,7 +52,7 @@ public class SwaggerConfig {
return GroupedOpenApi.builder()
.group("core-custom-api")
.displayName("Custom APIs in Core")
.pathsToMatch("/apis/api.halo.run/**")
.pathsToMatch("/apis/api.console.halo.run/**")
.build();
}
@ -61,7 +61,7 @@ public class SwaggerConfig {
return GroupedOpenApi.builder()
.group("plugin-custom-api")
.displayName("Custom APIs in Plugin")
.pathsToMatch("/apis/plugin.api.halo.run/**")
.pathsToMatch("/apis/api.plugin.halo.run/**")
.build();
}

View File

@ -48,7 +48,7 @@ public class CommentEndpoint implements CustomEndpoint {
@Override
public RouterFunction<ServerResponse> endpoint() {
final var tag = "api.halo.run/v1alpha1/Comment";
final var tag = "api.console.halo.run/v1alpha1/Comment";
return SpringdocRouteBuilder.route()
.GET("comments", this::listComments, builder -> {
builder.operationId("ListComments")

View File

@ -36,7 +36,7 @@ public class ContentEndpoint implements CustomEndpoint {
@Override
public RouterFunction<ServerResponse> endpoint() {
final var tag = "api.halo.run/v1alpha1/Content";
final var tag = "api.console.halo.run/v1alpha1/Content";
return SpringdocRouteBuilder.route()
.GET("contents/{snapshotName}", this::obtainContent,
builder -> builder.operationId("ObtainSnapshotContent")

View File

@ -22,12 +22,12 @@ public class CustomEndpointsBuilder {
public RouterFunction<ServerResponse> build() {
return SpringdocRouteBuilder.route()
.nest(RequestPredicates.path("/apis/api.halo.run/v1alpha1"),
.nest(RequestPredicates.path("/apis/api.console.halo.run/v1alpha1"),
() -> routerFunctions.stream().reduce(RouterFunction::and).orElse(null),
builder -> builder
.operationId("CustomEndpoints")
.description("Custom endpoints")
.tag("api.halo.run/v1alpha1/CustomEndpoint"))
.tag("api.console.halo.run/v1alpha1/CustomEndpoint"))
.build();
}
}

View File

@ -44,7 +44,7 @@ public class PluginEndpoint implements CustomEndpoint {
@Override
public RouterFunction<ServerResponse> endpoint() {
final var tag = "api.halo.run/v1alpha1/Plugin";
final var tag = "api.console.halo.run/v1alpha1/Plugin";
return SpringdocRouteBuilder.route()
.POST("plugins/install", contentType(MediaType.MULTIPART_FORM_DATA),
this::install, builder -> builder.operationId("InstallPlugin")

View File

@ -39,7 +39,7 @@ public class PostEndpoint implements CustomEndpoint {
@Override
public RouterFunction<ServerResponse> endpoint() {
final var tag = "api.halo.run/v1alpha1/Post";
final var tag = "api.console.halo.run/v1alpha1/Post";
return SpringdocRouteBuilder.route()
.GET("posts", this::listPost, builder -> {
builder.operationId("ListPosts")

View File

@ -32,7 +32,7 @@ public class ReplyEndpoint implements CustomEndpoint {
@Override
public RouterFunction<ServerResponse> endpoint() {
final var tag = "api.halo.run/v1alpha1/Reply";
final var tag = "api.console.halo.run/v1alpha1/Reply";
return SpringdocRouteBuilder.route()
.GET("replies", this::listReplies, builder -> {
builder.operationId("ListReplies")

View File

@ -39,7 +39,7 @@ public class SinglePageEndpoint implements CustomEndpoint {
@Override
public RouterFunction<ServerResponse> endpoint() {
final var tag = "api.halo.run/v1alpha1/SinglePage";
final var tag = "api.console.halo.run/v1alpha1/SinglePage";
return SpringdocRouteBuilder.route()
.GET("singlepages", this::listSinglePage, builder -> {
builder.operationId("ListSinglePages")

View File

@ -71,7 +71,7 @@ public class ThemeEndpoint implements CustomEndpoint {
@Override
public RouterFunction<ServerResponse> endpoint() {
final var tag = "api.halo.run/v1alpha1/Theme";
final var tag = "api.console.halo.run/v1alpha1/Theme";
return SpringdocRouteBuilder.route()
.POST("themes/install", contentType(MediaType.MULTIPART_FORM_DATA),
this::install, builder -> builder.operationId("InstallTheme")

View File

@ -47,7 +47,7 @@ public class UserEndpoint implements CustomEndpoint {
@Override
public RouterFunction<ServerResponse> endpoint() {
var tag = "api.halo.run/v1alpha1/User";
var tag = "api.console.halo.run/v1alpha1/User";
return SpringdocRouteBuilder.route()
.GET("/users/-", this::me, builder -> builder.operationId("GetCurrentUserDetail")
.description("Get current user detail")

View File

@ -128,7 +128,7 @@ public class PluginRequestMappingHandlerMapping extends RequestMappingHandlerMap
protected String buildPrefix(String pluginId, String version) {
GroupVersion groupVersion = GroupVersion.parseAPIVersion(version);
return String.format("/apis/plugin.api.halo.run/%s/plugins/%s", groupVersion.version(),
return String.format("/apis/api.plugin.halo.run/%s/plugins/%s", groupVersion.version(),
pluginId);
}
}

View File

@ -6,6 +6,6 @@ metadata:
halo.run/role-template: "true"
halo.run/hidden: "true"
rules:
- apiGroups: [ "api.halo.run" ]
- apiGroups: [ "api.console.halo.run" ]
resources: [ "comments", "comments/reply" ]
verbs: [ "create" ]

View File

@ -19,7 +19,7 @@ metadata:
halo.run/role-template: "true"
halo.run/hidden: "true"
rules:
- apiGroups: [ "api.halo.run" ]
- apiGroups: [ "api.console.halo.run" ]
resources: [ "users" ]
resourceNames: [ "-" ]
verbs: [ "list", "get" ]
@ -32,7 +32,7 @@ metadata:
halo.run/role-template: "true"
halo.run/hidden: "true"
rules:
- apiGroups: [ "api.halo.run" ]
- apiGroups: [ "api.console.halo.run" ]
resources: [ "users/permissions" ]
resourceNames: [ "-" ]
verbs: [ "list", "get" ]
@ -45,7 +45,7 @@ metadata:
halo.run/role-template: "true"
halo.run/hidden: "true"
rules:
- apiGroups: [ "api.halo.run" ]
- apiGroups: [ "api.console.halo.run" ]
resources: [ "users/password" ]
resourceNames: [ "-" ]
verbs: [ "update" ]

View File

@ -11,7 +11,7 @@ metadata:
rbac.authorization.halo.run/ui-permissions: |
["system:permissions:manage"]
rules:
- apiGroups: [ "api.halo.run" ]
- apiGroups: [ "api.console.halo.run" ]
resources: [ "users/permissions" ]
verbs: [ "create", "patch", "update", "delete", "deletecollection" ]
---
@ -27,6 +27,6 @@ metadata:
rbac.authorization.halo.run/ui-permissions: |
["system:permissions:view"]
rules:
- apiGroups: [ "api.halo.run" ]
- apiGroups: [ "api.console.halo.run" ]
resources: [ "users/permissions" ]
verbs: [ "get", "list" ]

View File

@ -43,6 +43,6 @@ metadata:
rbac.authorization.halo.run/module: "Users Management"
rbac.authorization.halo.run/display-name: "User Password Change"
rules:
- apiGroups: [ "api.halo.run" ]
- apiGroups: [ "api.console.halo.run" ]
resources: [ "users/password" ]
verbs: [ "update" ]

View File

@ -76,7 +76,7 @@ class UserEndpointTest {
void shouldResponseErrorIfUserNotFound() {
when(client.get(User.class, "fake-user"))
.thenReturn(Mono.error(new ExtensionNotFoundException()));
webClient.get().uri("/apis/api.halo.run/v1alpha1/users/-")
webClient.get().uri("/apis/api.console.halo.run/v1alpha1/users/-")
.exchange()
.expectStatus().is5xxServerError();
@ -90,7 +90,7 @@ class UserEndpointTest {
var user = new User();
user.setMetadata(metadata);
when(client.get(User.class, "fake-user")).thenReturn(Mono.just(user));
webClient.get().uri("/apis/api.halo.run/v1alpha1/users/-")
webClient.get().uri("/apis/api.console.halo.run/v1alpha1/users/-")
.exchange()
.expectStatus().isOk()
.expectHeader().contentType(MediaType.APPLICATION_JSON)
@ -108,7 +108,7 @@ class UserEndpointTest {
var user = new User();
when(userService.updateWithRawPassword("fake-user", "new-password"))
.thenReturn(Mono.just(user));
webClient.put().uri("/apis/api.halo.run/v1alpha1/users/-/password")
webClient.put().uri("/apis/api.console.halo.run/v1alpha1/users/-/password")
.bodyValue(new UserEndpoint.ChangePasswordRequest("new-password"))
.exchange()
.expectStatus().isOk()
@ -123,7 +123,8 @@ class UserEndpointTest {
var user = new User();
when(userService.updateWithRawPassword("another-fake-user", "new-password"))
.thenReturn(Mono.just(user));
webClient.put().uri("/apis/api.halo.run/v1alpha1/users/another-fake-user/password")
webClient.put()
.uri("/apis/api.console.halo.run/v1alpha1/users/another-fake-user/password")
.bodyValue(new UserEndpoint.ChangePasswordRequest("new-password"))
.exchange()
.expectStatus().isOk()
@ -149,7 +150,7 @@ class UserEndpointTest {
@Test
void shouldGetBadRequestIfRequestBodyIsEmpty() {
webClient.post().uri("/apis/api.halo.run/v1alpha1/users/fake-user/permissions")
webClient.post().uri("/apis/api.console.halo.run/v1alpha1/users/fake-user/permissions")
.contentType(MediaType.APPLICATION_JSON)
.exchange()
.expectStatus().isBadRequest();
@ -165,7 +166,7 @@ class UserEndpointTest {
.thenReturn(Mono.error(new ResponseStatusException(HttpStatus.NOT_FOUND)));
when(client.get(Role.class, "fake-role")).thenReturn(Mono.just(mock(Role.class)));
webClient.post().uri("/apis/api.halo.run/v1alpha1/users/fake-user/permissions")
webClient.post().uri("/apis/api.console.halo.run/v1alpha1/users/fake-user/permissions")
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(new UserEndpoint.GrantRequest(Set.of("fake-role")))
.exchange()
@ -181,7 +182,7 @@ class UserEndpointTest {
when(client.get(Role.class, "fake-role"))
.thenReturn(Mono.error(new ResponseStatusException(HttpStatus.NOT_FOUND)));
webClient.post().uri("/apis/api.halo.run/v1alpha1/users/fake-user/permissions")
webClient.post().uri("/apis/api.console.halo.run/v1alpha1/users/fake-user/permissions")
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(new UserEndpoint.GrantRequest(Set.of("fake-role")))
.exchange()
@ -197,7 +198,7 @@ class UserEndpointTest {
var role = mock(Role.class);
when(client.get(Role.class, "fake-role")).thenReturn(Mono.just(role));
webClient.post().uri("/apis/api.halo.run/v1alpha1/users/fake-user/permissions")
webClient.post().uri("/apis/api.console.halo.run/v1alpha1/users/fake-user/permissions")
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(new UserEndpoint.GrantRequest(Set.of("fake-role")))
.exchange()
@ -219,7 +220,7 @@ class UserEndpointTest {
when(client.list(same(RoleBinding.class), any(), any()))
.thenReturn(Flux.fromIterable(List.of(roleBinding)));
webClient.post().uri("/apis/api.halo.run/v1alpha1/users/fake-user/permissions")
webClient.post().uri("/apis/api.console.halo.run/v1alpha1/users/fake-user/permissions")
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(new UserEndpoint.GrantRequest(Set.of("fake-role"))).exchange()
.expectStatus().isOk();
@ -253,7 +254,7 @@ class UserEndpointTest {
when(userService.listRoles(eq("fake-user"))).thenReturn(
Flux.fromIterable(List.of(roleA)));
webClient.get().uri("/apis/api.halo.run/v1alpha1/users/fake-user/permissions")
webClient.get().uri("/apis/api.console.halo.run/v1alpha1/users/fake-user/permissions")
.exchange()
.expectStatus()
.isOk()

View File

@ -70,7 +70,7 @@ class PluginRequestMappingHandlerMappingTest {
assertThat(info.getPatternsCondition().getPatterns()).isEqualTo(
Collections.singleton(
new PathPatternParser().parse(
"/apis/plugin.api.halo.run/v1alpha1/plugins/fakePlugin/user/{id}")));
"/apis/api.plugin.halo.run/v1alpha1/plugins/fakePlugin/user/{id}")));
}
@Test
@ -95,7 +95,7 @@ class PluginRequestMappingHandlerMappingTest {
List<RequestMappingInfo> mappings = handlerMapping.getMappings("fakePlugin");
assertThat(mappings).hasSize(1);
assertThat(mappings.get(0).toString()).isEqualTo(
"{GET /apis/plugin.api.halo.run/v1alpha1/plugins/fakePlugin/user/{id}}");
"{GET /apis/api.plugin.halo.run/v1alpha1/plugins/fakePlugin/user/{id}}");
}
@Test
@ -122,7 +122,7 @@ class PluginRequestMappingHandlerMappingTest {
// get handler by mock exchange
ServerWebExchange exchange =
MockServerWebExchange.from(
get("/apis/plugin.api.halo.run/v1alpha1/plugins/fakePlugin/foo"));
get("/apis/api.plugin.halo.run/v1alpha1/plugins/fakePlugin/foo"));
HandlerMethod hm = (HandlerMethod) this.handlerMapping.getHandler(exchange).block();
assertThat(hm).isNotNull();
@ -137,7 +137,7 @@ class PluginRequestMappingHandlerMappingTest {
Method expected =
ResolvableMethod.on(TestController.class).annot(getMapping("/foo").params("p")).build();
String requestPath = "/apis/plugin.api.halo.run/v1alpha1/plugins/fakePlugin/foo?p=anything";
String requestPath = "/apis/api.plugin.halo.run/v1alpha1/plugins/fakePlugin/foo?p=anything";
ServerWebExchange exchange = MockServerWebExchange.from(get(requestPath));
HandlerMethod hm = (HandlerMethod) this.handlerMapping.getHandler(exchange).block();
@ -152,7 +152,7 @@ class PluginRequestMappingHandlerMappingTest {
Method expected =
ResolvableMethod.on(TestController.class).annot(getMapping("")).build();
String requestPath = "/apis/plugin.api.halo.run/v1alpha1/plugins/fakePlugin";
String requestPath = "/apis/api.plugin.halo.run/v1alpha1/plugins/fakePlugin";
ServerWebExchange exchange = MockServerWebExchange.from(get(requestPath));
HandlerMethod hm = (HandlerMethod) this.handlerMapping.getHandler(exchange).block();
@ -165,7 +165,7 @@ class PluginRequestMappingHandlerMappingTest {
// register handler methods first
handlerMapping.registerHandlerMethods("fakePlugin", new TestController());
String requestPath = "/apis/plugin.api.halo.run/v1alpha1/plugins/fakePlugin/bar";
String requestPath = "/apis/api.plugin.halo.run/v1alpha1/plugins/fakePlugin/bar";
ServerWebExchange exchange = MockServerWebExchange.from(post(requestPath));
Mono<Object> mono = this.handlerMapping.getHandler(exchange);

View File

@ -89,21 +89,21 @@ public class RequestInfoResolverTest {
void pluginsScopedAndPluginManage() {
List<CustomSuccessCase> testCases =
List.of(
new CustomSuccessCase("DELETE", "/apis/plugin.api.halo.run/v1/plugins/other/posts",
"delete", "apis", "plugin.api.halo.run", "v1", "", "plugins", "posts", "", "",
new CustomSuccessCase("DELETE", "/apis/api.plugin.halo.run/v1/plugins/other/posts",
"delete", "apis", "api.plugin.halo.run", "v1", "", "plugins", "posts", "", "",
new String[] {"plugins", "other", "posts"}),
// api group identification
new CustomSuccessCase("POST",
"/apis/plugin.api.halo.run/v1/plugins/other/posts/foo",
"/apis/api.plugin.halo.run/v1/plugins/other/posts/foo",
"create", "apis",
"plugin.api.halo.run", "v1", "", "plugins", "posts", "other", "foo",
"api.plugin.halo.run", "v1", "", "plugins", "posts", "other", "foo",
new String[] {"plugins", "other", "posts", "foo"}),
// api version identification
new CustomSuccessCase("POST",
"/apis/plugin.api.halo.run/v1beta3/plugins/other/posts/bar", "create",
"apis", "plugin.api.halo.run", "v1beta3", "", "plugins", "posts", "other",
"/apis/api.plugin.halo.run/v1beta3/plugins/other/posts/bar", "create",
"apis", "api.plugin.halo.run", "v1beta3", "", "plugins", "posts", "other",
"bar",
new String[] {"plugins", "other", "posts", "bar"}));
@ -119,14 +119,14 @@ public class RequestInfoResolverTest {
List<CustomSuccessCase> pluginScopedCases =
List.of(
new CustomSuccessCase("DELETE", "/apis/plugin.api.halo.run/v1/plugins/other/posts",
"delete", "apis", "plugin.api.halo.run", "v1", "", "plugins", "posts",
new CustomSuccessCase("DELETE", "/apis/api.plugin.halo.run/v1/plugins/other/posts",
"delete", "apis", "api.plugin.halo.run", "v1", "", "plugins", "posts",
"other", "", new String[] {"plugins", "other", "posts"}),
// api group identification
new CustomSuccessCase("POST",
"/apis/plugin.api.halo.run/v1/plugins/other/posts/some-name", "create", "apis",
"plugin.api.halo.run", "v1", "other", "plugins", "posts", "other", "some-name",
"/apis/api.plugin.halo.run/v1/plugins/other/posts/some-name", "create", "apis",
"api.plugin.halo.run", "v1", "other", "plugins", "posts", "other", "some-name",
new String[] {"plugins", "other", "posts", "some-name"}));
for (CustomSuccessCase pluginScopedCase : pluginScopedCases) {
@ -180,9 +180,9 @@ public class RequestInfoResolverTest {
new PolicyRule.Builder().apiGroups("").resources("posts").verbs("list", "get")
.build(),
new PolicyRule.Builder().apiGroups("").resources("categories").verbs("*").build(),
new PolicyRule.Builder().apiGroups("plugin.api.halo.run").resources("plugins/users")
new PolicyRule.Builder().apiGroups("api.plugin.halo.run").resources("plugins/users")
.resourceNames("foo/bar").verbs("*").build(),
new PolicyRule.Builder().apiGroups("plugin.api.halo.run").resources("plugins/users")
new PolicyRule.Builder().apiGroups("api.plugin.halo.run").resources("plugins/users")
.resourceNames("foo").verbs("*").build(),
new PolicyRule.Builder().nonResourceURLs("/healthy").verbs("get", "post", "head")
.build());
@ -239,11 +239,11 @@ public class RequestInfoResolverTest {
new RequestResolveCase("/apis/group/v1/posts", "GET", false),
// plugin custom resource url
new RequestResolveCase("/apis/plugin.api.halo.run/v1alpha1/plugins/foo/users", "GET",
new RequestResolveCase("/apis/api.plugin.halo.run/v1alpha1/plugins/foo/users", "GET",
true),
new RequestResolveCase("/apis/plugin.api.halo.run/v1alpha1/plugins/foo/users/bar",
new RequestResolveCase("/apis/api.plugin.halo.run/v1alpha1/plugins/foo/users/bar",
"GET", true),
new RequestResolveCase("/apis/plugin.api.halo.run/v1alpha1/plugins/foo/posts/bar",
new RequestResolveCase("/apis/api.plugin.halo.run/v1alpha1/plugins/foo/posts/bar",
"GET", false),
// non resource url