Yellowfin PHP + REST API ユーザー属性情報変更

## はじめに
これまでも、[『SSO』](https://qiita.com/ExtremeCarvFJ/items/989a3c2bfa34ccdd177f)、[『情報参照』](https://qiita.com/ExtremeCarvFJ/items/0d3d9005b03e917ad839)、[『ユーザー登録』](https://qiita.com/ExtremeCarvFJ/items/1ddf337a6b24a948dc1e)、[『グループメンバー登録』]( https://qiita.com/ExtremeCarvFJ/items/dbd0f8a0722e2bfe06d7)など、Yellowfin の管理に REST API を活用する方法を幾つか紹介してきました。今回は、ユーザー属性情報変更に REST APIを活用する方法を紹介します。
社員の異動時などに、人事情報やディレクトリサービスの情報と連動し、バッチ処理などで Yellowfin の属性情報を変更することは、セキュリティ面からも非常に重要です。例えば、IT 部門に所属しシステム管理者権限を持っていた社員が、財務部に移動した場合を想定してみます。部署移動に伴い、それまで保持していたシステム管理者権限は必要なくなり、一般ユーザーとしてのアクセスが適切となります。この場合、異動後即座にユーザーに紐づけるロール（Yellowfin へのアクセス権限のセット）を変更することで、セキュリティを担保しながら Yellowfin を運用することができます。

## REST API 開発者用ドキュメントと動作検証
Yellowfin の REST API に関する詳細な情報は、[開発者サイト](https://developers.yellowfinbi.com/dev/api-docs/current/)に記述があります。
上記で API の仕様を確認した後、ブラウザのディベロッパーツールなどで、リクエストする情報と、レスポンスの情報が正しいか否かを確認しましょう。Chrome の場合だと、API Tester が該当します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128512/7e8362c7-fda4-558e-8e3b-2ed7489a39cd.png)

## アクセストークンの取得
Yellowfin のリソースにアクセスするために、2 種類のトークンを使用します。
1 つ目はリフレッシュトークンです。有効期限の無いトークンで、アクセストークンを取得するために必ず必要です。refresh-tokens API に対してリフレッシュトークンを POST で要求し取得します。
2 つ目はアクセストークンです。access-tokens API に対して入手済みのリフレッシュトークンを使って、POST で要求し取得します。
アクセストークンの取得に関する詳細は、[『情報参照』](https://qiita.com/ExtremeCarvFJ/items/0d3d9005b03e917ad839)記事の該当箇所をご確認ください。

## ユーザー属性情報の変更に必要な情報
先の手順で取得したトークンを用いて、ユーザー IDとロールコードに関する情報を GET で取得します。
以下の処理では、ユーザー ID とロールコードを指定してユーザーの属性情報を変更します。
ユーザー ID とロールコードの取得に関しても、[『情報参照』](https://qiita.com/ExtremeCarvFJ/items/0d3d9005b03e917ad839)記事の該当箇所をご確認ください。
下記ユーザーの属性を変更しようと思います。現在 Consumer & Collaborator のロールで Yellowfin にアクセスしています。同ユーザーが情報システム部に移動したため、システム管理者権限のロールに付け替えることを想定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128512/04e71b06-ff93-f7f8-3123-0607d76dcea3.png)
ついでに、現在このユーザーは東京勤務ですが、システム部門は豪州のシドニーにあるため、言語とタイムゾーンも変更になることにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128512/185750a7-c5d2-2656-9c04-1b47ae8f495c.png)

## ユーザー属性情報の定義
ここまでに取得したアクセストークン、ユーザー ID、ロールコードを使って、ユーザーの属性情報を変更します。

早速、先の手順で確認したロールコードを活用します。メールアドレス、ロール、氏名、言語、時間帯などのユーザー属性を JSON 書式で定義します。この JSON ファイルを後述のプログラムの中でボディー情報として読み込みます。ちなみに、YFADMIN は System Administrators のロールコードです。languageCode と timeZoneCode も該当する情報を指定します。
```json:update_user.json
{
  "emailAddress": "toshiya.hosokawa@yellowfin.bi",
  "roleCode": "YFADMIN",
  "firstName": "俊哉",
  "lastName": "細川",
  "languageCode": "en",
  "timeZoneCode": "AUSTRALIA/SYDNEY"
}
```

## ユーザー属性情報の変更処理
ユーザー属性情報の変更に関する API の仕様は[『Update a user for the purpose of user administration』](https://developers.yellowfinbi.com/dev/api-docs/current/#operation/updateUserAdmin)に説明があります。この仕様に従って、/api/admin/users/{userId} API に対して、PATCH で要求を投げます。
下記サンプルでは、変数宣言個所で useId 変数に対象のユーザー ID を記述し、URL の一部とします。
ヘッダーデータの一部に UNIX 時間を示す整数値と、先の手順で取得したアクセストークンを指定しています。
ボディー情報として、先の手順で作成した JSON ファイルを読み込みます。
これら情報を伴い、cURL で PATCH 処理を実行します。

```php:ユーザー属性変更
//変数の宣言
$userId = '13170';
$url3 = 'http://localhost:8080/api/admin/users/'.$userId;
$time2 = ceil(microtime(true)*1000);

//ユーザー属性変更：ヘッダーデータ作成
$header3 = array(
	'Authorization:YELLOWFIN ts='.$time2.', nonce=123, token='.$accessToken,
	'Accept:application/vnd.yellowfin.api-v2+json',
	'Content-Type:application/json'
);

//ユーザー属性変更：ユーザーデータ読込
ob_start();
include("update_user.json");
$userData = ob_get_clean();

//ユーザー属性変更：変更処理
$ch3 = curl_init();
curl_setopt($ch3, CURLOPT_HTTPHEADER, $header3);
curl_setopt($ch3, CURLOPT_CUSTOMREQUEST, 'PATCH');
curl_setopt($ch3, CURLOPT_POSTFIELDS, $userData);
curl_setopt($ch3, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch3, CURLOPT_URL, $url3);
$result3 =curl_exec($ch3);
curl_close($ch3);
```

## プログラム全容
プログラムの全容は以下の通りです。
```php:deleteUser.php
//変数の宣言
$adminId = 'admin@yellowfin.com.au';
$adminPassword = 'test';
$time = ceil(microtime(true)*1000);
$url = 'http://localhost:8080/api/refresh-tokens';
$url2 = 'http://localhost:8080/api/access-tokens';
$refreshToken = "";
$accessToken = "";

//リフレッシュトークン：HEADERデータ作成
$header = array(
    'Authorization:YELLOWFIN ts='.$time.', nonce=123',
    'Accept:application/vnd.yellowfin.api-v2+json',
    'Content-Type:application/json;charset=UTF-8'
);

//リフレッシュトークン：BODYデータ作成
$body = array(
    'userName'=>$adminId,
    'password'=>$adminPassword
);
$body_json = json_encode($body, JSON_PRETTY_PRINT);

//リフレッシュトークン：Yellowfinにトークンを要求
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_POSTFIELDS, $body_json);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, $url);
$result = curl_exec($ch);
$json_result = json_decode($result);
$refreshToken = $json_result->securityToken;
curl_close($ch);

//アクセストークン：HEADERデータ作成
$header2 = array(
    'Authorization:YELLOWFIN ts='.$time.', nonce=123, token='.$refreshToken,
    'Accept:application/vnd.yellowfin.api-v2+json',
    'Content-Type:application/json'
);

//アクセストークン：Yellowfinにトークンを要求
$ch2 = curl_init();
curl_setopt($ch2, CURLOPT_HTTPHEADER, $header2);
curl_setopt($ch2, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch2, CURLOPT_POSTFIELDS, '');
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch2, CURLOPT_URL, $url2);
curl_close($ch);
$result2 = curl_exec($ch2);
$json_result2 = json_decode($result2);
$accessToken=$json_result2->securityToken;

//変数の宣言
$userId = '13170';
$url3 = 'http://localhost:8080/api/admin/users/'.$userId;
$time2 = ceil(microtime(true)*1000);

//ユーザー属性変更：ヘッダーデータ作成
$header3 = array(
	'Authorization:YELLOWFIN ts='.$time2.', nonce=123, token='.$accessToken,
	'Accept:application/vnd.yellowfin.api-v2+json',
	'Content-Type:application/json'
);

//ユーザー属性変更：ユーザーデータ読込
ob_start();
include("update_user.json");
$userData = ob_get_clean();

//ユーザー属性変更：変更処理
$ch3 = curl_init();
curl_setopt($ch3, CURLOPT_HTTPHEADER, $header3);
curl_setopt($ch3, CURLOPT_CUSTOMREQUEST, 'PATCH');
curl_setopt($ch3, CURLOPT_POSTFIELDS, $userData);
curl_setopt($ch3, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch3, CURLOPT_URL, $url3);
$result3 =curl_exec($ch3);
curl_close($ch3);
```

上記プログラムを実行すると、該当ユーザーの属性情報が変更されます。
```powershell:deleteUser.php
PS> php deleteUser.php
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128512/ff28d406-9cfc-62d5-82d5-749c4629192a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2128512/bb70452b-796a-7134-0c3e-a90c7a9d73cb.png)

## 最後に
ユーザーの退職時や移動時など、人事情報を即座に各システムに反映させることの重要性は言うまでもありません。API を活用して、様々な処理を自動化し、運用効率に加え、運用精度も高めていけたら素敵ですね。
では皆様、良いデータ分析を! See you then! Cheers!