権限の機能強化案

タイトルで悩むのもあほらしいのでカテゴリつけてみました。

さて、無類の権限好きなワタクシですが、思うところを書いてみます。
既に現状のS2Buriで可能なものもあるかもしれませんが、気にせずに書きます。


大きく分けて権限系には以下の2種類あるかと思います。

  • (A)データの閲覧権限
  • (B)データに対する何らかの処理の実行権限

「閲覧」自体を処理の1つと見なせば、(A)も(B)に含めることができますが、経験上ここは分けておいた方がお得な気がします。


現状のS2Buriでできることを整理します。

(A)→「getアクティビティ名()」シリーズのメソッドではそのステータスにある全データが取れてしまうので現状では非対応かと思います。

(B)→Participantをうまく活用できればそれっぽくすることができます。
S2Buriでユーザ権限ごとにアクセス制御 - 豆無日記のシリーズにあるような改造をしていくことでより隙なく対応していけますが、なんか場当たり的な気がしています。

というところかと思います。どうでしょうか?


僕が基本的にやりたいことは、

  • 実行ユーザが閲覧可能なデータの一覧を取得する。((A)と対応)
    • 件数が多い場合はS2Pager的に取り扱えると良い。
    • ステータスを問わずに取得、特定ステータスを指定しての取得のバリエーションがほしい。
  • その中から1つのデータを選んで、そのステータスでそのユーザに許可されているアクティビティ一覧を取得する。((B)と対応)
  • その中から1つのアクティビティを選んで実行する。その結果、データはフローを進んだり、内容が更新されたりする。((B)と対応)
    • いつの間にかステータスが進んでいた場合など、既に指定したアクティビティの実行権限がなければエラー。

ということです。

単にフローを進んでいくところの処理なんかはもう今のままで十分完成形に近いんじゃないかと思ってます。


さて、権限があるかどうかをどのように判断するかですが、基本形は現状のParticipantProviderのようにそのアプリが持つ独自のユーザ情報(UserDto等)とXPDLで定義されたロール(Participant)の対応付けから判断することになると思います。
できればそこに、対象となっているデータそのものも判断材料として追加してもらえればベストです。
データの内容によってフローを変えることができればとても柔軟性があがります。
ヘタすると、撲滅したはずのフラグ目的のみの項目が復活してくる可能性もありますけど。


実装イメージでいうと権限チェックという意味で、

public interface AccessController {
    boolean isExecutable(Object data, Object userData, String participantName);
}

という専用インタフェースがあってもいいのかもしれません。
(B)についてはActivity実行直前にこのメソッドを必ず実行する、という感じでしょうか。デフォルト実装では常にtrueを返せば今まで通り権限ノーチェックです。

既存のParticipantProvier#isUserInRole()ですが、これは今まで通りActivityを絞り込むためだけに使うと割り切ってしまえばそのままでよいと思います。

Activityを絞り込むためにParticipantも1つの条件として使ってみる。そのために既存のParticipantProvier#isUserInRole()を使う。
絞り込んだ結果のActivityを本当に実行しても良いかどうかを判断するためには、改めてAccessController#isExecutable()で確認する。
というイメージですね。


(A)についての実装イメージは...難しいですね。
何が難しいかというと閲覧の場合はListで取得するので対象データ数が多い。すると性能面が問題になるわけですね。

どのユーザがどのステータスのどんな内容のデータを閲覧してもよいのか。相手が単体データであればJava上でいくらでもかけますけど、大量データを対象としたときの性能などを考えるとSQL結合で結果が取得できるようにしないといけなそうです。やはり可視性に関する定義テーブルを用意することになるんでしょうか。

リスト取得の場合はSQLで可視性定義も結合してしまって、閲覧できるデータ群だけ取得する。
単品でアクセスしても良いのか確認する場合は、同様にSQL結合で実装しておいて、JavaでのAPIとして

public interface AccessController {
    boolean isReadable(Object data, Object userData, String participantName);
}

というインタフェースメソッドを用意するとか。

そのデータに対してどのようなアクティビティを実行できそうなのかは

public interface AccessController {
    List<Activity> getActivities(Object data, Object userData, String participantName);
}

でとるとか。

うーん、汚い仕様だ。
実行権限はアプリ開発者がAccessController#isExecutable()を実装することで表現できますが、閲覧権限の表現方法が対照的ではないところとか、なんかよくないですね。

混乱してきたのでひとまずこれで...。