/*
- * Copyright (C) 2007-2012 Mathieu Baudier
+ * Copyright (C) 2007-2012 Argeo GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
package org.argeo.jackrabbit.remote;
import java.io.Serializable;
-import java.util.List;
import javax.jcr.LoginException;
import javax.jcr.Repository;
import org.apache.commons.logging.LogFactory;
import org.apache.jackrabbit.server.SessionProvider;
import org.argeo.ArgeoException;
+import org.argeo.jcr.ArgeoJcrConstants;
import org.argeo.jcr.JcrUtils;
+import org.springframework.security.Authentication;
+import org.springframework.security.context.SecurityContextHolder;
/**
* Session provider assuming a single workspace and a short life cycle,
*/
public class ScopedSessionProvider implements SessionProvider, Serializable {
private static final long serialVersionUID = 6589775984177317058L;
- private final static Log log = LogFactory
+ private static final Log log = LogFactory
.getLog(ScopedSessionProvider.class);
-
private transient HttpSession httpSession = null;
private transient Session jcrSession = null;
private transient String currentRepositoryName = null;
private transient String currentWorkspaceName = null;
+ private transient String currentJcrUser = null;
+
+ // private transient String anonymousUserId = "anonymous";
public Session getSession(HttpServletRequest request, Repository rep,
String workspace) throws LoginException, ServletException,
RepositoryException {
+ Authentication authentication = SecurityContextHolder.getContext()
+ .getAuthentication();
+ if (authentication == null)
+ throw new ArgeoException(
+ "Request not authenticated by Spring Security");
+ String springUser = authentication.getName();
+
+ // HTTP
+ String requestJcrRepository = (String) request
+ .getAttribute(ArgeoJcrConstants.JCR_REPOSITORY_ALIAS);
+
// HTTP session
if (httpSession != null
&& !httpSession.getId().equals(request.getSession().getId()))
if (httpSession == null)
httpSession = request.getSession();
+ // Initializes current values
+ if (currentRepositoryName == null)
+ currentRepositoryName = requestJcrRepository;
if (currentWorkspaceName == null)
currentWorkspaceName = workspace;
+ if (currentJcrUser == null)
+ currentJcrUser = springUser;
+
+ // logout if there was a change in session coordinates
+ if (jcrSession != null)
+ if (!currentRepositoryName.equals(requestJcrRepository)) {
+ if (log.isDebugEnabled())
+ log.debug(getHttpSessionId() + " Changed from repository '"
+ + currentRepositoryName + "' to '"
+ + requestJcrRepository
+ + "', logging out cached JCR session.");
+ logout();
+ } else if (!currentWorkspaceName.equals(workspace)) {
+ if (log.isDebugEnabled())
+ log.debug(getHttpSessionId() + " Changed from workspace '"
+ + currentWorkspaceName + "' to '" + workspace
+ + "', logging out cached JCR session.");
+ logout();
+ } else if (!currentJcrUser.equals(springUser)) {
+ if (log.isDebugEnabled())
+ log.debug(getHttpSessionId() + " Changed from user '"
+ + currentJcrUser + "' to '" + springUser
+ + "', logging out cached JCR session.");
+ logout();
+ }
- // TODO optimize
- String pathInfo = request.getPathInfo();
- List<String> tokens = JcrUtils.tokenize(pathInfo);
- if (currentRepositoryName == null)
- currentRepositoryName = tokens.get(0);
- else if (!currentRepositoryName.equals(tokens.get(0))
- || !currentWorkspaceName.equals(workspace)) {
- JcrUtils.logoutQuietly(jcrSession);
- jcrSession = null;
- if (log.isDebugEnabled())
- log.debug(getHttpSessionId()
- + " Changed repository or workspace, logging out of "
- + currentWorkspaceName);
- }
-
- // JCR session
+ // login if needed
if (jcrSession == null)
try {
- jcrSession = login(rep, workspace);
- currentRepositoryName = tokens.get(0);
+ Session session = login(rep, workspace);
+ if (!session.getUserID().equals(springUser)) {
+ JcrUtils.logoutQuietly(session);
+ throw new ArgeoException("Spring Security user '"
+ + springUser + "' not in line with JCR user '"
+ + session.getUserID() + "'");
+ }
+ currentRepositoryName = requestJcrRepository;
// do not use workspace variable which may be null
- currentWorkspaceName = jcrSession.getWorkspace().getName();
+ currentWorkspaceName = session.getWorkspace().getName();
+ currentJcrUser = session.getUserID();
+
+ jcrSession = session;
return jcrSession;
} catch (RepositoryException e) {
throw new ArgeoException("Cannot open session to workspace "
+ workspace, e);
}
- else
- return jcrSession;
+
+ // returns cached session
+ return jcrSession;
}
protected Session login(Repository repository, String workspace)
log.trace(getHttpSessionId() + " Releasing JCR session " + session);
}
+ protected void logout() {
+ JcrUtils.logoutQuietly(jcrSession);
+ jcrSession = null;
+ }
+
protected final String getHttpSessionId() {
return httpSession != null ? httpSession.getId() : "<null>";
}
}
public void destroy() {
- JcrUtils.logoutQuietly(jcrSession);
- jcrSession = null;
- if (log.isDebugEnabled())
- log.debug(getHttpSessionId()
- + " Cleaned up provider for web session ");
+ logout();
+ if (getHttpSessionId() != null)
+ if (log.isDebugEnabled())
+ log.debug(getHttpSessionId()
+ + " Cleaned up provider for web session ");
httpSession = null;
}
-}
\ No newline at end of file
+
+}