1. HOME
  2. ブログ
  3. IT技術
  4. テスト駆動で学ぶ Firestore セキュリティルール【カスタム関数編:第1回】

テスト駆動で学ぶ Firestore セキュリティルール【カスタム関数編:第1回】

テスト駆動で成績データコレクションのルールを実装する【第1回】

この記事では、全4回に分けて、Firestore セキュリティルールでのカスタム関数の利用について解説していきます。

成績評価システムを想定した、成績データコレクション records のルール実装を例に、解説を進めていきます。

なお、今回の「カスタム関数編」では、これまでの「テスト駆動で学ぶ Firestore セキュリティルール」シリーズの内容を前提としていますので、以下の記事をご参照ください。

データ検証編はこちら

「データ検証編」では、リクエストデータ、データベース上のデータの参照などについて解説

データ比較編はこちら

「データ比較編」では、データの比較や型チェックなどについて解説

カスタム関数編の簡単な流れ

「カスタム関数編」では、以下のような流れで解説を進めていきます。

  1. 第1回 : カスタム関数の簡単な解説と実装ルールの要件設定&前準備
  2. 第2回 : データ追加用のルールの作成
  3. 第3回 : データ更新用のルールの作成
  4. 第4回 : データ取得・削除用のルールの作成

今回の内容は?

第1回である今回は、最初に「データ比較編」で作成したセキュリティルールをカスタム関数を使って整理しながら、カスタム関数について簡単に解説します。

その後、この記事から始まる「カスタム関数編」の全4回を通して、ルールを実装する成績データコレクション records の要件を設定します。

テストで必要となるコレクション usersseasons の要件も併せて設定します。

続いて、ルール実装の前準備として、テスト環境とテストデータを準備します。

カスタム関数について

まずは、前回の「データ比較編」で実装したルールを例に、カスタム関数について簡単に解説したいと思います。

データ比較編」では、書店のネットショッピングサービスを例に、書籍コレクション books のルールを実装しました。

そのとき実装したルールは、以下の通りです。

「データ比較編」で実装したルール

get アクセスについては、「下書きデータでなく、かつ在庫が6以上」であれば取得が可能となっています。

createupdate アクセスは、大雑把に、どちらも書籍の管理担当者チェックと、書籍データのフォーマットチェックを実行。

書籍の管理担当者であり、かつリクエストデータが適切なフォーマットであれば、データの追加・更新が可能です。

ルール全体の見通しが悪くなっているため調整する

フォーマットチェックの内容が多く、これにより「allow式」が長くなってしまっているため、ルール全体の見通しが悪くなっています。

今回の記事のテーマとなるカスタム関数を使って、上記のルールを整理し、見通しの良いルールに調整したいと思います。

上述のルールは、カスタム関数を使って、以下のように書き換えることが可能です。

「データ比較編」で実装したルールをカスタム関数で書き替える

ここで、カスタム関数 isAdminUser() を定義して、書籍の管理担当者チェック部分を関数化しています。

create アクセスでは、リクエストデータの、 update アクセスでは、データベース上のデータの書籍管理担当者をチェックするため、参照するデータが異なります。

リクエストデータ、データベース上のデータ、どちらのデータのチェックにも対応できるように、チェック対象のデータリソースを isAdminUser() 関数の引数で指定できるように定義。

また、 validBookData() 関数を定義して、リクエストデータのフォーマットチェックを1つにまとめています。

カスタム関数でのルール整理で見通しがよくなった

カスタム関数によるルールの整理によって、「allow式」が短くなって、ルールの見通しがよくなりました。

ここでの解説と同様、「カスタム関数編」では、成績評価システムを想定した成績コレクション records のセキュリティルールを例に、カスタム関数を使ってルールを整理しながらセキュリティルールの実装を進めていきます。

成績データコレクションの要件(実装目標)を設定

まずは、成績コレクション records と、テストで必要となる  users コレクション seasons コレクションの要件を設定します。

成績コレクション records の要件は、以下の通りに設定します。

コレクションパス

students/{studentId}/records

ロール

adminシステム管理者
teacher教師
student生徒

record ドキュメントのフォーマット

データ名称内容データ型条件
id成績IDstring型必須。変更不可。
studentId生徒IDstring型必須。変更不可。
season年度と学期map型必須。変更不可。
name生徒の名前string型必須
homeroomTeacher担任string型必須
record成績map型なし

各処理共通の要件

  1. ログインしていないユーザはアクセス不可

データ追加要件

  1. admin ユーザ以外は追加不可
  2. 成績フィールドは空のマップ
  3. 所定のフォーマットでないデータは追加不可

成績評価の設定は、teacher ユーザがデータ更新でのみ設定可能とします。

データ追加時に成績が設定されないように、追加時の成績フィールドは、空のマップのみ設定可能としています。

データ更新要件

admin ユーザの更新要件

  1. id の更新不可
  2. studentId の更新不可
  3. season の更新不可
  4. record の更新不可

teacher ユーザの更新要件

  1. 担任でないデータは更新不可
  2. 成績以外のフィールドは更新不可
  3. 対象シーズンが成績評価期間外の場合は更新不可

その他の更新要件

  1. student ユーザは更新不可
  2. 所定のフォーマットでないデータは更新不可

データ取得要件

  1. admin ユーザはデータの取得可

