天天看點

Subversion權限詳解深入 改進

1   背景假設

廈門央瞬公司是一家電子元器件裝置供應商,其中有個ARM部門,專門負責ARM晶片的方案設計、銷售,并在北京、上海各設立了一個辦事處。對于工作日志,原先采用郵件方式發給經理,但是這種方式有個缺點,那就是不具備連續性,要看以前的日志必須一封一封郵件去檢視,很麻煩。于是就想到利用 Subversion, 讓員工在自己電腦上編輯日志,然後利用svn傳送回來,既友善員工自己編寫日志,又友善對日志的歸檔處理,而且送出日志的時候隻需要執行一下 svn update 即可,比發送郵件還要簡單的多。

  • svn伺服器相關資訊
    • 伺服器位址: 192.168.0.1
    • 伺服器OS: MS Windows 2000 Server Edition 中文版
    • 代碼庫本地目錄: D:/svn/arm
  • arm部門文檔的目錄結構如下:
    arm                 部門名稱
    ├─diary           工作日志目錄
    │  ├─headquarters    總部工作日志目錄
    │  ├─beijing         北京辦日志目錄
    │  └─shanghai        上海辦日志目錄
    ├─ref             公司公共檔案參考目錄
    └─temp            臨時檔案目錄
          
  • 人員情況
    • morson,公司總經理,其實他不必親自看任何東西,就連部門經理們的每周總結都不一定看。但是為了表示對他的尊敬,以及滿足一下他的權力欲,還是給他開放了“閱讀所有文檔”的權限
    • michael,arm事業部的部門經理,沒事的時候喜歡弄點兒新技術,用svn來管理日志,就是他相處來的主意
    • scofield,北京辦人員,老員工,為人油滑難管
    • lincon,上海辦人員,老員工,大老實人一個
    • linda,總部協調員、秘書,文筆不錯,長得也不錯
    • rory,單片機技術員,技術支援
  • 通路權限需求分析
    • 允許總經理讀取所有檔案
    • 除部門經理外,所有其他人員,均隻能看到本辦事處人員工作日志
    • 不允許匿名通路
    • ref目錄隻允許經理和秘書寫,對其他人隻讀
    • temp目錄人人都可以寫

2   建立代碼庫

在伺服器 D:/svn 目錄下,建立 arm 代碼庫,指令如下:

D:/svn>svnadmin create arm
      

在客戶機 F:/temp 目錄下,建立好上述目錄結構

用指令 F:/temp>svnimportarmsvn://192.168.0.1/arm 導入結構

【注意點:關于導入時候的細微差别】

3   編輯代碼庫基礎配置檔案

編輯代碼庫 arm/conf/svnserve.conf 檔案,如下:

[general]
password-db = passwd.conf
anon-access = none
auth-access = write
authz-db = authz.conf
      

4   管理使用者帳号

建立代碼庫 arm/conf/passwd.conf 檔案,如下:

[users]
morson = ShowMeTheMoney
michael = mysecretpassword
scofield = hellolittilekiller
lincon = asyouknows111
rory = 8809117
linda = IlikeWorldCup2006
      

5   建立目錄通路權限控制檔案

建立代碼庫 arm/conf/authz.conf 檔案,内容如下:

[groups]
g_vip = morson
g_manager = michael
g_beijing = scofield
g_shanghai = lincon
g_headquarters = rory, linda
g_docs = linda
[arm:/]
@g_manager = rw
* = r
[arm:/diary/headquarters]
@g_manager = rw
@g_headquarters = rw
@g_vip = r
* =
[arm:/diary/beijing]
@g_manager = rw
@g_beijing = rw
@g_vip = r
* =
[arm:/diary/shanghai]
@g_manager = rw
@g_shanghai = rw
@g_vip = r
* =
[arm:/ref]
@g_manager = rw
@g_docs = rw
* = r
[arm:/temp]
* = rw
      

6   測試

在伺服器上,打開一個 DOS Prompt 視窗,輸入如下指令:

svn co svn://127.0.0.1/arm --no-auth-cache --username rory --password 8809117
      

我們應該得到如下目錄結構:

arm
├─diary
│  └─headquarters
├─ref
└─temp
      

然後修改ref目錄下任意檔案并送出,伺服器将會報錯“Access deni”

深入

本章将詳細介紹前一章所涉及的兩個配置檔案, svnserve.conf 和 authz.conf,通過對配置逐行的描述,來闡明其中的一些細節含義。

這裡首先要注意一點,任何配置檔案的有效配置行,都不允許存在前置空格,否則程式會無法識别。也就是說,如果你直接從本文的純文字格式中拷貝了相關的配置行過去,需要手動将前置的4個空格全部删除。當然了,如果你覺得一下子要删除好多行的同樣數目的前置空格是一件苦差使,那麼也許 UltraEdit 的“Column Mode”編輯模式,可以給你很大幫助呢。

1   svnserve.conf

arm/conf/svnserve.conf 檔案,是 svnserve.exe 這個伺服器程序的配置檔案,我們逐行解釋如下。

