《电子技术应用》
您所在的位置:首页 > 其他 > 设计应用 > 基于Web的SVN权限管理系统的设计与实现
基于Web的SVN权限管理系统的设计与实现
来源:微型机与应用2013年第11期
张存超,任洪敏
(上海海事大学 信息工程学院,上海 201306)
摘要: 设计和实现一款基于Web的SVN权限管理系统,完成SVN用户权限全面解析、权限信息编辑和分级授权等功能,并在前台提供基于用户/组和基于版本库路径的两种视图机制,以简化SVN权限管理。
Abstract:
Key words :

摘  要: 设计和实现一款基于Web的SVN权限管理系统,完成SVN用户权限全面解析、权限信息编辑和分级授权等功能,并在前台提供基于用户/组和基于版本库路径的两种视图机制,以简化SVN权限管理。
关键词: SVN;访问控制权限解析;分级授权

 随着软件开发规模的不断扩大和开发复杂性的不断提高,软件配置管理[1]在软件工程领域中的地位大大提高。软件配置管理SCM(Software Configuration Management)是一种标识、组织和控制修改的技术,它确保了正确实现变更并将变更报告给相关人员。把软件配置管理应用于整个软件开发过程,提高了软件开发的效率。
 软件配置管理活动要求有明确的角色、职责和权限的定义,一般地,组织内的所有人员应当根据系统赋予的权限来执行相应动作。所以一款良好的软件配置管理工具应当能对角色权限进行精确的解析,SVN(Subversion)允许权限管理员手工编辑各版本库[2]的权限配置文件,实现权限管理。然而,随着用户数量不断增加,依靠极少数管理员手工维护配置文件将困难重重,这体现在用户数量增加,使得权限配置文件内容过多,增加了管理员理解和管理难度,不允许普通用户做权限配置,而往往管理员数量却又极为有限;依靠手工操作配置文件易引入冗余及其他错误信息,无法保证文件内容的简洁性和正确性;缺少友好简易的可视化管理界面等。
 本文基于SVN权限配置文件,设计和实现一个基于Web的SVN权限管理系统,提供如下功能:独立开发权限解析模块,精确解析用户在所有版本库(分布式的多个版本库亦可)中的权限信息,提供多种视图机制查看和管理解析结果;检测和避免冗余和错误信息,保持权限配置文件的简洁;允许用户分级授权[3],使得项目中每个成员都能充当SVN权限管理者,更好地配合项目开发。
1 SVN及其管理工具的研究现状
 SVN是一个开源版本控制系统,管理随时间改变的数据,这些数据放置在一个版本库[2](Repository)中。版本库会记录每一次文件和目录的改动,可以把数据恢复到旧的版本,或是浏览数据的变动历史。
SVN的工作流程为:用户通过客户端向服务器端发出请求,通过身份验证后,可以向SVN服务器的指定版本库目录提交工作拷贝,或者从版本库中取出所需的文档或代码等数据。在做诸如检出(Checkout)、更新(Update)、提交(Commit)等各项操作时,仍需进行权限验证,检查用户对当前目录中的文件是否具有读写权限。
 权限验证作为SVN服务端的工作,贯穿于SVN操作的整个过程,传统的Subversion权限管理靠人工维护文本配置文件来完成,耗时耗力,易出错。近年来国内外都在研发SVN服务端的管理工具。其中,国外VisualSVN Server[4]集成了Subversion和Apache,开始实现对SVN的WEB管理,且其提供了包括权限管理在内的可视化界面,操作的友好性提高,但权限和用户信息管理仍掌握在极少数经验丰富的SVN服务器管理员手中;国内的SVN俱乐部开发的“SVN管家[5]”允许用户注册,远程修改个人信息及查看个人权限,提供了基于版本库级和基于目录级的远程权限设置等;开源软件“Submin”提供了基于Web浏览器的SVN管理接口,功能包括用户、用户组的管理、路径权限的设置等,兼容各种浏览器,界面更加优化。
然而,因权限管理工作难度的限制,上述工具的使用者仍是少数具备相关知识的专门管理员,使得工具使用的普遍性较低。本系统则致力于优化SVN权限管理,一方面提供不同视图角度更为全面的权限信息,提高交互性;另一方面支持分级授权,将大大降低权限管理的难度。
2 SVN权限管理系统的设计
 SVN权限管理系统设计框架如图1所示。

 系统总体分为两大模块:权限解析模块和权限信息维护模块。前者用于读取和解析多个版本库(分布式的版本库亦可)配置文件,并将各文件解析结果整合,发送到客户端浏览器;后者涉及对权限配置文件的维护,包括对组信息和权限规则的修改,还包括对冗余信息的检测和避免。此模块所做操作最终将更新到各配置文件中。
2.1 SVN权限解析模块的设计
 传统上,SVN客户端与服务端交互的方式是,用户在客户端输入用户名和版本库路径,提交至服务端,服务端则解析此用户对路径是否有读权限,若有则将路径下的内容(包括文件和文件夹)显示给用户,否则告知用户无权访问。
