Skip to content

Commit

Permalink
Refactor AList attachment handler and AList verification (#19)
Browse files Browse the repository at this point in the history
  • Loading branch information
JohnNiang authored Sep 12, 2024
1 parent 6a39426 commit 3d787dc
Show file tree
Hide file tree
Showing 4 changed files with 297 additions and 287 deletions.
17 changes: 8 additions & 9 deletions src/main/java/run/halo/alist/config/AListProperties.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package run.halo.alist.config;

import jakarta.validation.constraints.NotBlank;
import java.net.URL;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
Expand All @@ -17,25 +19,22 @@
@NoArgsConstructor
@Builder
public class AListProperties {

/**
* AList 站点地址.
*/
private String site;
@NotBlank
private URL site;

/**
* AList 基本路径下文件夹的路径.
*/
private String path;

/**
* Secret name.
*/
@NotBlank
private String secretName;

/**
* 获取 token key.
*
* @return token key
*/
public String getTokenKey() {
return site + secretName;
}
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
package run.halo.alist.controller;

import java.util.Objects;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.server.ServerWebInputException;
import org.springframework.web.util.UriComponentsBuilder;
import reactor.core.publisher.Mono;
import run.halo.alist.config.AListProperties;
import run.halo.alist.dto.AListResult;
import run.halo.alist.dto.request.AListGetFileInfoReq;
import run.halo.alist.dto.response.AListGetCurrentUserInfoRes;
import run.halo.alist.dto.response.AListGetFileInfoRes;
import run.halo.alist.endpoint.AListAttachmentHandler;
import run.halo.alist.exception.AListIllegalArgumentException;
import run.halo.app.extension.ReactiveExtensionClient;
import run.halo.app.plugin.ApiVersion;

/**
Expand All @@ -29,79 +31,61 @@
@RequiredArgsConstructor
@Slf4j
public class PolicyConfigValidationController {

private final AListAttachmentHandler handler;

@PostMapping("/configs/-/verify")
public Mono<Void> validatePolicyConfig(@RequestBody AListProperties properties) {
return handler.removeTokenCache(properties)
.then(
handler.auth(properties)
.flatMap(token -> handler.getWebClients()
.get(properties.getSite())
.get()
.uri("/api/me")
.header(HttpHeaders.AUTHORIZATION, token)
.retrieve()
.bodyToMono(
new ParameterizedTypeReference<AListResult<AListGetCurrentUserInfoRes>>() {
})
.flatMap(response -> {
if (response.getCode().equals("401")) {
return Mono.error(new AListIllegalArgumentException(
"Current user is disabled"));
}
if (!response.getCode().equals("200")) {
return Mono.error(new AListIllegalArgumentException(
"Wrong Username Or Password"));
}
AListGetCurrentUserInfoRes userInfo = response.getData();
return handler.getWebClients()
.get(properties.getSite())
.post()
.uri("/api/fs/get")
.header(HttpHeaders.AUTHORIZATION, token)
.body(Mono.just(AListGetFileInfoReq.builder()
.path("/")
.build()),
AListGetFileInfoReq.class)
.retrieve()
.bodyToMono(
new ParameterizedTypeReference<AListResult<AListGetFileInfoRes>>() {
})
.flatMap(res -> {
// 验证当前基本路径是否可用
if (!res.getCode().equals("200")) {
return Mono.error(
new AListIllegalArgumentException(res.getMessage()));
}
// 管理员用户拥有所有权限
if (userInfo.getRole() == 2) {
return Mono.empty();
}
// 普通用户验证权限
int permission = userInfo.getPermission();
StringBuilder sb = new StringBuilder();
if ((permission & 2) == 0) {
sb.append("无需密码访问权限 ");
}
if ((permission & 8) == 0) {
sb.append("创建目录或上传权限 ");
}
if ((permission & 128) == 0) {
sb.append("删除权限 ");
}
if (!sb.isEmpty()) {
sb.append("未开启");
return Mono.error(
new AListIllegalArgumentException(sb.toString()));
}
return Mono.empty();
});
private final ReactiveExtensionClient client;

@PostMapping("/configs/-/verify")
public Mono<AListGetCurrentUserInfoRes> validatePolicyConfig(
@RequestBody AListProperties properties) {
// check if the current user has permissions
return handler.getToken(properties)
.flatMap(token -> {
var getMeUri = UriComponentsBuilder.fromHttpUrl(properties.getSite().toString())
.path("/api/me")
.toUriString();
return handler.getWebClient().get().uri(getMeUri)
.header(HttpHeaders.AUTHORIZATION, token)
.retrieve()
.bodyToMono(
new ParameterizedTypeReference<AListResult<AListGetCurrentUserInfoRes>>() {
})

)
);
.flatMap(result -> {
if (!Objects.equals(HttpStatus.OK.value(), result.getCode())) {
return Mono.error(
new ServerWebInputException(
"Failed to get AList user info: " + result.getMessage()
)
);
}
return Mono.just(result.getData());
})
.flatMap(userInfo -> {
if (userInfo.isDisabled()) {
return Mono.error(
new ServerWebInputException("Current user is disabled")
);
}
// role = 2 means admin which permissions is 0.
if (userInfo.getRole() != 2) {
int perm = userInfo.getPermission();
// Permission "Make dir or upload": 0b1000 = 8
// Permission "Delete": 0b1000_0000 = 128
if ((perm & 0b1000_0000) == 0 || (perm & 0b1000) == 0) {
return Mono.error(
new ServerWebInputException("""
Current user has insufficient permissions. \
Make sure select "Make dir or upload" and "Delete" \
permissions for the user in AList.\
"""
)
);
}
}
return Mono.just(userInfo);
});
});
}
}

2 changes: 1 addition & 1 deletion src/main/java/run/halo/alist/dto/AListResult.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
@NoArgsConstructor
@Builder
public class AListResult <T>{
private String code;
private Integer code;
private String message;
private T data;
}
Loading

0 comments on commit 3d787dc

Please sign in to comment.