Non-memberユーザーの、公開プロジェクトへのアクセス制限について

Redmineの魅力の一つに複数プロジェクトを一つのシステムで管理できる点がある。各プロジェクトには「公開」「非公開」を設定でき、「公開」されたプロジェクトはメンバーでないユーザーからもアクセスできる(もちろんロールでアクセスポリシーを設定できる)

組織の文化にもよるところだが、通常はプロジェクトは「公開」とし、核となるメンバーだけプロジェクトへ登録(ロールを付与)する。その他のユーザーは自動でNon-memberロールとなるが、Non-Memberには、「チケットの閲覧」「注記の追加」「チケットの移動」程度の権限は与えておく。

こうすることで、直接のプロジェクトメンバーでなくてもチケットを参照したり、他の自分のプロジェクトへチケットをコピーしたりでき、自然とプロジェクト間の風通しも良くなる。管理面でも、比較的関わりの薄いユーザーをいちいちメンバー登録する必要もなければメンテする必要もなくなる。
非公開にしてしまうと、片っ端からメンバーを登録したり、誰がアクセスできる・できないを個々人が把握する必要があり、コミュニケーションロスにつながることになる。(ツールを使ったばかりに必要な情報すら阻害される原因を作ってしまうのは、本末転倒だ)

ただ、プロジェクトを「原則公開」で運用する場合、特に企業組織で使う場合、大きな問題がある。
ユーザーの属性(所属や派遣、請負など)によって、「公開」プロジェクトへのアクセスを制限しなければならないケースだ。

ここでは、特定の所属のユーザーは、Redmineの仕様通り「公開」プロジェクトにアクセスでき、それ以外のユーザーは「公開」プロジェクトへのアクセスを制限する(制限を受けるユーザーにとっては非公開プロジェクトになる)改造を行ってみる。


<Redmineでの設定>
  • Non-Memberのロール設定で、最低限「チケットの閲覧」「注記の追加」「チケットの移動」の権限を付与する。

<Redmineソースの改造>(v.1.3.0ベース)
  • usersテーブルにrestrictionカラムを追加するためのmigrationファイルを作成。(公開プロジェクトへのアクセスを制限するユーザーを識別するフラグ)
+class AddUsersRestriction < ActiveRecord::Migration
+  def self.up
+    add_column :users, :restriction, :boolean, :default => 0
+  end
+
+  def self.down
+    remove_column :users, :restriction
+  end
+end
       statement_by_role = {}
       unless options[:member]
         role = user.logged? ? Role.non_member : Role.anonymous
-        if role.allowed_to?(permission)
+        # Restriction-user cannot access the project as non-member, whether or not project is public.
+        if role.allowed_to?(permission) && !user.restriction?
           statement_by_role[role] = "#{Project.table_name}.is_public = #{connection.quoted_true}"
         end
       end
       roles = roles_for_project(context)
       return false unless roles
+
+      # Restricted-user cannot access the project as non-member, whether or not project is public.
+      if self.restriction?
+        roles.detect {|role|
+          role.member? &&
+          role.allowed_to?(action) &&
+          (block_given? ? yield(role, self) : true)
+        }
+      else
       roles.detect {|role|
         (context.is_public? || role.member?) &&
         role.allowed_to?(action) &&
         (block_given? ? yield(role, self) : true)
       }
+      end
     elsif context && context.is_a?(Array)
       # Authorize if user is authorized on every element of the array
       context.map do |project|


この他、関連する次の改造が必要になってくると思うけど、紹介はまたの機会ということで。
  • ユーザーメンテナンス画面で、「公開プロジェクトへのアクセス制限」フラグのメンテナンスができるようにする。
  • ユーザー一覧画面、プロフィール画面等で、制限ユーザーが判別できるような表示フィールドを設ける。
  • システム管理者以外は、プロジェクト設定の「公開」を設定できないよう、「公開」チェックボックスをdisableにする。(「原則公開」を貫くため。安易に変更できないように。)

0 件のコメント:

コメントを投稿