情報銀行のプラットフォームとして利用できるかもしれないPersonium（PDS） を検証してみる ９ ＜APIでExtRoleを触ってみる＞

##さて… APIでいろいろ触ってきましたが… この一連のエントリでの２つ目のヤマ場を迎えております。（1つめはAnsibleでの環境の構築だったのですが…）ここのヤマ場とはこのエントリで解説しようと思っている ExtCell と ExtRole なのです。 実は私もまだわかっていません。　全くの初物なのです。

Personium は PDS であり、これまでの一連のエントリでも 自身のデータをストアするための機能について説明してきております。あくまでもセル内のリソースにアクセスできる エライ（unitadmin）ユーザーか、エラくない（user）ユーザーです。エラくないユーザーに関しては＂誰がなんと云おうとも＂セル内のデータアクセスに限られています。

でも、なんのために自身のデータをストアすのかと云うと… たぶん… 
特定の信頼できる自身以外のユーザーになんらかの目的のため、参照してもらうためなのだと思います。
PDSのユーザーは、そういう何かりらののメリットのために「自身のデータをストアしそしてそれをストックする」と決断しているはずです。
日記のように、自身でストアしたデータを眺めニンマリすることが目的のユーザーは存在するかもしれませんが、なんのインセンティブもなくストア・ストックするモチベーションが湧くユーザーはごく稀な現象と思います。

- もしかすると… ダイエットを効果的に続けるための、トレーナーへの報告すべきデータかもしれません。
- もしかすると… 掛かりつけではない医師への、これまでに処方された薬の記録としての情報提供が目的かもしれません。
- もしかすると… ポイント取得を目的とした、家計簿データの提供なのかもしれません。
- そして、もしかするともしかすると… **『情報銀行』**への＂情報＂の提供が目的なのかもしれません。

そのためには、自身のセル（ボックス）内のデータを、他のセル（ユーザー）へ参照する権限を付与する機能が必要で、それが ExtCell ならびに ExtRole なのだと想定しています。

その ExtRole は、ユニットマネージャで見ると、以下の画像のように「Social」メニューの配下に「External Cell」「Relation」「External Role」とメニュー化されています。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/352554/79bac117-a0f8-71bc-c0bc-50d8e85893da.png)

そしていろいろドキュメントを漁ってみても、これらの概念や利用方法を簡単に説明されているドキュメントが見当たらないのです。なので私もここを避けて通っておりました…
たぶん Personium を利用して（しようとして）いる皆さんも、一段と大きなハードルが立ちはだかったのではないかと思います。

なので私も、いつまでも避けていてもしょうがないので、このエントリで取り上げ理解に向けた試行錯誤を記載しようかと思います。

---

###１．訳も分からず… まずは ユニットマネージャで操作

#### ExtRole

とはいえ、ユニットマネージャにも操作マニュアルが有る訳でもなく… 弄りながら探ってみることとしましょう。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/352554/afc4c19e-fb48-209a-e881-4b78fd12bd27.png)


- *External Role URL　・・・　これはExtRole名をURLで指定しろ… と云うことなのでしょうか？必須ですね。
- *Relation　　　　　　・・・　Relation 先ほどメニューにありましたね… そして必須です。
- □ Assign Role　　　 ・・・　これにチェックを入れると、下のRoleがEnableになりそうです。
- Role　　　　　　　　 ・・・　RoleがEnableになると［userrole（userbox）］が選択できるようになりました。

「External Role URL」は何を入力するのでしょう？
ExtRoleの登録なのですから、ExtRole名を求められるはずなので… でも要求されているのはURL！
なんのURLなのでしょう？？

ドキュメントの[ExtRole登録](https://personium.io/docs/ja/apiref/1.6.10/245_Create_External_Role.html) を参照すると、cURLサンプルとして以下のように記載されていますので参考にしてみましょう。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/352554/2ab51c89-db3a-2e9b-75af-73bc186b2d9f.png)

ちょっとcurlの要素を分解してみると
＂curl "https://{UnitFQDN}/{CellName}/__ctl/ExtRole" -X POST＂ これはコマンド。
「{UnitFQDN}/{CellName}セルにExtRoleを追加登録」というコマンドだと思います。

Bodyは、＂"ExtRole": "https://{UnitFQDN}/{CellName}/\_\_role/\_\_/{ExtRoleName}", "_Relation.Name": "{RelationName}", "\_Relation._Box.Name": "{BoxName}"＂なので、
 "ExtRole" にはURLが指定されています。
あとは "_Relation.Name" と "\_Relation._Box.Name" 。いまいちスッキリわかる感じではない。

#### Relation

ExtRole の登録に Relation が＂必須＂なのだから、たぶん先に Relation が存在していなければいけないとのことだと思いますよね。 なので次は Relation を探ってみましょう。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/352554/c402f51f-6e67-bc10-dde0-07deda6bb201.png)


- *Name　　　　　　　　・・・　ここはURLではないので、名称を指定すれば良さそうです。必須ですね。
- *Box where this relation is used・・・　「この関係が使われている箱」だそうです。 必須です。
- □ Assign Role　　　 ・・・　これにチェックを入れると、下のRoleがEnableになります。
- Role　　　　　　　　 ・・・　RoleがEnableになると［userrole（userbox）］が選択できるようになります。

とりあえず入力できない設定は無いので、ユニットマネージャを利用し Relation を以下の値で登録してみましょう。

| 設定 | 値 | 備考 |
|:--|:--|:--|
| Name | userExtRelation | 入力 |
| Box where this relation is used | userbox | 選択 |
| Assign Role | ON | チェック |
| Role | userrole（userbox） | 選択 |



