-
Notifications
You must be signed in to change notification settings - Fork 11k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Allow granting the mobile-upload-file
permission to guests
#34191
base: develop
Are you sure you want to change the base?
Changes from all commits
b6b3eac
a67238a
20a1eb4
6652357
3a5ede9
4787671
73d7ead
84cf7bd
7ff90bc
4fe4ee0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"@rocket.chat/meteor": minor | ||
--- | ||
|
||
Allows granting the `mobile-upload-file` permission to guests |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
import { License } from '@rocket.chat/core-services'; | ||
import type { ServerMethods } from '@rocket.chat/ddp-client'; | ||
import { Permissions } from '@rocket.chat/models'; | ||
import { Meteor } from 'meteor/meteor'; | ||
|
@@ -15,6 +16,10 @@ declare module '@rocket.chat/ddp-client' { | |
|
||
Meteor.methods<ServerMethods>({ | ||
async 'authorization:addPermissionToRole'(permissionId, role) { | ||
if (role === 'guest' && !AuthorizationUtils.hasRestrictionsToRole(role) && (await License.hasValidLicense())) { | ||
AuthorizationUtils.addRolePermissionWhiteList(role, await License.getGuestPermissions()); | ||
} | ||
Comment on lines
+19
to
+21
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For some reason EE tests were failing on CI because we didn't have any restrictions stored for the guest role (which didn't happen locally) 🤷♂️ so I went through all of the places where we populate such restrictions and couldn't find anything off, please tell me if you do |
||
|
||
if (AuthorizationUtils.isPermissionRestrictedForRole(permissionId, role)) { | ||
throw new Meteor.Error('error-action-not-allowed', 'Permission is restricted', { | ||
method: 'authorization:addPermissionToRole', | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
// This list is currently duplicated on the client code as there's no available API to load it from the server | ||
export const guestPermissions = ['view-d-room', 'view-joined-room', 'view-p-room', 'start-discussion']; | ||
export const guestPermissions = ['view-d-room', 'view-joined-room', 'view-p-room', 'start-discussion', 'mobile-upload-file']; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
import { expect } from 'chai'; | ||
import { before, describe, it, after } from 'mocha'; | ||
|
||
import { getCredentials, api, request, credentials, methodCall } from '../../data/api-data'; | ||
import { restorePermissionToRoles } from '../../data/permissions.helper'; | ||
import { IS_EE } from '../../e2e/config/constants'; | ||
|
||
(IS_EE ? describe : describe.skip)('[Guest Permissions]', () => { | ||
const guestPermissions = ['view-d-room', 'view-joined-room', 'view-p-room', 'start-discussion', 'mobile-upload-file']; | ||
|
||
before((done) => getCredentials(done)); | ||
|
||
after(() => Promise.all(guestPermissions.map((permissionName) => restorePermissionToRoles(permissionName)))); | ||
|
||
function succeedRemoveGuestPermission(permissionName: string) { | ||
it(`should allow removing the whitelisted permission ${permissionName} from the guest role`, async () => { | ||
const res = await request | ||
.post(methodCall('authorization:removeRoleFromPermission')) | ||
.set(credentials) | ||
.send({ | ||
message: JSON.stringify({ | ||
method: 'authorization:removeRoleFromPermission', | ||
params: [permissionName, 'guest'], | ||
id: 'id', | ||
msg: 'method', | ||
}), | ||
}) | ||
.expect('Content-Type', 'application/json') | ||
.expect(200); | ||
|
||
expect(res.body).to.have.property('success', true); | ||
expect(res.body).to.have.property('message'); | ||
const message = JSON.parse(res.body.message); | ||
expect(message).to.not.have.property('error'); | ||
|
||
const permissionsListRes = await request | ||
.get(api('permissions.listAll')) | ||
.set(credentials) | ||
.expect('Content-Type', 'application/json') | ||
.expect(200); | ||
expect(permissionsListRes.body).to.have.property('success', true); | ||
expect(permissionsListRes.body).to.have.property('update').and.to.be.an('array'); | ||
expect(permissionsListRes.body).to.have.property('remove').and.to.be.an('array'); | ||
|
||
const updatedPermission = permissionsListRes.body.update.find((permission: any) => permission._id === permissionName); | ||
expect(updatedPermission).to.have.property('_id', permissionName); | ||
expect(updatedPermission).to.have.property('roles').and.to.be.an('array').that.does.not.include('guest'); | ||
}); | ||
} | ||
|
||
function succeedAddGuestPermission(permissionName: string) { | ||
it(`should allow granting the whitelisted permission ${permissionName} to the guest role`, async () => { | ||
const res = await request | ||
.post(methodCall('authorization:addPermissionToRole')) | ||
.set(credentials) | ||
.send({ | ||
message: JSON.stringify({ | ||
method: 'authorization:addPermissionToRole', | ||
params: [permissionName, 'guest'], | ||
id: 'id', | ||
msg: 'method', | ||
}), | ||
}) | ||
.expect('Content-Type', 'application/json') | ||
.expect(200); | ||
|
||
expect(res.body).to.have.property('success', true); | ||
expect(res.body).to.have.property('message'); | ||
const message = JSON.parse(res.body.message); | ||
expect(message).to.not.have.property('error'); | ||
|
||
const permissionsListRes = await request | ||
.get(api('permissions.listAll')) | ||
.set(credentials) | ||
.expect('Content-Type', 'application/json') | ||
.expect(200); | ||
expect(permissionsListRes.body).to.have.property('success', true); | ||
expect(permissionsListRes.body).to.have.property('update').and.to.be.an('array'); | ||
expect(permissionsListRes.body).to.have.property('remove').and.to.be.an('array'); | ||
|
||
const updatedPermission = permissionsListRes.body.update.find((permission: any) => permission._id === permissionName); | ||
expect(updatedPermission).to.have.property('_id', permissionName); | ||
expect(updatedPermission).to.have.property('roles').and.to.be.an('array').that.includes('guest'); | ||
}); | ||
} | ||
|
||
describe('Default guest roles', () => { | ||
guestPermissions.forEach((permissionName) => { | ||
succeedRemoveGuestPermission(permissionName); | ||
}); | ||
|
||
guestPermissions.forEach((permissionName) => { | ||
succeedAddGuestPermission(permissionName); | ||
}); | ||
|
||
it('should not allow adding a non whitelisted permission to the guest role', async () => { | ||
const res = await request | ||
.post(methodCall('authorization:addPermissionToRole')) | ||
.set(credentials) | ||
.send({ | ||
message: JSON.stringify({ | ||
method: 'authorization:addPermissionToRole', | ||
params: ['create-c', 'guest'], | ||
id: 'id', | ||
msg: 'method', | ||
}), | ||
}) | ||
.expect('Content-Type', 'application/json') | ||
.expect(200); | ||
|
||
expect(res.body).to.have.property('success', true); | ||
expect(res.body).to.have.property('message'); | ||
const message = JSON.parse(res.body.message); | ||
expect(message).to.have.property('error'); | ||
expect(message.error).to.have.property('reason', 'Permission is restricted'); | ||
}); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had to add the
start-discussion
permission to this file so that it could be restored on my new end-to-end tests (withrestorePermissionToRoles
). We're currently inserting this permission somewhere else (onMeteor.startup
) and it was missing herestart-discussion-other-user
is not related to my tests, but I decided to bring this here too since it's created in the sameMeteor.startup
callback (so we avoid one more tech debt)