mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
. Final phase of web-client Guest Access
. Fix of UserTransaction handling in AuthenticationHelper - very noticable when Guest access fails on older (pre 1.2) databases . Refactoring of all servlet authentication patterns to be consistent and use a helper so all support Guest and Ticket arguments . Fix to external URL generation on Document and Space Details pages git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@2214 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -48,26 +48,48 @@ import org.springframework.web.context.support.WebApplicationContextUtils;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper to authenticate the current user using available Ticket information.
|
* Helper to authenticate the current user using available Ticket information.
|
||||||
|
* <p>
|
||||||
|
* User information is looked up in the Session. If found the ticket is retrieved and validated.
|
||||||
|
* If the ticket is invalid then a redirect is performed to the login page.
|
||||||
|
* <p>
|
||||||
|
* If no User info is found then a search will be made for a previous username stored in a Cookie
|
||||||
|
* value. If the username if found then a redirect to the Login page will occur. If no username
|
||||||
|
* is found then Guest access login will be attempted by the system. Guest access can be forced
|
||||||
|
* with the appropriate method call.
|
||||||
*
|
*
|
||||||
* @author Kevin Roast
|
* @author Kevin Roast
|
||||||
*/
|
*/
|
||||||
public final class AuthenticationHelper
|
public final class AuthenticationHelper
|
||||||
{
|
{
|
||||||
|
public static final String FACES_SERVLET = "/faces";
|
||||||
|
|
||||||
|
/** session variables */
|
||||||
public static final String AUTHENTICATION_USER = "_alfAuthTicket";
|
public static final String AUTHENTICATION_USER = "_alfAuthTicket";
|
||||||
public static final String SESSION_USERNAME = "_alfLastUser";
|
public static final String SESSION_USERNAME = "_alfLastUser";
|
||||||
public static final String SESSION_INVALIDATED = "_alfSessionInvalid";
|
public static final String SESSION_INVALIDATED = "_alfSessionInvalid";
|
||||||
|
|
||||||
|
/** JSF bean IDs */
|
||||||
public static final String LOGIN_BEAN = "LoginBean";
|
public static final String LOGIN_BEAN = "LoginBean";
|
||||||
|
|
||||||
|
/** public service bean IDs **/
|
||||||
|
private static final String AUTHENTICATION_SERVICE = "AuthenticationService";
|
||||||
|
private static final String UNPROTECTED_AUTH_SERVICE = "authenticationService";
|
||||||
|
private static final String PERSON_SERVICE = "personService";
|
||||||
|
|
||||||
|
/** cookie names */
|
||||||
private static final String COOKIE_ALFUSER = "alfUser";
|
private static final String COOKIE_ALFUSER = "alfUser";
|
||||||
|
|
||||||
private static Log logger = LogFactory.getLog(AuthenticationHelper.class);
|
private static Log logger = LogFactory.getLog(AuthenticationHelper.class);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper to authenticate the current user using session based Ticket information.
|
* Helper to authenticate the current user using session based Ticket information.
|
||||||
* <p>
|
* <p>
|
||||||
* User information is looked up in the Session. If found the ticket is retrieved and validated.
|
* User information is looked up in the Session. If found the ticket is retrieved and validated.
|
||||||
* If no User info is found or the ticket is invalid then a redirect is performed to the login page.
|
* If no User info is found or the ticket is invalid then a redirect is performed to the login page.
|
||||||
*
|
*
|
||||||
|
* @param guest True to force a Guest login attempt
|
||||||
|
*
|
||||||
* @return AuthenticationStatus result.
|
* @return AuthenticationStatus result.
|
||||||
*/
|
*/
|
||||||
public static AuthenticationStatus authenticate(
|
public static AuthenticationStatus authenticate(
|
||||||
@@ -91,10 +113,14 @@ public final class AuthenticationHelper
|
|||||||
|
|
||||||
// setup the authentication context
|
// setup the authentication context
|
||||||
WebApplicationContext wc = WebApplicationContextUtils.getRequiredWebApplicationContext(context);
|
WebApplicationContext wc = WebApplicationContextUtils.getRequiredWebApplicationContext(context);
|
||||||
AuthenticationService auth = (AuthenticationService)wc.getBean(ServletHelper.AUTHENTICATION_SERVICE);
|
AuthenticationService auth = (AuthenticationService)wc.getBean(AUTHENTICATION_SERVICE);
|
||||||
|
|
||||||
if (user == null || guest)
|
if (user == null || guest)
|
||||||
{
|
{
|
||||||
|
// Check for the session invalidated flag - this is set by the Logout action in the LoginBean
|
||||||
|
// it signals a forced Logout and means we should not immediately attempt a relogin as Guest.
|
||||||
|
// The attribute is removed from the session by the login.jsp page after the Cookie containing
|
||||||
|
// the last stored username string is cleared.
|
||||||
if (session.getAttribute(AuthenticationHelper.SESSION_INVALIDATED) == null)
|
if (session.getAttribute(AuthenticationHelper.SESSION_INVALIDATED) == null)
|
||||||
{
|
{
|
||||||
Cookie authCookie = getAuthCookie(httpRequest);
|
Cookie authCookie = getAuthCookie(httpRequest);
|
||||||
@@ -112,7 +138,7 @@ public final class AuthenticationHelper
|
|||||||
tx.begin();
|
tx.begin();
|
||||||
|
|
||||||
NodeService nodeService = services.getNodeService();
|
NodeService nodeService = services.getNodeService();
|
||||||
PersonService personService = (PersonService)wc.getBean(ServletHelper.PERSON_SERVICE);
|
PersonService personService = (PersonService)wc.getBean(PERSON_SERVICE);
|
||||||
NodeRef guestRef = personService.getPerson(PermissionService.GUEST);
|
NodeRef guestRef = personService.getPerson(PermissionService.GUEST);
|
||||||
user = new User(PermissionService.GUEST, auth.getCurrentTicket(), guestRef);
|
user = new User(PermissionService.GUEST, auth.getCurrentTicket(), guestRef);
|
||||||
NodeRef guestHomeRef = (NodeRef)nodeService.getProperty(guestRef, ContentModel.PROP_HOMEFOLDER);
|
NodeRef guestHomeRef = (NodeRef)nodeService.getProperty(guestRef, ContentModel.PROP_HOMEFOLDER);
|
||||||
@@ -125,6 +151,7 @@ public final class AuthenticationHelper
|
|||||||
user.setHomeSpaceId(guestHomeRef.getId());
|
user.setHomeSpaceId(guestHomeRef.getId());
|
||||||
|
|
||||||
tx.commit();
|
tx.commit();
|
||||||
|
tx = null; // clear this so we know not to rollback
|
||||||
|
|
||||||
// store the User object in the Session - the authentication servlet will then proceed
|
// store the User object in the Session - the authentication servlet will then proceed
|
||||||
session.setAttribute(AuthenticationHelper.AUTHENTICATION_USER, user);
|
session.setAttribute(AuthenticationHelper.AUTHENTICATION_USER, user);
|
||||||
@@ -132,6 +159,9 @@ public final class AuthenticationHelper
|
|||||||
// Set the current locale
|
// Set the current locale
|
||||||
I18NUtil.setLocale(Application.getLanguage(httpRequest.getSession()));
|
I18NUtil.setLocale(Application.getLanguage(httpRequest.getSession()));
|
||||||
|
|
||||||
|
// remove the session invalidated flag
|
||||||
|
session.removeAttribute(AuthenticationHelper.SESSION_INVALIDATED);
|
||||||
|
|
||||||
// it is the responsibilty of the caller to handle the Guest return status
|
// it is the responsibilty of the caller to handle the Guest return status
|
||||||
return AuthenticationStatus.Guest;
|
return AuthenticationStatus.Guest;
|
||||||
}
|
}
|
||||||
@@ -142,19 +172,26 @@ public final class AuthenticationHelper
|
|||||||
catch (AccessDeniedException accessError)
|
catch (AccessDeniedException accessError)
|
||||||
{
|
{
|
||||||
// Guest is unable to access either properties on Person
|
// Guest is unable to access either properties on Person
|
||||||
|
//AuthenticationService smallAuth = (AuthenticationService)wc.getBean(UNPROTECTED_AUTH_SERVICE);
|
||||||
|
//smallAuth.invalidateTicket(smallAuth.getCurrentTicket());
|
||||||
logger.warn("Unable to login as Guest: " + accessError.getMessage());
|
logger.warn("Unable to login as Guest: " + accessError.getMessage());
|
||||||
}
|
}
|
||||||
catch (Throwable e)
|
catch (Throwable e)
|
||||||
{
|
{
|
||||||
// Guest access not allowed - some other kind of serious failure to report
|
// Some other kind of serious failure to report
|
||||||
try { if (tx != null) {tx.rollback();} } catch (Exception tex) {}
|
//AuthenticationService smallAuth = (AuthenticationService)wc.getBean(UNPROTECTED_AUTH_SERVICE);
|
||||||
|
//smallAuth.invalidateTicket(smallAuth.getCurrentTicket());
|
||||||
throw new AlfrescoRuntimeException("Failed to authenticate as Guest user.", e);
|
throw new AlfrescoRuntimeException("Failed to authenticate as Guest user.", e);
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
try { if (tx != null) {tx.rollback();} } catch (Exception tex) {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// no user/ticket found or session invalidated by user (logout) - redirect to login page
|
// no user/ticket found or session invalidated by user (logout) - redirect to login page
|
||||||
httpResponse.sendRedirect(httpRequest.getContextPath() + "/faces" + Application.getLoginPage(context));
|
httpResponse.sendRedirect(httpRequest.getContextPath() + FACES_SERVLET + Application.getLoginPage(context));
|
||||||
|
|
||||||
return AuthenticationStatus.Failure;
|
return AuthenticationStatus.Failure;
|
||||||
}
|
}
|
||||||
@@ -167,7 +204,7 @@ public final class AuthenticationHelper
|
|||||||
catch (AuthenticationException authErr)
|
catch (AuthenticationException authErr)
|
||||||
{
|
{
|
||||||
// expired ticket - redirect to login page
|
// expired ticket - redirect to login page
|
||||||
httpResponse.sendRedirect(httpRequest.getContextPath() + "/faces" + Application.getLoginPage(context));
|
httpResponse.sendRedirect(httpRequest.getContextPath() + FACES_SERVLET + Application.getLoginPage(context));
|
||||||
return AuthenticationStatus.Failure;
|
return AuthenticationStatus.Failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,7 +232,7 @@ public final class AuthenticationHelper
|
|||||||
{
|
{
|
||||||
// setup the authentication context
|
// setup the authentication context
|
||||||
WebApplicationContext wc = WebApplicationContextUtils.getRequiredWebApplicationContext(context);
|
WebApplicationContext wc = WebApplicationContextUtils.getRequiredWebApplicationContext(context);
|
||||||
AuthenticationService auth = (AuthenticationService)wc.getBean(ServletHelper.AUTHENTICATION_SERVICE);
|
AuthenticationService auth = (AuthenticationService)wc.getBean(AUTHENTICATION_SERVICE);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
auth.validate(ticket);
|
auth.validate(ticket);
|
||||||
|
@@ -41,7 +41,6 @@ import org.alfresco.service.cmr.repository.NodeRef;
|
|||||||
import org.alfresco.service.cmr.repository.StoreRef;
|
import org.alfresco.service.cmr.repository.StoreRef;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.alfresco.web.app.Application;
|
import org.alfresco.web.app.Application;
|
||||||
import org.alfresco.web.bean.LoginBean;
|
|
||||||
import org.alfresco.web.ui.common.Utils;
|
import org.alfresco.web.ui.common.Utils;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
@@ -66,7 +65,10 @@ import org.apache.commons.logging.LogFactory;
|
|||||||
* To retrieve the content of a specific model property, use a 'property' arg, providing the workspace,
|
* To retrieve the content of a specific model property, use a 'property' arg, providing the workspace,
|
||||||
* node ID AND the qualified name of the property.
|
* node ID AND the qualified name of the property.
|
||||||
* <p>
|
* <p>
|
||||||
* The URL may be followed by a valid ticket argument for authentication: ?ticket=1234567890
|
* Like most Alfresco servlets, the URL may be followed by a valid 'ticket' argument for authentication:
|
||||||
|
* ?ticket=1234567890
|
||||||
|
* <p>
|
||||||
|
* And/or also followed by the "?guest=true" argument to force guest access login for the URL.
|
||||||
*
|
*
|
||||||
* @author Kevin Roast
|
* @author Kevin Roast
|
||||||
*/
|
*/
|
||||||
@@ -92,93 +94,72 @@ public class DownloadContentServlet extends HttpServlet
|
|||||||
protected void doGet(HttpServletRequest req, HttpServletResponse res)
|
protected void doGet(HttpServletRequest req, HttpServletResponse res)
|
||||||
throws ServletException, IOException
|
throws ServletException, IOException
|
||||||
{
|
{
|
||||||
ServletOutputStream out = res.getOutputStream();
|
// The URL contains multiple parts
|
||||||
|
// /alfresco/download/attach/workspace/SpacesStore/0000-0000-0000-0000/myfile.pdf
|
||||||
|
// the protocol, followed by the store, followed by the Id
|
||||||
|
// the last part is only used for mimetype and browser use
|
||||||
|
// may be followed by valid ticket for pre-authenticated usage: ?ticket=1234567890
|
||||||
|
String uri = req.getRequestURI();
|
||||||
|
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
logger.debug("Processing URL: " + uri + (req.getQueryString() != null ? ("?" + req.getQueryString()) : ""));
|
||||||
|
|
||||||
|
AuthenticationStatus status = ServletHelper.servletAuthenticate(req, res, getServletContext());
|
||||||
|
if (status == AuthenticationStatus.Failure)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: add compression here?
|
||||||
|
// see http://servlets.com/jservlet2/examples/ch06/ViewResourceCompress.java for example
|
||||||
|
// only really needed if we don't use the built in compression of the servlet container
|
||||||
|
StringTokenizer t = new StringTokenizer(uri, "/");
|
||||||
|
if (t.countTokens() < 7)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("Download URL did not contain all required args: " + uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
t.nextToken(); // skip web app name
|
||||||
|
t.nextToken(); // skip servlet name
|
||||||
|
|
||||||
|
String attachToken = t.nextToken();
|
||||||
|
boolean attachment = attachToken.equals(ARG_ATTACH);
|
||||||
|
|
||||||
|
StoreRef storeRef = new StoreRef(t.nextToken(), t.nextToken());
|
||||||
|
String id = t.nextToken();
|
||||||
|
String filename = t.nextToken();
|
||||||
|
|
||||||
|
// get property qualified name
|
||||||
|
QName propertyQName = null;
|
||||||
|
String property = req.getParameter(ARG_PROPERTY);
|
||||||
|
if (property == null || property.length() == 0)
|
||||||
|
{
|
||||||
|
propertyQName = ContentModel.PROP_CONTENT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
propertyQName = QName.createQName(property);
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeRef nodeRef = new NodeRef(storeRef, id);
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
{
|
||||||
|
logger.debug("Found NodeRef: " + nodeRef.toString());
|
||||||
|
logger.debug("Will use filename: " + filename);
|
||||||
|
logger.debug("For property: " + propertyQName);
|
||||||
|
logger.debug("With attachment mode: " + attachment);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attachment == true)
|
||||||
|
{
|
||||||
|
// set header based on filename - will force a Save As from the browse if it doesn't recognise it
|
||||||
|
// this is better than the default response of the browse trying to display the contents!
|
||||||
|
// TODO: make this configurable - and check it does not prevent streaming of large files
|
||||||
|
res.setHeader("Content-Disposition", "attachment;filename=\"" + URLDecoder.decode(filename, "UTF-8") + '"');
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// The URL contains multiple parts
|
|
||||||
// /alfresco/download/attach/workspace/SpacesStore/0000-0000-0000-0000/myfile.pdf
|
|
||||||
// the protocol, followed by the store, followed by the Id
|
|
||||||
// the last part is only used for mimetype and browser use
|
|
||||||
// may be followed by valid ticket for pre-authenticated usage: ?ticket=1234567890
|
|
||||||
String uri = req.getRequestURI();
|
|
||||||
|
|
||||||
if (logger.isDebugEnabled())
|
|
||||||
logger.debug("Processing URL: " + uri + (req.getQueryString() != null ? ("?" + req.getQueryString()) : ""));
|
|
||||||
|
|
||||||
// see if a ticket or guest parameter has been supplied
|
|
||||||
AuthenticationStatus status;
|
|
||||||
String ticket = req.getParameter(ServletHelper.ARG_TICKET);
|
|
||||||
if (ticket != null && ticket.length() != 0)
|
|
||||||
{
|
|
||||||
status = AuthenticationHelper.authenticate(getServletContext(), req, res, ticket);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
boolean forceGuest = false;
|
|
||||||
String guest = req.getParameter(ServletHelper.ARG_GUEST);
|
|
||||||
if (guest != null)
|
|
||||||
{
|
|
||||||
forceGuest = Boolean.parseBoolean(guest);
|
|
||||||
}
|
|
||||||
status = AuthenticationHelper.authenticate(getServletContext(), req, res, forceGuest);
|
|
||||||
}
|
|
||||||
if (status == AuthenticationStatus.Failure)
|
|
||||||
{
|
|
||||||
// authentication failed - no point returning the content as we haven't logged in yet
|
|
||||||
// so end servlet execution and save the URL so the login page knows what to do later
|
|
||||||
req.getSession().setAttribute(LoginBean.LOGIN_REDIRECT_KEY, uri);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: add compression here?
|
|
||||||
// see http://servlets.com/jservlet2/examples/ch06/ViewResourceCompress.java for example
|
|
||||||
// only really needed if we don't use the built in compression of the servlet container
|
|
||||||
StringTokenizer t = new StringTokenizer(uri, "/");
|
|
||||||
if (t.countTokens() < 7)
|
|
||||||
{
|
|
||||||
throw new IllegalArgumentException("Download URL did not contain all required args: " + uri);
|
|
||||||
}
|
|
||||||
|
|
||||||
t.nextToken(); // skip web app name
|
|
||||||
t.nextToken(); // skip servlet name
|
|
||||||
|
|
||||||
String attachToken = t.nextToken();
|
|
||||||
boolean attachment = attachToken.equals(ARG_ATTACH);
|
|
||||||
|
|
||||||
StoreRef storeRef = new StoreRef(t.nextToken(), t.nextToken());
|
|
||||||
String id = t.nextToken();
|
|
||||||
String filename = t.nextToken();
|
|
||||||
|
|
||||||
// get property qualified name
|
|
||||||
QName propertyQName = null;
|
|
||||||
String property = req.getParameter(ARG_PROPERTY);
|
|
||||||
if (property == null || property.length() == 0)
|
|
||||||
{
|
|
||||||
propertyQName = ContentModel.PROP_CONTENT;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
propertyQName = QName.createQName(property);
|
|
||||||
}
|
|
||||||
|
|
||||||
NodeRef nodeRef = new NodeRef(storeRef, id);
|
|
||||||
if (logger.isDebugEnabled())
|
|
||||||
{
|
|
||||||
logger.debug("Found NodeRef: " + nodeRef.toString());
|
|
||||||
logger.debug("Will use filename: " + filename);
|
|
||||||
logger.debug("For property: " + propertyQName);
|
|
||||||
logger.debug("With attachment mode: " + attachment);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (attachment == true)
|
|
||||||
{
|
|
||||||
// set header based on filename - will force a Save As from the browse if it doesn't recognise it
|
|
||||||
// this is better than the default response of the browse trying to display the contents!
|
|
||||||
// TODO: make this configurable - and check it does not prevent streaming of large files
|
|
||||||
res.setHeader("Content-Disposition", "attachment;filename=\"" + URLDecoder.decode(filename, "UTF-8") + '"');
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the services we need to retrieve the content
|
// get the services we need to retrieve the content
|
||||||
ServiceRegistry serviceRegistry = ServletHelper.getServiceRegistry(getServletContext());
|
ServiceRegistry serviceRegistry = ServletHelper.getServiceRegistry(getServletContext());
|
||||||
ContentService contentService = serviceRegistry.getContentService();
|
ContentService contentService = serviceRegistry.getContentService();
|
||||||
@@ -234,10 +215,6 @@ public class DownloadContentServlet extends HttpServlet
|
|||||||
{
|
{
|
||||||
throw new AlfrescoRuntimeException("Error during download content servlet processing: " + err.getMessage(), err);
|
throw new AlfrescoRuntimeException("Error during download content servlet processing: " + err.getMessage(), err);
|
||||||
}
|
}
|
||||||
finally
|
|
||||||
{
|
|
||||||
out.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -20,12 +20,18 @@ import java.io.IOException;
|
|||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
|
import javax.faces.application.NavigationHandler;
|
||||||
|
import javax.faces.context.FacesContext;
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.http.HttpServlet;
|
import javax.servlet.http.HttpServlet;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import org.alfresco.web.bean.LoginBean;
|
import org.alfresco.repo.webdav.WebDAVServlet;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.cmr.repository.StoreRef;
|
||||||
|
import org.alfresco.web.bean.BrowseBean;
|
||||||
|
import org.alfresco.web.bean.NavigationBean;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
@@ -39,7 +45,11 @@ import org.apache.commons.logging.LogFactory;
|
|||||||
* <p>
|
* <p>
|
||||||
* <code>http://<server>/alfresco/navigate/<outcome>[/<workspace>/<store>/<nodeId>]</code> or <br/>
|
* <code>http://<server>/alfresco/navigate/<outcome>[/<workspace>/<store>/<nodeId>]</code> or <br/>
|
||||||
* <code>http://<server>/alfresco/navigate/<outcome>[/webdav/<path/to/node>]</code>
|
* <code>http://<server>/alfresco/navigate/<outcome>[/webdav/<path/to/node>]</code>
|
||||||
* </p>
|
* <p>
|
||||||
|
* Like most Alfresco servlets, the URL may be followed by a valid 'ticket' argument for authentication:
|
||||||
|
* ?ticket=1234567890
|
||||||
|
* <p>
|
||||||
|
* And/or also followed by the "?guest=true" argument to force guest access login for the URL.
|
||||||
*
|
*
|
||||||
* @author Kevin Roast
|
* @author Kevin Roast
|
||||||
*/
|
*/
|
||||||
@@ -49,6 +59,11 @@ public class ExternalAccessServlet extends HttpServlet
|
|||||||
|
|
||||||
private static Log logger = LogFactory.getLog(ExternalAccessServlet.class);
|
private static Log logger = LogFactory.getLog(ExternalAccessServlet.class);
|
||||||
|
|
||||||
|
private final static String OUTCOME_DOCDETAILS = "showDocDetails";
|
||||||
|
private final static String OUTCOME_SPACEDETAILS = "showSpaceDetails";
|
||||||
|
private final static String OUTCOME_BROWSE = "browse";
|
||||||
|
|
||||||
|
private static final String ARG_TEMPLATE = "template";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see javax.servlet.http.HttpServlet#service(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
|
* @see javax.servlet.http.HttpServlet#service(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
|
||||||
@@ -56,20 +71,16 @@ public class ExternalAccessServlet extends HttpServlet
|
|||||||
protected void service(HttpServletRequest req, HttpServletResponse res)
|
protected void service(HttpServletRequest req, HttpServletResponse res)
|
||||||
throws ServletException, IOException
|
throws ServletException, IOException
|
||||||
{
|
{
|
||||||
boolean forceGuest = false;
|
|
||||||
String guest = req.getParameter(ServletHelper.ARG_GUEST);
|
|
||||||
if (guest != null)
|
|
||||||
{
|
|
||||||
forceGuest = Boolean.parseBoolean(guest);
|
|
||||||
}
|
|
||||||
AuthenticationStatus status = AuthenticationHelper.authenticate(getServletContext(), req, res, forceGuest);
|
|
||||||
|
|
||||||
// The URL contains multiple parts
|
|
||||||
// /alfresco/navigate/<outcome>
|
|
||||||
String uri = req.getRequestURI();
|
String uri = req.getRequestURI();
|
||||||
|
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
logger.debug("Processing URL: " + uri);
|
logger.debug("Processing URL: " + uri + (req.getQueryString() != null ? ("?" + req.getQueryString()) : ""));
|
||||||
|
|
||||||
|
AuthenticationStatus status = ServletHelper.servletAuthenticate(req, res, getServletContext());
|
||||||
|
if (status == AuthenticationStatus.Failure)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
StringTokenizer t = new StringTokenizer(uri, "/");
|
StringTokenizer t = new StringTokenizer(uri, "/");
|
||||||
int count = t.countTokens();
|
int count = t.countTokens();
|
||||||
@@ -82,31 +93,101 @@ public class ExternalAccessServlet extends HttpServlet
|
|||||||
|
|
||||||
String outcome = t.nextToken();
|
String outcome = t.nextToken();
|
||||||
|
|
||||||
// get rest of the tokens
|
// get rest of the tokens arguments
|
||||||
String[] tokens = new String[count - 3];
|
String[] args = new String[count - 3];
|
||||||
for (int i=0; i<count - 3; i++)
|
for (int i=0; i<count - 3; i++)
|
||||||
{
|
{
|
||||||
tokens[i] = t.nextToken();
|
args[i] = t.nextToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the session variable so the login bean knows which outcome to use
|
if (logger.isDebugEnabled())
|
||||||
req.getSession().setAttribute(LoginBean.LOGIN_OUTCOME_KEY, outcome);
|
logger.debug("External outcome found: " + outcome);
|
||||||
|
|
||||||
// set the args if any
|
// we almost always need this bean reference
|
||||||
req.getSession().setAttribute(LoginBean.LOGIN_OUTCOME_ARGS, tokens);
|
FacesContext fc = ServletHelper.getFacesContext(req, res, getServletContext());
|
||||||
|
BrowseBean browseBean = (BrowseBean)ServletHelper.getManagedBean(fc, "BrowseBean");
|
||||||
|
|
||||||
if (status == AuthenticationStatus.Success || status == AuthenticationStatus.Guest)
|
// setup is required for certain outcome requests
|
||||||
|
if (OUTCOME_DOCDETAILS.equals(outcome))
|
||||||
{
|
{
|
||||||
// clear the User object from the Session - this will force a relogin
|
NodeRef nodeRef = null;
|
||||||
// we do this so the outcome from the login page can then be changed
|
|
||||||
req.getSession().removeAttribute(AuthenticationHelper.AUTHENTICATION_USER);
|
|
||||||
|
|
||||||
if (logger.isDebugEnabled())
|
if (args[0].equals(WebDAVServlet.WEBDAV_PREFIX))
|
||||||
logger.debug("Removing User session - will redirect via login page...");
|
{
|
||||||
|
nodeRef = ServletHelper.resolveWebDAVPath(fc, args);
|
||||||
|
}
|
||||||
|
else if (args.length == 3)
|
||||||
|
{
|
||||||
|
StoreRef storeRef = new StoreRef(args[0], args[1]);
|
||||||
|
nodeRef = new NodeRef(storeRef, args[2]);
|
||||||
|
}
|
||||||
|
|
||||||
// redirect to root URL will force the login page to appear via the Authentication Filter
|
if (nodeRef != null)
|
||||||
res.sendRedirect(req.getContextPath());
|
{
|
||||||
|
// setup the Document on the browse bean
|
||||||
|
// TODO: the browse bean should accept a full NodeRef - not just an ID
|
||||||
|
browseBean.setupContentAction(nodeRef.getId(), true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else if (OUTCOME_SPACEDETAILS.equals(outcome))
|
||||||
|
{
|
||||||
|
NodeRef nodeRef = null;
|
||||||
|
|
||||||
|
if (args[0].equals(WebDAVServlet.WEBDAV_PREFIX))
|
||||||
|
{
|
||||||
|
nodeRef = ServletHelper.resolveWebDAVPath(fc, args);
|
||||||
|
}
|
||||||
|
else if (args.length == 3)
|
||||||
|
{
|
||||||
|
StoreRef storeRef = new StoreRef(args[0], args[1]);
|
||||||
|
nodeRef = new NodeRef(storeRef, args[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nodeRef != null)
|
||||||
|
{
|
||||||
|
// setup the Space on the browse bean
|
||||||
|
// TODO: the browse bean should accept a full NodeRef - not just an ID
|
||||||
|
browseBean.setupSpaceAction(nodeRef.getId(), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (OUTCOME_BROWSE.equals(outcome))
|
||||||
|
{
|
||||||
|
if (args != null)
|
||||||
|
{
|
||||||
|
NodeRef nodeRef = null;
|
||||||
|
int offset = 0;
|
||||||
|
if (args.length >= 3)
|
||||||
|
{
|
||||||
|
offset = args.length - 3;
|
||||||
|
StoreRef storeRef = new StoreRef(args[0+offset], args[1+offset]);
|
||||||
|
nodeRef = new NodeRef(storeRef, args[2+offset]);
|
||||||
|
|
||||||
|
// setup the ref as current Id in the global navigation bean
|
||||||
|
NavigationBean navigator = (NavigationBean)ServletHelper.getManagedBean(fc, "NavigationBean");
|
||||||
|
navigator.setCurrentNodeId(nodeRef.getId());
|
||||||
|
|
||||||
|
//
|
||||||
|
// TODO: handle this code
|
||||||
|
/*
|
||||||
|
// check for view mode first argument
|
||||||
|
if (args[0].equals(ARG_TEMPLATE))
|
||||||
|
{
|
||||||
|
browseBean.setDashboardView(true);
|
||||||
|
// the above call will auto-navigate to the correct outcome - so we don't!
|
||||||
|
//externalOutcome = null;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// perform the appropriate JSF navigation outcome
|
||||||
|
NavigationHandler navigationHandler = fc.getApplication().getNavigationHandler();
|
||||||
|
navigationHandler.handleNavigation(fc, null, outcome);
|
||||||
|
|
||||||
|
// perform the forward to the page processed by the Faces servlet
|
||||||
|
String viewId = fc.getViewRoot().getViewId();
|
||||||
|
getServletContext().getRequestDispatcher(AuthenticationHelper.FACES_SERVLET + viewId).forward(req, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -16,11 +16,38 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.web.app.servlet;
|
package org.alfresco.web.app.servlet;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLDecoder;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.faces.FactoryFinder;
|
||||||
|
import javax.faces.component.UIViewRoot;
|
||||||
|
import javax.faces.context.FacesContext;
|
||||||
|
import javax.faces.context.FacesContextFactory;
|
||||||
|
import javax.faces.el.ValueBinding;
|
||||||
|
import javax.faces.lifecycle.Lifecycle;
|
||||||
|
import javax.faces.lifecycle.LifecycleFactory;
|
||||||
import javax.servlet.ServletContext;
|
import javax.servlet.ServletContext;
|
||||||
|
import javax.servlet.ServletRequest;
|
||||||
|
import javax.servlet.ServletResponse;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import org.alfresco.service.ServiceRegistry;
|
import org.alfresco.service.ServiceRegistry;
|
||||||
|
import org.alfresco.service.cmr.model.FileFolderService;
|
||||||
|
import org.alfresco.service.cmr.model.FileInfo;
|
||||||
|
import org.alfresco.service.cmr.model.FileNotFoundException;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.web.app.Application;
|
||||||
|
import org.alfresco.web.bean.LoginBean;
|
||||||
|
import org.alfresco.web.bean.repository.Repository;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.springframework.web.context.WebApplicationContext;
|
import org.springframework.web.context.WebApplicationContext;
|
||||||
import org.springframework.web.context.support.WebApplicationContextUtils;
|
import org.springframework.web.context.support.WebApplicationContextUtils;
|
||||||
|
import org.springframework.web.jsf.FacesContextUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Useful constant values and common methods for Alfresco servlets.
|
* Useful constant values and common methods for Alfresco servlets.
|
||||||
@@ -30,14 +57,13 @@ import org.springframework.web.context.support.WebApplicationContextUtils;
|
|||||||
public final class ServletHelper
|
public final class ServletHelper
|
||||||
{
|
{
|
||||||
/** an existing Ticket can be passed to most servlet for non-session based authentication */
|
/** an existing Ticket can be passed to most servlet for non-session based authentication */
|
||||||
public static final String ARG_TICKET = "ticket";
|
private static final String ARG_TICKET = "ticket";
|
||||||
|
|
||||||
/** forcing guess access is available on most servlets */
|
/** forcing guess access is available on most servlets */
|
||||||
public static final String ARG_GUEST = "guest";
|
private static final String ARG_GUEST = "guest";
|
||||||
|
|
||||||
|
private static Log logger = LogFactory.getLog(ServletHelper.class);
|
||||||
|
|
||||||
/** public service bean IDs **/
|
|
||||||
public static final String AUTHENTICATION_SERVICE = "authenticationService";
|
|
||||||
public static final String PERSON_SERVICE = "personService";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the ServiceRegistry helper instance
|
* Return the ServiceRegistry helper instance
|
||||||
@@ -58,4 +84,152 @@ public final class ServletHelper
|
|||||||
private ServletHelper()
|
private ServletHelper()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform an authentication for the servlet request URI. Processing any "ticket" or
|
||||||
|
* "guest" URL arguments.
|
||||||
|
*
|
||||||
|
* @return AuthenticationStatus
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public static AuthenticationStatus servletAuthenticate(HttpServletRequest req, HttpServletResponse res, ServletContext sc)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
AuthenticationStatus status;
|
||||||
|
|
||||||
|
// see if a ticket or a force Guest parameter has been supplied
|
||||||
|
String ticket = req.getParameter(ServletHelper.ARG_TICKET);
|
||||||
|
if (ticket != null && ticket.length() != 0)
|
||||||
|
{
|
||||||
|
status = AuthenticationHelper.authenticate(sc, req, res, ticket);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
boolean forceGuest = false;
|
||||||
|
String guest = req.getParameter(ServletHelper.ARG_GUEST);
|
||||||
|
if (guest != null)
|
||||||
|
{
|
||||||
|
forceGuest = Boolean.parseBoolean(guest);
|
||||||
|
}
|
||||||
|
status = AuthenticationHelper.authenticate(sc, req, res, forceGuest);
|
||||||
|
}
|
||||||
|
if (status == AuthenticationStatus.Failure)
|
||||||
|
{
|
||||||
|
// authentication failed - no point returning the content as we haven't logged in yet
|
||||||
|
// so end servlet execution and save the URL so the login page knows what to do later
|
||||||
|
req.getSession().setAttribute(LoginBean.LOGIN_REDIRECT_KEY, req.getRequestURI() + (req.getQueryString() != null ? ("?" + req.getQueryString()) : ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return FacesContext made available to servlets and servlet filters.
|
||||||
|
* {@link http://www.thoughtsabout.net/blog/archives/000033.html}
|
||||||
|
*
|
||||||
|
* @return FacesContext
|
||||||
|
*/
|
||||||
|
public static FacesContext getFacesContext(ServletRequest req, ServletResponse res, ServletContext sc)
|
||||||
|
{
|
||||||
|
FacesContext facesContext = FacesContext.getCurrentInstance();
|
||||||
|
if (facesContext != null) return facesContext;
|
||||||
|
|
||||||
|
FacesContextFactory contextFactory = (FacesContextFactory)FactoryFinder.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
|
||||||
|
LifecycleFactory lifecycleFactory = (LifecycleFactory)FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
|
||||||
|
Lifecycle lifecycle = lifecycleFactory.getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE);
|
||||||
|
|
||||||
|
// Can get ServletContext here like this:
|
||||||
|
// ServletContext servletContext = ((HttpServletRequest)request).getSession().getServletContext();
|
||||||
|
|
||||||
|
// Doesn't set this instance as the current instance of FacesContext.getCurrentInstance
|
||||||
|
facesContext = contextFactory.getFacesContext(sc, req, res, lifecycle);
|
||||||
|
|
||||||
|
// Set using our inner class
|
||||||
|
InnerFacesContext.setFacesContextAsCurrent(facesContext);
|
||||||
|
|
||||||
|
// set a new viewRoot, otherwise context.getViewRoot returns null
|
||||||
|
UIViewRoot view = facesContext.getApplication().getViewHandler().createView(facesContext, "/jsp/root");
|
||||||
|
facesContext.setViewRoot(view);
|
||||||
|
|
||||||
|
return facesContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We need an inner class to be able to call FacesContext.setCurrentInstance
|
||||||
|
* since it's a protected method
|
||||||
|
*/
|
||||||
|
private abstract static class InnerFacesContext extends FacesContext
|
||||||
|
{
|
||||||
|
protected static void setFacesContextAsCurrent(FacesContext facesContext)
|
||||||
|
{
|
||||||
|
FacesContext.setCurrentInstance(facesContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a JSF managed bean reference.
|
||||||
|
*
|
||||||
|
* @param fc FacesContext
|
||||||
|
* @param name Name of the managed bean to return
|
||||||
|
*
|
||||||
|
* @return the managed bean or null if not found
|
||||||
|
*/
|
||||||
|
public static Object getManagedBean(FacesContext fc, String name)
|
||||||
|
{
|
||||||
|
ValueBinding vb = fc.getApplication().createValueBinding("#{" + name + "}");
|
||||||
|
return vb.getValue(fc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolves the given path elements to a NodeRef in the current repository
|
||||||
|
*
|
||||||
|
* @param context Faces context
|
||||||
|
* @param args The elements of the path to lookup
|
||||||
|
*/
|
||||||
|
public static NodeRef resolveWebDAVPath(FacesContext context, String[] args)
|
||||||
|
{
|
||||||
|
NodeRef nodeRef = null;
|
||||||
|
|
||||||
|
List<String> paths = new ArrayList<String>(args.length-1);
|
||||||
|
|
||||||
|
FileInfo file = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// create a list of path elements (decode the URL as we go)
|
||||||
|
for (int x = 1; x < args.length; x++)
|
||||||
|
{
|
||||||
|
paths.add(URLDecoder.decode(args[x], "UTF-8"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
logger.debug("Attempting to resolve webdav path to NodeRef: " + paths);
|
||||||
|
|
||||||
|
// get the company home node to start the search from
|
||||||
|
NodeRef companyHome = new NodeRef(Repository.getStoreRef(),
|
||||||
|
Application.getCompanyRootId());
|
||||||
|
|
||||||
|
WebApplicationContext wc = FacesContextUtils.getRequiredWebApplicationContext(context);
|
||||||
|
//WebApplicationContext wc = WebApplicationContextUtils.getRequiredWebApplicationContext(context);
|
||||||
|
FileFolderService ffs = (FileFolderService)wc.getBean("FileFolderService");
|
||||||
|
file = ffs.resolveNamePath(companyHome, paths);
|
||||||
|
nodeRef = file.getNodeRef();
|
||||||
|
}
|
||||||
|
catch (UnsupportedEncodingException uee)
|
||||||
|
{
|
||||||
|
if (logger.isWarnEnabled())
|
||||||
|
logger.warn("Failed to resolve webdav path", uee);
|
||||||
|
|
||||||
|
nodeRef = null;
|
||||||
|
}
|
||||||
|
catch (FileNotFoundException fne)
|
||||||
|
{
|
||||||
|
if (logger.isWarnEnabled())
|
||||||
|
logger.debug("Failed to resolve webdav path", fne);
|
||||||
|
|
||||||
|
nodeRef = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nodeRef;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -39,7 +39,6 @@ import org.alfresco.service.cmr.repository.TemplateException;
|
|||||||
import org.alfresco.service.cmr.repository.TemplateNode;
|
import org.alfresco.service.cmr.repository.TemplateNode;
|
||||||
import org.alfresco.service.cmr.repository.TemplateService;
|
import org.alfresco.service.cmr.repository.TemplateService;
|
||||||
import org.alfresco.web.app.Application;
|
import org.alfresco.web.app.Application;
|
||||||
import org.alfresco.web.bean.LoginBean;
|
|
||||||
import org.alfresco.web.ui.repo.component.template.DefaultModelHelper;
|
import org.alfresco.web.ui.repo.component.template.DefaultModelHelper;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
@@ -57,10 +56,13 @@ import org.apache.commons.logging.LogFactory;
|
|||||||
* identify the node to execute the default template for. The second set of elements encode
|
* identify the node to execute the default template for. The second set of elements encode
|
||||||
* the store and node Id of the template to used if a default is not set or not requested.
|
* the store and node Id of the template to used if a default is not set or not requested.
|
||||||
* <p>
|
* <p>
|
||||||
* The URL may be followed by a valid 'ticket' argument for authentication: ?ticket=1234567890
|
* The URL may be followed by a 'mimetype' argument specifying the mimetype to return the result as
|
||||||
* <br>
|
|
||||||
* And may be followed by a 'mimetype' argument specifying the mimetype to return the result as
|
|
||||||
* on the stream. Otherwise it is assumed that HTML is the default response mimetype.
|
* on the stream. Otherwise it is assumed that HTML is the default response mimetype.
|
||||||
|
* <p>
|
||||||
|
* Like most Alfresco servlets, the URL may be followed by a valid 'ticket' argument for authentication:
|
||||||
|
* ?ticket=1234567890
|
||||||
|
* <p>
|
||||||
|
* And/or also followed by the "?guest=true" argument to force guest access login for the URL.
|
||||||
*
|
*
|
||||||
* @author Kevin Roast
|
* @author Kevin Roast
|
||||||
*/
|
*/
|
||||||
@@ -85,67 +87,48 @@ public class TemplateContentServlet extends HttpServlet
|
|||||||
protected void doGet(HttpServletRequest req, HttpServletResponse res)
|
protected void doGet(HttpServletRequest req, HttpServletResponse res)
|
||||||
throws ServletException, IOException
|
throws ServletException, IOException
|
||||||
{
|
{
|
||||||
|
String uri = req.getRequestURI();
|
||||||
|
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
logger.debug("Processing URL: " + uri + (req.getQueryString() != null ? ("?" + req.getQueryString()) : ""));
|
||||||
|
|
||||||
|
AuthenticationStatus status = ServletHelper.servletAuthenticate(req, res, getServletContext());
|
||||||
|
if (status == AuthenticationStatus.Failure)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringTokenizer t = new StringTokenizer(uri, "/");
|
||||||
|
int tokenCount = t.countTokens();
|
||||||
|
if (tokenCount < 5)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("Download URL did not contain all required args: " + uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
t.nextToken(); // skip web app name
|
||||||
|
t.nextToken(); // skip servlet name
|
||||||
|
|
||||||
|
// get NodeRef to the content
|
||||||
|
StoreRef storeRef = new StoreRef(t.nextToken(), t.nextToken());
|
||||||
|
NodeRef nodeRef = new NodeRef(storeRef, t.nextToken());
|
||||||
|
|
||||||
|
// get NodeRef to the template if supplied
|
||||||
|
NodeRef templateRef = null;
|
||||||
|
if (tokenCount >= 8)
|
||||||
|
{
|
||||||
|
storeRef = new StoreRef(t.nextToken(), t.nextToken());
|
||||||
|
templateRef = new NodeRef(storeRef, t.nextToken());
|
||||||
|
}
|
||||||
|
|
||||||
|
String mimetype = MIMETYPE_HTML;
|
||||||
|
if (req.getParameter(ARG_MIMETYPE) != null)
|
||||||
|
{
|
||||||
|
mimetype = req.getParameter(ARG_MIMETYPE);
|
||||||
|
}
|
||||||
|
res.setContentType(mimetype);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
String uri = req.getRequestURI();
|
|
||||||
|
|
||||||
if (logger.isDebugEnabled())
|
|
||||||
logger.debug("Processing URL: " + uri + (req.getQueryString() != null ? ("?" + req.getQueryString()) : ""));
|
|
||||||
|
|
||||||
// see if a ticket has been supplied
|
|
||||||
AuthenticationStatus status;
|
|
||||||
String ticket = req.getParameter(ServletHelper.ARG_TICKET);
|
|
||||||
if (ticket != null && ticket.length() != 0)
|
|
||||||
{
|
|
||||||
status = AuthenticationHelper.authenticate(getServletContext(), req, res, ticket);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
boolean forceGuest = false;
|
|
||||||
String guest = req.getParameter(ServletHelper.ARG_GUEST);
|
|
||||||
if (guest != null)
|
|
||||||
{
|
|
||||||
forceGuest = Boolean.parseBoolean(guest);
|
|
||||||
}
|
|
||||||
status = AuthenticationHelper.authenticate(getServletContext(), req, res, forceGuest);
|
|
||||||
}
|
|
||||||
if (status == AuthenticationStatus.Failure)
|
|
||||||
{
|
|
||||||
// authentication failed - no point returning the content as we haven't logged in yet
|
|
||||||
// so end servlet execution and save the URL so the login page knows what to do later
|
|
||||||
req.getSession().setAttribute(LoginBean.LOGIN_REDIRECT_KEY, uri);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
StringTokenizer t = new StringTokenizer(uri, "/");
|
|
||||||
int tokenCount = t.countTokens();
|
|
||||||
if (tokenCount < 5)
|
|
||||||
{
|
|
||||||
throw new IllegalArgumentException("Download URL did not contain all required args: " + uri);
|
|
||||||
}
|
|
||||||
|
|
||||||
t.nextToken(); // skip web app name
|
|
||||||
t.nextToken(); // skip servlet name
|
|
||||||
|
|
||||||
// get NodeRef to the content
|
|
||||||
StoreRef storeRef = new StoreRef(t.nextToken(), t.nextToken());
|
|
||||||
NodeRef nodeRef = new NodeRef(storeRef, t.nextToken());
|
|
||||||
|
|
||||||
// get NodeRef to the template if supplied
|
|
||||||
NodeRef templateRef = null;
|
|
||||||
if (tokenCount >= 8)
|
|
||||||
{
|
|
||||||
storeRef = new StoreRef(t.nextToken(), t.nextToken());
|
|
||||||
templateRef = new NodeRef(storeRef, t.nextToken());
|
|
||||||
}
|
|
||||||
|
|
||||||
String mimetype = MIMETYPE_HTML;
|
|
||||||
if (req.getParameter(ARG_MIMETYPE) != null)
|
|
||||||
{
|
|
||||||
mimetype = req.getParameter(ARG_MIMETYPE);
|
|
||||||
}
|
|
||||||
res.setContentType(mimetype);
|
|
||||||
|
|
||||||
// get the services we need to retrieve the content
|
// get the services we need to retrieve the content
|
||||||
ServiceRegistry serviceRegistry = ServletHelper.getServiceRegistry(getServletContext());
|
ServiceRegistry serviceRegistry = ServletHelper.getServiceRegistry(getServletContext());
|
||||||
NodeService nodeService = serviceRegistry.getNodeService();
|
NodeService nodeService = serviceRegistry.getNodeService();
|
||||||
|
@@ -17,10 +17,7 @@
|
|||||||
package org.alfresco.web.bean;
|
package org.alfresco.web.bean;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.net.URLDecoder;
|
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -36,14 +33,9 @@ import javax.servlet.http.HttpServletRequest;
|
|||||||
import org.alfresco.config.ConfigService;
|
import org.alfresco.config.ConfigService;
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationException;
|
import org.alfresco.repo.security.authentication.AuthenticationException;
|
||||||
import org.alfresco.repo.webdav.WebDAVServlet;
|
|
||||||
import org.alfresco.service.cmr.model.FileFolderService;
|
|
||||||
import org.alfresco.service.cmr.model.FileInfo;
|
|
||||||
import org.alfresco.service.cmr.model.FileNotFoundException;
|
|
||||||
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
|
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.alfresco.service.cmr.repository.NodeService;
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
import org.alfresco.service.cmr.repository.StoreRef;
|
|
||||||
import org.alfresco.service.cmr.security.AuthenticationService;
|
import org.alfresco.service.cmr.security.AuthenticationService;
|
||||||
import org.alfresco.service.cmr.security.PersonService;
|
import org.alfresco.service.cmr.security.PersonService;
|
||||||
import org.alfresco.web.app.Application;
|
import org.alfresco.web.app.Application;
|
||||||
@@ -114,14 +106,6 @@ public class LoginBean
|
|||||||
{
|
{
|
||||||
this.configService = configService;
|
this.configService = configService;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param fileFolderService The FileFolderService to set.
|
|
||||||
*/
|
|
||||||
public void setFileFolderService(FileFolderService fileFolderService)
|
|
||||||
{
|
|
||||||
this.fileFolderService = fileFolderService;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param val Username from login dialog
|
* @param val Username from login dialog
|
||||||
@@ -276,7 +260,8 @@ public class LoginBean
|
|||||||
|
|
||||||
FacesContext fc = FacesContext.getCurrentInstance();
|
FacesContext fc = FacesContext.getCurrentInstance();
|
||||||
|
|
||||||
if (this.username != null && this.password != null)
|
if (this.username != null && this.username.length() != 0 &&
|
||||||
|
this.password != null && this.password.length() != 0)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -284,14 +269,18 @@ public class LoginBean
|
|||||||
|
|
||||||
// Authenticate via the authentication service, then save the details of user in an object
|
// Authenticate via the authentication service, then save the details of user in an object
|
||||||
// in the session - this is used by the servlet filter etc. on each page to check for login
|
// in the session - this is used by the servlet filter etc. on each page to check for login
|
||||||
|
//this.authenticationService = (AuthenticationService)FacesContextUtils.getRequiredWebApplicationContext(FacesContext.getCurrentInstance()).getBean("authenticationService");
|
||||||
this.authenticationService.authenticate(this.username, this.password.toCharArray());
|
this.authenticationService.authenticate(this.username, this.password.toCharArray());
|
||||||
|
|
||||||
// remove the session invalidated flag (used to remove last username cookie by AuthenticationFilter)
|
// remove the session invalidated flag (used to remove last username cookie by AuthenticationFilter)
|
||||||
session.remove(AuthenticationHelper.SESSION_INVALIDATED);
|
session.remove(AuthenticationHelper.SESSION_INVALIDATED);
|
||||||
|
|
||||||
// setup User object and Home space ID
|
// setup User object and Home space ID
|
||||||
User user = new User(this.authenticationService.getCurrentUserName(), this.authenticationService.getCurrentTicket(),
|
User user = new User(
|
||||||
|
this.authenticationService.getCurrentUserName(),
|
||||||
|
this.authenticationService.getCurrentTicket(),
|
||||||
personService.getPerson(this.username));
|
personService.getPerson(this.username));
|
||||||
|
|
||||||
NodeRef homeSpaceRef = (NodeRef) this.nodeService.getProperty(personService.getPerson(this.username), ContentModel.PROP_HOMEFOLDER);
|
NodeRef homeSpaceRef = (NodeRef) this.nodeService.getProperty(personService.getPerson(this.username), ContentModel.PROP_HOMEFOLDER);
|
||||||
|
|
||||||
// check that the home space node exists - else user cannot login
|
// check that the home space node exists - else user cannot login
|
||||||
@@ -305,118 +294,31 @@ public class LoginBean
|
|||||||
// the app to continue without redirecting to the login page
|
// the app to continue without redirecting to the login page
|
||||||
session.put(AuthenticationHelper.AUTHENTICATION_USER, user);
|
session.put(AuthenticationHelper.AUTHENTICATION_USER, user);
|
||||||
|
|
||||||
// if an external outcome has been provided then use that, else use default
|
// if a redirect URL has been provided then use that
|
||||||
String externalOutcome = (String)fc.getExternalContext().getSessionMap().get(LOGIN_OUTCOME_KEY);
|
// this allows servlets etc. to provide a URL to return too after a successful login
|
||||||
if (externalOutcome != null)
|
String redirectURL = (String)fc.getExternalContext().getSessionMap().get(LOGIN_REDIRECT_KEY);
|
||||||
|
if (redirectURL != null)
|
||||||
{
|
{
|
||||||
// TODO: This is a quick solution. It would be better to specify the (identifier?)
|
|
||||||
// of a handler class that would be responsible for processing specific outcome arguments.
|
|
||||||
|
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
logger.debug("External outcome found: " + externalOutcome);
|
logger.debug("Redirect URL found: " + redirectURL);
|
||||||
|
|
||||||
// setup is required for certain outcome requests
|
// remove redirect URL from session
|
||||||
if (OUTCOME_DOCDETAILS.equals(externalOutcome))
|
fc.getExternalContext().getSessionMap().remove(LOGIN_REDIRECT_KEY);
|
||||||
{
|
|
||||||
NodeRef nodeRef = null;
|
|
||||||
|
|
||||||
String[] args = (String[]) fc.getExternalContext().getSessionMap().get(LOGIN_OUTCOME_ARGS);
|
|
||||||
if (args[0].equals(WebDAVServlet.WEBDAV_PREFIX))
|
|
||||||
{
|
|
||||||
nodeRef = resolveWebDAVPath(fc, args);
|
|
||||||
}
|
|
||||||
else if (args.length == 3)
|
|
||||||
{
|
|
||||||
StoreRef storeRef = new StoreRef(args[0], args[1]);
|
|
||||||
nodeRef = new NodeRef(storeRef, args[2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nodeRef != null)
|
|
||||||
{
|
|
||||||
// setup the Document on the browse bean
|
|
||||||
// TODO: the browse bean should accept a full NodeRef - not just an ID
|
|
||||||
this.browseBean.setupContentAction(nodeRef.getId(), true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (OUTCOME_SPACEDETAILS.equals(externalOutcome))
|
|
||||||
{
|
|
||||||
NodeRef nodeRef = null;
|
|
||||||
|
|
||||||
String[] args = (String[]) fc.getExternalContext().getSessionMap().get(LOGIN_OUTCOME_ARGS);
|
|
||||||
if (args[0].equals(WebDAVServlet.WEBDAV_PREFIX))
|
|
||||||
{
|
|
||||||
nodeRef = resolveWebDAVPath(fc, args);
|
|
||||||
}
|
|
||||||
else if (args.length == 3)
|
|
||||||
{
|
|
||||||
StoreRef storeRef = new StoreRef(args[0], args[1]);
|
|
||||||
nodeRef = new NodeRef(storeRef, args[2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nodeRef != null)
|
|
||||||
{
|
|
||||||
// setup the Space on the browse bean
|
|
||||||
// TODO: the browse bean should accept a full NodeRef - not just an ID
|
|
||||||
this.browseBean.setupSpaceAction(nodeRef.getId(), true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (OUTCOME_BROWSE.equals(externalOutcome))
|
|
||||||
{
|
|
||||||
String[] args = (String[]) fc.getExternalContext().getSessionMap().get(LOGIN_OUTCOME_ARGS);
|
|
||||||
if (args != null)
|
|
||||||
{
|
|
||||||
NodeRef nodeRef = null;
|
|
||||||
int offset = 0;
|
|
||||||
if (args.length >= 3)
|
|
||||||
{
|
|
||||||
offset = args.length - 3;
|
|
||||||
StoreRef storeRef = new StoreRef(args[0+offset], args[1+offset]);
|
|
||||||
nodeRef = new NodeRef(storeRef, args[2+offset]);
|
|
||||||
|
|
||||||
// setup the ref as current Id in the global navigation bean
|
|
||||||
this.navigator.setCurrentNodeId(nodeRef.getId());
|
|
||||||
|
|
||||||
// check for view mode first argument
|
|
||||||
if (args[0].equals(LOGIN_ARG_TEMPLATE))
|
|
||||||
{
|
|
||||||
this.browseBean.setDashboardView(true);
|
|
||||||
// the above call will auto-navigate to the correct outcome - so we don't!
|
|
||||||
externalOutcome = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fc.getExternalContext().getSessionMap().remove(LOGIN_OUTCOME_KEY);
|
try
|
||||||
return externalOutcome;
|
{
|
||||||
|
fc.getExternalContext().redirect(redirectURL);
|
||||||
|
fc.responseComplete();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
catch (IOException ioErr)
|
||||||
|
{
|
||||||
|
logger.warn("Unable to redirect to url: " + redirectURL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// if a redirect URL has been provided then use that
|
return "success";
|
||||||
String redirectURL = (String)fc.getExternalContext().getSessionMap().get(LOGIN_REDIRECT_KEY);
|
|
||||||
if (redirectURL != null)
|
|
||||||
{
|
|
||||||
if (logger.isDebugEnabled())
|
|
||||||
logger.debug("Redirect URL found: " + redirectURL);
|
|
||||||
|
|
||||||
// remove URL from session
|
|
||||||
fc.getExternalContext().getSessionMap().remove(LOGIN_REDIRECT_KEY);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
fc.getExternalContext().redirect(redirectURL);
|
|
||||||
fc.responseComplete();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
catch (IOException ioErr)
|
|
||||||
{
|
|
||||||
logger.warn("Unable to redirect to url: " + redirectURL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return "success";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (AuthenticationException aerr)
|
catch (AuthenticationException aerr)
|
||||||
@@ -481,59 +383,6 @@ public class LoginBean
|
|||||||
|
|
||||||
return alfrescoAuth ? "logout" : "relogin";
|
return alfrescoAuth ? "logout" : "relogin";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------
|
|
||||||
// Private helpers
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resolves the given path elements to a NodeRef in the current repository
|
|
||||||
*
|
|
||||||
* @param context Faces context
|
|
||||||
* @param args The elements of the path to lookup
|
|
||||||
*/
|
|
||||||
private NodeRef resolveWebDAVPath(FacesContext context, String[] args)
|
|
||||||
{
|
|
||||||
NodeRef nodeRef = null;
|
|
||||||
|
|
||||||
List<String> paths = new ArrayList<String>(args.length-1);
|
|
||||||
|
|
||||||
FileInfo file = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// create a list of path elements (decode the URL as we go)
|
|
||||||
for (int x = 1; x < args.length; x++)
|
|
||||||
{
|
|
||||||
paths.add(URLDecoder.decode(args[x], "UTF-8"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (logger.isDebugEnabled())
|
|
||||||
logger.debug("Attempting to resolve webdav path to NodeRef: " + paths);
|
|
||||||
|
|
||||||
// get the company home node to start the search from
|
|
||||||
NodeRef companyHome = new NodeRef(Repository.getStoreRef(),
|
|
||||||
Application.getCompanyRootId());
|
|
||||||
|
|
||||||
file = this.fileFolderService.resolveNamePath(companyHome, paths);
|
|
||||||
nodeRef = file.getNodeRef();
|
|
||||||
}
|
|
||||||
catch (UnsupportedEncodingException uee)
|
|
||||||
{
|
|
||||||
if (logger.isWarnEnabled())
|
|
||||||
logger.warn("Failed to resolve webdav path", uee);
|
|
||||||
|
|
||||||
nodeRef = null;
|
|
||||||
}
|
|
||||||
catch (FileNotFoundException fne)
|
|
||||||
{
|
|
||||||
if (logger.isWarnEnabled())
|
|
||||||
logger.debug("Failed to resolve webdav path", fne);
|
|
||||||
|
|
||||||
nodeRef = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return nodeRef;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------
|
||||||
@@ -550,16 +399,8 @@ public class LoginBean
|
|||||||
private static final String MSG_PASSWORD_LENGTH = "login_err_password_length";
|
private static final String MSG_PASSWORD_LENGTH = "login_err_password_length";
|
||||||
|
|
||||||
public static final String LOGIN_REDIRECT_KEY = "_alfRedirect";
|
public static final String LOGIN_REDIRECT_KEY = "_alfRedirect";
|
||||||
public static final String LOGIN_OUTCOME_KEY = "_alfOutcome";
|
|
||||||
public static final String LOGIN_OUTCOME_ARGS = "_alfOutcomeArgs";
|
|
||||||
public static final String LOGIN_EXTERNAL_AUTH= "_alfExternalAuth";
|
public static final String LOGIN_EXTERNAL_AUTH= "_alfExternalAuth";
|
||||||
|
|
||||||
public final static String OUTCOME_DOCDETAILS = "showDocDetails";
|
|
||||||
public final static String OUTCOME_SPACEDETAILS = "showSpaceDetails";
|
|
||||||
public final static String OUTCOME_BROWSE = "browse";
|
|
||||||
|
|
||||||
private static final String LOGIN_ARG_TEMPLATE = "template";
|
|
||||||
|
|
||||||
/** user name */
|
/** user name */
|
||||||
private String username = null;
|
private String username = null;
|
||||||
|
|
||||||
@@ -586,7 +427,4 @@ public class LoginBean
|
|||||||
|
|
||||||
/** ConfigService bean reference */
|
/** ConfigService bean reference */
|
||||||
private ConfigService configService;
|
private ConfigService configService;
|
||||||
|
|
||||||
/** FileFolderService bean reference */
|
|
||||||
private FileFolderService fileFolderService;
|
|
||||||
}
|
}
|
||||||
|
@@ -27,7 +27,7 @@
|
|||||||
</managed-property>
|
</managed-property>
|
||||||
<managed-property>
|
<managed-property>
|
||||||
<property-name>authenticationService</property-name>
|
<property-name>authenticationService</property-name>
|
||||||
<value>#{authenticationService}</value>
|
<value>#{AuthenticationService}</value>
|
||||||
</managed-property>
|
</managed-property>
|
||||||
<managed-property>
|
<managed-property>
|
||||||
<property-name>personService</property-name>
|
<property-name>personService</property-name>
|
||||||
@@ -45,10 +45,6 @@
|
|||||||
<property-name>configService</property-name>
|
<property-name>configService</property-name>
|
||||||
<value>#{configService}</value>
|
<value>#{configService}</value>
|
||||||
</managed-property>
|
</managed-property>
|
||||||
<managed-property>
|
|
||||||
<property-name>fileFolderService</property-name>
|
|
||||||
<value>#{FileFolderService}</value>
|
|
||||||
</managed-property>
|
|
||||||
</managed-bean>
|
</managed-bean>
|
||||||
|
|
||||||
<managed-bean>
|
<managed-bean>
|
||||||
|
@@ -250,7 +250,7 @@
|
|||||||
<a:actionLink value="#{msg.download_content}" href="#{DocumentDetailsBean.downloadUrl}" target="new" id="link4" />
|
<a:actionLink value="#{msg.download_content}" href="#{DocumentDetailsBean.downloadUrl}" target="new" id="link4" />
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<a href='<a:outputText value="#{DocumentDetailsBean.bookmarkUrl}" id="out1" />' onclick="return false;"><a:outputText value="#{msg.details_page_bookmark}" id="out2" /></a>
|
<a href='<%=request.getContextPath()%><a:outputText value="#{DocumentDetailsBean.bookmarkUrl}" id="out1" />' onclick="return false;"><a:outputText value="#{msg.details_page_bookmark}" id="out2" /></a>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<a href='<a:outputText value="#{DocumentDetailsBean.nodeRefUrl}" id="out3" />' onclick="return false;"><a:outputText value="#{msg.noderef_link}" id="out4" /></a>
|
<a href='<a:outputText value="#{DocumentDetailsBean.nodeRefUrl}" id="out3" />' onclick="return false;"><a:outputText value="#{msg.noderef_link}" id="out4" /></a>
|
||||||
|
@@ -248,7 +248,7 @@
|
|||||||
<a:actionLink value="#{msg.view_in_cifs}" href="#{SpaceDetailsBean.cifsPath}" target="new" id="link2" />
|
<a:actionLink value="#{msg.view_in_cifs}" href="#{SpaceDetailsBean.cifsPath}" target="new" id="link2" />
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<a href='<a:outputText value="#{SpaceDetailsBean.bookmarkUrl}" id="out1" />' onclick="return false;"><a:outputText value="#{msg.details_page_bookmark}" id="out2" /></a>
|
<a href='<%=request.getContextPath()%><a:outputText value="#{SpaceDetailsBean.bookmarkUrl}" id="out1" />' onclick="return false;"><a:outputText value="#{msg.details_page_bookmark}" id="out2" /></a>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<a href='<a:outputText value="#{SpaceDetailsBean.nodeRefUrl}" id="out3" />' onclick="return false;"><a:outputText value="#{msg.noderef_link}" id="out4" /></a>
|
<a href='<a:outputText value="#{SpaceDetailsBean.nodeRefUrl}" id="out3" />' onclick="return false;"><a:outputText value="#{msg.noderef_link}" id="out4" /></a>
|
||||||
|
@@ -41,7 +41,7 @@
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// setup value used by JSF bean state ready for login page if we find the cookie
|
// setup value used by JSF bean state ready for login page if we find the cookie
|
||||||
if (authCookie != null)
|
if (authCookie != null && authCookie.getValue() != null)
|
||||||
{
|
{
|
||||||
session.setAttribute(AuthenticationHelper.SESSION_USERNAME, authCookie.getValue());
|
session.setAttribute(AuthenticationHelper.SESSION_USERNAME, authCookie.getValue());
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user