文件控管?


#1

想詢問一下要做階層狀的權限該使用哪個工具比較好

一般商業用網站 權限類型幾個特徵

1.站方控管

2.商家自行設定

3.使用者點選

如果要做一個比較彈性的階層權限 該用那個gem比較好

實務情況是 類似內部的檔案上傳與控管

原本我的思考 主要有2個區域

一個為檔案上傳 另一個就是權限邏輯

感覺會在邏輯區塊 會較複雜

但好像不只這樣

一般 ruby on rails 會使用在公開性質網站

上傳的靜態檔案通常也都在public底下

但這樣不就沒有意義了

今天某某某沒有權限 但他卻可以直接獲得連結取得檔案

甚至是被瀏覽器搜到網址

http://www.123.com.tw/xxx檔案管理-xxx公司合約書.pdf

這樣不就很尷尬

下面是我找到幾款可以用來做複雜權限的幾套gem

gem "six"
https://github.com/randx/six

gem 'fibman’
https://github.com/Warrenoo/fibman

gem 'Pundit ’ 搭配 Enum
https://github.com/elabs/pundit
ActiveRecord::Enum
http://api.rubyonrails.org/v4.1/classes/ActiveRecord/Enum.html

但我感覺我是需要換個工具來實作…

有沒有人有做過相關的實務


#2

答案應該是不需要,直接用 cancancan 就好了,這類的東西都有『自訂』可以用,而自訂內你可以寫自己的規則,而你的規則…不就你想寫啥都可以了?

and 別想太多,連 git => gogs 之類的也就幾個打勾選項而已,因為它單純的學 linux 檔案權限內區分為:可刪 / 可新增 / 可寫 / 可讀,這幾類而已,而 restful 也都幫你切好了,也就是 CRUD 而已,不是嗎?

簡單的來說,一般來說使用者不能看到其他的使用者的基本資料,而管理者可以,所以對"他人基本資料"的操作而言,一般使用者為 0 ,而管理者是 7

所有 model / relation 都這樣搞即可,針對的都是使用者且不用太複雜化的(當然使用者在你的例子內會分為:顧客 / 商家 / 管理員 …),你可以另外建一個 model 來管理這些關係即可,或是學我們家用白名單列表之類的,且可以用『群組 / 身份』來做項目的收斂,因為你不會想讓使用者勾到死唄|||

至於其他的 … 總是會有要調整的部分,不要過早最佳化,出現再說唄,真的出現過多了之後再來重新想新的
schema 架構來收斂即可

然後剩下的,你的上傳如果都放在 public 內,不用過個水另外 send_file,被偷基本上是活該唄|||


#3

我看了好久jc打的內容

不知道這樣整理對不對

1.基本上檔案的 可刪 / 可新增 / 可寫 / 可讀 可能在另一台linux機器上 然後所有檔案 基本上都是預設 不可讀取修改 只能看到檔名(這裡會有一個restful接口 接前端請求)

2.前台 website 則是讀取檔名出來展現 然後如果要修改or下載or看檔案 則是透過 restful 變更檔案的狀態賦予給該名使用者linux 檔案權限

3.安全的作法 可能是使用者登入 website 後 restful 到後端linux將檔案的權限進行賦予 如果登出 或是經過一定時間 一樣把 linux 對相關使用者權限全數關閉 然後要求使用者重新登入 website 重新登入後再重新賦予相關權限

以上基本上就是linux對檔案與使用者權限的控制而已


4.前端 website 的權限邏輯 就看自己喜歡或是習慣 cancancan 或是自己習慣的權限gem寫相關權限賦予 自己習慣的工具即可

我的想法 大概是這樣 不知道對不對

然後更專業性質的 中間還會有一層虛擬層

像google drobox

做為鏡像 可以分享連結 複製 但其實他只是把訊息做為一個鏡像分享 實際檔案還是一個而已

(這是我想像這種結構的產品 實際上不知道@@!)


#4

