From 68faba24bf46bb141ebdfc00291dc6ee506038c2 Mon Sep 17 00:00:00 2001 From: xausky Date: Mon, 21 Mar 2022 22:05:21 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E5=88=86=E4=BA=AB?= =?UTF-8?q?=E8=BF=9E=E6=8E=A5=E7=9A=84=E8=A7=A3=E6=9E=90=E5=92=8C=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=EF=BC=88=E5=8F=AA=E8=AF=BB=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../client/AliYunDriverClient.java | 30 +++++++- .../config/AliYunDriverCronTask.java | 2 +- .../model/DownloadRequest.java | 20 +++++ .../model/FileListRequest.java | 10 +++ .../model/ShareTokenRequest.java | 24 ++++++ .../model/result/ShareTokenResult.java | 36 +++++++++ .../webdavteambition/model/result/TFile.java | 10 +++ .../store/AliYunDriverClientService.java | 74 +++++++++++++------ .../store/AliYunDriverFileSystemStore.java | 2 +- 9 files changed, 183 insertions(+), 25 deletions(-) create mode 100644 src/main/java/com/github/zxbu/webdavteambition/model/ShareTokenRequest.java create mode 100644 src/main/java/com/github/zxbu/webdavteambition/model/result/ShareTokenResult.java diff --git a/src/main/java/com/github/zxbu/webdavteambition/client/AliYunDriverClient.java b/src/main/java/com/github/zxbu/webdavteambition/client/AliYunDriverClient.java index 7b5519a..5026597 100644 --- a/src/main/java/com/github/zxbu/webdavteambition/client/AliYunDriverClient.java +++ b/src/main/java/com/github/zxbu/webdavteambition/client/AliYunDriverClient.java @@ -1,6 +1,8 @@ package com.github.zxbu.webdavteambition.client; import com.github.zxbu.webdavteambition.config.AliYunDriveProperties; +import com.github.zxbu.webdavteambition.model.ShareTokenRequest; +import com.github.zxbu.webdavteambition.model.result.ShareTokenResult; import com.github.zxbu.webdavteambition.util.JsonUtil; import net.sf.webdav.exceptions.WebdavException; import okhttp3.*; @@ -18,6 +20,8 @@ import java.nio.file.LinkOption; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Collections; +import java.util.Date; +import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeUnit; @@ -25,6 +29,7 @@ public class AliYunDriverClient { private static final Logger LOGGER = LoggerFactory.getLogger(AliYunDriverClient.class); private OkHttpClient okHttpClient; private AliYunDriveProperties aliYunDriveProperties; + private Map shareTokenMapping = new HashMap<>(); public AliYunDriverClient(AliYunDriveProperties aliYunDriveProperties) { @@ -141,10 +146,18 @@ public class AliYunDriverClient { } public String post(String url, Object body) { + return post(url, body, null); + } + + public String post(String url, Object body, String shareId) { String bodyAsJson = JsonUtil.toJson(body); - Request request = new Request.Builder() + Request.Builder requestBuilder = new Request.Builder() .post(RequestBody.create(MediaType.parse("application/json; charset=utf-8"), bodyAsJson)) - .url(getTotalUrl(url)).build(); + .url(getTotalUrl(url)); + if (shareId != null){ + requestBuilder.header("X-Share-Token", readShareToken(shareId)); + } + Request request = requestBuilder.build(); try (Response response = okHttpClient.newCall(request).execute()){ LOGGER.info("post {}, body {}, code {}", url, bodyAsJson, response.code()); if (!response.isSuccessful()) { @@ -207,6 +220,19 @@ public class AliYunDriverClient { return aliYunDriveProperties.getUrl() + url; } + public synchronized String readShareToken(String shareId){ + ShareTokenResult result = shareTokenMapping.get(shareId); + if (result != null && result.getExpire_time().after(new Date())){ + return result.getShare_token(); + } + ShareTokenRequest request = new ShareTokenRequest(); + request.setShare_id(shareId); + String resultString = post("/share_link/get_share_token", request); + result = JsonUtil.readValue(resultString, ShareTokenResult.class); + shareTokenMapping.put(shareId, result); + return result.getShare_token(); + } + private void deleteRefreshTokenFile() { String refreshTokenPath = aliYunDriveProperties.getWorkDir() + "refresh-token"; Path path = Paths.get(refreshTokenPath); diff --git a/src/main/java/com/github/zxbu/webdavteambition/config/AliYunDriverCronTask.java b/src/main/java/com/github/zxbu/webdavteambition/config/AliYunDriverCronTask.java index 1a7b992..bcd899c 100644 --- a/src/main/java/com/github/zxbu/webdavteambition/config/AliYunDriverCronTask.java +++ b/src/main/java/com/github/zxbu/webdavteambition/config/AliYunDriverCronTask.java @@ -19,7 +19,7 @@ public class AliYunDriverCronTask { public void refreshToken() { try { TFile root = aliYunDriverClientService.getTFileByPath("/"); - aliYunDriverClientService.getTFiles(root.getFile_id()); + aliYunDriverClientService.getTFiles(root.getFile_id(), null); } catch (Exception e) { // nothing } diff --git a/src/main/java/com/github/zxbu/webdavteambition/model/DownloadRequest.java b/src/main/java/com/github/zxbu/webdavteambition/model/DownloadRequest.java index 67c3429..a4fa94f 100644 --- a/src/main/java/com/github/zxbu/webdavteambition/model/DownloadRequest.java +++ b/src/main/java/com/github/zxbu/webdavteambition/model/DownloadRequest.java @@ -2,7 +2,9 @@ package com.github.zxbu.webdavteambition.model; public class DownloadRequest { private String drive_id; + private String share_id; private String file_id; + private String shareToken; private Integer expire_sec = 14400; public String getDrive_id() { @@ -28,4 +30,22 @@ public class DownloadRequest { public void setExpire_sec(Integer expire_sec) { this.expire_sec = expire_sec; } + + public String getShare_id() { + return share_id; + } + + public DownloadRequest setShare_id(String share_id) { + this.share_id = share_id; + return this; + } + + public String getShareToken() { + return shareToken; + } + + public DownloadRequest setShareToken(String shareToken) { + this.shareToken = shareToken; + return this; + } } diff --git a/src/main/java/com/github/zxbu/webdavteambition/model/FileListRequest.java b/src/main/java/com/github/zxbu/webdavteambition/model/FileListRequest.java index 7779566..3a638d5 100644 --- a/src/main/java/com/github/zxbu/webdavteambition/model/FileListRequest.java +++ b/src/main/java/com/github/zxbu/webdavteambition/model/FileListRequest.java @@ -2,6 +2,7 @@ package com.github.zxbu.webdavteambition.model; public class FileListRequest extends Page{ private String drive_id; + private String share_id; private Boolean all = false; private String fields = "*"; private String image_thumbnail_process = "image/resize,w_400/format,jpeg"; @@ -9,6 +10,15 @@ public class FileListRequest extends Page{ private String parent_file_id; private String video_thumbnail_process = "video/snapshot,t_0,f_jpg,ar_auto,w_300"; + public String getShare_id() { + return share_id; + } + + public FileListRequest setShare_id(String share_id) { + this.share_id = share_id; + return this; + } + public String getDrive_id() { return drive_id; } diff --git a/src/main/java/com/github/zxbu/webdavteambition/model/ShareTokenRequest.java b/src/main/java/com/github/zxbu/webdavteambition/model/ShareTokenRequest.java new file mode 100644 index 0000000..08ed1ba --- /dev/null +++ b/src/main/java/com/github/zxbu/webdavteambition/model/ShareTokenRequest.java @@ -0,0 +1,24 @@ +package com.github.zxbu.webdavteambition.model; + +public class ShareTokenRequest { + private String share_id; + private String share_pwd; + + public String getShare_id() { + return share_id; + } + + public ShareTokenRequest setShare_id(String share_id) { + this.share_id = share_id; + return this; + } + + public String getShare_pwd() { + return share_pwd; + } + + public ShareTokenRequest setShare_pwd(String share_pwd) { + this.share_pwd = share_pwd; + return this; + } +} diff --git a/src/main/java/com/github/zxbu/webdavteambition/model/result/ShareTokenResult.java b/src/main/java/com/github/zxbu/webdavteambition/model/result/ShareTokenResult.java new file mode 100644 index 0000000..49ffcdf --- /dev/null +++ b/src/main/java/com/github/zxbu/webdavteambition/model/result/ShareTokenResult.java @@ -0,0 +1,36 @@ +package com.github.zxbu.webdavteambition.model.result; + +import java.util.Date; + +public class ShareTokenResult { + private String share_token; + private Integer expires_in; + private Date expire_time; + + public Date getExpire_time() { + return expire_time; + } + + public ShareTokenResult setExpire_time(Date expire_time) { + this.expire_time = expire_time; + return this; + } + + public String getShare_token() { + return share_token; + } + + public ShareTokenResult setShare_token(String share_token) { + this.share_token = share_token; + return this; + } + + public Integer getExpires_in() { + return expires_in; + } + + public ShareTokenResult setExpires_in(Integer expires_in) { + this.expires_in = expires_in; + return this; + } +} diff --git a/src/main/java/com/github/zxbu/webdavteambition/model/result/TFile.java b/src/main/java/com/github/zxbu/webdavteambition/model/result/TFile.java index 246bc3a..86cd257 100644 --- a/src/main/java/com/github/zxbu/webdavteambition/model/result/TFile.java +++ b/src/main/java/com/github/zxbu/webdavteambition/model/result/TFile.java @@ -20,6 +20,7 @@ public class TFile { private String url; private Long size; private String download_url; + private String share_id; public Date getCreated_at() { return created_at; @@ -148,4 +149,13 @@ public class TFile { public void setUpdated_at(Date updated_at) { this.updated_at = updated_at; } + + public String getShare_id() { + return share_id; + } + + public TFile setShare_id(String share_id) { + this.share_id = share_id; + return this; + } } diff --git a/src/main/java/com/github/zxbu/webdavteambition/store/AliYunDriverClientService.java b/src/main/java/com/github/zxbu/webdavteambition/store/AliYunDriverClientService.java index 4cc7046..390949a 100644 --- a/src/main/java/com/github/zxbu/webdavteambition/store/AliYunDriverClientService.java +++ b/src/main/java/com/github/zxbu/webdavteambition/store/AliYunDriverClientService.java @@ -24,8 +24,9 @@ import javax.servlet.http.HttpServletRequest; import java.io.IOException; import java.io.InputStream; import java.util.*; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; +import java.util.regex.Matcher; +import java.util.regex.Pattern; @Service public class AliYunDriverClientService { @@ -34,6 +35,7 @@ public class AliYunDriverClientService { private static String rootPath = "/"; private static int chunkSize = 10485760; // 10MB private TFile rootTFile = null; + private Pattern sharePatten = Pattern.compile("^.*卍([a-zA-Z0-9]{11})$"); private static Cache> tFilesCache = Caffeine.newBuilder() .initialCapacity(128) @@ -51,10 +53,10 @@ public class AliYunDriverClientService { AliYunDriverFileSystemStore.setBean(this); } - public Set getTFiles(String nodeId) { - Set tFiles = tFilesCache.get(nodeId, key -> { + public Set getTFiles(String nodeId, String shareId) { + Set tFiles = tFilesCache.get(shareId + ":" + nodeId, key -> { // 获取真实的文件列表 - return getTFiles2(nodeId); + return getTFiles2(nodeId, shareId); }); Set all = new LinkedHashSet<>(tFiles); // 获取上传中的文件列表 @@ -63,8 +65,8 @@ public class AliYunDriverClientService { return all; } - private Set getTFiles2(String nodeId) { - List tFileList = fileListFromApi(nodeId, null, new ArrayList<>()); + private Set getTFiles2(String nodeId, String shareId) { + List tFileList = fileListFromApi(nodeId, null, new ArrayList<>(), shareId); tFileList.sort(Comparator.comparing(TFile::getUpdated_at).reversed()); Set tFileSets = new LinkedHashSet<>(); for (TFile tFile : tFileList) { @@ -76,22 +78,26 @@ public class AliYunDriverClientService { return tFileSets; } - private List fileListFromApi(String nodeId, String marker, List all) { + private List fileListFromApi(String nodeId, String marker, List all, String shareId) { FileListRequest listQuery = new FileListRequest(); listQuery.setMarker(marker); listQuery.setLimit(100); listQuery.setOrder_by("updated_at"); listQuery.setOrder_direction("DESC"); - listQuery.setDrive_id(client.getDriveId()); listQuery.setParent_file_id(nodeId); - String json = client.post("/file/list", listQuery); + if (shareId != null){ + listQuery.setShare_id(shareId); + } else { + listQuery.setDrive_id(client.getDriveId()); + } + String json = client.post("/file/list", listQuery, shareId); TFileListResult tFileListResult = JsonUtil.readValue(json, new TypeReference>() { }); all.addAll(tFileListResult.getItems()); if (!StringUtils.hasLength(tFileListResult.getNext_marker())) { return all; } - return fileListFromApi(nodeId, tFileListResult.getNext_marker(), all); + return fileListFromApi(nodeId, tFileListResult.getNext_marker(), all, shareId); } @@ -283,13 +289,25 @@ public class AliYunDriverClientService { public Response download(String path, HttpServletRequest request, long size ) { TFile file = getTFileByPath(path); - DownloadRequest downloadRequest = new DownloadRequest(); - downloadRequest.setDrive_id(client.getDriveId()); - downloadRequest.setFile_id(file.getFile_id()); - String json = client.post("/file/get_download_url", downloadRequest); - Object url = JsonUtil.getJsonNodeValue(json, "url"); - LOGGER.debug("{} url = {}", path, url); - return client.download(url.toString(), request, size); + if (file.getShare_id() == null){ + DownloadRequest downloadRequest = new DownloadRequest(); + downloadRequest.setDrive_id(client.getDriveId()); + downloadRequest.setFile_id(file.getFile_id()); + String json = client.post("/file/get_download_url", downloadRequest); + Object url = JsonUtil.getJsonNodeValue(json, "url"); + LOGGER.debug("{} url = {}", path, url); + return client.download(url.toString(), request, size); + } else { + DownloadRequest downloadRequest = new DownloadRequest(); + downloadRequest.setFile_id(file.getFile_id()); + downloadRequest.setShare_id(file.getShare_id()); + downloadRequest.setShareToken(client.readShareToken(file.getShare_id())); + downloadRequest.setExpire_sec(600); + String json = client.post("/file/get_share_link_download_url", downloadRequest, file.getShare_id()); + Object url = JsonUtil.getJsonNodeValue(json, "url"); + LOGGER.debug("{} url = {}", path, url); + return client.download(url.toString(), request, size); + } } private TFile getNodeIdByPath2(String path) { @@ -304,7 +322,11 @@ public class AliYunDriverClientService { if (tFile == null ) { return null; } - return getNodeIdByParentId(tFile.getFile_id(), pathInfo.getName()); + Matcher matcher = sharePatten.matcher(pathInfo.getName()); + if (matcher.find()){ + return getShareRootTFile(matcher.group(1), pathInfo.getName()); + } + return getNodeIdByParentId(tFile.getFile_id(), tFile.getShare_id(), pathInfo.getName()); } @@ -343,14 +365,24 @@ public class AliYunDriverClientService { return rootTFile; } - private TFile getNodeIdByParentId(String parentId, String name) { - Set tFiles = getTFiles(parentId); + private TFile getShareRootTFile(String shareId, String name){ + TFile rootTFile = new TFile(); + rootTFile.setName(name); + rootTFile.setFile_id("root"); + rootTFile.setCreated_at(new Date()); + rootTFile.setUpdated_at(new Date()); + rootTFile.setType("folder"); + rootTFile.setShare_id(shareId); + return rootTFile; + } + + private TFile getNodeIdByParentId(String parentId, String shareId, String name) { + Set tFiles = getTFiles(parentId, shareId); for (TFile tFile : tFiles) { if (tFile.getName().equals(name)) { return tFile; } } - return null; } diff --git a/src/main/java/com/github/zxbu/webdavteambition/store/AliYunDriverFileSystemStore.java b/src/main/java/com/github/zxbu/webdavteambition/store/AliYunDriverFileSystemStore.java index a939ca1..3c6d068 100644 --- a/src/main/java/com/github/zxbu/webdavteambition/store/AliYunDriverFileSystemStore.java +++ b/src/main/java/com/github/zxbu/webdavteambition/store/AliYunDriverFileSystemStore.java @@ -136,7 +136,7 @@ public class AliYunDriverFileSystemStore implements IWebdavStore { if (tFile.getType().equals(FileType.file.name())) { return new String[0]; } - Set tFileList = aliYunDriverClientService.getTFiles(tFile.getFile_id()); + Set tFileList = aliYunDriverClientService.getTFiles(tFile.getFile_id(), tFile.getShare_id()); return tFileList.stream().map(TFile::getName).toArray(String[]::new); } From df04102d01302139fd1044b53004aceb247a8d50 Mon Sep 17 00:00:00 2001 From: xausky Date: Wed, 23 Mar 2022 19:25:56 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E4=BD=BF=E7=94=A8=20!=20=E4=BD=9C=E4=B8=BA?= =?UTF-8?q?=E5=85=B1=E4=BA=AB=E7=9B=AE=E5=BD=95=E8=AF=86=E5=88=AB=E7=AC=A6?= =?UTF-8?q?=E5=8F=B7=EF=BC=8C=E5=A2=9E=E5=8A=A0=E5=8A=A0=E5=AF=86=E5=88=86?= =?UTF-8?q?=E4=BA=AB=E7=9A=84=E6=94=AF=E6=8C=81=E4=BD=BF=E7=94=A8=20:=20?= =?UTF-8?q?=E7=AC=A6=E5=8F=B7=E5=90=8E=E9=9D=A2=E5=8A=A0=E5=AF=86=E7=A0=81?= =?UTF-8?q?=E7=9A=84=E6=A0=BC=E5=BC=8F=EF=BC=8C=E4=BF=AE=E5=A4=8D=E4=B8=80?= =?UTF-8?q?=E4=BA=9B=E5=AF=B9=E5=85=B1=E4=BA=AB=E7=9B=AE=E5=BD=95=E5=86=99?= =?UTF-8?q?=E5=85=A5=EF=BC=8C=E7=A7=BB=E5=8A=A8=EF=BC=8C=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=EF=BC=8C=E5=88=A0=E9=99=A4=E6=93=8D=E4=BD=9C=E7=9A=84=20BUG?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../client/AliYunDriverClient.java | 12 ++-- .../config/AliYunDriverCronTask.java | 2 +- .../webdavteambition/model/result/TFile.java | 20 +++++++ .../store/AliYunDriverClientService.java | 59 +++++++++++-------- .../store/AliYunDriverFileSystemStore.java | 25 ++++++-- 5 files changed, 84 insertions(+), 34 deletions(-) diff --git a/src/main/java/com/github/zxbu/webdavteambition/client/AliYunDriverClient.java b/src/main/java/com/github/zxbu/webdavteambition/client/AliYunDriverClient.java index 5026597..a11a208 100644 --- a/src/main/java/com/github/zxbu/webdavteambition/client/AliYunDriverClient.java +++ b/src/main/java/com/github/zxbu/webdavteambition/client/AliYunDriverClient.java @@ -146,16 +146,16 @@ public class AliYunDriverClient { } public String post(String url, Object body) { - return post(url, body, null); + return post(url, body, null, null); } - public String post(String url, Object body, String shareId) { + public String post(String url, Object body, String shareId, String sharePassword) { String bodyAsJson = JsonUtil.toJson(body); Request.Builder requestBuilder = new Request.Builder() .post(RequestBody.create(MediaType.parse("application/json; charset=utf-8"), bodyAsJson)) .url(getTotalUrl(url)); if (shareId != null){ - requestBuilder.header("X-Share-Token", readShareToken(shareId)); + requestBuilder.header("X-Share-Token", readShareToken(shareId, sharePassword)); } Request request = requestBuilder.build(); try (Response response = okHttpClient.newCall(request).execute()){ @@ -220,13 +220,15 @@ public class AliYunDriverClient { return aliYunDriveProperties.getUrl() + url; } - public synchronized String readShareToken(String shareId){ - ShareTokenResult result = shareTokenMapping.get(shareId); + public synchronized String readShareToken(String shareId, String sharePassword){ + // shareKey 为 sharePassword == null ? shareId : shareId + ":" + sharePassword + ShareTokenResult result = shareTokenMapping.get(shareId + ":" + sharePassword); if (result != null && result.getExpire_time().after(new Date())){ return result.getShare_token(); } ShareTokenRequest request = new ShareTokenRequest(); request.setShare_id(shareId); + request.setShare_pwd(sharePassword == null ? "" : sharePassword); String resultString = post("/share_link/get_share_token", request); result = JsonUtil.readValue(resultString, ShareTokenResult.class); shareTokenMapping.put(shareId, result); diff --git a/src/main/java/com/github/zxbu/webdavteambition/config/AliYunDriverCronTask.java b/src/main/java/com/github/zxbu/webdavteambition/config/AliYunDriverCronTask.java index bcd899c..3a3bcbc 100644 --- a/src/main/java/com/github/zxbu/webdavteambition/config/AliYunDriverCronTask.java +++ b/src/main/java/com/github/zxbu/webdavteambition/config/AliYunDriverCronTask.java @@ -19,7 +19,7 @@ public class AliYunDriverCronTask { public void refreshToken() { try { TFile root = aliYunDriverClientService.getTFileByPath("/"); - aliYunDriverClientService.getTFiles(root.getFile_id(), null); + aliYunDriverClientService.getTFiles(root.getFile_id(), null, null); } catch (Exception e) { // nothing } diff --git a/src/main/java/com/github/zxbu/webdavteambition/model/result/TFile.java b/src/main/java/com/github/zxbu/webdavteambition/model/result/TFile.java index 86cd257..b21c3de 100644 --- a/src/main/java/com/github/zxbu/webdavteambition/model/result/TFile.java +++ b/src/main/java/com/github/zxbu/webdavteambition/model/result/TFile.java @@ -21,6 +21,8 @@ public class TFile { private Long size; private String download_url; private String share_id; + private String share_password; + private String origin_file_id; public Date getCreated_at() { return created_at; @@ -158,4 +160,22 @@ public class TFile { this.share_id = share_id; return this; } + + public String getOrigin_file_id() { + return origin_file_id; + } + + public TFile setOrigin_file_id(String origin_file_id) { + this.origin_file_id = origin_file_id; + return this; + } + + public String getShare_password() { + return share_password; + } + + public TFile setShare_password(String share_password) { + this.share_password = share_password; + return this; + } } diff --git a/src/main/java/com/github/zxbu/webdavteambition/store/AliYunDriverClientService.java b/src/main/java/com/github/zxbu/webdavteambition/store/AliYunDriverClientService.java index 390949a..e561602 100644 --- a/src/main/java/com/github/zxbu/webdavteambition/store/AliYunDriverClientService.java +++ b/src/main/java/com/github/zxbu/webdavteambition/store/AliYunDriverClientService.java @@ -24,6 +24,7 @@ import javax.servlet.http.HttpServletRequest; import java.io.IOException; import java.io.InputStream; import java.util.*; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -35,7 +36,7 @@ public class AliYunDriverClientService { private static String rootPath = "/"; private static int chunkSize = 10485760; // 10MB private TFile rootTFile = null; - private Pattern sharePatten = Pattern.compile("^.*卍([a-zA-Z0-9]{11})$"); + private final Pattern shareNamePatten = Pattern.compile("^.*!(?[a-zA-Z0-9]{11})(?>$|:(?[a-zA-Z0-9]{4})$)"); private static Cache> tFilesCache = Caffeine.newBuilder() .initialCapacity(128) @@ -53,10 +54,10 @@ public class AliYunDriverClientService { AliYunDriverFileSystemStore.setBean(this); } - public Set getTFiles(String nodeId, String shareId) { + public Set getTFiles(String nodeId, String shareId, String sharePassword) { Set tFiles = tFilesCache.get(shareId + ":" + nodeId, key -> { // 获取真实的文件列表 - return getTFiles2(nodeId, shareId); + return getTFiles2(nodeId, shareId, sharePassword); }); Set all = new LinkedHashSet<>(tFiles); // 获取上传中的文件列表 @@ -65,11 +66,12 @@ public class AliYunDriverClientService { return all; } - private Set getTFiles2(String nodeId, String shareId) { - List tFileList = fileListFromApi(nodeId, null, new ArrayList<>(), shareId); + private Set getTFiles2(String nodeId, String shareId, String sharePassword) { + List tFileList = fileListFromApi(nodeId, null, new ArrayList<>(), shareId, sharePassword); tFileList.sort(Comparator.comparing(TFile::getUpdated_at).reversed()); Set tFileSets = new LinkedHashSet<>(); for (TFile tFile : tFileList) { + tFile.setShare_password(sharePassword); if (!tFileSets.add(tFile)) { LOGGER.info("当前目录下{} 存在同名文件:{},文件大小:{}", nodeId, tFile.getName(), tFile.getSize()); } @@ -78,7 +80,7 @@ public class AliYunDriverClientService { return tFileSets; } - private List fileListFromApi(String nodeId, String marker, List all, String shareId) { + private List fileListFromApi(String nodeId, String marker, List all, String shareId, String sharePassword) { FileListRequest listQuery = new FileListRequest(); listQuery.setMarker(marker); listQuery.setLimit(100); @@ -90,14 +92,20 @@ public class AliYunDriverClientService { } else { listQuery.setDrive_id(client.getDriveId()); } - String json = client.post("/file/list", listQuery, shareId); - TFileListResult tFileListResult = JsonUtil.readValue(json, new TypeReference>() { - }); + String json; + try { + json = client.post("/file/list", listQuery, shareId, sharePassword); + } catch (WebdavException e){ + // 无法获取列表可能是 shareId 已经失效,与其报错不如返回空,特别是使用 dav 挂载时候,报错会导致 IO 错误无法删除目录 + e.printStackTrace(); + return Collections.emptyList(); + } + TFileListResult tFileListResult = JsonUtil.readValue(json, new TypeReference>() {}); all.addAll(tFileListResult.getItems()); if (!StringUtils.hasLength(tFileListResult.getNext_marker())) { return all; } - return fileListFromApi(nodeId, tFileListResult.getNext_marker(), all, shareId); + return fileListFromApi(nodeId, tFileListResult.getNext_marker(), all, shareId, sharePassword); } @@ -219,7 +227,7 @@ public class AliYunDriverClientService { TFile tFile = getTFileByPath(sourcePath); RenameRequest renameRequest = new RenameRequest(); renameRequest.setDrive_id(client.getDriveId()); - renameRequest.setFile_id(tFile.getFile_id()); + renameRequest.setFile_id(tFile.getOrigin_file_id() != null ? tFile.getOrigin_file_id() : tFile.getFile_id()); renameRequest.setName(newName); client.post("/file/update", renameRequest); clearCache(); @@ -233,7 +241,7 @@ public class AliYunDriverClientService { TFile targetTFile = getTFileByPath(targetPath); MoveRequest moveRequest = new MoveRequest(); moveRequest.setDrive_id(client.getDriveId()); - moveRequest.setFile_id(sourceTFile.getFile_id()); + moveRequest.setFile_id(sourceTFile.getOrigin_file_id() != null ? sourceTFile.getOrigin_file_id() : sourceTFile.getFile_id()); moveRequest.setTo_parent_file_id(targetTFile.getFile_id()); client.post("/file/move", moveRequest); clearCache(); @@ -247,7 +255,7 @@ public class AliYunDriverClientService { } RemoveRequest removeRequest = new RemoveRequest(); removeRequest.setDrive_id(client.getDriveId()); - removeRequest.setFile_id(tFile.getFile_id()); + removeRequest.setFile_id(tFile.getOrigin_file_id() != null ? tFile.getOrigin_file_id() : tFile.getFile_id()); client.post("/recyclebin/trash", removeRequest); clearCache(); } @@ -301,9 +309,9 @@ public class AliYunDriverClientService { DownloadRequest downloadRequest = new DownloadRequest(); downloadRequest.setFile_id(file.getFile_id()); downloadRequest.setShare_id(file.getShare_id()); - downloadRequest.setShareToken(client.readShareToken(file.getShare_id())); + downloadRequest.setShareToken(client.readShareToken(file.getShare_id(), file.getShare_password())); downloadRequest.setExpire_sec(600); - String json = client.post("/file/get_share_link_download_url", downloadRequest, file.getShare_id()); + String json = client.post("/file/get_share_link_download_url", downloadRequest, file.getShare_id(), file.getShare_password()); Object url = JsonUtil.getJsonNodeValue(json, "url"); LOGGER.debug("{} url = {}", path, url); return client.download(url.toString(), request, size); @@ -322,11 +330,7 @@ public class AliYunDriverClientService { if (tFile == null ) { return null; } - Matcher matcher = sharePatten.matcher(pathInfo.getName()); - if (matcher.find()){ - return getShareRootTFile(matcher.group(1), pathInfo.getName()); - } - return getNodeIdByParentId(tFile.getFile_id(), tFile.getShare_id(), pathInfo.getName()); + return getNodeIdByParentId(tFile.getFile_id(), pathInfo.getName(), tFile.getShare_id(), tFile.getShare_password()); } @@ -365,7 +369,7 @@ public class AliYunDriverClientService { return rootTFile; } - private TFile getShareRootTFile(String shareId, String name){ + private TFile getShareRootTFile(String shareId, String name, String originFileId, String sharePassword){ TFile rootTFile = new TFile(); rootTFile.setName(name); rootTFile.setFile_id("root"); @@ -373,14 +377,21 @@ public class AliYunDriverClientService { rootTFile.setUpdated_at(new Date()); rootTFile.setType("folder"); rootTFile.setShare_id(shareId); + rootTFile.setOrigin_file_id(originFileId); + rootTFile.setShare_password(sharePassword); return rootTFile; } - private TFile getNodeIdByParentId(String parentId, String shareId, String name) { - Set tFiles = getTFiles(parentId, shareId); + private TFile getNodeIdByParentId(String parentId, String name, String shareId, String sharePassword) { + Set tFiles = getTFiles(parentId, shareId, sharePassword); for (TFile tFile : tFiles) { if (tFile.getName().equals(name)) { - return tFile; + Matcher matcher = shareNamePatten.matcher(name); + if (matcher.find()){ + return getShareRootTFile(matcher.group("shareId"), name, tFile.getFile_id(), matcher.group("password")); + } else { + return tFile; + } } } return null; diff --git a/src/main/java/com/github/zxbu/webdavteambition/store/AliYunDriverFileSystemStore.java b/src/main/java/com/github/zxbu/webdavteambition/store/AliYunDriverFileSystemStore.java index 3c6d068..526b988 100644 --- a/src/main/java/com/github/zxbu/webdavteambition/store/AliYunDriverFileSystemStore.java +++ b/src/main/java/com/github/zxbu/webdavteambition/store/AliYunDriverFileSystemStore.java @@ -21,12 +21,15 @@ import java.security.Principal; import java.util.Enumeration; import java.util.Optional; import java.util.Set; +import java.util.regex.Pattern; public class AliYunDriverFileSystemStore implements IWebdavStore { private static final Logger LOGGER = LoggerFactory.getLogger(AliYunDriverFileSystemStore.class); private static AliYunDriverClientService aliYunDriverClientService; + private final Pattern inSharePatten = Pattern.compile(".*!(?[a-zA-Z0-9]{11})(?>\\/.|:(?[a-zA-Z0-9]{4})\\/.)"); + public AliYunDriverFileSystemStore(File file) { } @@ -68,14 +71,18 @@ public class AliYunDriverFileSystemStore implements IWebdavStore { @Override public void createFolder(ITransaction transaction, String folderUri) { LOGGER.info("createFolder {}", folderUri); - + if (inSharePatten.matcher(folderUri).find()){ + throw new WebdavException("共享目录不可写"); + } aliYunDriverClientService.createFolder(folderUri); } @Override public void createResource(ITransaction transaction, String resourceUri) { LOGGER.info("createResource {}", resourceUri); - + if (inSharePatten.matcher(resourceUri).find()){ + throw new WebdavException("共享目录不可写"); + } } @Override @@ -103,6 +110,9 @@ public class AliYunDriverFileSystemStore implements IWebdavStore { @Override public long setResourceContent(ITransaction transaction, String resourceUri, InputStream content, String contentType, String characterEncoding) { LOGGER.info("setResourceContent {}", resourceUri); + if (inSharePatten.matcher(resourceUri).find()){ + throw new WebdavException("共享目录不可写"); + } HttpServletRequest request = transaction.getRequest(); HttpServletResponse response = transaction.getResponse(); @@ -136,7 +146,7 @@ public class AliYunDriverFileSystemStore implements IWebdavStore { if (tFile.getType().equals(FileType.file.name())) { return new String[0]; } - Set tFileList = aliYunDriverClientService.getTFiles(tFile.getFile_id(), tFile.getShare_id()); + Set tFileList = aliYunDriverClientService.getTFiles(tFile.getFile_id(), tFile.getShare_id(), tFile.getShare_password()); return tFileList.stream().map(TFile::getName).toArray(String[]::new); } @@ -160,13 +170,20 @@ public class AliYunDriverFileSystemStore implements IWebdavStore { @Override public void removeObject(ITransaction transaction, String uri) { LOGGER.info("removeObject: {}", uri); + if (inSharePatten.matcher(uri).find()){ + // 对于共享文件夹内的删除进行跳过,因为在删除共享目录时候用户使用 rm -r 'Test!Pfb5mXu2TLK' 之类的命令或者使用 GUI 删除都会递归删除子文件,如果这里报错就会导致本身的文件夹也无法删除 + LOGGER.info("removeObject skip: {}", uri); + return; + } aliYunDriverClientService.remove(uri); } @Override public boolean moveObject(ITransaction transaction, String destinationPath, String sourcePath) { LOGGER.info("moveObject, destinationPath={}, sourcePath={}", destinationPath, sourcePath); - + if (inSharePatten.matcher(destinationPath).find() || inSharePatten.matcher(sourcePath).find()){ + throw new WebdavException("共享目录不可写"); + } PathInfo destinationPathInfo = aliYunDriverClientService.getPathInfo(destinationPath); PathInfo sourcePathInfo = aliYunDriverClientService.getPathInfo(sourcePath); // 名字相同,说明是移动目录