Skip to content

Commit d2cab23

Browse files
committed
configure firebase CLI (firebase-tools)
1 parent eaac7ae commit d2cab23

7 files changed

+236
-5
lines changed

Diff for: .firebaserc

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"projects": {
3+
"default": "collaborative-learning-ec215"
4+
}
5+
}

Diff for: README.md

+23-5
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,31 @@ To deploy a production release:
4848
1. Push production to GitHub
4949
1. Use https://github.com/concord-consortium/collaborative-learning/releases to create a new release tag
5050

51-
### Debugging
51+
## Deploying database rules:
52+
53+
### Requirements:
54+
55+
* You should install the firebase CLI via: `npm install -g firebase-tools`
56+
* You shouuld be logged in to firebase: `firebase login`
57+
58+
You deploy firebase functions and rules directly from the working directory using
59+
the `firebase deploy` command. You can see `firebase deploy help` for more info.
60+
61+
See which project you have access to and which you are currently using via: `firebase projects:list`
62+
63+
### To deploy database rules:
64+
```
65+
$ npm run deploy:firestore:rules # deploys firestore rules
66+
$ npm run deploy:firebase:rules # deploys firebase (real-time-database) rules
67+
```
68+
69+
## Debugging
5270

5371
To enable per component debugging set the "debug" localstorage key with one or more of the following:
5472

5573
- `canvas` this will show the document key over the canvas, useful for looking up documents in Firebase
5674

57-
### Testing
75+
## Testing
5876

5977
Run `npm test` to run all Jest tests.
6078

@@ -66,19 +84,19 @@ Along with `dev`, `test`, `authed` and `demo` modes the app has a `qa` mode. QA
6684
2. qaClear - either "all", "class" or "offering". When this parameter is present the QA database is cleared at the level requested based on the user parameters.
6785
This is useful to clear data between automated QA runs. When complete the app will display `<span className="qa-clear">QA Cleared: OK</span>`.
6886

69-
###To run Cypress integration tests:
87+
### To run Cypress integration tests:
7088
- `npm run test:local`
7189
- `npm run test:dev`
7290
- `npm run test:branch` (requires change in environments.json to add the branch name)
7391
- `npm run test:master`
7492
- `npm run test:production`
7593

76-
## Additional notes about configuration
94+
### Additional notes about configuration
7795

7896
You can also temporarily overwrite any configuration option using env variables with `CYPRESS_` prefix. E.g.:
7997
- `CYPRESS_baseUrl=https://collaborative-learning.concord.org/branch/fix-data-attributes npm run test:dev`
8098

81-
## Writing tests, workflow and patterns
99+
### Writing tests, workflow and patterns
82100

83101
1. Tests should not depend on other tests.
84102
2. Take a look at `cypress/support/commands.js`. This file implements LARA-specific helpers that will make test

Diff for: database.rules.json

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
{
2+
"rules": {
3+
"test": {
4+
".read": "auth !== null",
5+
".write": "auth !== null"
6+
},
7+
"dev": {
8+
".read": "auth !== null",
9+
".write": "auth !== null"
10+
},
11+
"demo": {
12+
".read": "auth !== null",
13+
".write": "auth !== null"
14+
},
15+
"qa": {
16+
".read": "auth !== null",
17+
".write": "auth !== null"
18+
},
19+
"authed": {
20+
"portals": {
21+
"learn_concord_org": {
22+
"classes": {
23+
"$class_hash": {
24+
".read": "auth != null && auth.class_hash == $class_hash",
25+
".write": "auth != null && auth.class_hash == $class_hash",
26+
"users": {
27+
"$user_id": {
28+
"latestGroupId": {
29+
".read": "auth !== null",
30+
".write": "auth !== null"
31+
}
32+
}
33+
}
34+
}
35+
}
36+
},
37+
"learn_staging_concord_org": {
38+
"classes": {
39+
"$class_hash": {
40+
".read": "auth != null && auth.class_hash == $class_hash",
41+
".write": "auth != null && auth.class_hash == $class_hash",
42+
"users": {
43+
"$user_id": {
44+
"latestGroupId": {
45+
".read": "auth !== null",
46+
".write": "auth !== null"
47+
}
48+
}
49+
}
50+
}
51+
}
52+
}
53+
}
54+
},
55+
"authed-copy": {
56+
"portals": {
57+
"learn_concord_org": {
58+
"classes": {
59+
"$class_hash": {
60+
".read": "auth != null && auth.class_hash == $class_hash",
61+
".write": "auth != null && auth.class_hash == $class_hash"
62+
}
63+
}
64+
},
65+
"learn_staging_concord_org": {
66+
"classes": {
67+
"$class_hash": {
68+
".read": "auth != null && auth.class_hash == $class_hash",
69+
".write": "auth != null && auth.class_hash == $class_hash"
70+
}
71+
}
72+
}
73+
}
74+
}
75+
}
76+
}

