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/09/09 10:12:38 UTC

svn commit: r1701942 - in /openmeetings/trunk/singlewebapp: openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/ openmeetings-db/src/main/java/org/apache/openmeetings/ openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/user/ o...

Author: vdegtyarev
Date: Wed Sep  9 08:12:38 2015
New Revision: 1701942

URL: http://svn.apache.org/r1701942
Log:
OPENMEETINGS-1125 Connections are shown as expected - merge to trunk.

Added:
    openmeetings/trunk/singlewebapp/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/KickMessageDialog.html
    openmeetings/trunk/singlewebapp/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/KickMessageDialog.java
Modified:
    openmeetings/trunk/singlewebapp/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/UserService.java
    openmeetings/trunk/singlewebapp/openmeetings-db/src/main/java/org/apache/openmeetings/IApplication.java
    openmeetings/trunk/singlewebapp/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/user/IUserService.java
    openmeetings/trunk/singlewebapp/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/connection/ConnectionsPanel.html
    openmeetings/trunk/singlewebapp/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/connection/ConnectionsPanel.java
    openmeetings/trunk/singlewebapp/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
    openmeetings/trunk/singlewebapp/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Client.java
    openmeetings/trunk/singlewebapp/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/WebSession.java
    openmeetings/trunk/singlewebapp/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/SignInPage.html
    openmeetings/trunk/singlewebapp/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/SignInPage.java

Modified: openmeetings/trunk/singlewebapp/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/UserService.java
URL: http://svn.apache.org/viewvc/openmeetings/trunk/singlewebapp/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/UserService.java?rev=1701942&r1=1701941&r2=1701942&view=diff
==============================================================================
--- openmeetings/trunk/singlewebapp/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/UserService.java (original)
+++ openmeetings/trunk/singlewebapp/openmeetings-core/src/main/java/org/apache/openmeetings/core/remote/UserService.java Wed Sep  9 08:12:38 2015
@@ -19,11 +19,13 @@
 package org.apache.openmeetings.core.remote;
 
 import static org.apache.openmeetings.util.OpenmeetingsVariables.webAppRootKey;
+import static org.apache.openmeetings.util.OpenmeetingsVariables.wicketApplicationName;
 
 import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 
+import org.apache.openmeetings.IApplication;
 import org.apache.openmeetings.core.remote.red5.ScopeApplicationAdapter;
 import org.apache.openmeetings.db.dao.server.ISessionManager;
 import org.apache.openmeetings.db.dao.server.ServerDao;
@@ -37,6 +39,7 @@ import org.apache.openmeetings.db.entity
 import org.apache.openmeetings.db.entity.user.UserContact;
 import org.apache.openmeetings.db.util.AuthLevelUtil;
 import org.apache.openmeetings.db.util.TimezoneUtil;
+import org.apache.wicket.Application;
 import org.red5.logging.Red5LoggerFactory;
 import org.red5.server.api.scope.IScope;
 import org.slf4j.Logger;
@@ -299,7 +302,21 @@ 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))) {
+				((IApplication)Application.get(wicketApplicationName)).invalidateClient(userId, sessionId);
+			}
+		} catch (Exception err) {
+			log.error("[kickUserBySessionId]", err);
 		}
 		return null;
 	}

Modified: openmeetings/trunk/singlewebapp/openmeetings-db/src/main/java/org/apache/openmeetings/IApplication.java
URL: http://svn.apache.org/viewvc/openmeetings/trunk/singlewebapp/openmeetings-db/src/main/java/org/apache/openmeetings/IApplication.java?rev=1701942&r1=1701941&r2=1701942&view=diff
==============================================================================
--- openmeetings/trunk/singlewebapp/openmeetings-db/src/main/java/org/apache/openmeetings/IApplication.java (original)
+++ openmeetings/trunk/singlewebapp/openmeetings-db/src/main/java/org/apache/openmeetings/IApplication.java Wed Sep  9 08:12:38 2015
@@ -37,4 +37,5 @@ public interface IApplication {
 	String getOmContactsLink();
 	String getOmInvitationLink(String baseUrl, Invitation i);
 	String urlForActivatePage(PageParameters pp);
+	void invalidateClient(Long userId, String sessionId);
 }

