Created
August 4, 2021 17:08
-
-
Save pfiadDi/bb9e362db3c40ebccd0396af01bb5598 to your computer and use it in GitHub Desktop.
Firestore Advanced Security Rules
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
rules_version = '2'; | |
service cloud.firestore { | |
match /databases/{database}/documents { | |
function isAuthenticated() { | |
return request.auth != null; | |
} | |
function isDefined(field) { | |
return field in request.resource.data | |
} | |
function val(field) { | |
return request.resource.data[field]; | |
} | |
function isString(field) { | |
return string(val(field)) == val(field); | |
} | |
function isInt(field) { | |
return int(val(field)) == val(field); | |
} | |
function isIntWithValue(value) { | |
return int(value) == value; | |
} | |
function hasTimestampKeys(field) { | |
return request.resource.data[field].keys().hasOnly(['nanoseconds','seconds']) | |
} | |
function isTimestamp(field) { | |
return correctSizeField(2, field) && hasTimestampKeys(field) && isIntWithValue(request.resource.data[field].seconds) && isIntWithValue(request.resource.data[field].nanoseconds) | |
} | |
function isCreatingStatusObject(field) { | |
return isNotCreatingStatusError(field) || isCreatingStatusError(field); | |
} | |
function isNotCreatingStatusError(field) { | |
return correctSizeField(1, field) && request.resource.data[field].keys().hasOnly(['status']) && isCreatingStatus(request.resource.data[field].status) | |
} | |
function isCreatingStatusError(field) { | |
return correctSizeField(2, field) && request.resource.data[field].keys().hasOnly(['status','error']) && isCreatingStatus(request.resource.data[field]['status']) | |
} | |
function isValidAuthUid() { | |
return request.auth.uid == request.resource.data.uid; | |
} | |
function correctSize(no) { | |
return request.resource.data.size() == no; | |
} | |
function correctSizeField(no,field) { | |
return request.resource.data[field].size() == no; | |
} | |
function isCreatingStatus(value) { | |
return value in ['Drafting','Request','Success','CreatingFailed']; | |
} | |
function isCorrectStatus(value) { | |
return value in ['Draft','Active','Paused','Ended']; | |
} | |
function isCorrectPhrasing(value) { | |
return value in ['WithoutArticle','FemaleArticle','MaleArticle','NoneChosen']; | |
} | |
function isOwner(uid) { | |
return uid in request.resource.data.owners; | |
} | |
function isOwnerUpdate(uid) { | |
return uid in resource.data.owners; | |
} | |
function onlyAllowedFields() { | |
return request.resource.data.keys().hasOnly(['name','status','participants','endDate','startDate','companyName','owners', 'phrasing','creatingStatus']) | |
} | |
match /surveys/{surveyId} { | |
allow create: if isAuthenticated() && isDefined('name') && isString('name') && isDefined('status') && isDefined('participants') && isInt('participants') && isDefined('endDate') && isTimestamp('endDate') && isDefined('startDate') && isTimestamp('startDate') && isDefined('companyName') && isString('companyName') && isDefined('status') && isCorrectStatus(val('status')) && isDefined('owners') && isOwner(request.auth.uid) && onlyAllowedFields() && isDefined('phrasing') && isCorrectPhrasing(val('phrasing')) && isDefined('creatingStatus') && isCreatingStatusObject('creatingStatus'); | |
allow update: if isAuthenticated() && isDefined('name') && isString('name') && isDefined('status') && isDefined('participants') && isInt('participants') && isDefined('endDate') && isTimestamp('endDate') && isDefined('startDate') && isTimestamp('startDate') && isDefined('companyName') && isString('companyName') && isDefined('status') && isCorrectStatus(val('status')) && isDefined('owners') && isOwnerUpdate(request.auth.uid) && onlyAllowedFields() && isDefined('phrasing') && isCorrectPhrasing(val('phrasing')) && isDefined('creatingStatus') && isCreatingStatusObject('creatingStatus'); | |
allow read: if isAuthenticated(); | |
} | |
match /surveys/{surveyId}/reports/{reportId} { | |
allow write: if false; | |
allow read: if isAuthenticated(); | |
} | |
match /surveys/{surveyId}/introduction/{introductionId} { | |
allow write: if false; | |
allow read: if isAuthenticated(); | |
} | |
match /surveys/{surveyId}/traits/{traitsId} { | |
allow write: if false; | |
allow read: if isAuthenticated(); | |
} | |
match /surveys/{surveyId}/end/{endId} { | |
allow write: if false; | |
allow read: if isAuthenticated(); | |
} | |
match /surveys/{surveyId}/answers/{answerId} { | |
function surveyData() { | |
return get(/databases/$(database)/documents/surveys/$(surveyId)).data; | |
} | |
function isActive() { | |
return request.time >= surveyData().startDate && request.time <= surveyData().endDate | |
} | |
allow create: if isAuthenticated() && isValidAuthUid() && isDefined('uid') && isString('uid') && correctSize(6) && (request.time >= get(/databases/$(database)/documents/surveys/$(surveyId)).data.startDate && request.time <= get(/databases/$(database)/documents/surveys/$(surveyId)).data.endDate); | |
allow update: if false; | |
allow read: if isAuthenticated(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment