Skip to content

Commit

Permalink
feat: 简化配置,修改挂载路径概念,适配所有非 GUEST 用户
Browse files Browse the repository at this point in the history
  • Loading branch information
Roozenlz committed Aug 2, 2024
1 parent d480c8a commit b4ef145
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 50 deletions.
6 changes: 1 addition & 5 deletions src/main/java/run/halo/alist/config/AListProperties.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,9 @@ public class AListProperties {
*/
private String site;
/**
* AList 挂载路径.
* AList 基本路径下文件夹的路径.
*/
private String path;
/**
* AList 基本路径.
*/
private String basePath;
/**
* Secret name.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
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.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import run.halo.alist.endpoint.AListAttachmentHandler;
import run.halo.alist.config.AListProperties;
import run.halo.alist.dto.AListResult;
import run.halo.alist.dto.response.AListStorageListRes;
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.plugin.ApiVersion;

Expand All @@ -39,31 +39,68 @@ public Mono<Void> validatePolicyConfig(@RequestBody AListProperties properties)
.flatMap(token -> handler.getWebClients()
.get(properties.getSite())
.get()
.uri("/api/admin/storage/list")
.uri("/api/me")
.header(HttpHeaders.AUTHORIZATION, token)
.retrieve()
.bodyToMono(
new ParameterizedTypeReference<AListResult<AListStorageListRes>>() {
new ParameterizedTypeReference<AListResult<AListGetCurrentUserInfoRes>>() {
})
.flatMap(response -> {
if (response.getCode().equals("200")) {
return Flux.fromIterable(response.getData().getContent())
.filter(volume -> Objects.equals(volume.getMountPath(),
properties.getPath()))
.switchIfEmpty(Mono.error(new AListIllegalArgumentException(
"The mount path does not exist")))
.all(volume -> !volume.isDisabled())
.filter(isValid -> isValid)
.switchIfEmpty(Mono.error(new AListIllegalArgumentException(
"The storage is disabled")))
.then();
} else if (response.getCode().equals("403")) {
if (!response.getCode().equals("200")) {
return Mono.error(new AListIllegalArgumentException(
"Wrong Username Or Password"));
}
AListGetCurrentUserInfoRes userInfo = response.getData();
if (userInfo.isDisabled()) {
return Mono.error(new AListIllegalArgumentException(
"You are not an admin"));
"User is disabled"));
}
return Mono.error(new AListIllegalArgumentException(
"Wrong Username Or Password"));
}))
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();
});

})

)
);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package run.halo.alist.dto.response;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
* @author <a href="https://roozen.top">Roozen</a>
* @version 1.0
* 2024/8/2
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class AListGetCurrentUserInfoRes {
private int id;
private String username;
private String password;
/**
* 基本路径
*/
@JsonProperty("base_path")
private String basePath;
private int role;
private boolean disabled;
private int permission;
@JsonProperty("sso_id")
private String ssoId;
/**
* 是否开启二步验证
*/
private boolean otp;
}
49 changes: 32 additions & 17 deletions src/main/java/run/halo/alist/endpoint/AListAttachmentHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.springframework.http.codec.multipart.FilePart;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.client.WebClientRequestException;
import org.springframework.web.util.UriComponentsBuilder;
import org.springframework.web.util.UriUtils;
import reactor.core.publisher.Mono;
Expand All @@ -33,6 +34,7 @@
import run.halo.alist.dto.request.AListGetFileInfoReq;
import run.halo.alist.dto.request.AListLoginReq;
import run.halo.alist.dto.request.AListRemoveFileReq;
import run.halo.alist.dto.response.AListGetCurrentUserInfoRes;
import run.halo.alist.dto.response.AListGetFileInfoRes;
import run.halo.alist.dto.response.AListLoginRes;
import run.halo.alist.dto.response.AListUploadAsTaskRes;
Expand Down Expand Up @@ -117,11 +119,8 @@ public Mono<Attachment> upload(UploadContext uploadContext) {
var metadata = new Metadata();
metadata.setName(UUID.randomUUID().toString());
metadata.setAnnotations(
Map.of(Constant.EXTERNAL_LINK_ANNO_KEY,
UriUtils.encodePath(
properties.getSite() + "/d" + properties.getPath() + "/"
+ file.name(),
StandardCharsets.UTF_8)));
Map.of(Constant.EXTERNAL_LINK_ANNO_KEY, ""));