本系统在权限解析方面将做如下改进:客户端仅需给定用户名,无需给定版本库路径,而靠权限解析模块解析出多个相关版本库中用户有权限的所有路径信息(包括路径名称和对路径具有的权限)。
2.1.1 权限配置文件简介
 SVN的权限配置信息保存在一个文本文件中(默认路径是各版本库“conf”子目录下的“authz”文件)。以下为权限文件部分内容(‘#’表示单行注释):
###组定义
[groups]
group=user1,user2
###基于版本库路径的授权方式
[Repo:/SubPath]
user=r
@group=rw
*=
[Repo:/SubPath/abc]
user3=r
user3=w
 权限配置文件内容包含组定义和权限规则定义。组定义以“[groups]”为开始标记,定义格式为“组名=用户名1,用户名2……”,组与组之间允许嵌套;SVN采取基于版本库路径[6]的显示方式定义用户权限。对于版本库“Repo”下的“SubPath”子路径,用户“user”有只读权限,组“group”有读写权限(‘@’为组标识),其他用户(‘*’指代除“user”和“group”之外的其他用户,也包括匿名用户)则无任何权限。此外,用户权限具有“继承性”,即若子路径下未改变用户权限,则用户对子路径将继承对父路径拥有的权限。如user对“[Repo:/SubPath/abc]”有从“[Repo:/SubPath]”继承来的读权限。SVN授权的另一个特点是权限之间的“覆盖”,如“user=w”将覆盖“user=r”,使得“user3”对“[Repo:/SubPath/abc]”仅有写权限。
2.1.2 权限解析类图设计
 根据2.1.1节内容,设计的权限解析模块类图如图2(仅给出权限解析所需要的类、成员变量和方法等)所示。

 其中,“User”类和“Group”类分别代表用户和组;“AccessLevel”类代表权限,且只允许四种权限:Read(只读)、Write(只写)、ReadAndWrite(读写)和NoneAccess(无读写权限);“AccessRule”类代表一条权限规则(如“user=rw”);“RepoPath”类代表版本库路径,定义格式为“[版本库名称:/子路径]”;“AccessRulesUnit”类代表一条版本库路径及其下的若干规则集合(例如2.1.1节配置文件内容中的部分),是反映“基于路径授权”的基本单元;“AccessManager”类是权限管理类,包括了权限解析和管理的几乎所有方法。执行“AccessManager”构造函数会将配置文件中所有组定义封装到“groupList”中,将权限规则定义封装到“unitList”中。
2.1.3 权限解析的核心方法实现
 “AccessManager”类中的“parseRootPaths”和“parseLevel”方法是权限解析的核心方法。其中“parseRootPaths”方法对给定的用户(或组),将解析出其在配置文件中有权限的所有版本库路径(鉴于权限在路径间的继承性,相同版本库下的路径集合只需解析出最顶层路径即可);“parseLevel”方法用于判断指定用户(或组)对指定版本库路径具有的权限。
 以上两个方法能正确执行的前提条件是已调用“AccessManager”中的“sortUnitList”方法(作为权限解析前的预处理工作,见图1),使得在“unitList”中所有“AccessRulesUnit”对象可以“按序”排列,以最大程度降低权限解析的难度。这里的“按序”规则如下:从“unitList”中取出所有“AccessRulesUnit”对象中的“RepoPath”成员,使得所有“RepoPath”按版本库名称分类存放,并保证同一版本库下子路径排列在父路径之前。一种路径“按序”排列的示例为:

 [Repo1:/SubPath/abc]
 [Repo1:/SubPath]
 [Repo1:/]
 [Repo2:/SubPath/abc]
 [Repo2:/]
 [/]###是所有版本库路径的根目录
 “RepoPath”的排列顺序即其所在的“AccessRulesUnit”对象在“unitList”中的顺序。
 “parseRootPaths”方法(参数以user为例,group亦可)伪码如下(使用java语言描述):
 List parseRootPaths(User user){
 if(isEmpty(unitList))return null;
 List pathList=new LinkedList<RepoPath>();
 RepoPath currentPath=firstElem(unitList).path;
 /*add用于判断在pathList中做添加元素还是覆盖元素操作*/
 boolean add=false;
 for(AccessRulesUnit unit:unitList){
 RepoPath path=unit.path;
 if(!isInSameRepository(currentPath,path)){
 add=true;
        currentPath=path;
 }
 AccessRule rule=
 new AccessRule(user,ReadLevel);
 if(unit.hasAccessRule(rule)){
 /*add为true说明之前已找到一个最顶层路径或当前扫描到新的版本库里的路径*/
         if(add || isEmpty(pathList))
 addElem(pathList,path);
   /* false说明当前找到更高层的路径,应覆盖上次找到的路径(为pathList中的最后一个元素)*/
 else replaceLastElem(pathList, path);
    add = false;
         continue ;
 }
 /*当前unit不包含rule,说明当前pathList
 末尾元素即是一个最顶层路径*/
 add = true ;
    }
   return pathList ;
 }
 “parseLevel”方法(参数以user为例,group亦可)伪码如下(使用java语言描述):
 AccessLevel parseLevel(User user, RepoPath path){
    boolean findPathOrParentPath = false ;
   for(int index = 0; index < unitList.size(); index ++){
 AccessRulesUnit unit = unitList.get(index);
 if(!unit.hasPathOrParentPath(path)){
 /*若findPathOrParentPath为true,说明所有与path同版本库的路径均已检查过,因已执行过“sortUnitList”方法,之后不在同版本库的路径不必检查,直接跳到unitList最后一个元素(可能包含“[/]”)即可*/
         if(findPathOrParentPath){
            index=unitList.size()-1;
unit = unitList.get(index) ;
      if(!unit.hasPath(new RepoPath("[/]")))
         break ;
         }else continue;
}
findPathOrParentPath = true ;
if(unit.hasUser(user)){
         //返回含有user的规则中的权限
    return unit.getRule(user).level;
}
if(unit.hasAnonymousRule()){
         return unit.getAnonymousRule().level;
}
   }
   return NoneAccess;
}
 执行上述两方法可确保在做权限解析时,最坏情况下“unitList”至多被迭代访问一次即可(T(n)=O(n),n为unitList的长度),相比未采取优化策略时(T(n)至少为O(n2)),大大降低了解析难度,避免了对“unitList”多次迭代访问。
2.2 权限信息维护模块的设计
2.2.1 分级授权和权限撤销

 传统上权限配置都由专门的SVN管理员完成,而本系统所做改进则是实现了分级配置、分级授权和权限撤销。
 分级授权是使权限配置工作分散化的做法,目的是降低管理员的压力,也使各用户充分参与其中,更好地配合软件开发过程。本系统通过分级授权,使得不用依靠专门的SVN管理员,用户可将自己对路径的访问权限授予他人(所有用户/组对任何人都是可见的,但并非任何人都能修改用户/组信息),每个项目组成员都可成为权限管理者,从根本上简化了SVN权限管理工作。
 对于权限的撤销,为了防止配置混乱,用户的权限仅能由授予者撤销,若在此之前此用户已将权限授予他人,则做权限的级联撤销。
2.2.2 冗余权限规则的避免
 授权操作频繁,预示着权限文件内容的不断增加,随之冗余权限规则也极易出现,考虑以下情形:
 (1)重复定义引起的冗余。如在2.1.1节配置文件内容中添加了如下规则:“user=r”或者“@newGroup=r(组‘newGroup’中包含了‘user’用户)”。
 (2)权限覆盖引起的冗余(见2.1.1节配置文件内容,“user=w”覆盖了“user=r”,使后者成为无效冗余规则)。
 为了保持权限文件内容的简洁清晰,优化查询权限的效率,避免引入冗余信息十分重要。本文采取的方法是,授权之前先调用“AccessManager”中的“parseLevel”方法检查被授权的用户对路径是否已具有相同权限,有则无需授权。
3 SVN权限管理系统界面管理
 本系统登录后的界面如图3和图4所示(当前登录者为拥有系统最多权限的管理员)。

 前台界面主要使用了JQuery EasyUI(一组基于jQuery的UI插件集合)中的Treegrid、Datagrid、Tabs、Dialog等组件,提供了清晰友好的交互界面。
 本系统前台界面所做改进是提供了两种视图机制管理用户权限,包括用户/组视图和版本库路径视图。图3给出了用户/组视图,针对当前选中的用户/组,经解析模块,将给出其有权限的版本库顶层路径集合及对应的权限。图4是版本库路径视图,针对选中的版本库路径,解析出对此路径有权限的所有用户/组及对应权限。两种视图机制下均允许用户进行权限配置(使用分级授权的思想),提高了系统与用户的交互性,降低了权限管理的难度。
 传统SVN用户权限管理是通过维护一个文本配置文件来完成的,用户人数的增多使得依靠少数管理员人工理解和维护配置文件困难重重。本文在深入理解SVN权限配置的基础上,设计和实现了一个基于Web的SVN权限管理系统,针对用户提供更加全面的权限信息;提出使用基于角色的分级授权机制,各个项目组可独立管理本组用户权限;前台提供基于用户/组和基于版本库路径两种视图机制,使权限管理更加简单直观。
参考文献
[1] 王强,曹汉平,贾素玲.IT软件项目管理[M].北京:清华大学出版社,2005.
[2] Ben Collins-Sussman, Brian W. Fitzpatrick, C. Michael Pilato. Subversion权威指南(针对Subversion 1.7)[M/OL]. 2004.
[3] 郭军.基于角色的访问控制分级授权管理的研究[D].西安:西安电子科技大学,2012.
[4] 纪洲鹏,赵斐斐.可视化版本控制在.Net三层架构开发中的应用[J].软件导刊,2013(1):89-90.
[5] SVN Club. SVN管家(Windows版本)项目[EB/OL].http://www.svnclub.com,[2012-02].
[6] 曾绍庚.Linux SVN服务器权限精确控制的实现[J].信息与电脑(理论版),2011(7):163-164.

此内容为AET网站原创,未经授权禁止转载。