Diff for: firebase.json

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"database": {
3+
"rules": "database.rules.json"
4+
},
5+
"firestore": {
6+
"rules": "firestore.rules",
7+
"indexes": "firestore.indexes.json"
8+
},
9+
"emulators": {
10+
"firestore": {
11+
"port": 8088
12+
},
13+
"database": {
14+
"port": 9000
15+
},
16+
"ui": {
17+
"enabled": true
18+
}
19+
}
20+
}

Diff for: firestore.indexes.json

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"indexes": [
3+
{
4+
"collectionGroup": "docs",
5+
"queryScope": "COLLECTION_GROUP",
6+
"fields": [
7+
{
8+
"fieldPath": "classes",
9+
"arrayConfig": "CONTAINS"
10+
},
11+
{
12+
"fieldPath": "problem",
13+
"order": "ASCENDING"
14+
}
15+
]
16+
}
17+
],
18+
"fieldOverrides": []
19+
}

Diff for: firestore.rules

+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
// NOTE: to deploy only these rules run
2+
// `npm run deploy:firestore:rules`
3+
4+
rules_version = '2';
5+
service cloud.firestore {
6+
match /databases/{database}/documents {
7+
8+
function isAuthed() {
9+
return request.auth != null;
10+
}
11+
12+
// function hasClass() {
13+
// return isAuthed() && request.auth.token.class_hash != null;
14+
// }
15+
16+
// function hasClassHash(classHash) {
17+
// return request.auth.token.class_hash == classHash;
18+
// }
19+
20+
function hasRole(role) {
21+
return isAuthed() && request.auth.token.user_type == role;
22+
}
23+
24+
function hasUserId() {
25+
return isAuthed() && request.auth.token.platform_user_id != null;
26+
}
27+
28+
// function matchUserId(userId) {
29+
// return hasUserId() && string(request.auth.token.platform_user_id) == userId;
30+
// }
31+
32+
function matchFirebaseUserId(userId) {
33+
return isAuthed() && request.auth.uid == userId;
34+
}
35+
36+
function isAuthedTeacher() {
37+
return hasUserId() && hasRole("teacher");
38+
}
39+
40+
function docMatchUserId() {
41+
return isAuthed() &&
42+
string(request.auth.token.platform_user_id) == resource.data.uid;
43+
}
44+
45+
function classInClasses() {
46+
return isAuthed() && request.auth.token.class_hash in resource.data.classes;
47+
}
48+
49+
//
50+
// portal-authenticated secure access rules
51+
//
52+
match /authed/{portal} {
53+
allow read, write: if isAuthedTeacher();
54+
55+
match /mcsupports/{docId} {
56+
// any portal-authenticated teacher can create supports
57+
allow create: if isAuthedTeacher();
58+
// teachers can only update/delete their own supports
59+
allow update, delete: if docMatchUserId();
60+
// teachers and students in appropriate classes can read supports
61+
allow read: if docMatchUserId() || classInClasses();
62+
}
63+
}
64+
65+
//
66+
// non-portal-authenticated/dev/demo/qa/test rules
67+
//
68+
match /demo/{demoName}/{restOfPath=**} {
69+
allow read, write: if isAuthed();
70+
}
71+
72+
match /dev/{userId}/{restOfPath=**} {
73+
allow read: if isAuthed();
74+
// users can only write to their own folders
75+
allow write: if matchFirebaseUserId(userId);
76+
}
77+
78+
match /qa/{userId}/{restOfPath=**} {
79+
allow read: if isAuthed();
80+
// users can only write to their own folders
81+
allow write: if matchFirebaseUserId(userId);
82+
}
83+
84+
match /test/{userId}/{restOfPath=**} {
85+
allow read: if isAuthed();
86+
// users can only write to their own folders
87+
allow write: if matchFirebaseUserId(userId);
88+
}
89+
90+
}
91+
}

Diff for: package.json

+2
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@
4242
"build:debug": "npm-run-all lint clean build:webpack",
4343
"build:webpack": "cross-env NODE_OPTIONS=--max_old_space_size=4096 webpack --mode production",
4444
"clean": "rimraf dist",
45+
"deploy:database:rules": "firebase deploy --only database",
46+
"deploy:firestore:rules": "firebase deploy --only firestore:rules",
4547
"lint": "eslint \"./src/**/*.{js,json,jsx,ts,tsx}\"",
4648
"lint:build": "eslint -c \".eslintrc.build.js\" \"./src/**/*.{js,json,jsx,ts,tsx}\"",
4749
"lint:fix": "eslint --fix \"./src/**/*.{js,json,jsx,ts,tsx}\"",

0 commit comments

Comments
 (0)