＂userExtRelation＂が登録できました！！
![image.png](https://qiita-image-store.s3.amazonaws.com/0/352554/c18dfd00-a0ed-5364-33ac-861648c0cb74.png)


#### ExtRole 再び

ではもう一度 ExtRole に戻り、以下の値で登録してみましょう。

| 設定 | 値 | 備考 |
|:--|:--|:--|
| External Role URL | https://personium.takky.org/usercell/__role/__/userExtRole | 入力 |
| Relation | userExtRelation | 選択 |
| Assign Role | ON | チェック |
| Role | userrole（userbox） | 選択 |

＂userExtRole＂も登録ができました！！
![image.png](https://qiita-image-store.s3.amazonaws.com/0/352554/75063a08-1b5f-3427-990f-7f040a25c341.png)


####でもなんだか… 私の気分は晴れません…

以下の設定では、メリットのある誰かに、自身のデータの参照権を提供する設定になっているようには思えません！！
　Relation：nameで指定したRelationを、自身のセル内のボックスに対して設定
　　　　　　　（オプションでセル内のロールを設定）
　ExtRole ：自身のセル内のURLで指定したExtRoleを、自身のセル内のリレーションに対して設定
　　　　　　　（オプションでセル内のロールを設定）


###２．ExtRoleでやりたいことの整理

ユニットマネージャを利用し、ExtRoleを作成することには成功しました。
しかし、私の気が晴れていないのは、前の項で説明しました。

ここで一度、ExtRoleでやりたいことを整理してみましょう。

| 対象 | 目的 | 値 | 備考 |
|:--|:--|:--|:--|
| 参照先のセル | 自身のセル | usercell | 作成済 |
| 参照先のボックス | 自身のセル内のボックス | userbox | 作成済 |
| 参照先のコレクション１ | 自身のセル内のボックス上のWebDav | WebDavContents  | 作成済 |
| 参照先のコレクション２ | 自身のセル内のボックス上のOData | ODataContents | 作成済 |
| 参照を許可するセル | 友達のセル | friendcell | 未作成 |
| 参照を許可するボックス | 友達のセル内のボックス | friendbox | 未作成 |
| リレーション | 自身のデータの参照を許可するリレーション | userRelation | ？？ |
| ロール（権限） | 自身のデータの参照を許可する権限 | userExtRole | ？？ |


ボックスはアプリとひも付いていることは以前のエントリーで説明しています。
アプリからリクエストされるAPIは「参照を許可するボックス」からの要求であり、これに対し権限が許可されている場合に、参照先のコレクションのデータを参照できるべきです。

そしてこの権限の許可は、参照先のユーザーが許可（権限を付与）する形になるはずです。

リレーション（Relation）には、「参照を許可するボックス」もしくは「参照を許可するロール」を指定し、ロール（ExtRole）には、リレーション（Relation）に対するロール（権限）が登録されような気がします。
そしてそれらを整理すると、以下のようになります。

【 Relation 】

| 設定 | 目的 | 値 | 備考 |
|:--|:--|:--|:--|
| Name | リレーション名 | userExtRelation |  |
| Box where this relation is used | 参照先のボックス | userbox |  |
| Role | ロール（権限） | userrole（userbox） |  |

【 ExtRole 】

| 設定 | 目的 | 値 | 備考 |
|:--|:--|:--|:--|
| External Role URL | 参照を許可するロール | https://personium.takky.org/friendcell/__role/__/friendRole |  |
| Relation | リレーション名 | userExtRelation |  |
| Role | ロール（権限） | userrole（userbox） |  |

それでもまだ… なんだかしっくりしません。


###３．参照を許可するセルやボックスを作成する

しっくりはしないにせよ、まずは参照を許可する対象が必要なのは明らかです。
まずは、参照を許可する対象のセル・ボックス・ユーザー・ロールを作成しましょう。

#####参照許可対象のセル（friendcell）の作成
　（unitadmin のトークンで作業をします）

```
$ curl "https://personium.takky.org/__ctl/Cell" \
-X POST -i -k \
-d "{\"Name\":\"friendcell\"}" \
-H "Accept:application/json" -H "Authorization:Bearer {{unitAdminToken}}"

HTTP/1.1 201 
Date: Mon, 25 Mar 2019 06:12:15 GMT
Content-Type: application/json
Content-Length: 251
Connection: keep-alive
Location: https://personium.takky.org/__ctl/Cell('friendcell')
DataServiceVersion: 2.0
ETag: W/"1-1553494335667"
X-Personium-Version: 1.7.4
Server: Personium

{
  "d":{
    "results":{
      "__metadata":{
        "uri":"https:\/\/personium.takky.org\/__ctl\/Cell('friendcell')",
        "etag":"W\/\"1-1553494335667\"",
        "type":"UnitCtl.Cell"
      },
      "Name":"friendcell",
      "__published":"\/Date(1553494335667)\/",
      "__updated":"\/Date(1553494335667)\/"
    }
  }
}
```

#####参照許可対象のボックス（friendbox）の作成

```
$ curl "https://personium.takky.org/friendcell/__ctl/Box" \
-X POST -i \
-d "{\"Name\":\"friendbox\"}" \
-H "Accept:application/json" -H "Authorization:Bearer {{unitAdminToken}}"

HTTP/1.1 201 
Date: Mon, 25 Mar 2019 06:19:25 GMT
Content-Type: application/json
Content-Length: 271
Connection: keep-alive
Location: https://personium.takky.org/usercell/__ctl/Box('friendbox')
DataServiceVersion: 2.0
ETag: W/"1-1553494765198"
X-Personium-Version: 1.7.4
Server: Personium

{
  "d":{
    "results":{
      "__metadata":{
        "uri":"https:\/\/personium.takky.org\/friendcell\/__ctl\/Box('friendbox')",
        "etag":"W\/\"1-1553494765198\"",
        "type":"CellCtl.Box"
      },
      "Name":"friendbox",
      "Schema":null,
      "__published":"\/Date(1553494765198)\/",
      "__updated":"\/Date(1553494765198)\/"
    }
  }
}
```

#####参照許可対象のアカウント（friend）の作成

```
$ curl "https://personium.takky.org/friendcell/__ctl/Account" \
-X POST -i \
-d "{\"Name\":\"friend\"}" \
-H "X-Personium-Credential:{{passWord}}" \
-H "Accept:application/json" -H "Authorization:Bearer {{unitAdminToken}}"

HTTP/1.1 201 
Date: Mon, 25 Mar 2019 06:26:02 GMT
Content-Type: application/json
Content-Length: 312
Connection: keep-alive
Location: https://personium.takky.org/friendcell/__ctl/Account('friend')
DataServiceVersion: 2.0
ETag: W/"1-1553495162662"
X-Personium-Version: 1.7.4
Server: Personium

{
  "d":{
    "results":{
      "__metadata":{
        "uri":"https:\/\/personium.takky.org\/friendcell\/__ctl\/Account('friend')",
        "etag":"W\/\"1-1553495162662\"",
        "type":"CellCtl.Account"
      },
      "Name":"friend",
      "LastAuthenticated":null,
      "Type":"basic",
      "Cell":null,
      "__published":"\/Date(1553495162662)\/",
      "__updated":"\/Date(1553495162662)\/"
    }
  }
}
```

#####参照許可対象のロール（friendrole）の作成

```
$ curl "https://personium.takky.org/friendcell/__ctl/Role" \
-X POST -i \
-d "{\"Name\":\"friendrole\",\"_Box.Name\":\"friendbox\"}" \
-H "Accept:application/json" -H "Authorization:Bearer {{unitAdminToken}}"

HTTP/1.1 201 
Date: Mon, 25 Mar 2019 07:02:57 GMT
Content-Type: application/json
Content-Length: 314
Connection: keep-alive
Location: https://personium.takky.org/friendcell/__ctl/Role(Name='friendrole',_Box.Name='friendbox')
DataServiceVersion: 2.0
ETag: W/"1-1553497377324"
X-Personium-Version: 1.7.4
Server: Personium

{
  "d":{
    "results":{
      "__metadata":{
        "uri":"https:\/\/personium.takky.org\/friendcell\/__ctl\/Role(Name='friendrole',_Box.Name='friendbox')",
        "etag":"W\/\"1-1553497377324\"",
        "type":"CellCtl.Role"
      },
      "Name":"friendrole",
      "_Box.Name":"friendbox",
      "__published":"\/Date(1553497377324)\/",
      "__updated":"\/Date(1553497377324)\/"
    }
  }
}
```

#####参照許可対象のロール（friendrole）とアカウント（friend）のひも付け

```
$ curl "https://personium.takky.org/friendcell/__ctl/Role(Name='friendrole',_Box.Name='friendbox')/\$links/_Account" \
-X POST -i \
-d "{\"uri\":\"https://personium.takky.org/friendcell/__ctl/Account('friend')\"}" \
-H "Accept:application/json" -H "Authorization:Bearer {{unitAdminToken}}"

HTTP/1.1 204 
Date: Mon, 25 Mar 2019 07:32:46 GMT
Connection: keep-alive
DataServiceVersion: 2.0
X-Personium-Version: 1.7.4
Server: Personium
```

#####［おまけ］確認用のWebDavオブジェクトの作成とACL（read,write）の付与

```
$ curl "https://personium.takky.org/friendcell/friendbox/WebDavContents" \
-X MKCOL -i \
-d "<?xml version=\"1.0\" encoding=\"utf-8\"?><D:mkcol xmlns:D=\"DAV:\" xmlns:p=\"urn:x-personium:xmlns\"><D:set><D:prop><D:resourcetype><D:collection/></D:resourcetype></D:prop></D:set></D:mkcol>" \
-H "Accept:application/json" -H "Authorization:Bearer {{unitAdminToken}}"

HTTP/1.1 201 
Date: Mon, 25 Mar 2019 08:00:10 GMT
Content-Length: 0
Connection: keep-alive
ETag: "1-1553500810323"
X-Personium-Version: 1.7.4
Server: Personium



$ curl 'https://personium.takky.org/friendcell/friendbox/WebDavContents'  \
-X ACL -i \
-d '<D:acl xmlns:D="DAV:" xmlns:p="urn:x-personium:xmlns" xml:base="https://personium.takky.org/friendcell/__role/friendbox/"><D:ace><D:principal><D:href>friendrole</D:href></D:principal><D:grant><D:privilege><p:read/></D:privilege><D:privilege><p:write/></D:privilege></D:grant></D:ace></D:acl>' \
-H "Accept:application/json" -H "Authorization:Bearer {{unitAdminToken}}"

HTTP/1.1 200 
Date: Mon, 25 Mar 2019 08:06:37 GMT
Content-Length: 0
Connection: keep-alive
ETag: "2-1553500810323"
X-Personium-Version: 1.7.4
Server: Personium


```

###４．friend の トークンで userboxのWebDavContents にアクセス

まずは、アカウント（friend）のトークンの取得し、friendboxのWebDavContents にアクセス


```
$ curl "https://personium.takky.org/friendcell/__token" \
-X POST -i \
-d "grant_type=password&username=friend&password={{passWord}}" \
-H "Content-Type: application/x-www-form-urlencoded"

HTTP/1.1 200 
Date: Mon, 25 Mar 2019 07:41:48 GMT
Content-Type: application/json
Content-Length: 331
Connection: keep-alive
X-Personium-Version: 1.7.4
Server: Personium

{
  "access_token":"{{friend_token}}",
  "refresh_token_expires_in":86400,
  "refresh_token":"{{refresh_token}}",
  "token_type":"Bearer",
  "expires_in":3600
}



$ curl "https://personium.takky.org/friendcell/friendbox/WebDavContents" \
-X PROPFIND -i \
-d '<?xml version="1.0" encoding="utf-8"?><D:propfind xmlns:D="DAV:"><D:allprop/></D:propfind>' \
-H 'Depth:0' \
-H "Accept:application/json" -H "Authorization:Bearer {{friend_token}}"

HTTP/1.1 207 
Date: Mon, 25 Mar 2019 08:09:22 GMT
Content-Type: application/xml
Content-Length: 532
Connection: keep-alive
ETag: "2-1553500810323"
X-Personium-Version: 1.7.4
Server: Personium

<multistatus xmlns="DAV:">
    <response>
        <href>https://personium.takky.org/friendcell/friendbox/WebDavContents</href>
        <propstat>
            <prop>
                <creationdate>2019-03-25T08:00:10.323+0000</creationdate>
                <getlastmodified>Mon, 25 Mar 2019 08:00:10 GMT</getlastmodified>
                <resourcetype>
                    <collection/>
                </resourcetype>
            </prop>
            <status>HTTP/1.1 200 OK</status>
        </propstat>
    </response>
</multistatus>
```

friendboxのWebDavコレクションへのアクセスはOKです。


次に、上記で取得したトークンで、他のセルのWebDavコレクションにアクセスしてみる。
これで、スルっとアクセスできたらやばいよね！！

```
$ curl "https://personium.takky.org/usercell/userbox/WebDavContents" \
-X PROPFIND -i \
-d '<?xml version="1.0" encoding="utf-8"?><D:propfind xmlns:D="DAV:"><D:allprop/></D:propfind>' \
-H 'Depth:0' \
-H "Accept:application/json" -H "Authorization:Bearer {{friend_token}}"

HTTP/1.1 401 
Date: Mon, 25 Mar 2019 08:11:11 GMT
Content-Type: application/json
Content-Length: 77
Connection: keep-alive
WWW-Authenticate: Bearer realm="https://personium.takky.org/usercell/"
WWW-Authenticate: Basic realm="https://personium.takky.org/usercell/"
X-Personium-Version: 1.7.4
Server: Personium

{
  "code":"PR401-AU-0006",
  "message":{
    "lang":"en","value":"Token parse error."
  }
}
```

想定通り、エラー！！
でも、エラーコードが「Token parse error.」となっている。ちょっと想定外。

####あ〜 そして今思い出しましたぁ。 他のセルのデータにアクセスするには、トランスセルアクセストークンってやつがキーとなっていて、それはリクエストに p_target というパラメータを付与するのでした。
前回のもくもく会で会話してたの… 今、思い出したわ…


###### もくもく会（第4回）のメモ
```
１．トランスセルアクセストークンを理解し、アプリ内で他のCellのコンテンツを参照する

　ー　ー　ー　ー　ー　ー　ー　ー　ー　ー　ー　ー　ー　ー　ー　ー　

もくもく会内での実装は叶わなかったが、＠shimono さん、dixonsui さんに
参考にすべきドキュメント・コードを教えていただいた。
参考情報を確認したところ、③のコードをベースに組み込めば容易に実現できそうである。

また、Unit Managerの「External Cell」と「Relation」についての確認が漏れていたので、操作ならびに実装をしながら確認する。

　ー　ー　ー　ー　ー　ー　ー　ー　ー　ー　ー　ー　ー　ー　ー　ー　

　① Slack内での「トランスセルアクセストークン」についての会話
　　→ 『「トランスセルアクセストークン」と「普通のアクセストークン」との違いは、1つのみ指定できる p_target だけ』をいう認識
https://personium-io.slack.com/conversation/C4BU5DENB/p1547101511043500

　② Tokenの種類についての説明
　　→ ここでは（curl "{CellURL}__token" -X POST -i -d \
'grant_type=urn:ietf:params:oauth:grant-type:saml2-bearer&assertion=\
{SAML_token}&p_target={CellURL}'）となっており、① の認識とはギャップがある（ので、今後実際の実装で確認する）
https://personium.io/docs/ja/apiref/current/293_OAuth2_Token_Endpoint.html

　③ 他のアプリ（myboard）で Transcell token を取得している処理のコード
　　→ L83〜L95の処理で getTranscellToken() と getAppAuthToken()を取得し、それぞれのTokenを、getProtectedBoxAccessToken4ExtCell() に渡すらしい。
https://github.com/personium/app-myboard/blob/master/src/html/js/common.js#L83

　④ Chromeの「Restlet Client」で操作するサンプルの設定ファイル
　　→ ③の L83〜L95 の処理が、"05"〜"09"の工程と思われる
　　　　 "01 Get User Auth token"
　　　　 "02 Get App authentication token"
　　　　 "03 Get protected Box access token"
　　　　 "04 Get User Box URL"
　　　　 "045 Get list of logs"
　　　　 "05 Get App authentication token (friend)"
　　　　 "06 Get Transcell token (friend)"
　　　　 "07 Get protected Box access token (friend)"
　　　　 "08 Get Friend Box URL"
　　　　 "09 Get list of logs (friend)"
https://github.com/personium/template-app-cell/blob/master/doc/Personium_Mokumoku3.json
```

い〜やぁ… すっかり忘れていましたわ！

なので、アカウント（friend）の usercell 用のトランスセルアクセストークンの取得し、userboxのWebDavContents にアクセスしてみる

#####トランスセルアクセストークンの取得

上記のメモには＂&p_target={CellURL}＂とあるので、参照先のセルを指定すれば良いらしい。

```
$ curl "https://personium.takky.org/friendcell/__token" \
-X POST -i \
-d "grant_type=password&username=friend&password={{passWord}}&p_target=https://personium.takky.org/usercell/" \
-H "Content-Type: application/x-www-form-urlencoded"

HTTP/1.1 200 
Date: Mon, 25 Mar 2019 09:03:57 GMT
Content-Type: application/json
Content-Length: 4391
Connection: keep-alive
Location: https://personium.takky.org/usercell/__token
X-Personium-Version: 1.7.4
Server: Personium

{
  "access_token":"{{transcell_token}}",
  "refresh_token_expires_in":86400,
  "refresh_token":"{{reflesh_token}}",
  "p_target":"https:\/\/personium.takky.org\/usercell\/",
  "token_type":"Bearer",
  "expires_in":3600
}
```

おー。 ながーい{{transcell_token}}を取得することができました。

このトークンで、他のセルのWebDavコレクションにアクセスしてみましょう。

```
$ curl "https://personium.takky.org/usercell/userbox/WebDavContents" \
-X PROPFIND -i \
-d '<?xml version="1.0" encoding="utf-8"?><D:propfind xmlns:D="DAV:"><D:allprop/></D:propfind>' \
-H 'Depth:0' \
-H "Accept:application/json" -H "Authorization:Bearer {{transcell_token}}"

HTTP/1.1 403 
Date: Mon, 25 Mar 2019 09:13:12 GMT
Content-Type: application/json
Content-Length: 90
Connection: keep-alive
X-Personium-Version: 1.7.4
Server: Personium

{
  "code":"PR403-AU-0002",
  "message":{
    "lang":"en",
    "value":"Necessary privilege is lacking."
  }
}
```

わぉ！ 
普通のトークンでのエラーコードが「Token parse error.」だったが、トランスセルアクセストークンでアクセスすると、「Necessary privilege is lacking.」と＂必要な権限がない＂エラーになりました。
要するに、間違ったことはしていないけど… 権限が足りないのでアクセスができない。と云うことでしょう。
一歩前進したように感じる。


###５．friend の トランスセルアクセストークンで userboxのWebDavContents にアクセス（ExtCell）

一歩前進したものの、ドキュメントからもこれ以上の情報も得られず、これからどうしよう… と途方にくれながらユニットマネージャから usercell をいろいろ触っていると…
先ほどは触れなかった、「External Cell」ってやつがあることに気がつきました。
そしてこれの登録用ダイアログを触ってみると、 Select Cell の項目に friendcell が選択できることにも気がつきました！

![image.png](https://qiita-image-store.s3.amazonaws.com/0/352554/806ffe78-a275-fcaa-8edf-b1c450d3cb07.png)

そして Relation の設定に、以前の項で作成した「userExtRelation」も選択ができます。
そして勢いで［Create］をぽちっと。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/352554/2973fb3f-544c-20ea-af17-488470281143.png)

ついでに勢いなので、前の項で「Necessary privilege is lacking.」エラーとなったのと同じコマンドを実行してみましょう！

```
$ curl "https://personium.takky.org/usercell/userbox/WebDavContents" \
-X PROPFIND -i \
-d '<?xml version="1.0" encoding="utf-8"?><D:propfind xmlns:D="DAV:"><D:allprop/></D:propfind>' \
-H 'Depth:0' \
-H "Accept:application/json" -H "Authorization:Bearer {{friend_token}}"

HTTP/1.1 207 
Date: Mon, 25 Mar 2019 09:27:48 GMT
Content-Type: application/xml
Content-Length: 528
Connection: keep-alive
ETag: "7-1552907213235"
X-Personium-Version: 1.7.4
Server: Personium

<multistatus xmlns="DAV:">
    <response>
        <href>https://personium.takky.org/usercell/userbox/WebDavContents</href>
        <propstat>
            <prop>
                <creationdate>2019-03-18T11:06:53.235+0000</creationdate>
                <getlastmodified>Mon, 18 Mar 2019 11:06:53 GMT</getlastmodified>
                <resourcetype>
                    <collection/>
                </resourcetype>
            </prop>
            <status>HTTP/1.1 200 OK</status>
        </propstat>
    </response>
</multistatus>
```

###ん？ 207??

あれ… WebDavのコレクションが参照できています！ あっけなく… 感動が少ない…

ちょっとまだ、キツネにつままれている感が漂っているため… もう一度 ExtCell を削除して試してみましょう。

```
$ curl "https://personium.takky.org/usercell/userbox/WebDavContents" \
-X PROPFIND -i \
-d '<?xml version="1.0" encoding="utf-8"?><D:propfind xmlns:D="DAV:"><D:allprop/></D:propfind>' \
-H 'Depth:0' \
-H "Accept:application/json" -H "Authorization:Bearer {{transcell_token}}"

HTTP/1.1 403 
Date: Mon, 25 Mar 2019 09:36:11 GMT
Content-Type: application/json
Content-Length: 90
Connection: keep-alive
X-Personium-Version: 1.7.4
Server: Personium

{
  "code":"PR403-AU-0002",
  "message":{
    "lang":"en",
    "value":"Necessary privilege is lacking."
  }
}
```

やはり、権限がないエラーです。
このことより、偶然の賜物ではあるけど、上記で設定した ExtCell であればアクセスができるようです。

**※ なおこの後の操作で、これまでに登録した ExtRole は邪魔になりますので、ここで削除しておいてください。**



####では調子に乗って… 上手くいった ExtCell をAPIで登録してみましょう！

今の所、ExtCellでは確認ができましたが、まだAPIでの作成はできていません。
Relation も全て削除して、APIでの作成をしてみましょう。

以下のような設定でうまくいったはずです…

【 ExtCell 】

| 設定 | 目的 | 値 | 備考 |
|:--|:--|:--|:--|
| External Cell Location | 参照を許可するセルが存在するユニット | This Unit | This Unit／Other |
| Select Cell | 参照を許可するセル | friendcell |  |
| Relation | リレーション | userExtRelation | Assign |

【 Relation 】

| 設定 | 目的 | 値 | 備考 |
|:--|:--|:--|:--|
| Name | リレーション名 | userExtRelation |  |
| Box where this relation is used | 参照先のボックス | userbox |  |
| Role | ロール（権限） | userrole（userbox） | Assign |


######ExtCellの設定をユニットマネージャで確認すると…
![image.png](https://qiita-image-store.s3.amazonaws.com/0/352554/5fdb9f6b-dbd1-7dd7-b88c-133951715974.png)

#####API での Relation の登録と、ロールのアサイン

Relation（userExtRelation）の登録

```
$ curl "https://personium.takky.org/usercell/__ctl/Relation" \
-X POST -i \
-d '{ "Name":"userExtRelation", "_Box.Name": "userbox"}' \
-H "Accept:application/json" -H "Authorization:Bearer {{unitAdminToken}}"

HTTP/1.1 201 
Date: Tue, 26 Mar 2019 07:54:55 GMT
Content-Type: application/json
Content-Length: 326
Connection: keep-alive
Location: https://personium.takky.org/usercell/__ctl/Relation(Name='userExtRelation',_Box.Name='userbox')
DataServiceVersion: 2.0
ETag: W/"1-1553586895898"
X-Personium-Version: 1.7.4
Server: Personium

{
  "d":{
    "results":{
      "__metadata":{
        "uri":"https:\/\/personium.takky.org\/usercell\/__ctl\/Relation(Name='userExtRelation',_Box.Name='userbox')",
        "etag":"W\/\"1-1553586895898\"",
        "type":"CellCtl.Relation"
      },
      "Name":"userExtRelation",
      "_Box.Name":"userbox",
      "__published":"\/Date(1553586895898)\/",
      "__updated":"\/Date(1553586895898)\/"
    }
  }
}
```

Relation（userExtRelation）へのロールのアサイン

```
$ curl "https://personium.takky.org/usercell/__ctl/Relation(Name='userExtRelation',_Box.Name='userbox')/\$links/_Role" \
-X POST -i  \
-d "{\"uri\":\"https://personium.takky.org/usercell/__ctl/Role(Name='userrole',_Box.Name='userbox')\"}"
-H "Accept:application/json" -H "Authorization:Bearer {{unitAdminToken}}"

HTTP/1.1 204 
Date: Tue, 26 Mar 2019 08:04:59 GMT
Connection: keep-alive
DataServiceVersion: 2.0
X-Personium-Version: 1.7.4
Server: Personium
```

確認。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/352554/eeb1be21-5335-b4cb-97dd-7dcb26b8bdbe.png)


#####API での ExtCell の登録と、Relation のアサイン

ExtCell（friendcell） の登録

```
curl "https://personium.takky.org/usercell/__ctl/ExtCell" \
-X POST -i \
-d '{"Url":"https://personium.takky.org/friendcell/"}' \
-H "Accept:application/json" -H "Authorization:Bearer {{unitAdminToken}}"

HTTP/1.1 201 
Date: Tue, 26 Mar 2019 08:11:18 GMT
Content-Type: application/json
Content-Length: 338
Connection: keep-alive
Location: https://personium.takky.org/usercell/__ctl/ExtCell('https%3A%2F%2Fpersonium.takky.org%2Ffriendcell%2F')
DataServiceVersion: 2.0
ETag: W/"1-1553587878806"
X-Personium-Version: 1.7.4
Server: Personium

{
  "d":{
    "results":{
      "__metadata":{
        "uri":"https:\/\/personium.takky.org\/usercell\/__ctl\/ExtCell('https%3A%2F%2Fpersonium.takky.org%2Ffriendcell%2F')",
        "etag":"W\/\"1-1553587878806\"",
        "type":"CellCtl.ExtCell"
      },
      "Url":"https:\/\/personium.takky.org\/friendcell\/",
      "__published":"\/Date(1553587878806)\/",
      "__updated":"\/Date(1553587878806)\/"
    }
  }
}
```

ExtCell（friendcell） への Relaiton のアサイン

```
$ curl "https://personium.takky.org/usercell/__ctl/ExtCell('https%3A%2F%2Fpersonium.takky.org%2Ffriendcell%2F')/\$links/_Relation" \
-X POST -i  \
-d "{\"uri\":\"https://personium.takky.org/usercell/__ctl/Relation(Name='userExtRelation',_Box.Name='userbox')\"}" \
-H "Accept:application/json" -H "Authorization:Bearer {{unitAdminToken}}"

HTTP/1.1 204 
Date: Tue, 26 Mar 2019 09:15:02 GMT
Connection: keep-alive
DataServiceVersion: 2.0
X-Personium-Version: 1.7.4
Server: Personium
```

確認。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/352554/ddbf4400-0154-7f25-d97b-b3b896ee46e7.png)

#####ユーザー（friend）でのセル（usercell）のデータへのアクセスの確認
APIでも登録ができましたね！
では前の確認と同様に、トランスセルトークンで WebDavContents にアクセスしてみましょう！

```
$ curl "https://personium.takky.org/friendcell/__token" \
-X POST -i \
-d "grant_type=password&username=friend&password={{passWord}}&p_target=https://personium.takky.org/usercell/" \
-H "Content-Type: application/x-www-form-urlencoded"

HTTP/1.1 200 
Date: Tue, 26 Mar 2019 09:18:00 GMT
Content-Type: application/json
Content-Length: 4391
Connection: keep-alive
Location: https://personium.takky.org/usercell/__token
X-Personium-Version: 1.7.4
Server: Personium

{
  "access_token":"{{friend_token}}",
  "p_target":"https:\/\/personium.takky.org\/usercell\/",
  "token_type":"Bearer",
  "expires_in":3600
}



$ curl "https://personium.takky.org/usercell/userbox/WebDavContents" \
-X PROPFIND -i \
-d '<?xml version="1.0" encoding="utf-8"?><D:propfind xmlns:D="DAV:"><D:allprop/></D:propfind>' \
-H 'Depth:0' \
-H "Accept:application/json" -H "Authorization:Bearer {{friend_token}}"

HTTP/1.1 207 
Date: Tue, 26 Mar 2019 09:18:33 GMT
Content-Type: application/xml
Content-Length: 528
Connection: keep-alive
ETag: "7-1552907213235"
X-Personium-Version: 1.7.4
Server: Personium

<multistatus xmlns="DAV:">
    <response>
        <href>https://personium.takky.org/usercell/userbox/WebDavContents</href>
        <propstat>
            <prop>
                <creationdate>2019-03-18T11:06:53.235+0000</creationdate>
                <getlastmodified>Mon, 18 Mar 2019 11:06:53 GMT</getlastmodified>
                <resourcetype>
                    <collection/>
                </resourcetype>
            </prop>
            <status>HTTP/1.1 200 OK</status>
        </propstat>
    </response>
</multistatus>
```

ちゃんとアクセスができました！！
OKです。

####ユーザー（friend2）でのセル（usercell）のデータへのアクセスの確認

#####ここで理解したい内容は、ExtCell で設定された Cell の全てのアカウントに反映されるということです。
そうですよね… これまでの設定では、セル（friendcell）単位でしか指定されていないので、アカウント単位ででの制御はできるはずがないですよね…

さっそく、確認してみましょう…
まずは、ユーザー（friend2）の作成。

**そして、このユーザー（friend2）は「ロールには属していない」といことにも注目です**

```
curl "https://personium.takky.org/friendcell/__ctl/Account" \
-X POST -i \
-d "{\"Name\":\"friend2\"}" \
-H "X-Personium-Credential:{{passWord}}" \
-H "Accept:application/json" -H "Authorization:Bearer {{unitAdminToken}}"

HTTP/1.1 201 
Date: Tue, 26 Mar 2019 10:08:43 GMT
Content-Type: application/json
Content-Length: 315
Connection: keep-alive
Location: https://personium.takky.org/friendcell/__ctl/Account('friend2')
DataServiceVersion: 2.0
ETag: W/"1-1553594923327"
X-Personium-Version: 1.7.4
Server: Personium

{
  "d":{
    "results":{
      "__metadata":{
        "uri":"https:\/\/personium.takky.org\/friendcell\/__ctl\/Account('friend2')",
        "etag":"W\/\"1-1553594923327\"",
        "type":"CellCtl.Account"
      },
      "Name":"friend2",
      "LastAuthenticated":null,
      "Type":"basic",
      "Cell":null,
      "__published":"\/Date(1553594923327)\/",
      "__updated":"\/Date(1553594923327)\/"
    }
  }
}
```

それでは、どのロールにも属していないユーザー（friend2）のトランスセルトークンで WebDavContents にアクセスしてみましょう！

```
$ curl "https://personium.takky.org/friendcell/__token" \
-X POST -i \
-d "grant_type=password&username=friend2&password={{passWord}}&p_target=https://personium.takky.org/usercell/" \
-H "Content-Type: application/x-www-form-urlencoded"

HTTP/1.1 200 
Date: Tue, 26 Mar 2019 10:16:17 GMT
Content-Type: application/json
Content-Length: 4159
Connection: keep-alive
Location: https://personium.takky.org/usercell/__token
X-Personium-Version: 1.7.4
Server: Personium

{
  "access_token":"{{friend_token}}",
  "p_target":"https:\/\/personium.takky.org\/usercell\/",
  "token_type":"Bearer",
  "expires_in":3600
}




$ curl "https://personium.takky.org/usercell/userbox/WebDavContents" \
-X PROPFIND -i \
-d '<?xml version="1.0" encoding="utf-8"?><D:propfind xmlns:D="DAV:"><D:allprop/></D:propfind>' \
-H 'Depth:0' \
-H "Accept:application/json" -H "Authorization:Bearer {{friend_token}}"

HTTP/1.1 207 
Date: Tue, 26 Mar 2019 10:18:50 GMT
Content-Type: application/xml
Content-Length: 528
Connection: keep-alive
ETag: "7-1552907213235"
X-Personium-Version: 1.7.4
Server: Personium

<multistatus xmlns="DAV:">
    <response>
        <href>https://personium.takky.org/usercell/userbox/WebDavContents</href>
        <propstat>
            <prop>
                <creationdate>2019-03-18T11:06:53.235+0000</creationdate>
                <getlastmodified>Mon, 18 Mar 2019 11:06:53 GMT</getlastmodified>
                <resourcetype>
                    <collection/>
                </resourcetype>
            </prop>
            <status>HTTP/1.1 200 OK</status>
        </propstat>
    </response>
</multistatus>
```

アクセスできましたね！！

ExtCell で設定すると、ユーザー（friend）に加え、なんのロールにも属していないユーザー（friend2）のトランスセルトークンでも WebDavContents にアクセスができることを確認できました。
他のセルからのアクセス許可の範囲を、セル内の全てのアカウントを対象とする場合は、ExtCellで良いと云うことがわかりました。



###６．friend の トランスセルアクセストークンで userboxのWebDavContents にアクセス（ExtRole）

前の項で確認までしましたが、ExtCell では他のセルからのユーザー単位でのアクセス制限をコントロールができない。と云うことがわかりました。
なのでたぶん… ExtRole ならユーザー単位でのアクセス制限をコントロールできるような気がします。
いや… 絶対にできます。そうでなきゃ PDS が廃ります。

でもいろいろほぼ1日、ドキュメントを漁ったり Google 先生に問い合わせてみたり… 実際にAPIで叩いたり…　したのですが、正しい設定を見つけられませんでした。
意を決し、コミニュティに問い合わせて ＠sawami や ＠dixonsiu さんにアドバイスをもらったところ、以下のような設定をすべきである。と回答をもらいました。

これまで私は、ExtCell と ExtRole は機能別に使い分けるものなのかと思っていました… が違いました。
**ExtCell と ExtRole は組み合わせて利用するものだったのです！！**
そんなこと、どこにも書いてませんでしたよ〜！！

【 ExtCell 】

| 設定 | 目的 | 値 | 備考 |
|:--|:--|:--|:--|
| External Cell Location | 参照を許可するセルが存在するユニット | This Unit | This Unit／Other |
| Select Cell | 参照を許可するセル | friendcell |  |
| Relation | リレーション | friendExtRelation | Assign |

【 Relation 】

| 設定 | 目的 | 値 | 備考 |
|:--|:--|:--|:--|
| Name | リレーション名 | friendExtRelation |  |
| Box where this relation is used | 参照先のボックス | userbox |  |
| Role | ロール（権限） | ー | **ロールにはアサインしません** |

※Relation のロールには、何もアサインしません。ここがポイントです！

【 ExtRole 】

| 設定 | 目的 | 値 | 備考 |
|:--|:--|:--|:--|
| External Role URL | 参照を許可するロール | https://personium.takky.org/friendcell/__role/__/friendrole | 許可対象のユーザーが属しているロールを指定 |
| Relation | リレーション名 | friendExtRelation |  |
| Role | ロール（権限） | userrole（userbox） |  |


ユニットマネージャで上記の各設定を登録すると、以下のようになります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/352554/c9b40f44-6e0b-91fe-19ba-e9ec5392b4b2.png)





