本記事は Pleasanter(プリザンター) Advent Calendar 2021 1日目の記事です。
概要
プリザンターは、1つのテーブルでレコード単位のアクセス制御が行えます。組織やグループに見せる範囲を限定することで、実用的なアプリケーションを開発することができます。本記事ではレコードのアクセス制御を実現する複数の方法について説明します。
レコードのアクセス制御の種類
レコードのアクセス制御を実現する方法は下記の通りです。
- レコードに直接権限を付与する方法
- レコード作成時に自動的に権限を付与する方法
- 拡張SQLでレコードが抽出されるようにする方法
- サーバスクリプトのview.Filtersでレコードが抽出されるようにする方法
- 拡張SQLとサーバスクリプトの組み合わせでレコードが抽出されるようにする方法
レコードに直接権限を付与する方法
この方法は最もシンプルな方法ですが、レコード1つ1つに設定を行う必要があるため、レコード数が多い場合など運用が難しいケースが多いです。操作方法は、レコードの編集画面の「レコードのアクセス制御」タブを開き、任意のアクセス権を付与します。この操作を行うにはテーブルまたはレコードに対して「権限の管理」権限が必要です。
レコード作成時に自動的に権限を付与する方法
この方法は、レコードを作成した人に自動的に権限を付与する方法です。レコードを作成したタイミングで権限が付与されるためレコードに直接権限を付与する方法に比べ、運用しやすいのが特徴です。利用者からの問い合わせを受け付けて、回答するような業務に適しています。利用者には「サイトのアクセス制御」で「作成」権限のみを付与し、レコードが作成されたタイミングでレコードに「読み取り」権限が追加されるように設定します。この方法はレコードの作成時にのみ自動的にアクセス権を付与する仕組みです。レコードの更新時には動作いたしません。
設定方法
「テーブルの管理」「サイトのアクセス制御」タブで「利用者グループ」に「作成」権限を付与します。
「テーブルの管理」「レコードのアクセス制御」タブで「ユーザ」に「読み取り」権限を付与します。
「利用者グループ」のユーザでログインすると新規作成のみ行うことができます。
自分で作成したレコードは閲覧することができます。レコード作成時に自動的に読み取り権限が付与されているためです。
拡張SQLでレコードが抽出されるようにする方法
ここからは高度な方法です。レコードに権限を付与する方法と異なり、レコード取得時のSQLにWhere句を追加することで柔軟なアクセス制御を実現します。拡張SQLはブラウザで設定することができません。サーバのディレクトリに設定ファイルとSQLを書いたファイルを格納することで実装します。拡張SQLで実装したSQLは一覧画面だけでなく編集画面でも有効です。編集画面のURLを直接要求された場合でも、Where句の条件に該当しないレコードを表示することはできません。
設定方法
設定ファイル(Test.json)とSQLを書いたファイル(Test.json.sql)を準備します。Testの部分は任意のファイル名に変更可能です。ファイルはプリザンターの起動時に読み込まれるため、ファイルを格納した後にプリザンターを再起動する必要があります。SQL文は全体をカッコで囲む必要があります。SQL文にはサブクエリも使用可能です。下記の例ではサイトID 2 のテーブルで、管理者(Manager)または担当者(Owner)が自分自身(@_U)のレコードのみを抽出します。
格納先ディレクトリ(環境に合わせて読み替えてください)
C:\web\pleasanter\Implem.Pleasanter\App_Data\Parameters\ExtendedSqls
Test.json: サイトID 2 でWhere句を追加します。
{
"SiteIdList": [ 2 ],
"OnSelectingWhere": true
}
Test.json.sql: 管理者(Manager)または担当者(Owner)が自分自身のレコードのみを抽出します。@_UにはユーザIDが格納されます。下記は期限付きテーブルの例です。記録テーブルの場合には"Issues"の部分を"Results"に変更してください。
("Issues"."Manager" = @_U or "Issues"."Owner" = @_U)
サーバスクリプトのview.Filtersでレコードが抽出されるようにする方法
拡張SQLを使用する方法は柔軟なSQLを実装することができますが、設定時にサーバの再起動が必要です。サーバスクリプトのview.Filtersを使用するとサーバの再起動を行わずに柔軟なアクセス制御を実現します。また、サーバスクリプトを使用するとJavaScriptを使用してフィルタの適用条件を制御することが可能です。拡張SQLでレコードが抽出されるようにする方法と同様に一覧画面だけでなく編集画面でも有効です。
設定方法
「テーブルの管理」「サーバスクリプト」タブで「新規作成」をクリックします。表示されたダイアログに下記のようにスクリプトを記述します。「条件」は「ビュー処理時」にのみチェックします。下記の例ではグループID 1 に所属していないユーザに対し、管理者(Manager)または担当者(Owner)が自分自身(context.UserId)のレコードのみを抽出します。view.Filtersにor_で始まる任意のフィルタ名にセットすることでor条件での抽出が可能です。
let group = groups.Get(1);
if (!group.ContainsUser(context.UserId)) {
let data = {};
data.Manager = `["${context.UserId}"]`;
data.Owner = `["${context.UserId}"]`;
view.Filters.or_MyFilter = JSON.stringify(data);
}
拡張SQLとサーバスクリプトの組み合わせでレコードが抽出されるようにする方法
サーバスクリプトのview.Filtersでは実装できないような複雑なWhere句を拡張SQLで実装し、サーバスクリプトから条件によって拡張SQLの適用をコントロールすることができます。この方法は最も柔軟なアクセス制御を行うことが可能です。
設定方法
名前付きの拡張SQLをセットして、サーバスクリプトのビュー処理時に呼び出します。下記の例ではグループID 1 に所属していないユーザに対し、管理者(Manager)または担当者(Owner)が自分自身(@_U)のレコードのみを抽出します。
格納先ディレクトリ(環境に合わせて読み替えてください)
C:\web\pleasanter\Implem.Pleasanter\App_Data\Parameters\ExtendedSqls
Test.json: "Name":"SelectingWhereName"、"SpecifyByName":true、"OnSelectingWhere":trueとします。
{
"Name": "SelectingWhereName",
"SpecifyByName": true,
"OnSelectingWhere": true
}
Test.json.sql: 管理者(Manager)または担当者(Owner)が自分自身のレコードのみを抽出します。@_UにはユーザIDが格納されます。下記は期限付きテーブルの例です。記録テーブルの場合には"Issues"の部分を"Results"に変更してください。
("Issues"."Manager" = @_U or "Issues"."Owner" = @_U)
サーバスクリプト:ビュー処理時
let group = groups.Get(1);
if (!group.ContainsUser(context.UserId)) {
view.Filters.OnSelectingWhere = 'SelectingWhereName';
}
注意事項
プリザンターの横断検索は拡張SQLやサーバスクリプトのview.Filtersによるアクセス制御が行えません。拡張SQLやサーバスクリプトのview.Filtersを使用した場合には、対象のテーブルが横断検索にヒットしないよう下記の設定を行ってください。
テーブルの管理:検索:検索の設定:横断検索を無効化
https://pleasanter.org/manual/table-management-disable-cross-search
おわりに
プリザンターは今後も業務に役立つローコード開発プラットフォームとして進化を続けてまいります。応援よろしくお願いします。皆さん良いクリスマスをお過ごしください。
https://pleasanter.org