Skip to content

Commit

Permalink
Fix for SuperAdmin and move image resize to the frontend (#1637)
Browse files Browse the repository at this point in the history
* Fixes for SuperAdmin rules and permissions & error management

* Fixes for SuperAdmin rules and permissions & error management

* Update lighthouse-ci.yml

* Maybe fix build?

* Maybe fix test?

* Change upload image to resize in the client and update storage rules

* Add new storage rules and change max upload size to 10k x 10k px

* Fixup remove file and no more need for a function

* Fixup storage rules for orgs

* Update translation
  • Loading branch information
HugoGresse authored Nov 8, 2024
1 parent 90800fa commit 6c6d8fa
Show file tree
Hide file tree
Showing 28 changed files with 1,662 additions and 3,077 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
npm run build
- name: run lighthouse ci
run: |
npm install -g @lhci/cli@0.3.x
npm install -g @lhci/cli@0.14.x
lhci autorun --config=./lighthouse/lighthouserc.json
env:
LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_GITHUB_APP_TOKEN }}
12 changes: 11 additions & 1 deletion config/firestore.rules
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ service cloud.firestore {
}

match /userVotes/{ref} {
allow read: if authenticated() && resource.data.userId == request.auth.uid || isAdmin(projectData(projectId)) || isAnOrgViewer(getOrganization(projectData(projectId).organizationId));
allow read: if authenticated() && isSuperAdmin(request.auth.uid) || resource.data.userId == request.auth.uid || isAdmin(projectData(projectId)) || isAnOrgViewer(getOrganization(projectData(projectId).organizationId));
allow create: if authenticated() && request.resource.data.userId == request.auth.uid;
allow update: if authenticated() && resource.data.userId == request.auth.uid || isAdmin(projectData(projectId));
allow delete: if authenticated() && (isAdmin(projectData(projectId)) || isAnOrgAdmin(getOrganization(projectData(projectId).organizationId))) && (isEmailVerified() || isPhoneNumberAccount());
Expand Down Expand Up @@ -101,5 +101,15 @@ service cloud.firestore {
allow update: if authenticated() && ((isAnOrgAdmin(resource.data) && request.resource.data.ownerUserId == resource.data.ownerUserId) || isOrgOwner(resource.data) );
allow delete: if authenticated() && isOrgOwner(resource.data);
}

// SUPER ADMIN

match /admins/users/admins/{userId} {
allow get: if authenticated() && isSuperAdmin(request.auth.uid);
allow list: if false;
allow create: if false;
allow update: if false;
allow delete: if false;
}
}
}
22 changes: 22 additions & 0 deletions config/firestore.rules.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,12 @@ const getProject = (app, projectId) => {
return app.collection('projects').doc(projectId).get()
}

const createSuperAdmin = async (app, userId) => {
return app.collection('admins/users/admins').doc(userId).set({
admin: true,
})
}

const addFullDataToProject = async (app, projectId, userId) => {
const speakerRef = await app
.collection('projects')
Expand Down Expand Up @@ -1062,6 +1068,22 @@ describe('Firestore rules', () => {

await firebase.assertFails(listOrg)
})
it('cannot get or create a super admin', async () => {
const app = createApp(UID_ADMIN)

createProject(app, 'First project', UID_VIEWER)
createProject(app, 'Second project with another user', UID_EDITOR)

const superAdminCreationRequest = createSuperAdmin(app, UID_ADMIN)
await firebase.assertFails(superAdminCreationRequest)

const readSuperAdmin = app
.collection('admins/users/admins')
.doc(UID_ADMIN)
.get()

await firebase.assertFails(readSuperAdmin)
})

// Note: cannot do more test as I cannot add super user with the regular app :/
})
Expand Down
29 changes: 28 additions & 1 deletion config/storage.rules
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@ rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {

// Projects
function projectData(projectId) { return firestore.get(/databases/(default)/documents/projects/$(projectId)).data; }
function isAdmin(data) { return data.owner == request.auth.uid || request.auth.uid in data.members;}

// org
function getOrganization(organizationId) { return firestore.get(/databases/(default)/documents/organizations/$(organizationId)).data; }
function isAnOrgEditor(organization) { return request.auth.uid in organization.editorUserIds; }
function isAnOrgAdmin(organization) { return request.auth.uid in organization.adminUserIds; }


match /users/{userId}/{imageId} {
allow read: if true;
allow write: if request.auth != null
Expand All @@ -12,7 +22,24 @@ service firebase.storage {

match /projects/{projectId}/{imageId} {
allow read: if true;
allow write: if false;
allow write: if request.auth != null
&& (
isAdmin(projectData(projectId))
|| isAnOrgEditor(getOrganization(projectData(projectId).organizationId))
|| isAnOrgAdmin(getOrganization(projectData(projectId).organizationId))
)
&& request.resource.size < 5 * 1024 * 1024
&& request.resource.contentType.matches('image/.*');
}
match /organizations/{organizationId}/{imageId} {
allow read: if true;
allow write: if request.auth != null
&& (
isAnOrgEditor(getOrganization(organizationId))
|| isAnOrgAdmin(getOrganization(organizationId))
)
&& request.resource.size < 5 * 1024 * 1024
&& request.resource.contentType.matches('image/.*');
}

}
Expand Down
Loading

0 comments on commit 6c6d8fa

Please sign in to comment.