首先,我們告訴 svnserve.exe,使用者名與密碼放在 passwd.conf 檔案下。當然,你可以改成任意的有效檔案名,比如預設的就是 passwd:

password-db = passwd.conf
      

接下來這兩行的意思,是說隻允許經過驗證的使用者,方可通路代碼庫。 那麼哪些是“經過驗證的”使用者呢?噢,當然,就是前面說那些在 passwd.conf 檔案裡面持有使用者名密碼的家夥。這兩行的等号後面,目前隻允許 read write none 三種值,你如果想實作一些特殊的值,比如說“read-once”之類的,建議你自己動手改源代碼,反正它也是自由軟體:

anon-access = none
auth-access = write
      

接下來就是最關鍵的一句呢,它告訴 svnserve.exe,項目目錄通路權限的相關配置是放在 authz.conf 檔案裡:

authz-db = authz.conf
      

當然,svn 1.3.2 引入本功能的時候,系統預設使用 authz 而不是 authz.conf 作為配置檔案。不過由于鄙人是處女座的,有着強烈的完美主義情結,看着 svnserve.conf 有字尾而 passwd 和 authz 沒有就是不爽,硬是要改了。

2   authz.conf 之使用者分組

arm/conf/authz.conf 檔案的配置段,可以分為兩類,``[group]`` 是一類,裡面放置着所有使用者分組資訊。其餘以 [arm:/] 開頭的是另外一類,每一段就是對應着項目的一個目錄,其目錄相關權限,就在此段内設定。

首先,我們将人員分組管理,以便以後由于人員變動而需要重新設定權限時候,盡量少改動東西。我們一共設定了5個使用者分組,分組名稱統一采用 g_ 字首,以友善識别。當然了,分組成員之間采用逗号隔開:

[groups]
# 任何想要檢視所有文檔的非本部門人士
g_vip = morson
# 經理
g_manager = michael
# 北京辦人員
g_beijing = scofield
# 上海辦人員
g_shanghai = lincon
# 總部一般員工
g_headquarters = rory, linda
# 小秘,撰寫文檔
g_docs = linda
      

注意到沒有, linda 這個帳号同時存在“總部”和“文檔員”兩個分組裡面,這可不是我老眼昏花寫錯了,是因為 svnserve.exe 允許我這樣設定。它意味着,這個家夥所擁有的權限,将會比他的同僚 rory 要多一些,這樣的确很友善。具體多了哪些呢?請往下看!

3   authz.conf 之項目根目錄

接着,我們對項目根目錄做了限制,該目錄隻允許arm事業部的經理才能修改,其他人都隻能眼巴巴的看着:

[arm:/]
@g_manager = rw
* = r
      
  • [arm:/] 表示這個目錄結構的相對根節點,或者說是 arm 項目的根目錄
  • 這裡的 @ 表示接下來的是一個組名,不是使用者名。你當然也可以将 @g_manager=rw 這一行替換成 michael=rw ,而表達的意義完全一樣。
  • * 表示“除了上面提到的那些人之外的其餘所有人”,也就是“除了部門經理外的其他所有人”,當然也包括總經理那個怪老頭
  • * = r 則表示“那些人隻能讀,不能寫”

4   authz.conf 之項目子目錄

然後,我們要給總部人員開放日志目錄的讀寫權限:

[arm:/diary/headquarters]
@g_manager = rw
@g_headquarters = rw
@g_vip = r
* =
      
  • 我敢打賭,設計svn的家夥們,大部分都是在 unix/linux 平台下工作,是以他們總喜歡使用 / 來辨別子目錄,而完全忽視在 MS Windows 下是用 / 來做同樣的事情。是以這兒,為了表示 arm/diary/headquarters 這個目錄,我們必須使用 [arm:/diary/headquarters] 這樣的格式。
  • 這裡最後一行的 *= 表示,除了經理、總部人員、特别人士之外,任何人都被禁止通路本目錄。這一行是否可以省略呢?
  • 之是以這兒需要将 @g_vip=r 一句加上,就是因為存在上述這個解釋。如果說你沒有明确地給總經理授予讀的權力,則他會和其他人一樣,被 * 給排除在外。
  • 如果衆位看官中間,有誰玩過防火牆配置的話,可能會感覺上述的配置很熟悉。不過這裡有一點與防火牆配置不一樣,那就是各個配置行之間,沒有 先後順序 一說。也就是說,如果我将本段配置的 *= 這一行挪到最前面,完全不影響整個配置的最終效果。
  • 請注意這兒,我們并沒有給 arm/diary 目錄設定權限,就直接跳到其子目錄下進行設定了。我當然是故意這樣的,因為我想在這兒引入“繼承”的概念。
  • 權限具備繼承性 任何子目錄,均可繼承其父目錄的所有權限,除非它自己被明确設定了其他的權限。也就是說,在 arm 目錄設定權限後, arm/diary 目錄沒有進行設定,就意味着它的權限與 arm 目錄一樣,都是隻有經理才有權讀寫,其他人隻能幹瞪眼。
  • 【 * = 是否可以省略】【用例子引入覆寫】【單使用者權限的繼承問題】【父目錄權限內建與全面覆寫問題】

現在來看看

好了,我們現在掌握了“繼承”的威力,它讓我們節省了不少敲鍵盤的時間。可是現在又有一個問題了,

屬性具備覆寫性質子目錄若設定了屬性,則完全覆寫父目錄。

5   authz.conf 的其他注意點

  1. 父目錄的 r 權限,對子目錄 w 權限的影響

把這個問題專門提出來,是因為在1.3.1及其以前的版本裡面,有個bug,即為了子目錄的寫權限,項目首目錄必須具備讀權限。是以現在使用了1.3.2版本,就友善了那些想在一個代碼庫存放多個互相獨立的項目的管理者,來配置設定權限了。比如說央舜公司建立一個大的代碼庫用于存放所有員工日志,叫做 diary,而arm事業部隻是其中一個部門,則可以這樣做:

[diary:/]
@g_chief_manager = rw
[diary:/arm]
@g_arm_manager = rw
@g_arm = r
      

這樣,對于所有arm事業部的人員來說,就可以将 svn://192.168.0.1/diary/arm 這個URL當作根目錄來進行日常操作,而完全不管它其實隻是一個子目錄,并且當有少數好奇心比較強的人想試着 checkout 一下 svn://192.168.0.1/diary 的時候,馬上就會得到一個警告“Access deni”,哇,太酷了。

  1. 預設權限

如果說我對某個目錄不設定任何權限,會怎樣?馬上動手做個試驗,将:

[diary:/]
@g_chief_manager = rw
      

改成:

[diary:/]
# @g_chief_manager = rw
      

這樣就相當于什麼都沒有設定。在我的 svn 1.3.2 版本上,此時是禁止任何通路。也就是說,如果你想要讓某人通路某目錄,你一定要顯式指明這一點。這個政策,看起來與防火牆的政策是一緻的。

  1. 隻讀權限帶來的一個小副作用

若設定了:

[arm:/diary]
* = r
      

則svnserve認為,任何人,都不允許改動diary目錄,包括删除和改名,和新增。

也就是說,如果你在項目初期建立目錄時候,一不小心寫錯目錄名稱,比如因拼寫錯誤寫成 dairy,以後除非你改動 authz.conf 裡面的這行設定,否則無法利用 svn mv 指令将錯誤的目錄更正。

改進

1   對中文目錄的支援

上午上班的時候,Morson 來到 Michael 的桌子前面,說道:“你是否可以将我們的北京辦、上海辦目錄,改成用中文的,看着那些拼音我覺得很難受?” Michael 心想,還好這兩天剛了解了一些與 unicode 編碼相關的知識,于是微笑地回答:“當然可以,你明天下午就可以看到中文目錄名稱了。”

  1. 使用 svn mv 指令,将原來的一些目錄改名并 commit 入代碼庫,改名後的目錄結構如下:
    arm
    ├─工作日志
    │  ├─總部人員
    │  ├─北京辦
    │  └─上海辦
    ├─公司公共檔案參考目錄
    └─臨時檔案存放處
          
  2. 修改代碼庫的 authz.conf 檔案,将相應目錄逐一改名
  3. 使用 UltraEdit 将 authz.conf 檔案轉換成不帶 BOM 的 UTF-8 格式

    将配置檔案轉換成 UTF-8 格式之後,Subversion 就能夠正确識别中文字元了。但是這裡需要注意一點,即必須保證 UTF-8 檔案不包含 BOM 。BOM 是 Byte Order Mark 的縮寫,指 UNICODE 檔案頭部用于指明高低位元組排列順序的幾個字元,通常是 FFFE ,而将之用 UTF-8 編碼之後,就是 EFBBBF 。由于 UTF-8 檔案本身不存在位元組序問題,是以對 UTF-16 等編碼方式有重大意義的 BOM,對于 UTF-8 來說,隻有一個作用——表明這個檔案是 UTF-8 格式。由于 BOM 會給文本處理帶來很多難題,是以現在很多軟體都要求使用不帶 BOM 的 UTF-8 檔案,特别是一些處理文本的軟體,如 PHP、 UNIX 腳本檔案等,svn 也是如此。

目前常用的一些文本編輯工具中,MS Windows 自帶的“記事本”裡面,“另存為”菜單儲存出來的 UTF-8 格式檔案,會自動帶上 BOM 。新版本 UltraEdit 提供了選項,允許使用者選擇是否需要 BOM,而老版本的不會添加 BOM。請各位檢視一下自己常用的編輯器的說明檔案,看看它是否支援這個功能。

利用 UltraEdit ,我們可以将 BOM 去掉。方法是,首先利用“UTF-8 TO ASCII”菜單将檔案轉換成本地編碼,通常是GB2312碼,然後再使用“ASCII TO UTF-8(UNICODE Editing)”來轉換到 UTF-8 即可。