DigitalPlatform / dp2

Integrated Library System / 图书馆集成系统
http://digitalplatform.github.io/dp2
Apache License 2.0
107 stars 54 forks source link

dp2library 共享文件夹功能 #1125

Open DigitalPlatform opened 2 years ago

DigitalPlatform commented 2 years ago

dp2library 最新版增加了一个共享文件夹功能。

通过在 library.xml 中用 fileShare 元素定义用于共享的文件夹:

    <fileShare>
        <directory name="data" path="c:\data" read="*" />
        <directory name="document" path="c:\document" read="supervisor,catalog" />
    </fileShare>

其中,每一个 directory 元素定义一个独立的共享文件夹。name 属性定义文件夹显示的名字,path 属性定义文件夹的物理路径, read 属性定义哪些用户可以读取这个文件夹。

read 属性如果缺省,则任何用户都不可以读取这个文件夹。也就是说必须定义 read 属性,才能让这个文件夹被真正共享。

用内务的系统管理窗的“内核”属性页,可以看到所定义的共享文件夹,名字就是 directory 元素 name 属性定义的那个名字。

目前仅支持查看和读取共享文件夹中的文件,不支持修改和写入这些文件。

DigitalPlatform commented 2 years ago

测试要点

1) 由于 dp2library 中原有的数据目录本身的共享访问功能代码被改动了,所以原有的功能全部都要回归测试。

当账户具有权限 managedatabase 或 backup 的时候,这个用户可以上传和删除数据目录 backup 子目录的能力。 当账户具有权限 managedatabase 或 upload 的时候,这个用户可以上传和删除数据目录 upload 子目录的能力。

当一个账户没有权限 managedatabase 和 upload 的时候,能查看数据目录 upload 子目录内的文件。(这一点是否科学,可以探讨一下)

2) 原有的内务启动大备份同时下载大备份文件;或者单独到系统管理窗“内核”属性页下载这些备份文件的功能,要回归测试。

3) 针对新功能,在 library.xml 中配置 fileShare 元素定义的共享文件夹,要利用内务系统管理窗“内核”属性页进行各项测试。

4) 针对原有的数据目录的 upload 子目录,dp2libraryConsole 命令行前端可以列目录,上传和下载文件、目录,这些功能需要回归测试。(dp2libraryConsole 的使用方法另行介绍)

5) 内务系统管理窗“内核”属性页的编辑配置文件对话框,当所编辑的文件名的扩展名为 .md 时,会出现 MarkDown 预览属性页

DigitalPlatform commented 2 years ago

dp2library ListFile() API 分析

        public LibraryServerResult ListFile(
            string strAction,
            string strCategory,
            string strFileName,
            long lStart,
            long lLength,
            out List<FileItemInfo> infos)

    // API ListFile()所使用的结构
    [DataContract(Namespace = "http://dp2003.com/dp2library/")]
    public class FileItemInfo
    {
        [DataMember]
        public string Name = ""; // 文件(或目录)名
        [DataMember]
        public string CreateTime = "";   // 创建时间。本地时间 "u" 字符串
        [DataMember]
        public string LastWriteTime = "";   // 本地时间 "u" 字符串
        [DataMember]
        public string LastAccessTime = "";   // 本地时间 "u" 字符串

        [DataMember]
        public long Size = 0;   // 尺寸。-1 表示这是目录对象
    }

参数 strAction 是要执行的动作。可用值 list/cd/delete,分别是列目录、切换目录、删除。

参数 strCategory 是目录。

参数 strFileName 是文件名。常用来表示匹配模式,例如 *.txt

参数 lStart 是希望返回的事项集合的起点偏移量。

参数 lLength 是希望返回的事项集合的元素数量。-1 表示尽量多地返回。

参数 infos 是返回的事项集合。每个元素的类型是 FileItemInfo。

函数的返回值是 LibraryServerResult 类型。result.Value 中如果为 -1 表示失败;为其他值则表示事项的总数。注意,一次 API 调用,info 参数中不一定可以返回全部事项,所以需要用 result.Value 来表示事项的总数。

权限检查

delete

