-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfirestore.rules
More file actions
90 lines (76 loc) · 3.12 KB
/
Copy pathfirestore.rules
File metadata and controls
90 lines (76 loc) · 3.12 KB
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
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// --- Helper Functions ---
function isSignedIn() {
return request.auth != null;
}
function getUserData() {
let u = get(/databases/$(database)/documents/users/$(request.auth.uid));
return u != null ? u.data : null;
}
function hasRole(role) {
return isSignedIn() && getUserData() != null && getUserData().role == role;
}
// --- Colleges Collection ---
match /colleges/{collegeId} {
allow read: if true;
allow write: if hasRole('admin') || hasRole('superadmin');
}
// --- Users Collection ---
match /users/{userId} {
allow read: if true;
allow create: if isSignedIn() && (request.auth.uid == userId);
allow update: if hasRole('admin') || hasRole('superadmin') ||
(request.auth.uid == userId &&
request.resource.data.diff(resource.data).affectedKeys().hasOnly(['xp', 'uploads', 'downloads', 'notesCount', 'name', 'avatar', 'views_activity']));
allow delete: if hasRole('admin') || hasRole('superadmin');
}
// --- Consolidated Notes Collection ---
match /notes/{noteId} {
// Access Rule: Public read for approved/verified, or signed in users
allow read: if true; // Everyone can see counts/metadata
// Creation Rule: Signed in users can upload
allow create: if isSignedIn();
// Update Rule: Allow anyone to increment stats, full edit for admins/uploader
allow update: if hasRole('admin') || hasRole('superadmin') ||
(hasRole('coadmin') && getUserData().collegeId == resource.data.collegeId) ||
(isSignedIn() && resource.data.uploadedBy == request.auth.uid) ||
(request.resource.data.diff(resource.data).affectedKeys().hasOnly(['views', 'downloads', 'likes', 'lastViewed', 'dislikes']));
allow delete: if hasRole('admin') || hasRole('superadmin') || (isSignedIn() && resource.data.uploadedBy == request.auth.uid);
// --- Engagement Subcollections ---
match /likes/{userId} {
allow read: if true;
allow write: if isSignedIn() && request.auth.uid == userId;
}
match /dislikes/{userId} {
allow read: if true;
allow write: if isSignedIn() && request.auth.uid == userId;
}
match /engagement/{userId} {
allow read: if true;
allow write: if isSignedIn() && request.auth.uid == userId;
}
}
// --- Role Invites ---
match /role_invites/{emailId} {
allow read, delete: if isSignedIn();
allow write: if hasRole('admin') || hasRole('superadmin');
}
// --- Analytics (Global Standard) ---
match /analytics/{docId} {
allow read: if true;
allow write: if true;
}
// --- Presence ---
match /presence/{userId} {
allow read: if true;
allow write: if isSignedIn() && request.auth.uid == userId;
}
// --- Legacy / Safety ---
match /college_admins/{collegeId} {
allow read: if true;
allow write: if hasRole('admin') || hasRole('superadmin');
}
}
}