Modified: openmeetings/trunk/singlewebapp/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/user/IUserService.java
URL: http://svn.apache.org/viewvc/openmeetings/trunk/singlewebapp/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/user/IUserService.java?rev=1701942&r1=1701941&r2=1701942&view=diff
==============================================================================
--- openmeetings/trunk/singlewebapp/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/user/IUserService.java (original)
+++ openmeetings/trunk/singlewebapp/openmeetings-db/src/main/java/org/apache/openmeetings/db/dao/user/IUserService.java Wed Sep  9 08:12:38 2015
@@ -21,4 +21,6 @@ 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/trunk/singlewebapp/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/connection/ConnectionsPanel.html
URL: http://svn.apache.org/viewvc/openmeetings/trunk/singlewebapp/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/connection/ConnectionsPanel.html?rev=1701942&r1=1701941&r2=1701942&view=diff
==============================================================================
--- openmeetings/trunk/singlewebapp/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/connection/ConnectionsPanel.html (original)
+++ openmeetings/trunk/singlewebapp/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/connection/ConnectionsPanel.html Wed Sep  9 08:12:38 2015
@@ -44,6 +44,16 @@
 						<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>&nbsp;</td>
+					</tr>
+				</tbody>
 			</table>
 		</div>
 		<div class="adminPanelColumnForm">

Modified: openmeetings/trunk/singlewebapp/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/connection/ConnectionsPanel.java
URL: http://svn.apache.org/viewvc/openmeetings/trunk/singlewebapp/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/connection/ConnectionsPanel.java?rev=1701942&r1=1701941&r2=1701942&view=diff
==============================================================================
--- openmeetings/trunk/singlewebapp/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/connection/ConnectionsPanel.java (original)
+++ openmeetings/trunk/singlewebapp/openmeetings-web/src/main/java/org/apache/openmeetings/web/admin/connection/ConnectionsPanel.java Wed Sep  9 08:12:38 2015
@@ -27,11 +27,14 @@ import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 
+import org.apache.openmeetings.core.remote.UserService;
 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.web.admin.AdminPanel;
 import org.apache.openmeetings.web.admin.SearchableDataView;
+import org.apache.openmeetings.web.app.Application;
+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;
@@ -125,6 +128,76 @@ public class ConnectionsPanel extends Ad
 		};
 		add(container.add(dataView).setOutputMarkupId(true), details.setVisible(false).setOutputMarkupPlaceholderTag(true));
 		
