-
Notifications
You must be signed in to change notification settings - Fork 1.2k
fix: fallback to open rules when Storage emulator rules are missing #10949
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,4 @@ | ||
| - Fall back to default open rules with a warning when Storage emulator rules or targets are unconfigured. | ||
| - Added extensions replacement registry and scraper tool to track migrations for deprecated extensions ahead of the March 2027 decommission date. | ||
| - [Added] Loads existing `.env` files and passes environment variables to functions discovery in `runtimeDelegate`. | ||
| - Adds --immediate flag to ext:uninstall (#10921) |
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -14,8 +14,8 @@ | |||||||||||
| } | ||||||||||||
|
|
||||||||||||
| /** | ||||||||||||
| * Parses rules file for each target specified in the storage config under {@link options}. | ||||||||||||
| * @returns The rules file path if the storage config does not specify a target and an array | ||||||||||||
| * of project resources and their corresponding rules files otherwise. | ||||||||||||
| * @throws {FirebaseError} if storage config is missing or rules file is missing or invalid. | ||||||||||||
| */ | ||||||||||||
|
|
@@ -23,52 +23,46 @@ | |||||||||||
| projectId: string, | ||||||||||||
| options: Options, | ||||||||||||
| ): SourceFile | RulesConfig[] { | ||||||||||||
| const storageConfig = options.config.data.storage; | ||||||||||||
|
Check warning on line 26 in src/emulator/storage/rules/config.ts
|
||||||||||||
| const storageLogger = EmulatorLogger.forEmulator(Emulators.STORAGE); | ||||||||||||
| if (!storageConfig) { | ||||||||||||
| if (Constants.isDemoProject(projectId)) { | ||||||||||||
| storageLogger.logLabeled( | ||||||||||||
| "BULLET", | ||||||||||||
| "storage", | ||||||||||||
| `Detected demo project ID "${projectId}", using a default (open) rules configuration.`, | ||||||||||||
| ); | ||||||||||||
| return defaultStorageRules(); | ||||||||||||
| } | ||||||||||||
| throw new FirebaseError( | ||||||||||||
| "Cannot start the Storage emulator without rules file specified in firebase.json: run 'firebase init' and set up your Storage configuration", | ||||||||||||
| ); | ||||||||||||
| logDefaultRulesWarning(projectId, storageLogger); | ||||||||||||
| return defaultStorageRules(); | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| // No target specified | ||||||||||||
| if (!Array.isArray(storageConfig)) { | ||||||||||||
| if (!storageConfig.rules) { | ||||||||||||
| throw new FirebaseError( | ||||||||||||
| "Cannot start the Storage emulator without rules file specified in firebase.json: run 'firebase init' and set up your Storage configuration", | ||||||||||||
| ); | ||||||||||||
| logDefaultRulesWarning(projectId, storageLogger); | ||||||||||||
| return defaultStorageRules(); | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| return getSourceFile(storageConfig.rules, options); | ||||||||||||
|
Check warning on line 40 in src/emulator/storage/rules/config.ts
|
||||||||||||
| } | ||||||||||||
| // Multiple targets | ||||||||||||
| const results: RulesConfig[] = []; | ||||||||||||
| const { rc } = options; | ||||||||||||
| for (const targetConfig of storageConfig) { | ||||||||||||
| if (!targetConfig.target) { | ||||||||||||
| throw new FirebaseError("Must supply 'target' in Storage configuration"); | ||||||||||||
| } | ||||||||||||
| const targets = rc.target(projectId, "storage", targetConfig.target); | ||||||||||||
| if (targets.length === 0) { | ||||||||||||
| // Fall back to open if this is a demo project | ||||||||||||
| // Fall back to open if this is a demo project or targets are missing | ||||||||||||
| if (Constants.isDemoProject(projectId)) { | ||||||||||||
| storageLogger.logLabeled( | ||||||||||||
| "BULLET", | ||||||||||||
| "storage", | ||||||||||||
| `Detected demo project ID "${projectId}", using a default (open) rules configuration. Storage targets in firebase.json will be ignored.`, | ||||||||||||
| ); | ||||||||||||
| return defaultStorageRules(); | ||||||||||||
| } else { | ||||||||||||
| storageLogger.logLabeled( | ||||||||||||
| "WARN", | ||||||||||||
| "storage", | ||||||||||||
| `Storage target '${targetConfig.target}' in firebase.json is not configured in .firebaserc. The emulator will default to allowing all reads and writes.`, | ||||||||||||
| ); | ||||||||||||
| } | ||||||||||||
| // Otherwise, requireTarget will error out | ||||||||||||
| rc.requireTarget(projectId, "storage", targetConfig.target); | ||||||||||||
| return defaultStorageRules(); | ||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Returning
Suggested change
References
|
||||||||||||
| } | ||||||||||||
| results.push( | ||||||||||||
| ...rc.target(projectId, "storage", targetConfig.target).map((resource: string) => { | ||||||||||||
|
|
@@ -79,6 +73,22 @@ | |||||||||||
| return results; | ||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If all targets were skipped because they were unconfigured (meaning
Suggested change
|
||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| function logDefaultRulesWarning(projectId: string, storageLogger: EmulatorLogger): void { | ||||||||||||
| if (Constants.isDemoProject(projectId)) { | ||||||||||||
| storageLogger.logLabeled( | ||||||||||||
| "BULLET", | ||||||||||||
| "storage", | ||||||||||||
| `Detected demo project ID "${projectId}", using a default (open) rules configuration.`, | ||||||||||||
| ); | ||||||||||||
| } else { | ||||||||||||
| storageLogger.logLabeled( | ||||||||||||
| "WARN", | ||||||||||||
| "storage", | ||||||||||||
| "Did not find a Storage rules file specified in a firebase.json config file. The emulator will default to allowing all reads and writes. Learn more about this option: https://firebase.google.com/docs/emulator-suite/install_and_configure#security_rules_configuration.", | ||||||||||||
| ); | ||||||||||||
| } | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| function defaultStorageRules(): SourceFile { | ||||||||||||
| const defaultRulesPath = "emulators/default_storage.rules"; | ||||||||||||
| const name = absoluteTemplateFilePath(defaultRulesPath); | ||||||||||||
|
|
||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's add a test case to verify that when multiple targets are configured, but only some are missing in
.firebaserc, the emulator successfully parses the configured targets and skips the missing ones instead of discarding all rules.