1import * as GCP from "@/GCP";
2import * as Effect from "effect/Effect";
3import { serveProbes } from "../../bindingHost.ts";
4
5const denyRules = `rules_version = '2';
6service cloud.firestore {
7 match /databases/{database}/documents {
8 match /{document=**} {
9 allow read, write: if false;
10 }
11 }
12}`;
13
14/** Deny-all Firestore ruleset the bindings test and release. */
15export const DenyAll = GCP.FirebaseRules.Ruleset("Firestore", {
16 source: { files: [{ name: "firestore.rules", content: denyRules }] },
17});
18
19/** Release pointing at {@link DenyAll} (generated release id). */
20export const Live = Effect.gen(function* () {
21 const ruleset = yield* DenyAll;
22 return yield* GCP.FirebaseRules.Release("Live", {
23 rulesetName: ruleset.name,
24 });
25});
26
27/**
28 * Effect-native Cloud Run service exercising every Firebase Rules binding as
29 * its own runtime service account. Deployed from {@link ../Bindings.test.ts}.
30 */
31export default class FirebaseRulesBindingsHost extends GCP.Function<FirebaseRulesBindingsHost>()(
32 "FirebaseRulesBindingsHost",
33 { main: import.meta.url, invokerIamDisabled: true },
34 Effect.gen(function* () {
35 const testRuleset = yield* GCP.FirebaseRules.TestRuleset(yield* DenyAll);
36 const getExecutable = yield* GCP.FirebaseRules.GetReleaseExecutable(
37 yield* Live,
38 );
39
40 return {
41 fetch: serveProbes({
42 testRuleset: testRuleset({
43 body: {
44 testSuite: {
45 testCases: [
46 {
47 expectation: "DENY",
48 request: {
49 auth: null,
50 path: "/databases/(default)/documents/notes/a",
51 method: "get",
52 },
53 },
54 {
55 expectation: "ALLOW",
56 request: {
57 auth: null,
58 path: "/databases/(default)/documents/notes/a",
59 method: "get",
60 },
61 },
62 ],
63 },
64 },
65 }),
66 getReleaseExecutable: getExecutable(),
67 }),
68 };
69 }).pipe(
70 Effect.provide(GCP.FirebaseRules.TestRulesetHttp),
71 Effect.provide(GCP.FirebaseRules.GetReleaseExecutableHttp),
72 ),
73) {}