+		SearchableDataProvider<org.apache.openmeetings.web.app.Client> sdpWeb = new SearchableDataProvider<org.apache.openmeetings.web.app.Client>(null) {
+			private static final long serialVersionUID = 1L;
+			
+			@Override
+			public Iterator<? extends org.apache.openmeetings.web.app.Client> iterator(long first, long count) {
+				List<org.apache.openmeetings.web.app.Client> l = new ArrayList<org.apache.openmeetings.web.app.Client>(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 containerWeb = new WebMarkupContainer("containerWeb");
+		SearchableDataView<org.apache.openmeetings.web.app.Client> dataViewWeb = new SearchableDataView<org.apache.openmeetings.web.app.Client>("clientListWeb", sdpWeb) {
+			private static final long serialVersionUID = 1L;
+
+			@Override
+			protected void populateItem(final Item<org.apache.openmeetings.web.app.Client> item) {
+				org.apache.openmeetings.web.app.Client 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 ConfirmableAjaxLink("kick", 605) {
+					private static final long serialVersionUID = 1L;
+
+					@Override
+					public void onClick(AjaxRequestTarget target) {
+						org.apache.openmeetings.web.app.Client 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 = org.apache.openmeetings.web.app.Client.class.getDeclaredFields();
+						RepeatingView lines = new RepeatingView("line");
+						org.apache.openmeetings.web.app.Client 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/trunk/singlewebapp/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java
URL: http://svn.apache.org/viewvc/openmeetings/trunk/singlewebapp/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java?rev=1701942&r1=1701941&r2=1701942&view=diff
==============================================================================
--- openmeetings/trunk/singlewebapp/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java (original)
+++ openmeetings/trunk/singlewebapp/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Application.java Wed Sep  9 08:12:38 2015
@@ -27,8 +27,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.Map.Entry;
@@ -38,6 +40,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.IApplication;
 import org.apache.openmeetings.db.dao.basic.ConfigurationDao;
 import org.apache.openmeetings.db.dao.label.LabelDao;
@@ -97,7 +102,8 @@ import ro.fortsoft.wicket.dashboard.web.
 public class Application extends AuthenticatedWebApplication implements IApplication {
 	private static final Logger log = getLogger(Application.class, webAppRootKey);
 	private static boolean isInstalled;
-	private static Map<Long, Set<Client>> ONLINE_USERS = new ConcurrentHashMap<Long, Set<Client>>();
+	private static MultiKeyMap ONLINE_USERS = new MultiKeyMap(); 
+	private static Map<String, org.apache.openmeetings.web.app.Client> INVALID_SESSIONS = new ConcurrentHashMap<String, org.apache.openmeetings.web.app.Client>();
 	private static Map<Long, Set<Client>> ROOMS = new ConcurrentHashMap<Long, Set<Client>>();
 	//additional maps for faster searching should be created
 	private DashboardContext dashboardContext;
@@ -203,25 +209,84 @@ public class Application extends Authent
 		return get().dashboardContext;
 	}
 	
-	public static void addOnlineUser(Client client) {
-		long userId = client.getUserId();
-		if (!ONLINE_USERS.containsKey(userId)) {
-			ONLINE_USERS.put(userId, new ConcurrentHashSet<Client>());
-		}
-		ONLINE_USERS.get(userId).add(client);
+	public synchronized static void addOnlineUser(org.apache.openmeetings.web.app.Client client) {
+		try {
+			ONLINE_USERS.put(client.getUserId(), client.getSessionId(), client);
+		} catch (Exception err) {
+			log.error("[addOnlineUser]", err);
+		}
 	}
 	
-	public static void removeOnlineUser(Client c) {
-		long userId = c.getUserId();
-		if (ONLINE_USERS.containsKey(userId)) {
-			Set<Client> clients = ONLINE_USERS.get(userId);
-			clients.remove(c);
-			if (clients.isEmpty()) {
-				ONLINE_USERS.remove(userId);
+	public synchronized static void removeOnlineUser(org.apache.openmeetings.web.app.Client c) {
+		try {
+			if (c != null) {
+				ONLINE_USERS.remove(c.getUserId(), c.getSessionId());
+			}
+		} catch (Exception err) {
+			log.error("[removeOnlineUser]", err);
+		}
+	}
+	
+	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<org.apache.openmeetings.web.app.Client> getClients() {
+		return new ArrayList<org.apache.openmeetings.web.app.Client>(ONLINE_USERS.values());
+	}
+
+	public static List<org.apache.openmeetings.web.app.Client> getClients(Long userId) {
+		List<org.apache.openmeetings.web.app.Client> result =  new ArrayList<org.apache.openmeetings.web.app.Client>();
+        MapIterator it = ONLINE_USERS.mapIterator();
+        while (it.hasNext()) {
+            MultiKey multi = (MultiKey) it.next();
+            if (multi.size() > 1 && userId.equals(multi.getKey(0))){
+            	result.add(getClientByKeys(userId, (String)(multi.getKey(1))));
+            	break;
+            }
+        }
+        return result;
+	}
+	
+	public static int getClientsSize() {
+		return ONLINE_USERS.size();
+	}
+	
+	public static org.apache.openmeetings.web.app.Client getClientByKeys(Long userId, String sessionId) {
+		return (org.apache.openmeetings.web.app.Client) ONLINE_USERS.get(userId, sessionId);
+	}
+	
+	@Override
+	public void invalidateClient(Long userId, String sessionId) {
+		org.apache.openmeetings.web.app.Client client = getClientByKeys(userId, sessionId);
+		if (client != null) {
+			if (!INVALID_SESSIONS.containsKey(client.getSessionId())) {
+				INVALID_SESSIONS.put(client.getSessionId(), client);
+				removeOnlineUser(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);
+		}
+	}
+	
 	public static Client addUserToRoom(long roomId, int pageId) {
 		if (!ROOMS.containsKey(roomId)) {
 			ROOMS.put(roomId, new ConcurrentHashSet<Client>());
@@ -290,14 +355,6 @@ public class Application extends Authent
 		return false;
 	}
 	
-	public static boolean isUserOnline(long userId) {
-		return ONLINE_USERS.containsKey(userId);
-	}
-	
-	public static Set<Client> getClients(long userId) {
-		return ONLINE_USERS.containsKey(userId) ? ONLINE_USERS.get(userId) : new HashSet<Client>();
-	}
-	
 	//TODO need more safe way FIXME
 	public <T> T _getBean(Class<T> clazz) {
 		WebApplicationContext wac = getWebApplicationContext(getServletContext());

Modified: openmeetings/trunk/singlewebapp/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Client.java
URL: http://svn.apache.org/viewvc/openmeetings/trunk/singlewebapp/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Client.java?rev=1701942&r1=1701941&r2=1701942&view=diff
==============================================================================
--- openmeetings/trunk/singlewebapp/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Client.java (original)
+++ openmeetings/trunk/singlewebapp/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/Client.java Wed Sep  9 08:12:38 2015
@@ -19,9 +19,11 @@
 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;
 
 /**
@@ -29,7 +31,7 @@ import org.apache.wicket.protocol.ws.api
  * @author solomax
  *
  */
-public class Client implements Serializable {
+public class Client implements IDataProviderEntity, Serializable {
 	private static final long serialVersionUID = 1L;
 
 	public enum Right {
@@ -40,8 +42,10 @@ public class Client implements Serializa
 	private long userId;
 	private String uid;
 	private Set<Right> rights = new HashSet<Right>();
+	private Date connectedSince;
 
 	public Client() {
+		this.connectedSince = new Date();
 	}
 	
 	public Client(String sessionId, IKey key, long userId) {
@@ -52,6 +56,7 @@ public class Client implements Serializa
 		this.sessionId = sessionId;
 		this.pageId = pageId;
 		this.userId = userId;
+		this.connectedSince = new Date();
 	}
 
 	public String getSessionId() {
@@ -124,4 +129,24 @@ public class Client implements Serializa
 	public boolean hasRight(Right right) {
 		return rights.contains(Right.moderator) ? true : rights.contains(right);
 	}
+
+	public Date getConnectedSince() {
+		return connectedSince;
+	}
+
+	public void setConnectedSince(Date connectedSince) {
+		this.connectedSince = connectedSince;
+	}
+
+	@Override
+	public Long getId() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	@Override
+	public void setId(Long id) {
+		// TODO Auto-generated method stub
+		
+	}
 }

Modified: openmeetings/trunk/singlewebapp/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/WebSession.java
URL: http://svn.apache.org/viewvc/openmeetings/trunk/singlewebapp/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/WebSession.java?rev=1701942&r1=1701941&r2=1701942&view=diff
==============================================================================
--- openmeetings/trunk/singlewebapp/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/WebSession.java (original)
+++ openmeetings/trunk/singlewebapp/openmeetings-web/src/main/java/org/apache/openmeetings/web/app/WebSession.java Wed Sep  9 08:12:38 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>();
@@ -296,6 +302,7 @@ public class WebSession extends Abstract
 	}
 	
 	public static long getLanguage() {
+		checkIsInvalid();
 		WebSession session = get();
 		if (session.languageId < 0) {
 			if (session.isSignedIn()) {
@@ -330,6 +337,7 @@ public class WebSession extends Abstract
 	}
 
 	public static long getUserId() {
+		checkIsInvalid();
 		return get().userId;
 	}
 	
@@ -362,8 +370,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
 	public long getOmLanguage() {
 		return getLanguage();
 	}
+	
+	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();
+		}
+	}
 }

Added: openmeetings/trunk/singlewebapp/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/KickMessageDialog.html
URL: http://svn.apache.org/viewvc/openmeetings/trunk/singlewebapp/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/KickMessageDialog.html?rev=1701942&view=auto
==============================================================================
--- openmeetings/trunk/singlewebapp/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/KickMessageDialog.html (added)
+++ openmeetings/trunk/singlewebapp/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/KickMessageDialog.html Wed Sep  9 08:12:38 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/trunk/singlewebapp/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/KickMessageDialog.java
URL: http://svn.apache.org/viewvc/openmeetings/trunk/singlewebapp/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/KickMessageDialog.java?rev=1701942&view=auto
==============================================================================
--- openmeetings/trunk/singlewebapp/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/KickMessageDialog.java (added)
+++ openmeetings/trunk/singlewebapp/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/KickMessageDialog.java Wed Sep  9 08:12:38 2015
@@ -0,0 +1,75 @@
+/*
+ * 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.core.request.handler.IPartialPageRequestHandler;
+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(IPartialPageRequestHandler arg0, DialogButton arg1) {
+		WebSession.setKickedByAdmin(false);
+		Application.get().restartResponseAtSignInPage();
+	}
+
+}

Modified: openmeetings/trunk/singlewebapp/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/SignInPage.html
URL: http://svn.apache.org/viewvc/openmeetings/trunk/singlewebapp/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/SignInPage.html?rev=1701942&r1=1701941&r2=1701942&view=diff
==============================================================================
--- openmeetings/trunk/singlewebapp/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/SignInPage.html (original)
+++ openmeetings/trunk/singlewebapp/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/SignInPage.html Wed Sep  9 08:12:38 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/trunk/singlewebapp/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/SignInPage.java
URL: http://svn.apache.org/viewvc/openmeetings/trunk/singlewebapp/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/SignInPage.java?rev=1701942&r1=1701941&r2=1701942&view=diff
==============================================================================
--- openmeetings/trunk/singlewebapp/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/SignInPage.java (original)
+++ openmeetings/trunk/singlewebapp/openmeetings-web/src/main/java/org/apache/openmeetings/web/pages/auth/SignInPage.java Wed Sep  9 08:12:38 2015
@@ -75,6 +75,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"));
@@ -137,7 +138,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() {
@@ -147,8 +150,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", ""));
 	}