forked from google/ground-platform
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfirestore.rules
130 lines (114 loc) · 4.12 KB
/
firestore.rules
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/**
* Copyright 2020 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Define access rules for Firestore collections and documents.
service cloud.firestore {
match /databases/{database}/documents {
/**
* Reads access control list for specified surveyId. The ACL is represented
* as a map keyed by email, with a single role as the value.
*/
function acl(surveyId) {
return get(/databases/$(database)/documents/surveys/$(surveyId)).data.acl;
}
/**
* Returns user profile data associated with specified userId.
*/
function user(userId) {
return get(/databases/$(database)/documents/users/$(userId)).data
}
/**
* Returns email address for the requesting user.
*/
function email() {
return user(request.auth.uid).email;
}
/**
* Returns the role of the specified email address in the given survey.
*/
function role(surveyId, email) {
return acl(surveyId)[email];
}
/**
* Returns the regular expression for users allowed access.
*/
function passRegexp() {
return get(/databases/$(database)/documents/passlist/regexp).data.regexp
}
/**
* Returns true iff the specified email is in the pass list.
*/
function isInPassList(email) {
return exists(/databases/$(database)/documents/passlist/$(email))
}
/**
* Return true iff the user's email is in the implicit regex or
* explicit passlist.
*/
function canAccess(email) {
return email.matches(passRegexp()) || isInPassList(email);
}
/**
* Return true iff the user with the given email can read the specified
* survey.
*/
function canViewSurvey(surveyId, email) {
return canAccess(email) && role(surveyId, email) != null;
}
/**
* Return true iff the user with the given email can manage the specified
* survey (i.e., modify the survey document).
*/
function canManageSurvey(surveyId, email) {
return canAccess(email) && role(surveyId, email) in ['owner', 'survey-organizer'];
}
/**
* Return true iff the user with the given email can contribute LOIs
* and submissions to the specified survey (i.e., add/edit LOIs and
* submissions).
*/
function canContributeToSurvey(surveyId, email) {
return canAccess(email) && role(surveyId, email) in ['owner', 'survey-organizer', 'data-collector'];
}
// All users need to be able to read the passlist for rules to work.
match /users/{userId} {
allow read, create, write: if userId == request.auth.uid;
}
// All users need to be able to read the passlist for rules to work.
match /passlist/{email} {
allow read;
}
// Apply survey-level ACLs and passlist to survey documents.
match /surveys/{surveyId} {
allow read: if canViewSurvey(surveyId, email())
allow read, write: if canManageSurvey(surveyId, email())
allow create, read, write: if canAccess(email())
}
// Allow passlisted users to access Terms of Service and other config.
match /config/{id} {
allow read: if canAccess(email())
}
// Apply survey-level ACLs and passlist to LOI documents.
match /surveys/{surveyId}/lois/{loiId} {
allow read: if canViewSurvey(surveyId, email())
allow read, write, create: if canContributeToSurvey(surveyId, email())
}
// Apply survey-level ACLs and passlist to submission documents.
match /surveys/{surveyId}/submissions/{submissionId} {
allow read: if canViewSurvey(surveyId, email())
allow read, write, create: if canContributeToSurvey(surveyId, email())
}
}
}