redash でアカウントを使用停止にする方法

退職者が出たなどで、redashにアクセスできないようにしようとしたときにハマったのでメモ。
結論から言うと、ユーザをロックできる機能がないのでGUIからアクセスを禁止したいユーザのメールアドレスを類推できないものに変更する。
もっといいやり方がないものか…

## ユーザの削除

**redashはGUIからアカウントを作成することはできるがロック・削除することはできない。**
調べてみると、コマンドラインからユーザの削除はできるもよう。

以下のコマンドでユーザの一覧を表示させる。

```
cd /opt/redash/current
sudo -u redash bin/run ./manage.py users list
```

以下の結果が出る。

```
Id: 1
Name: testuser
Email: testuser@example.com
Organization: test
```

削除したいユーザのメールアドレスを指定して削除する。

```
sudo -u redash bin/run ./manage.py users delete [メールアドレス]
```

しかし、ダッシュボードやクエリを作成したことがあるユーザの場合、
外部キー制約でエラーになってしまう。
削除はしたくないしアカウントをロックさせるようなものはないか？
redashをもう少し調査してみた。

## ユーザアカウントをロックできるか？

redashのユーザを管理しているテーブルのusersテーブルのスキーマをみると、ロックに関する項目はない。

```
sudo su
su - postgres
psql -l

   Name    |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges
-----------+----------+----------+-------------+-------------+-----------------------
 postgres  | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |
 redash    | redash   | UTF8     | en_US.UTF-8 | en_US.UTF-8 |
 template0 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
           |          |          |             |             | postgres=CTc/postgres
 template1 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
           |          |          |             |             | postgres=CTc/postgres
(4 rows)(4 rows)
```

```
psql redash

redash=# \d
                       List of relations
 Schema |               Name               |   Type   | Owner
--------+----------------------------------+----------+--------
 public | access_permissions               | table    | redash
 public | access_permissions_id_seq        | sequence | redash
 public | alembic_version                  | table    | redash
 public | alert_subscriptions              | table    | redash
 public | alert_subscriptions_id_seq       | sequence | redash
 public | alerts                           | table    | redash
 public | alerts_id_seq                    | sequence | redash
 public | api_keys                         | table    | redash
 public | api_keys_id_seq                  | sequence | redash
 public | changes                          | table    | redash
 public | changes_id_seq                   | sequence | redash
 public | dashboards                       | table    | redash
 public | dashboards_id_seq                | sequence | redash
 public | data_source_groups               | table    | redash
 public | data_source_groups_id_seq        | sequence | redash
 public | data_sources                     | table    | redash
 public | data_sources_id_seq              | sequence | redash
 public | events                           | table    | redash
 public | events_id_seq                    | sequence | redash
 public | groups                           | table    | redash
 public | groups_id_seq                    | sequence | redash
 public | notification_destinations        | table    | redash
 public | notification_destinations_id_seq | sequence | redash
 public | organizations                    | table    | redash
 public | organizations_id_seq             | sequence | redash
 public | queries                          | table    | redash
 public | queries_id_seq                   | sequence | redash
 public | query_results                    | table    | redash
 public | query_results_id_seq             | sequence | redash
 public | query_snippets                   | table    | redash
 public | query_snippets_id_seq            | sequence | redash
 public | users                            | table    | redash
 public | users_id_seq                     | sequence | redash
 public | visualizations                   | table    | redash
 public | visualizations_id_seq            | sequence | redash
 public | widgets                          | table    | redash
 public | widgets_id_seq                   | sequence | redash
(37 rows)
```

```
redash=# \d users
                                     Table "public.users"
    Column     |           Type           |                     Modifiers
---------------+--------------------------+----------------------------------------------------
 updated_at    | timestamp with time zone | not null
 created_at    | timestamp with time zone | not null
 id            | integer                  | not null default nextval('users_id_seq'::regclass)
 org_id        | integer                  | not null
 name          | character varying(320)   | not null
 email         | character varying(320)   | not null
 password_hash | character varying(128)   |
 groups        | integer[]                |
 api_key       | character varying(40)    | not null
Indexes:
    "users_pkey" PRIMARY KEY, btree (id)
    "users_api_key_key" UNIQUE CONSTRAINT, btree (api_key)
    "users_org_id_email" UNIQUE, btree (org_id, email)
Foreign-key constraints:
    "users_org_id_fkey" FOREIGN KEY (org_id) REFERENCES organizations(id)
Referenced by:
    TABLE "access_permissions" CONSTRAINT "access_permissions_grantee_id_fkey" FOREIGN KEY (grantee_id) REFERENCES users(id)
    TABLE "access_permissions" CONSTRAINT "access_permissions_grantor_id_fkey" FOREIGN KEY (grantor_id) REFERENCES users(id)
    TABLE "alert_subscriptions" CONSTRAINT "alert_subscriptions_user_id_fkey" FOREIGN KEY (user_id) REFERENCES users(id)
    TABLE "alerts" CONSTRAINT "alerts_user_id_fkey" FOREIGN KEY (user_id) REFERENCES users(id)
    TABLE "api_keys" CONSTRAINT "api_keys_created_by_id_fkey" FOREIGN KEY (created_by_id) REFERENCES users(id)
    TABLE "changes" CONSTRAINT "changes_user_id_fkey" FOREIGN KEY (user_id) REFERENCES users(id)
    TABLE "dashboards" CONSTRAINT "dashboards_user_id_fkey" FOREIGN KEY (user_id) REFERENCES users(id)
    TABLE "events" CONSTRAINT "events_user_id_fkey" FOREIGN KEY (user_id) REFERENCES users(id)
    TABLE "notification_destinations" CONSTRAINT "notification_destinations_user_id_fkey" FOREIGN KEY (user_id) REFERENCES users(id)
    TABLE "queries" CONSTRAINT "queries_last_modified_by_id_fkey" FOREIGN KEY (last_modified_by_id) REFERENCES users(id)
    TABLE "queries" CONSTRAINT "queries_user_id_fkey" FOREIGN KEY (user_id) REFERENCES users(id)
    TABLE "query_snippets" CONSTRAINT "query_snippets_user_id_fkey" FOREIGN KEY (user_id) REFERENCES users(id)


```

**ロックまたはアカウントの凍結で使えそうな項目がない…**

## 苦肉の対応

結局、退職者のアカウントのログインを防ぐため、
該当のアカウントのメールアドレスをGUIから類推できないメールアドレスに修正することによって対応。

もっといいやり方がないものか…