diff --git a/source/java/org/alfresco/repo/web/scripts/portlet/WebClientPortletAuthenticatorFactory.java b/source/java/org/alfresco/repo/web/scripts/portlet/WebClientPortletAuthenticatorFactory.java new file mode 100644 index 0000000000..64222542f1 --- /dev/null +++ b/source/java/org/alfresco/repo/web/scripts/portlet/WebClientPortletAuthenticatorFactory.java @@ -0,0 +1,223 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ +package org.alfresco.repo.web.scripts.portlet; + +import javax.portlet.PortletSession; +import javax.portlet.RenderRequest; +import javax.portlet.RenderResponse; +import javax.transaction.UserTransaction; + +import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.alfresco.repo.web.scripts.Repository; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.security.AuthenticationService; +import org.alfresco.service.transaction.TransactionService; +import org.alfresco.web.app.servlet.AuthenticationHelper; +import org.alfresco.web.bean.repository.User; +import org.alfresco.web.scripts.Authenticator; +import org.alfresco.web.scripts.Description.RequiredAuthentication; +import org.alfresco.web.scripts.portlet.PortletAuthenticatorFactory; +import org.alfresco.web.scripts.portlet.WebScriptPortletRequest; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + + +/** + * Portlet authenticator which synchronizes with the Alfresco Web Client authentication + * + * @author davidc + */ +public class WebClientPortletAuthenticatorFactory implements PortletAuthenticatorFactory +{ + // Logger + private static final Log logger = LogFactory.getLog(WebClientPortletAuthenticatorFactory.class); + + // dependencies + private AuthenticationService authenticationService; + private TransactionService transactionService; + private Repository repository; + + /** + * @param authenticationService + */ + public void setAuthenticationService(AuthenticationService authenticationService) + { + this.authenticationService = authenticationService; + } + + /** + * @param scriptContext + */ + public void setRepository(Repository repository) + { + this.repository = repository; + } + + /** + * @param transactionService + */ + public void setTransactionService(TransactionService transactionService) + { + this.transactionService = transactionService; + } + + /* (non-Javadoc) + * @see org.alfresco.web.scripts.portlet.PortletAuthenticatorFactory#create(javax.portlet.RenderRequest, javax.portlet.RenderResponse) + */ + public Authenticator create(RenderRequest req, RenderResponse res) + { + return new WebClientPortletAuthenticator(req, res); + } + + + public class WebClientPortletAuthenticator implements Authenticator + { + // dependencies + private RenderRequest req; + private RenderResponse res; + + /** + * Construct + * + * @param authenticationService + * @param req + * @param res + */ + public WebClientPortletAuthenticator(RenderRequest req, RenderResponse res) + { + this.req = req; + this.res = res; + } + + /* (non-Javadoc) + * @see org.alfresco.web.scripts.Authenticator#authenticate(org.alfresco.web.scripts.Description.RequiredAuthentication, boolean) + */ + public boolean authenticate(RequiredAuthentication required, boolean isGuest) + { + PortletSession session = req.getPortletSession(); + + // first look for the username key in the session - we add this by hand for some portals + // when the WebScriptPortletRequest is created + String portalUser = (String)req.getPortletSession().getAttribute(WebScriptPortletRequest.ALFPORTLETUSERNAME); + if (portalUser == null) + { + portalUser = req.getRemoteUser(); + } + + if (logger.isDebugEnabled()) + { + logger.debug("JSR-168 Remote user: " + portalUser); + } + + if (isGuest || portalUser == null) + { + if (logger.isDebugEnabled()) + logger.debug("Authenticating as Guest"); + + // authenticate as guest + AuthenticationUtil.setCurrentUser(AuthenticationUtil.getGuestUserName()); + + if (logger.isDebugEnabled()) + logger.debug("Setting Web Client authentication context for guest"); + + createWebClientUser(session); + removeSessionInvalidated(session); + } + else + { + if (logger.isDebugEnabled()) + logger.debug("Authenticating as user " + portalUser); + + AuthenticationUtil.setCurrentUser(portalUser); + + // determine if Web Client context needs to be updated + User user = getWebClientUser(session); + if (user == null || !portalUser.equals(user.getUserName())) + { + if (logger.isDebugEnabled()) + logger.debug("Setting Web Client authentication context for user " + portalUser); + + createWebClientUser(session); + removeSessionInvalidated(session); + } + } + + return true; + } + + /** + * Helper. Remove Web Client session invalidated flag + * + * @param session + */ + private void removeSessionInvalidated(PortletSession session) + { + session.removeAttribute(AuthenticationHelper.SESSION_INVALIDATED, PortletSession.APPLICATION_SCOPE); + } + + /** + * Helper. Create Web Client session user + * + * @param session + */ + private void createWebClientUser(PortletSession session) + { + UserTransaction tx = null; + try + { + // start a txn as this method interacts with public services + tx = transactionService.getUserTransaction(); + tx.begin(); + + NodeRef personRef = repository.getPerson(); + User user = new User(authenticationService.getCurrentUserName(), authenticationService.getCurrentTicket(), personRef); + NodeRef homeRef = repository.getUserHome(personRef); + if (homeRef != null) + { + user.setHomeSpaceId(homeRef.getId()); + } + session.setAttribute(AuthenticationHelper.AUTHENTICATION_USER, user, PortletSession.APPLICATION_SCOPE); + + tx.commit(); + } + catch (Throwable e) + { + try { if (tx != null) {tx.rollback();} } catch (Exception tex) {} + } + } + + /** + * Helper. Get Web Client session user + * + * @param session + * @return + */ + private User getWebClientUser(PortletSession session) + { + return (User)session.getAttribute(AuthenticationHelper.AUTHENTICATION_USER, PortletSession.APPLICATION_SCOPE); + } + } + +} \ No newline at end of file diff --git a/source/java/org/alfresco/repo/web/scripts/portlet/WebScriptRepoPortlet.java b/source/java/org/alfresco/repo/web/scripts/portlet/WebScriptRepoPortlet.java new file mode 100644 index 0000000000..866e3833df --- /dev/null +++ b/source/java/org/alfresco/repo/web/scripts/portlet/WebScriptRepoPortlet.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ +package org.alfresco.repo.web.scripts.portlet; + +import java.io.IOException; + +import javax.portlet.ActionRequest; +import javax.portlet.ActionResponse; +import javax.portlet.PortletException; +import javax.portlet.PortletSecurityException; +import javax.portlet.RenderRequest; +import javax.portlet.RenderResponse; + +import org.alfresco.web.app.Application; +import org.alfresco.web.scripts.portlet.WebScriptPortlet; + + +/** + * Repository (server-tier) implementation of Web Script Portlet + * + * Informs Web Client Application of Portlet request. + * + * @author davidc + */ +public class WebScriptRepoPortlet extends WebScriptPortlet +{ + + /* (non-Javadoc) + * @see org.alfresco.web.scripts.portlet.WebScriptPortlet#processAction(javax.portlet.ActionRequest, javax.portlet.ActionResponse) + */ + @Override + public void processAction(ActionRequest req, ActionResponse res) throws PortletException, PortletSecurityException, IOException + { + Application.setInPortalServer(true); + super.processAction(req, res); + } + + /* (non-Javadoc) + * @see org.alfresco.web.scripts.portlet.WebScriptPortlet#render(javax.portlet.RenderRequest, javax.portlet.RenderResponse) + */ + @Override + public void render(RenderRequest req, RenderResponse res) throws PortletException, PortletSecurityException, IOException + { + Application.setInPortalServer(true); + super.render(req, res); + } + +} diff --git a/source/java/org/alfresco/repo/web/scripts/servlet/WebClientAuthenticatorFactory.java b/source/java/org/alfresco/repo/web/scripts/servlet/WebClientAuthenticatorFactory.java new file mode 100644 index 0000000000..a36c46b8c9 --- /dev/null +++ b/source/java/org/alfresco/repo/web/scripts/servlet/WebClientAuthenticatorFactory.java @@ -0,0 +1,169 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ +package org.alfresco.repo.web.scripts.servlet; + +import java.io.IOException; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.alfresco.web.app.servlet.AuthenticationHelper; +import org.alfresco.web.app.servlet.AuthenticationStatus; +import org.alfresco.web.app.servlet.BaseServlet; +import org.alfresco.web.scripts.Authenticator; +import org.alfresco.web.scripts.WebScriptException; +import org.alfresco.web.scripts.Description.RequiredAuthentication; +import org.alfresco.web.scripts.servlet.ServletAuthenticatorFactory; +import org.alfresco.web.scripts.servlet.WebScriptServletRequest; +import org.alfresco.web.scripts.servlet.WebScriptServletResponse; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.web.context.ServletContextAware; + + +/** + * Alfresco Web Client Authentication + * + * @author davidc + */ +public class WebClientAuthenticatorFactory implements ServletAuthenticatorFactory, ServletContextAware +{ + // Logger + private static final Log logger = LogFactory.getLog(WebClientAuthenticator.class); + + // dependencies + private ServletContext context; + + + /* (non-Javadoc) + * @see org.springframework.web.context.ServletContextAware#setServletContext(javax.servlet.ServletContext) + */ + public void setServletContext(ServletContext context) + { + this.context = context; + } + + /* (non-Javadoc) + * @see org.alfresco.web.scripts.servlet.ServletAuthenticatorFactory#create(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) + */ + public Authenticator create(WebScriptServletRequest req, WebScriptServletResponse res) + { + return new WebClientAuthenticator(req, res); + } + + + /** + * Alfresco Web Client Authentication + * + * @author davidc + */ + public class WebClientAuthenticator implements Authenticator + { + // dependencies + private WebScriptServletRequest servletReq; + private WebScriptServletResponse servletRes; + + /** + * Construct + * + * @param authenticationService + * @param req + * @param res + */ + public WebClientAuthenticator(WebScriptServletRequest req, WebScriptServletResponse res) + { + this.servletReq = req; + this.servletRes = res; + } + + /* (non-Javadoc) + * @see org.alfresco.web.scripts.WebScriptServletAuthenticator#authenticate(org.alfresco.web.scripts.WebScriptDescription.RequiredAuthentication, boolean, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) + */ + public boolean authenticate(RequiredAuthentication required, boolean isGuest) + { + AuthenticationStatus status = null; + + try + { + // + // validate credentials + // + HttpServletRequest req = servletReq.getHttpServletRequest(); + HttpServletResponse res = servletRes.getHttpServletResponse(); + String ticket = req.getParameter("ticket"); + + if (logger.isDebugEnabled()) + { + logger.debug("Alfresco ticket provided: " + (ticket != null && ticket.length() > 0)); + } + + if (ticket != null && ticket.length() > 0) + { + if (logger.isDebugEnabled()) + logger.debug("Authenticating ticket " + ticket); + + status = AuthenticationHelper.authenticate(context, req, res, ticket); + } + else + { + if (isGuest && RequiredAuthentication.guest == required) + { + if (logger.isDebugEnabled()) + logger.debug("Authenticating as Guest"); + + status = AuthenticationHelper.authenticate(context, req, res, true); + } + else + { + if (logger.isDebugEnabled()) + logger.debug("Authenticating session"); + + status = AuthenticationHelper.authenticate(context, req, res, false, false); + } + } + + // + // if not authorized, redirect to login page + // + if (status == null || status == AuthenticationStatus.Failure) + { + // authentication failed - now need to display the login page to the user, if asked to + if (logger.isDebugEnabled()) + logger.debug("Redirecting to Alfresco Login"); + + BaseServlet.redirectToLoginPage(req, res, context); + } + } + catch(IOException e) + { + throw new WebScriptException("Failed to authenticate", e); + } + + return !(status == null || status == AuthenticationStatus.Failure); + } + } + +} \ No newline at end of file