[OPENMEETINGS-1416] Room moderator right calculation is unified

git-svn-id: https://svn.apache.org/repos/asf/openmeetings/application/trunk@1753012 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/ConferenceService.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/ConferenceService.java
index 4fa3bde..4756b2a 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/ConferenceService.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/ConferenceService.java
@@ -86,27 +86,6 @@
 	}
 
 	/**
-	 * gets all rooms of an group TODO:check if the requesting user is
-	 * also member of that group
-	 * 
-	 * @param SID
-	 * @param groupId
-	 * @return - all rooms of an group
-	 */
-	public SearchResult<RoomGroup> getRoomsByGroup(String SID,
-			long groupId, int start, int max, String orderby,
-			boolean asc) {
-
-		log.debug("getRoomsByGroup");
-
-		Long userId = sessiondataDao.check(SID);
-		if (AuthLevelUtil.hasModLevel(userDao.get(userId), groupId)) {
-			return roomManager.getRoomGroupByGroupId(groupId, start, max, orderby, asc);
-		}
-		return null;
-	}
-
-	/**
 	 * get a List of all public availible rooms (non-appointments)
 	 * 
 	 * @param SID
diff --git a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ScopeApplicationAdapter.java b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ScopeApplicationAdapter.java
index 0ba1453..9e3efb1 100644
--- a/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ScopeApplicationAdapter.java
+++ b/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/red5/ScopeApplicationAdapter.java
@@ -49,14 +49,13 @@
 import org.apache.openmeetings.db.dao.user.UserDao;
 import org.apache.openmeetings.db.dto.room.BrowserStatus;
 import org.apache.openmeetings.db.dto.room.RoomStatus;
-import org.apache.openmeetings.db.entity.calendar.Appointment;
-import org.apache.openmeetings.db.entity.calendar.MeetingMember;
 import org.apache.openmeetings.db.entity.log.ConferenceLog;
 import org.apache.openmeetings.db.entity.room.Client;
 import org.apache.openmeetings.db.entity.room.Room;
 import org.apache.openmeetings.db.entity.room.Room.RoomElement;
 import org.apache.openmeetings.db.entity.server.Server;
 import org.apache.openmeetings.db.entity.user.User;
+import org.apache.openmeetings.db.util.AuthLevelUtil;
 import org.apache.openmeetings.util.CalendarPatterns;
 import org.apache.openmeetings.util.InitializationContainer;
 import org.apache.openmeetings.util.OmFileHelper;
@@ -1126,184 +1125,46 @@
 
 			currentClient.setUsercolor(colorObj);
 
+			User u = userDao.get(currentClient.getUserId());
 			// Inject externalUserId if nothing is set yet
-			if (currentClient.getExternalUserId() == null) {
-				if (currentClient.getUserId() != null) {
-					User us = userDao.get(currentClient.getUserId());
-					if (us != null) {
-						currentClient.setExternalUserId(us.getExternalId());
-						currentClient.setExternalUserType(us.getExternalType());
-					}
-				}
+			if (currentClient.getExternalUserId() == null && u != null) {
+				currentClient.setExternalUserId(u.getExternalId());
+				currentClient.setExternalUserType(u.getExternalType());
 			}
 
-			// This can be set without checking for Moderation Flag
-			currentClient.setIsSuperModerator(isSuperModerator);
-
-			sessionManager.updateClientByStreamId(streamid, currentClient, true, null);
-
-			Room room = roomDao.get(roomId);
-			if (!room.isHidden(RoomElement.MicrophoneStatus)) {
+			Room r = roomDao.get(roomId);
+			if (!r.isHidden(RoomElement.MicrophoneStatus)) {
 				currentClient.setCanGiveAudio(true);
 			}
-
+			sessionManager.updateClientByStreamId(streamid, currentClient, true, null); // first save to get valid room count
 			// Log the User
 			conferenceLogDao.add(ConferenceLog.Type.roomEnter,
 					currentClient.getUserId(), streamid, roomId,
 					currentClient.getUserip(), "");
 			
 			// Check for Moderation LogicalRoom ENTER
-			List<Client> clientListRoom = sessionManager.getClientListByRoom(roomId);
+			List<Client> roomClients = sessionManager.getClientListByRoom(roomId);
 
 			// Return Object
 			RoomStatus roomStatus = new RoomStatus();
 			// appointed meeting or moderated Room? => Check Max Users first
-
-			// default logic for non regular rooms
-			if (!room.isAppointment()) {
-				if (room.isModerated()) {
-					// if this is a Moderated Room then the Room can be only
-					// locked off by the Moderator Bit
-					// List<RoomClient> clientModeratorListRoom =
-					// this.sessionManager.getCurrentModeratorByRoom(roomId);
-
-					// If there is no Moderator yet we have to check if the
-					// current User has the Bit set to true to
-					// become one, otherwise he won't get Moderation and has to
-					// wait
-					if (becomeModerator) {
-						currentClient.setIsMod(true);
-
-						// There is a need to send an extra Event here, cause at
-						// this moment there could be
-						// already somebody in the Room waiting
-
-						// Update the Client List
-						sessionManager.updateClientByStreamId(streamid, currentClient, false, null);
-
-						List<Client> modRoomList = sessionManager.getCurrentModeratorByRoom(currentClient.getRoomId());
-						
-						//Sync message to everybody
-						sendMessageToCurrentScope("setNewModeratorByList", modRoomList, false);
-					} else {
-						// The current User is not a Teacher/Admin or whatever
-						// Role that should get the
-						// Moderation
-						currentClient.setIsMod(false);
-					}
-				} else {
-					// If this is a normal Room Moderator rules : first come, first draw ;-)
-					log.debug("setRoomValues : Room"
-							+ roomId
-							+ " not appointed! Moderator rules : first come, first draw ;-)");
-					if (clientListRoom.size() == 1) {
-						log.debug("Room is empty so set this user to be moderation role");
-						currentClient.setIsMod(true);
-					} else {
-						log.debug("Room is already somebody so set this user not to be moderation role");
-
-						if (becomeModerator) {
-							currentClient.setIsMod(true);
-
-							// Update the Client List
-							sessionManager.updateClientByStreamId(streamid, currentClient, false, null);
-
-							List<Client> modRoomList = sessionManager.getCurrentModeratorByRoom(currentClient.getRoomId());
-
-							// There is a need to send an extra Event here,
-							// cause at this moment there could be
-							// already somebody in the Room waiting -swagner check this comment, 20.01.2012
-							
-							//Sync message to everybody
-							sendMessageToCurrentScope("setNewModeratorByList", modRoomList, false);
-
-						} else {
-							// The current User is not a Teacher/Admin or
-							// whatever Role that should get the Moderation
-							currentClient.setIsMod(false);
-						}
-					}
-				}
-
+			if (isSuperModerator) {
+				// This can be set without checking for Moderation Flag
+				currentClient.setIsSuperModerator(isSuperModerator);
+				currentClient.setIsMod(isSuperModerator);
+			} else {
+				Room.Right rr = AuthLevelUtil.getRoomRight(u, r, r.isAppointment() ? appointmentDao.getByRoom(r.getId()) : null, roomClients.size());
+				currentClient.setIsSuperModerator(rr == Room.Right.superModerator);
+				currentClient.setIsMod(becomeModerator || rr == Room.Right.moderator);
+			}
+			if (currentClient.getIsMod()) {
 				// Update the Client List
 				sessionManager.updateClientByStreamId(streamid, currentClient, false, null);
-			} else {
-				// If this is an Appointment then the Moderator will be set to the Invitor
-				Appointment ment = appointmentDao.getByRoom(roomId);
-				Long userIdInRoomClient = currentClient.getUserId();
-				boolean found = false;
-				boolean moderator_set = false;
-				if (ment != null) {
-					// First check owner who is not in the members list
-					if (ment.getOwner().getId().equals(userIdInRoomClient)) {
-						found = true;
-						log.debug("User "
-								+ userIdInRoomClient
-								+ " is moderator due to flag in MeetingMember record");
-						currentClient.setIsMod(true);
-						moderator_set = true;
-	
-						// Update the Client List
-						sessionManager.updateClientByStreamId(streamid, currentClient, false, null);
-	
-						List<Client> modRoomList = sessionManager.getCurrentModeratorByRoom(currentClient.getRoomId());
-	
-						// There is a need to send an extra Event here, cause at this moment 
-						// there could be already somebody in the Room waiting
-	
-						//Sync message to everybody
-						sendMessageToCurrentScope("setNewModeratorByList", modRoomList, false);
-					}
-					if (!found) {
-						// Check if current user is set to moderator
-						for (MeetingMember member : ment.getMeetingMembers()) {
-							// only persistent users can schedule a meeting
-							// user-id is only set for registered users
-							if (member.getUser() != null) {
-								log.debug("checking user " + member.getUser().getFirstname()
-										+ " for moderator role - ID : "
-										+ member.getUser().getId());
-		
-								if (member.getUser().getId().equals(userIdInRoomClient)) {
-									found = true;
-									log.debug("User " + userIdInRoomClient+ " is NOT moderator due to flag in MeetingMember record");
-									currentClient.setIsMod(false);
-									sessionManager.updateClientByStreamId(streamid, currentClient, false, null);
-									break;
-								}
-							}
-						}
-					}
-				}
-				if (!found) {
-					log.debug("User "
-							+ userIdInRoomClient
-							+ " could not be found as MeetingMember -> definitely no moderator");
-					currentClient.setIsMod(false);
-					sessionManager.updateClientByStreamId(streamid, currentClient, false, null);
-				} else {
-					// if current user is part of the member list, but moderator
-					// couldn't be retrieved : first come, first draw!
-					if (clientListRoom.size() == 1 && !moderator_set) {
-						log.debug("");
-						currentClient.setIsMod(true);
 
-						// Update the Client List
-						sessionManager.updateClientByStreamId(streamid, currentClient, false, null);
-
-						List<Client> modRoomList = sessionManager.getCurrentModeratorByRoom(currentClient.getRoomId());
-
-						// There is a need to send an extra Event here, cause at
-						// this moment there could be
-						// already somebody in the Room waiting
-
-						//Sync message to everybody
-						sendMessageToCurrentScope("setNewModeratorByList", modRoomList, false);
-						
-						sessionManager.updateClientByStreamId(streamid, currentClient, false, null);
-					}
-				}
-
+				List<Client> modRoomList = sessionManager.getCurrentModeratorByRoom(currentClient.getRoomId());
+				
+				//Sync message to everybody
+				sendMessageToCurrentScope("setNewModeratorByList", modRoomList, false);
 			}
 			
 			//Sync message to everybody
@@ -1319,7 +1180,7 @@
 			// RoomStatus roomStatus = new RoomStatus();
 
 			// FIXME: Rework Client Object to DTOs
-			roomStatus.setClientList(clientListRoom);
+			roomStatus.setClientList(roomClients);
 			roomStatus.setBrowserStatus(browserStatus);
 
 			return roomStatus;
@@ -1482,10 +1343,9 @@
 	 * @param whiteboardObjParam - array of parameters being sended to whiteboard
 	 * @param whiteboardId - id of whiteboard parameters will be send to
 	 */
