From 1a1ab378da382a73ef746a606590eaac140b50ab Mon Sep 17 00:00:00 2001
From: timkinnane <tim@nestedcode.com>
Date: Sun, 29 Jan 2017 22:44:07 +1100
Subject: [PATCH] Add permissions for adding to each room type

---
 .../server/startup.coffee                     |  5 +--
 .../server/methods/addUserToRoom.coffee       | 32 +++++++++----------
 .../flex-tab/tabs/membersList.coffee          |  5 ++-
 server/startup/migrations/v084.js             |  6 ++--
 4 files changed, 25 insertions(+), 23 deletions(-)

diff --git a/packages/rocketchat-authorization/server/startup.coffee b/packages/rocketchat-authorization/server/startup.coffee
index e4573533e4a..e6430857c8c 100644
--- a/packages/rocketchat-authorization/server/startup.coffee
+++ b/packages/rocketchat-authorization/server/startup.coffee
@@ -7,8 +7,9 @@ Meteor.startup ->
 	permissions = [
 		{ _id: 'access-permissions',            roles : ['admin'] }
 		{ _id: 'add-oauth-service',             roles : ['admin'] }
-		{ _id: 'add-user-to-own-room',          roles : ['admin', 'owner', 'moderator'] }
-		{ _id: 'add-user-to-any-room',          roles : ['admin'] }
+		{ _id: 'add-user-to-joined-room',       roles : ['admin', 'owner', 'moderator'] }
+		{ _id: 'add-user-to-any-c-room',        roles : ['admin'] }
+		{ _id: 'add-user-to-any-p-room',				roles : [] }
 		{ _id: 'archive-room',                  roles : ['admin', 'owner'] }
 		{ _id: 'assign-admin-role',             roles : ['admin'] }
 		{ _id: 'ban-user',                      roles : ['admin', 'owner', 'moderator'] }
diff --git a/packages/rocketchat-lib/server/methods/addUserToRoom.coffee b/packages/rocketchat-lib/server/methods/addUserToRoom.coffee
index a9a7f8317b3..3e7bb459214 100644
--- a/packages/rocketchat-lib/server/methods/addUserToRoom.coffee
+++ b/packages/rocketchat-lib/server/methods/addUserToRoom.coffee
@@ -13,28 +13,26 @@ Meteor.methods
 		userId = Meteor.userId()
 		user = Meteor.user()
 		userInRoom = room.usernames?.indexOf(user.username) >= 0
-		canAddToOwnRoom = RocketChat.authz.hasPermission userId, 'add-user-to-own-room', room._id
-		canAddToAnyRoom = RocketChat.authz.hasPermission userId, 'add-user-to-any-room'
 		newUser = RocketChat.models.Users.findOneByUsername data.username
 
+		if not newUser?._id?
+			throw new Meteor.Error 'error-invalid-user', 'Invalid user', { method: 'addUserToRoom' }
+
+		# Can't add to direct room ever
 		if room.t is 'd'
 			throw new Meteor.Error 'error-cant-invite-for-direct-room', 'Can\'t invite user to direct rooms', { method: 'addUserToRoom' }
 
-		# Can't add to private room if you're not a member
-		if room.t is 'p' and not userInRoom
+		# Can add to any room you're in, with permission - otherwise need specific permission
+		if userInRoom and RocketChat.authz.hasPermission userId, 'add-user-to-joined-room', room._id
+			canAddUser = true
+		else if room.t is 'c' and RocketChat.authz.hasPermission userId, 'add-user-to-any-c-room'
+			canAddUser = true
+		else if room.t is 'p' and RocketChat.authz.hasPermission userId, 'add-user-to-any-p-room'
+			canAddUser = true
+
+		if canAddUser
+			RocketChat.addUserToRoom(data.rid, newUser, user);
+		else
 			throw new Meteor.Error 'error-not-allowed', 'Not allowed', { method: 'addUserToRoom' }
 
-		# Can't add to channels when you're not a member (without higher permissions)
-		if room.t is 'c' and not userInRoom and not canAddToAnyRoom
-			throw new Meteor.Error 'error-not-allowed', 'Not allowed', { method: 'addUserToRoom' }
-
-		# Can't add to channels when you are a member without permission
-		if room.t is 'c' and userInRoom and not canAddToOwnRoom
-			throw new Meteor.Error 'error-not-allowed', 'Not allowed', { method: 'addUserToRoom' }
-
-		if not newUser?._id?
-			throw new Meteor.Error 'error-invalid-user', 'Invalid user', { method: 'addUserToRoom' }
-
-		RocketChat.addUserToRoom(data.rid, newUser, user);
-
 		return true
diff --git a/packages/rocketchat-ui-flextab/flex-tab/tabs/membersList.coffee b/packages/rocketchat-ui-flextab/flex-tab/tabs/membersList.coffee
index 80f082fa254..dc5b0594c7c 100644
--- a/packages/rocketchat-ui-flextab/flex-tab/tabs/membersList.coffee
+++ b/packages/rocketchat-ui-flextab/flex-tab/tabs/membersList.coffee
@@ -62,7 +62,10 @@ Template.membersList.helpers
 	canAddUser: ->
 		roomData = Session.get('roomData' + this._id)
 		return '' unless roomData
-		return roomData.t in ['p', 'c'] and RocketChat.authz.hasAtLeastOnePermission(['add-user-to-any-room', 'add-user-to-own-room'], this._id)
+		return switch roomData.t
+			when 'p' then RocketChat.authz.hasAtLeastOnePermission ['add-user-to-any-p-room', 'add-user-to-own-room'], this._id
+			when 'c' then RocketChat.authz.hasAtLeastOnePermission ['add-user-to-any-c-room', 'add-user-to-own-room'], this._id
+			else false
 
 	autocompleteSettingsAddUser: ->
 		return {
diff --git a/server/startup/migrations/v084.js b/server/startup/migrations/v084.js
index 699a34c3bd4..c731e85c714 100644
--- a/server/startup/migrations/v084.js
+++ b/server/startup/migrations/v084.js
@@ -6,7 +6,7 @@ RocketChat.Migrations.add({
 			// Update permission name, copy values from old name
 			var oldPermission = RocketChat.models.Permissions.findOne('add-user-to-room');
 			if (oldPermission && oldPermission.roles.length) {
-				RocketChat.models.Permissions.upsert({ _id: 'add-user-to-own-room' }, { $set: { roles: oldPermission.roles } });
+				RocketChat.models.Permissions.upsert({ _id: 'add-user-to-joined-room' }, { $set: { roles: oldPermission.roles } });
 				RocketChat.models.Permissions.remove({ _id: 'add-user-to-room' });
 			}
 
@@ -16,10 +16,10 @@ RocketChat.Migrations.add({
 		if (RocketChat && RocketChat.models && RocketChat.models.Permissions) {
 
 			// Revert permission name, copy values from updated name
-			var newPermission = RocketChat.models.Permissions.findOne('add-user-to-own-room');
+			var newPermission = RocketChat.models.Permissions.findOne('add-user-to-joined-room');
 			if (newPermission && newPermission.roles.length) {
 				RocketChat.models.Permissions.upsert({ _id: 'add-user-to-room' }, { $set: { roles: newPermission.roles } });
-				RocketChat.models.Permissions.remove({ _id: 'add-user-to-own-room' });
+				RocketChat.models.Permissions.remove({ _id: 'add-user-to-joined-room' });
 			}
 
 		}
-- 
GitLab