Commit 88d6b2af by Tuukka Kivilahti

Merge branch 'sessionlist' into 'master'

Sessionlist

Add hostname to user session list and make the ui prettier and more sortable.

See merge request !271
2 parents 75be0a1d cfb52bff
...@@ -39,6 +39,24 @@ public interface SessionMgmtBeanLocal { ...@@ -39,6 +39,24 @@ public interface SessionMgmtBeanLocal {
void updateSessionUser(String sessionId, String user); void updateSessionUser(String sessionId, String user);
String getUsername(String sessionId); UserContainer getUsername(String sessionId);
public static class UserContainer {
private final String hostname;
private final String username;
public UserContainer(String hostname, String username) {
this.hostname = hostname;
this.username = username;
}
public String getHostname() {
return hostname;
}
public String getUsername() {
return username;
}
}
} }
...@@ -36,6 +36,7 @@ import javax.servlet.http.HttpSession; ...@@ -36,6 +36,7 @@ import javax.servlet.http.HttpSession;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import fi.codecrew.moya.clientutils.BortalLocalContextHolder;
import fi.codecrew.moya.enums.apps.UserPermission; import fi.codecrew.moya.enums.apps.UserPermission;
/** /**
...@@ -55,7 +56,7 @@ public class SessionMgmtBean implements SessionMgmtBeanLocal { ...@@ -55,7 +56,7 @@ public class SessionMgmtBean implements SessionMgmtBeanLocal {
// TODO Auto-generated constructor stub // TODO Auto-generated constructor stub
} }
private final ConcurrentHashMap<String, String> sessionUsers = new ConcurrentHashMap<String, String>(); private final ConcurrentHashMap<String, UserContainer> sessionUsers = new ConcurrentHashMap<>();
private final Set<HttpSession> sessions = Collections.newSetFromMap(new ConcurrentHashMap<HttpSession, Boolean>()); private final Set<HttpSession> sessions = Collections.newSetFromMap(new ConcurrentHashMap<HttpSession, Boolean>());
@SuppressWarnings("unused") @SuppressWarnings("unused")
...@@ -65,7 +66,7 @@ public class SessionMgmtBean implements SessionMgmtBeanLocal { ...@@ -65,7 +66,7 @@ public class SessionMgmtBean implements SessionMgmtBeanLocal {
public void updateSessionUser(String sessionId, String user) { public void updateSessionUser(String sessionId, String user) {
if (!sessionUsers.containsKey(sessionId)) { if (!sessionUsers.containsKey(sessionId)) {
sessionUsers.put(sessionId, user); sessionUsers.put(sessionId, new UserContainer(BortalLocalContextHolder.getHostname(), user));
} }
} }
...@@ -87,7 +88,7 @@ public class SessionMgmtBean implements SessionMgmtBeanLocal { ...@@ -87,7 +88,7 @@ public class SessionMgmtBean implements SessionMgmtBeanLocal {
} }
@Override @Override
public String getUsername(String sessionId) { public UserContainer getUsername(String sessionId) {
return sessionUsers.get(sessionId); return sessionUsers.get(sessionId);
} }
......
<!DOCTYPE html <!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" <html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:p="http://primefaces.org/ui">
xmlns:c="http://java.sun.com/jsp/jstl/core">
<h:body> <h:body>
<ui:composition template="#{sessionHandler.template}"> <ui:composition template="#{sessionHandler.template}">
<f:metadata> <f:metadata>
...@@ -11,59 +10,48 @@ ...@@ -11,59 +10,48 @@
<ui:define name="content"> <ui:define name="content">
<h:form> <h:form>
<h:dataTable value="#{userSessionView.sessions}" var="sess"> <p:dataTable sort value="#{userSessionView.sessions}" var="sess" sortBy="#{sess.id}">
<h:column> <p:column headerText="#{i18n['httpsession.id']}">
<f:facet name="header">
<h:outputText value="#{i18n['httpsession.id']}" />
</f:facet>
<h:outputText value="#{sess.id}" /> <h:outputText value="#{sess.id}" />
</h:column> </p:column>
<h:column>
<f:facet name="header"> <p:column headerText="#{i18n['httpsession.user']}" sortBy="#{sess.username}">
<h:outputText value="#{i18n['httpsession.user']}" /> <h:outputText value="#{sess.username}" />
</f:facet> </p:column>
<h:outputText value="#{sess.id}" converter="#{sessionToUsernameConverter}" />
</h:column> <p:column headerText="#{i18n['httpsession.hostname']}" sortBy="#{sess.hostname}">
<h:column> <h:outputText value="#{sess.hostname}" />
<f:facet name="header"> </p:column>
<h:outputText value="#{i18n['httpsession.creationTime']}" />
</f:facet> <p:column sortBy="#{sessionHandler.creationDateTime}" headerText="#{i18n['httpsession.creationTime']}">
<h:outputText value="#{sess.creationDateTime}"> <h:outputText value="#{sess.creationDateTime}">
<f:convertDateTime pattern="#{sessionHandler.shortDatetimeFormat}" timeZone="#{sessionHandler.timezone}" /> <f:convertDateTime pattern="#{sessionHandler.shortDatetimeFormat}" timeZone="#{sessionHandler.timezone}" />
</h:outputText> </h:outputText>
</h:column> </p:column>
<h:column>
<f:facet name="header"> <p:column sortBy="#{sessionHandler.lastAccessedDateTime}" headerText="#{i18n['httpsession.lastAccessedTime']}">
<h:outputText value="#{i18n['httpsession.lastAccessedTime']}" />
</f:facet>
<h:outputText value="#{sess.lastAccessedDateTime}"> <h:outputText value="#{sess.lastAccessedDateTime}">
<f:convertDateTime pattern="#{sessionHandler.shortDatetimeFormat}" timeZone="#{sessionHandler.timezone}" /> <f:convertDateTime pattern="#{sessionHandler.shortDatetimeFormat}" timeZone="#{sessionHandler.timezone}" />
</h:outputText> </h:outputText>
</h:column> </p:column>
<h:column>
<f:facet name="header"> <p:column headerText="#{i18n['httpsession.sessionHasExisted']}">
<h:outputText value="#{i18n['httpsession.sessionHasExisted']}" />
</f:facet>
<h:outputText value="#{sess.lastAccessedTime - sess.creationTime}" /> <h:outputText value="#{sess.lastAccessedTime - sess.creationTime}" />
</h:column> </p:column>
<h:column>
<f:facet name="header"> <p:column headerText="#{i18n['httpsession.maxInactiveInterval']}">
<h:outputText value="#{i18n['httpsession.maxInactiveInterval']}" />
</f:facet>
<h:outputText value="#{sess.maxInactiveInterval}" /> <h:outputText value="#{sess.maxInactiveInterval}" />
</h:column> </p:column>
<h:column>
<f:facet name="header"> <p:column headerText="#{i18n['httpsession.isSessionNew']}">
<h:outputText value="#{i18n['httpsession.isSessionNew']}" />
</f:facet>
<h:outputText value="#{sess.new}" /> <h:outputText value="#{sess.new}" />
</h:column> </p:column>
<h:column>
<p:column>
<h:commandButton action="#{userSessionView.invalidateSession}" value="#{i18n['httpsession.invalidate']}" /> <h:commandButton action="#{userSessionView.invalidateSession}" value="#{i18n['httpsession.invalidate']}" />
</h:column> </p:column>
</h:dataTable> </p:dataTable>
</h:form> </h:form>
</ui:define> </ui:define>
......
...@@ -107,6 +107,9 @@ public class HostnameFilter implements Filter { ...@@ -107,6 +107,9 @@ public class HostnameFilter implements Filter {
* @param authType * @param authType
*/ */
void insertLoggingContext(HttpServletRequest request, AuthType authType) { void insertLoggingContext(HttpServletRequest request, AuthType authType) {
if (request == null)
return;
Principal userPrincipal = request.getUserPrincipal(); Principal userPrincipal = request.getUserPrincipal();
if (userPrincipal != null) { if (userPrincipal != null) {
String userString = userPrincipal.getName(); String userString = userPrincipal.getName();
...@@ -187,7 +190,7 @@ public class HostnameFilter implements Filter { ...@@ -187,7 +190,7 @@ public class HostnameFilter implements Filter {
} }
// pass the request along the filter chain // pass the request along the filter chain
try { try {
insertLoggingContext((HttpServletRequest) request, authtype); insertLoggingContext(httpRequest, authtype);
chain.doFilter(request, response); chain.doFilter(request, response);
} catch (Exception t) { } catch (Exception t) {
if (AuthType.REST == authtype) { if (AuthType.REST == authtype) {
......
...@@ -48,9 +48,8 @@ public class UserSessionView extends GenericCDIView { ...@@ -48,9 +48,8 @@ public class UserSessionView extends GenericCDIView {
public void initView() public void initView()
{ {
if (super.requirePermissions(UserPermission.MANAGE_HTTP_SESSION) && sessions == null) if (super.requirePermissions(UserPermission.MANAGE_HTTP_SESSION) && sessions == null) {
{ sessions = new ListDataModel<>(HttpSessionWrapper.wrap(sessionMgmt.getSessions(),sessionMgmt));
sessions = new ListDataModel<>(HttpSessionWrapper.wrap(sessionMgmt.getSessions()));
super.beginConversation(); super.beginConversation();
} }
} }
......
/*
* Copyright Codecrew Ry
*
* All rights reserved.
*
* This license applies to any software containing a notice placed by the
* copyright holder. Such software is herein referred to as the Software.
* This license covers modification, distribution and use of the Software.
*
* Any distribution and use in source and binary forms, with or without
* modification is not permitted without explicit written permission from the
* copyright owner.
*
* A non-exclusive royalty-free right is granted to the copyright owner of the
* Software to use, modify and distribute all modifications to the Software in
* future versions of the Software.
*
*/
package fi.codecrew.moya.web.converter;
import javax.ejb.EJB;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.inject.Named;
import fi.codecrew.moya.beans.SessionMgmtBeanLocal;
import fi.codecrew.moya.beans.SessionMgmtBeanLocal.UserContainer;
import fi.codecrew.moya.utilities.I18n;
@Named()
public class SessionToHostnameConverter implements Converter {
@EJB
private SessionMgmtBeanLocal sessbean;
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
return null;
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
String ret = "";
if (value != null) {
UserContainer retCont = sessbean.getUsername(value.toString());
if (retCont != null)
ret = retCont.getHostname();
}
if (ret == null || ret.isEmpty()) {
ret = I18n.get("user.unauthenticated");
}
return ret;
}
}
...@@ -25,6 +25,7 @@ import javax.faces.convert.Converter; ...@@ -25,6 +25,7 @@ import javax.faces.convert.Converter;
import javax.inject.Named; import javax.inject.Named;
import fi.codecrew.moya.beans.SessionMgmtBeanLocal; import fi.codecrew.moya.beans.SessionMgmtBeanLocal;
import fi.codecrew.moya.beans.SessionMgmtBeanLocal.UserContainer;
import fi.codecrew.moya.utilities.I18n; import fi.codecrew.moya.utilities.I18n;
@Named() @Named()
...@@ -41,12 +42,12 @@ public class SessionToUsernameConverter implements Converter { ...@@ -41,12 +42,12 @@ public class SessionToUsernameConverter implements Converter {
@Override @Override
public String getAsString(FacesContext context, UIComponent component, Object value) { public String getAsString(FacesContext context, UIComponent component, Object value) {
String ret = ""; String ret = "";
if (value != null) if (value != null) {
{ UserContainer retCont = sessbean.getUsername(value.toString());
ret = sessbean.getUsername(value.toString()); if(retCont != null)
ret = retCont.getUsername();
} }
if (ret == null || ret.isEmpty()) if (ret == null || ret.isEmpty()) {
{
ret = I18n.get("user.unauthenticated"); ret = I18n.get("user.unauthenticated");
} }
return ret; return ret;
......
...@@ -30,12 +30,19 @@ import javax.servlet.ServletContext; ...@@ -30,12 +30,19 @@ import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionContext; import javax.servlet.http.HttpSessionContext;
import fi.codecrew.moya.beans.SessionMgmtBeanLocal;
import fi.codecrew.moya.beans.SessionMgmtBeanLocal.UserContainer;
public class HttpSessionWrapper implements HttpSession public class HttpSessionWrapper implements HttpSession
{ {
private final HttpSession session; private final HttpSession session;
private final String hostname;
private final String username;
public HttpSessionWrapper(HttpSession session) public HttpSessionWrapper(HttpSession session, String username, String hostname)
{ {
this.username = username;
this.hostname = hostname;
this.session = session; this.session = session;
} }
...@@ -146,22 +153,31 @@ public class HttpSessionWrapper implements HttpSession ...@@ -146,22 +153,31 @@ public class HttpSessionWrapper implements HttpSession
session.setMaxInactiveInterval(arg0); session.setMaxInactiveInterval(arg0);
} }
public static List<HttpSessionWrapper> wrap(Set<HttpSession> sessions) { public static List<HttpSessionWrapper> wrap(Set<HttpSession> sessions, SessionMgmtBeanLocal sessionMgmt) {
ArrayList<HttpSessionWrapper> ret = new ArrayList<>(); ArrayList<HttpSessionWrapper> ret = new ArrayList<>();
for (HttpSession s : sessions) { for (HttpSession s : sessions) {
ret.add(new HttpSessionWrapper(s)); UserContainer uc = sessionMgmt.getUsername(s.getId());
ret.add(new HttpSessionWrapper(s, uc.getUsername(), uc.getHostname()));
} }
Collections.sort(ret, new LastSeenComparator()); Collections.sort(ret, new LastSeenComparator());
return ret; return ret;
} }
public String getUsername() {
return username;
}
public String getHostname() {
return hostname;
}
private static class LastSeenComparator implements Comparator<HttpSessionWrapper> private static class LastSeenComparator implements Comparator<HttpSessionWrapper>
{ {
@Override @Override
public int compare(HttpSessionWrapper o1, HttpSessionWrapper o2) { public int compare(HttpSessionWrapper o1, HttpSessionWrapper o2) {
return Long.compare(o1.getLastAccessedTime(), o2.getLastAccessedTime()); return Long.compare(o2.getLastAccessedTime(), o1.getLastAccessedTime());
} }
} }
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!