You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openmeetings.apache.org by vd...@apache.org on 2015/08/10 10:07:53 UTC

svn commit: r1694985 - in /openmeetings/branches/3.0.x/src: db/java/org/apache/openmeetings/db/dao/user/ main/java/org/apache/openmeetings/remote/ web/java/org/apache/openmeetings/web/admin/connection/ web/java/org/apache/openmeetings/web/app/ web/java...

Author: vdegtyarev
Date: Mon Aug 10 08:07:52 2015
New Revision: 1694985

URL: http://svn.apache.org/r1694985
Log:
OPENMEETINGS-1125 is fixed. Connections are shown as expected.

Added:
    openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/app/WebClient.java
    openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/pages/auth/KickMessageDialog.html
    openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/pages/auth/KickMessageDialog.java
Modified:
    openmeetings/branches/3.0.x/src/db/java/org/apache/openmeetings/db/dao/user/IUserService.java
    openmeetings/branches/3.0.x/src/main/java/org/apache/openmeetings/remote/UserService.java
    openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/admin/connection/ConnectionsPanel.html
    openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/admin/connection/ConnectionsPanel.java
    openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/app/Application.java
    openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/app/WebSession.java
    openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/pages/MainPage.java
    openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/pages/auth/RegisterDialog.java
    openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/pages/auth/SignInPage.html
    openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/pages/auth/SignInPage.java

Modified: openmeetings/branches/3.0.x/src/db/java/org/apache/openmeetings/db/dao/user/IUserService.java
URL: http://svn.apache.org/viewvc/openmeetings/branches/3.0.x/src/db/java/org/apache/openmeetings/db/dao/user/IUserService.java?rev=1694985&r1=1694984&r2=1694985&view=diff
==============================================================================
--- openmeetings/branches/3.0.x/src/db/java/org/apache/openmeetings/db/dao/user/IUserService.java (original)
+++ openmeetings/branches/3.0.x/src/db/java/org/apache/openmeetings/db/dao/user/IUserService.java Mon Aug 10 08:07:52 2015
@@ -21,4 +21,5 @@ package org.apache.openmeetings.db.dao.u
 //FIXME HACK to bypass cross project compilation
 public interface IUserService {
 	Boolean kickUserByStreamId(String SID, String streamid, long serverId);
+	Boolean kickUserBySessionId(String SID, long userId, String sessionId);
 }

Modified: openmeetings/branches/3.0.x/src/main/java/org/apache/openmeetings/remote/UserService.java
URL: http://svn.apache.org/viewvc/openmeetings/branches/3.0.x/src/main/java/org/apache/openmeetings/remote/UserService.java?rev=1694985&r1=1694984&r2=1694985&view=diff
==============================================================================
--- openmeetings/branches/3.0.x/src/main/java/org/apache/openmeetings/remote/UserService.java (original)
+++ openmeetings/branches/3.0.x/src/main/java/org/apache/openmeetings/remote/UserService.java Mon Aug 10 08:07:52 2015
@@ -21,6 +21,7 @@ package org.apache.openmeetings.remote;
 import static org.apache.openmeetings.db.entity.user.PrivateMessage.INBOX_FOLDER_ID;
 import static org.apache.openmeetings.db.entity.user.PrivateMessage.SENT_FOLDER_ID;
 import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
+import static org.apache.openmeetings.web.app.Application.removeOnlineUser;
 
 import java.util.ArrayList;
 import java.util.Calendar;
@@ -62,6 +63,8 @@ import org.apache.openmeetings.mail.Mail
 import org.apache.openmeetings.remote.red5.ScopeApplicationAdapter;
 import org.apache.openmeetings.util.AuthLevelUtil;
 import org.apache.openmeetings.util.CalendarPatterns;
+import org.apache.openmeetings.web.app.Application;
+import org.apache.openmeetings.web.app.WebClient;
 import org.apache.openmeetings.web.mail.template.AbstractTemplatePanel;
 import org.apache.openmeetings.web.util.ContactsHelper;
 import org.red5.logging.Red5LoggerFactory;
