【Elasticsearch】作成したロール・ユーザーの検証

## 環境
以下を参考に環境構築を行う。
[【Elasticsearch】DockerでElasticsearchを使えるようにする](https://qiita.com/dai_chi/items/90497e17b387626be466)

## 事前準備
### ロール・ユーザーの作成
下記にロール・ユーザーの追加の仕方を纏めてます。
[ロールを追加してみる](https://qiita.com/dai_chi/items/c9c1201f3df7fd026ee3)
[ユーザーを追加してみる](https://qiita.com/dai_chi/items/d79974a4bfe547bc8589)

作成したいロール・ユーザーは以下の通り
対象indexを制限:index1のみを操作できるようにする
- delete:delete_only_user

<details><summary>DSL文</summary>

``` json
PUT /_security/role/delete_role
{
  "indices" : [
    {
      "names" : [ "index1" ],
      "privileges" : [ "delete" ]
    }
  ]
}

PUT /_security/user/delete_only_user
{
  "password" : "password",
  "roles" : [ "delete_role" ],
  "full_name" : "Delete Only User"
}
```
</details>

- read:read_only_user

<details><summary>DSL文</summary>

``` json
PUT /_security/role/read_role
{
  "indices" : [
    {
      "names" : [ "index1" ],
      "privileges" : [ "read" ]
    }
  ]
}

PUT /_security/user/read_only_user
{
  "password" : "password",
  "roles" : [ "read_role" ],
  "full_name" : "Read Only User"
}
```
</details>

- write:write_only_user

<details><summary>DSL文</summary>

``` json
PUT /_security/role/write_role
{
  "indices" : [
    {
      "names" : [ "index1" ],
      "privileges" : [ "write" ]
    }
  ]
}

PUT /_security/user/write_only_user
{
  "password" : "password",
  "roles" : [ "write_role" ],
  "full_name" : "Write Only User"
}
```

</details>

- all:enabled_test_user(false)
<details><summary>DSL文</summary>

``` json
PUT /_security/role/all_role
{
  "indices" : [
    {
      "names" : [ "index1" ],
      "privileges" : [ "all" ]
    }
  ]
}

PUT /_security/user/enabled_test_user
{
  "password" : "password",
  "roles" : [ "all_role" ],
  "full_name" : "Enabled Test User",
  "enabled" : false
}
```
</details>

- all:all_user

<details><summary>DSL文</summary>

``` json
PUT /_security/user/all_user
{
  "password" : "password",
  "roles" : [ "all_role" ],
  "full_name" : "All User"
}
```
</details>

### 作成ができたかを確認する方法
``` json
GET /_security/role/<ロール名>
GET /_security/user/<ユーザー名>
```

### indexの作成
下記の2つのindexを作成して、テスト用のドキュメントを作成します。
- indexの作成
``` json
PUT /index1

PUT /index2
```

- ドキュメントを作成
``` json
POST /index1/_doc/1
{
  "name": "doc1",
  "description": "This is a test document for index1."
}

POST /index2/_doc/1
{
  "name": "doc2",
  "description": "This is a test document for index2."
}
```

- 追加したドキュメントの参照方法
``` json
GET /index1/_doc/1
GET /index2/_doc/1
```

## やりたいこと
- delete権限のみ
  - index1で検索・作成・更新・削除できるか
  - index2で削除できるか
- read権限のみ
  - index1で検索・作成・更新・削除できるか
  - index2で検索できるか
- write権限のみ
  - index1で検索・作成・更新・削除ができるか
  - index2で検索・作成・更新・削除ができるか
- 無効のユーザーでログインできるか
- all権限
  - index1で検索・作成・更新・削除ができるか
  - index2で検索・作成・更新・削除ができるか

## 検証
### delete権限のみ
<details><summary>index1で検索・作成・更新・削除できるか</summary>

- 検索するがエラーとなる
``` bash
curl -u 'delete_only_user:password' GET 'localhost:9200/index1/_search?pretty'
curl: (6) Could not resolve host: GET
{
  "error" : {
    "root_cause" : [
      {
        "type" : "security_exception",
        "reason" : "action [indices:data/read/search] is unauthorized for user [delete_only_user] with effective roles [delete_role] on indices [index1], this action is granted by the index privileges [read,all]"
      }
    ],
    "type" : "security_exception",
    "reason" : "action [indices:data/read/search] is unauthorized for user [delete_only_user] with effective roles [delete_role] on indices [index1], this action is granted by the index privileges [read,all]"
  },
  "status" : 403
}
```

- 作成するがエラーとなる
``` bash
curl -u 'delete_only_user:password' POST 'localhost:9200/index1/_doc/1?pretty' -H 'Content-Type: application/json' -d'
{
    "name": "new_doc",
    "description": "new document"
}'
curl: (6) Could not resolve host: POST
{
  "error" : {
    "root_cause" : [
      {
        "type" : "security_exception",
        "reason" : "action [indices:data/write/index] is unauthorized for user [delete_only_user] with effective roles [delete_role] on indices [index1], this action is granted by the index privileges [create_doc,create,index,write,all]"
      }
    ],
    "type" : "security_exception",
    "reason" : "action [indices:data/write/index] is unauthorized for user [delete_only_user] with effective roles [delete_role] on indices [index1], this action is granted by the index privileges [create_doc,create,index,write,all]"
  },
  "status" : 403
}
```

- 更新するがエラーとなる
``` bash
curl -u 'delete_only_user:password' -X POST "localhost:9200/index1/_update/1?pretty" -H 'Content-Type: application/json' -d'
{
  "doc": {
    "name": "update_doc",
    "description": "update document"
  }
}'
{
  "error" : {
    "root_cause" : [
      {
        "type" : "security_exception",
        "reason" : "action [indices:data/write/update] is unauthorized for user [delete_only_user] with effective roles [delete_role] on indices [index1], this action is granted by the index privileges [index,write,all]"
      }
    ],
    "type" : "security_exception",
    "reason" : "action [indices:data/write/update] is unauthorized for user [delete_only_user] with effective roles [delete_role] on indices [index1], this action is granted by the index privileges [index,write,all]"
  },
  "status" : 403
}
```

- 削除
``` bash
curl -u 'delete_only_user:password' -X DELETE "localhost:9200/index1/_doc/1?pretty"
{
  "_index" : "index1",
  "_id" : "1",
  "_version" : 2,
  "result" : "deleted",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 11,
  "_primary_term" : 1
}
```

</details>

<details><summary>index2で削除できるか</summary>

- 削除
``` bash
curl -u 'delete_only_user:password' -X DELETE "localhost:9200/index2/_doc/1?pretty"
{
  "error" : {
    "root_cause" : [
      {
        "type" : "security_exception",
        "reason" : "action [indices:data/write/bulk[s]] is unauthorized for user [delete_only_user] with effective roles [delete_role] on indices [index2], this action is granted by the index privileges [create_doc,create,delete,index,write,all]"
      }
    ],
    "type" : "security_exception",
    "reason" : "action [indices:data/write/bulk[s]] is unauthorized for user [delete_only_user] with effective roles [delete_role] on indices [index2], this action is granted by the index privileges [create_doc,create,delete,index,write,all]"
  },
  "status" : 403
}
```

</details>

### read権限のみ
<details><summary>index1で検索・作成・更新・削除ができるか</summary>

- 参照できる

``` bash
curl -u 'read_only_user:password' GET 'localhost:9200/index1/_search?pretty'
curl: (6) Could not resolve host: GET
{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "index1",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "name" : "doc1",
          "description" : "This is a test document for index1."
        }
      }
    ]
  }
}
```
- 作成するとエラーになる

``` bash
curl -u 'read_only_user:password' POST 'localhost:9200/index1/_doc/1?pretty' -H 'Content-Type: application/json' -d'
{
    "name": "new_doc",
    "description": "new document"
}'
curl: (6) Could not resolve host: POST
{
  "error" : {
    "root_cause" : [
      {
        "type" : "security_exception",
        "reason" : "action [indices:data/write/index] is unauthorized for user [read_only_user] with effective roles [read_role] on indices [index1], this action is granted by the index privileges [create_doc,create,index,write,all]"
      }
    ],
    "type" : "security_exception",
    "reason" : "action [indices:data/write/index] is unauthorized for user [read_only_user] with effective roles [read_role] on indices [index1], this action is granted by the index privileges [create_doc,create,index,write,all]"
  },
  "status" : 403
}
```
- 更新するとエラーになる

``` bash
curl -u 'read_only_user:password' -X POST "localhost:9200/index1/_update/1?pretty" -H 'Content-Type: application/json' -d'
{
  "doc": {
    "name": "update_doc",
    "description": "update document"
  }
}'
{
  "error" : {
    "root_cause" : [
      {
        "type" : "security_exception",
        "reason" : "action [indices:data/write/update] is unauthorized for user [read_only_user] with effective roles [read_role] on indices [index1], this action is granted by the index privileges [index,write,all]"
      }
    ],
    "type" : "security_exception",
    "reason" : "action [indices:data/write/update] is unauthorized for user [read_only_user] with effective roles [read_role] on indices [index1], this action is granted by the index privileges [index,write,all]"
  },
  "status" : 403
}
```
- 削除するとエラーになる

``` bash
curl -u 'read_only_user:password' -X DELETE "localhost:9200/index1/_doc/1?pretty"
{
  "error" : {
    "root_cause" : [
      {
        "type" : "security_exception",
        "reason" : "action [indices:data/write/delete] is unauthorized for user [read_only_user] with effective roles [read_role] on indices [index1], this action is granted by the index privileges [delete,write,all]"
      }
    ],
    "type" : "security_exception",
    "reason" : "action [indices:data/write/delete] is unauthorized for user [read_only_user] with effective roles [read_role] on indices [index1], this action is granted by the index privileges [delete,write,all]"
  },
  "status" : 403
}
```
</details>

<details><summary>index2で検索ができるか</summary>

- index2にはread権限がないのでエラーになる

``` bash
curl -u 'read_only_user:password' GET 'localhost:9200/index2/_search?pretty'
curl: (6) Could not resolve host: GET
{
  "error" : {
    "root_cause" : [
      {
        "type" : "security_exception",
        "reason" : "action [indices:data/read/search] is unauthorized for user [read_only_user] with effective roles [read_role] on indices [index2], this action is granted by the index privileges [read,all]"
      }
    ],
    "type" : "security_exception",
    "reason" : "action [indices:data/read/search] is unauthorized for user [read_only_user] with effective roles [read_role] on indices [index2], this action is granted by the index privileges [read,all]"
  },
  "status" : 403
}
```
</details>

### write権限のみ
<details><summary>index1で作成・更新・削除ができるか</summary>
- 参照するとエラーになる

``` bash
curl -u 'write_only_user:password' GET 'localhost:9200/index1/_search?pretty'
curl: (6) Could not resolve host: GET
{
  "error" : {
    "root_cause" : [
      {
        "type" : "security_exception",
        "reason" : "action [indices:data/read/search] is unauthorized for user [write_only_user] with effective roles [write_role] on indices [index1], this action is granted by the index privileges [read,all]"
      }
    ],
    "type" : "security_exception",
    "reason" : "action [indices:data/read/search] is unauthorized for user [write_only_user] with effective roles [write_role] on indices [index1], this action is granted by the index privileges [read,all]"
  },
  "status" : 403
}
```
- 作成できる

``` bash
curl -u 'write_only_user:password' POST 'localhost:9200/index1/_doc/1?pretty' -H 'Content-Type: application/json' -d'
{
    "name": "new_doc",
    "description": "new document"
}'
curl: (6) Could not resolve host: POST
{
  "_index" : "index1",
  "_id" : "1",
  "_version" : 4,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 4,
  "_primary_term" : 1
}
```
- 更新できる

``` bash
curl -u 'write_only_user:password' -X POST "localhost:9200/index1/_update/1?pretty" -H 'Content-Type: application/json' -d'
{
  "doc": {
    "name": "update_doc",
    "description": "update document"
  }
}'
{
  "_index" : "index1",
  "_id" : "1",
  "_version" : 8,
  "result" : "updated",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 8,
  "_primary_term" : 1
} 
```
- 削除できる

``` bash
curl -u 'write_only_user:password' -X DELETE "localhost:9200/index1/_doc/1?pretty"
{
  "_index" : "index1",
  "_id" : "1",
  "_version" : 9,
  "result" : "deleted",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 9,
  "_primary_term" : 1
}
```
</details>

<details><summary>index2で作成・更新・削除ができるか</summary>

- 参照するとエラーになる

``` bash
curl -u 'write_only_user:password' GET 'localhost:9200/index2/_search?pretty'
curl: (6) Could not resolve host: GET
{
  "error" : {
    "root_cause" : [
      {
        "type" : "security_exception",
        "reason" : "action [indices:data/read/search] is unauthorized for user [write_only_user] with effective roles [write_role] on indices [index2], this action is granted by the index privileges [read,all]"
      }
    ],
    "type" : "security_exception",
    "reason" : "action [indices:data/read/search] is unauthorized for user [write_only_user] with effective roles [write_role] on indices [index2], this action is granted by the index privileges [read,all]"
  },
  "status" : 403
}
```
- 作成するとエラーになる

``` bash
curl -u 'write_only_user:password' POST 'localhost:9200/index2/_doc/1?pretty' -H 'Content-Type: application/json' -d'
{
    "name": "new_doc",
    "description": "new document"
}'
curl: (6) Could not resolve host: POST
{
  "error" : {
    "root_cause" : [
      {
        "type" : "security_exception",
        "reason" : "action [indices:data/write/bulk[s]] is unauthorized for user [write_only_user] with effective roles [write_role] on indices [index2], this action is granted by the index privileges [create_doc,create,delete,index,write,all]"
      }
    ],
    "type" : "security_exception",
    "reason" : "action [indices:data/write/bulk[s]] is unauthorized for user [write_only_user] with effective roles [write_role] on indices [index2], this action is granted by the index privileges [create_doc,create,delete,index,write,all]"
  },
  "status" : 403
}
```
- 更新するとエラーになる

``` bash
curl -u 'write_only_user:password' -X POST "localhost:9200/index2/_update/1?pretty" -H 'Content-Type: application/json' -d'
{
  "doc": {
    "name": "update_doc",
    "description": "update document"
  }
}'
{
  "error" : {
    "root_cause" : [
      {
        "type" : "security_exception",
        "reason" : "action [indices:data/write/update] is unauthorized for user [write_only_user] with effective roles [write_role] on indices [index2], this action is granted by the index privileges [index,write,all]"
      }
    ],
    "type" : "security_exception",
    "reason" : "action [indices:data/write/update] is unauthorized for user [write_only_user] with effective roles [write_role] on indices [index2], this action is granted by the index privileges [index,write,all]"
  },
  "status" : 403
}
```
- 削除するとエラーになる

``` bash
curl -u 'write_only_user:password' -X DELETE "localhost:9200/index2/_doc/1?pretty"
{
  "error" : {
    "root_cause" : [
      {
        "type" : "security_exception",
        "reason" : "action [indices:data/write/bulk[s]] is unauthorized for user [write_only_user] with effective roles [write_role] on indices [index2], this action is granted by the index privileges [create_doc,create,delete,index,write,all]"
      }
    ],
    "type" : "security_exception",
    "reason" : "action [indices:data/write/bulk[s]] is unauthorized for user [write_only_user] with effective roles [write_role] on indices [index2], this action is granted by the index privileges [create_doc,create,delete,index,write,all]"
  },
  "status" : 403
}
```

</details>

### 無効のユーザーでログインできるか
<details><summary>enabled_test_userで参照するもエラーとなる</summary>

``` bash
curl -u 'enabled_test_user:password' GET 'localhost:9200/index1/_search?pretty'
curl: (6) Could not resolve host: GET
{
  "error" : {
    "root_cause" : [
      {
        "type" : "security_exception",
        "reason" : "unable to authenticate user [enabled_test_user] for REST request [/index1/_search?pretty]",
        "header" : {
          "WWW-Authenticate" : [
            "Basic realm=\"security\" charset=\"UTF-8\"",
            "ApiKey"
          ]
        }
      }
    ],
    "type" : "security_exception",
    "reason" : "unable to authenticate user [enabled_test_user] for REST request [/index1/_search?pretty]",
    "header" : {
      "WWW-Authenticate" : [
        "Basic realm=\"security\" charset=\"UTF-8\"",
        "ApiKey"
      ]
    }
  },
  "status" : 401
}
```
</details>
<details><summary>all_userで参照できるか確認</summary>

``` bash
curl -u 'all_user:password' GET 'localhost:9200/index1/_search?pretty'
curl: (6) Could not resolve host: GET
{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "index1",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "name" : "doc1",
          "description" : "This is a test document for index1."
        }
      }
    ]
  }
}
```
</details>

### all権限
<details><summary>index1で検索・作成・更新・削除できるか</summary>

- 検索
``` bash
curl -u 'all_user:password' GET 'localhost:9200/index1/_search?pretty'
curl: (6) Could not resolve host: GET
{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "index1",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "name" : "new_doc",
          "description" : "new document"
        }
      }
    ]
  }
}
```

- 作成
``` bash
curl -u 'all_user:password' POST 'localhost:9200/index1/_doc/1?pretty' -H 'Content-Type: application/json' -d'
{
    "name": "new_doc",
    "description": "new document"
}'
curl: (6) Could not resolve host: POST
{
  "_index" : "index1",
  "_id" : "1",
  "_version" : 2,
  "result" : "created",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 13,
  "_primary_term" : 1
}
```

- 更新
``` bash
curl -u 'all_user:password' -X POST "localhost:9200/index1/_update/1?pretty" -H 'Content-Type: application/json' -d'
{
  "doc": {
    "name": "update_doc",
    "description": "update document"
  }
}'
{
  "_index" : "index1",
  "_id" : "1",
  "_version" : 3,
  "result" : "updated",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 14,
  "_primary_term" : 1
}
```

- 削除
``` bash
curl -u 'all_user:password' -X DELETE "localhost:9200/index1/_doc/1?pretty"
{
  "_index" : "index1",
  "_id" : "1",
  "_version" : 4,
  "result" : "deleted",
  "_shards" : {
    "total" : 2,
    "successful" : 1,
    "failed" : 0
  },
  "_seq_no" : 15,
  "_primary_term" : 1
}
```

</details>

<details><summary>index2で削除できるか</summary>

- 検索するがエラーとなる
``` bash
curl -u 'all_user:password' GET 'localhost:9200/index2/_search?pretty'
{
  "error" : {
    "root_cause" : [
      {
        "type" : "security_exception",
        "reason" : "action [indices:data/read/search] is unauthorized for user [all_user] with effective roles [all_role] on indices [index2], this action is granted by the index privileges [read,all]"
      }
    ],
    "type" : "security_exception",
    "reason" : "action [indices:data/read/search] is unauthorized for user [all_user] with effective roles [all_role] on indices [index2], this action is granted by the index privileges [read,all]"
  },
  "status" : 403
}
```

- 作成するがエラーとなる
``` bash
curl -u 'all_user:password' POST 'localhost:9200/index2/_doc/1?pretty' -H 'Content-Type: application/json' -d'
{
    "name": "new_doc",
    "description": "new document"
}'
curl: (6) Could not resolve host: POST
{
  "error" : {
    "root_cause" : [
      {
        "type" : "security_exception",
        "reason" : "action [indices:data/write/bulk[s]] is unauthorized for user [all_user] with effective roles [all_role] on indices [index2], this action is granted by the index privileges [create_doc,create,delete,index,write,all]"
      }
    ],
    "type" : "security_exception",
    "reason" : "action [indices:data/write/bulk[s]] is unauthorized for user [all_user] with effective roles [all_role] on indices [index2], this action is granted by the index privileges [create_doc,create,delete,index,write,all]"
  },
  "status" : 403
}
```

- 更新するがエラーとなる
``` bash
curl -u 'all_user:password' -X POST "localhost:9200/index2/_update/1?pretty" -H 'Content-Type: application/json' -d'
{
  "doc": {
    "name": "update_doc",
    "description": "update document"
  }
}'
{
  "error" : {
    "root_cause" : [
      {
        "type" : "security_exception",
        "reason" : "action [indices:data/write/update] is unauthorized for user [all_user] with effective roles [all_role] on indices [index2], this action is granted by the index privileges [index,write,all]"
      }
    ],
    "type" : "security_exception",
    "reason" : "action [indices:data/write/update] is unauthorized for user [all_user] with effective roles [all_role] on indices [index2], this action is granted by the index privileges [index,write,all]"
  },
  "status" : 403
}
```

- 削除するがエラーとなる
``` bash
curl -u 'all_user:password' -X DELETE "localhost:9200/index2/_doc/1?pretty"
{
  "error" : {
    "root_cause" : [
      {
        "type" : "security_exception",
        "reason" : "action [indices:data/write/bulk[s]] is unauthorized for user [all_user] with effective roles [all_role] on indices [index2], this action is granted by the index privileges [create_doc,create,delete,index,write,all]"
      }
    ],
    "type" : "security_exception",
    "reason" : "action [indices:data/write/bulk[s]] is unauthorized for user [all_user] with effective roles [all_role] on indices [index2], this action is granted by the index privileges [create_doc,create,delete,index,write,all]"
  },
  "status" : 403
}
```
</details>

## まとめ

### index1
| role | user | 検索 | 作成 | 更新 | 削除 |  
| :---: | :---: | :---: | :---: | :---: | :---: |
| delete_role | delete_only_user | × | × | × | ◯ | 
| read_role | read_only_user | ◯ | × | × | × |
| write_role | write_only_user | × | ◯ | ◯ | ◯ |
| all_role | enabled_test_user | × | × | × | × |
| all_role | all_user | ◯ | ◯ | ◯ | ◯|

### index2
| role | user | 検索 | 作成 | 更新 | 削除 |  
| :---: | :---: | :---: | :---: | :---: | :---: |
| delete_role | delete_only_user | - | - | - | × | 
| read_role | read_only_user | × | - | - | - |
| write_role | write_only_user | × | × | × | × |
| all_role | enabled_test_user | × | × | × | × |
| all_role | all_user | × | × | × | × |

write権限だけ注意が必要な印象。
参照・追加・更新だけの権限って用意できないのかな？
これはまた検証ですね。
その前にそもそもそんな権限が必要なのかというのも考えたいものです。