当执行 "delete" 动作的时候,函数先要检查当前用户针对 strCategory 目录的权限是否满足删除要求。

这是通过调用 LibraryApplication::CheckWriteResRights() 函数实现的:

        // return:
        //      -1  error
        //      0   不具备权限
        //      1   具备权限
        public int CheckWriteResRights(
            string strLibraryCodeList,
            string strRights,
            string strResPath,
            out string strLibraryCode,
            out string strError)

(疑问:为何不参考 strFileName 参数?因为它里面一般是匹配模式)

针对 !backup!cfgs 目录(及其下的文件和子目录),要求当前账户具有 backup 或 managedatabase 权限。 针对 !upload 目录(及其下的文件和子目录),要求当前账户具有 upload 或 managedatabase 权限。 针对 !library.xml 文件,要求当前账户具有 managedatabase 权限。

其余的子目录或者文件不支持删除操作。(注:共享文件夹也是不支持删除操作)

为了防范攻击,函数还专门限定了所删除的目录和文件不能越过 数据目录\上述一级子目录(即 backup cfgs 或 upload)这个根。

如果 strCategory 中是表达的书目库路径,例如 中文图书/cfgs/browse中文图书/1,则进行如下权限检查:

当前账户如果具备 managedatabase 权限,则所有路径被允许操作。否则,

如果 strCategory 中是 中文图书/cfgs/template 这样的形态,要求当前账户具备 writetemplate 权限。 如果 strCategory 中是 中文图书/1中文图书/?这样的形态,要求当前账户具备 writerecord 权限。 如果 strCategory 中是 中文图书/1/object/1 这样的形态,要求当前账户具备 writeobject 权限。 上面描述的形态以外的其他的、属于书目库的路径形态,要求当前账户具备 writeres 权限。

如果 strCategory 中是表达的读者库路径,例如 读者/cfgs/browse读者/1,则进行如下权限检查:

首先要求当前用户是全局账户,或者是分馆账户、拥有对这个读者库的管辖权。 如果 strCategory 中是 读者/cfgs/template 这样的形态,要求当前账户具备 writetemplate 权限。 如果 strCategory 中是 读者/1读者/?这样的形态,不允许操作(即不允许修改读者 XML 记录)。 如果 strCategory 中是 读者/1/object/1 这样的形态,要求当前账户具备 writeobject 权限。 上面描述的形态以外的其他的、属于读者库的路径形态,要求当前账户具备 writeres 权限。

如果 strCategory 中表达的是评注库、实体库、期库、订购库的路径,处理原则同上读者库路径的原则。

如果 strCategory 中表达的是实用库的路径,处理原则同上书目库路径的原则。

list cd

当执行 "list" 或 "cd" 动作的时候,函数先要检查当前用户针对 strCategory 目录的权限是否满足读取要求。

这是通过调用 LibraryApplication::CheckGetResRights() 函数实现的:

        // return:
        //      -1  error
        //      0   不具备权限
        //      1   具备权限
        //      2   具备部分权限
        public int CheckGetResRights(
            SessionInfo sessioninfo,
            string strLibraryCodeList,
            string strRights,
            string strResPath,
            out string strLibraryCode,
            out string strFilePath,
            out string strError)

针对 ! 开头的目录,代表 dp2library 的数据目录。library.xml 中 fileShare 元素定义的共享文件夹命名是自由的。 当前账户至少要有 download 和 backup 权限之一,才被允许访问它们。

如果当前账户不具备权限 managedatabase 或 backup,能列出的 dp2library 数据目录下的第一级目录名被限定为 upload。

对于共享文件夹,当前账户还应符合 library.xml 中 fileShare/directory/@read 属性值要求(read 属性值为星号,或属性值的账户名列表中包含当前账户名)

如果当前账户具备 writeres 或 writeobject 权限,则可以访问所有数据库记录和其下的对象记录。

对于书目库下属的 cfgs 子目录内的配置文件,无论什么账户都可以访问。对于书目库下属的数据库记录,无论什么账户都可以访问。对于书目库下属的数据库记录下属的对象记录,比较复杂,此处略去介绍,以后补充。