@@ -497,7 +500,24 @@ public class UserService implements IUse
 				return true;
 			}
 		} catch (Exception err) {
-			log.error("[kickUserByStreamId]", err);
+			log.error("[kickUserByPublicSID]", err);
+		}
+		return null;
+	}
+
+	@Override
+	public Boolean kickUserBySessionId(String SID, long userId, String sessionId) {
+		try {
+			Long users_id = sessiondataDao.checkSession(SID);
+			// admin only
+			if (AuthLevelUtil.hasAdminLevel(userDao.getRights(users_id))) {
+				WebClient client = Application.getClientByKeys(userId, sessionId);
+				if (client != null) {
+					removeOnlineUser(client);
+				}
+			}
+		} catch (Exception err) {
+			log.error("[kickUserBySessionId]", err);
 		}
 		return null;
 	}

Modified: openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/admin/connection/ConnectionsPanel.html
URL: http://svn.apache.org/viewvc/openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/admin/connection/ConnectionsPanel.html?rev=1694985&r1=1694984&r2=1694985&view=diff
==============================================================================
--- openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/admin/connection/ConnectionsPanel.html (original)
+++ openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/admin/connection/ConnectionsPanel.html Mon Aug 10 08:07:52 2015
@@ -44,6 +44,18 @@
 						<td wicket:id="server"></td>
 					</tr>
 				</tbody>
+				<tbody wicket:id="containerWeb" >
+					<tr wicket:id="clientListWeb">
+						<td wicket:id="id"></td>
+						<td wicket:id="login"></td>
+						<td wicket:id="since"></td>
+						<td wicket:id="scope"></td>
+						<td><a wicket:id="kick"><wicket:message key="603" /></a></td>
+						<!--  
+						<td wicket:id="server"></td> 
+						-->
+					</tr>
+				</tbody>
 			</table>
 		</div>
 		<div class="adminPanelColumnForm">

Modified: openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/admin/connection/ConnectionsPanel.java
URL: http://svn.apache.org/viewvc/openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/admin/connection/ConnectionsPanel.java?rev=1694985&r1=1694984&r2=1694985&view=diff
==============================================================================
--- openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/admin/connection/ConnectionsPanel.java (original)
+++ openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/admin/connection/ConnectionsPanel.java Mon Aug 10 08:07:52 2015
@@ -31,8 +31,12 @@ import java.util.List;
 import org.apache.openmeetings.db.dao.server.ISessionManager;
 import org.apache.openmeetings.db.dao.user.IUserService;
 import org.apache.openmeetings.db.entity.room.Client;
+import org.apache.openmeetings.remote.UserService;
 import org.apache.openmeetings.web.admin.AdminPanel;
 import org.apache.openmeetings.web.admin.SearchableDataView;
+import org.apache.openmeetings.web.app.Application;
+import org.apache.openmeetings.web.app.WebClient;
+import org.apache.openmeetings.web.app.WebSession;
 import org.apache.openmeetings.web.common.ConfirmableAjaxLink;
 import org.apache.openmeetings.web.common.PagedEntityListPanel;
 import org.apache.openmeetings.web.data.SearchableDataProvider;
@@ -67,6 +71,21 @@ public class ConnectionsPanel extends Ad
 				return getBean(ISessionManager.class).getClients().size();
 			}
 		};
+		
+		SearchableDataProvider<WebClient> sdpWeb = new SearchableDataProvider<WebClient>(null) {
+			private static final long serialVersionUID = 1L;
+			
+			@Override
+			public Iterator<? extends WebClient> iterator(long first, long count) {
+				List<WebClient> l = new ArrayList<WebClient>(Application.getClients());
+				return l.subList((int)Math.max(0, first), (int)Math.min(first + count, l.size())).iterator();
+			}
+			
+			@Override
+			public long size() {
+				return Application.getClientsSize();
+			}
+		};
 		final WebMarkupContainer container = new WebMarkupContainer("container");
 		final WebMarkupContainer details = new WebMarkupContainer("details");
 		SearchableDataView<Client> dataView = new SearchableDataView<Client>("clientList", sdp) {
@@ -123,7 +142,63 @@ public class ConnectionsPanel extends Ad
 				item.add(AttributeModifier.append("class", "clickable ui-widget-content"));
 			}
 		};
