Skip to content

Commit 77d8c0c

Browse files
authored
chore(rules): Exposed admin.securiryRules namespace (#1050)
1 parent acd068f commit 77d8c0c

File tree

5 files changed

+230
-62
lines changed

5 files changed

+230
-62
lines changed

gulpfile.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ gulp.task('compile', function() {
8989
'lib/instance-id/index.d.ts',
9090
'lib/messaging/index.d.ts',
9191
'lib/remote-config/index.d.ts',
92+
'lib/security-rules/index.d.ts',
9293
];
9394

9495
workflow = workflow.pipe(filter(configuration));

src/firebase-namespace-api.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import { database } from './database/index';
2020
import { instanceId } from './instance-id/index';
2121
import { messaging } from './messaging/index';
2222
import { remoteConfig } from './remote-config/index';
23+
import { securityRules } from './security-rules/index';
2324

2425
/**
2526
* `FirebaseError` is a subclass of the standard JavaScript `Error` object. In
@@ -220,6 +221,7 @@ export namespace app {
220221
instanceId(): instanceId.InstanceId;
221222
messaging(): messaging.Messaging;
222223
remoteConfig(): remoteConfig.RemoteConfig;
224+
securityRules(): securityRules.SecurityRules;
223225

224226
/**
225227
* Renders this local `FirebaseApp` unusable and frees the resources of

src/firebase-namespace.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,4 @@ export * from './database/index';
2020
export * from './instance-id/index';
2121
export * from './messaging/index';
2222
export * from './remote-config/index';
23+
export * from './security-rules/index';

src/security-rules/index.ts

Lines changed: 218 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,28 +14,226 @@
1414
* limitations under the License.
1515
*/
1616

17-
import { FirebaseApp } from '../firebase-app';
18-
import * as securityRulesApi from './security-rules';
19-
20-
export declare function securityRules(app?: FirebaseApp): securityRulesApi.SecurityRules;
17+
import { app } from '../firebase-namespace-api';
2118

2219
/**
23-
* We must define a namespace to make the typings work correctly. Otherwise
24-
* `admin.securityRules()` cannot be called like a function. Temporarily,
25-
* admin.securityRules is used as the namespace name because we cannot barrel
26-
* re-export the contents from security-rules, and we want it to
27-
* match the namespacing in the re-export inside src/index.d.ts
20+
* Gets the {@link admin.securityRules.SecurityRules
21+
* `SecurityRules`} service for the default app or a given app.
22+
*
23+
* `admin.securityRules()` can be called with no arguments to access the
24+
* default app's {@link admin.securityRules.SecurityRules
25+
* `SecurityRules`} service, or as `admin.securityRules(app)` to access
26+
* the {@link admin.securityRules.SecurityRules `SecurityRules`}
27+
* service associated with a specific app.
28+
*
29+
* @example
30+
* ```javascript
31+
* // Get the SecurityRules service for the default app
32+
* var defaultSecurityRules = admin.securityRules();
33+
* ```
34+
*
35+
* @example
36+
* ```javascript
37+
* // Get the SecurityRules service for a given app
38+
* var otherSecurityRules = admin.securityRules(otherApp);
39+
* ```
40+
*
41+
* @param app Optional app to return the `SecurityRules` service
42+
* for. If not provided, the default `SecurityRules` service
43+
* is returned.
44+
* @return The default `SecurityRules` service if no app is provided, or the
45+
* `SecurityRules` service associated with the provided app.
2846
*/
47+
export declare function securityRules(app?: app.App): securityRules.SecurityRules;
48+
2949
/* eslint-disable @typescript-eslint/no-namespace */
30-
export namespace admin.securityRules {
31-
// See https://github.com/microsoft/TypeScript/issues/4336
32-
/* eslint-disable @typescript-eslint/no-unused-vars */
33-
// See https://github.com/typescript-eslint/typescript-eslint/issues/363
34-
export import RulesFile = securityRulesApi.RulesFile;
35-
export import RulesetMetadata = securityRulesApi.RulesetMetadata;
36-
export import RulesetMetadataList = securityRulesApi.RulesetMetadataList;
37-
38-
/* eslint-disable @typescript-eslint/no-empty-interface */
39-
export interface Ruleset extends securityRulesApi.Ruleset {}
40-
export interface SecurityRules extends securityRulesApi.SecurityRules {}
50+
export namespace securityRules {
51+
/**
52+
* A source file containing some Firebase security rules. The content includes raw
53+
* source code including text formatting, indentation and comments. Use the
54+
* [`securityRules.createRulesFileFromSource()`](admin.securityRules.SecurityRules#createRulesFileFromSource)
55+
* method to create new instances of this type.
56+
*/
57+
export interface RulesFile {
58+
readonly name: string;
59+
readonly content: string;
60+
}
61+
62+
/**
63+
* Required metadata associated with a ruleset.
64+
*/
65+
export interface RulesetMetadata {
66+
/**
67+
* Name of the `Ruleset` as a short string. This can be directly passed into APIs
68+
* like [`securityRules.getRuleset()`](admin.securityRules.SecurityRules#getRuleset)
69+
* and [`securityRules.deleteRuleset()`](admin.securityRules.SecurityRules#deleteRuleset).
70+
*/
71+
readonly name: string;
72+
/**
73+
* Creation time of the `Ruleset` as a UTC timestamp string.
74+
*/
75+
readonly createTime: string;
76+
}
77+
78+
/**
79+
* A page of ruleset metadata.
80+
*/
81+
export interface RulesetMetadataList {
82+
/**
83+
* A batch of ruleset metadata.
84+
*/
85+
readonly rulesets: RulesetMetadata[];
86+
/**
87+
* The next page token if available. This is needed to retrieve the next batch.
88+
*/
89+
readonly nextPageToken?: string;
90+
}
91+
92+
/**
93+
* A set of Firebase security rules.
94+
*/
95+
export interface Ruleset extends RulesetMetadata {
96+
readonly source: RulesFile[];
97+
}
98+
99+
/**
100+
* The Firebase `SecurityRules` service interface.
101+
*
102+
* Do not call this constructor directly. Instead, use
103+
* [`admin.securityRules()`](admin.securityRules#securityRules).
104+
*/
105+
export interface SecurityRules {
106+
app: app.App;
107+
108+
/**
109+
* Creates a {@link admin.securityRules.RulesFile `RuleFile`} with the given name
110+
* and source. Throws an error if any of the arguments are invalid. This is a local
111+
* operation, and does not involve any network API calls.
112+
*
113+
* @example
114+
* ```javascript
115+
* const source = '// Some rules source';
116+
* const rulesFile = admin.securityRules().createRulesFileFromSource(
117+
* 'firestore.rules', source);
118+
* ```
119+
*
120+
* @param name Name to assign to the rules file. This is usually a short file name that
121+
* helps identify the file in a ruleset.
122+
* @param source Contents of the rules file.
123+
* @return A new rules file instance.
124+
*/
125+
createRulesFileFromSource(name: string, source: string | Buffer): RulesFile;
126+
127+
/**
128+
* Creates a new {@link admin.securityRules.Ruleset `Ruleset`} from the given
129+
* {@link admin.securityRules.RulesFile `RuleFile`}.
130+
*
131+
* @param file Rules file to include in the new `Ruleset`.
132+
* @returns A promise that fulfills with the newly created `Ruleset`.
133+
*/
134+
createRuleset(file: RulesFile): Promise<Ruleset>;
135+
136+
/**
137+
* Gets the {@link admin.securityRules.Ruleset `Ruleset`} identified by the given
138+
* name. The input name should be the short name string without the project ID
139+
* prefix. For example, to retrieve the `projects/project-id/rulesets/my-ruleset`,
140+
* pass the short name "my-ruleset". Rejects with a `not-found` error if the
141+
* specified `Ruleset` cannot be found.
142+
*
143+
* @param name Name of the `Ruleset` to retrieve.
144+
* @return A promise that fulfills with the specified `Ruleset`.
145+
*/
146+
getRuleset(name: string): Promise<Ruleset>;
147+
148+
/**
149+
* Deletes the {@link admin.securityRules.Ruleset `Ruleset`} identified by the given
150+
* name. The input name should be the short name string without the project ID
151+
* prefix. For example, to delete the `projects/project-id/rulesets/my-ruleset`,
152+
* pass the short name "my-ruleset". Rejects with a `not-found` error if the
153+
* specified `Ruleset` cannot be found.
154+
*
155+
* @param name Name of the `Ruleset` to delete.
156+
* @return A promise that fulfills when the `Ruleset` is deleted.
157+
*/
158+
deleteRuleset(name: string): Promise<void>;
159+
160+
/**
161+
* Retrieves a page of ruleset metadata.
162+
*
163+
* @param pageSize The page size, 100 if undefined. This is also the maximum allowed
164+
* limit.
165+
* @param nextPageToken The next page token. If not specified, returns rulesets
166+
* starting without any offset.
167+
* @return A promise that fulfills with a page of rulesets.
168+
*/
169+
listRulesetMetadata(
170+
pageSize?: number, nextPageToken?: string): Promise<RulesetMetadataList>;
171+
172+
/**
173+
* Gets the {@link admin.securityRules.Ruleset `Ruleset`} currently applied to
174+
* Cloud Firestore. Rejects with a `not-found` error if no ruleset is applied
175+
* on Firestore.
176+
*
177+
* @return A promise that fulfills with the Firestore ruleset.
178+
*/
179+
getFirestoreRuleset(): Promise<Ruleset>;
180+
181+
/**
182+
* Creates a new {@link admin.securityRules.Ruleset `Ruleset`} from the given
183+
* source, and applies it to Cloud Firestore.
184+
*
185+
* @param source Rules source to apply.
186+
* @return A promise that fulfills when the ruleset is created and released.
187+
*/
188+
releaseFirestoreRulesetFromSource(source: string | Buffer): Promise<Ruleset>;
189+
190+
/**
191+
* Applies the specified {@link admin.securityRules.Ruleset `Ruleset`} ruleset
192+
* to Cloud Firestore.
193+
*
194+
* @param ruleset Name of the ruleset to apply or a `RulesetMetadata` object
195+
* containing the name.
196+
* @return A promise that fulfills when the ruleset is released.
197+
*/
198+
releaseFirestoreRuleset(ruleset: string | RulesetMetadata): Promise<void>;
199+
200+
/**
201+
* Gets the {@link admin.securityRules.Ruleset `Ruleset`} currently applied to a
202+
* Cloud Storage bucket. Rejects with a `not-found` error if no ruleset is applied
203+
* on the bucket.
204+
*
205+
* @param bucket Optional name of the Cloud Storage bucket to be retrieved. If not
206+
* specified, retrieves the ruleset applied on the default bucket configured via
207+
* `AppOptions`.
208+
* @return A promise that fulfills with the Cloud Storage ruleset.
209+
*/
210+
getStorageRuleset(bucket?: string): Promise<Ruleset>;
211+
212+
/**
213+
* Creates a new {@link admin.securityRules.Ruleset `Ruleset`} from the given
214+
* source, and applies it to a Cloud Storage bucket.
215+
*
216+
* @param source Rules source to apply.
217+
* @param bucket Optional name of the Cloud Storage bucket to apply the rules on. If
218+
* not specified, applies the ruleset on the default bucket configured via
219+
* {@link admin.AppOptions `AppOptions`}.
220+
* @return A promise that fulfills when the ruleset is created and released.
221+
*/
222+
releaseStorageRulesetFromSource(
223+
source: string | Buffer, bucket?: string): Promise<Ruleset>;
224+
225+
/**
226+
* Applies the specified {@link admin.securityRules.Ruleset `Ruleset`} ruleset
227+
* to a Cloud Storage bucket.
228+
*
229+
* @param ruleset Name of the ruleset to apply or a `RulesetMetadata` object
230+
* containing the name.
231+
* @param bucket Optional name of the Cloud Storage bucket to apply the rules on. If
232+
* not specified, applies the ruleset on the default bucket configured via
233+
* {@link admin.AppOptions `AppOptions`}.
234+
* @return A promise that fulfills when the ruleset is released.
235+
*/
236+
releaseStorageRuleset(
237+
ruleset: string | RulesetMetadata, bucket?: string): Promise<void>;
238+
}
41239
}

src/security-rules/security-rules.ts

Lines changed: 8 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -21,47 +21,13 @@ import {
2121
SecurityRulesApiClient, RulesetResponse, RulesetContent, ListRulesetsResponse,
2222
} from './security-rules-api-client-internal';
2323
import { FirebaseSecurityRulesError } from './security-rules-internal';
24+
import { securityRules } from './index';
2425

25-
/**
26-
* A source file containing some Firebase security rules. The content includes raw
27-
* source code including text formatting, indentation and comments. Use the
28-
* [`securityRules.createRulesFileFromSource()`](admin.securityRules.SecurityRules#createRulesFileFromSource)
29-
* method to create new instances of this type.
30-
*/
31-
export interface RulesFile {
32-
readonly name: string;
33-
readonly content: string;
34-
}
35-
36-
/**
37-
* Required metadata associated with a ruleset.
38-
*/
39-
export interface RulesetMetadata {
40-
/**
41-
* Name of the `Ruleset` as a short string. This can be directly passed into APIs
42-
* like [`securityRules.getRuleset()`](admin.securityRules.SecurityRules#getRuleset)
43-
* and [`securityRules.deleteRuleset()`](admin.securityRules.SecurityRules#deleteRuleset).
44-
*/
45-
readonly name: string;
46-
/**
47-
* Creation time of the `Ruleset` as a UTC timestamp string.
48-
*/
49-
readonly createTime: string;
50-
}
51-
52-
/**
53-
* A page of ruleset metadata.
54-
*/
55-
export interface RulesetMetadataList {
56-
/**
57-
* A batch of ruleset metadata.
58-
*/
59-
readonly rulesets: RulesetMetadata[];
60-
/**
61-
* The next page token if available. This is needed to retrieve the next batch.
62-
*/
63-
readonly nextPageToken?: string;
64-
}
26+
import RulesFile = securityRules.RulesFile;
27+
import RulesetMetadata = securityRules.RulesetMetadata;
28+
import RulesetMetadataList = securityRules.RulesetMetadataList;
29+
import RulesetInterface = securityRules.Ruleset;
30+
import SecurityRulesInterface = securityRules.SecurityRules;
6531

6632
class RulesetMetadataListImpl implements RulesetMetadataList {
6733

@@ -91,7 +57,7 @@ class RulesetMetadataListImpl implements RulesetMetadataList {
9157
/**
9258
* Represents a set of Firebase security rules.
9359
*/
94-
export class Ruleset implements RulesetMetadata {
60+
export class Ruleset implements RulesetInterface {
9561

9662
public readonly name: string;
9763
public readonly createTime: string;
@@ -119,7 +85,7 @@ export class Ruleset implements RulesetMetadata {
11985
* Do not call this constructor directly. Instead, use
12086
* [`admin.securityRules()`](admin.securityRules#securityRules).
12187
*/
122-
export class SecurityRules implements FirebaseServiceInterface {
88+
export class SecurityRules implements FirebaseServiceInterface, SecurityRulesInterface {
12389

12490
private static readonly CLOUD_FIRESTORE = 'cloud.firestore';
12591
private static readonly FIREBASE_STORAGE = 'firebase.storage';

0 commit comments

Comments
 (0)