var spec = new Attachment.AttachmentSpec();
SimpleFilePart simpleFilePart = (SimpleFilePart) file;
spec.setDisplayName(simpleFilePart.filename());
Expand Down Expand Up @@ -183,7 +182,9 @@ public Mono<String> auth(AListProperties properties) {
.retrieve()
.bodyToMono(
new ParameterizedTypeReference<AListResult<AListLoginRes>>() {
});
})
.onErrorMap(WebClientRequestException.class,
e -> new AListIllegalArgumentException(e.getMessage()));
}).flatMap(response -> {
if (response.getCode().equals("200")) {
log.info("[AList Info] : Login successfully");
Expand All @@ -198,7 +199,12 @@ public Mono<String> auth(AListProperties properties) {

private AListProperties getProperties(ConfigMap configMap) {
var settingJson = configMap.getData().getOrDefault("default", "{}");
return JsonUtils.jsonToObject(settingJson, AListProperties.class);
AListProperties aListProperties =
JsonUtils.jsonToObject(settingJson, AListProperties.class);
if (aListProperties.getPath().equals("/")) {
aListProperties.setPath("");
}
return aListProperties;
}

@Override
Expand Down Expand Up @@ -264,16 +270,25 @@ public Mono<URI> getPermalink(Attachment attachment, Policy policy, ConfigMap co
}
return Mono.error(new AListRequestErrorException(response.getMessage()));
}))
.map(response -> UriComponentsBuilder.fromHttpUrl(properties.getSite())
.path("/d{path}{basePath}/{name}")
.queryParamIfPresent("sign",
Optional.ofNullable(response.getData().getSign()).filter(s -> !s.isEmpty()))
.buildAndExpand(
properties.getPath(),
properties.getBasePath(),
response.getData().getName()
)
.toUri());
.flatMap(response -> webClients.get(properties.getSite())
.get()
.uri("/api/me")
.header(HttpHeaders.AUTHORIZATION,
tokenCache.getIfPresent(properties.getTokenKey()))
.retrieve()
.bodyToMono(
new ParameterizedTypeReference<AListResult<AListGetCurrentUserInfoRes>>() {
})
.map(res -> UriComponentsBuilder.fromHttpUrl(properties.getSite())
.path("/d{basePath}{path}/{name}")
.queryParamIfPresent("sign",
Optional.ofNullable(response.getData().getSign()).filter(s -> !s.isEmpty()))
.buildAndExpand(
res.getData().getBasePath(),
properties.getPath(),
response.getData().getName()
)
.toUri()));
}

boolean shouldHandle(Policy policy) {
Expand Down
7 changes: 1 addition & 6 deletions src/main/resources/extensions/policy-template-alist.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,7 @@ spec:
- $formkit: text
name: path
label: 挂载路径
validation: required
help: AList 存储中的挂载路径,必须以 / 开头,如 /aliyun
- $formkit: text
name: basePath
label: 基本路径
help: 所填用户的基本路径,可在 AList 管理 -> 用户 查看,必须以 / 开头,如 /aliyun,为 / 时留空即可
help: 所填用户基本路径(可在 AList 管理 -> 用户 查看)下文件夹的路径,必须以 / 开头,支持多级目录如 /picture/2024,则全路径为{基本路径}/picture/2024,上传文件时会自动创建不存在的目录,为 / 时留空即可
- $formkit: secret
name: secretName
required: true
Expand Down

0 comments on commit b4ef145

Please sign in to comment.