管理者か否かを判定！堅牢なアプリを作る

どうもこんばんは、みかんです。

**！！！！とつぜんですがたいせつなおしらせ！！！！**

2020年1月27日
App Maker の提供終了に向けた対応のご案内
https://support.google.com/a/answer/9682494?p=am_announcement&visit_id=637157414793613981-426262357&rd=1


??!???!?!?!???!?

残念ながら2021年1月19日には終了してしまうそうです(涙)
移行先はAppSheetかApp EngineかGoogleフォームだそうです・・・

消すのは忍びないので記事は残して置きますが、何かの間違いじゃ無い限り役に立つことはないでしょう・・・


**！！！！おしらせはおわりです！！！！！**

今回は「管理者か否かを判定！堅牢なアプリを作る」を書いてみます。
下記ステップでやっていきます。

* 1 下準備
* 2 モデルを守る
* 3 ページを守る
* 4 スクリプトで守る

# 1 下準備

まずは説明のためのアプリを用意します。
といっても、Starter Appをちょっといじる程度で良いので、Starter Appを選択します。

|<img width="275" alt="ap01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26085/033a3138-10ca-42d5-d7d5-2c9a0e7d35da.png">|
|:-:|

さて、まずは管理者とは誰なのか、という説明をするために、一旦この状態でデプロイをしてみます。
SettingsのDeploymentで新規作成しましょう。

|![gif001-compressor.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26085/5fa06904-1fbe-0e94-e7ff-abc075d1fb1e.gif)|
|:-:|

|<img width="455" alt="ap02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26085/587d22c0-60dd-54a1-fd3c-92d9086e67c8.png">|
|:-:|

このデプロイの設定に、「Users with Admin access」というものがあります。
ここに設定したアカウントが、このアプリでは管理者として扱われます。
複数設定することも可能で、Google Groupを割り当てることも可能です。

# 2 モデルを守る

まずは、モデルについて解説したいので、適当なモデルを作ります。

|<img width="811" alt="ap03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26085/a2776313-bf17-0e62-b3a8-9775f2a87afe.png">|
|:-:|

このモデルを、「管理者しかアクセスできない」ようにしてみましょう。
「SECURITY」タブに移動します。

|<img width="983" alt="ap04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26085/3691afb8-e004-69bb-0eb8-69ff9b68596c.png">|
|:-:|

**Admins Only**となっています。最初から管理者しかアクセスできないようになっていますね。
ここで、右端のAdvancedというチェックマークをクリックしてみます。

|<img width="967" alt="ap05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26085/024050ec-ba5d-5e11-95cf-c576faf48a01.png">|
|:-:|

するとこのように、モデルに対する「作成、読込、更新、削除」毎に権限設定ができるようになりました。
読み込むのはいいけど書き込みなど編集は許可しない、といった細かい設定も可能ということです。

Admins Onlyとなっているところをクリックしてみると、、

|<img width="264" alt="ap06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26085/93679c21-14fb-8297-b5c3-7991d0ba28b2.png">|
|:-:|

いくつか選択肢が表示されます。大体名前の通りです。Everyoneだと、誰でもその操作が許可されます。
アプリ独自の判定基準を設けたい場合は、Scriptを選んでビジネスロジックを組んでいくことも可能です。
特定の日付を過ぎていたら編集できないようにする、とかですね。

このように、モデルで権限を設定しておくと、仮にAdminでないユーザーが、モデルにアクセスするような処理に関わるような時に、App Maker側でエラーとなるような動きをします。

なので、App Makerにおいてまず一番始めにやることは、モデルの設定を適切にすること、になります。

よくあるパターンとしては、特に制限を設けるつもりが無くアプリをリリースした時に、
デフォルトの設定がAdmins Onlyなので一般ユーザーがアクセスできない！となるパターンですね。
作業している人は必ずAdminになるので、自分でテストしている段階では気づけないところが厄介です。

必ず、一般ユーザーとして振る舞えるテスト用のアカウントを用意してもらうようにしましょう。

# 3 ページを守る

モデルの権限を守っていれば最終的には安全ですが、そもそもとしてアプリの作りとして、権限が無い人は権限を必要とする画面にアクセスできないようにすることも必要でしょう。

App Makerにはそれを簡単に設定する機能も備わっています。Starter Appの「Settings」ページを開き、プロパティエディタを見てみましょう。

|<img width="790" alt="ap07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26085/97ba786a-87ce-03a0-86e5-613eb7431486.png">|
|:-:|

「Security」という項目があることがわかると思います。
あれ？Securityがないぞ？となった場合は、選択しているウィジェットがページのトップレベルの「Settings」になっていない可能性があるので、確認してみてください。今何が選択されているかは、上の画像でいうとヘッダーのすぐ上あたりに表示されています。(Panel: Settingsとなっている部分です。)

|<img width="179" alt="ap08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26085/ba0e385d-c01b-6a3c-8378-f9cda05b5400.png">|
|:-:|

選択肢もモデルと似ていますが、「Owner or Roles」がありません。それはデータの作成者なら触れる等といった設定なので、画面では関係ない概念だからです。

# 4 スクリプトで守る

モデルもページも守れたので、これで大体安心ですが、管理者だけに見えるボタンなどを置きたい場合は、スクリプトでの制御が必要です。

試しに一般ユーザーがアクセス可能なPageに、ボタンを置いて、それを管理者だけが見えるように設定してみたいと思います。

|![gif002-compressor.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26085/291aeab1-bbf2-84ae-f7da-e642bb7276c0.gif)|
|:-:|

visibleというプロパティはその名の通り、見える見えないを制御するプロパティです。
これを、現在のユーザーのRoleがAdminsか否かで切り替わるように設定しています。

各ウィジェットにはモデルやページのような「Security」という設定項目が無いので、代わりに権限に応じて見える見えないを切り替えるようにした、という対応です。

スクリプトかというとちょっと微妙ですが、、スクリプトでも、同じような感じで値を参照できます。

```javascript
var isAdmin = app.user.role.Admins;
```

見える見えないの制御を、複雑に制御したい場合はこのスクリプトと合わせるようなイメージで書いていくことになると思います。

権限周りは細かいところも含めるともう少し色々あるのですが、最低限これを知っているだけでも大分便利に作っていけると思いますので紹介してみました。

以上です。良いApp Makerライフを!