-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfirestore.rules
152 lines (149 loc) · 6.78 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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
function isAdmin(request) {
return getUser(request.auth.uid).role =='admin';
}
function getUser(id) {
return get(/databases/$(database)/documents/users/$(id)).data;
}
function getOrg(id) {
return get(/databases/$(database)/documents/organizations/$(id)).data;
}
function getApiKey(id) {
return get(/databases/$(database)/documents/api_keys/$(id)).data;
}
// TODO: overall prevent DDOSes by setting "last update" stuff
match /users/{userId} {
// TODO: Maybe more strict
// TODO: how to prevent taking someone else tag?
allow write: if request.auth != null && request.auth.uid == userId &&
// Allow changing everything except credits
(!request.resource.data.diff(resource.data).affectedKeys().hasAny(['credits', 'rateLimits'])); // &&
// If the user try to change lastSignInTime, it has to be within the 20 seconds obviously
//request.time - request.resource.data.get('lastSignInTime', request.time) < duration.value(20, 's');
allow read: if true; // TODO
}
match /recommendations/{recommendationId} {
allow read: if request.auth != null && request.auth.uid == recommendationId;
}
match /preferences/{preferenceId} {
// Currently can only write to own preferences
// But can read others
// TODO: can we restrict to only read on "favoriteTopics"?
allow read: if request.auth != null;
allow update, delete: if request.auth != null && request.auth.uid == preferenceId;
allow create: if request.auth != null;
}
match /{path=**}/tags/{tagId} {
allow read: if request.auth != null;
// Only allows writing feedback tags
allow write: if request.resource.data.feedback.userId == request.auth.uid;
}
match /langames/{langameId} {
// Only allow access to invited Langames
// TODO
// allow read: if request.auth != null && request.auth.uid in resource.data.players;
allow read: if request.auth != null;
allow create: if request.auth != null; // TODO:
}
match /langame_presences/{userId} {
// TODO
allow read: if request.auth != null;
allow create: if request.auth != null;
}
match /topics/{topicId} {
allow read: if request.auth != null;
}
match /feedbacks/{feedbackId} {
allow write: if request.auth != null && request.auth.uid == feedbackId;
}
match /prompts/{promptId} {
allow read, write: if request.auth != null &&
isAdmin(request);
}
match /memes/{memeId} {
allow read, write: if request.auth != null &&
isAdmin(request);
}
match /deleted_memes/{memeId} {
allow read, write: if request.auth != null &&
isAdmin(request);
}
match /messages/{messageId} {
function isRateLimited(request) {
let user = getUser(request.auth.uid);
// Is rate limited? (one second per user)
return "rateLimits" in user && (request.time - duration.value(1, 's')) <= user.rateLimits.message;
}
allow read: if request.auth != null;
allow create: if request.auth != null &&
request.resource.data.keys()
.hasAll([
"type",
"body",
"createdAt",
"langameId",
"author"]) &&
// Clients can only send messages of type "text"
request.resource.data.type == 1 &&
!isRateLimited(request);
}
match /apis/{apiId} {
allow read: if request.auth != null;
}
match /organizations/{organizationId} {
// Can read organizations which I am member of
allow read: if isAdmin(request) ||
(request.auth != null &&
request.auth.uid in resource.data.members);
allow update: if request.auth != null &&
request.auth.uid in resource.data.members &&
// The member "membersRole" is "owner"
resource.data.membersRole[request.auth.uid] == "owner";
// Can create organizations if adding oneself in the members
allow create: if request.auth != null &&
// just in case (discord auth...)
get(/databases/$(database)/documents/users/$(request.auth.uid)).data != null &&
request.resource.data.keys().hasAll(['members', 'membersRole', 'name']) &&
// request.auth.uid contained in members
request.auth.uid in request.resource.data.members;
}
match /api_keys/{apiKeyId} {
// Can only read API keys where "owner" is an organization
// where I am member
allow read: if request.auth != null &&
request.auth.uid in getOrg(resource.data.owner).members;
allow create: if request.auth != null &&
request.auth.uid in getOrg(request.resource.data.owner).members;
// TODO: max 10 keys smthing
// Can only delete API keys if I am the owner of the organization
allow delete: if request.auth != null &&
request.auth.uid in getOrg(resource.data.owner).members &&
getOrg(resource.data.owner).membersRole[request.auth.uid] == "owner";
}
match /usages/{usageId} {
allow read: if request.auth != null &&
request.auth.uid in getOrg(getApiKey(usageId).owner).members ||
request.auth != null && isAdmin(request);
}
match /social_interactions/{socialInteractionsId} {
allow read: if request.auth != null && isAdmin(request);
}
match /configs/{configId} {
allow read: if request.auth != null && isAdmin(request);
allow write: if request.auth != null;
// allow write: if request.auth.uid in getOrg(resource.data.guild_id).members
}
match /discord_users/{discordUserId} {
allow read: if request.auth != null && isAdmin(request);
}
match /conversations/{discordUserId} {
allow write: if request.auth != null && isAdmin(request);
allow read: if request.auth != null;
}
match /saved_conversations/{conversationId} {
allow read: if request.auth != null;
}
}
}