#####API での Relation の登録（ロールのアサインは不要です）

Relation（userExtRelation）の登録

```
$ curl "https://personium.takky.org/usercell/__ctl/Relation" \
-X POST -i \
-d '{ "Name":"friendExtRelation", "_Box.Name": "userbox"}' \
-H "Accept:application/json" -H "Authorization:Bearer {{unitAdminToken}}"

HTTP/1.1 201 
Date: Wed, 27 Mar 2019 03:22:20 GMT
Content-Type: application/json
Content-Length: 330
Connection: keep-alive
Location: https://personium.takky.org/usercell/__ctl/Relation(Name='friendExtRelation',_Box.Name='userbox')
DataServiceVersion: 2.0
ETag: W/"1-1553656940933"
X-Personium-Version: 1.7.4
Server: Personium

{
  "d":{
    "results":{
      "__metadata":{
        "uri":"https:\/\/personium.takky.org\/usercell\/__ctl\/Relation(Name='friendExtRelation',_Box.Name='userbox')",
        "etag":"W\/\"1-1553656940933\"",
        "type":"CellCtl.Relation"
      },
      "Name":"friendExtRelation",
      "_Box.Name":"userbox",
      "__published":"\/Date(1553656940933)\/",
      "__updated":"\/Date(1553656940933)\/"
    }
  }
}
```

確認。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/352554/8c7aff4d-ec08-5119-f865-92adb493fa97.png)
ロールはアサインされていません！

#####API での ExtCell の登録と、Relation のアサイン

ExtCell（friendcell） の登録

```
$ curl "https://personium.takky.org/usercell/__ctl/ExtCell" \
-X POST -i \
-d '{"Url":"https://personium.takky.org/friendcell/"}' \
-H "Accept:application/json" -H "Authorization:Bearer {{unitAdminToken}}"

HTTP/1.1 201 
Date: Wed, 27 Mar 2019 03:26:09 GMT
Content-Type: application/json
Content-Length: 338
Connection: keep-alive
Location: https://personium.takky.org/usercell/__ctl/ExtCell('https%3A%2F%2Fpersonium.takky.org%2Ffriendcell%2F')
DataServiceVersion: 2.0
ETag: W/"1-1553657169038"
X-Personium-Version: 1.7.4
Server: Personium

{
  "d":{
    "results":{
      "__metadata":{
        "uri":"https:\/\/personium.takky.org\/usercell\/__ctl\/ExtCell('https%3A%2F%2Fpersonium.takky.org%2Ffriendcell%2F')",
        "etag":"W\/\"1-1553657169038\"",
        "type":"CellCtl.ExtCell"
      },
      "Url":"https:\/\/personium.takky.org\/friendcell\/",
      "__published":"\/Date(1553657169038)\/",
      "__updated":"\/Date(1553657169038)\/"
    }
  }
}
```

ExtCell（friendcell） への Relaiton のアサイン

```
$ curl "https://personium.takky.org/usercell/__ctl/ExtCell('https%3A%2F%2Fpersonium.takky.org%2Ffriendcell%2F')/\$links/_Relation" \
-X POST -i  \
-d "{\"uri\":\"https://personium.takky.org/usercell/__ctl/Relation(Name='userExtRelation',_Box.Name='userbox')\"}" \
-H "Accept:application/json" -H "Authorization:Bearer {{unitAdminToken}}"

HTTP/1.1 204 
Date: Wed, 27 Mar 2019 03:33:01 GMT
Connection: keep-alive
DataServiceVersion: 2.0
X-Personium-Version: 1.7.4
Server: Personium
```

※APIの場合、許可対象のセルを指定するURLはURLエンコードします


確認。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/352554/76f6e41e-c565-ea1e-5f37-03e0099cde89.png)


#####API での ExtRole の登録と、ロールのアサイン

ExtRole（friendrole） の登録

※ ここでは一つ注意があります。
　ExtRoleを登録する際、許可対象のロールを指定しますが、以下の画像のようにロールはBoxにひも付いてる場合のそのロールの指定方法は、通常であれば「https://{{FWDN}}/{{CELL}}/__role/{{BOX}}/{{ロール}}」のように、ひも付いたBoxを含めて指定します。
　しかしの ExtRole の指定時の{{BOX}}は＂\_\_＂を指定するようです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/352554/b3dd1894-b779-ea7b-9b31-ea7b3b8864ad.png)

```
$ curl "https://personium.takky.org/usercell/__ctl/ExtRole" \
-X POST -i \
-d '{ "ExtRole": "https://personium.takky.org/friendcell/__role/__/friendrole", "_Relation.Name": "friendExtRelation", "_Relation._Box.Name": "userbox"}' \
-H "Accept:application/json" -H "Authorization:Bearer {{unitAdminToken}}"

HTTP/1.1 201 
Date: Wed, 27 Mar 2019 04:06:00 GMT
Content-Type: application/json
Content-Length: 530
Connection: keep-alive
Location: https://personium.takky.org/usercell/__ctl/ExtRole(ExtRole='https%3A%2F%2Fpersonium.takky.org%2Ffriendcell%2F__role%2F__%2Ffriendrole',_Relation.Name='friendExtRelation',_Relation._Box.Name='userbox')
DataServiceVersion: 2.0
ETag: W/"1-1553659560291"
X-Personium-Version: 1.7.4
Server: Personium

{
  "d":{
    "results":{
      "__metadata":{
        "uri":"https:\/\/personium.takky.org\/usercell\/__ctl\/ExtRole(ExtRole='https%3A%2F%2Fpersonium.takky.org%2Ffriendcell%2F__role%2F__%2Ffriendrole',_Relation.Name='friendExtRela tion',_Relation._Box.Name='userbox')",
        "etag":"W\/\"1-1553658532391\"",
        "type":"CellCtl.ExtRole"
      },
      "ExtRole":"https:\/\/personium.takky.org\/friendcell\/__role\/__\/friendrole",
      "_Relation.Name":"friendExtRelation",
      "_Relation._Box.Name":"userbox",
      "__published":"\/Date(1553658532391)\/",
      "__updated":"\/Date(1553658532391)\/"
    }
  }
}
```
前述の注意で解説した通り、ロールの指定は＂/\_\_role/\_\_/friendrole＂でOKでした！


ExtRole（friendrole） への ロールのアサイン

```
$ curl "https://personium.takky.org/usercell/__ctl/Role(Name='userrole',_Box.Name='userbox')/\$links/_ExtRole" \
-X POST -i  \
-d "{\"uri\":\"https://personium.takky.org/usercell/__ctl/ExtRole(ExtRole='https://personium.takky.org/friendcell/__role/__/friendrole',_Relation.Name='friendExtRelation',_Relation._Box.Name='userbox')\"}" \

HTTP/1.1 204 
Date: Wed, 27 Mar 2019 04:07:04 GMT
Connection: keep-alive
DataServiceVersion: 2.0
X-Personium-Version: 1.7.4
Server: Personium

```

確認。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/352554/28dafb9e-c689-d2f8-a39c-ec98e5ce423f.png)

いいんじゃ無いでしょうか！！


#####ユーザー（friend）でのセル（usercell）のデータへのアクセスの確認

ではでは…
ExtCellの確認と同様に、トランスセルトークンで WebDavContents にアクセスしてみましょう！

```
$ curl "https://personium.takky.org/friendcell/__token" \
-X POST -i \
-d "grant_type=password&username=friend&password={{passWord}}&p_target=https://personium.takky.org/usercell/" \
-H "Content-Type: application/x-www-form-urlencoded"

HTTP/1.1 200 
Date: Wed, 27 Mar 2019 04:11:37 GMT
Content-Type: application/json
Content-Length: 4391
Connection: keep-alive
Location: https://personium.takky.org/usercell/__token
X-Personium-Version: 1.7.4
Server: Personium

{
  "access_token":"{{friend_token}}",
  "p_target":"https:\/\/personium.takky.org\/usercell\/",
  "token_type":"Bearer",
  "expires_in":3600
}



$ curl "https://personium.takky.org/usercell/userbox/WebDavContents" \
-X PROPFIND -i \
-d '<?xml version="1.0" encoding="utf-8"?><D:propfind xmlns:D="DAV:"><D:allprop/></D:propfind>' \
-H 'Depth:0' \
-H "Accept:application/json" -H "Authorization:Bearer {{friend_token}}"

HTTP/1.1 207 
Date: Wed, 27 Mar 2019 04:13:05 GMT
Content-Type: application/xml
Content-Length: 528
Connection: keep-alive
ETag: "7-1552907213235"
X-Personium-Version: 1.7.4
Server: Personium

<multistatus xmlns="DAV:">
    <response>
        <href>https://personium.takky.org/usercell/userbox/WebDavContents</href>
        <propstat>
            <prop>
                <creationdate>2019-03-18T11:06:53.235+0000</creationdate>
                <getlastmodified>Mon, 18 Mar 2019 11:06:53 GMT</getlastmodified>
                <resourcetype>
                    <collection/>
                </resourcetype>
            </prop>
            <status>HTTP/1.1 200 OK</status>
        </propstat>
    </response>
</multistatus>
```

設定した許可対象のロール（friendrole）に属しているユーザー（friend）はちゃんとアクセスができました！！
OKです。


####ユーザー（friend2）でのセル（usercell）のデータへのアクセスの確認

#####ここで理解したい内容は、ExtRole で設定された Roleに属したアカウントのみに、アクセス権が反映されるということです。

セル（friendcell）のロール（friendrole）には属していないユーザー（friend2）は、アクセスができなければ、ExtRoleが正しく機能し、正しく設定されていることが確認できます。

それでは、どのロールにも属していないユーザー（friend2）のトランスセルトークンで WebDavContents にアクセスしてみましょう！

```
$ curl "https://personium.takky.org/friendcell/__token" \
-X POST -i \
-d "grant_type=password&username=friend2&password={{passWord}}&p_target=https://personium.takky.org/usercell/" \
-H "Content-Type: application/x-www-form-urlencoded"

HTTP/1.1 200 
Date: Wed, 27 Mar 2019 04:14:29 GMT
Content-Type: application/json
Content-Length: 4159
Connection: keep-alive
Location: https://personium.takky.org/usercell/__token
X-Personium-Version: 1.7.4
Server: Personium

{
  "access_token":"{{friend_token}}",
  "p_target":"https:\/\/personium.takky.org\/usercell\/",
  "token_type":"Bearer",
  "expires_in":3600
}


$ curl "https://personium.takky.org/usercell/userbox/WebDavContents" \
-X PROPFIND -i \
-d '<?xml version="1.0" encoding="utf-8"?><D:propfind xmlns:D="DAV:"><D:allprop/></D:propfind>' \
-H 'Depth:0' \
-H "Accept:application/json" -H "Authorization:Bearer {{friend_token}}"

HTTP/1.1 403 
Date: Wed, 27 Mar 2019 04:15:30 GMT
Content-Type: application/json
Content-Length: 90
Connection: keep-alive
X-Personium-Version: 1.7.4
Server: Personium

{
  "code":"PR403-AU-0002",
  "message":{
    "lang":"en","value":"Necessary privilege is lacking."
  }
}
```

**おぉ…！！ 想定通り「権限がない」エラーでアクセスできません**

これで、ロールをうまく利用することにより、他のセルからのアクセスをアカウント単位で制御することが可能になりましたので、アプリケーションを構築する上で機能の幅を広げることができますね！！

###OKです〜！！


###７．いろいろ把握できたところで、一旦整理

なぜ、ExtCell や ExtRole を利用したかったのか… それは他のセル（ユーザー）にも自身のデータを参照させても良い場合に、適切にかつ安全にそして自身が主導権を持って管理したかったのですよね。
Personium は PDS を謳っているのですが、これまでは自身の身が参照できるデータをストックする機能については把握できていたのですが、他のユーザーに参照させる機能の利用の仕方について、とまった説明がなく、他のコミニュティのみなさんも戸惑っている姿をなんどもお見かけしましたし、コミニュティからの説明も、いまいち的を得ていない状況が散見しました。

さて、ここまで試行錯誤を含めながら、私は把握できました。
なので、できるだけみなさんにも分かりやすいよう整理してみます。

#####【目的】
自身のセル内にストックしているデータを、自身のセル内のコントロールできるロールの設定に従って、他のセル（ユーザー）への参照**（これまでず〜と＂参照＂を記載していましたが write もアリなので＂利用＂にしましょう）**する権限を提供できる仕組み。
この場合、他のセル（ユーザー）であれば、どのアカウントであっても、全て同等の権限を提供しても良い場合と、特定のアカウントにのみ権限を限定できる機能もあると便利である。

#####【解決できる機能（ExtCell・ExtRole ならびに Relation）】
「ソーシャルグラフを構築するための機能」として提供されている ExtCell・ExtRole ならびに Relation の設定を組み合わせて利用すると、【目的】である「他のセル（ユーザー）への利用する権限を提供できる仕組み」を実現できる。
そして、「他セルの全アカウント」ならびに「他セルの特定のアカウント」と権限をアカウントにより限定できる機能も実現される。


#####【目的のパターンと実現方法】

| 項目 | 他セルの<br>全アカウント | 他セルの<br>特定のアカウント | 備考 |
|:--|:--|:--|:--|
| 利用を許可する<br>単位 | 自セルのロール | 自セルのロール |  |
| 利用を許可できる<br>コレクション | 全て | 全て | なので注意が<br>必要です |
| 利用する<br>ソーシャル機能 | **ExtCell＋Relation** | **ExtCell＋Relation＋ExtRole** |  |
| 権限管理の単位 | 他セル | 他セル内のロール | 実際に管理<br>される対象は<br>アカウント |
| 権限の許可認証<br>の単位 | トランスセルトークン | トランスセルトークン  | p_target="参照セル" |

しかしここで実現できるのは「特定少数のアカウント」です… そしてそのうえ許可するアカウントの属しているロール名までが明らかにできたアカウントのみです。
あるアプリのみにクローズしたユーザーを対象にしたり、複数のアプリがそれぞれの内部構造を共有できることが前提のコミニュティ（エコシステム）なのであれば、これらの機能は効果を得られるでしょう。

ただし… 「不特定のアカウント」に対しては提供できないと思われます。
かつ「特定多数のアカウント」の場合は、それぞれのセルへのアクセスが必要となり、パフォーマンスやレスポンスの関する問題に直面する可能性も考えられることに注意が必要です。


#####【「他セルの全アカウントに許可」する場合の設定内容】

| ソーシャル機能 | 設定項目 | 設定内容の概要 | 設定例 | 備考 |
|:--|:--|:--|:--|:--|
| Relation | Name | Relation内でユニークな識別子 | userExtRelation |  |
| Relation | Box where this relation is used | 利用対象とする自セル内のボックス | userbox |  |
| Relation | Assign Role | ロールアサインの有無 | ON | チェックボックス |
| Relation | Role | 許可するボックスが指定されている自セル内のロール | userrole(userbox) | ONの時選択可 |
| ExtCell | External Cell Location | 許可する他セルの属するユニット | This Unit | ラジオボタン |
| ExtCell | Select Cell | 許可する他セル | friendcell | 自ユニットの場合選択 |
| ExtCell | Assign Relation | Relationアサインの有無 | ON | チェックボックス |
| ExtCell | Relation | 許可するボックスが指定されているRelation | userExtRelation | ONの時選択可 |

ユニットマネージャでの設定例）
![image.png](https://qiita-image-store.s3.amazonaws.com/0/352554/24a9a027-d0c9-0a6c-e591-309bfa5f2f09.png)


#####【「他セルの特定のアカウントに許可」する場合の設定内容】

| ソーシャル機能 | 設定項目 | 設定内容の概要 | 設定例 | 備考 |
|:--|:--|:--|:--|:--|
| Relation | Name | Relation内でユニークな識別子 | friendExtRelation |  |
| Relation | Box where this relation is used | 利用対象とする自セル内のボックス | userbox |  |
| Relation | Assign Role | ロールアサインの有無 | OFF | チェックボックス |
| Relation | Role | アサインするロール | ー |  |
| ExtCell | External Cell Location | 許可するセルの属するユニット | This Unit | ラジオボタン |
| ExtCell | Select Cell | 許可するセル | friendcell | 自ユニットの場合選択 |
| ExtCell | Assign Relation | Relationアサインの有無 | ON | チェックボックス |
| ExtCell | Relation | 許可するボックスが指定されているRelation | friendExtRelation | ONの時選択可 |
| ExtRole | External Role URL | 許可対象のアカウントが属する他セル内のロール | https://personium.takky.org/friendcell/__role/__/friendrole | URL指定 |
| ExtRole | Relation | ひも付けるリレーション | friendExtRelation | 自ユニットの場合選択 |
| ExtRole | Assign Role | Roleアサインの有無 | ON | チェックボックス |
| ExtRole | Role | 許可するボックスが指定されている自セル内のロール | userrole(userbox) | ONの時選択可 |


ユニットマネージャでの設定例）
![image.png](https://qiita-image-store.s3.amazonaws.com/0/352554/fc39dc45-869e-8066-9f5c-df6f4def670b.png)


##### ＠sawami さんよりアドバイスいただいた時の、ExtRoleの利用イメージ

私もこのイメージで初めて、どう ExtCell・ExtRole・Relation を利用すれば良いか、頭の中で整理できました。たぶんこのイメージだけを出されても、それはそれでチンプンカンプンなのでしょうが… またわからなくなったら見直せるよう、ここに記録しておきます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/352554/bc7bcc7b-d69c-49d3-cedb-2f98861e9a00.png)


はい！！
やはりこの**ソーシャル（Social）連携関連API**は理解しづらく、説明してもこんなに長くなってしまい＂簡単に利用する＂ための説明には程遠い感じですが… これが私の限界です。

まぁ「APIを利用する」ことにこだわらずユニットマネージャだけで実現する方法なら、マニュアルもシンプルになり、もう少しスッキリ操作できるし簡単に利用できようになるのかもしれません。だれか… その方向性のマニュルの作成に取り組んでもらえると嬉しいですね！！ ＞ ＠sugimoto さんとか…


---

###最後に

ようやくこの ExtRole の利用についてのエントリを公開することができました。長かったぁ…
というかここが私自身理解できていなかったので、このエントリにとりかかることから避けていた。ということの方が正しい表現です。
でもようやく理解ができてよかっタァ。

これまでに Personium に興味を持った方々もの中にも、たぶんここで挫折してしまった人は少なくはないのではないかと想像しています。
しかも… この**ソーシャル（Social）連携**を理解し実装できたとしても、多くの事業者がビジネスモデルとして描いた場合に、どうしても避けては通れない「不特定のアカウント」「特定多数のアカウント」についての扱いがほぼ無視された機能となっており、ここで＂利用しない＂という結論付けてしまった事業者もあったのではないかと思っております。

そういう私も、現在のこの**ソーシャル（Social）連携**からの拡張が「今後・未来永劫ない」のであればちょっと選択しづらいなぁ… と感じております。

しかしながら…
以前のエントリで登場した＂ある異邦人＂さんからは、この辺の「拡張を模索している」との（たぶん公ではない）リーク情報もあったことは… 私は忘れてはいません。
それが「どのようにセキュリティを担保」しつつ、「エコシステムとしての理念を確保」しながら、「より便利で喜ばれる**ソーシャル（Social）連携**」へと進化するのか、期待をしつつじっくりと見届けて行きたいと思っております。

コミニュティの皆さん…　引き続き期待しておりますので、よろしくお願いします！！


---


####メニュー
- [x] [１＜はじめに＞](https://qiita.com/takky0330/items/5352a820e5e59747218c)
- [x] [２＜Personiumに触れてみるには＞](https://qiita.com/takky0330/items/6e7e5686c8ab2a25f7e8)
- [x] [３＜Ansibleでインストールする＞](https://qiita.com/takky0330/items/19449b05e8b2775382d5)
- [x] [４＜ざっくりとPersoniumとは＞](https://qiita.com/takky0330/items/7781d0cb4ac879b65ab5)
- [x] [５＜APIでアクセスしてみる＞](https://qiita.com/takky0330/items/270a5c5386fd80d5d3c1)
- [x] [６＜VirtualBoxイメージでサクッと触る＞](https://qiita.com/takky0330/items/788ff75f675c9207ad6e)
- [x] [７＜APIでWebDavを触ってみる＞](https://qiita.com/takky0330/items/42febbf90de2986bb452)
- [x] [８＜APIでODataを触ってみる＞](https://qiita.com/takky0330/items/c1809ad5f3f7f85430ad)
- [x] [９＜APIでExtRoleを触ってみる＞](https://qiita.com/takky0330/items/74285b516e06fc00edad)
- [ ] １０＜セルとボックスについて理解する＞
- [ ] １１＜ホームアプリを触ってみる＞
- [ ] １２＜ユニットマネージャって便利じゃん＞
- [ ] １３＜テンプレートアプリってなんぞや＞
- [ ] １４＜自分のアプリケーション＞


- [x] [＜成功した手順＞ 新しいバージョン（1.7.9）の Personium を Ansibleでインストールする](https://qiita.com/takky0330/items/9598498f8dbb9681fc9b)
- [x] [＜失敗した手順＞ 新しいバージョン（1.7.9）の Personium を Ansibleでインストールする](https://qiita.com/takky0330/items/1706be1e23122ec2ac86)