Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions apps/meteor/app/slashcommands-archiveroom/server/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ import { isRegisterUser } from '@rocket.chat/core-typings';
import { Users, Rooms } from '@rocket.chat/models';
import { Meteor } from 'meteor/meteor';

import { RoomMemberActions } from '../../../definition/IRoomTypeConfig';
import { i18n } from '../../../server/lib/i18n';
import { roomCoordinator } from '../../../server/lib/rooms/roomCoordinator';
import { hasPermissionAsync } from '../../authorization/server/functions/hasPermission';
import { archiveRoom } from '../../lib/server/functions/archiveRoom';
import { settings } from '../../settings/server';
import { slashCommands } from '../../utils/lib/slashCommand';
Expand All @@ -25,6 +28,7 @@ slashCommands.add({
channel = channel.replace('#', '');
room = await Rooms.findOneByName(channel);
}

if (!userId) {
return;
}
Expand All @@ -45,9 +49,12 @@ slashCommands.add({
return;
}

// You can not archive direct messages.
if (room.t === 'd') {
return;
if (!(await roomCoordinator.getRoomDirectives(room.t).allowMemberAction(room, RoomMemberActions.ARCHIVE, userId))) {
throw new Meteor.Error('error-direct-message-room', `rooms type: ${room.t} can not be archived`, { method: 'archiveRoom' });
}

if (!(await hasPermissionAsync(userId, 'archive-room', room._id))) {
throw new Meteor.Error('error-not-authorized', 'Not authorized', { method: 'archiveRoom' });
Comment thread
ggazzo marked this conversation as resolved.
Resolved
}

if (room.archived) {
Expand Down
8 changes: 6 additions & 2 deletions apps/meteor/app/slashcommands-unarchiveroom/server/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Meteor } from 'meteor/meteor';
import { RoomMemberActions } from '../../../definition/IRoomTypeConfig';
import { i18n } from '../../../server/lib/i18n';
import { roomCoordinator } from '../../../server/lib/rooms/roomCoordinator';
import { hasPermissionAsync } from '../../authorization/server/functions/hasPermission';
import { unarchiveRoom } from '../../lib/server/functions/unarchiveRoom';
import { settings } from '../../settings/server';
import { slashCommands } from '../../utils/lib/slashCommand';
Expand Down Expand Up @@ -47,9 +48,12 @@ slashCommands.add({
return;
}

// You can not archive direct messages.
if (!(await roomCoordinator.getRoomDirectives(room.t).allowMemberAction(room, RoomMemberActions.ARCHIVE, userId))) {
return;
throw new Meteor.Error('error-direct-message-room', `rooms type: ${room.t} can not be unarchive`, { method: 'unarchiveRoom' });
Comment thread
ggazzo marked this conversation as resolved.
Resolved
}

if (!(await hasPermissionAsync(userId, 'unarchive-room', room._id))) {
throw new Meteor.Error('error-not-authorized', 'Not authorized', { method: 'unarchiveRoom' });
Comment thread
ggazzo marked this conversation as resolved.
Resolved
}

if (!room.archived) {
Expand Down
156 changes: 154 additions & 2 deletions apps/meteor/tests/end-to-end/api/16-commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { before, describe, it } from 'mocha';
import { getCredentials, api, request, credentials } from '../../data/api-data.js';
import { sendSimpleMessage } from '../../data/chat.helper.js';
import { createRoom } from '../../data/rooms.helper.js';
import { password } from '../../data/user';
import { createUser, deleteUser, login } from '../../data/users.helper.js';

describe('[Commands]', function () {
this.retries(0);
Expand Down Expand Up @@ -58,7 +60,7 @@ describe('[Commands]', function () {

describe('[/commands.list]', () => {
it('should return a list of commands', (done) => {
request
void request
.get(api('commands.list'))
.set(credentials)
.expect(200)
Expand All @@ -72,7 +74,7 @@ describe('[Commands]', function () {
.end(done);
});
it('should return a list of commands even requested with count and offset params', (done) => {
request
void request
.get(api('commands.list'))
.set(credentials)
.query({
Expand Down Expand Up @@ -239,4 +241,154 @@ describe('[Commands]', function () {
.end(done);
});
});

describe('Command archive', function () {
describe('unauthorized cases', () => {
let user;
let credentials;

this.beforeAll(async () => {
user = await createUser({
joinDefaultChannels: true,
});
credentials = await login(user.username, password);
});

this.afterAll(async () => {
await deleteUser(user);
});

it('should return an error when the user is not logged in', async () => {
await request
.post(api('commands.run'))
.send({ command: 'archive', roomId: 'GENERAL' })
.expect(401)
.expect((res) => {
expect(res.body).to.have.property('status', 'error');
});
});

it('should return an error when the user has not enough permissions', async () => {
await request
.post(api('commands.run'))
.set(credentials)
.send({
command: 'archive',
roomId: 'GENERAL',
})
.expect('Content-Type', 'application/json')
.expect(400)
.expect((res) => {
expect(res.body).to.have.property('success', false);
expect(res.body).to.have.property('errorType', 'error-not-authorized');
});
});
});

describe('authorized cases', function () {
this.afterAll(async () => {
await request
.post(api('commands.run'))
.set(credentials)
.send({
command: 'unarchive',
roomId: 'GENERAL',
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
});
});

it('should return a success when the user has enough permissions', async () => {
await request
.post(api('commands.run'))
.set(credentials)
.send({
command: 'archive',
roomId: 'GENERAL',
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
});
});
});
});

describe('Command unarchive', function () {
describe('unauthorized cases', () => {
let user;
let credentials;
this.beforeAll(async () => {
user = await createUser({
joinDefaultChannels: true,
});
credentials = await login(user.username, password);
});

this.afterAll(async () => {
await deleteUser(user);
});

it('should return an error when the user is not logged in', async () => {
await request
.post(api('commands.run'))
.send({ command: 'unarchive', roomId: 'GENERAL' })
.expect(401)
.expect((res) => {
expect(res.body).to.have.property('status', 'error');
});
});

it('should return an error when the user has not enough permissions', async () => {
await request
.post(api('commands.run'))
.set(credentials)
.send({
command: 'unarchive',
roomId: 'GENERAL',
})
.expect('Content-Type', 'application/json')
.expect(400)
.expect((res) => {
expect(res.body).to.have.property('success', false);
expect(res.body).to.have.property('errorType', 'error-not-authorized');
});
});
});

describe('authorized cases', () => {
before(async () => {
await request
.post(api('commands.run'))
.set(credentials)
.send({
command: 'archive',
roomId: 'GENERAL',
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
});
});
it('should return a success when the user has enough permissions', async () => {
await request
.post(api('commands.run'))
.set(credentials)
.send({
command: 'unarchive',
roomId: 'GENERAL',
})
.expect('Content-Type', 'application/json')
.expect(200)
.expect((res) => {
expect(res.body).to.have.property('success', true);
});
});
});
});
});