3 var proxyquireNoCallThru = require('proxyquire').noCallThru();
4 var assert = require('assert');
5 const sinon = require('sinon');
6 const mongoUtils = require('gitter-web-persistence-utils/lib/mongo-utils');
7 var fixtureLoader = require('gitter-web-test-utils/lib/test-fixtures');
8 var Promise = require('bluebird');
9 var StatusError = require('statuserror');
10 var persistence = require('gitter-web-persistence');
11 var RoomWithPolicyService = require('../lib/room-with-policy-service');
12 const roomService = require('../lib/room-service');
13 const troupeService = require('gitter-web-rooms/lib/troupe-service');
14 const policyFactory = require('gitter-web-permissions/lib/policy-factory');
16 describe('room-with-policy-service', function() {
17 var fixture = fixtureLoader.setup({
25 troupeWithReservedTags: {
26 tags: ['foo:bar', 'foo']
31 users: ['userBan', 'userBanAdmin']
36 users: ['userBan', 'userBanAdmin']
44 canAdmin: function() {
45 return Promise.resolve(true);
48 return Promise.resolve(true);
52 var notAdminPolicy = {
53 canAdmin: function() {
54 return Promise.resolve(false);
58 const canWritePolicy = {
59 canWrite: async () => {
64 describe('updateTags #slow', function() {
65 it('should update tags', function() {
66 var rawTags = 'js, open source, looooooooooooooooooooooooooooongtag,,,,';
67 var cleanTags = ['js', 'open source', 'looooooooooooooooooo'];
68 var r = new RoomWithPolicyService(fixture.troupe1, fixture.user1, isAdminPolicy);
69 return r.updateTags(rawTags).then(function(troupe) {
70 assert.deepEqual(troupe.tags.toObject(), cleanTags);
74 it('should not save reserved-word tags(colons) with normal-user', function() {
75 var rawTags = 'hey, foo:bar, there';
76 var cleanTags = ['hey', 'there'];
78 var r = new RoomWithPolicyService(fixture.troupe1, fixture.user1, isAdminPolicy);
79 return r.updateTags(rawTags).then(function(troupe) {
80 assert.deepEqual(troupe.tags.toObject(), cleanTags);
84 it('should deny a non-admin', function() {
85 var rawTags = 'hey, foo:bar, there';
87 var r = new RoomWithPolicyService(fixture.troupe1, fixture.user1, notAdminPolicy);
93 .catch(StatusError, function(err) {
94 assert.strictEqual(err.status, 403);
98 it('should save reserved-word tags with staff-user', function() {
99 var rawTags = 'hey, foo:bar, there';
100 var cleanTags = ['hey', 'foo:bar', 'there'];
102 var r = new RoomWithPolicyService(fixture.troupe1, fixture.userStaff, notAdminPolicy);
103 return r.updateTags(rawTags).then(function(troupe) {
104 assert.deepEqual(troupe.tags.toObject(), cleanTags);
108 it('should retain reserved-word tags with normal-user', function() {
109 var fixtureTags = 'foo:bar, foo';
110 var userTags = 'hey, there';
111 var userActualTags = ['hey', 'there', 'foo:bar'];
113 var r1 = new RoomWithPolicyService(
114 fixture.troupeWithReservedTags,
118 var r2 = new RoomWithPolicyService(
119 fixture.troupeWithReservedTags,
125 .updateTags(fixtureTags)
127 return r2.updateTags(userTags);
129 .then(function(troupe) {
130 assert.deepEqual(troupe.tags.toObject(), userActualTags);
135 describe('bans #slow', function() {
136 it('should ban users from rooms #slow', function() {
137 var roomMembershipService = require('../lib/room-membership-service');
139 var r = new RoomWithPolicyService(fixture.troupeBan, fixture.userBanAdmin, isAdminPolicy);
142 .findBanByUsername(fixture.troupeBan._id, fixture.userBan.username)
143 .then(function(banned) {
147 .banUserFromRoom(fixture.userBan.username, {})
148 .then(function(ban) {
149 assert.equal(ban.userId, fixture.userBan.id);
150 assert.equal(ban.bannedBy, fixture.userBanAdmin.id);
151 assert(ban.dateBanned);
153 return roomMembershipService.checkRoomMembership(
154 fixture.troupeBan._id,
158 .then(function(bannedUserIsInRoom) {
159 assert(!bannedUserIsInRoom);
161 return roomService.findBanByUsername(fixture.troupeBan.id, fixture.userBan.username);
163 .then(function(ban) {
168 .findBanByUsername(fixture.troupeBan._id, fixture.userBan.username)
169 .then(function(banned) {
172 return r.unbanUserFromRoom(ban.userId).then(function() {
174 .findBanByUsername(fixture.troupeBan._id, fixture.userBan.username)
175 .then(function(banned) {
178 return roomService.findBanByUsername(
179 fixture.troupeBan.id,
180 fixture.userBan.username
183 .then(function(ban) {
192 it('should not allow admins to be banned', function() {
193 var RoomWithPolicyService = proxyquireNoCallThru('../lib/room-with-policy-service', {
194 'gitter-web-permissions/lib/policy-factory': {
195 createPolicyForRoom: function(user, room) {
196 assert.strictEqual(user.id, fixture.userBan.id);
197 assert.strictEqual(room.id, fixture.troupeBan2.id);
198 return Promise.resolve({
199 canAdmin: function() {
200 return Promise.resolve(true);
207 var r = new RoomWithPolicyService(fixture.troupeBan2, fixture.userBanAdmin, isAdminPolicy);
210 .banUserFromRoom(fixture.userBan.username, {})
212 assert(false, 'Expected to fail as banned user is an admin');
214 .catch(StatusError, function(err) {
215 assert.equal(err.status, 403);
219 it('should not allow non-admins to ban', function() {
220 var r = new RoomWithPolicyService(fixture.troupeBan2, fixture.userBanAdmin, notAdminPolicy);
223 .banUserFromRoom(fixture.userBan.username, {})
225 assert(false, 'Expected to fail');
227 .catch(StatusError, function(err) {
228 assert.equal(err.status, 403);
233 describe('virtualUser bans #slow', () => {
234 describe('banVirtualUserFromRoom', () => {
235 const virtualUserBanfixtures = fixtureLoader.setup({
239 troupeWithBannedVirtualUsers1: {
244 externalId: 'banned-user:matrix.org'
246 dateBanned: new Date('1995-12-17T03:24:00+00:00'),
247 bannedBy: 'userBanAdmin'
253 it('should not allow non-admins to ban', async () => {
254 const roomWithPolicyService = new RoomWithPolicyService(
255 virtualUserBanfixtures.troupe1,
256 virtualUserBanfixtures.user1,
261 await roomWithPolicyService.banVirtualUserFromRoom({
263 externalId: 'bad-guy:matrix.org'
265 assert(false, 'Expected to fail');
267 assert.equal(err.status, 403);
271 it('bans virtualUser', async () => {
272 const roomWithPolicyService = new RoomWithPolicyService(
273 virtualUserBanfixtures.troupe1,
274 virtualUserBanfixtures.userBanAdmin,
278 const ban = await roomWithPolicyService.banVirtualUserFromRoom({
280 externalId: 'bad-guy:matrix.org'
283 assert.strictEqual(ban.userId, undefined);
284 assert.strictEqual(ban.virtualUser.type, 'matrix');
285 assert.strictEqual(ban.virtualUser.externalId, 'bad-guy:matrix.org');
287 mongoUtils.objectIDsEqual(ban.bannedBy, virtualUserBanfixtures.userBanAdmin._id),
292 it('unable to ban virtualUser with invalid properties', async () => {
293 const roomWithPolicyService = new RoomWithPolicyService(
294 virtualUserBanfixtures.troupe1,
295 virtualUserBanfixtures.userBanAdmin,
300 await roomWithPolicyService.banVirtualUserFromRoom({
302 // This is invalid because the max length is 255
303 externalId: 'x'.repeat(1000)
305 assert(false, 'Expected to fail');
307 assert.equal(err.status, 400);
311 it('returns existing ban', async () => {
312 const roomWithPolicyService = new RoomWithPolicyService(
313 virtualUserBanfixtures.troupeWithBannedVirtualUsers1,
314 virtualUserBanfixtures.userBanAdmin,
318 const ban = await roomWithPolicyService.banVirtualUserFromRoom({
320 externalId: 'banned-user:matrix.org'
323 assert.strictEqual(ban.dateBanned.toISOString(), '1995-12-17T03:24:00.000Z');
326 it('removes messages when option passed', async () => {
327 const removeAllMessagesForVirtualUserInRoomIdStub = sinon.stub();
328 const stubbedRoomWithPolicyService = proxyquireNoCallThru(
329 '../lib/room-with-policy-service',
331 'gitter-web-chats': {
332 removeAllMessagesForVirtualUserInRoomId: removeAllMessagesForVirtualUserInRoomIdStub
337 const roomWithPolicyService = new stubbedRoomWithPolicyService(
338 virtualUserBanfixtures.troupe1,
339 virtualUserBanfixtures.userBanAdmin,
343 await roomWithPolicyService.banVirtualUserFromRoom(
346 externalId: 'spammer:matrix.org'
353 assert(removeAllMessagesForVirtualUserInRoomIdStub.calledOnce);
357 describe('unbanVirtualUserFromRoom', () => {
358 const virtualUserBanfixtures = fixtureLoader.setup({
361 troupeWithBannedVirtualUsers1: {
366 externalId: 'banned-user:matrix.org'
368 dateBanned: new Date('1995-12-17T03:24:00+00:00'),
369 bannedBy: 'userBanAdmin'
375 it('should not allow non-admins to unban', async () => {
376 const roomWithPolicyService = new RoomWithPolicyService(
377 virtualUserBanfixtures.troupeWithBannedVirtualUsers1,
378 virtualUserBanfixtures.user1,
383 await roomWithPolicyService.unbanVirtualUserFromRoom({
385 externalId: 'banned-user:matrix.org'
387 assert(false, 'Expected to fail');
389 assert.equal(err.status, 403);
393 it('unbans user', async () => {
394 const roomWithPolicyService = new RoomWithPolicyService(
395 virtualUserBanfixtures.troupeWithBannedVirtualUsers1,
396 virtualUserBanfixtures.userBanAdmin,
400 await roomWithPolicyService.unbanVirtualUserFromRoom({
402 externalId: 'banned-user:matrix.org'
405 const updatedRoom = await troupeService.findById(
406 virtualUserBanfixtures.troupeWithBannedVirtualUsers1._id
408 assert.strictEqual(updatedRoom.bans.length, 0);
413 describe('meta', function() {
414 it('should allow you to set a welcome message', async function() {
415 const welcomeMessageText = 'this is a test';
416 const r = new RoomWithPolicyService(fixture.troupe1, fixture.user1, isAdminPolicy);
417 await r.updateRoomMeta({ welcomeMessage: welcomeMessageText });
419 const { welcomeMessage } = await r.getMeta();
420 assert(welcomeMessage.text);
421 assert(welcomeMessage.html);
422 assert.equal(welcomeMessage.text, welcomeMessageText);
425 it('should retrieve room metadata', async () => {
426 const r = new RoomWithPolicyService(fixture.troupe1, fixture.user1, isAdminPolicy);
427 await r.updateRoomMeta({ welcomeMessage: 'hello' });
428 const result = await r.getMeta();
429 assert.deepStrictEqual(result, {
430 welcomeMessage: { text: 'hello', html: 'hello' }
435 describe('delete room', function() {
436 it('should allow an admin to delete a room', function() {
437 var r = new RoomWithPolicyService(fixture.troupeForDeletion, fixture.user1, isAdminPolicy);
438 return r.deleteRoom().then(function() {
439 return persistence.Troupe.findById(fixture.troupeForDeletion._id).then(function(troupe) {
445 it('should not allow a non-admin to delete a room', function() {
446 var r = new RoomWithPolicyService(fixture.troupeForDeletion, fixture.user1, notAdminPolicy);
447 return r.deleteRoom().catch(StatusError, function(err) {
448 assert.equal(err.status, 403);
453 describe('sendMessage', () => {
454 const banFixtures = fixtureLoader.setup({
458 troupeWithBannedUsers1: {
462 dateBanned: Date.now(),
463 bannedBy: 'userAdmin1'
467 troupeWithBannedVirtualUsers1: {
472 externalId: 'banned-user:matrix.org'
474 dateBanned: Date.now(),
475 bannedBy: 'userAdmin1'
481 it('normal user can send message', async () => {
482 const roomWithPolicyService = new RoomWithPolicyService(
488 const chatMessage = await roomWithPolicyService.sendMessage({ text: 'heya' });
493 it('virtualUser can send message', async () => {
494 const roomWithPolicyService = new RoomWithPolicyService(
500 const chatMessage = await roomWithPolicyService.sendMessage({
504 externalId: 'test-person:matrix.org',
510 assert(chatMessage.virtualUser);
513 it('banned user can not send message', async () => {
514 const policy = await policyFactory.createPolicyForRoomId(
515 banFixtures.userBanned1,
516 banFixtures.troupeWithBannedUsers1._id
519 const roomWithPolicyService = new RoomWithPolicyService(
520 banFixtures.troupeWithBannedUsers1,
521 banFixtures.userBanned1,
526 await roomWithPolicyService.sendMessage({
529 assert(false, 'Expected to fail');
531 assert.equal(err.status, 403);
535 it('banned virtualUser can not send message', async () => {
536 const policy = await policyFactory.createPolicyForRoomId(
537 banFixtures.userBanned1,
538 banFixtures.troupeWithBannedVirtualUsers1._id
541 const roomWithPolicyService = new RoomWithPolicyService(
542 banFixtures.troupeWithBannedVirtualUsers1,
543 banFixtures.userBridge1,
548 await roomWithPolicyService.sendMessage({
552 externalId: 'banned-user:matrix.org'
555 assert(false, 'Expected to fail');
557 assert.equal(err.status, 403);
562 describe('editMessage', () => {
563 const editFixtures = fixtureLoader.setup({
569 troupeWithBannedUsers1: {
573 dateBanned: Date.now(),
574 bannedBy: 'userAdmin1'
578 troupeWithBannedVirtualUsers1: {
583 externalId: 'banned-user:matrix.org'
585 dateBanned: Date.now(),
586 bannedBy: 'userAdmin1'
595 messageFromVirtualUser1: {
599 externalId: 'test-person:matrix.org',
605 messageFromBannedUser1: {
607 troupe: 'troupeWithBannedUsers1',
610 messageFromBannedVirtualUser1: {
614 externalId: 'banned-user:matrix.org',
615 displayName: 'bad-person'
617 troupe: 'troupeWithBannedVirtualUsers1',
622 it('normal user can edit message', async () => {
623 const roomWithPolicyService = new RoomWithPolicyService(
624 editFixtures.troupe1,
629 const chatMessage = await roomWithPolicyService.editMessage(editFixtures.message1, 'heya');
632 assert.strictEqual(chatMessage.text, 'heya');
635 it('admin user not allowed edit another users message', async () => {
636 const roomWithPolicyService = new RoomWithPolicyService(
637 editFixtures.troupe1,
638 editFixtures.userAdmin1,
643 await roomWithPolicyService.editMessage(editFixtures.message1, 'heya');
644 assert(false, 'Expected to fail');
646 assert.equal(err.status, 403);
650 it('virtualUser can edit message', async () => {
651 const roomWithPolicyService = new RoomWithPolicyService(
652 editFixtures.troupe1,
653 editFixtures.userBridge1,
657 const chatMessage = await roomWithPolicyService.editMessage(
658 editFixtures.messageFromVirtualUser1,
663 assert(chatMessage.virtualUser);
664 assert.strictEqual(chatMessage.text, 'aliens');
667 it('banned user can not edit message', async () => {
668 const policy = await policyFactory.createPolicyForRoomId(
669 editFixtures.userBanned1,
670 editFixtures.troupeWithBannedUsers1._id
673 const roomWithPolicyService = new RoomWithPolicyService(
674 editFixtures.troupeWithBannedUsers1,
675 editFixtures.userBanned1,
680 await roomWithPolicyService.editMessage(editFixtures.messageFromBannedUser1, 'heya');
681 assert(false, 'Expected to fail');
683 assert.equal(err.status, 403);
687 it('banned virtualUser can not edit message', async () => {
688 const policy = await policyFactory.createPolicyForRoomId(
689 editFixtures.userBanned1,
690 editFixtures.troupeWithBannedVirtualUsers1._id
693 const roomWithPolicyService = new RoomWithPolicyService(
694 editFixtures.troupeWithBannedVirtualUsers1,
695 editFixtures.userBridge1,
700 await roomWithPolicyService.editMessage(editFixtures.messageFromBannedVirtualUser1, 'heya');
701 assert(false, 'Expected to fail');
703 assert.equal(err.status, 403);
708 describe('deleteMessageFromRoom', () => {
709 const deleteFixtures = fixtureLoader.setup({
724 messageInAnotherRoom1: {
727 text: 'another rooms message'
731 it('sender can delete message', async () => {
732 const roomWithPolicyService = new RoomWithPolicyService(
733 deleteFixtures.troupe1,
734 deleteFixtures.user1,
738 await roomWithPolicyService.deleteMessageFromRoom(deleteFixtures.message1);
743 it('admin can delete message', async () => {
744 const roomWithPolicyService = new RoomWithPolicyService(
745 deleteFixtures.troupe1,
746 deleteFixtures.userAdmin1,
750 await roomWithPolicyService.deleteMessageFromRoom(deleteFixtures.message2);
755 it('room admin can not delete message from another room', async () => {
756 const roomWithPolicyService = new RoomWithPolicyService(
757 deleteFixtures.troupe1,
758 deleteFixtures.userAdmin1,
763 await roomWithPolicyService.deleteMessageFromRoom(deleteFixtures.messageInAnotherRoom1);
764 assert(false, 'Expected to fail');
766 assert.equal(err.status, 404);