fake_firebase_security_rules

pub package Tests

This project simulates Firebase Security Rules. It is meant to be used by Fake Cloud Firestore and Firebase Storage Mocks. Given these request inputs:

  • Firebase security rules such as:
service cloud.firestore {
  match /databases/{database}/documents {
    match /users/{userId} {
      allow read, write: if request.auth != null && request.auth.uid == userId;
    }
  }
}
  • Concrete path, access method, eg an update on /databases/some-db/users/abcd,
  • Variables, eg a Map such as {'request': { 'auth': { 'uid': 'efgh' } } },

the library computes whether the request should be allowed or not.

Usage

import 'package:fake_firebase_security_rules/fake_firebase_security_rules.dart';

// https://firebase.google.com/docs/rules/rules-and-auth#leverage_user_information_in_rules
final authUidDescription = '''
service cloud.firestore {
  match /databases/{database}/documents {
    // Make sure the uid of the requesting user matches name of the user
    // document. The wildcard expression {userId} makes the userId variable
    // available in rules.
    match /users/{userId} {
      allow read, write: if request.auth != null && request.auth.uid == userId;
    }
  }
}''';

void main(List<String> args) async {
  final securityRules = FakeFirebaseSecurityRules(authUidDescription);
  final uid = 'a57293b';
  final variables = {
    'request': {
      'auth': {'uid': uid}
    }
  };
  // Prints out `true`.
  print(securityRules.isAllowed(
      'databases/some-database/documents/users/$uid', Method.read,
      variables: variables));
  // Prints out `false`.
  print(securityRules.isAllowed(
      'databases/some-database/documents/users/someone-elses-id', Method.read,
      variables: variables));
  // Prints out `false`.
  print(securityRules.isAllowed(
      'databases/some-database/documents/somewhere-else/someone-doc',
      Method.read,
      variables: variables));
}

See the Unit tests for more advanced examples of usage.

Features

Supports:

  • rules declarations used in Firestore and Firebase Storage.
  • recursive match definitions.
  • exhaustive path matching with path variables and wildcards, eg /users/{userId}/{documents=**}.
  • request.auth object populated with uid, custom claims...
  • standard CEL types and methods, eg bool, int, double, String, Map, List, String.match(regexp), a in list... See cel-dart's supported features for an exhaustive list.

Missing:

  • timestamps.
  • durations.
  • custom functions.
  • resource object.
  • request.resource object.
  • exists(), get() functions.

Implementation details

Differences between Firebase Rules CEL and standard CEL

  • Timestamps. Although not implemented in this project yet, Firebase Rules uses its own Timestamp implementation while CEL uses google.protobuf.Timestamp (spec).

How the project works

FirestoreRules.g4 describes a grammar that parses security rules into Matches. A Match contains a path, made up of segments. Some segments might be variables or wildcards. The expression at the right of allow statements is in Common Expression Language (CEL). CEL is a language used by many security projects. See the CEL specs.

  1. Upon initialization, FakeFirebaseSecurityRules parses security rules into a tree of Matches.
  2. When a request comes in, FakeFirebaseSecurityRules finds the first Match and allow statement that corresponds to the given path and whose CEL expression evaluates to true.

Working on the grammar

The fastest way to get your environment up and running is to create a Codespace on the repository, then pip install antlr4-tools. Once this is done, you can run antlr4-parse to try out the rules against some inputs and antlr4 to regenerate the Parser in lib/src/parser/gen.

cd grammar
# Test the grammar on one file.
antlr4-parse FirestoreRules.g4 rulesDefinition -tree -tokens 9_custom_claims.txt
# Test the grammar on all sample files.
./checkAllDescriptions.sh

Generating the parser

If you modify FirestoreRules.g4, you may want to regenerate the parser:

cd grammar
./regenerateParser.sh

Libraries

fake_firebase_security_rules
Fake for Firebase Security Rules. To be used by fake_cloud_firestore and mock_firebase_storage.