/**
* Copyright (c) 2009--2013 Red Hat, Inc.
*
* This software is licensed to you under the GNU General Public License,
* version 2 (GPLv2). There is NO WARRANTY for this software, express or
* implied, including the implied warranties of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
* along with this software; if not, see
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
*
* Red Hat trademarks are not licensed under GPLv2. No permission is
* granted to use or replicate Red Hat trademarks that are incorporated
* in this software or its documentation.
*/
package com.redhat.rhn.frontend.servlets;
import com.redhat.rhn.common.util.TimeUtils;
import com.redhat.rhn.domain.session.WebSession;
import com.redhat.rhn.domain.session.WebSessionFactory;
import com.redhat.rhn.manager.session.SessionManager;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* PxtSessionDelegateImpl is an implementation of PxtSessionDelegate that wraps a
* RequestContext object.
*
* @see PxtSessionDelegate
* @see com.redhat.rhn.frontend.struts.RequestContext
* @version $Rev$
*/
public class PxtSessionDelegateImpl implements PxtSessionDelegate {
private PxtCookieManager pxtCookieManager;
protected PxtSessionDelegateImpl() {
pxtCookieManager = new PxtCookieManager();
}
/**
* {@inheritDoc}
*/
public WebSession getPxtSession(HttpServletRequest request) {
loadPxtSession(request);
return (WebSession)request.getAttribute("session");
}
/**
* {@inheritDoc}
*/
public WebSession getPxtSessionIfExists(HttpServletRequest request) {
Object sessionAttribute = request.getAttribute("session");
if (!(sessionAttribute instanceof WebSession)) {
Long pxtSessionId = getPxtSessionId(request);
if (pxtSessionId != null) {
sessionAttribute = findPxtSessionById(pxtSessionId);
}
request.setAttribute("session", sessionAttribute);
}
return (WebSession)sessionAttribute;
}
/**
* {@inheritDoc}
*/
public Long getWebUserId(HttpServletRequest request) {
WebSession session = getPxtSessionIfExists(request);
return ((session == null) ? null : session.getWebUserId());
}
/**
* {@inheritDoc}
*/
public void updateWebUserId(HttpServletRequest request, HttpServletResponse response,
Long id) {
// generate new session to prevent session fixation (BZ 672159)
Object sessionAttribute = createPxtSession(id);
request.setAttribute("session", sessionAttribute);
refreshPxtSession(request, response);
}
/**
* {@inheritDoc}
*/
public boolean isPxtSessionExpired(HttpServletRequest request) {
return getPxtSession(request).isExpired();
}
/**
* {@inheritDoc}
*/
public boolean isPxtSessionKeyValid(HttpServletRequest request) {
Cookie pxtCookie = pxtCookieManager.getPxtCookie(request);
return pxtCookie != null &&
SessionManager.isPxtSessionKeyValid(pxtCookie.getValue());
}
/**
* Loads the pxt session and stores it in the request as an attribute named
* <code>session</code>. If the pxt session is not already present in the request,
* it is fetched from the database if the pxt cookie is available. If the pxt cookie
* is not available, a new pxt session is created.
*
* @param request The current request.
*/
protected void loadPxtSession(HttpServletRequest request) {
Object sessionAttribute = request.getAttribute("session");
if (!(sessionAttribute instanceof WebSession)) {
Long pxtSessionId = getPxtSessionId(request);
if (pxtSessionId != null) {
sessionAttribute = findPxtSessionById(pxtSessionId);
}
// There is a scenario in which the pxt session will not be found above even
// though the request contains a session id. If a logged in user sends a request
// over HTTP, EnvironmentFilter intercepts the request, invalidates the pxt
// session, and redirects the request over HTTPS. When this occurs, the pxt
// cookie still exists, but the session id that it carries is now invalid.
// Consequently, a new pxt session will need to be created.
if (sessionAttribute == null) {
sessionAttribute = createPxtSession(null);
}
request.setAttribute("session", sessionAttribute);
}
}
/**
* Parses the pxt session id out of the pxt cookie if it included in the request.
*
* @param request The current request.
*
* @return The pxt session id parsed out of the pxt cookie, if the cookie is included in
* the request. Return <code>null</code> if the pxt cookie is not found or if the key
* is invalid.
*/
protected Long getPxtSessionId(HttpServletRequest request) {
Cookie pxtCookie = pxtCookieManager.getPxtCookie(request);
if (pxtCookie == null) {
return null;
}
if (!SessionManager.isPxtSessionKeyValid(pxtCookie.getValue())) {
return null;
}
String[] tokens = pxtCookie.getValue().split("x");
return Long.valueOf(tokens[0]);
}
/**
* Retrieves the pxt session with the given ID. This method simply wraps a call to
* <code>WebSessionFactory</code>. This makes it easier to write tests that can avoid
* calls to <code>WebSessionFactory</code>, which would result in database calls.
*
* @param id The session ID to search by.
* @return The pxt session or <code>null</code> if no session is found.
* @see WebSessionFactory#lookupById(Long)
*/
protected WebSession findPxtSessionById(Long id) {
return WebSessionFactory.lookupById(id);
}
/**
* Creates a new pxt session. This method simply wraps a call to <code>SessionManager
* </code>. This makes it easier to write tests that can avoid calls to
* <code>SessionManager</code>, which would result in database calls.
*
* @param uid The user id to create the session for.
* @return A new pxt session.
* @see SessionManager#makeSession(Long, long)
*/
protected WebSession createPxtSession(Long uid) {
return SessionManager.makeSession(uid, SessionManager.lifetimeValue());
}
/**
* {@inheritDoc}
*/
public void refreshPxtSession(HttpServletRequest request,
HttpServletResponse response) {
refreshPxtSession(request, response, (int)SessionManager.lifetimeValue());
}
private void refreshPxtSession(HttpServletRequest request,
HttpServletResponse response, int pxtCookieExpiration) {
WebSession pxtSession = getPxtSession(request);
Cookie pxtCookie = pxtCookieManager.createPxtCookie(pxtSession.getId(), request,
pxtCookieExpiration);
pxtSession.setExpires(TimeUtils.currentTimeSeconds() +
SessionManager.lifetimeValue());
savePxtSession(pxtSession);
response.addCookie(pxtCookie);
}
/**
* This method is a hook for testing.
*
* @param pxtSession The session to be saved
*/
protected void savePxtSession(WebSession pxtSession) {
WebSessionFactory.save(pxtSession);
}
/**
* {@inheritDoc}
*/
public void invalidatePxtSession(HttpServletRequest request,
HttpServletResponse response) {
//updateWebUserId(request, response, null);
WebSession pxtSession = getPxtSession(request);
pxtSession.setWebUserId(null);
// Invalidate csrf_token
request.getSession().setAttribute("csrf_token", null);
refreshPxtSession(request, response, 0);
}
}