DrupalのGroupモジュールに高い可能性を感じているが、権限のモデリングは非常に難しい

hagi に投稿

私はGroupモジュールに魅力を感じてる。CMSの地平を変えるものだとすら思う。ただ、まだ端緒にあって今後モデルそのものが変遷していって恐らく最終的にはCoreに入ることになるだろうと思っている。

Webページの管理にCMSを利用するのはかなり常識化した。そして、複数ユーザーのBlogサイト等の構築では、執筆者とコンテンツを結びつけて考えなければいけないので、ユーザー管理が行われるようになった。さらに、内容の適切性をチェックする必要があるケースに対応して「草稿執筆→編集者承認による公開」といったワークフローも利用されるようになっている。さらに、チーム内だけに限定公開したいというニーズも生まれ、一人の執筆者が複数のチームに属するとか、ニーズはどんどん拡大する。

Drupalは編集ワークフローに関しては、CoreにContent Moderationモジュールを組み込み、標準ワークフローを提供している。状態管理という観点では優れた機能を提供しており、私も複数の案件で実用している。すごく捨象すれば、このモジュールを上手に使えば、非公開と公開のワークフロー管理は可能になる。

一方で、コンテンツの見せ方で考えると、有料会員だけに見せたいとか、一定のメンバーだけに自分が書いたものでなくても編集権限を与えたいとかが問題となる。Content Moderationのワークフローの設定は、管理者でないと設定が困難なので、チームに管理を移譲することができない。Groupモジュールは、その問題に対する体系的なアプローチを可能とするフレームワークを提供している。

図は、UMLクラス図でGroupモジュールだどのように権限管理を拡張しているかを書いたものだ。

最終的には、グループというEntityを作り、そこにメンバー(独自役割つき)、コンテンツ(独自表示編集権限つき)を結びつけたいというのが「やりたいこと」という事になる。できあがり時には、グループメンバー、グループノードを加えた3つのEntityの実態だけで管理できる。これと、Drupalの本来の権限管理機能の拡張(一部上書き)で「やりたいこと」が実現できるようになる。

しかし、その問題に体系的にアプローチしようと思うと、グループに対して、グループタイプという抽象化が必要になる。例えば、英会話教室のクラスでも考えてみれば良い。英会話教室は、メンバーに教師と生徒という役割があって、教材というコンテンツ(所定のコンテンツタイプ)があって、特定英会話教室の生徒だけがその教材を見ることができるといったイメージである。

この英会話教室グループタイプが定義できたら、例えば、「片口先生2020年サマークラス」をグループとして作り、片口先生を教師の役割でグループメンバーに追加し、何人かの生徒をグループメンバーに追加する。そして、片口先生は、一般には非公開な既存の教材から選んで、サマークラスの教材として登録すると開講準備が完了といった感じとなる。もちろん、現実の世界では、教師以外にも運営者が必要になるし、今だとコンテンツとして、教室の管理(何月何日何時から何時までXX教室/Zoomで開催等)も必要となるだろう。しっかりしたフレームワークがなければ、クラスを開講する度に毎回プログラムを書くなりして、システム的な対応が必要になるので、現実的には「できません」という事になるが、うまくグループタイプが定義できたら、プログラマの助けを借りずにあっという間に新たなクラスを立ち上げることができ、その管理を教師に委任できるようになるのである。DrupalのGroupモジュールを使いこなせば、そんな夢のような事が可能になるのである。

図に戻ると、Group Moduleの枠の左上の3つのEntityがそろえば、機能は実現できるが、抽象化するためにはGroupType、もともとDrupalのContentTypeと関連付けるためのGroupNodeTypeを定義しないといけないことになる。そこでキーとなるのが、GroupNodeに関する権限設定(GroupNodePermission)である。グループ内の権限が「教師」であれば、教材コンテンツを新たに追加できる権限が「Entity: Add content item entities」である。既存の教材とクラスで使う設定をするのが「Relation: Add entity relations」ということになる。全社は、新たに教材を作成して、引き続き「Relation: Add entity relations」を行うのと同じだ。「生徒」の方は、コンテンツを見られれば良いので、ほとんどの権限はいらないが「Entity: View any content item entities」は必要となる。グループに属する教材を見るのを許して上げなければ、教材が見られないので当然である。さらに、そのコンテンツが未公開のものであれば、「Entity: View any unpublished content item entities」も与えてあげないと非公開コンテンツにアクセスできない。publishdはDrupalのcore機能で、グループ内のアクセス権はグループの機能なので、クロスで効いてくるのが非常に難しい。

最近Groupが1.0としてリリースされ、セキュリティ上の脆弱性が発見されたので修正が加えられた1.1がリリースされた。ところが、このリリースで「Entity: View any content item entities」の権限だけで非公開コンテンツにもアクセスできる状態が生じてしまった。それで、早速1.2にリリースアップされ、この問題が解消された。迅速な対応は称賛に値すると思う。ところが、新しい「教材」を非公開でグループコンテンツとして作成すると、「Entity: Edit own content item entities」があっても、編集することができない状態になってしまった。では「Entity: Edit own unpublished content item entities」という権限を加えればよいのか、あるいはCoreの権限をうまく取り込むのが正しいのかは難しい問題である。個人と権限が結び付けられているものをグループメンバーに結びつけるためには、本来Authorでない他の個人に追加の権限が与えられないといけない。一方で、Authorの権限が不当に侵害されてはいけない。Content Moderation機能との整合性はとらなければいけない。中々難しい。

ちなみに、現在想定しているプロジェクトでは、ワークアラウンドは可能である。ただ、やはりモデルが動けば影響は甚大なのでよくよく考えないといけない。

タグ