摘 要: 設(shè)計(jì)和實(shí)現(xiàn)一款基于Web的SVN權(quán)限管理系統(tǒng),完成SVN用戶權(quán)限全面解析、權(quán)限信息編輯和分級(jí)授權(quán)等功能,并在前臺(tái)提供基于用戶/組和基于版本庫(kù)路徑的兩種視圖機(jī)制,以簡(jiǎn)化SVN權(quán)限管理。
關(guān)鍵詞: SVN;訪問(wèn)控制;權(quán)限解析;分級(jí)授權(quán)
隨著軟件開(kāi)發(fā)規(guī)模的不斷擴(kuò)大和開(kāi)發(fā)復(fù)雜性的不斷提高,軟件配置管理[1]在軟件工程領(lǐng)域中的地位大大提高。軟件配置管理SCM(Software Configuration Management)是一種標(biāo)識(shí)、組織和控制修改的技術(shù),它確保了正確實(shí)現(xiàn)變更并將變更報(bào)告給相關(guān)人員。把軟件配置管理應(yīng)用于整個(gè)軟件開(kāi)發(fā)過(guò)程,提高了軟件開(kāi)發(fā)的效率。
軟件配置管理活動(dòng)要求有明確的角色、職責(zé)和權(quán)限的定義,一般地,組織內(nèi)的所有人員應(yīng)當(dāng)根據(jù)系統(tǒng)賦予的權(quán)限來(lái)執(zhí)行相應(yīng)動(dòng)作。所以一款良好的軟件配置管理工具應(yīng)當(dāng)能對(duì)角色權(quán)限進(jìn)行精確的解析,SVN(Subversion)允許權(quán)限管理員手工編輯各版本庫(kù)[2]的權(quán)限配置文件,實(shí)現(xiàn)權(quán)限管理。然而,隨著用戶數(shù)量不斷增加,依靠極少數(shù)管理員手工維護(hù)配置文件將困難重重,這體現(xiàn)在用戶數(shù)量增加,使得權(quán)限配置文件內(nèi)容過(guò)多,增加了管理員理解和管理難度,不允許普通用戶做權(quán)限配置,而往往管理員數(shù)量卻又極為有限;依靠手工操作配置文件易引入冗余及其他錯(cuò)誤信息,無(wú)法保證文件內(nèi)容的簡(jiǎn)潔性和正確性;缺少友好簡(jiǎn)易的可視化管理界面等。
本文基于SVN權(quán)限配置文件,設(shè)計(jì)和實(shí)現(xiàn)一個(gè)基于Web的SVN權(quán)限管理系統(tǒng),提供如下功能:獨(dú)立開(kāi)發(fā)權(quán)限解析模塊,精確解析用戶在所有版本庫(kù)(分布式的多個(gè)版本庫(kù)亦可)中的權(quán)限信息,提供多種視圖機(jī)制查看和管理解析結(jié)果;檢測(cè)和避免冗余和錯(cuò)誤信息,保持權(quán)限配置文件的簡(jiǎn)潔;允許用戶分級(jí)授權(quán)[3],使得項(xiàng)目中每個(gè)成員都能充當(dāng)SVN權(quán)限管理者,更好地配合項(xiàng)目開(kāi)發(fā)。
1 SVN及其管理工具的研究現(xiàn)狀
SVN是一個(gè)開(kāi)源版本控制系統(tǒng),管理隨時(shí)間改變的數(shù)據(jù),這些數(shù)據(jù)放置在一個(gè)版本庫(kù)[2](Repository)中。版本庫(kù)會(huì)記錄每一次文件和目錄的改動(dòng),可以把數(shù)據(jù)恢復(fù)到舊的版本,或是瀏覽數(shù)據(jù)的變動(dòng)歷史。
SVN的工作流程為:用戶通過(guò)客戶端向服務(wù)器端發(fā)出請(qǐng)求,通過(guò)身份驗(yàn)證后,可以向SVN服務(wù)器的指定版本庫(kù)目錄提交工作拷貝,或者從版本庫(kù)中取出所需的文檔或代碼等數(shù)據(jù)。在做諸如檢出(Checkout)、更新(Update)、提交(Commit)等各項(xiàng)操作時(shí),仍需進(jìn)行權(quán)限驗(yàn)證,檢查用戶對(duì)當(dāng)前目錄中的文件是否具有讀寫權(quán)限。
權(quán)限驗(yàn)證作為SVN服務(wù)端的工作,貫穿于SVN操作的整個(gè)過(guò)程,傳統(tǒng)的Subversion權(quán)限管理靠人工維護(hù)文本配置文件來(lái)完成,耗時(shí)耗力,易出錯(cuò)。近年來(lái)國(guó)內(nèi)外都在研發(fā)SVN服務(wù)端的管理工具。其中,國(guó)外VisualSVN Server[4]集成了Subversion和Apache,開(kāi)始實(shí)現(xiàn)對(duì)SVN的WEB管理,且其提供了包括權(quán)限管理在內(nèi)的可視化界面,操作的友好性提高,但權(quán)限和用戶信息管理仍掌握在極少數(shù)經(jīng)驗(yàn)豐富的SVN服務(wù)器管理員手中;國(guó)內(nèi)的SVN俱樂(lè)部開(kāi)發(fā)的“SVN管家[5]”允許用戶注冊(cè),遠(yuǎn)程修改個(gè)人信息及查看個(gè)人權(quán)限,提供了基于版本庫(kù)級(jí)和基于目錄級(jí)的遠(yuǎn)程權(quán)限設(shè)置等;開(kāi)源軟件“Submin”提供了基于Web瀏覽器的SVN管理接口,功能包括用戶、用戶組的管理、路徑權(quán)限的設(shè)置等,兼容各種瀏覽器,界面更加優(yōu)化。
然而,因權(quán)限管理工作難度的限制,上述工具的使用者仍是少數(shù)具備相關(guān)知識(shí)的專門管理員,使得工具使用的普遍性較低。本系統(tǒng)則致力于優(yōu)化SVN權(quán)限管理,一方面提供不同視圖角度更為全面的權(quán)限信息,提高交互性;另一方面支持分級(jí)授權(quán),將大大降低權(quán)限管理的難度。
2 SVN權(quán)限管理系統(tǒng)的設(shè)計(jì)
SVN權(quán)限管理系統(tǒng)設(shè)計(jì)框架如圖1所示。
系統(tǒng)總體分為兩大模塊:權(quán)限解析模塊和權(quán)限信息維護(hù)模塊。前者用于讀取和解析多個(gè)版本庫(kù)(分布式的版本庫(kù)亦可)配置文件,并將各文件解析結(jié)果整合,發(fā)送到客戶端瀏覽器;后者涉及對(duì)權(quán)限配置文件的維護(hù),包括對(duì)組信息和權(quán)限規(guī)則的修改,還包括對(duì)冗余信息的檢測(cè)和避免。此模塊所做操作最終將更新到各配置文件中。
2.1 SVN權(quán)限解析模塊的設(shè)計(jì)
傳統(tǒng)上,SVN客戶端與服務(wù)端交互的方式是,用戶在客戶端輸入用戶名和版本庫(kù)路徑,提交至服務(wù)端,服務(wù)端則解析此用戶對(duì)路徑是否有讀權(quán)限,若有則將路徑下的內(nèi)容(包括文件和文件夾)顯示給用戶,否則告知用戶無(wú)權(quán)訪問(wèn)。
本系統(tǒng)在權(quán)限解析方面將做如下改進(jìn):客戶端僅需給定用戶名,無(wú)需給定版本庫(kù)路徑,而靠權(quán)限解析模塊解析出多個(gè)相關(guān)版本庫(kù)中用戶有權(quán)限的所有路徑信息(包括路徑名稱和對(duì)路徑具有的權(quán)限)。
2.1.1 權(quán)限配置文件簡(jiǎn)介
SVN的權(quán)限配置信息保存在一個(gè)文本文件中(默認(rèn)路徑是各版本庫(kù)“conf”子目錄下的“authz”文件)。以下為權(quán)限文件部分內(nèi)容(‘#’表示單行注釋):
###組定義
[groups]
group=user1,user2
###基于版本庫(kù)路徑的授權(quán)方式
[Repo:/SubPath]
user=r
@group=rw
*=
[Repo:/SubPath/abc]
user3=r
user3=w
權(quán)限配置文件內(nèi)容包含組定義和權(quán)限規(guī)則定義。組定義以“[groups]”為開(kāi)始標(biāo)記,定義格式為“組名=用戶名1,用戶名2……”,組與組之間允許嵌套;SVN采取基于版本庫(kù)路徑[6]的顯示方式定義用戶權(quán)限。對(duì)于版本庫(kù)“Repo”下的“SubPath”子路徑,用戶“user”有只讀權(quán)限,組“group”有讀寫權(quán)限(‘@’為組標(biāo)識(shí)),其他用戶(‘*’指代除“user”和“group”之外的其他用戶,也包括匿名用戶)則無(wú)任何權(quán)限。此外,用戶權(quán)限具有“繼承性”,即若子路徑下未改變用戶權(quán)限,則用戶對(duì)子路徑將繼承對(duì)父路徑擁有的權(quán)限。如user對(duì)“[Repo:/SubPath/abc]”有從“[Repo:/SubPath]”繼承來(lái)的讀權(quán)限。SVN授權(quán)的另一個(gè)特點(diǎn)是權(quán)限之間的“覆蓋”,如“user=w”將覆蓋“user=r”,使得“user3”對(duì)“[Repo:/SubPath/abc]”僅有寫權(quán)限。
2.1.2 權(quán)限解析類圖設(shè)計(jì)
根據(jù)2.1.1節(jié)內(nèi)容,設(shè)計(jì)的權(quán)限解析模塊類圖如圖2(僅給出權(quán)限解析所需要的類、成員變量和方法等)所示。
其中,“User”類和“Group”類分別代表用戶和組;“AccessLevel”類代表權(quán)限,且只允許四種權(quán)限:Read(只讀)、Write(只寫)、ReadAndWrite(讀寫)和NoneAccess(無(wú)讀寫權(quán)限);“AccessRule”類代表一條權(quán)限規(guī)則(如“user=rw”);“RepoPath”類代表版本庫(kù)路徑,定義格式為“[版本庫(kù)名稱:/子路徑]”;“AccessRulesUnit”類代表一條版本庫(kù)路徑及其下的若干規(guī)則集合(例如2.1.1節(jié)配置文件內(nèi)容中的部分),是反映“基于路徑授權(quán)”的基本單元;“AccessManager”類是權(quán)限管理類,包括了權(quán)限解析和管理的幾乎所有方法。執(zhí)行“AccessManager”構(gòu)造函數(shù)會(huì)將配置文件中所有組定義封裝到“groupList”中,將權(quán)限規(guī)則定義封裝到“unitList”中。
2.1.3 權(quán)限解析的核心方法實(shí)現(xiàn)
“AccessManager”類中的“parseRootPaths”和“parseLevel”方法是權(quán)限解析的核心方法。其中“parseRootPaths”方法對(duì)給定的用戶(或組),將解析出其在配置文件中有權(quán)限的所有版本庫(kù)路徑(鑒于權(quán)限在路徑間的繼承性,相同版本庫(kù)下的路徑集合只需解析出最頂層路徑即可);“parseLevel”方法用于判斷指定用戶(或組)對(duì)指定版本庫(kù)路徑具有的權(quán)限。
以上兩個(gè)方法能正確執(zhí)行的前提條件是已調(diào)用“AccessManager”中的“sortUnitList”方法(作為權(quán)限解析前的預(yù)處理工作,見(jiàn)圖1),使得在“unitList”中所有“AccessRulesUnit”對(duì)象可以“按序”排列,以最大程度降低權(quán)限解析的難度。這里的“按序”規(guī)則如下:從“unitList”中取出所有“AccessRulesUnit”對(duì)象中的“RepoPath”成員,使得所有“RepoPath”按版本庫(kù)名稱分類存放,并保證同一版本庫(kù)下子路徑排列在父路徑之前。一種路徑“按序”排列的示例為:
[Repo1:/SubPath/abc]
[Repo1:/SubPath]
[Repo1:/]
[Repo2:/SubPath/abc]
[Repo2:/]
[/]###是所有版本庫(kù)路徑的根目錄
“RepoPath”的排列順序即其所在的“AccessRulesUnit”對(duì)象在“unitList”中的順序。
“parseRootPaths”方法(參數(shù)以u(píng)ser為例,group亦可)偽碼如下(使用java語(yǔ)言描述):
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說(shuō)明之前已找到一個(gè)最頂層路徑或當(dāng)前掃描到新的版本庫(kù)里的路徑*/
if(add || isEmpty(pathList))
addElem(pathList,path);
/* false說(shuō)明當(dāng)前找到更高層的路徑,應(yīng)覆蓋上次找到的路徑(為pathList中的最后一個(gè)元素)*/
else replaceLastElem(pathList, path);
add = false;
continue ;
}
/*當(dāng)前unit不包含rule,說(shuō)明當(dāng)前pathList
末尾元素即是一個(gè)最頂層路徑*/
add = true ;
}
return pathList ;
}
“parseLevel”方法(參數(shù)以u(píng)ser為例,group亦可)偽碼如下(使用java語(yǔ)言描述):
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,說(shuō)明所有與path同版本庫(kù)的路徑均已檢查過(guò),因已執(zhí)行過(guò)“sortUnitList”方法,之后不在同版本庫(kù)的路徑不必檢查,直接跳到unitList最后一個(gè)元素(可能包含“[/]”)即可*/
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的規(guī)則中的權(quán)限
return unit.getRule(user).level;
}
if(unit.hasAnonymousRule()){
return unit.getAnonymousRule().level;
}
}
return NoneAccess;
}
執(zhí)行上述兩方法可確保在做權(quán)限解析時(shí),最壞情況下“unitList”至多被迭代訪問(wèn)一次即可(T(n)=O(n),n為unitList的長(zhǎng)度),相比未采取優(yōu)化策略時(shí)(T(n)至少為O(n2)),大大降低了解析難度,避免了對(duì)“unitList”多次迭代訪問(wèn)。
2.2 權(quán)限信息維護(hù)模塊的設(shè)計(jì)
2.2.1 分級(jí)授權(quán)和權(quán)限撤銷
傳統(tǒng)上權(quán)限配置都由專門的SVN管理員完成,而本系統(tǒng)所做改進(jìn)則是實(shí)現(xiàn)了分級(jí)配置、分級(jí)授權(quán)和權(quán)限撤銷。
分級(jí)授權(quán)是使權(quán)限配置工作分散化的做法,目的是降低管理員的壓力,也使各用戶充分參與其中,更好地配合軟件開(kāi)發(fā)過(guò)程。本系統(tǒng)通過(guò)分級(jí)授權(quán),使得不用依靠專門的SVN管理員,用戶可將自己對(duì)路徑的訪問(wèn)權(quán)限授予他人(所有用戶/組對(duì)任何人都是可見(jiàn)的,但并非任何人都能修改用戶/組信息),每個(gè)項(xiàng)目組成員都可成為權(quán)限管理者,從根本上簡(jiǎn)化了SVN權(quán)限管理工作。
對(duì)于權(quán)限的撤銷,為了防止配置混亂,用戶的權(quán)限僅能由授予者撤銷,若在此之前此用戶已將權(quán)限授予他人,則做權(quán)限的級(jí)聯(lián)撤銷。
2.2.2 冗余權(quán)限規(guī)則的避免
授權(quán)操作頻繁,預(yù)示著權(quán)限文件內(nèi)容的不斷增加,隨之冗余權(quán)限規(guī)則也極易出現(xiàn),考慮以下情形:
?。?)重復(fù)定義引起的冗余。如在2.1.1節(jié)配置文件內(nèi)容中添加了如下規(guī)則:“user=r”或者“@newGroup=r(組‘newGroup’中包含了‘user’用戶)”。
?。?)權(quán)限覆蓋引起的冗余(見(jiàn)2.1.1節(jié)配置文件內(nèi)容,“user=w”覆蓋了“user=r”,使后者成為無(wú)效冗余規(guī)則)。
為了保持權(quán)限文件內(nèi)容的簡(jiǎn)潔清晰,優(yōu)化查詢權(quán)限的效率,避免引入冗余信息十分重要。本文采取的方法是,授權(quán)之前先調(diào)用“AccessManager”中的“parseLevel”方法檢查被授權(quán)的用戶對(duì)路徑是否已具有相同權(quán)限,有則無(wú)需授權(quán)。
3 SVN權(quán)限管理系統(tǒng)界面管理
本系統(tǒng)登錄后的界面如圖3和圖4所示(當(dāng)前登錄者為擁有系統(tǒng)最多權(quán)限的管理員)。
前臺(tái)界面主要使用了JQuery EasyUI(一組基于jQuery的UI插件集合)中的Treegrid、Datagrid、Tabs、Dialog等組件,提供了清晰友好的交互界面。
本系統(tǒng)前臺(tái)界面所做改進(jìn)是提供了兩種視圖機(jī)制管理用戶權(quán)限,包括用戶/組視圖和版本庫(kù)路徑視圖。圖3給出了用戶/組視圖,針對(duì)當(dāng)前選中的用戶/組,經(jīng)解析模塊,將給出其有權(quán)限的版本庫(kù)頂層路徑集合及對(duì)應(yīng)的權(quán)限。圖4是版本庫(kù)路徑視圖,針對(duì)選中的版本庫(kù)路徑,解析出對(duì)此路徑有權(quán)限的所有用戶/組及對(duì)應(yīng)權(quán)限。兩種視圖機(jī)制下均允許用戶進(jìn)行權(quán)限配置(使用分級(jí)授權(quán)的思想),提高了系統(tǒng)與用戶的交互性,降低了權(quán)限管理的難度。
傳統(tǒng)SVN用戶權(quán)限管理是通過(guò)維護(hù)一個(gè)文本配置文件來(lái)完成的,用戶人數(shù)的增多使得依靠少數(shù)管理員人工理解和維護(hù)配置文件困難重重。本文在深入理解SVN權(quán)限配置的基礎(chǔ)上,設(shè)計(jì)和實(shí)現(xiàn)了一個(gè)基于Web的SVN權(quán)限管理系統(tǒng),針對(duì)用戶提供更加全面的權(quán)限信息;提出使用基于角色的分級(jí)授權(quán)機(jī)制,各個(gè)項(xiàng)目組可獨(dú)立管理本組用戶權(quán)限;前臺(tái)提供基于用戶/組和基于版本庫(kù)路徑兩種視圖機(jī)制,使權(quán)限管理更加簡(jiǎn)單直觀。
參考文獻(xiàn)
[1] 王強(qiáng),曹漢平,賈素玲.IT軟件項(xiàng)目管理[M].北京:清華大學(xué)出版社,2005.
[2] Ben Collins-Sussman, Brian W. Fitzpatrick, C. Michael Pilato. Subversion權(quán)威指南(針對(duì)Subversion 1.7)[M/OL]. 2004.
[3] 郭軍.基于角色的訪問(wèn)控制分級(jí)授權(quán)管理的研究[D].西安:西安電子科技大學(xué),2012.
[4] 紀(jì)洲鵬,趙斐斐.可視化版本控制在.Net三層架構(gòu)開(kāi)發(fā)中的應(yīng)用[J].軟件導(dǎo)刊,2013(1):89-90.
[5] SVN Club. SVN管家(Windows版本)項(xiàng)目[EB/OL].http://www.svnclub.com,[2012-02].
[6] 曾紹庚.Linux SVN服務(wù)器權(quán)限精確控制的實(shí)現(xiàn)[J].信息與電腦(理論版),2011(7):163-164.