-		add(container.add(dataView).setOutputMarkupId(true), details.setVisible(false).setOutputMarkupPlaceholderTag(true));
+		add(container.add(dataView).setOutputMarkupId(true));
+		
+		final WebMarkupContainer containerWeb = new WebMarkupContainer("containerWeb");
+		SearchableDataView<WebClient> dataViewWeb = new SearchableDataView<WebClient>("clientListWeb", sdpWeb) {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			protected void populateItem(final Item<WebClient> item) {
+				WebClient c = item.getModelObject();
+				item.add(new Label("id", c.getUserId()));
+				item.add(new Label("login", getBean(UserService.class).getUserById(getSid(), c.getUserId()).getLogin()));
+				item.add(new Label("since", c.getConnectedSince()));
+				item.add(new Label("scope", "hibernate"));
+				item.add(new Label("server", "no cluster"));
+				item.add(new ConfirmableAjaxLink("kick", 605) {
+					private static final long serialVersionUID = 1L;
+
+					@Override
+					public void onClick(AjaxRequestTarget target) {
+						WebClient c = item.getModelObject();
+						getBean(IUserService.class).kickUserBySessionId(getSid(), c.getUserId()
+								, c.getSessionId());
+						target.add(containerWeb, details.setVisible(false));
+					}
+				}.setEnabled(!c.getSessionId().equals(WebSession.get().getId())));
+				item.add(new AjaxEventBehavior("onclick") {
+					private static final long serialVersionUID = 1L;
+
+					@Override
+					protected void onEvent(AjaxRequestTarget target) {
+						Field[] ff = WebClient.class.getDeclaredFields();
+						RepeatingView lines = new RepeatingView("line");
+						WebClient c = item.getModelObject();
+						for (Field f : ff) {
+							int mod = f.getModifiers();
+							if (Modifier.isStatic(mod) || Modifier.isTransient(mod)) {
+								continue;
+							}
+							WebMarkupContainer line = new WebMarkupContainer(lines.newChildId());
+							line.add(new Label("name", f.getName()));
+							String val = "";
+							try {
+								f.setAccessible(true);
+								val = "" + f.get(c);
+							} catch (Exception e) {
+							}
+							line.add(new Label("value", val));
+							lines.add(line);
+						}
+						details.addOrReplace(lines);
+						target.add(details.setVisible(true));
+					}
+				});
+				item.add(AttributeModifier.append("class", "clickable ui-widget-content"));
+			}
+		};
+		add(containerWeb.add(dataViewWeb).setOutputMarkupId(true), details.setVisible(false).setOutputMarkupPlaceholderTag(true));
 		
 		add(new PagedEntityListPanel("navigator", dataView) {
 			private static final long serialVersionUID = 1L;

Modified: openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/app/Application.java
URL: http://svn.apache.org/viewvc/openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/app/Application.java?rev=1694985&r1=1694984&r2=1694985&view=diff
==============================================================================
--- openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/app/Application.java (original)
+++ openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/app/Application.java Mon Aug 10 08:07:52 2015
@@ -24,8 +24,10 @@ import static org.springframework.web.co
 import static org.springframework.web.context.support.WebApplicationContextUtils.getWebApplicationContext;
 
 import java.text.MessageFormat;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
@@ -33,6 +35,9 @@ import java.util.concurrent.ConcurrentHa
 
 import javax.servlet.ServletContext;
 
+import org.apache.commons.collections.MapIterator;
+import org.apache.commons.collections.keyvalue.MultiKey;
+import org.apache.commons.collections.map.MultiKeyMap;
 import org.apache.openmeetings.db.dao.basic.ConfigurationDao;
 import org.apache.openmeetings.db.dao.label.LabelDao;
 import org.apache.openmeetings.db.dao.user.UserDao;
@@ -72,7 +77,6 @@ import org.apache.wicket.request.Url;
 import org.apache.wicket.request.component.IRequestablePage;
 import org.apache.wicket.request.mapper.info.PageComponentInfo;
 import org.apache.wicket.request.mapper.parameter.PageParametersEncoder;
-import org.apache.wicket.util.collections.ConcurrentHashSet;
 import org.apache.wicket.util.tester.WicketTester;
 import org.slf4j.Logger;
 import org.springframework.web.context.WebApplicationContext;
@@ -86,7 +90,8 @@ import ro.fortsoft.wicket.dashboard.web.
 public class Application extends AuthenticatedWebApplication {
 	private static final Logger log = getLogger(Application.class, webAppRootKey);
 	private static boolean isInstalled;
-	private static Map<Long, Set<String>> ONLINE_USERS = new ConcurrentHashMap<Long, Set<String>>();
+	private static MultiKeyMap ONLINE_USERS = new MultiKeyMap(); 
+	private static Map<String, WebClient> INVALID_SESSIONS = new ConcurrentHashMap<String, WebClient>();
 	private DashboardContext dashboardContext;
 	private static Set<Long> STRINGS_WITH_APP = new HashSet<Long>(); //FIXME need to be removed
 	private static String appName;
@@ -187,30 +192,65 @@ public class Application extends Authent
 		return get().dashboardContext;
 	}
 	
-	public static void addOnlineUser(long userId, String sessionId) {
-		if (!ONLINE_USERS.containsKey(userId)) {
-			ONLINE_USERS.put(userId, new ConcurrentHashSet<String>());
-		}
-		ONLINE_USERS.get(userId).add(sessionId);
-	}
-	
-	public static void removeOnlineUser(long userId, String sessionId) {
-		if (ONLINE_USERS.containsKey(userId)) {
-			Set<String> sessions = ONLINE_USERS.get(userId);
-			if (sessions.isEmpty()) {
-				ONLINE_USERS.remove(userId);
-			} else if (sessions.contains(sessionId)) {
-				if (sessions.size() > 1) {
-					sessions.remove(sessionId);
-				} else {
-					ONLINE_USERS.remove(userId);
-				}
+	public synchronized static void addOnlineUser(WebClient client) {
+		try {
+			ONLINE_USERS.put(client.getUserId(), client.getSessionId(), client);
+		} catch (Exception err) {
+			log.error("[addOnlineUser]", err);
+		}
+	}
+	
+	public synchronized static void removeOnlineUser(WebClient c) {
+		try {
+			if (c != null) {
+				ONLINE_USERS.remove(c.getUserId(), c.getSessionId());
+				invalidateClient(c);
 			}
+		} catch (Exception err) {
+			log.error("[removeOnlineUser]", err);
 		}
 	}
 	
-	public static boolean isUserOnline(long userId) {
-		return ONLINE_USERS.containsKey(userId);
+	public static boolean isUserOnline(Long userId) {
+        MapIterator it = ONLINE_USERS.mapIterator();
+        boolean isUserOnline = false;
+        while (it.hasNext()) {
+            MultiKey multi = (MultiKey) it.next();
+            if (multi.size() > 0 && userId.equals(multi.getKey(0))){
+            	isUserOnline = true;
+            	break;
+            }
+        } 
+		return isUserOnline;
+	}
+
+	@SuppressWarnings("unchecked")
+	public static List<WebClient> getClients() {
+		return new ArrayList<WebClient>(ONLINE_USERS.values());
+	}
+
+	public static int getClientsSize() {
+		return ONLINE_USERS.size();
+	}
+	
+	public static WebClient getClientByKeys(Long userId, String sessionId) {
+		return (WebClient) ONLINE_USERS.get(userId, sessionId);
+	}
+	
+	public static void invalidateClient(WebClient client) {
+		if (!INVALID_SESSIONS.containsKey(client.getSessionId())) {
+			INVALID_SESSIONS.put(client.getSessionId(), client);
+		}
+	}
+	
+	public static boolean isInvaldSession(String sessionId) {
+		return sessionId == null ? false : INVALID_SESSIONS.containsKey(sessionId);
+	}
+	
+	public static void removeInvalidSession(String sessionId) {
+		if (INVALID_SESSIONS.containsKey(sessionId)){
+			INVALID_SESSIONS.remove(sessionId);
+		}
 	}
 	
 	//TODO need more safe way FIXME

Added: openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/app/WebClient.java
URL: http://svn.apache.org/viewvc/openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/app/WebClient.java?rev=1694985&view=auto
==============================================================================
--- openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/app/WebClient.java (added)
+++ openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/app/WebClient.java Mon Aug 10 08:07:52 2015
@@ -0,0 +1,143 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License") +  you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openmeetings.web.app;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.openmeetings.db.entity.IDataProviderEntity;
+import org.apache.wicket.protocol.ws.api.registry.IKey;
+
+/**
+ * Temporary class, later will be merged with {@link org.apache.openmeetings.db.entity.room.Client}
+ * @author solomax
+ *
+ */
+public class WebClient  implements IDataProviderEntity, Serializable {
+	private static final long serialVersionUID = 1L;
+
+	public enum Right {
+		moderator
+	}
+	private String sessionId;
+	private int pageId;
+	private long userId;
+	private String uid;
+	private Set<Right> rights = new HashSet<Right>();
+	private Date connectedSince;
+	private int serverId = 0;
+
+	public WebClient() {
+	}
+	
+	public WebClient(String sessionId, IKey key, long userId) {
+		this(sessionId, key.hashCode(), userId);
+	}
+	
+	public WebClient(String sessionId, int pageId, long userId) {
+		this.sessionId = sessionId;
+		this.pageId = pageId;
+		this.userId = userId;
+		this.connectedSince = new Date();
+	}
+
+	public String getSessionId() {
+		return sessionId;
+	}
+
+	public void setSessionId(String sessionId) {
+		this.sessionId = sessionId;
+	}
+
+	public int getPageId() {
+		return pageId;
+	}
+
+	public void setPageId(int pageId) {
+		this.pageId = pageId;
+	}
+
+	public long getUserId() {
+		return userId;
+	}
+
+	public void setUserId(long userId) {
+		this.userId = userId;
+	}
+
+	public String getUid() {
+		return uid;
+	}
+
+	public void setUid(String uid) {
+		this.uid = uid;
+	}
+	public Date getConnectedSince() {
+		return connectedSince;
+	}
+
+	public void setConnectedSince(Date connectedSince) {
+		this.connectedSince = connectedSince;
+	}
+	
+	public int getServerId() {
+		return this.serverId;
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + pageId;
+		result = prime * result + ((sessionId == null) ? 0 : sessionId.hashCode());
+		result = prime * result + (int) (userId ^ (userId >>> 32));
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		WebClient other = (WebClient) obj;
+		if (pageId != other.pageId)
+			return false;
+		if (sessionId == null) {
+			if (other.sessionId != null)
+				return false;
+		} else if (!sessionId.equals(other.sessionId))
+			return false;
+		if (userId != other.userId)
+			return false;
+		return true;
+	}
+
+	public Set<Right> getRights() {
+		return rights;
+	}
+
+	public boolean hasRight(Right right) {
+		return rights.contains(Right.moderator) ? true : rights.contains(right);
+	}
+}

Modified: openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/app/WebSession.java
URL: http://svn.apache.org/viewvc/openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/app/WebSession.java?rev=1694985&r1=1694984&r2=1694985&view=diff
==============================================================================
--- openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/app/WebSession.java (original)
+++ openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/app/WebSession.java Mon Aug 10 08:07:52 2015
@@ -24,7 +24,11 @@ import static org.apache.openmeetings.ut
 import static org.apache.openmeetings.util.OpenmeetingsVariables.CONFIG_DEFAULT_LANG_KEY;
 import static org.apache.openmeetings.web.app.Application.getAuthenticationStrategy;
 import static org.apache.openmeetings.web.app.Application.getBean;
+import static org.apache.openmeetings.web.app.Application.getClientByKeys;
 import static org.apache.openmeetings.web.app.Application.getDashboardContext;
+import static org.apache.openmeetings.web.app.Application.isInvaldSession;
+import static org.apache.openmeetings.web.app.Application.removeInvalidSession;
+import static org.apache.openmeetings.web.app.Application.removeOnlineUser;
 
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
@@ -100,6 +104,7 @@ public class WebSession extends Abstract
 	private Long recordingId;
 	private Long loginError = null;
 	private String externalType;
+	public static boolean kickedByAdmin = false;
 	public final static List<String> AVAILABLE_TIMEZONES = Arrays.asList(TimeZone.getAvailableIDs());
 	public final static Set<String> AVAILABLE_TIMEZONE_SET = new LinkedHashSet<String>(AVAILABLE_TIMEZONES);
 	
@@ -110,6 +115,7 @@ public class WebSession extends Abstract
 
 	@Override
 	public void invalidate() {
+		removeOnlineUser(getClientByKeys(getUserId(), get().getId()));
 		super.invalidate();
 		userId = -1;
 		rights = new HashSet<User.Right>();
@@ -288,6 +294,7 @@ public class WebSession extends Abstract
 	}
 	
 	public static long getLanguage() {
+		checkIsInvalid();
 		WebSession session = get();
 		if (session.languageId < 0) {
 			if (session.isSignedIn()) {
@@ -322,6 +329,7 @@ public class WebSession extends Abstract
 	}
 
 	public static long getUserId() {
+		checkIsInvalid();
 		return get().userId;
 	}
 	
@@ -354,8 +362,17 @@ public class WebSession extends Abstract
 	}
 	
 	public static Set<Right> getRights() {
+		checkIsInvalid();
 		return get().rights;
 	}
+	
+	public static void setKickedByAdmin(boolean kicked) {
+		kickedByAdmin = kicked;
+	}
+	
+	public boolean isKickedByAdmin() {
+		return kickedByAdmin;
+	}
 
 	public OmUrlFragment getArea() {
 		return area;
@@ -483,4 +500,14 @@ public class WebSession extends Abstract
 			dashboardContext.getDashboardPersister().save(dashboard);
 		}
 	}
+	
+	private static void checkIsInvalid() {
+		if (isInvaldSession(get().getId())) {
+			setKickedByAdmin(true);
+			removeInvalidSession(get().getId());
+			org.apache.wicket.Session session = (org.apache.wicket.Session)get();
+			session.invalidate();
+			Application.get().restartResponseAtSignInPage();
+		}
+	}
 }

Modified: openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/pages/MainPage.java
URL: http://svn.apache.org/viewvc/openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/pages/MainPage.java?rev=1694985&r1=1694984&r2=1694985&view=diff
==============================================================================
--- openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/pages/MainPage.java (original)
+++ openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/pages/MainPage.java Mon Aug 10 08:07:52 2015
@@ -20,6 +20,7 @@ package org.apache.openmeetings.web.page
 
 import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
 import static org.apache.openmeetings.web.app.Application.addOnlineUser;
+import static org.apache.openmeetings.web.app.Application.getClientByKeys;
 import static org.apache.openmeetings.web.app.Application.removeOnlineUser;
 import static org.apache.openmeetings.web.app.WebSession.getUserId;
 import static org.apache.openmeetings.web.util.OmUrlFragment.CHILD_ID;
@@ -28,6 +29,7 @@ import static org.apache.openmeetings.we
 import static org.apache.openmeetings.web.util.OmUrlFragment.getPanel;
 
 import org.apache.openmeetings.web.app.Application;
+import org.apache.openmeetings.web.app.WebClient;
 import org.apache.openmeetings.web.app.WebSession;
 import org.apache.openmeetings.web.common.BasePanel;
 import org.apache.openmeetings.web.common.ConfirmableAjaxLink;
@@ -122,14 +124,15 @@ public class MainPage extends BaseInited
 			@Override
 			protected void onConnect(ConnectedMessage message) {
 				super.onConnect(message);
-				addOnlineUser(getUserId(), WebSession.get().getId());
+				addOnlineUser(new WebClient(WebSession.get().getId(), message.getKey(), getUserId()));
 				log.debug("WebSocketBehavior::onConnect");
 			}
 			
 			@Override
 			protected void onClose(ClosedMessage message) {
+				WebClient client = getClientByKeys(getUserId(), WebSession.get().getId());
+				removeOnlineUser(client);
 				super.onClose(message);
-				removeOnlineUser(getUserId(), WebSession.get().getId());
 				log.debug("WebSocketBehavior::onClose");
 			}
 		});

Added: openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/pages/auth/KickMessageDialog.html
URL: http://svn.apache.org/viewvc/openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/pages/auth/KickMessageDialog.html?rev=1694985&view=auto
==============================================================================
--- openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/pages/auth/KickMessageDialog.html (added)
+++ openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/pages/auth/KickMessageDialog.html Mon Aug 10 08:07:52 2015
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+  
+      http://www.apache.org/licenses/LICENSE-2.0
+    	  
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+  
+-->
+<html xmlns:wicket="http://wicket.apache.org">
+	<wicket:panel>
+		<table>
+			<tr>
+				<td wicket:id="message">[message]</td>
+			</tr>
+		</table>
+	</wicket:panel>
+</html>
\ No newline at end of file

Added: openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/pages/auth/KickMessageDialog.java
URL: http://svn.apache.org/viewvc/openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/pages/auth/KickMessageDialog.java?rev=1694985&view=auto
==============================================================================
--- openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/pages/auth/KickMessageDialog.java (added)
+++ openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/pages/auth/KickMessageDialog.java Mon Aug 10 08:07:52 2015
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License") +  you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.openmeetings.web.pages.auth;
+
+import org.apache.openmeetings.web.app.Application;
+import org.apache.openmeetings.web.app.WebSession;
+import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.markup.html.basic.Label;
+
+import com.googlecode.wicket.jquery.core.JQueryBehavior;
+import com.googlecode.wicket.jquery.core.Options;
+import com.googlecode.wicket.jquery.ui.widget.dialog.AbstractDialog;
+import com.googlecode.wicket.jquery.ui.widget.dialog.DialogButton;
+
+public class KickMessageDialog extends AbstractDialog<String> {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+
+	public KickMessageDialog(String id) {
+		super(id, "");
+		add(new Label("message", Application.getString(606)));
+	}
+
+	@Override
+	protected void onInitialize() {
+		super.onInitialize();
+		add(new JQueryBehavior(JQueryWidget.getSelector(this), "dialog") {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+            protected String $()  {
+                return this.$(Options.asString("open"));
+            }
+        });
+	};
+	
+	@Override
+	public void onConfigure(JQueryBehavior behavior) {
+		super.onConfigure(behavior);
+		behavior.setOption("closeOnEscape", false);
+        behavior.setOption("dialogClass", Options.asString("no-close"));
+        behavior.setOption("resizable", false);
+	}
+
+	public String getOnClickJavaScript() {
+		return "$('#" + getButtons().get(0).getMarkupId() +"').click(function(e){$('#" + getMarkupId() +"').close(); })";
+	}
+
+	@Override
+	public void onClose(AjaxRequestTarget target, DialogButton button) {
+		WebSession.setKickedByAdmin(false);
+		Application.get().restartResponseAtSignInPage();
+	}
+
+}

Modified: openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/pages/auth/RegisterDialog.java
URL: http://svn.apache.org/viewvc/openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/pages/auth/RegisterDialog.java?rev=1694985&r1=1694984&r2=1694985&view=diff
==============================================================================
--- openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/pages/auth/RegisterDialog.java (original)
+++ openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/pages/auth/RegisterDialog.java Mon Aug 10 08:07:52 2015
@@ -42,7 +42,6 @@ import org.apache.openmeetings.util.cryp
 import org.apache.openmeetings.web.app.Application;
 import org.apache.openmeetings.web.app.WebSession;
 import org.apache.openmeetings.web.common.LanguageDropDown;
-import org.apache.openmeetings.web.pages.MainPage;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.markup.html.form.AjaxButton;
 import org.apache.wicket.extensions.validation.validator.RfcCompliantEmailAddressValidator;
@@ -69,7 +68,7 @@ import com.googlecode.wicket.jquery.ui.w
 
 public class RegisterDialog extends AbstractFormDialog<String> {
 	private static final long serialVersionUID = 1L;
-	private static final Logger log = Red5LoggerFactory.getLogger(MainPage.class, webAppRootKey);
+	private static final Logger log = Red5LoggerFactory.getLogger(RegisterDialog.class, webAppRootKey);
 	private DialogButton cancelBtn = new DialogButton("cancel", Application.getString(122));
 	private DialogButton registerBtn = new DialogButton("register", Application.getString(121));
 	private FeedbackPanel feedback = new FeedbackPanel("feedback");

Modified: openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/pages/auth/SignInPage.html
URL: http://svn.apache.org/viewvc/openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/pages/auth/SignInPage.html?rev=1694985&r1=1694984&r2=1694985&view=diff
==============================================================================
--- openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/pages/auth/SignInPage.html (original)
+++ openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/pages/auth/SignInPage.html Mon Aug 10 08:07:52 2015
@@ -38,5 +38,6 @@
 		<div wicket:id="signin"></div>
 		<div wicket:id="register"></div>
 		<div wicket:id="forget"></div>
+		<div wicket:id="kick"></div>
 	</wicket:extend>
 </html>

Modified: openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/pages/auth/SignInPage.java
URL: http://svn.apache.org/viewvc/openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/pages/auth/SignInPage.java?rev=1694985&r1=1694984&r2=1694985&view=diff
==============================================================================
--- openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/pages/auth/SignInPage.java (original)
+++ openmeetings/branches/3.0.x/src/web/java/org/apache/openmeetings/web/pages/auth/SignInPage.java Mon Aug 10 08:07:52 2015
@@ -81,6 +81,7 @@ public class SignInPage extends BaseInit
 	private static final long serialVersionUID = 1L;
 	private static final Logger log = Red5LoggerFactory.getLogger(SignInPage.class, webAppRootKey);
 	private SignInDialog d;
+	private KickMessageDialog m;
 	
 	static boolean allowRegister() {
 		return "1".equals(getBean(ConfigurationDao.class).getConfValue(CONFIG_FRONTEND_REGISTER_KEY, String.class, "0"));
@@ -143,7 +144,9 @@ public class SignInPage extends BaseInit
 		d.setForgetPasswordDialog(f);
 		r.setSignInDialog(d);
 		f.setSignInDialog(d);
-		add(d, r.setVisible(allowRegister()), f);
+		m = new KickMessageDialog("kick");
+		add(d.setVisible(!WebSession.get().isKickedByAdmin()), 
+				r.setVisible(allowRegister()), f, m.setVisible(WebSession.get().isKickedByAdmin()));
 	}
 	
 	public SignInPage() {
@@ -153,8 +156,7 @@ public class SignInPage extends BaseInit
 	@Override
 	public void renderHead(IHeaderResponse response) {
 		super.renderHead(response);
-		//TODO need to be removed if autoOen will be enabled
-		response.render(OnDomReadyHeaderItem.forScript("$('#" + d.getMarkupId() + "').dialog('open');"));
+		response.render(OnDomReadyHeaderItem.forScript(m.getOnClickJavaScript()));
 		response.render(new CssContentHeaderItem(".no-close .ui-dialog-titlebar-close { display: none; }", "dialog-noclose", ""));
 	}