嘛…完全反了 Orz",我們重頭再來一次,先不談檔案,用一般 restful 的方式來想

例如說 Item 這個 model 丟去 action 會變成 CRUD,而你要取得與下載 Item 則使用者一定會過 CRUD 四個 action,而通常再增加,通常都是 1:1 或關聯表

而 1:1 或關聯表,類似, ItemAuthor,ItemReader,ItemPermission,ItemDetail 都可以用類似的方式來管不是?

所以以 Item / ItemAuthor 就可以管理誰是作者,誰是協作者,而相對之下有其權限了?而針對是"誰",也大概就是 User / Manager / Sponsor,之後你就可以展開白名單表,類似 Users(User / Manager / Sponsor) x Target(Item ItemAuthor) 的 3 x 2 關係表,有列上去的才能存取,也就是類似(未測,只是表達其結構)

class AbilityUser
  include CanCan::Ability
    def initialize(user)
      case user.permission
      when 0 #reader
        can [:index , :show], [Item]
        can [:join], [ItemAuthor]
      when 1 #author
        can [:index , :show , :edit , :update], [Item]
        can [:join , :destroy], [ItemAuthor]
      when 2 #owner
        can [:index , :show , :edit , :update , :destroy], [Item]
        can [:join , :destroy , :edit , :join_admin], [ItemAuthor]
      else
        #這邊亂寫的,只是表示自訂能力而已,一般來說不使用這樣的語法
        if up = UserPermission.where(:user_id => current_user.id).first
          if up.is_admin
            temp = [:index , :show , :edit , :update , :delete]
            temp << :export
            can temp, [Item]
          end
        end
      end
    end
  end
end
class AbilityManager
  include CanCan::Ability
    def initialize(manager)
      can [:all], [Item] #其實管理者應該還要再分身份
      can [:all], [ItemAuthor]
    end
  end
end

這類的白名單關聯就可以定下來,你想做啥都可以(這是 cancancan 基本功能之一,往下丟 model 然後判斷是否有其 action 權限,還有超多種寫法,全數可自訂)

再來,你的檔案全部用 Rails action 內的 send_file 就可以防止靜態檔案網址被存取,前提是你必須放在不是 public 下,簡單的來說,如果你有看過我之前的 paperclip 教學

其中的可以改填類似

:path => ":rails_root/storage/uploads/images/:id_:style_:fingerprint.:extension"
:url => "/storage/images/:id_:style_:fingerprint.:extension"

如果你直接用類似 <%= @item.item.url(:item) %> 是取不到東西的,因為東西不在 public 下所以沒有對外網址

在 action 下多一行改用

#前置你想怎樣過濾都行,否則一率 deny,通過的才能走到下一行
send_file @item.item.url(:item)

就好了哩(這邊未側), send_file 的語意是我拿檔案後再傳給你,這邊不限定 public 下的檔案,而類似 S3 也有單一次專用的下載連結,so~~

anyway 我這邊回答了你兩個問題

第一個
使用者權限該怎樣管?對我而言最安全的就是白名單展開表,沒在表內全部 deny,沒有別的,想要自幹就自幹,調整順序即可,包含你想做成打勾的,樹狀的,委派的,啥都可以做得出來

第二個
File path 未過濾被盜取的問題?就在 action 過個水即可哩,而不是給使用者直接且真正的來源,包括你說的 GoogleDrive 也都是,否則你如何隱藏資訊在後面?

去玩玩看寫寫看,或是把這個項目家在目前的專案上,否則你都在空想唄…

以上


#5

ok

看來我是把項目server概念切開來 複雜化了

主要還是jc大講的第2點 我沒弄懂意思 :sweat:

經jc大講解我大概理解了

確實我比較煩惱的問題 File path 未過濾被盜取的問題? 所以才把構思想想成這樣子

權限邏輯這個就個人發揮了 程式邏輯功夫 沒啥好說的

存取檔案的實務 這個我就先開個專案出來玩看看

jc的說明確實釐清了一些概念

真的感謝jc大 :grinning: