Open Distro ユーザ自身のパスワード変更

#Open Distro の REST APIでの変更

REST API権限のないユーザで、Kibana consoleで自身のパスワードを変更しようと

```ShellSession
PUT _opendistro/_security/api/internalusers/<ユーザ名>
{
 "password": "パスワード"
}
```
を実行しても

```
{
  "status": "FORBIDDEN",
  "message": "No permission to access REST API: User <ユーザ名> with Open Distro Security Roles [<ロール名>, own_index] does not have any role privileged for admin access. No client TLS certificate found in request"
}
```
権限がないとエラーになります。

- <ロール名>は、今ログインしているアカウントとマッピングされているロール名が表示されます。

opendistro-for-elasticsearch/security の issueにEnhancementとして登録されてますが、いつ対応されるかはわからないです。
https://github.com/opendistro-for-elasticsearch/security/issues/47


REST APIは、ロール単位にアクセス制御できます。
https://opendistro.github.io/for-elasticsearch-docs/docs/security-access-control/api/#access-control-for-the-api

elasticsearch.yml に以下のような記述があり、all_access, security_rest_api_access ロールに対して許可をしています。

```yml:elasticsearch.yml
 :
opendistro_security.restapi.roles_enabled: ["all_access", "security_rest_api_access"]
 :
```
ここで指定するとすべてのAPIが利用可能になります。
また、endpoint単位に無効化できるメソッドを指定できます。

```yml:elasticsearch.yml
 :
opendistro_security.restapi.endpoints_disabled.<role>.<endpoint>: ["<method>", ...]
 :
```
自身のパスワード変更だけなので、internalusersへのPUTだけ許可すればよさげです。

```yml:elasticsearch.yml
 :
opendistro_security.restapi.endpoints_disabled.<role>.ACTIONGROUPS: ["GET", "PUT","POST","DELETE","PATCH"]
opendistro_security.restapi.endpoints_disabled.<role>.ROLES: ["GET", "PUT","POST","DELETE","PATCH"]
opendistro_security.restapi.endpoints_disabled.<role>.ROLESMAPPING: ["GET", "PUT","POST","DELETE","PATCH"]
opendistro_security.restapi.endpoints_disabled.<role>.INTERNALUSERS: ["GET", "POST","DELETE","PATCH"]
opendistro_security.restapi.endpoints_disabled.<role>.CONFIG: ["GET", "PUT","POST","DELETE","PATCH"]
opendistro_security.restapi.endpoints_disabled.<role>.CACHE: ["GET", "PUT","POST","DELETE","PATCH"]
opendistro_security.restapi.endpoints_disabled.<role>.LICENSE: ["GET", "PUT","POST","DELETE","PATCH"]
opendistro_security.restapi.endpoints_disabled.<role>.SYSTEMINFO: ["GET", "PUT","POST","DELETE","PATCH"]
 :
```

１アカウント１ロールなら問題ないのですが、複数アカウントだと他人のパスワードまで変更できてしまうのは、ちょっとだめかな。
１アカウント１ロールの場合は、ロール増える毎に定義追加とかも面倒。

#Pluginの中で、REST APIにアクセスできるアカウントに変身してごまかしてみる

ということでpluginの中で変身すればよくね、ということで作ってみる。

https://www.elastic.co/guide/en/kibana/current/development-elasticsearch.html
ここにあるadminは、Kibanaの状態を管理するアカウント。こいつのロールにPUTだけ追加すればいいと。。

```javascript:example.js
  const {callWithInternalUser} = server.plugins.elasticsearch.getCluster('admin');
  const {callWithRequest} = server.plugins.elasticsearch.getCluster('data');

　　　:
//var username = _opendistro/_security/authinfo で、現在のセッションの情報から取得
//var userPassword = クライアントから送られてきたパス。;
   :
        await callWithInternalUser('transport.request', {
            method: "PUT",
            path: "_opendistro/_security/api/internalusers/" + username,
            body: { password : userPassword }
          }
        ).then(function(resp){
           // なんか処理
        });

```
のような感じでできるのではないかと思われます。

adminのロールはなんだ。。。。このadminはOpen Distroのadminではなく、Kibanaの状態管理アカウントらしい。

```yml:kibana.yml
 :
elasticsearch.username: kibanaserver
elasticsearch.password: kibanaserver
 :
```
とあるので、kibanaserverのロール。
OpenDistroでkibanaserverは、kibana_serverにマッピングされてるからこいつに許可を追加。

```yml:elasticsearch.yml
 :
opendistro_security.restapi.roles_enabled: ["all_access", "security_rest_api_access", "kibana_server"]
 :
opendistro_security.restapi.endpoints_disabled.kibana_server.ACTIONGROUPS: ["GET", "PUT","POST","DELETE","PATCH"]
opendistro_security.restapi.endpoints_disabled.kibana_server.ROLES: ["GET", "PUT","POST","DELETE","PATCH"]
opendistro_security.restapi.endpoints_disabled.kibana_server.ROLESMAPPING: ["GET", "PUT","POST","DELETE","PATCH"]
opendistro_security.restapi.endpoints_disabled.kibana_server.INTERNALUSERS: ["GET", "POST","DELETE","PATCH"]
opendistro_security.restapi.endpoints_disabled.kibana_server.CONFIG: ["GET", "PUT","POST","DELETE","PATCH"]
opendistro_security.restapi.endpoints_disabled.kibana_server.CACHE: ["GET", "PUT","POST","DELETE","PATCH"]
opendistro_security.restapi.endpoints_disabled.kibana_server.LICENSE: ["GET", "PUT","POST","DELETE","PATCH"]
opendistro_security.restapi.endpoints_disabled.kibana_server.SYSTEMINFO: ["GET", "PUT","POST","DELETE","PATCH"]
 :
```

とりあえず、Pluginでパスワード変更はできたので、
動きの理解はあっているようです。
今のところの回避策その１。。。