-	@SuppressWarnings({ "rawtypes", "unchecked" })
-	public int sendVarsByWhiteboardId(ArrayList whiteboardObjParam, Long whiteboardId) {
+	public int sendVarsByWhiteboardId(List<?> whiteboardObjParam, Long whiteboardId) {
 		try {
-			Map whiteboardObj = new HashMap();
+			Map<Integer, Object> whiteboardObj = new HashMap<>();
 			int i = 0;
 			for (Object obj : whiteboardObjParam) {
 				whiteboardObj.put(i++, obj);
@@ -1508,15 +1368,16 @@
 
 			if (action.equals("deleteMindMapNodes")) {
 				// Simulate Single Delete Events for z-Index
-				List actionObject = (List) whiteboardObj.get(3);
+				List<?> actionObject = (List<?>) whiteboardObj.get(3);
 
-				List<List> itemObjects = (List) actionObject.get(3);
+				@SuppressWarnings("unchecked")
+				List<List<?>> itemObjects = (List<List<?>>) actionObject.get(3);
 
-				Map whiteboardTempObj = new HashMap();
+				Map<Integer, Object> whiteboardTempObj = new HashMap<>();
 				whiteboardTempObj.put(2, "delete");
 
-				for (List itemObject : itemObjects) {
-					List<Object> tempActionObject = new LinkedList<Object>();
+				for (List<?> itemObject : itemObjects) {
+					List<Object> tempActionObject = new ArrayList<>();
 					tempActionObject.add("mindmapnode");
 					tempActionObject.add(itemObject.get(0)); // z-Index -8
 					tempActionObject.add(null); // simulate -7
@@ -1624,7 +1485,7 @@
 	 * wrapper method
 	 * @param newMessage
 	 */
-	public void sendMessageToMembers(Object newMessage) {
+	public void sendMessageToMembers(List<?> newMessage) {
 		//Sync to all users of current scope
 		sendMessageToCurrentScope("sendVarsToMessage", newMessage, false);
 	}
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/Room.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/Room.java
index df7c00e..80779fc 100644
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/Room.java
+++ b/openmeetings-db/src/main/java/org/apache/openmeetings/db/entity/room/Room.java
@@ -94,6 +94,18 @@
 	public static final int RESTRICTED_TYPE_ID = 3;
 	public static final int INTERVIEW_TYPE_ID = 4;
 	
+	public enum Right {
+		superModerator
+		, moderator
+		, whiteBoard
+		, share
+		, remoteControl
+		, audio
+		, video
+		, mute
+		, exclusive
+	}
+	
 	@XmlType(namespace="org.apache.openmeetings.room.element")
 	public enum RoomElement {
 		TopBar
@@ -146,6 +158,7 @@
 			return rt;
 		}
 	}
+	
 	@Id
 	@GeneratedValue(strategy = GenerationType.IDENTITY)
 	@Column(name = "id")
diff --git a/openmeetings-db/src/main/java/org/apache/openmeetings/db/util/AuthLevelUtil.java b/openmeetings-db/src/main/java/org/apache/openmeetings/db/util/AuthLevelUtil.java
index fa3ee78..9b39dcc 100644
--- a/openmeetings-db/src/main/java/org/apache/openmeetings/db/util/AuthLevelUtil.java
+++ b/openmeetings-db/src/main/java/org/apache/openmeetings/db/util/AuthLevelUtil.java
@@ -22,49 +22,78 @@
 
 import java.util.Set;
 
+import org.apache.openmeetings.db.entity.calendar.Appointment;
+import org.apache.openmeetings.db.entity.room.Room;
+import org.apache.openmeetings.db.entity.room.RoomGroup;
+import org.apache.openmeetings.db.entity.room.RoomModerator;
 import org.apache.openmeetings.db.entity.user.GroupUser;
 import org.apache.openmeetings.db.entity.user.User;
-import org.apache.openmeetings.db.entity.user.User.Right;
 import org.red5.logging.Red5LoggerFactory;
 import org.slf4j.Logger;
 
 public class AuthLevelUtil {
 	private static final Logger log = Red5LoggerFactory.getLogger(AuthLevelUtil.class, webAppRootKey);
 	
-	private static boolean check(Set<Right> rights, Right level) {
+	private static boolean check(Set<User.Right> rights, User.Right level) {
 		boolean result = rights.contains(level);
 		log.debug(String.format("Level %s :: %s", level, result ? "[GRANTED]" : "[DENIED]"));
 		return result;
 	}
 	
-	public static boolean hasUserLevel(Set<Right> rights) {
-		return check(rights, Right.Room);
+	public static boolean hasUserLevel(Set<User.Right> rights) {
+		return check(rights, User.Right.Room);
 	}
 
-	public static boolean hasModLevel(User u, Long groupId) {
-		boolean result = hasAdminLevel(u.getRights());
-		if (!result && groupId != null) {
-			for (GroupUser ou : u.getGroupUsers()) {
-				if (groupId.equals(ou.getGroup().getId())) {
-					if (ou.isModerator()) {
-						result = true;
-					}
+	public static Room.Right getRoomRight(User u, Room r, Appointment a, int userCount) {
+		Room.Right result = null;
+		if (hasAdminLevel(u.getRights())) {
+			//admin user get superModerator level, no-one can kick him/her
+			result = Room.Right.superModerator;
+		} else if (r.isAppointment() && a != null) {
+			// appointment owner is super moderator
+			if (u.getId().equals(a.getOwner().getId())) {
+				result = Room.Right.superModerator;
+			}
+		}
+		if (result == null) {
+			if (!r.isModerated() && 1 == userCount) {
+				//room is not moderated, first user is moderator!
+				result = Room.Right.moderator;
+			}
+			//performing loop here to set possible 'superModerator' right
+			for (RoomModerator rm : r.getModerators()) {
+				if (u.getId().equals(rm.getUser().getId())) {
+					result = rm.isSuperModerator() ? Room.Right.superModerator : Room.Right.moderator;
 					break;
 				}
 			}
+			//no need to loop if client is moderator
+			if (result == null && !r.getRoomGroups().isEmpty()) {
+				for (RoomGroup rg : r.getRoomGroups()) {
+					for (GroupUser gu : u.getGroupUsers()) {
+						if (gu.getGroup().getId().equals(rg.getGroup().getId()) && gu.isModerator()) {
+							result = Room.Right.moderator;
+							break;
+						}
+					}
+					if (result != null) {
+						break;
+					}
+				}
+			}
 		}
 		return result;
 	}
 
-	public static boolean hasAdminLevel(Set<Right> rights) {
-		return check(rights, Right.Admin);
+	public static boolean hasAdminLevel(Set<User.Right> rights) {
+		return check(rights, User.Right.Admin);
 	}
 
-	public static boolean hasWebServiceLevel(Set<Right> rights) {
-		return check(rights, Right.Soap);
+	public static boolean hasWebServiceLevel(Set<User.Right> rights) {
+		return check(rights, User.Right.Soap);
 	}
 
-	public static boolean hasLoginLevel(Set<Right> rights) {
-		return check(rights, Right.Login);
+	public static boolean hasLoginLevel(Set<User.Right> rights) {
+		return check(rights, User.Right.Login);
 	}
 }
diff --git a/openmeetings-screenshare/src/main/java/org/apache/openmeetings/screen/webstart/CoreScreenShare.java b/openmeetings-screenshare/src/main/java/org/apache/openmeetings/screen/webstart/CoreScreenShare.java
index 52c7cf3..058a458 100644
--- a/openmeetings-screenshare/src/main/java/org/apache/openmeetings/screen/webstart/CoreScreenShare.java
+++ b/openmeetings-screenshare/src/main/java/org/apache/openmeetings/screen/webstart/CoreScreenShare.java
@@ -41,7 +41,6 @@
 import java.util.HashMap;
 import java.util.Map;
 
-import org.apache.commons.codec.binary.Hex;
 import org.apache.openmeetings.screen.webstart.gui.ScreenSharerFrame;
 import org.red5.client.net.rtmp.INetStreamEventHandler;
 import org.red5.io.utils.ObjectMap;
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
index 5ce98ec..ae0e823 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
@@ -43,10 +43,10 @@
 import org.apache.openmeetings.db.dao.user.UserDao;
 import org.apache.openmeetings.db.entity.room.Invitation;
 import org.apache.openmeetings.db.entity.room.Room;
+import org.apache.openmeetings.db.entity.room.Room.Right;
 import org.apache.openmeetings.db.entity.user.User;
 import org.apache.openmeetings.db.entity.user.User.Type;
 import org.apache.openmeetings.util.InitializationContainer;
-import org.apache.openmeetings.web.app.Client.Right;
 import org.apache.openmeetings.web.pages.ActivatePage;
 import org.apache.openmeetings.web.pages.MainPage;
 import org.apache.openmeetings.web.pages.NotInitedPage;
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Client.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Client.java
index a5a74d1..1e9c90e 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Client.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Client.java
@@ -24,6 +24,7 @@
 import java.util.UUID;
 
 import org.apache.openmeetings.db.entity.IDataProviderEntity;
+import org.apache.openmeetings.db.entity.room.Room.Right;
 import org.apache.wicket.protocol.ws.api.registry.IKey;
 
 /**
@@ -34,17 +35,6 @@
 public class Client implements IDataProviderEntity {
 	private static final long serialVersionUID = 1L;
 
-	public enum Right {
-		superModerator
-		, moderator
-		, whiteBoard
-		, share
-		, remoteControl
-		, audio
-		, video
-		, mute
-		, exclusive
-	}
 	public enum Activity {
 		broadcast
 		, share
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
index 8e101e6..959ad3a 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/RoomPanel.java
@@ -31,15 +31,14 @@
 
 import org.apache.openmeetings.db.dao.basic.ConfigurationDao;
 import org.apache.openmeetings.db.dao.calendar.AppointmentDao;
-import org.apache.openmeetings.db.dao.user.GroupUserDao;
 import org.apache.openmeetings.db.dao.user.UserDao;
 import org.apache.openmeetings.db.entity.calendar.Appointment;
 import org.apache.openmeetings.db.entity.calendar.MeetingMember;
 import org.apache.openmeetings.db.entity.file.FileItem;
 import org.apache.openmeetings.db.entity.room.Room;
+import org.apache.openmeetings.db.entity.room.Room.Right;
 import org.apache.openmeetings.db.entity.room.Room.RoomElement;
 import org.apache.openmeetings.db.entity.room.RoomGroup;
-import org.apache.openmeetings.db.entity.room.RoomModerator;
 import org.apache.openmeetings.db.entity.user.GroupUser;
 import org.apache.openmeetings.db.entity.user.User;
 import org.apache.openmeetings.db.util.AuthLevelUtil;
@@ -48,7 +47,6 @@
 import org.apache.openmeetings.util.message.TextRoomMessage;
 import org.apache.openmeetings.web.app.Application;
 import org.apache.openmeetings.web.app.Client;
-import org.apache.openmeetings.web.app.Client.Right;
 import org.apache.openmeetings.web.app.WebSession;
 import org.apache.openmeetings.web.common.BasePanel;
 import org.apache.openmeetings.web.room.activities.ActivitiesPanel;
@@ -368,31 +366,9 @@
 			Client c = getClient();
 			addUserToRoom(c.setRoomId(getRoom().getId()));
 			User u = getBean(UserDao.class).get(getUserId());
-			if (AuthLevelUtil.hasAdminLevel(u.getRights())) {
-				//admin user get superModerator level, no-one can kick him/her
-				c.getRights().add(Right.superModerator);
-			} else {
-				if (!r.isModerated() && 1 == getRoomClients(r.getId()).size()) {
-					//room is not moderated, first user is moderator!
-					c.getRights().add(Right.moderator);
-				}
-				//performing loop here to set possible 'superModerator' right
-				for (RoomModerator rm : r.getModerators()) {
-					if (getUserId().equals(rm.getUser().getId())) {
-						c.getRights().add(rm.isSuperModerator() ? Right.superModerator : Right.moderator);
-						break;
-					}
-				}
-				//no need to loop if client is moderator
-				if (!c.hasRight(Right.moderator) && !r.getRoomGroups().isEmpty()) {
-					for (RoomGroup rg : r.getRoomGroups()) {
-						GroupUser gu = getBean(GroupUserDao.class).getByGroupAndUser(rg.getGroup().getId(), getUserId());
-						if (gu.isModerator()) {
-							c.getRights().add(Right.moderator);
-							break;
-						}
-					}
-				}
+			Right rr = AuthLevelUtil.getRoomRight(u, r, r.isAppointment() ? getBean(AppointmentDao.class).getByRoom(r.getId()) : null, getRoomClients(r.getId()).size());
+			if (rr != null) {
+				c.getRights().add(rr);
 			}
 		}
 	}
@@ -422,7 +398,7 @@
 		return hasRight(userId, roomId, Right.moderator);
 	}
 	
-	public static boolean hasRight(long userId, long roomId, Client.Right r) {
+	public static boolean hasRight(long userId, long roomId, Right r) {
 		for (Client c : getRoomClients(roomId)) {
 			if (c.getUserId().equals(userId) && c.hasRight(r)) {
 				return true;
@@ -475,7 +451,7 @@
 		}
 	}
 
-	public void requestRight(AjaxRequestTarget target, Client.Right right) {
+	public void requestRight(AjaxRequestTarget target, Right right) {
 		RoomMessage.Type reqType = null;
 		switch (right) {
 			case moderator:
@@ -540,7 +516,7 @@
 	public boolean screenShareAllowed() {
 		Room r = getRoom();
 		return Room.Type.interview != r.getType() && !r.isHidden(RoomElement.ScreenSharing)
-				&& r.isAllowRecording() && getClient().hasRight(Client.Right.share) && getSharingUser() == null;
+				&& r.isAllowRecording() && getClient().hasRight(Right.share) && getSharingUser() == null;
 	}
 	
 	public RoomSidebar getSidebar() {
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/ActivitiesPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/ActivitiesPanel.java
index 59ff6d5..3560f4e 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/ActivitiesPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/activities/ActivitiesPanel.java
@@ -33,12 +33,12 @@
 import java.util.Map;
 
 import org.apache.openmeetings.db.dao.user.UserDao;
+import org.apache.openmeetings.db.entity.room.Room.Right;
 import org.apache.openmeetings.db.entity.room.Room.RoomElement;
 import org.apache.openmeetings.db.entity.user.User;
 import org.apache.openmeetings.util.message.RoomMessage;
 import org.apache.openmeetings.util.message.TextRoomMessage;
 import org.apache.openmeetings.web.app.Client;
-import org.apache.openmeetings.web.app.Client.Right;
 import org.apache.openmeetings.web.common.BasePanel;
 import org.apache.openmeetings.web.room.RoomPanel;
 import org.apache.wicket.Component;
@@ -93,13 +93,13 @@
 							remove(id, target);
 							break;
 						case decline:
-							if (room.getClient().hasRight(Client.Right.moderator)) {
+							if (room.getClient().hasRight(Right.moderator)) {
 								broadcast(new TextRoomMessage(room.getRoom().getId(), getUserId(), RoomMessage.Type.activityRemove, id));
 							}
 							break;
 						case accept:
 							Client client = getOnlineClient(a.getUid());
-							if (room.getClient().hasRight(Client.Right.moderator) && client != null && roomId == client.getRoomId()) {
+							if (room.getClient().hasRight(Right.moderator) && client != null && roomId == client.getRoomId()) {
 								switch (a.getType()) {
 									case reqRightModerator:
 										broadcast(new TextRoomMessage(room.getRoom().getId(), getUserId(), RoomMessage.Type.activityRemove, id));
@@ -152,7 +152,7 @@
 				case reqRightAv:
 				case reqRightMute:
 				case reqRightExclusive:
-					if (room.getClient().hasRight(Client.Right.moderator)) {
+					if (room.getClient().hasRight(Right.moderator)) {
 						accept.setVisible(true);
 						decline.setVisible(true);
 						break;
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java
index 00ba6a5..39ab2b7 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/menu/RoomMenuPanel.java
@@ -38,7 +38,6 @@
 import org.apache.openmeetings.db.entity.room.Room.RoomElement;
 import org.apache.openmeetings.db.entity.room.RoomPoll;
 import org.apache.openmeetings.db.entity.user.User;
-import org.apache.openmeetings.db.entity.user.User.Right;
 import org.apache.openmeetings.util.message.RoomMessage;
 import org.apache.openmeetings.util.message.TextRoomMessage;
 import org.apache.openmeetings.web.app.Application;
@@ -87,7 +86,7 @@
 		}
 		@Override
 		public void onClick(AjaxRequestTarget target) {
-			room.requestRight(target, Client.Right.moderator);
+			room.requestRight(target, Room.Right.moderator);
 		}
 	};
 	private final RoomPanel room;
@@ -168,7 +167,7 @@
 
 		@Override
 		public void onClick(AjaxRequestTarget target) {
-			pollResults.updateModel(target, room.getClient().hasRight(Client.Right.moderator));
+			pollResults.updateModel(target, room.getClient().hasRight(Room.Right.moderator));
 			pollResults.open(target);
 		}
 	};
@@ -266,15 +265,15 @@
 		exitMenuItem.setEnabled(notExternalUser);//TODO check this
 		filesMenu.setEnabled(room.getSidebar().isShowFiles());
 		actionsMenu.setEnabled(!r.isHidden(RoomElement.ActionMenu) && r.isAllowUserQuestions());
-		boolean moder = room.getClient().hasRight(Client.Right.moderator);
+		boolean moder = room.getClient().hasRight(Room.Right.moderator);
 		inviteMenuItem.setEnabled(notExternalUser && moder);
 		//TODO add check "sharing started"
 		boolean shareVisible = room.screenShareAllowed();
 		shareMenuItem.setEnabled(shareVisible);
 		//FIXME TODO apply* should be enabled if moder is in room
 		applyModerMenuItem.setEnabled(!moder);
-		applyWbMenuItem.setEnabled(!room.getClient().hasRight(Client.Right.whiteBoard));
-		applyAvMenuItem.setEnabled(!room.getClient().hasRight(Client.Right.audio) || !room.getClient().hasRight(Client.Right.video));
+		applyWbMenuItem.setEnabled(!room.getClient().hasRight(Room.Right.whiteBoard));
+		applyAvMenuItem.setEnabled(!room.getClient().hasRight(Room.Right.audio) || !room.getClient().hasRight(Room.Right.video));
 		pollCreateMenuItem.setEnabled(moder);
 		pollVoteMenuItem.setEnabled(pollExists && notExternalUser && !pollDao.hasVoted(r.getId(), getUserId()));
 		pollResultMenuItem.setEnabled(pollExists || pollDao.getArchived(r.getId()).size() > 0);
@@ -317,7 +316,7 @@
 	}
 	
 	public void exit(IPartialPageRequestHandler handler) {
-		if (WebSession.getRights().contains(Right.Dashboard)) {
+		if (WebSession.getRights().contains(User.Right.Dashboard)) {
 			roomExit(room, false);
 			room.getMainPage().updateContents(ROOMS_PUBLIC, handler);
 		} else {
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomClientPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomClientPanel.java
index 2e27fec..83997bd 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomClientPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomClientPanel.java
@@ -22,10 +22,10 @@
 import static org.apache.openmeetings.web.app.WebSession.getUserId;
 
 import org.apache.openmeetings.db.dao.user.UserDao;
+import org.apache.openmeetings.db.entity.room.Room.Right;
 import org.apache.openmeetings.db.entity.room.Room.RoomElement;
 import org.apache.openmeetings.db.entity.user.User;
 import org.apache.openmeetings.web.app.Client;
-import org.apache.openmeetings.web.app.Client.Right;
 import org.apache.openmeetings.web.room.RoomPanel;
 import org.apache.openmeetings.web.room.sidebar.icon.KickRightIcon;
 import org.apache.openmeetings.web.room.sidebar.icon.RefreshIcon;
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java
index a5d5c23..6cd5cb3 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/RoomSidebar.java
@@ -27,9 +27,9 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 
+import org.apache.openmeetings.db.entity.room.Room.Right;
 import org.apache.openmeetings.db.entity.room.Room.RoomElement;
 import org.apache.openmeetings.web.app.Client;
-import org.apache.openmeetings.web.app.Client.Right;
 import org.apache.openmeetings.web.room.RoomPanel;
 import org.apache.wicket.ajax.AbstractDefaultAjaxBehavior;
 import org.apache.wicket.ajax.AjaxRequestTarget;
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/AudioRightIcon.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/AudioRightIcon.java
index 3f4eace..9caec1f 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/AudioRightIcon.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/AudioRightIcon.java
@@ -18,8 +18,8 @@
  */
 package org.apache.openmeetings.web.room.sidebar.icon;
 
+import org.apache.openmeetings.db.entity.room.Room.Right;
 import org.apache.openmeetings.web.app.Client;
-import org.apache.openmeetings.web.app.Client.Right;
 import org.apache.openmeetings.web.room.RoomPanel;
 
 public class AudioRightIcon extends RoomRightIcon {
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/ExclusiveRightIcon.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/ExclusiveRightIcon.java
index e6b378f..bdf04ff 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/ExclusiveRightIcon.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/ExclusiveRightIcon.java
@@ -18,8 +18,8 @@
  */
 package org.apache.openmeetings.web.room.sidebar.icon;
 
+import org.apache.openmeetings.db.entity.room.Room.Right;
 import org.apache.openmeetings.web.app.Client;
-import org.apache.openmeetings.web.app.Client.Right;
 import org.apache.openmeetings.web.room.RoomPanel;
 
 public class ExclusiveRightIcon extends RoomRightIcon {
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/KickRightIcon.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/KickRightIcon.java
index 61a7b33..30a447f 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/KickRightIcon.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/KickRightIcon.java
@@ -20,8 +20,8 @@
 
 import static org.apache.openmeetings.web.room.sidebar.RoomSidebar.FUNC_ACTION;
 
+import org.apache.openmeetings.db.entity.room.Room.Right;
 import org.apache.openmeetings.web.app.Client;
-import org.apache.openmeetings.web.app.Client.Right;
 import org.apache.openmeetings.web.room.RoomPanel;
 import org.apache.openmeetings.web.room.RoomPanel.Action;
 import org.apache.wicket.core.request.handler.IPartialPageRequestHandler;
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/ModeratorRightIcon.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/ModeratorRightIcon.java
index 76b148b..8990116 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/ModeratorRightIcon.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/ModeratorRightIcon.java
@@ -18,8 +18,8 @@
  */
 package org.apache.openmeetings.web.room.sidebar.icon;
 
+import org.apache.openmeetings.db.entity.room.Room.Right;
 import org.apache.openmeetings.web.app.Client;
-import org.apache.openmeetings.web.app.Client.Right;
 import org.apache.openmeetings.web.room.RoomPanel;
 
 public class ModeratorRightIcon extends RoomRightIcon {
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/MuteRightIcon.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/MuteRightIcon.java
index 52b876c..3e10b40 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/MuteRightIcon.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/MuteRightIcon.java
@@ -18,8 +18,8 @@
  */
 package org.apache.openmeetings.web.room.sidebar.icon;
 
+import org.apache.openmeetings.db.entity.room.Room.Right;
 import org.apache.openmeetings.web.app.Client;
-import org.apache.openmeetings.web.app.Client.Right;
 import org.apache.openmeetings.web.room.RoomPanel;
 
 public class MuteRightIcon extends RoomRightIcon {
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/RefreshIcon.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/RefreshIcon.java
index a93eb1e..063c3a1 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/RefreshIcon.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/RefreshIcon.java
@@ -20,8 +20,8 @@
 
 import static org.apache.openmeetings.web.room.sidebar.RoomSidebar.FUNC_ACTION;
 
+import org.apache.openmeetings.db.entity.room.Room.Right;
 import org.apache.openmeetings.web.app.Client;
-import org.apache.openmeetings.web.app.Client.Right;
 import org.apache.openmeetings.web.room.RoomPanel;
 import org.apache.openmeetings.web.room.RoomPanel.Action;
 import org.apache.wicket.core.request.handler.IPartialPageRequestHandler;
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/RemoteControlRightIcon.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/RemoteControlRightIcon.java
index 26a6444..7b47210 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/RemoteControlRightIcon.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/RemoteControlRightIcon.java
@@ -18,8 +18,8 @@
  */
 package org.apache.openmeetings.web.room.sidebar.icon;
 
+import org.apache.openmeetings.db.entity.room.Room.Right;
 import org.apache.openmeetings.web.app.Client;
-import org.apache.openmeetings.web.app.Client.Right;
 import org.apache.openmeetings.web.room.RoomPanel;
 import org.apache.wicket.core.request.handler.IPartialPageRequestHandler;
 
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/RoomRightIcon.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/RoomRightIcon.java
index da5484a..bc81451 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/RoomRightIcon.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/RoomRightIcon.java
@@ -20,8 +20,8 @@
 
 import static org.apache.openmeetings.web.room.sidebar.RoomSidebar.FUNC_CHANGE_RIGHT;
 
+import org.apache.openmeetings.db.entity.room.Room.Right;
 import org.apache.openmeetings.web.app.Client;
-import org.apache.openmeetings.web.app.Client.Right;
 import org.apache.openmeetings.web.room.RoomPanel;
 import org.apache.wicket.behavior.AttributeAppender;
 import org.apache.wicket.core.request.handler.IPartialPageRequestHandler;
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/ScreenShareRightIcon.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/ScreenShareRightIcon.java
index 1fb1f45..2bab653 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/ScreenShareRightIcon.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/ScreenShareRightIcon.java
@@ -18,8 +18,8 @@
  */
 package org.apache.openmeetings.web.room.sidebar.icon;
 
+import org.apache.openmeetings.db.entity.room.Room.Right;
 import org.apache.openmeetings.web.app.Client;
-import org.apache.openmeetings.web.app.Client.Right;
 import org.apache.openmeetings.web.room.RoomPanel;
 import org.apache.wicket.core.request.handler.IPartialPageRequestHandler;
 
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/VideoRightIcon.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/VideoRightIcon.java
index c8b48d4..b61a2ea 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/VideoRightIcon.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/VideoRightIcon.java
@@ -18,8 +18,8 @@
  */
 package org.apache.openmeetings.web.room.sidebar.icon;
 
+import org.apache.openmeetings.db.entity.room.Room.Right;
 import org.apache.openmeetings.web.app.Client;
-import org.apache.openmeetings.web.app.Client.Right;
 import org.apache.openmeetings.web.room.RoomPanel;
 
 public class VideoRightIcon extends RoomRightIcon {
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/WhiteboardRightIcon.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/WhiteboardRightIcon.java
index 16075f2..abfc254 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/WhiteboardRightIcon.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/room/sidebar/icon/WhiteboardRightIcon.java
@@ -19,9 +19,9 @@
 package org.apache.openmeetings.web.room.sidebar.icon;
 
 import org.apache.openmeetings.db.entity.room.Room;
+import org.apache.openmeetings.db.entity.room.Room.Right;
 import org.apache.openmeetings.db.entity.room.Room.RoomElement;
 import org.apache.openmeetings.web.app.Client;
-import org.apache.openmeetings.web.app.Client.Right;
 import org.apache.openmeetings.web.room.RoomPanel;
 
 public class WhiteboardRightIcon extends RoomRightIcon {
diff --git a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/ChatPanel.java b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/ChatPanel.java
index ac7f862..04cd0b6 100644
--- a/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/ChatPanel.java
+++ b/openmeetings-web/src/main/java/org/apache/openmeetings/web/user/ChatPanel.java
@@ -41,6 +41,7 @@
 import org.apache.openmeetings.db.dao.user.UserDao;
 import org.apache.openmeetings.db.entity.basic.ChatMessage;
 import org.apache.openmeetings.db.entity.room.Room;
+import org.apache.openmeetings.db.entity.room.Room.Right;
 import org.apache.openmeetings.db.entity.room.Room.RoomElement;
 import org.apache.openmeetings.db.entity.user.User;
 import org.apache.openmeetings.web.app.Application;
@@ -229,7 +230,7 @@
 		IWebSocketConnectionRegistry reg = WebSocketSettings.Holder.get(Application.get()).getConnectionRegistry();
 		for (Client c : getRoomClients(m.getToRoom().getId())) {
 			try {
-				if (!m.isNeedModeration() || (m.isNeedModeration() && c.hasRight(Client.Right.moderator))) {
+				if (!m.isNeedModeration() || (m.isNeedModeration() && c.hasRight(Right.moderator))) {
 					IWebSocketConnection con = reg.getConnection(Application.get(), c.getSessionId(), new PageIdKey(c.getPageId()));
 					if (con != null) {
 						con.sendMessage(msg);