[OutSystems]プログラムからUsersアプリケーションのGroupを操作する

OutSystemsで作成したアプリケーションのAuthorization（ログインしているユーザーにその操作をする権限があるかを判定する）をには、Roleを使います。
Roleをユーザーに割り当てる手段として、

1. ユーザーに直接Roleを割り当てる
1. ユーザーをGroupに所属させ、そのGroupにRoleを割り当てる

の2通りがあります。
このGroupをプログラムから操作する方法を確認してみました。

# 確認環境
Personal Environment(Version 11.12.0 (Build 30002))
Service Studio (Version 11.11.2)

# Groupの概要
Groupの管理はUsersアプリケーションで行います。
UsersアプリケーションのGroupsタブで、Groupの作成・変更・削除・Roleの割当・ユーザーの割当をする。Groupに所属しているユーザーは、直接割り当てられたRoleに加えて、所属するGroupに割り当てられたRoleも持つことになります。

Usersアプリケーションで特定ユーザーのページを開くと、Groups下に所属Groupの一覧、Roles下に持っているRoleの一覧。Group経由で付与されたRoleはInherited from列に該当Role名が表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/97197a9c-c509-be5a-329f-0c484e0ec81b.png)

# Groupに関わるドキュメント
Entityは(System)モジュール内。完全な解説は見つからないが、[アプリケーションのユーザー、グループ、ロール](https://success.outsystems.com/ja-jp/Support/Enterprise_Customers/Maintenance_and_Operations/Data_Migration_From_Production_to_Non-Production_Environment/Application_users_groups_and_roles)が参考になる。
また、Usersアプリケーションが公開しているGroup操作用のAPIについては、[Users API](https://success.outsystems.com/ja-jp/Documentation/11/Reference/OutSystems_APIs/Users_API)の「Group_」で始まるAPIのドキュメントが該当する。

# Groupに関するモジュール・Entityの構造
Group及び関連データは(System)モジュールのGroup・Group_User・Group_Role Entityに入っているようです。公式仕様が見つかりません（近いところはGroupに関わるドキュメントにリンクがある）が、これらのEntityを参照することで、Group関連データの読み込みは可能。

Groupを作成・削除・更新するActionはUsersアプリケーションがPublicなActionとして公開しています。
しかし、Groupに含まれるユーザーやRoleを管理する機能は公開されていません。Users アプリケーションはCloneして実装を確認することができます。が、個人的には参照はともかく、非公開機能に基づいて更新はためらいます。ここでは、Groupに含まれるユーザー・Roleの管理をプログラムから実現する方法は検証対象外としておきます。

(System)モジュールのEntityをService StudioのEntity Diagramとして表現してみたのが以下の図。Groupの実体はGroup Entity、Groupに所属するユーザーはGroup_User Entity、Groupに割り当てられたRoleはGroup_Role Entityです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/d1f36852-ee5f-c584-cec7-3735627baf4c.png)

# 各機能の実装方法
## グループの検索
(System)モジュールのGroup EntityをAggregate・SQLで検索する。
Group Entityの属性は以下の通り。ユーザーが入力可能なのはNameとDescription。

| Name | Data Type | 用途 |
|:-|:-:|:-|
| Id |  Integer | 主キー  |
| Name | Text  | Group名  |
| Description | Text | Groupの説明  |
| Created By | User Identifier  | Groupを作成したユーザーのId  |
| Created  | DateTime  | Groupを作成した日時  |
| Has_Custom_Management  | Boolean  | 基本的にFalse。Trueにするのは、OutSystems標準のGroup機能への追加的な機能を別途アドオンするとき、Trueにすると、Usersアプリケーションに表示されなくなる  |

## グループに所属するユーザーの検索
(System)モジュールのGroup_User Entityを検索する。
例えば、指定Groupに所属するユーザーの一覧であれば以下のようにする。Group_UserはGroup IdとUser Idの対応を1レコードに持っているので、Group Idをキーに検索すると該当グループに所属するユーザーの一覧が返る。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/33f583e7-b56d-8ac2-865c-76d600a2e956.png)

## グループに割り当てられたRoleの検索
(System)モジュールのGroup_Role Entityを検索する。
例えば、指定Groupに割り当てられたRoleの一覧であれば、以下のようにする。Group_RoleはGroup IdとRole Idの対応を1レコードに持っているので、Group Idをキーに検索すると、該当グループに割り当てられたRoleの一覧が返る。
Espace Entityを結合対象としているのは、Roleを定義したモジュールを特定するため。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/970bec39-b4a8-83e6-72e0-aa3cac0d3e8e.png)

## グループを作る
UsersモジュールのGroup_CreateNew Actionを使う。UsersのUserManager Roleが必要。
呼び出し例。Created_ByとCreated属性はパラメータで指定しても、Action内で適切な値が再設定される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/77617d04-8307-da31-505e-442068ca9849.png)

## グループを削除する
UsersモジュールのGroup_Delete Actionを使う。UsersのUserManager Roleが必要。
パラメータのGroup Idで指定したGroupを削除する。

## グループを更新する
UsersモジュールのGroup_Update Actionを使う。UsersのUserManager Roleが必要。
Group Entityレコードを渡して呼び出すが、その中で実際に更新に使われるのはNameとDescription属性のみ。

## グループに所属するユーザーの管理
公開されている情報には該当部分がない。
UsersアプリケーションのGroupUsers Blockが参考になる。

## グループに割り当てられたRoleの管理
公開されている情報には該当部分がない。
UsersアプリケーションのGroupRoles Blockが参考になる。