From 324c6c519f96039a40c7078ce5b7f7d036532c9f Mon Sep 17 00:00:00 2001 From: messense Date: Thu, 23 Dec 2021 20:36:00 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=8F=AA=E8=AF=BB=E6=A8=A1?= =?UTF-8?q?=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 禁止上传、修改和删除文件 --- Cargo.lock | 4 +-- .../files/aliyundrive-webdav.config | 1 + .../files/aliyundrive-webdav.init | 7 +++++ .../model/cbi/aliyundrive-webdav/client.lua | 4 +++ .../po/zh-cn/aliyundrive-webdav.po | 6 ++++ src/main.rs | 26 +++++++++++----- src/vfs.rs | 31 +++++++++++++++++++ 7 files changed, 69 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 39e0619ffb..c2448d399d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1534,9 +1534,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.82" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8daf5dd0bb60cbd4137b1b587d2fc0ae729bc07cf01cd70b36a1ed5ade3b9d59" +checksum = "23a1dfb999630e338648c83e91c59a4e9fb7620f520c3194b6b89e276f2f1959" dependencies = [ "proc-macro2", "quote", diff --git a/openwrt/aliyundrive-webdav/files/aliyundrive-webdav.config b/openwrt/aliyundrive-webdav/files/aliyundrive-webdav.config index 66a4ef1afa..e5d041268f 100644 --- a/openwrt/aliyundrive-webdav/files/aliyundrive-webdav.config +++ b/openwrt/aliyundrive-webdav/files/aliyundrive-webdav.config @@ -12,3 +12,4 @@ config server option root '/' option no_trash '0' option domain_id '' + option read_only '0' diff --git a/openwrt/aliyundrive-webdav/files/aliyundrive-webdav.init b/openwrt/aliyundrive-webdav/files/aliyundrive-webdav.init index f8faf91f97..b274edc265 100755 --- a/openwrt/aliyundrive-webdav/files/aliyundrive-webdav.init +++ b/openwrt/aliyundrive-webdav/files/aliyundrive-webdav.init @@ -38,6 +38,13 @@ start_service() { ;; *) ;; esac + + case "$(uci_get_by_type server read_only 0)" in + 1|on|true|yes|enabled) + extra_options="$extra_options --read-only" + ;; + *) ;; + esac fi procd_open_instance diff --git a/openwrt/luci-app-aliyundrive-webdav/luasrc/model/cbi/aliyundrive-webdav/client.lua b/openwrt/luci-app-aliyundrive-webdav/luasrc/model/cbi/aliyundrive-webdav/client.lua index 7cdbf8842e..ec6d324eac 100644 --- a/openwrt/luci-app-aliyundrive-webdav/luasrc/model/cbi/aliyundrive-webdav/client.lua +++ b/openwrt/luci-app-aliyundrive-webdav/luasrc/model/cbi/aliyundrive-webdav/client.lua @@ -47,6 +47,10 @@ cache_ttl.datatype = "uinteger" no_trash = e:option(Flag, "no_trash", translate("Delete file permanently instead of trashing")) no_trash.rmempty = false +read_only = e:option(Flag, "read_only", translate("Enable read only mode")) +read_only.description = translate("Disallow upload, modify and delete file operations") +read_only.rmempty = false + domain_id = e:option(Value, "domain_id", translate("Domain ID")) domain_id.description = translate("Input domain_id option will use Aliyun PDS instead of AliyunDrive") diff --git a/openwrt/luci-app-aliyundrive-webdav/po/zh-cn/aliyundrive-webdav.po b/openwrt/luci-app-aliyundrive-webdav/po/zh-cn/aliyundrive-webdav.po index 09718aab18..84d8c51620 100644 --- a/openwrt/luci-app-aliyundrive-webdav/po/zh-cn/aliyundrive-webdav.po +++ b/openwrt/luci-app-aliyundrive-webdav/po/zh-cn/aliyundrive-webdav.po @@ -67,6 +67,12 @@ msgstr "限制只能访问该云盘目录,默认为 / 表示不限制,注意 msgid "Delete file permanently instead of trashing" msgstr "删除文件不放入回收站" +msgid "Enable read only mode" +msgstr "启用只读模式" + +msgid "Disallow upload, modify and delete file operations" +msgstr "禁止上传、修改和删除文件操作" + msgid "Domain ID" msgstr "阿里云相册与云盘服务 domainId" diff --git a/src/main.rs b/src/main.rs index 162a99e28a..d91349ee12 100644 --- a/src/main.rs +++ b/src/main.rs @@ -56,6 +56,9 @@ struct Opt { /// Aliyun PDS domain id #[structopt(long)] domain_id: Option, + /// Enable read only mode + #[structopt(long)] + read_only: bool, } #[tokio::main(flavor = "multi_thread")] @@ -104,14 +107,21 @@ async fn main() -> anyhow::Result<()> { .map_err(|_| { io::Error::new(io::ErrorKind::Other, "initialize aliyundrive client failed") })?; - let fs = AliyunDriveFileSystem::new(drive, opt.root, opt.cache_size, opt.cache_ttl, no_trash) - .await - .map_err(|_| { - io::Error::new( - io::ErrorKind::Other, - "initialize aliyundrive file system failed", - ) - })?; + let fs = AliyunDriveFileSystem::new( + drive, + opt.root, + opt.cache_size, + opt.cache_ttl, + no_trash, + opt.read_only, + ) + .await + .map_err(|_| { + io::Error::new( + io::ErrorKind::Other, + "initialize aliyundrive file system failed", + ) + })?; debug!("aliyundrive file system initialized"); let dav_server = DavHandler::builder() diff --git a/src/vfs.rs b/src/vfs.rs index e7f53fb2bc..68a106bec6 100644 --- a/src/vfs.rs +++ b/src/vfs.rs @@ -31,6 +31,7 @@ pub struct AliyunDriveFileSystem { uploading: Arc>>, root: PathBuf, no_trash: bool, + read_only: bool, } impl AliyunDriveFileSystem { @@ -40,6 +41,7 @@ impl AliyunDriveFileSystem { cache_size: usize, cache_ttl: u64, no_trash: bool, + read_only: bool, ) -> Result { let dir_cache = Cache::new(cache_size, cache_ttl); debug!("dir cache initialized"); @@ -54,6 +56,7 @@ impl AliyunDriveFileSystem { uploading: Arc::new(DashMap::new()), root, no_trash, + read_only, }) } @@ -210,6 +213,10 @@ impl DavFileSystem for AliyunDriveFileSystem { if options.write && options.create_new { return Err(FsError::Exists); } + if options.write && self.read_only { + return Err(FsError::Forbidden); + } + if let Some(size) = options.size { // 上传中的文件刚开始 size 可能为 0,更新为正确的 size if file.size == 0 { @@ -218,6 +225,10 @@ impl DavFileSystem for AliyunDriveFileSystem { } AliyunDavFile::new(self.clone(), file, parent_file.id) } else if options.write && (options.create || options.create_new) { + if self.read_only { + return Err(FsError::Forbidden); + } + let size = options.size; let name = dav_path .file_name() @@ -282,6 +293,10 @@ impl DavFileSystem for AliyunDriveFileSystem { let path = self.normalize_dav_path(dav_path); debug!(path = %path.display(), "fs: create_dir"); async move { + if self.read_only { + return Err(FsError::Forbidden); + } + let parent_path = path.parent().ok_or(FsError::NotFound)?; let parent_file = self .get_file(parent_path.to_path_buf()) @@ -312,6 +327,10 @@ impl DavFileSystem for AliyunDriveFileSystem { let path = self.normalize_dav_path(dav_path); debug!(path = %path.display(), "fs: remove_dir"); async move { + if self.read_only { + return Err(FsError::Forbidden); + } + let file = self .get_file(path.clone()) .await? @@ -336,6 +355,10 @@ impl DavFileSystem for AliyunDriveFileSystem { let path = self.normalize_dav_path(dav_path); debug!(path = %path.display(), "fs: remove_file"); async move { + if self.read_only { + return Err(FsError::Forbidden); + } + let file = self .get_file(path.clone()) .await? @@ -361,6 +384,10 @@ impl DavFileSystem for AliyunDriveFileSystem { let to = self.normalize_dav_path(to_dav); debug!(from = %from.display(), to = %to.display(), "fs: copy"); async move { + if self.read_only { + return Err(FsError::Forbidden); + } + let file = self .get_file(from.clone()) .await? @@ -390,6 +417,10 @@ impl DavFileSystem for AliyunDriveFileSystem { let to = self.normalize_dav_path(to_dav); debug!(from = %from.display(), to = %to.display(), "fs: rename"); async move { + if self.read_only { + return Err(FsError::Forbidden); + } + if from.parent() == to.parent() { // rename if let Some(name) = to.file_name() {