teacher ユーザの取得要件

  1. 担任でないデータは取得不可

student ユーザの取得要件

  1. 自分以外のデータは取得不可
  2. 対象シーズンが成績評価期間の場合は取得不可

データ削除要件

  1. admin ユーザ以外は削除不可

関連コレクションの要件を設定

以下、テストの中で records コレクション以外に必要となるコレクションの要件を簡単に設定します。

「seasons」コレクションのフォーマット

データ名称内容データ型条件
idシーズンID。 {year}_{semester} のようなフォーマットで設定。string型必須。変更不可。
evaluationPeriod成績評価期間bool型必須

成績評価期間の更新は、admin ユーザだけが行えるものと想定します。

前述の records コレクションの要件設定でふれた通り、評価期間中のみ teacher ユーザが担当生徒の成績評価を更新できるものとします。

「users」コレクションのフォーマット

データ名称内容データ型条件
idユーザIDstring型必須。変更不可。
rolesロール。 adminteacherまたは studentを設定。list型必須

roles は、複数ロールを設定する場合を想定して「list型」としています。

例えば、 admin と  teacher ロールを兼任する場合や、他のロールを追加する場合などを想定しています。

seasonsusers コレクションは、要件の設定のみで、本記事では、ルールの実装・解説はしません。

前準備 ~ テスト環境 ~

以下のリポジトリに、本記事のコードをまとめてあります。

【GitHub】
rightcode/firestore-security-rules-test_custom-function

テスト環境のセットアップ

以下のコマンドを実行して、テスト環境をセットアップしてください。

Firebase CLI ツールのインストール

Firebase CLI ツールをインストールしていない場合は、以下のコマンドを実行してインストールしてください。

npm パッケージのインストール

以下のコマンドを実行して、必要となる npm パッケージをインストールしてください。

Firestore エミュレータを起動

以下のコマンドを実行して、Firestore エミュレータを起動してください。

以上で、テスト環境の準備は完了です。

テスト環境のセットアップの解説

テスト環境のセットアップの、より詳細な内容は、以下の記事をご参照ください。

master ブランチに実装済みのコードを設置してありますので、本記事中のコードを確認する場合は、以下のコマンドよりmaster ブランチをチェックアウトしてください。

コードの調整などにより、本記事の内容とは記述が若干異なる場合があります。

前準備 ~ テストデータ ~

テストを作成する前に、まず、テストデータ用のコードを用意します。

以下の4つファイルを作成してください。

  1. tests/data/collections/records.ts
  2. tests/data/collections/seasons.ts
  3. tests/data/collections/users.ts
  4. tests/data/InitialData.ts

追加したファイルに、コードを追加していきます。

成績データコレクションのテストデータ

tests/data/collections/records.ts に、以下のコードを追加してください。

「seasons」コレクションのテストデータ

tests/data/collections/seasons.ts に、以下のコードを追加してください。

「users」コレクションのテストデータ

tests/data/collections/users.ts に、以下のコードを追加してください。

初期データのテストデータ

tests/data/InitialData.ts に、以下のコードを追加してください。

テストデータの概要

tests/data /collections/records.ts

records コレクションのサンプルデータを定義しています。

初期データ、更新用データには records.tsseasons.tsusers.ts で定義しているテスト用のサンプルデータを使用しています。

tests/data/collections/seasons.ts

seasons コレクションのサンプルデータを定義しています。

初期データには、引数により成績評価期間フラグの設定が可能です。

tests/data/collections/users.ts

users コレクションのサンプルデータを定義しています。

admin, teacher, student ロールのサンプルユーザを定義しています。

tests/data/InitialData.ts

初期データのセットアップ用クラス。

各テストの前に必要な初期データをデータベースに追加します。

第2回へつづく!

「カスタム関数編」第1回となるこの記事では、前回の記事「データ比較編」で作成したセキュリティルールを例に、カスタム関数の使い方を簡単に解説してみました。

また、カスタム関数の利用例として扱う、成績データコレクション records の要件を設定し、ルール実装に使用するテスト環境とテストデータを準備しました。

次回は、今回設定した要件に沿って、データ追加用ルールの実装を進めていきます。

お楽しみに!

第2回の記事はこちら

こちらの記事もオススメ!

書いた人はこんな人

広告メディア事業部
広告メディア事業部
「好きを仕事にするエンジニア集団」の(株)ライトコードです!

ライトコードは、福岡、東京、大阪の3拠点で事業展開するIT企業です。
現在は、国内を代表する大手IT企業を取引先にもち、ITシステムの受託事業が中心。
いずれも直取引で、月間PV数1億を超えるWebサービスのシステム開発・運営、インフラの構築・運用に携わっています。

システム開発依頼・お見積もり大歓迎!

また、現在「WEBエンジニア」「モバイルエンジニア」「営業」「WEBデザイナー」「WEBディレクター」を積極採用中です!
インターンや新卒採用も行っております。

以下よりご応募をお待ちしております!
https://rightcode.co.jp/recruit

関連記事

採用情報

\ あの有名サービスに参画!? /

バックエンドエンジニア

\ クリエイティブの最前線 /

フロントエンドエンジニア

\ 世界を変える…! /

Androidエンジニア

\ みんなが使うアプリを創る /

iOSエンジニア